Hi @C4DS,
thank you for reaching out to us. I had some trouble understanding the finer details of your question. Your DoRecursion
method looks correct to me. One thing noteworthy pointing out for a SceneHook
context is that one does not have the guarantee that the caches always have been built or are up-to-date, depending on where and when the SceneHook
does intercept.
What I do not quite understand is why you do bundle up deformer and SDS ("... including the original input object for the deformation/SDS ...", I assume SDS does stand for Subdivision Surfaces), since an SDS-object does not write its output to the deformed cache but the cache. Generally speaking, caches can be quite complex in Cinema, since you often use generators. And in this case the deformed caches can be buried deep within the cache of the generator. You can use either the C++ SDK examples ActiveObject plugin to get a better sense of the full complexity of Cinema's scene graph:

or use a little script I did post here, which only does focus on printing the expanded BaseObject
scene graph tree with caches to the console, which can be a bit easier to read on large caches.
This seems to work, except that I ignore any polygon object which is not an input of a deform/SDS. So, how to distinguish between a polygon object which is an input and one which isn't an input for deform/SDS?
Well, you use BIT_CONTROLOBJECT
like you do in your code. It will be set by ObjectData
nodes (registered with the correct flag) on the object they govern or are governed by. Generators will mark their input objects and themselves in this fashion and deformers will not mark themselves but the objects they deform. So for this scenario here:

The expanded tree of the top null would look like this (the output is from my script):
Null/Null (BIT_CONTROLOBJECT: False)
Null/Null returns 'None' for GetCache.
Null/Null returns 'None' for GetDeformCache.
children of Null/Null:
Polygon/Cube (BIT_CONTROLOBJECT: True)
Polygon/Cube returns 'None' for GetCache.
Polygon/Cube returns for GetDeformCache:
# This is Polygon/Cube deformed by the deformer Bend/Bend.
Polygon/Cube (BIT_CONTROLOBJECT: False)
Polygon/Cube returns 'None' for GetCache.
Polygon/Cube returns 'None' for GetDeformCache.
Polygon/Cube has no children.
Polygon/Cube has no children.
Bend/Bend (BIT_CONTROLOBJECT: False)
Bend/Bend returns 'None' for GetCache.
Bend/Bend returns 'None' for GetDeformCache.
Bend/Bend has no children.
This will get even more complex once you do include generators.
How to find back the relation "original object" <-> "deformed object".
It depends on what you would consider to be a "original object". Raw polygon objects, i.e. nodes of type Opolygon
, will always directly hold their deformed cache, even if the deformer is not a direct child of them (see previous example) or when you have multiple consecutive levels of deformation. For generators this is not so easy, and I would say it is a bit a matter of opinion there what you would consider to be the original and what not. The important point here is that deformed caches then will be buried within the cache of the generator, since only editable point objects are processed for deformers (i.e., something that is hidden in the cache for a generator).
As already stated, I am not quite sure what you are asking exactly for. So I hope this helps a bit. If I missed your point, I would kindly ask you to explain again what your goals are.
Cheers,
Ferdinand