Getting deformed points?



  • On 06/09/2015 at 00:32, xxxxxxxx wrote:

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

    ---------
    I've got a tag plugin that needs to operate on the deformed points of an object.

    What is the best way of retrieving this information through the C++ API? It seems like GetDeformCache() doesn't always work, depending on where and when you call it. The documents briefly mention using the Hierarchy class to rebuild caches, but state that this is extremely resource intensive and should be used sparingly.

    Since I'm using the tag on anywhere from 10 to 80 objects in a single scene, I'm guessing I probably shouldn't be using the Hierarchy class as per the SDK warning. However, I'm not sure what else I should use in it's place. I need to get access to the deformed points whenever the tag is executed, but as I said before, GetDeformCache() tends to fail if the scene has just been loaded from disk or is being sent to an external renderer (like the picture viewer).

    There's gotta be some way of doing this, since the Xpresso Point node has a "Use deformed points" option that does exactly what I'm looking for. I just need to know how to implement that in my own C++ plugin.

    -CMPX



  • On 06/09/2015 at 03:20, xxxxxxxx wrote:

    Your tag needs the Generator priority (or any higher value). It will be executed after generators and
    deformers have been evaluated, therefore you will have access to the deformed geometry.



  • On 06/09/2015 at 18:20, xxxxxxxx wrote:

    This seems to work reasonably well most of the time, but sometimes it fails when I'm rendering to the picture viewer or render queue. I haven't been able to track down the exact cause, GetDeformCache() just returns nothing, even though I know there should be active deformations (which means the stuff the tag positions onto the geometry isn't in the right place during render).

    Do you by chance know how the Xpresso "Point" node handles deformation internally? Are they just forcing the cache build via SendModelingCommand() with CSTO or the Hierarchy class?

    -CMPX



  • On 07/09/2015 at 06:09, xxxxxxxx wrote:

    Hi,

    can you tell us a bit more about where and how you use GetDeformCache()? Perhaps some simplified code example?



  • On 07/09/2015 at 19:46, xxxxxxxx wrote:

    The only code I have right now is the former version of the plugin I wrote under Python, since I'm attempting to port it to C++.

    In the Python plugin, I was trying to get the deform cache for the object under the Execute() method. I would only attempt to get the deform cache if the target object had children objects underneath it (which I realize is poor design, since I'm assuming that the child objects are deformers). If I failed to get the deform cache on the first try, I'd call SendModelingCommand() with CSTO on that object, which has the undocumented side effect of forcing a cache rebuild for that object (yes, I know the documentation states I shouldn't do this for that exact reason). Then I'd try and get the deform cache again, and give up if that failed.

    This was, of course, all a really horrible kludgy hack.

    The actual plugin itself reads in geometry from a deformed polygon object, and creates a set of splines or hair guides (depending on what object the tag is attached to) travelling across the surface of a quadrangle polygon strip. I'm basically using this to approximate the functionality of "Geo Maya Hair", which is a Mays plugin that turns polygon strips into hair guides.

    Anyways...

    I want to get this thing ported to C++. My primary problem is that I don't know what the correct method is to get the deformed points of a polygon object **under any circumstances**. Ideally, I think the plugin should check GetDeformCache() first just to see if the cache is available, but if it isn't, then I need to do something else to manually rebuild the cache. I don't know how to do that, and the hacks I used in the Python version (as detailed above) certainly don't seem like the right way to go about that.

    -CMPX



  • On 08/09/2015 at 09:27, xxxxxxxx wrote:

    Hi,

    I tried here with a small example, basically a TagData plugin running on Generator priority, where I use the code snippet on GetCache(). It seems to work as expected. For example I get caches when rendering to Picture Viewer or on scene load. But then again, my test scene might be lacking the needed complexity. Can you maybe provide me with a scenario, where you have problems retrieving a cache? Or maybe you can send me a scene file?



  • On 09/09/2015 at 00:37, xxxxxxxx wrote:

    Well...

    My plugin was originally designed to operate in conjunction with a hair object. It generates custom hair guides based on strips of quadrangle polygon geometry. It also has provisions for selecting a specific "strip" of polygons from a polygon object containing numerous separated strips.

    Normally I'd have anywhere between 60 to 80 individual Hair objects in a scene, each with their own instance of my tag plugin, and each configured to generate guides for a specific strip of polygons. The source polygon object is almost always being deformed by a Skin deformer, at the bare minimum. Sometimes there's other deformers as well, like displacement, jiggle, collision, etc. I've also dabbled around with soft body physics (yet another deformer, except that one runs as a tag)

    Maybe I was just configuring the priorities wrong, but I could never get things working reliably through GetDeformCache(). Sooner or later, it'd always return nil/none/null, which would screw up the renders somewhere (usually in the PV or render queue). Which is when I came up with that workaround for forcing the cache building.

    I suppose I should rephrase my question for clarity:

    How can I force a C++ plugin build the deform caches for an object if they have not already been built?

    -CMPX



  • On 09/09/2015 at 04:56, xxxxxxxx wrote:

    Hi,

    I'm not aware of a possibility to start building the caches from a TagData plugin.
    I think, it would be better to solve your problems retrieving the caches correctly. But as said before I will need your help, as I have not been able to reproduce any issues.



  • On 09/09/2015 at 20:34, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    How can I force a C++ plugin build the deform caches for an object if they have not already been built?

    I am not 100% sure if this will actually work but you could try calling the CurrentStateToObject modelling command. There is actually a wrapper method that does this in lib_sculpt.h.

      
    void EnsureSculptObjectReady(PolygonObject *obj, BaseDocument *doc)   
    {   
         ModelingCommandData cd;   
         if (!obj || !doc) return;   
      
         BaseObject          *op = obj;   
         BaseContainer bc;   
      
         bc.SetBool(MDATA_CURRENTSTATETOOBJECT_NOGENERATE, true);   
      
         cd.doc = doc;   
         cd.op = op;   
         cd.bc = &bc;   
      
         SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, cd);   
    }   
    


  • On 10/09/2015 at 07:37, xxxxxxxx wrote:

    Personally I'd rather like to find the reason, why caches can not be retrieved the way it is intended. Such workarounds might not be the best solution performance-wise.



  • On 10/09/2015 at 19:22, xxxxxxxx wrote:

    I've gotten enough of the C++ plugin written that I could start fiddling around with it in a variety of test scenes.

    It seems to work fine. The priority controls on the tag definitely have an effect, since if I set them to anything lower then "Generators", I can see GetDeformCache() fail and return nothing. If I set the priority to "Generators" or higher, then GetDeformCache() returns a valid object on the first try.

    Sorry for the confusion, everything works as intended.

    The Python version of the plugin definitely *does* have issues with this, but the C++ version does not. I just kinda assumed the C++ version would share the same issues as the Python plugin, and I'd need some way of ensuring that GetDeformCache() returned a valid object. Looks like that's not the case.

    -CMPX


Log in to reply