animation disregarded after toolplugin



  • 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



  • 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



  • 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



  • This post is deleted!


  • 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



  • 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



  • 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



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


Log in to reply