How to ger render result from Subdivision Surface?

On 05/08/2017 at 01:40, xxxxxxxx wrote:

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

Hi All!

There is a subdivision surface object in Cinema. If we place objects under it they are subdivided with following number of subdivisions:

  1. For Picture Viewer with #Render subdivisions
  2. For Editor View with #Editor subdivisions

There are some common routines:

BaseDocument * doc = GetActiveDocument();
BaseObject * some_object = doc->GetFirstObject(); // and also enumerate the hierarchy
BaseObject * dc = some_object->GetDeformCache(); // if null then check GetCache(), etc.

For Subdivision Surface object the some_object->GetDeformCache() returns the object with #num subdivs corresponding to #Editor setting. I would like to know a way how to get result corresponding to #Render setting (typically a higher number and better precision). Is it possible to get it at any time for active document out of the Picture Viewer renderer?


On 07/08/2017 at 02:54, xxxxxxxx wrote:


this depends a bit on what you mean with "any time".

You will need the cache to be built in the resolution you want (editor/render). Therefore you can use ExecutePasses() with the respective BUILDFLAGS as discussed in this thread (a bit further down).

If your code itself is executed as part of the scene evaluation (i.E. GetVirtualObjects() of an ObjectData), then it can get a bit more complicated, as you will need to isolate the object into a temporary document, so you can call ExecutePasses() in that situation. On the other hand you are using GetActiveDocument() in your code snippet, so you are probably not in such a context of a NodeData derived plugin.

On 13/08/2017 at 06:12, xxxxxxxx wrote:

Hi Andreas,

Yes, we anaylize  GetActiveDocument() check dirty flags and if dirty then test the hierarchy and test object dirty flags. If they are dirty then update the corresponding object in the renderer (all works interactively and quite nice).

If I assign BUILDFLAGS_EXTERNALRENDERER for  ExecutePasses() then everything is built for render mode in our custom interactive renderer. But it seems that after this the Editor rebuilds the caches of objects of GetActiveDocument() back to Editor state. 
Later user can apply simple change in the scene (like Light source enable/disable). In this case we use BUILDFLAGS_EXTERNALRENDERER for  ExecutePasses(). Then we test the hierarchy again and there see that subdivision caches of objects are new/rebuilt (dirty) and renderer recalculates them again. For huge subdivisions this is expensive. And the reason is that we changed the active scene of Editor and Editor changed it back.
As you suggested one potential solution is to isolate subdiv object hierarcy into the temporary document and subdivide there with full render settings. Sounds fine but involves some copy and CPU subdivision. Not yet tested it.

On 14/08/2017 at 08:58, xxxxxxxx wrote:

Hi Aaron,

I'm not sure I do understand. It is the intended behavior to have the cache at editor resolution, while in the editor/viewport. And there is only one cache, so it needs to be rebuild in editor resolution. So if you want to have this persistent, then you would either need to set the editor resolution equal to the render solution (or maybe nicer, ask the user to do so himself) or work with some kind of clone.

On 14/08/2017 at 09:18, xxxxxxxx wrote:

Hi Andreas, yes, all this seems logical. What I am trying to do it to make most fluent experience where user doesn't need to click unnecessary things. If we place high numbers for Editor mode slot then OpenGL viewport render slows down a lot (if we talk about say 30M polygons). 
We use GetActiveDocument() and it's native Editor-mode objects but we may open IPR (Interactive Preview Render) which listens for GetActiveDocument(). And if we load some render-mode objects to IPR using GetActiveDocument() then we don't want to force their huge reloads in few seconds after any click. I think that working with a clone to temporarty document or making own subdiv tag are options to go.