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,
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!