ObjectData::GetDimension() ignored?
-
Hi guys.
ObjectData::GetDimension() callback is ignored in most of the cases.-
When ObjectData::GetVirtualObjects() callback returns null object, in this case GetDimension() is completely ignored. It is the case when it would be most useful!
-
When ObjectData::GetVirtualObjects() callback returns valid PolygonObject, in this case GetDimension() is again ignored because the plugin is calculating dimension from returned PolygonObject.
Is there some additional settings which needs to be set to force plugin to use GetDimension()?
Thanks!
-
-
Hello @wtools3d,
Thank you for reaching out to us. Unfortunately, your question is a bit ambiguous, especially regarding how you register your plugin and what you would consider to be "to be completely ignored", and finally the code you have written.
Our C++
ObjectData
example plugin Rounded Tube does overwrite::GetDimension
and it does what I would expect it to do.ObjectData::GetDimension
is called whenBaseObject::GetDimension
is invoked (or its Python counter parts.GetMp()
and.GetRad()
). The call chain fromBaseObject::GetDimension
goes through our core and visits during this alsoObjectData::GetDimension
. There are of course fallback methods in place which take over whenObjectData::GetDimension
is not implemented, but I neither see any general conditions which would suppress the output fromObjectData::GetDimension
nor is there a difference when I inspect the values.- The only central exit conditions are:
a. The plugin interface is the null pointer.
b. The plugin isOBJECT_ISSPLINE
, thenSplineObject.GetDimension
will be called on the cache of the Spline object generator your plugin is implementing.
c. OtherwiseObjectData::GetDimension
will be called with the bounding box values which have been calculated so far. - Other events and entities are also calling this same chain, and from what I can see, they all work properly.
Calling
BaseObject::GetDimension
indirectly from Python, the returned value250, 50, 250
lines up with the value500, 100, 500
in the Coordinate Manager. Note thatGetDimension
asks for the 'radii' of the bounding box, not its diameters. So, you must return half the value for each bounding box axis.And
RoundedTube::GetDimension
being called, setting these values, the break point is on the method scope exit, and shown are the returned values forrad
:
Cheers,
Ferdinand -
Hi Ferdinand.
I'll explain each issue separately:First. try to multiply *rad value by 10, in your example.
case 1: *rad = Vector(rady, rado + radx, rado + radx) *10; break;Then when you try to select this object and use 'Frame Selected Elements' function in the viewport.
It will frame to the size of actual geometry not to the overridden size multiplied by 10.
So it ignores the override. -
Hello @wtools3d,
This is a different issue as you claim in the title and body of your first posting, and your core claim, that
GetDimension
is being ignored, is not true. Here I multiply the values by 10.And as you can see, these values are respected in API calls as well as the Coordinate Manager and other elements of Cinema 4D using them.
Your issue seems to lie with the fact that the multiple frame commands as 'Frame Elements' and 'Frame Geometry' do not frame bounding boxes as yielded by the objects, but the actual geometry. This is not really an SDK issue and there are three things you can do:
- File a request with user support, that you either want the existing commands to be changed or a new one being added. Chances for this happening are low, because I think the behavior of the frame commands is intentional.
- Implement a 'Frame Bounding Box' command yourself, good framing is not trivial though (at least I would consider it non-trivial).
- Make your inflated bounding box actually to be true, by adding dummy points or null objects for the maxima of your 'fake' bounding box. This won't work for obvious reasons when you want your fake bounding box to be smaller than the bounding box of your geometry. It will also have the flaw that this will be reflected when the user converts your object with
Current State to Object
. With some message and cache hacking, you could fiddle things into place though. Here is a simple hack ofRoundedTube::GetVirtualObjects
:
if (hh->GetBuildFlags() & BUILDFLAGS::ISOPARM) { lop = GenerateIsoLathe(cpadr, cpcnt, seg); if (!lop) goto error; SetAxis(lop, axis); ret->SetIsoparm(lop); } // --- Start of modifications of RoundedTube::GetVirtualObjects // I just added here a null object as the child of the cache root which // is 2500 units 'above' the root on the y-axis. BaseObject* null = BaseObject::Alloc(Onull); if (!null) goto error; null->InsertUnder(ret); Matrix ml = null->GetMl(); ml.off = Vector(0, 2500, 0); null->SetMl(ml); // --- End of modifications of RoundedTube::GetVirtualObjects DeleteMem(cpadr); return ret; error: DeleteMem(cpadr); blDelete(ret); return nullptr; }
Which will frame then like this when pressing
O
:Cheers,
Ferdinand -
Now it's more clear.
I assumed behavior of the framing commands on wrong premise.Maybe you could add some further explanation in the documentation where the overwritten bounding data is used in the cinema.
Thank you for your suggestions how to resolve this on my side!
Regards,
Viktor -
Hello @wtools3d,
@wtools3d said in ObjectData::GetDimension() ignored?:
Maybe you could add some further explanation in the documentation where the overwritten bounding data is used in the cinema.
Yes, this is a good idea, I will do that.
Cheers,
Ferdinand