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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    animation disregarded after toolplugin

    Cinema 4D SDK
    python r20
    3
    8
    1.0k
    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.
    • D
      DavidWeidemann
      last edited by

      Hi there,

      I am currently making a plugin that is similar to the move tool in cinema.

      The problem:
      If you take the MOVETOOL, change the position of an animated object with the movetool, DON'T make a new key for the position of the object and go to the next frame this object will go to the animated position again and ignore the changes I did. very logic.
      interestingly enough if I use my tool, change the position of an animated object, DON'T make a key, go to the next frame...
      ... stunningly enough the object does not go back to the keyed position. sometimes it does. sometimes it only goes there after I go to the next frame, sometimes to the frame after. It seems to be locked or something, and get unlocked only after a certain time, or whatever...

      What I tried so far:
      I tried c4d.GeSyncMessage(c4d.EVMSG_ASYNCEDITORMOVE) because it sounded promsing, EventAdd is in it of course. I tried to set the matrix dirty manually (of course SetMg will do that anyways I guess). I don't know if it is something that I am missing, maybe something thread related that blocks the object. or that the object doesn't know it needs to be updated. Or just an error I made?

      The simplified code:

      def MouseInput(self, doc, data, bd, win, msg):
          objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE)
          if len(objects) == 0:
              return True
      
          # Retrieves which clicks is currently clicked
          device = 0
          if msg[c4d.BFM_INPUT_CHANNEL ]== c4d.BFM_INPUT_MOUSELEFT:
              device = c4d.KEY_MLEFT
          elif msg[c4d.BFM_INPUT_CHANNEL] == c4d.BFM_INPUT_MOUSERIGHT:
               device = c4d.KEY_MRIGHT
          else:
              return True
      
          # Retrieves the X/Y screen position of the mouse.
          mx = msg[c4d.BFM_INPUT_X]
          my = msg[c4d.BFM_INPUT_Y]
      
          # need to store the undo for autokey
          doc.StartUndo()
          undoObjs = list()
          for o in objects:
              doc.AddUndo(c4d.UNDOTYPE_CHANGE, o)
              undoObjs.append( doc.GetUndoPtr() )
      
          # Start a Dragging session
          win.MouseDragStart(button=device, mx=int(mx), my=int(my), flags=c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE|c4d.MOUSEDRAGFLAGS_NOMOVE)
          result, dx, dy, channel = win.MouseDrag()
      
          # While the Mouse is still in the Dragging (clicked) state
          while result == c4d.MOUSEDRAGRESULT_CONTINUE:
              # If user doesnt move the mouse simply updates frag information
              if dx == 0.0 and dy == 0.0:
                  result, dx, dy, channel = win.MouseDrag()
                  continue
      
              # Offsets the original position with the delta of the dragging
              mx += dx
              my += dy
      
              # do something with the matrices of the objects
              for i in xrange(len(objects)):
                  objects[i].SetMg(SOME MATRIX)        
      
              # Updates the Viewport 
              c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW | c4d.DA_NO_THREAD | c4d.DA_NO_ANIMATION)
              # and attribute manager
              c4d.GeSyncMessage(c4d.EVMSG_DOCUMENTRECALCULATED)
              # maybe this helps with that problem? but no
              c4d.GeSyncMessage(c4d.EVMSG_ASYNCEDITORMOVE)
      
              # Updates drag information
              result, dx, dy, channel = win.MouseDrag()
      
          # do autokey
          ID_AUTOKEYING_COMMAND = 12425
          if c4d.IsCommandChecked(ID_AUTOKEYING_COMMAND):
              for i in xrange(len(objects)):
                  doc.AutoKey(objects[i], undoObjs[i], False, True, False, False, False, False)
      
          doc.EndUndo()
      
          # If the user press ESC while dragging, do an Undo (remove the Metaball Object)
          if win.MouseDragEnd() == c4d.MOUSEDRAGRESULT_ESCAPE:
              doc.DoUndo(True)
      
          # Pushes an update event to Cinema 4D
          c4d.EventAdd()
          return True
      

      if anybody has an idea, please let me know!

      Thank you,
      David

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hi,

        I do not really understand why you would expect your code to nullify any changes made to the matrices of the selected objects when advancing to the next frame if they have not been keyframed, because there is no logic for that in your code.

        Maybe I do not understand your question correctly. You also poll the active input device and store it in variable of the same name, but actually never test against that (i.e. you also start a mouse drag session with device == 0), but that is only a minor problem. Overlooked the return True 😉

        Cheers,
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • D
          DavidWeidemann
          last edited by

          Hi zipit,

          Sorry, maybe I was unclear. If you set a matrix on an object via code and that object is animated, the normal behaviour is (if you scrub through the timeline, or whatever) that the object just plays its animation. So there is no logic in my code for that, I was just testing the behaviour with autokey enabled and disabled.

          But I actually just found the error and it was a human one. I had an EventAdd() in GetCursorInfo() and that apparently kind of blocked the animation being properly played if the mouse still hovered over the viewport. what I really needed was a call of DrawViews()...

          Thank you for trying to understand me though 😲

          Cheers,
          David

          1 Reply Last reply Reply Quote 0
          • D
            DavidWeidemann
            last edited by

            This post is deleted!
            1 Reply Last reply Reply Quote 0
            • M
              m_adam
              last edited by

              Hi @DavidWeidemann maybe the question will look stupid and you will probably answer I want to have only 1 shortcut and not 2 but why do you want to create AutoKey within your tool and not letting the user set the AutoKey mode and use the move tool or your custom tool that changes the position and let Cinema 4D does the AutoKey for free?

              In fact, this really reminds me AddEditNumberArrows Stops Working on Keyed objects which is almost the same issue.

              Cheers,
              Maxime

              MAXON SDK Specialist

              Development Blog, MAXON Registered Developer

              1 Reply Last reply Reply Quote 0
              • D
                DavidWeidemann
                last edited by DavidWeidemann

                Hi Maxime,

                I initialy tested exactly that: set the matrices with the tool and wait for c4d to do the autokeying (for free).
                But that does not happen. if autokey is enabled and I just set the matrices, the objects jump right back to their old tracks.

                That is why I check if autokey is enabled with c4d.IsCommandChecked(ID_AUTOKEYING_COMMAND) and then request c4d to do a autokey.
                If the user disables autokey or disables the position autokeying nothing happens. So it isn't like I am doing something where the user ends up saying "who made that key?"

                Is there another way?

                Cheers,
                David

                1 Reply Last reply Reply Quote 0
                • M
                  m_adam
                  last edited by

                  Hi @DavidWeidemann sorry, you were right, I've looked at how the Move tool works internally and it basically does what you do, creating undo and manually create autokey, so your code is fine.

                  Cheers,
                  Maxime

                  MAXON SDK Specialist

                  Development Blog, MAXON Registered Developer

                  1 Reply Last reply Reply Quote 0
                  • D
                    DavidWeidemann
                    last edited by

                    ⛅
                    But I appreciate that you where trying to make things more streamlined 😊

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