Fast access to geometry objects
-
On 22/12/2015 at 03:20, xxxxxxxx wrote:
Hi,
Originally posted by xxxxxxxx
May I call the Run() method for any document (like GetActiveDocument() ) and do my things at any time? Do I need to copy the document to prevent user changes to the currently edited document by user? How to synchronize user edits and potential automatic creation of caches when I call Run() as described here?
What do you mean by "do my things at any time"? What's the type of your plugin and in what method are you using a Hierarchy::Run()?
Originally posted by xxxxxxxx
Do I have to call SendModelingCommand() right before Run()?
If you use Hierarchy::Run() you don't have to SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT) because the caches for all dirty objects will be built.
-
On 22/12/2015 at 04:00, xxxxxxxx wrote:
This is supposed to be used for interactive renderer that is working in a thread parallel to the main Cinema 4D thread.
I plan to call Hierarchy::Run() using MessageData class for timer callback every 1 or 2 seconds.
And inside Hierarchy::Do() (which is called for every object) I plan to check if the BaseObject has changed using GetDirty() infromation. If the object has changed then geometry will be loaded to the renderer and updated accordingly.I just want to avoid unnecessary re-polygonization of the scene in this process based on Hierarchy::Run() that I plan to implement. For example, if some object with curved surfaces has created the polygon caches once and then it wasn't changed by user then I don't want to trigger the polygon cache rebuild for such objects.
I have renamed the topic title to the broader one than VolumeData only.
-
On 04/01/2016 at 02:27, xxxxxxxx wrote:
Hello,
Cinema 4D does not have an interactive renderer. Therefore the SDK does not include anything that is especially made for building an interactive renderer. Tools like the Hierarchy class are build for different purposes. So everything you build will be experimental and may or may not work.
If you really want to access the caches of "changed" objects you might want to read and iterate the cache manually as shown in GetCache().
Best wishes,
Sebastian -
On 18/01/2016 at 03:57, xxxxxxxx wrote:
Hello Sebastian,
Regarding recursive example of GetCache() the question is: do the functions op->GetCache(nullptr); and op->GetDeformCache(); produce cache data inside them and return the pointers to user? Or alternatively the caches could already be produced somewhere and these functions simply return the pointers.
I am interested in this to know whether I can call these functions for free.For example a strange situation for me is like this that I have noticed:
- I traverse the scene graph using GetCache() recursive example above;
- For Oinstance nodes we get cache (using op->GetCache()) and go down the hierarchy and these cached objects of instance have different address returned by pobj->GetPolygonR(); which seems to be memory vasting if it happens inside C4D even without me calling op->GetCache().
Thanks,
Anton -
On 18/01/2016 at 04:55, xxxxxxxx wrote:
1- the cache is already there, so they are free "if the cache is not there, it will return nullptr"
2- if the instance object got "render instance" checked, its GetCache() will return nullptr. -
On 18/01/2016 at 07:12, xxxxxxxx wrote:
Originally posted by xxxxxxxx
1- the cache is already there, so they are free "if the cache is not there, it will return nullptr"
Ok, why then Cinema does not exploit memory saving geometry instancing?
-
On 19/01/2016 at 01:25, xxxxxxxx wrote:
Hello,
in its default mode an Instance object acts as a generator and rebuilds the referenced object. This way it is possible to deform the instance. If you enable "Render Instance" Cinema will use the geometry of the referenced object directly and it is not longer possible to deform the instance.
Best wishes,
Sebastian -
On 23/01/2016 at 10:45, xxxxxxxx wrote:
Thanks for previous reply, Sebastian!
Are there any events in Cinema that allow to determine which BaseObjects were added or removed from scene hierarchy?
Of course I can compute it on my side by holding the list of old BaseObjects and the list of new BaseObjects and compare the lists. This needs hierarchical brute force checking of all the BaseObjects of BaseDocument. But I would like to look for some optimization.
Thanks,
Anton -
On 25/01/2016 at 01:52, xxxxxxxx wrote:
Hello,
when you add or remove an object you have to call EventAdd() to inform Cinema that something changed. EventAdd() triggers the core message EVMSG_CHANGE. Also when Cinema changes something in the scene it only calls EventAdd(). So the only thing to catch is EVMSG_CHANGE.
Best wishes,
Sebastian -
On 25/01/2016 at 05:44, xxxxxxxx wrote:
Thanks Sebastian, I knew about it EVEMSG_CHANGE already.
Currently, analyze there HDirty flags of BaseDocument with some inverval of time to make sure if I need to retravese Cinema scene graph and either add/remove or change the objects and instances in our rendering system.
UInt32 hdirty_object = doc->GetHDirty(HDIRTYFLAGS_OBJECT); UInt32 hdirty_object_matrix = doc->GetHDirty(HDIRTYFLAGS_OBJECT_MATRIX); UInt32 hdirty_object_hierarchy = doc->GetHDirty(HDIRTYFLAGS_OBJECT_HIERARCHY); UInt32 hdirty_tag = doc->GetHDirty(HDIRTYFLAGS_TAG);
And it is convenient. One remaining issue is with GetCache() and GetDeformCache() which may return nullptr if the cache is not yet built for generator object. They seem to build these caches lasilly and these caches become available some time later. And this is a clever idea for compute amortization!
My routing which periodically checks dirty bits may grab the scene data updates after generator object (like torus) was added but before they have caches built. And it also updates loaded dirty flags. And I also don't know how much time Cinema needs to build the caches.
Questions:
- Is there any way to know that while the cache is not yet built but should be there?
One possible solution is to make a big switch and check all supported generator objects (torus, sphere and others) and assume that they need caches. If no caches done for this time scene traversal then return later and check again. But this may require several scene full traversal until everything is loaded correctly to our renderer.
-
Is there any way to force all caches of BaseDocument to be built? May cause unwanted delays for user.
-
Is there any way to check for the whole BaseDocument using some cheap function whether all the needed caches of scene objects were built or not yet? Such a function can help me to know this kind of hint: "scene changed, but caches are being prepared yet, check later". With this I can save some flops full on scene traversals.
Thanks a lot for info!
Anton -
On 25/01/2016 at 09:39, xxxxxxxx wrote:
Hello,
you can check if an object is a generator by checking the OBJECT_GENERATOR flag. So you don't have to hardcode all generator types. I wouldn't know any way to check if all caches are build but you should be able to build the caches with ExecutePasses().
Best wishes,
Sebastian -
On 25/01/2016 at 11:03, xxxxxxxx wrote:
Hello Sebastian,
Does the function ExecutePasses() rebuild the caches from scratch every time I call it or it basically finish building where needed?
-
On 26/01/2016 at 09:28, xxxxxxxx wrote:
Hello,
ExecutePasses() triggers only the – well- execution of the scene. If a given generator actually does rebuild its cache or not is decided by that generator depending on its dirty state etc.
best wishes,
Sebastian