如何用Python从存储列表批量分配Blender修改器参数值?
如何通过循环批量赋值Blender修改器参数?
问题描述
我正在编写脚本,用于将FBX文件重新导入Blender场景并重建原模型上的所有修改器,但在重新分配旧修改器的参数值时遇到了问题。
脚本会先记录重新导入前模型上所有修改器的参数值并存储到列表中。当新模型导入后,脚本会创建新修改器并尝试从列表中分配存储的参数值,但在此步骤受阻。
显式分配参数值的Python代码很简单,示例如下:
yourobjectname = "Cube" #for example numberofsubdivisions = 3 #for example bpy.data.objects[yourobjectname].modifiers["Subsurf"].levels = numberofsubdivisions
但尝试如下循环赋值时:
for n, param in enumerate(dir(modifier)): stored_value = stored_param_values[n] modifier.param = stored_value
会报错:modifier object has no property "param"。
请问如何在不逐一显式调用参数的情况下,通过循环正确访问修改器参数并修改其值?
解决方案
你遇到的核心问题有两个:
dir(modifier)会返回对象的所有属性名称,包括Blender内部的私有属性(比如以__开头的)和只读属性,这些属性不能被直接赋值。- 循环里的
modifier.param是在访问名为param的固定属性,而非遍历到的字符串变量param对应的实际参数,属于Python变量名和属性名的混淆。
正确实现步骤
1. 筛选可编辑的参数
Blender的修改器属于bpy.types.PropertyGroup类,可通过bl_rna.properties获取所有可编辑的用户参数,过滤掉只读和内部属性:
# 获取修改器的所有可编辑属性名 editable_params = [prop.identifier for prop in modifier.bl_rna.properties if not prop.is_readonly]
2. 用getattr和setattr动态操作属性
Python内置的getattr(obj, attr_name)可以通过字符串获取对象属性,setattr(obj, attr_name, value)可以通过字符串设置属性值,替换你原来的循环逻辑:
# 假设stored_params是键为参数名、值为存储值的字典(推荐用字典避免顺序不匹配) for param_name in editable_params: if param_name in stored_params: setattr(modifier, param_name, stored_params[param_name])
优化建议:用字典存储参数
列表存储参数值容易因为参数顺序不匹配导致赋值错误,建议记录参数时直接用字典:
# 记录旧修改器参数的示例 old_modifier = bpy.data.objects["OldCube"].modifiers["Subsurf"] stored_params = {} for prop in old_modifier.bl_rna.properties: if not prop.is_readonly and not prop.identifier.startswith("_"): stored_params[prop.identifier] = getattr(old_modifier, prop.identifier)
完整示例代码
import bpy # 1. 记录旧模型的所有修改器及参数 old_obj = bpy.data.objects["OldCube"] modifier_data = [] for mod in old_obj.modifiers: params = {} # 遍历并筛选可编辑参数 for prop in mod.bl_rna.properties: if not prop.is_readonly and not prop.identifier.startswith("_"): params[prop.identifier] = getattr(mod, prop.identifier) modifier_data.append({ "type": mod.type, "name": mod.name, "params": params }) # 2. 导入新FBX(此处假设已完成导入,新对象为new_obj) new_obj = bpy.data.objects["NewCube"] # 3. 重建修改器并批量赋值参数 for mod_info in modifier_data: new_mod = new_obj.modifiers.new(name=mod_info["name"], type=mod_info["type"]) for param_name, value in mod_info["params"].items(): try: setattr(new_mod, param_name, value) except AttributeError: # 部分参数可能因版本或修改器类型差异不可用,直接跳过 print(f"无法设置参数 {param_name},已跳过")
内容的提问来源于stack exchange,提问作者Knkemora
相关产品推荐
相关产品推荐

