Archicad C++ API
About Archicad add-on development using the C++ API.

Transforms in notifications

Anonymous
Not applicable
I think I'm making a beginners' error by omission, so hoping for a tip from more experienced users.

I set up a notification for modified elements with ACAPI_Notify_InstallElementObserver().

In the callback, between the APINotifyElement_BeginEvents and APINotifyElement_EndEvents notifications, I get the elemType->elemHead.guid from the API_NotifyElementType parameter and call ACAPI_Element_Get() to get the actual element of interest.

Now as far as I know this gives me only database info about the element, so I use the guid and make a call across to the ModelerAPI and get the equivalent ModelerAPI::Element. (I don't know if there's a direct call to do this conversion; I have my own method that iterates until it finds the modeler element's corresponding guid.)

I need the ModelerAPI element to get its Transform.

The problem I'm having is that when - for example - I move an item in the scene, the callback is called as expected and I can examine the modeler element's transform. But the transform is always one call behind the actual in-scene transform. So the first call just gives me the previous transform before I moved the element.

Any subsequent moves will show the element's previous transform. I thought maybe the begin/end calls come into play, so I cache the element then check the transform in the APINotifyElement_EndEvents call, but it's the same.

I hope I've explained the problem clearly. In summary: everything works but the transform I get in the callback is the previous position of the element. It's like I have to force a re-read of the scene so the modeler element data is refreshed but I don't know how to do this.

Any advice greatly appreciated.

UPDATE: well my workaround was to simply start up a timer and re-check the element's transform via its cached UUID. Seems to work. But it leads to another issue I haven't figured out: how do transforms work with geometry? It seems polygon data is in world coordinates. So passing directly to renderer has everything in its correct place. But if I pass the transform of the element that contains the polygons, sometimes it's just Identity, but when it's not it puts the element in the wrong place.

Which makes it tricky to handle position changes. I've tried delta positioning (placing initially with Identity transform, then any subsequent moves subtracting previous cached transform from latest) but I'm not getting correct results. If anyone's got any suggestions on how to manage transforms with geometry (via model > elements > bodies > polygons) I'd be interested to hear it. Somewhere I thought I saw in some docs that you had to pass the transform in, but that seems to put the geometry out of place, relative to where the mesh is in global coords. Perhaps the only way to update is to redraw the polygons.
2 REPLIES 2
Ralph Wessel
Mentor
MarkHenryC wrote:
I need the ModelerAPI element to get its Transform.
I know it's marked as "Obsolete" in the documentation, but I'd recommend using the ACAPI_3D_GetComponent function from the 3D Manager. You can retrieve the body transformation matrix from body.tranmat in the populated API_Component3D structure. This will give you the correct results immediately.
Ralph Wessel BArch
Anonymous
Not applicable
Thanks Ralph. I'l check it out.