Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    When to create keyframes?

    Scheduled Pinned Locked Moved SDK Help
    8 Posts 0 Posters 712 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 18/12/2008 at 01:17, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   10 & 11 
      Platform:   Windows  ; Mac  ;  
      Language(s) :     C++  ;

      ---------
      Hi,

      I need to create keyframes from within the GetVirtualObjects() function of my ObjectData plugin. As I have learned from experience and from the SDK, this is a bad thing, because in R10 is may crash and in R11 it will crash.

      What I want to do is a key frame baking function for my plugin. The user clicks a button in the plugin, I catch the click in the plugin's Message() function. I set a Bool variable "RecordMode" to TRUE. Then a loop from the first to the last frame of the scene will run, animating the document to each frame of the scene; each time triggering the GetVirtualObjects(). In the GetVirtualObjects(), I check if "RecordMode" is TRUE. If so, I want to create keyframes for several objects in the scene.

      As I said, creating the keyframes directly in the GetVirtualObjects() will crash R11, because it's not thread safe. I have now two possibilities:

      1. Create the keyframes in the plugin's Message() function.
      This would mean to run the above mentioned loop, trigger GetVirtualObjects() and then create the keyframes. Sounds good, but unfortunately, GetVirtualObjects() always seems to be called last. Whatever keyframes I create, they're created before GetVirtualObjects() did its work.
      Question: Is there a way to manually FORCE GetVirtualObjects() to be called?

      2. Call a MessageData plugin to create the keyframes
      Very little is known about the MessageData. As I understood it, I could call a MessageData plugin from the end of my GetVirtualObjects(). It would create the keyframes and not get me into trouble with thread stuff. I see there's also a (very) little example in the SDK.
      Question: Will a MessageData plugin help me, and if so: how would I pass the required data (e.g. a Pointer to an object in the scene) to it?

      Long text, sorry. I really hope somebody can help. Thanks in advance!

      Greetings,
      Jack

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 18/12/2008 at 05:32, xxxxxxxx wrote:

        Is threading the problem, anyway?

        In R11 I get crashes *everytime* I use the following function *anywhere* in an ObjectData plugin:

        > Bool CreateVectorKey(BaseDocument \*doc, BaseObject \*op, const BaseTime &time;, LONG index, Vector value) \> { \>      // check if tracks exist \>      CTrack \*trackX = op->FindCTrack(DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0))); \>      CTrack \*trackY = op->FindCTrack(DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0))); \>      CTrack \*trackZ = op->FindCTrack(DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0))); \> \>      StopAllThreads(); \>      if (!trackX) \>      { \>           trackX = CTrack::Alloc(op,DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0))); \>           op->InsertTrackSorted(trackX); \>      } \>      if (!trackY) \>      { \>           trackY = CTrack::Alloc(op,DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0))); \>           op->InsertTrackSorted(trackY); \>      } \>      if (!trackZ) \>      { \>           trackZ = CTrack::Alloc(op,DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0))); \>           op->InsertTrackSorted(trackZ); \>      } \> \>      CKey \*keyX = trackX->GetCurve()->AddKey(time); if (!keyX) return FALSE; \>      CKey \*keyY = trackY->GetCurve()->AddKey(time); if (!keyY) return FALSE; \>      CKey \*keyZ = trackZ->GetCurve()->AddKey(time); if (!keyZ) return FALSE; \> \>      keyX->SetValue(trackX->GetCurve(),value.x); \>      keyY->SetValue(trackY->GetCurve(),value.y); \>      keyZ->SetValue(trackZ->GetCurve(),value.z); \> \>      return TRUE; \> }

        The very same code works absolutely fine in another plugin of mine, which is a TagData plugin.

        It is sure that the problem is caused by the above shown code. If I don't call it, no crash happens. Unfortunately, the crash doesn't happen immediately when calling the code but some time later, outside my code. So I just see the disassembler when it happens.

        This is annoying. Does really nobody have an idea how to set keyframes from the Message() function of an ObjectData plugin, in a way that it works in R10 and R11?

        Thanks in advance.

        Greetings,
        Jack

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 28/12/2008 at 12:10, xxxxxxxx wrote:

          it's quit similar to my code, except that I included more checks against failure. I use it in object plugins as well as in tag plugins. No problems by now.

          My object is a generator object without using GetVirtualObject(). Maybe try to insert a further execution call, that you use for your recording stuff.

          > \> Bool XY::AddToExecution(PluginObject\* op, PriorityList\* list) \> { \>      list->Add(op, EXECUTION_EXPRESSION, 0); \>      return TRUE; \> } \>

          This is my key writer:

          > \>      CTrack               \*track; \>      CCurve               \*seq; \>      CKey               \*key; \> \>      val[0] = value.x; \>      val[1] = value.y; \>      val[2] = value.z; \> \>      for (i=0; i<3; i++) \>      { \>           // check if track exists \>                descID = DescID(DescLevel(index, DTYPE_VECTOR, 0), DescLevel(VECTOR_X+i, DTYPE_REAL, 0)); \>                track = op->FindCTrack(descID); \>                if (!track) \>                { \>                     track = CTrack::Alloc(op,descID); \>                     if (!track) \>                          return FALSE; \>                     op->InsertTrackSorted(track); \>                } \>                seq = track->GetCurve(); \>                if (!seq) \>                     return FALSE; \>                key = seq->AddKey(time); \>                if (!key) \>                     return FALSE; \>                key->SetValue(seq, val[i]); \>            \>      } \>

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 30/12/2008 at 07:59, xxxxxxxx wrote:

            Howdy,

            I'm not that familiar with GetVirtualObjects() but after looking at the Atom.cpp SDK example, I notice that when it generates the objects, the generated objects are not inserted into the document.

            So, my question would be, are you trying to set keys for a virtual (generated) object that is not inserted into the document, and is it even possible to set keys for virtual objects?

            Adios,
            Cactus Dan

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 31/12/2008 at 07:23, xxxxxxxx wrote:

              Hi,

              first of all, thank you Robert. But I think the method of keyframe creation is not the problem. I use the exact same function in another plugin of mine, in the Execute() function of an expression tag. It works fine there, in all releases. I bet it's a threading problem.

              Dan: The virtual hierachy is returned as the result of GetVirtualObjects(). You are right, setting keyframes for the virtual objects would not make much sense.
              In my plugin, I implemented a function for converting the virtual objects to real objects. If the user activates that function, the virtual hierarchy is inserted into the document. Then I just work on the real objects instead of the virtual objects, and return NULL from GetVirtualObjects(). I only try to create keyframes for the real objects.

              Maybe I'll make a recorder tag that will create the keyframes, I'll think about it next year 😉

              Happy New Year to all of you!

              Cheers,
              Jack

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 31/12/2008 at 08:42, xxxxxxxx wrote:

                Howdy,

                Ah, OK. Yes that makes much more sense. 🐵

                Well, can you store the PSR values in the plugin's container or an array when GetVirtualObjects() is called and set the keys afterwards?

                Using the Atom.cpp as an example and a MessageData plugin, I noticed that the core messages EVMSG_CHANGE is sent before GetVirtualObjects() and EVMSG_DOCUMENTRECALCULATED is sent after GetVirtualObjects(), if that helps. ;o)

                Adios,
                Cactus Dan

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 06/01/2009 at 02:33, xxxxxxxx wrote:

                  I am not sure what you want to achieve, as far as I understand it you want to cache the translations of your virtual objects?

                  cheers,
                  Matthias

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 06/01/2009 at 05:19, xxxxxxxx wrote:

                    I want to cache the translations (and rotations, scale etc) of child objects of my Generator Object, since the Bake function in the timeline doesn't seem to notice they are being moved.

                    Anyway, it's not that important, but I'd still be interested in a solution.

                    Greetings,
                    Jack

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post