Hi @stevebaer, @dale , @everyone,
I need to understand as depth as possible the behavior of rhino custom objects (or RhinoObject). I have created a fake plugin isolating the issues in question, with comments, in case you can help me with some time. Using C#, it only contains an Entity and EntityCurve classes, a UserDictionary, a CustomCurveObject, two simple commands and a simple ETO panel. CustomRhinoObjectTest.zip (126.6 KB)
What I’m trying to do in my real plugin is to put all the logic of my tools inside Entities, an abstract object with several behaviour patterns, and with this framework automate as much as possible the creation of commands for Rhino and components for GH. That’s something that is more or less done, I’m explaining it for context and because it’s a important constraint, for example, my entities can not inherit from other classes (due to the C# limitation).
Now I’m with getting my geometric entities to sync with Rhino custom objects, I need the states of the two objects to sync correctly in both directions for all the behaviour that a rhino object can have (gumball, control points, etc) and for all the input contexts (commands, UI and the own entities).
My current approach is for each geometric entity (EntityCurve, EntitySurface, etc) to convert it to its corresponding Rhino object (CustomCurveObject, CustomBrepObject, etc) so that the user can play with it, and store inside of it the entity instance. With this I can modify the rhino object and update the state of my entity, via command, UI or with the gumball, but there are some issues that I explain below. But first, do you think this is the best way for my entities to act on the document?
Issue 1
Here I call the command EntityCurve, select a curve, and replace the curve with my custom object. When selected, the panel show its parameters, wich just inflate a boundingbox as a visual reference that it is working. All works well until I create a duplicate. I can modify the copy but when I modify the original, the copy recovers the values of the original object. This is due to the history, but I don’t understand why. How can I prevent this from happening? Rhino6 does not have a method to add a custom curve object without the history.
How do I know if the duplication context is due to rhino replacing the object due to a user modification, or if it is due to a copy of the object being created? Because in the second case I have to duplicate the entity. This is my current code:
protected override void OnDuplicate(RhinoObject source)
{
RhinoApp.WriteLine("OnDuplicate");
base.OnDuplicate(source);
if (source is RhinoEntityCurve rhe)
{
Entity = rhe.Entity.Duplicate() as EntityCurve;
}
}
Issue 2
When I edit the curve from the control points, my custom object seems to disappear, how do I make it work correctly?
Issue 3
For some reason, I had to replace the ObjectTable.Replace method by Delete+Add, bc it would remove the name of the object, as if it were replacing the attributes. Is that intentional?
// This remove rhObj attributes
//doc.Objects.Replace(objRef, rhObj);
doc.Objects.Delete(objRef, true);
doc.Objects.AddRhinoObject(rhObj, null);
Issue 4
For some reason, overriding ShortDescription() method and calling its base method throws an exception: Rhino.Runtime.DocumentCollectedException: ‘This object cannot be modified because it is controlled by a document.’
//public override string ShortDescription(bool plural)
//{
// return base.ShortDescription(plural);
//}
Issue 5
From your experience, what other things should I take into account? Should I make my own undo? If I want to include the entity’s metadata in a UserData, should I take something into account to keep it sync as well? Is there anything non-obvious that I should know?
I am very sorry it is so much text. Thank you very much for your time.