animation disregarded after toolplugin
I am currently making a plugin that is similar to the move tool in cinema.
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:
c4d.GeSyncMessage(c4d.EVMSG_ASYNCEDITORMOVE)because it sounded promsing,
EventAddis 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!
ferdinand last edited by ferdinand
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 withOverlooked the
device == 0), but that is only a minor problem.
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
This post is deleted!
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.
DavidWeidemann last edited by DavidWeidemann
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?
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.
But I appreciate that you where trying to make things more streamlined