怎么批量修改c4d对象名称?

已解决 · 获得 3 积分
📁 分类: 其它相关问题 👤 提问者: 小图 🕒 2025-9-2 11:38 👁️ 浏览 140 次
打开一个网上下载的模型,全是广告和链接。有上百条对象名称是这样的,我想批量修改,但是手动一个一个修改太麻烦了,如何批量重命名?

全部回答 (1) 条)

c4dservice 2025-9-2 11:39
最佳答案
可以用我这个原创的脚本来实现,可以按序号重命名、可以指定名称、可以替换某些字段
复制脚本到C4D脚本管理器中,新建一个空白脚本,然后运行即可
# -*- 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()

参与回答

登录后即可回答问题,帮助他人解决疑惑

立即登录

相关问题推荐

c4d打开glb文件看不见材质是什么原因?
Money 已解决 · 获得 1 积分 2 回答
解压密码?
Money 悬赏 1 积分 2 回答
苹果主机的雷雳3/4口是不是 Type-c?
Money 已解决 · 获得 3 积分 1 回答
c4d默认渲染主要是用CPU还是GPU?
Money 已解决 · 获得 1 积分 1 回答
求一个系统的c4d中文教程
Money 已解决 · 获得 1 积分 1 回答
c4d 2026发布日期有了吗?
Money 已解决 · 获得 10 积分 1 回答
gfxcamp打不开了,提示无法访问此网站
Money 已解决 · 获得 1 积分 1 回答
c4d之家是哪年成立的?
Money 已解决 · 获得 10 积分 1 回答
救一套kb3d brutalist 2055
Money 悬赏 1 积分 1 回答
Money 更多其它相关问题 Home 返回问答首页
关闭

C4D精选推荐 /10

知识
问答
快速回复 返回顶部 返回列表