When I see an object selected event, I check the types.
If it’s ObjectType.SubD, I try to get the SubD data via
SubDObject subd = (SubDObject) obj;
but I don’t see a property like subd.SubDGeometry or anything else to get a handle on the SubD instance itself.
Curves, Surfaces, and Breps have an intuitive structure (curve example shown):
CurveObject crv = (CurveObject) obj;
and then retrieve data or run methods on crv.CurveGeometry
EDIT: this seems to be stored on .Geometry, a naming difference from the other object types.
I think I may have what I needed particularly with your nudge to just try casting the .Geometry object to SubD, but I think this might still be an omission/bug.
I had thought that the API convention for RhinoObject types such as the curve I mentioned is:
Geometry for the base geometry
[specific]Geometry such as [Curve/Surface/Brep]Geometry for the details.
I can apparently cast RhinoObject.Geometry to SubD in the case where RhinoObject.ObjectType is SubD, but for API consistency it seems like the extra [specificclass]Geometry properties should be offered directly for all appropriate RhinoObject types.
If nothing else, doing that avoids requiring me to create a conditional with one branch the docs don’t tell me how to handle: if they don’t provide a dedicated property and I use something like ‘is’, what am I supposed to do if ObjectType == SubDObjectType but ‘is SubD’ doesn’t succeed and the cast throws an error? Undefined behavior it seems, which is bad.
make sure that the picking / object getting successfully returns a SubDObject.
then casting should always be successful.
But as you never now.
At least throwing an Exception is what I do in those cases.
Or if you don t like unhandled Exceptions:
…print an Error Message to the command line and return False / null / …
@Tom_P Thanks, but that’s not the question I intended to ask. The question was why I should catch an exception and @stevebaer is captuting the reason why.
If I follow your (reasonable given the situation approach!), and working in C#, I have a big Switch statement which handles which object type I’m dealing with (ObjectType). I then peform a cast to get the details I want, and then I have a code branch to trap an error if the cast doesn’t actually work.
If that happens, where’s the error? Inside Rhino.
That’s why the API should provide such helper functions: an error on the cast, if it happens, is on Rhino’s side of the fence.
It also makes the on ramp for new developers, and unusual code paths for existing ones, much easier because the IDE tells you exactly what you can assign CurveGeometry to while just Geometry… you find out at runtime. You can also skip the cast entirely, in an error-safe way, if you only want to grab a property or two, or invoke a method or two:
int i = varname.CurveGeometry.[thingIwant]