c4d 2023+一键删除对象材质标签脚本
一键删除打开模型中所有的对象后面材质标签脚本,脚本是为针对C4D 2023版本写的,其它版本没有测试,理论上来讲是向上向下兼容的,如果想在其它版本中使用,可以联系我。
1.下面这个版本就是只删除材质标签的脚本
import c4d
from c4d import gui
def remove_material_tags_from_object(obj):
"""递归删除对象及其子对象上的所有材质标签"""
if not obj:
return 0
removed_count = 0
# 获取对象的所有标签
tag = obj.GetFirstTag()
while tag:
next_tag = tag.GetNext() # 先获取下一个标签,因为当前标签可能会被删除
# 检查是否是材质标签
if tag.GetType() == c4d.Ttexture:
doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
tag.Remove()
removed_count += 1
tag = next_tag
# 递归处理子对象
child = obj.GetDown()
while child:
removed_count += remove_material_tags_from_object(child)
child = child.GetNext()
return removed_count
def main():
# 获取当前文档
global doc
doc = c4d.documents.GetActiveDocument()
if not doc:
gui.MessageDialog("没有找到活动文档")
return
# 开始撤销记录
doc.StartUndo()
total_removed = 0
# 获取场景中的所有顶级对象
obj = doc.GetFirstObject()
while obj:
total_removed += remove_material_tags_from_object(obj)
obj = obj.GetNext()
# 结束撤销记录
doc.EndUndo()
# 更新文档
c4d.EventAdd()
# 显示完成消息
if total_removed > 0:
gui.MessageDialog(f"成功删除了 {total_removed} 个材质标签")
else:
gui.MessageDialog("没有找到任何材质标签")
if __name__ == '__main__':
main()2.如果您只想删除选中对象的材质标签,可以使用这个版本:
import c4d
from c4d import gui
def remove_material_tags_from_object(obj):
"""递归删除对象及其子对象上的所有材质标签"""
if not obj:
return 0
removed_count = 0
# 获取对象的所有标签
tag = obj.GetFirstTag()
while tag:
next_tag = tag.GetNext()
# 检查是否是材质标签
if tag.GetType() == c4d.Ttexture:
doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
tag.Remove()
removed_count += 1
tag = next_tag
# 递归处理子对象
child = obj.GetDown()
while child:
removed_count += remove_material_tags_from_object(child)
child = child.GetNext()
return removed_count
def main():
# 获取当前文档
global doc
doc = c4d.documents.GetActiveDocument()
if not doc:
gui.MessageDialog("没有找到活动文档")
return
# 获取选中的对象
selected_objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
if not selected_objects:
gui.MessageDialog("请先选择要删除材质标签的对象")
return
# 开始撤销记录
doc.StartUndo()
total_removed = 0
# 处理所有选中的对象
for obj in selected_objects:
total_removed += remove_material_tags_from_object(obj)
# 结束撤销记录
doc.EndUndo()
# 更新文档
c4d.EventAdd()
# 显示完成消息
if total_removed > 0:
gui.MessageDialog(f"成功删除了 {total_removed} 个材质标签")
else:
gui.MessageDialog("选中的对象上没有找到任何材质标签")
if __name__ == '__main__':
main()3.还可以扩展以下功能:群组,并将群组重命名的脚本
import c4d
from c4d import gui
class GroupNameDialog(gui.GeDialog):
"""群组名称选择对话框"""
# 控件ID
ID_COMBO_NAMES = 1000
ID_EDIT_CUSTOM = 1001
ID_BTN_OK = 1002
ID_BTN_CANCEL = 1003
def __init__(self):
self.group_name = None # 默认为None,表示未选择
def CreateLayout(self):
"""创建对话框布局"""
self.SetTitle("选择群组名称")
# 主要布局
self.GroupBegin(0, c4d.BFH_SCALEFIT, 1, 0)
self.GroupBorderSpace(15, 15, 15, 15)
# 标题
self.AddStaticText(0, c4d.BFH_LEFT, name="请选择群组名称:")
self.AddSeparatorH(0)
# 下拉选择框
self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0)
self.AddStaticText(0, c4d.BFH_LEFT, name="预设名称:")
self.AddComboBox(self.ID_COMBO_NAMES, c4d.BFH_SCALEFIT)
self.GroupEnd()
# 自定义输入框
self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0)
self.AddStaticText(0, c4d.BFH_LEFT, name="自定义名称:")
self.AddEditText(self.ID_EDIT_CUSTOM, c4d.BFH_SCALEFIT)
self.GroupEnd()
# 说明文字
self.AddSeparatorH(0)
self.AddStaticText(0, c4d.BFH_LEFT, name="提示:选择预设名称或输入自定义名称")
self.AddStaticText(0, c4d.BFH_LEFT, name="如果两者都有内容,将优先使用自定义名称")
self.AddSeparatorH(0)
# 按钮
self.GroupBegin(0, c4d.BFH_CENTER, 2, 0)
self.AddButton(self.ID_BTN_OK, c4d.BFH_LEFT, name="确定")
self.AddButton(self.ID_BTN_CANCEL, c4d.BFH_LEFT, name="取消")
self.GroupEnd()
self.GroupEnd()
return True
def InitValues(self):
"""初始化控件值"""
# 添加下拉选项
self.AddChild(self.ID_COMBO_NAMES, 0, "请选择...")
self.AddChild(self.ID_COMBO_NAMES, 1, "c4d.cn")
self.AddChild(self.ID_COMBO_NAMES, 2, "c4d.com")
self.AddChild(self.ID_COMBO_NAMES, 3, "pic.net")
self.AddChild(self.ID_COMBO_NAMES, 4, "c4d.net")
# 设置默认选择
self.SetLong(self.ID_COMBO_NAMES, 0) # 默认选择"请选择..."
self.SetString(self.ID_EDIT_CUSTOM, "")
return True
def Command(self, id, msg):
"""处理控件事件"""
if id == self.ID_BTN_OK:
# 确定按钮
custom_name = self.GetString(self.ID_EDIT_CUSTOM).strip()
combo_selection = self.GetLong(self.ID_COMBO_NAMES)
# 优先使用自定义名称
if custom_name:
self.group_name = custom_name
elif combo_selection > 0: # 0是"请选择..."
preset_names = ["", "c4d.cn", "c4d.com", "pic.net", "c4d.net"]
self.group_name = preset_names[combo_selection]
else:
gui.MessageDialog("请选择预设名称或输入自定义名称")
return True
self.Close()
elif id == self.ID_BTN_CANCEL:
# 取消按钮
self.group_name = None
self.Close()
return True
def remove_material_tags_from_object(obj, doc):
"""递归删除对象及其子对象上的所有材质标签"""
if not obj:
return 0
removed_count = 0
# 获取对象的所有标签
tag = obj.GetFirstTag()
while tag:
next_tag = tag.GetNext()
# 检查是否是材质标签
if tag.GetType() == c4d.Ttexture:
doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
tag.Remove()
removed_count += 1
tag = next_tag
# 递归处理子对象
child = obj.GetDown()
while child:
removed_count += remove_material_tags_from_object(child, doc)
child = child.GetNext()
return removed_count
def create_group_with_all_objects(doc, group_name):
"""创建群组并将所有对象放入其中"""
# 获取所有顶级对象
objects = []
obj = doc.GetFirstObject()
while obj:
objects.append(obj)
obj = obj.GetNext()
if not objects:
return None
# 创建空对象作为群组
group = c4d.BaseObject(c4d.Onull)
group.SetName(group_name)
# 将群组插入到文档中
doc.InsertObject(group)
doc.AddUndo(c4d.UNDOTYPE_NEW, group)
# 将所有对象移动到群组下
for obj in objects:
doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
obj.Remove()
obj.InsertUnder(group)
return group
def main():
# 获取当前文档
doc = c4d.documents.GetActiveDocument()
if not doc:
gui.MessageDialog("没有找到活动文档")
return
# 显示群组名称选择对话框
dialog = GroupNameDialog()
dialog.Open(c4d.DLG_TYPE_MODAL)
if dialog.group_name is None:
# 用户取消了操作
gui.MessageDialog("操作已取消")
return
# 开始撤销记录
doc.StartUndo()
# 第一步:删除所有材质标签
total_removed = 0
obj = doc.GetFirstObject()
while obj:
total_removed += remove_material_tags_from_object(obj, doc)
obj = obj.GetNext()
# 第二步:创建群组并移动所有对象
group = create_group_with_all_objects(doc, dialog.group_name)
# 结束撤销记录
doc.EndUndo()
# 更新文档
c4d.EventAdd()
# 显示完成消息
message = f"操作完成!\n"
if total_removed > 0:
message += f"删除了 {total_removed} 个材质标签\n"
if group:
message += f"创建了群组 '{dialog.group_name}' 并移动了所有对象"
else:
message += "场景中没有对象需要分组"
gui.MessageDialog(message)
if __name__ == '__main__':
main()