Cinema 4D - my Python script - find replace object names

From NoskeWiki
Jump to navigation Jump to search


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. There is a simpler version of this renamer code (one which doesn't use regex) in the example at Cinema 4D - Python scripts.

# Does a Find/Replace on object names over all selected object
# using Regular Expressions.
import c4d
from c4d import gui
import re  # Regular expression

# Unique id numbers for each of the GUI elements
LBL_USAGE = 1000
LBL_INFO1 = 1001
LBL_INFO2 = 1002
GROUP_TEXT = 10000
TXT_FIND = 10001
BTN_OK = 20001
BTN_CANCEL = 20002

class OptionsDialog(gui.GeDialog):
  """ Dialog for doing a find replace on object names.
  def CreateLayout(self):
    self.SetTitle('Find and Replace Object Names')
    self.AddMultiLineEditText(LBL_USAGE, c4d.BFH_SCALEFIT, inith=40, initw=500,
        "USAGE: Does find/replace on selected object names\n"
        "   using regular expression")
    # Find replace strings:
    self.GroupBegin(GROUP_TEXT, c4d.BFH_SCALEFIT, 2, 2)
    self.AddStaticText(LBL_INFO1, c4d.BFH_LEFT, name='Find:') 
    self.AddEditText(TXT_FIND, c4d.BFH_SCALEFIT)
    self.SetString(TXT_FIND, 'Cap1')
    self.AddStaticText(LBL_INFO2, c4d.BFH_LEFT, name='Replace with:') 
    self.AddEditText(TXT_REPLACE, c4d.BFH_SCALEFIT)
    self.SetString(TXT_REPLACE, 'Floor')
    # Checkbox Option - append to existing string:
    self.AddCheckbox(CHK_MATCH_CASE, c4d.BFH_SCALEFIT,
                     initw=1, inith=1, name="match case")
    self.SetBool(CHK_MATCH_CASE, True)   
    # 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.ok = False
    return True
  # React to user's input:
  def Command(self, id, msg):
    if id==BTN_CANCEL:
    elif id==BTN_OK:
      self.ok = True
      self.option_find = self.GetString(TXT_FIND)
      self.option_replace = self.GetString(TXT_REPLACE)
      self.option_match_case = self.GetBool(CHK_MATCH_CASE)
    return True
def main():
  # Get the selected objects, including children.
  selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
  if len(selection) <= 0:
    gui.MessageDialog('Must select objects!')
  # 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:
  # Setup regex find pattern:
  pattern = re.compile(dlg.option_find, flags=re.IGNORECASE)
  if (dlg.option_match_case):
    pattern = re.compile(dlg.option_find)
  num_renamed = 0
  for i in range(0,len(selection)):
    sel = selection[i]
    new_name = pattern.sub(dlg.option_replace, sel.GetName())
    if (sel.GetName() != new_name):
      print ' - ' + sel.GetName() + ' > ' + new_name
      doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, sel)
      num_renamed += 1
  c4d.EventAdd()  # Update C4D to see changes.
  gui.MessageDialog(str(num_renamed) + ' of ' + str(len(selection)) +
                    ' objects renamed')
if __name__=='__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 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! :)