Current Frame does not update [SOLVED]



  • On 15/06/2014 at 07:39, xxxxxxxx wrote:

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

    ---------
    I am trying to animate an object, which is a c++ object plugin, programatically with the current frame. For example the position in x should be equal to the current frame. 
    If I output the current frame variable to the console, it does not update, but stays at 0.
    The object does animate in the viewport, but does not update when the animation is previewed or rendered.
    I am calculating the current frame the regular way, ie: int cF = doc->GetTime().GetFrame(doc->GetFps());

    Any help on how to force the update of the calculated current frame when rendering would be greatly appreciated.

    Thanks!



  • On 15/06/2014 at 14:01, xxxxxxxx wrote:

    Are you calling doc->ExecutePasses(...)?  Also make sure to call EventAdd() after the call to have the display and other areas updated.



  • On 17/06/2014 at 00:39, xxxxxxxx wrote:

    Thanks for the reply Robert.

    I'm afraid ExecutePasses() and EventAdd() do not solve my problem. The current frame is still not updating. It is set to 0 even with those functions added.

    If someone has a code snippet with an updating current frame that would be great.



  • On 17/06/2014 at 02:46, xxxxxxxx wrote:

    Are you by any chance keeping the value for the current frame in a class-level variable and using that to do some sort of calculation with?

    If you are, you will need to copy this variable to the destination object in your object's CopyTo() routine.



  • On 17/06/2014 at 11:49, xxxxxxxx wrote:

    Yes I am Spedler. I am getting the current frame in a function that returns the polygonal object, which is in turn generated with the GetVirtualObject function.

    Can you please provide a snippet on how and where to use CopyTo() to get the current frame to update?

    Thanks!



  • On 17/06/2014 at 12:48, xxxxxxxx wrote:

    CopyTo() doesn't update the current frame. When you render to the PV, the scene is copied first by Cinema. If you have a class-level variable and you don't copy that when the scene is copied, the value is lost. I was guessing this might be why the current frame always returns as 0.

    So you might do it like this:

      
    Bool MyObject::CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, COPYFLAGS flags, AliasTrans *trn)   
    MyObject *myob = (MyObject* )dest;   
    if(!myob)   
        return FALSE;   
    myob->currentFrame = currentFrame;   
         return SUPER::CopyTo(dest, snode, dnode, flags, trn);   
    }   
    

    In this, 'currentFrame' is a class-level variable in which you have stored the current frame. It's just copied across to the new scene when Cinema calls CopyTo().

    This may or may not fix the problem, it depends on your code and if this really is the issue in the first place.



  • On 19/06/2014 at 06:27, xxxxxxxx wrote:

    Thank you for the snippet Spedler. Unfortunately, it didn't work.

    I am baffled as to why the current frame updates in the viewport and not in the rendering.

    BTW, in the Python version of the plugin, I got the same odd behavior. In the Python generator version, checking FORCE UPDATE solved the problem.

    So I guess I am looking for a C++ equivalent of FORCE UPDATE.



  • On 19/06/2014 at 16:52, xxxxxxxx wrote:

    EventAdd(EVENT_FORCEREDRAW);

    You may also want to add a DrawViews(DRAWFLAGS_FORCEFULLREDRAW, editor's basedraw) if that alone does not work.



  • On 19/06/2014 at 23:09, xxxxxxxx wrote:

    Already tried that, still didn't work.

    Tried to calculate the current frame on another object plugin than mine, it didn't update either.



  • On 20/06/2014 at 09:57, xxxxxxxx wrote:

    The way I do this is to use the cf class member variable to automatically change a gizmo in the plugin depending on the current frame. And the gizmo then changes the object's position.
    Trying to pipe the cf value directly into the object's position didn't work for me because the AM needs to be physically changed for that movement to take effect.
    There's probably a way around this. But since ObjectData plugins are meant to use the gizmos that the users physically changes, I don't mind doing it this way. And I can also hide that gizmo if I want.

    Since you're a Windows user. If you want my plugin example to play around with. Just tell me where to e-mail it.
    It has a few other interesting goodies in it too. Smile

    -ScottA



  • On 20/06/2014 at 21:19, xxxxxxxx wrote:

    Thanks for the file Scott.

    In your code the position is updated with the current frame, which is working. That's not unfortunately what I am trying to do. I need to access the current frame to do some calculations. For example, I want to check whether the current frame > 0. This will always return FALSE, even if a parameter is updated by the current frame value.

    So problem still unsolved, at least for my needs. But thanks again for the file.



  • On 21/06/2014 at 07:54, xxxxxxxx wrote:

    You can get the current frame value by getting it from gizmo. Not from the cf class variable:

        BaseDocument *doc = node->GetDocument();  
      BaseObject *op = (BaseObject* )node;  
      BaseContainer *nodebc = op->GetDataInstance();  
      
      LONG frameValue = nodebc->GetLong(POSITION);  
      GePrint(LongToString(frameValue));
    

    It's basically the same thing as getting the value from the class member variable. Only getting it indirectly through the gizmo.
    The gizmo acts a bit like like a "getter" method.

    -ScottA



  • On 21/06/2014 at 08:25, xxxxxxxx wrote:

    I ran a quick little test with rendering to see if the correct frame numbers were getting returned.

    Bool AtomObject::Message(GeListNode *node, LONG type, void *data)  
    {  
      BaseDocument *doc = node->GetDocument();  
      BaseObject *op = (BaseObject* )node;  
      BaseContainer *nodebc = op->GetDataInstance();  
      
      
      //The rendering message is sent twice  
      //Once before the rendering starts...and again when the rendering is finished     
      if(type == MSG_MULTI_RENDERNOTIFICATION)   
      {  
          LONG pos = nodebc->GetLong(POSITION);  
          GePrint(LongToString(pos));  
          GePrint("Is Rendering");    
      }  
      
    ...the rest of the Message() method coded here  
    

    It returns frame 0 when the render starts. And frame 90 when the render finishes.
    So it seems to be working for me.

    -ScottA



  • On 21/06/2014 at 21:19, xxxxxxxx wrote:

    SOLVED!

    It was my mistake after all. The current frame would update fine (without any extra workarounds) if the current document was obtained properly.

    BaseDocument *doc = GetActiveDocument(); will not update the current frame
    BaseDocument *doc = node->GetDocument(); would update it.

    The solution was inspired by looking at Scott's snippet, so thanks Scott!


Log in to reply