Cinema 4D - my Python scripts - copy object to other objects

From NoskeWiki
Jump to navigation Jump to search

About

NOTE: This page is a daughter page of: Cinema 4D


This page contains code for a Python script I've written for Cinema 4D. To understand how it compiles see Cinema 4D - my Python scripts.

copy_object_to_other_objects.py

copy_object_to_other_objects.py

# Takes a set of objects and lets you specify the name of
# the object you wish to add as the parent or child of each
# of the other selected objects.

import c4d
import time
from c4d import gui

# Unique id numbers for each of the GUI elements:
LBL_USAGE = 1000
GROUP_TEXT = 10000
LBL_INFO1 = 10001
TXT_OBJ_TO_COPY = 10002
LBL_INFO2 = 10003
LBL_NUM_OBJS = 10004
RADIO_GROUP = 20000
RADIO_ADD_AS_PARENT = 20001
RADIO_ADD_AS_CHILD = 20002
GROUP_OPTIONS = 30000
BTN_OK = 30001
BTN_CANCEL = 30002

class OptionsDialog(gui.GeDialog):
  """ Dialog for adding a parent or child object to a set of selected objects.
  """
  def CreateLayout(self):
    self.SetTitle('Add Parent Or Child Object')
    self.AddMultiLineEditText(LBL_USAGE, c4d.BFH_SCALEFIT, inith=45, initw=500,
                              style=c4d.DR_MULTILINE_READONLY)
    self.SetString(LBL_USAGE,
        'USAGE: Of all objects selected, chose one to\n' +
        '    copy as a new child or parent of all others.')
    # Strings to add:
    self.GroupBegin(GROUP_TEXT, c4d.BFH_SCALEFIT, 2, 2)
    self.AddStaticText(LBL_INFO1, c4d.BFH_LEFT, name='Object name to copy:') 
    self.AddEditText(TXT_OBJ_TO_COPY, c4d.BFH_SCALEFIT)
    self.SetString(TXT_OBJ_TO_COPY, self.default_name)  # Default object to copy.
    self.AddStaticText(LBL_INFO2, c4d.BFH_LEFT, name='Number copies to make:') 
    self.AddStaticText(LBL_NUM_OBJS, c4d.BFH_SCALEFIT, name=self.num_objs)
    self.GroupEnd()
    self.AddSeparatorH(c4d.BFH_SCALE);
    # Radio Button Group - rename parent or children:
    self.AddRadioGroup(RADIO_GROUP, c4d.BFH_LEFT, 1, 1)
    self.AddChild(RADIO_GROUP, RADIO_ADD_AS_PARENT,
                  'Add as new parent')
    self.AddChild(RADIO_GROUP, RADIO_ADD_AS_CHILD,
                  'Add as new child')
    self.SetBool(RADIO_ADD_AS_PARENT, True)  # Set first radio button on.
    self.GroupEnd()
    self.AddSeparatorH(c4d.BFH_SCALE);
    # Buttons - an Ok and Cancel button:
    self.GroupBegin(GROUP_OPTIONS, c4d.BFH_CENTER, 2, 1)
    self.AddButton(BTN_OK, c4d.BFH_SCALE, name='Ok')
    self.AddButton(BTN_CANCEL, c4d.BFH_SCALE, name='Cancel')
    self.GroupEnd()
    self.ok = False
    return True
  
  # React to user's input:
  def Command(self, id, msg):
    if id==BTN_CANCEL:
      self.Close()
    elif id==BTN_OK:
      self.ok = True
      self.option_obj_name_to_copy = self.GetString(TXT_OBJ_TO_COPY)
      self.option_add_as_child = self.GetBool(RADIO_ADD_AS_CHILD)
      self.Close()
    return True
    

def main():
  selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER)
  if len(selection) <= 1:
    gui.MessageDialog('Start by selecting the object to copy, plus all ' +
                      'the object to copy to.')
    return

  # Open non-modal options dialogue to let users copy objects.
  dlg = OptionsDialog()
  dlg.default_name = selection[0].GetName()
  dlg.num_objs = len(selection) - 1
  dlg.Open(c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=50)
  if not dlg.ok:
    return

  obj_to_copy = None
  for j in range(0,len(selection)):
    if selection[j].GetName() == dlg.option_obj_name_to_copy:
      obj_to_copy = selection[j]
      selection.remove(obj_to_copy)
      break
  
  if obj_to_copy == None:
    gui.MessageDialog('Could not find an object called ' +
        dlg.option_obj_name_to_copy + ' in selected objects.')
    return
  
  doc.StartUndo()
  for i in range(0,len(selection)):
    obj = selection[i]
    new_obj = obj_to_copy.GetClone()
    if dlg.option_add_as_child:
      doc.InsertObject(new_obj, parent=obj)
      doc.AddUndo(c4d.UNDOTYPE_NEW, new_obj)  # Added after add.
    else:
      doc.InsertObject(new_obj, pred=obj)
      doc.AddUndo(c4d.UNDOTYPE_NEW, new_obj)  # Added after add.
      doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
      obj.Remove()
      doc.InsertObject(obj,parent=new_obj)
  doc.EndUndo()
  c4d.EventAdd()  # Show updated changes.
  
  gui.MessageDialog(str(len(selection)) + ' objects were added')

if __name__=='__main__':
  main()


See Also


Code license
For all of the code on my site... if there are specific instruction or licence comments please leave them in. If you copy my code with minimum modifications to another webpage, or into any code other people will see I would love an acknowledgment to my site.... otherwise, the license for this code is more-or-less WTFPL (do what you want)! If only copying <20 lines, then don't bother. That said - if you'd like to add a web-link to my site www.andrewnoske.com or (better yet) the specific page with code, that's a really sweet gestures! Links to the page may be useful to yourself or your users and helps increase traffic to my site. Hope my code is useful! :)