Hi everyone. I am trying to learn Python and I have been trying to modify scripts from the official C4D Github page.
I want to see how I could possibly add a GUI button to this code that copies an animation curve from one object to another.
I have tried combining two different scripts here.
I am trying to get when the user clicks the ok button it copies the curve and adds to the other object. Right now the script will do that but only when you click execute.
Please let me know if you have any thoughts, thank you!
Copyright: MAXON Computer GmbH
Author: Manuel Magalhaes
Description:
- Copies the position, rotation and animation Tracks (so all Keyframes) from obj1 to obj2.
Notes:
- If obj2 already have some animation data for its position, rotation, and animation these data will be lost.
Class/method highlighted:
- BaseObject.GetCTracks()
- CTracks.GetDescriptionID()
- CTracks.FindCTrack()
- C4DAtom.GetClone()
- CTracks.InsertTrackSorted()
- BaseDocument.AnimateObject()
"""
import c4d
class ExampleDialog(c4d.gui.GeDialog):
def CreateLayout(self):
"""
This Method is called automatically when Cinema 4D Create the Layout (display) of the Dialog.
"""
# Defines the title of the Dialog
self.SetTitle("This is an example Dialog")
# Creates a Ok and Cancel Button
self.AddDlgGroup(c4d.DLG_OK | c4d.DLG_CANCEL)
return True
def Command(self, messageId, bc):
"""
This Method is called automatically when the user clicks on a gadget and/or changes its value this function will be called.
It is also called when a string menu item is selected.
:param messageId: The ID of the gadget that triggered the event.
:param bc: The original message container
:return: False if there was an error, otherwise True.
"""
# User click on Ok button
if messageId == c4d.DLG_OK:
print("User Click on Ok")
return True
# User click on Cancel button
elif messageId == c4d.DLG_CANCEL:
print("User Click on Cancel")
# Close the Dialog
self.Close()
return True
return True
def main():
# Creates a new instance of the GeDialog
dlg = ExampleDialog()
# Opens the GeDialog, since it's open it as Modal, it block Cinema 4D
dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=300, defaulth=50)
# Retrieves the object called obj1 from the active document.
animatedBox = doc.SearchObject("obj1")
if animatedBox is None:
raise RuntimeError("Failed to retrieve obj1 in document.")
# Retrieves the object called obj2 from the active document.
fixedBox = doc.SearchObject("obj2")
if fixedBox is None:
raise RuntimeError("Failed to retrieve obj2 in document.")
# Retrieves all the CTrack of obj1. CTracks contains all keyframes information of a parameter.
tracks = animatedBox.GetCTracks()
if not tracks:
raise ValueError("Failed to retrieve animated tracks information for obj1.")
# Defines a list that will contains the ID of parameters we want to copy.
# Such ID can be found by drag-and-drop a parameter into the python console.
trackListToCopy = [c4d.ID_BASEOBJECT_POSITION, c4d.ID_BASEOBJECT_ROTATION, c4d.ID_BASEOBJECT_SCALE]
# Start the Undo process.
doc.StartUndo()
# Iterates overs the CTracks of obj1.
for track in tracks:
# Retrieves the full parameter ID (DescID) describing a parameter.
did = track.GetDescriptionID()
# If the Parameter ID of the current CTracks is not on the trackListToCopy we go to the next one.
if not did[0].id in trackListToCopy:
continue
# Find if our static object already got an animation track for this parameter ID.
foundTrack = fixedBox.FindCTrack(did)
if foundTrack:
# Removes the track if found.
doc.AddUndo(c4d.UNDOTYPE_DELETE, foundTrack)
foundTrack.Remove()
# Copies the initial CTrack in memory. All CCurve and CKey are kept in this CTrack.
clone = track.GetClone()
# Inserts the copied CTrack to the static object.
#fixedBox.InsertTrackSorted(clone)
doc.AddUndo(c4d.UNDOTYPE_NEW, clone)
# Ends the Undo Process.
doc.EndUndo()
# Updates fixedBox Geometry taking in account previously created keyframes
animateFlag = c4d.ANIMATEFLAGS_NONE if c4d.GetC4DVersion() > 20000 else c4d.ANIMATEFLAGS_0
doc.AnimateObject(fixedBox, doc.GetTime(), animateFlag)
# Pushes an update event to Cinema 4D
c4d.EventAdd()
if __name__ == "__main__":
main()