I defined a UserData (Hole), this data is added to Brep, saved, copied, moved, undeleted, the data is normal, when I modify the Hole, I need to replace the Brep, after replacing the Brep, if I undo the replacement, Then my data will be lost, what is the reason?
Here is my code when I replace Brep:
internal static void Hole_XY_RhinoUpdateHole(XY_Hole hole)
{
//When I undo, my data is lost
RhinoApp.WriteLine("Replace Hole Brep!!!!!!!!!!! + BeginUndoRecord");
var sn = RhinoDoc.ActiveDoc.BeginUndoRecord("ReplaceHole");
RhinoObject rhinoObject = RhinoDoc.ActiveDoc.Objects.Find(hole.AttachGuid);
if (rhinoObject != null && rhinoObject.Geometry.UserData.Find(typeof(XY_Hole)) is XY_Hole _Hole)
{
Brep brep = hole.CreateBrep();
RhinoDoc.ActiveDoc.Objects.Replace(rhinoObject.Id, brep); //Here hole.OnDuplicate is called four times?????
bool commit = rhinoObject.CommitChanges(); //returns false forever???
RhinoDoc.ActiveDoc.Views.Redraw();
}
if (sn > 0)
{
RhinoApp.WriteLine("Replace Hole Brep!!!!!!!!!!! + EndUndoRecord");
RhinoDoc.ActiveDoc.EndUndoRecord(sn);
}
}
private void RhinoDoc_AddRhinoObject(object sender, RhinoObjectEventArgs e)
{
if (e.TheObject.Geometry.UserData.Find(typeof(XY_Hole)) is XY_Hole hole) hole.AttachGuid = e.TheObject.Id;
}
The reason why your UserData is lost when you undo the replacement of Brep is because the Undo mechanism in Rhino reverts the changes made to the geometry of the RhinoObject, but does not restore any attached UserData. When you replace the Brep, the RhinoObject gets a new geometry, and any previously attached UserData is lost.
I wanted to regenerate a RhinoObject, but it seems to be the same result. The RhinoObject deleted by Object.Delete will still lose data after undoing the deletion, but the RhinoObject deleted manually by pressing del will not lose the data after undoing.
internal static void Hole_XY_RhinoUpdateHole(XY_Hole hole)
{
//When I undo, my data is lost
RhinoApp.WriteLine("Replace Hole Brep!!!!!!!!!!! + BeginUndoRecord");
var sn = RhinoDoc.ActiveDoc.BeginUndoRecord("ReplaceHole");
RhinoObject rhinoObject = RhinoDoc.ActiveDoc.Objects.Find(hole.AttachGuid);
if (rhinoObject != null && rhinoObject.Geometry.UserData.Find(typeof(XY_Hole)) is XY_Hole _Hole)
{
Brep brep = hole.CreateBrep();
//RhinoDoc.ActiveDoc.Objects.Replace(rhinoObject.Id, brep); //Here hole.OnDuplicate is called four times?????
//bool commit = rhinoObject.CommitChanges(); //returns false forever???
RhinoDoc.ActiveDoc.Objects.AddBrep(brep, rhinoObject.Attributes.Duplicate()); //Here hole.OnDuplicate is called four times ??
RhinoDoc.ActiveDoc.Objects.Delete(rhinoObject); //When I undo, my data is still lost
RhinoDoc.ActiveDoc.Views.Redraw();
}
if (sn > 0)
{
RhinoApp.WriteLine("Replace Hole Brep!!!!!!!!!!! + EndUndoRecord");
RhinoDoc.ActiveDoc.EndUndoRecord(sn);
}
}
Assign the previously stored data to the new object
It’s not fragile, this is how it works, userdata is object specific, therefore if you remove that specific object and a new one is created (UNDO) you lose all user data to that object, so you must implement an UNDO that stores the data and reassigns it. It’s not fragile, that’s how it works, and It’s actually pretty solid.
@dale@farouk.serragedine
New problem occurs, data is not copied when copying properties;
My custom object inherits from Rhino.DocObjects.Custom.UserData; after the inherited object is added to Attributes.UserData, it cannot be copied and moved? This question was asked a long time ago