Thank you Cairyn and Ferdinand again. This is all making much more sense now, I appreciate you helping me understand how to correctly set up a simple interface. I do need to spend more time just learning the fundamentals of Python.
Latest posts made by stereo_stan
-
RE: Add button to run a script
-
RE: Add button to run a script
One more question on this topic. I have tried to combine Cairyn's note on creating a button with the py-commanddata_dialogr13 script from Maxon github to create an async dialog.
For some reason, it will not add my button to the dialog-basically just trying to add buttons to the py-commanddata script. Do you have any possible suggestions on making something like this work? Basically would like an async dialog with buttons. Thank you for any advice.
""" Copyright: MAXON Computer GmbH Author: Maxime Adam Description: - Creates a Dialog which display 2 buttons OK and Cancel. Class/method highlighted: - c4d.plugins.CommandData - CommandData.Execute() - c4d.gui.GeDialog - GeDialog.CreateLayout() - GeDialog.Command() """ import c4d from c4d import gui # Be sure to use a unique ID obtained from www.plugincafe.com PLUGIN_ID = 1057171 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. self.AddButton(ID_BUTTON3, c4d.BFH_SCALEFIT, name="Jump into code") Args: messageId (int): The ID of the gadget that triggered the event. bc (c4d.BaseContainer): The original message container. Returns: bool: False if there was an error, otherwise True. """ # User click on Ok buttonG if messageId == c4d.DLG_OK: print("User Click on yep") return True if ID == ID_BUTTON3: print ("Button clicked") 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 Command(self, id, msg): if id == ID_BUTTON3: print ("Button clicked") return True class ExampleDialogCommand(c4d.plugins.CommandData): """Command Data class that holds the ExampleDialog instance.""" dialog = None def Execute(self, doc): """Called when the user executes a command via either CallCommand() or a click on the Command from the extension menu. Args: doc (c4d.documents.BaseDocument): The current active document. Returns: bool: True if the command success. """ # Creates the dialog if its not already exists if self.dialog is None: self.dialog = ExampleDialog() # Opens the dialog return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=400, defaulth=32) def RestoreLayout(self, sec_ref): """Used to restore an asynchronous dialog that has been placed in the users layout. Args: sec_ref (PyCObject): The data that needs to be passed to the dialog. Returns: bool: True if the restore success """ # Creates the dialog if its not already exists if self.dialog is None: self.dialog = ExampleDialog() # Restores the layout return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref) # main if __name__ == "__main__": # Registers the plugin c4d.plugins.RegisterCommandPlugin(id=PLUGIN_ID, str="Py-CommandData Dialog", info=0, help="Display a basic GUI", dat=ExampleDialogCommand(), icon=None)
-
RE: Add button to run a script
Thank you Cairyn and Ferdinand, this is all very helpful and I have a better understanding of different ways to approach this type of project.
Yes, I do not think I want to run an external script, just have one script that a user can perform a few different commands from. Essentially so they can just have one command icon ( script ) in their interface and when they click on that it opens up a GeDialog with a bunch of options they can run by clicking on buttons inside of the GeDialog vs having to click on a bunch of different scripts. I assume those buttons are essentially other scripts that are all bundled together that they would drop in their scripts folder.
I am so excited about all of the possibilities of adding programming into my daily work as a c4d animator-it is challenging to learn from a non-programming background but this forum has helped a lot.
Thanks again.
-
RE: Add button to run a script
Thank you. Yes, the goal is to be able to execute multiple commands in one plugin so I was trying to find a way to connect the GeDialog with some commands.
I am new to programming and I have read through the GeDialog documentation and I can not figure out a way to connect the two concepts.
Is there some example code that creates a few buttons that run some commands?
Thank you for your help, I appreciate it.
-
Add button to run a script
Hi everyone, I am trying to learn how to code python by modifying the maxon scripts.
I have this basic script working as a plugin. It makes the object editable and moves the anchor point. I am trying to figure out a way to make this work with a button click instead of just clicking on the script to run it.
Can you please help me get one or two buttons to work with this code? Thank you for any guidance!
import c4d
import osdef load_bitmap(path):
path = os.path.join(os.path.dirname(file), path)
bmp = c4d.bitmaps.BaseBitmap()
if bmp.InitWith(path)[0] != c4d.IMAGERESULT_OK:
bmp = None
return bmpimport c4d
from c4d import guiclass MakeEditableAnchor(c4d.plugins.CommandData):
PLUGIN_ID = 1058020 PLUGIN_NAME = 'MakeEditableAnchor' PLUGIN_INFO = 0 PLUGIN_ICON = load_bitmap('res/icons/makeeditableanchor.jpg') PLUGIN_HELP = '' def Register(self): return c4d.plugins.RegisterCommandPlugin( self.PLUGIN_ID, self.PLUGIN_NAME, self.PLUGIN_INFO, self.PLUGIN_ICON, self.PLUGIN_HELP, self) def Execute(self, doc): gui.MessageDialog('Hello World!') c4d.CallCommand(12236) # Make Editable op = doc.GetActiveObject() #op = doc.SearchObject("obj1") ps = op.GetAllPoints() #Points in Local coordinates List m = op.GetMg() #Object Global Matrix center = op.GetMp() #Local coordinates center: https://tinyurl.com/wed88cn rad = op.GetRad() # Geometry radius: https://tinyurl.com/tb6vn64 center -= c4d.Vector(0,rad.y,0) #Move down axis to lowest point. Comment this line to keep axis in a center center *= m #Convert to Global coordinates center new_m = c4d.Matrix(m) #Copy matrix new_m.off = center #Change its center loc_m = ~new_m * m #Get local matrix op.SetAllPoints([loc_m.Mul(p) for p in ps]) op.SetMg(new_m) op.Message(c4d.MSG_UPDATE) c4d.EventAdd() # Execute main() return True
if name == 'main':
MakeEditableAnchor().Register() -
RE: Add a GUI button
Thank you Ferdinand, sorry for not posting correctly-I will work on making sure to understand the correct way to interact on the forum as I move forward.
-
Add a GUI button
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()