Cinema 4D - my Python scripts - object parent child renamer

From NoskeWiki
Jump to: navigation, 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.

object_parent_child_renamer.py

object_parent_child_renamer.py

# Script for renaming objects using the name of their immediate first child
# or immediate parent.
 
import c4d
from c4d import gui
 
# Unique id numbers for each of the GUI elements:
LBL_USAGE = 1000
LBL_INFO1 = 1002
LBL_INFO2 = 1003
LBL_INFO3 = 1004
LBL_DUMMY1 = 1000
GROUP_TEXT = 10000
TXT_PREFIX = 10001
TXT_POSTFIX = 10002
CHK_APPEND_TO_EXISTING = 10003
RADIO_GROUP = 20000
RADIO_RENAME_PARENTS = 20001
RADIO_RENAME_CHILREN = 20002
GROUP_OPTIONS = 30000
BTN_OK = 30001
BTN_CANCEL = 30002
 
class OptionsDialog(gui.GeDialog):
  """ Dialog for renaming objects based on the name of the child or parent.
  """
  def CreateLayout(self):
    self.SetTitle('Object Parent Child Renamer')
    self.AddMultiLineEditText(LBL_USAGE, c4d.BFH_SCALEFIT, inith=45, initw=500,
                              style=c4d.DR_MULTILINE_READONLY)
    self.SetString(LBL_USAGE,
        'USAGE: For all parent objects selected, renames\n' +
        '    them using the name of their first child or\n' +
        '    renames all their children using the parent name.')
    # Radio Button Group - rename parent or children:
    self.AddRadioGroup(RADIO_GROUP, c4d.BFH_LEFT, 1, 1)
    self.AddChild(RADIO_GROUP, RADIO_RENAME_PARENTS,
                  'Rename parent using first child name')
    self.AddChild(RADIO_GROUP, RADIO_RENAME_CHILREN,
                  'Rename children to parents name')
    self.SetBool(RADIO_RENAME_PARENTS, True)  # Set first radio button on.
    self.GroupEnd()
    self.AddSeparatorH(c4d.BFH_SCALE);
    # Checkbox Option - append to existing string:
    self.AddCheckbox(CHK_APPEND_TO_EXISTING, c4d.BFH_SCALEFIT,
                     initw=1, inith=1, name='append to existing name')
    self.AddSeparatorH(c4d.BFH_SCALE);
    # Strings to add:
    self.GroupBegin(GROUP_TEXT, c4d.BFH_SCALEFIT, 2, 3)
    self.AddStaticText(LBL_INFO1, c4d.BFH_SCALEFIT, name='Add extra text:') 
    self.AddStaticText(LBL_DUMMY1, c4d.BFH_SCALEFIT, name='')  # Fill space.
    self.AddStaticText(LBL_INFO2, c4d.BFH_LEFT, name='  prefix:') 
    self.AddEditText(TXT_PREFIX, c4d.BFH_SCALEFIT)
    self.SetString(TXT_PREFIX, '')  # Default 'prefix' string.
    self.AddStaticText(LBL_INFO3, c4d.BFH_LEFT, name='  postfix:') 
    self.AddEditText(TXT_POSTFIX, c4d.BFH_SCALEFIT)
    self.SetString(TXT_POSTFIX, '')  # Default 'postfix' string.
    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_rename_parents = self.GetBool(RADIO_RENAME_PARENTS)
      self.option_rename_children = self.GetBool(RADIO_RENAME_CHILREN)
      self.option_append = self.GetBool(CHK_APPEND_TO_EXISTING)
      self.option_prefix = self.GetString(TXT_PREFIX)
      self.option_postfix = self.GetString(TXT_POSTFIX)
      self.Close()
    return True
 
 
def rename_obj_to_match_object(obj_to, obj_from, prefix, postfix, append):
  """Renames 'obj_to' to match 'obj_from'.
 
  Args:
    obj_to: Object to rename.
    obj_from: Object with the name we want to use.
    prefix: String to append to start of new name.
    postfix: String to appent to end of new name.
    append: Boolean set true if we want to append to existing name.
 
  Returns:
    1 if object was renamed, else 0.
  """
  if (obj_to == None or obj_from == None):
    return 0;
  new_name = prefix + obj_from.GetName() + postfix
  if append:
    new_name = obj_to.GetName() + new_name
  if (obj_to.GetName() != new_name):
    print ' - ' + obj_to.GetName() + ' > ' + new_name
    doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, obj_to)
    obj_to.SetName(new_name)
    return 1
  return 0;
 
 
def main():
  # Get the selected objects, without children.
  selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER)
 
  if len(selection) <= 0:
    gui.MessageDialog('Must select objects!')
    return
 
  # Open the options dialogue to let users choose their options.
  dlg = OptionsDialog()
  dlg.Open(c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=50)
  if not dlg.ok:
    return
 
  doc.StartUndo()  # Start undo block.
  num_renamed = 0
  num_children = 0
  num_parents = len(selection)
  for i in range(0,len(selection)):
    parent = selection[i]
    child = selection[i].GetDown()
 
    if(dlg.option_rename_parents):
      num_renamed += rename_obj_to_match_object(parent, child,
          dlg.option_prefix, dlg.option_postfix, dlg.option_append)
 
    if(dlg.option_rename_children):
      while (child != None):
        num_renamed += rename_obj_to_match_object(parent, child,
            dlg.option_prefix, dlg.option_postfix, dlg.option_append)
        child = child.GetNext()
        num_children += 1
  doc.EndUndo()   # End undo block.
  c4d.EventAdd()  # Update C4D to see changes.
 
  if dlg.option_rename_parents:
    gui.MessageDialog(str(num_renamed) + ' of ' + str(num_parents) +
                      ' parent objects renamed (to match first child)')
  elif dlg.option_rename_children:
    gui.MessageDialog(str(num_renamed) + ' of ' + str(num_children) +
                      ' immediate children renamed over ' +
                      str(num_parents) + ' parents searched')
 
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!  :)