这是一个Cinema 4D的Python脚本,可以实现批量重命名对象的功能。这个脚本包含序列号重命名、自定义重命名和字符替换功能。使用说明: 1. 安装使用: 将脚本保存为 .py 文件 在 Cinema 4D 中通过 脚本 → 用户脚本 → 加载脚本 来运行 2. 功能介绍: 序列号重命名: 可以设置前缀(如"对象_") 可以设置起始序号 会自动生成 对象_001、对象_002 这样的名称 自定义重命名: 输入新的名称 如果选择多个对象,会自动添加序号 字符替换: 输入要替换的文字(如广告内容) 输入替换成的文字 会在所有对象名称中进行查找替换 3. 操作选项: 重命名所有对象:处理场景中的所有对象 重命名选中对象:只处理当前选中的对象(包括子对象) 4. 安全特性: 支持撤销操作(Ctrl+Z) 操作前会提示确认 显示处理结果统计 这个脚本应该能够很好地解决你遇到的广告名称问题,你可以根据需要选择合适的重命名方式。 脚本代码: - # -*- coding: utf-8 -*-
- """
- Cinema 4D 批量重命名工具
- 支持序列号重命名、自定义重命名和字符替换
- """
- import c4d
- from c4d import gui
- # 全局变量定义
- DIALOG_ID = 1000
- GROUP_MAIN = 2000
- GROUP_BUTTONS = 2001
- GROUP_RADIO = 2002 # 单选按钮组
- # 控件ID
- RADIO_SEQUENCE = 3001 # 序列号重命名
- RADIO_CUSTOM = 3002 # 自定义重命名
- RADIO_REPLACE = 3003 # 字符替换
- EDIT_PREFIX = 4001 # 前缀输入框
- EDIT_START_NUM = 4002 # 起始序号
- EDIT_CUSTOM_NAME = 4003 # 自定义名称
- EDIT_OLD_TEXT = 4004 # 要替换的文字
- EDIT_NEW_TEXT = 4005 # 替换成的文字
- BTN_RENAME_ALL = 5001 # 重命名所有对象
- BTN_RENAME_SELECTED = 5002 # 重命名选中对象
- BTN_CANCEL = 5003 # 取消按钮
- class RenameDialog(gui.GeDialog):
- """重命名对话框类"""
-
- def CreateLayout(self):
- """创建对话框布局"""
- self.SetTitle("批量重命名工具")
-
- # 主要分组
- self.GroupBegin(GROUP_MAIN, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 1, 0)
- self.GroupBorderSpace(10, 10, 10, 10)
-
- # 重命名方式选择标题
- self.AddStaticText(0, c4d.BFH_LEFT, 0, 0, "选择重命名方式:", 0)
- self.AddSeparatorH(0, c4d.BFH_SCALEFIT)
-
- # 单选按钮组 - 确保互斥
- self.GroupBegin(GROUP_RADIO, c4d.BFH_SCALEFIT, 1, 0)
-
- # 方式1:序列号重命名
- self.AddRadioButton(RADIO_SEQUENCE, c4d.BFH_LEFT, 0, 0, "1. 序列号重命名")
-
- # 序列号重命名的参数
- self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0)
- self.GroupBorderSpace(20, 5, 10, 5)
- self.AddStaticText(0, c4d.BFH_LEFT, 60, 0, "前缀:", 0)
- self.AddEditText(EDIT_PREFIX, c4d.BFH_SCALEFIT, 150, 0)
- self.AddStaticText(0, c4d.BFH_LEFT, 60, 0, "起始序号:", 0)
- self.AddEditNumberArrows(EDIT_START_NUM, c4d.BFH_LEFT, 80, 0)
- self.GroupEnd()
-
- # 分隔线
- self.AddSeparatorH(0, c4d.BFH_SCALEFIT)
-
- # 方式2:自定义重命名
- self.AddRadioButton(RADIO_CUSTOM, c4d.BFH_LEFT, 0, 0, "2. 自定义重命名")
-
- # 自定义重命名的参数
- self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0)
- self.GroupBorderSpace(20, 5, 10, 5)
- self.AddStaticText(0, c4d.BFH_LEFT, 60, 0, "新名称:", 0)
- self.AddEditText(EDIT_CUSTOM_NAME, c4d.BFH_SCALEFIT, 150, 0)
- self.AddStaticText(0, c4d.BFH_LEFT, 0, 0, "注意:多个对象会自动添加序号", 0)
- self.GroupEnd()
-
- # 分隔线
- self.AddSeparatorH(0, c4d.BFH_SCALEFIT)
-
- # 方式3:字符替换
- self.AddRadioButton(RADIO_REPLACE, c4d.BFH_LEFT, 0, 0, "3. 字符替换")
-
- # 字符替换的参数
- self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0)
- self.GroupBorderSpace(20, 5, 10, 5)
- self.AddStaticText(0, c4d.BFH_LEFT, 80, 0, "要替换的文字:", 0)
- self.AddEditText(EDIT_OLD_TEXT, c4d.BFH_SCALEFIT, 150, 0)
- self.AddStaticText(0, c4d.BFH_LEFT, 80, 0, "替换成:", 0)
- self.AddEditText(EDIT_NEW_TEXT, c4d.BFH_SCALEFIT, 150, 0)
- self.AddStaticText(0, c4d.BFH_LEFT, 0, 0, "注意:仅替换包含指定文字的对象名称", 0)
- self.GroupEnd()
-
- self.GroupEnd() # 结束单选按钮组
- self.GroupEnd() # 结束主分组
-
- # 分隔线
- self.AddSeparatorH(0, c4d.BFH_SCALEFIT)
-
- # 按钮组
- self.GroupBegin(GROUP_BUTTONS, c4d.BFH_CENTER, 3, 1)
- self.AddButton(BTN_RENAME_ALL, c4d.BFH_LEFT, 120, 0, "处理所有对象")
- self.AddButton(BTN_RENAME_SELECTED, c4d.BFH_LEFT, 120, 0, "处理选中对象")
- self.AddButton(BTN_CANCEL, c4d.BFH_LEFT, 80, 0, "取消")
- self.GroupEnd()
-
- return True
-
- def InitValues(self):
- """初始化控件值"""
- # 设置单选按钮组 - 默认选择序列号重命名
- self.SetBool(RADIO_SEQUENCE, True)
- self.SetBool(RADIO_CUSTOM, False)
- self.SetBool(RADIO_REPLACE, False)
-
- # 设置默认值
- self.SetString(EDIT_PREFIX, "对象_")
- self.SetInt32(EDIT_START_NUM, 1)
- self.SetString(EDIT_CUSTOM_NAME, "新对象")
- self.SetString(EDIT_OLD_TEXT, "")
- self.SetString(EDIT_NEW_TEXT, "")
-
- return True
-
- def Command(self, id, msg):
- """处理命令事件"""
- # 处理单选按钮互斥
- if id == RADIO_SEQUENCE:
- self.SetBool(RADIO_SEQUENCE, True)
- self.SetBool(RADIO_CUSTOM, False)
- self.SetBool(RADIO_REPLACE, False)
-
- elif id == RADIO_CUSTOM:
- self.SetBool(RADIO_SEQUENCE, False)
- self.SetBool(RADIO_CUSTOM, True)
- self.SetBool(RADIO_REPLACE, False)
-
- elif id == RADIO_REPLACE:
- self.SetBool(RADIO_SEQUENCE, False)
- self.SetBool(RADIO_CUSTOM, False)
- self.SetBool(RADIO_REPLACE, True)
-
- # 处理按钮点击
- elif id == BTN_RENAME_ALL:
- self.ProcessObjects(False) # 处理所有对象
-
- elif id == BTN_RENAME_SELECTED:
- self.ProcessObjects(True) # 处理选中对象
-
- elif id == BTN_CANCEL:
- self.Close()
-
- return True
-
- def ProcessObjects(self, selected_only):
- """处理对象 - 根据选择的模式执行不同操作"""
- doc = c4d.documents.GetActiveDocument()
- if not doc:
- gui.MessageDialog("没有活动的文档!")
- return
-
- # 获取要处理的对象列表
- if selected_only:
- objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
- if not objects:
- gui.MessageDialog("请先选择要处理的对象!")
- return
- scope_text = "选中"
- else:
- objects = self.GetAllObjects(doc.GetFirstObject())
- scope_text = "所有"
-
- if not objects:
- gui.MessageDialog("没有找到可处理的对象!")
- return
-
- # 开始撤销记录
- doc.StartUndo()
-
- try:
- # 根据选择的重命名方式进行处理
- if self.GetBool(RADIO_SEQUENCE):
- processed_count = self.RenameWithSequence(objects, doc)
- operation_text = "重命名"
- elif self.GetBool(RADIO_CUSTOM):
- processed_count = self.RenameWithCustomName(objects, doc)
- operation_text = "重命名"
- elif self.GetBool(RADIO_REPLACE):
- processed_count = self.ReplaceInObjects(objects, doc)
- operation_text = "替换"
- else:
- gui.MessageDialog("请选择一种处理方式!")
- doc.EndUndo()
- return
-
- # 结束撤销记录
- doc.EndUndo()
-
- # 刷新视图
- c4d.EventAdd()
-
- # 显示结果
- if processed_count > 0:
- gui.MessageDialog(f"成功{operation_text}了 {processed_count} 个对象!\n(从{scope_text}{len(objects)}个对象中筛选)")
- else:
- if self.GetBool(RADIO_REPLACE):
- old_text = self.GetString(EDIT_OLD_TEXT)
- gui.MessageDialog(f"在{scope_text}{len(objects)}个对象中没有找到包含'{old_text}'的对象名称!")
- else:
- gui.MessageDialog("没有对象需要处理!")
-
- except Exception as e:
- doc.EndUndo()
- gui.MessageDialog(f"处理过程中出现错误:{str(e)}")
-
- def GetAllObjects(self, obj):
- """递归获取所有对象"""
- objects = []
- while obj:
- objects.append(obj)
- # 递归获取子对象
- if obj.GetDown():
- objects.extend(self.GetAllObjects(obj.GetDown()))
- obj = obj.GetNext()
- return objects
-
- def RenameWithSequence(self, objects, doc):
- """使用序列号重命名 - 重命名所有传入的对象"""
- prefix = self.GetString(EDIT_PREFIX)
- start_num = self.GetInt32(EDIT_START_NUM)
-
- processed_count = 0
- for i, obj in enumerate(objects):
- doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
- new_name = f"{prefix}{start_num + i:03d}"
- obj.SetName(new_name)
- processed_count += 1
-
- return processed_count
-
- def RenameWithCustomName(self, objects, doc):
- """使用自定义名称重命名 - 重命名所有传入的对象"""
- custom_name = self.GetString(EDIT_CUSTOM_NAME)
-
- if not custom_name.strip():
- gui.MessageDialog("请输入自定义名称!")
- return 0
-
- processed_count = 0
- if len(objects) == 1:
- # 只有一个对象时直接使用自定义名称
- doc.AddUndo(c4d.UNDOTYPE_CHANGE, objects[0])
- objects[0].SetName(custom_name)
- processed_count = 1
- else:
- # 多个对象时添加序号
- for i, obj in enumerate(objects):
- doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
- new_name = f"{custom_name}_{i + 1:03d}"
- obj.SetName(new_name)
- processed_count += 1
-
- return processed_count
-
- def ReplaceInObjects(self, objects, doc):
- """字符替换功能 - 只替换包含指定字符的对象"""
- old_text = self.GetString(EDIT_OLD_TEXT)
- new_text = self.GetString(EDIT_NEW_TEXT)
-
- if not old_text.strip():
- gui.MessageDialog("请输入要替换的文字!")
- return 0
-
- processed_count = 0
-
- # 扫描所有对象,只处理包含指定文字的对象
- for obj in objects:
- current_name = obj.GetName()
- if old_text in current_name:
- doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
- new_name = current_name.replace(old_text, new_text)
- obj.SetName(new_name)
- processed_count += 1
- # 可以添加调试信息
- print(f"替换: '{current_name}' -> '{new_name}'")
-
- return processed_count
- def main():
- """主函数"""
- dialog = RenameDialog()
- dialog.Open(c4d.DLG_TYPE_MODAL, defaultw=400, defaulth=500)
- if __name__ == '__main__':
- main()
复制代码 | |
Comment :1