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