I also thought of maintaining plugin data in an ArchivableDictionary and linking it to the history replay with my own RecordID:
if (!history.SetInt(1, updateFromEto))
return false;
to
if (!history.SetInt(1, pluginDataRecordID))
return false;
But then the question is, how do you force a call to the virtual ReplayHistory(...)? I need access to the replay.Results[i].Update___(...) methods to change the children objs.
I figured out I can store the parameters outside of HistoryRecord. All I need is a way to update a child object without Rhino thinking I broke history.
Sometimes you need to change the parameterization of a command:
The Editors for BlendCrv and BlendSrf are part of the BlendCrv and BlendSrf command classess, so they share access to a lot of functionality for doing the edits.
After an object to edit is selected, they get the history record for that object.
That has a bunch of parameters that were set by the command before and used to make the object being edited.
After some of those parameters get changed by the edit, a new object is made using the modified params.
A new history record is made with the changed parameters and any that weren’t changed are copied from the old history record.
That new history record is attached to the new object.
The history manager is checked for state settings and history recording is turned on temporarily if necessary.
Also history locking is turned off temporarily if necessary.
The old object being edited is replaced (Doc.ReplaceObjec()) with the newly changed one that has the new history record attached.
As far as the RhinoDoc and ReplaceObject are concerned, that looks just like a new object being made by a command, which it actually is.
The history states are restored if necessary.
CRhinoHistoryRecord and CRhinoHistoryManager are exposed in the sdk.
I don’t really know if there is something you can’t get at from a plugin. I haven’t tried it, but I doubt there is.
If I store parameterization outside of the HistoryRecord and use doc.Objects.Replace(), then ObjRef1 will still update ObjRef2, and ObjRef2 will update ObjRef3 as usual:
PluginCmd()
_params = getParams()
crv2 = doCmd( _params )
history = new Rhino.DocObjects.HistoryRecord()
objRef2 = doc.Objects.AddCurve(curv2, null, history, false)
//object ref ID used to get _params from plugin dict
WriteHistory(history, ObjRef1, objRef2.ID)
writePluginHistory(objRef2.ID, _params )
PluginCmdEdit()
_params = readPluginHistory(objRef2.ID)
update( _params )
newCrv2 = doCmd( _params )
doc.Objects.Replace(objRef2, newCrv2 )
updatePluginHistory(objRef2.ID, _params )
//doc.Objects.Replace(objRef2) triggers a HistoryReplay and updates ObjRef3
//ObjRef1 is still ObjRef2's parent and will trigger HistoryReplay