Running Xpresso tags inside GetVirtualObjects()

On 09/03/2018 at 08:19, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R17 
Platform:    Mac  ;  
Language(s) :     C++  ;

Greetings to all.

Is there any way to execute Xpresso tags on objects cloned inside GetVirtualObjects()?

It seems like this isn't possible without the host object being a part of an active document. The presence of hh->GetDocument() would lead me to believe that they are, but I'm not sure how this works- calling hh->GetDocument()->ExecutePasses() just causes C4D to crash with a critical error on gv_world.cpp(1264).

Likewise, I've tried calling Execute() on the GvNodeMaster of the Xpresso tag(s), but this always returns GV_CALC_ERR_NOT_INITIALIZED and does nothing. I've tried initializing the GvNodeMaster manually, but again, InitCalculation() always fails with GV_CALC_ERR_NOT_INITIALIZED.

It seems to be possible to create a new document (specifically for use within my plugin) and keep stuff synchronized in there with what gets returned from GetVirtualObjects() then call ExecutePasses() myself to manually update things, however I have no idea if this is a safe thing to do.

Is there any way of enabling Xpresso tags on objects returned from GetVirtualObjects() without creating a new BaseDocument instance?


On 12/03/2018 at 03:51, xxxxxxxx wrote:


it looks like you already found the solution. GetVirtualObjects() is being called as part of the execution pipeline of a document. Attempting to execute the same document (calling ExecutePasses()), while already at it, well... you already found out the hard way.
Your workaround of a temporary BaseDocument is completely fine and should be safe.

Now, for the Xpresso tag, we are not completely sure, we understood the final goal. Is it about generating an object with Xpresso tag (i.e. returning an object from GetVirtualObject() with an Xpresso tag attached) or about getting the resulting cache of an input object with an Xpresso tag attached or about some temporary object having an Xpresso tag to create an intermediate result?
In the first two cases I hadn't expected any need for manual execution of the Xpresso tag.

On 12/03/2018 at 05:10, xxxxxxxx wrote:

Hey, thanks for the reply.

The end goal was to create a replacement for the mograph cloner that could randomize certain user data parameters on a per-clone basis, then expect the Xpresso tags attached to that object to fire off properly. For example, you could clone an industrial robot arm rig a dozen times and control the user data for each clone on a per-clone basis, then expect the cloned (virtual) rig to properly update itself.

Using a temporary base document seems to work fine. It doesn't really feel like the cleanest approach, but I've not been able to crash C4D using this method so I guess it's as good as any. Thanks for your help!