Order Of Hierarchy Updates For Fieldobjects
-
Hello,
I am working on a FieldObject plugin that I am registering with RegisterFieldPlugin. My FieldObject is meant to be getting data from a linked object in its UI and then using the passed data to calculate the values for Sample.
My issue is coming in that when I make a change to the linked object it is not being reflected in the FieldObject. This issue seems to stem from the fact that the FieldObject is running its code prior to the change in the linked object being reflected. So instead of the FieldObject having fresh values it referencing the previous data.
Visualized this is what seems to be happening.
FieldObject runs its Sample
Linked Object updates its dataand I am looking to have the reverse order happen. This happens regardless of the order of the objects in the Object Manager.
Is it possible to have an object in the scene update before the FieldObject is called? In the sdk is there an example of the order in which Cinema will call things to be updated in the hierarchy.
Any help would be greatly appreciated.
John Thomas
-
Hello @JohnThomas,
Thank you for reaching out to us. Without your code and the high level design of your field, it is hard to give here good advice.
Dependencies in Cinema 4D
Cinema 4D does not have a dependency graph in a more narrow sense. So, when we have this scene graph:
Obj.1 Obj.1.1 Obj.2 Field.F
Cinema 4D will by default update the scene in depth-first traversal:
Obj.1, Obj.1.1, Obj.2, Field.F, ...
. WithObjectData.CheckDirty
an object can signal to Cinema 4D that it considers itself outdated and with that invoke a scene update. WithObjectData.AddToExecution
you can influence whenObjectData::Execute
is being called in a scene update (and with that sidestep the pure hierarchical execution to some degree), and withNodeData::GetAccessedObjects
you can tell Cinema 4D which parts of the scene graph can be evaluated in parallel (e.g. tell Cinema 4D that it is safe to evalObj.1
andObj.1.1
in parallel, because both signal that they do not access each others data). ButGetAccessedObjects
is about access violations, and not update dependencies, so you cannot tell Cinema 4D to wait for something with this function.So, for
Obj.1
which relies in its cache output on the cache output ofObj.2
, you have already a problem with 'normal' cache generating objects, asObj.1
will be built beforeObj.2
. Cinema 4D's solution to that are hierarchies. Cache relevant inputs are generally expected to be child objects of the object which needs them, e.g., a spline (Obj.1.1
) below an extrude object (Obj.1
). The object with a dependency then calls one of the a bit ill named "hierarchy clone"BaseObject
methods:Which effectively result in the children, the dependencies, being built before the dependent (the parent), and the dependent therefore operating on data from this scene update and not the last one. But this really only works within the local hierarchy of an object.
Dependencies for a Field
Your case is rather tricky here, because fields, while being objects, fall outside of that scheme. You could also say that fields are not really meant to be dependent on other scene elements; although Cinema 4D has some native fields which violate that rule.
The problem is that fields, other than polygon and spline generators are not executed themself at a fixed point in the scene update but rather are polled by other objects while they are updating themselves. Fields also do not mix well with the "things I depend on, should be my children"-scheme.
When your field is just linking some simple object, you can just draw a copy from that object, put it into a dummy scene, and execute the passes there, to get the current state of that object (possibly before it updates itself because it comes 'after' the object which invokes your field). But this strategy quickly falls
apart when that linked node has complex dependencies itself. You can technically clone the whole scene and eval the passes there, but that is performance wise terrible and you must also avoid feedback loops, as such cloned scene would also contain your field which clones the whole scene upon sampling.Bottom Line
There is no ideal solution here. Cinema 4D's dependency handling is not perfect, but people often also do not realize that they build conceptually impossible systems. A field which relies on the cache of an object could be linked as a field in that very object it depends on to build that object's cache. An impossible scenario.
There are ways to solve this to a certain degree, but they depend on the case, and generally also require some sophisticated critical case checking. Cinema 4D's architecture largely prevents from the worst things happening when users construct cyclically dependent scenes (a cube C which depends on a sphere S which depends on the cube C which ...), but when you start manually executing passes within scene execution all that is out of the window.
Maybe you can shed some light on what you are trying to achieve on a higher level?
Cheers,
Ferdinand -
@ferdinand Thanks for the response.
That's what I was afraid the situation would be, I believe I have a work around that will be able to fulfill what I need it to do.
John Thomas