【转载】Blender Python 编程技巧

830 阅读3分钟

————————————————
版权声明:本文为CSDN博主「Linsoft1994」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:blog.csdn.net/Linsoft1994…

正文

Blender Python 编程技巧 整理自 docs.blender.org/

bpy.data

object 复制

ob = obj.copy() # duplicate linked(浅拷贝)
ob.data = obj.data.copy() # optional: make this a real duplicate (not linked)(深拷贝)
bpy.context.scene.objects.link(ob) # 添加到场景
ob.location.y += 5

object 数学变换

# 获取旋转四元数
ob.rotation_euler.to_quaternion()

文件读写

docs.blender.org/api/blender…

# 链接所有以 A 为开头的 object
# data_from 为原文件的数据,data_to 为选择加入当前文件的数据
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
    data_to.objects = [name for name in data_from.objects if name.startswith("A")]

# 复制所有 data 并进入当前 blend 文件
with bpy.data.libraries.load(filepath) as (data_from, data_to):
    for attr in dir(data_to):
        setattr(data_to, attr, getattr(data_from, attr))

# write selected objects and their data to a blend file
data_blocks = set(bpy.context.selected_objects)
bpy.data.libraries.write("./new_library.blend", data_blocks)

object 界面选中与取消

ob = bpy.data.objects[0]
ob.select_set(True) # add to selected list
bpy.context.scene.objects.active = ob # make ob active

# 选中所有
bpy.ops.object.select_all(action='SELECT')
# 取消所有选中
bpy.ops.object.select_all(action='DESELECT')

添加灯光

scene = bpy.context.scene

# Create new lamp datablock
lamp_data = bpy.data.lamps.new(name="New Lamp", type='POINT')

# Create new object with our lamp datablock
lamp_object = bpy.data.objects.new(name="New Lamp", object_data=lamp_data)

# Link lamp object to the scene so it'll appear in this scene
scene.objects.link(lamp_object)

# Place lamp to a specified location
lamp_object.location = (5.0, 5.0, 5.0)

修改 Object 材质

# 获取第 0 个材质槽
slot = obj.material_slots[0]
# 材质槽中的材质名
print(slot.name)
# 材质槽的链接方式(OBJECT 或 DATA)
print(slot.link)
# 材质槽的材质
print(slot.material)
# 仅对 OBJECT 进行材质修改
mat = bpy.data.materials['Mat.002']
slot.link = 'OBJECT'
slot.material = mat

修改材质的纹理

img = bpy.data.images.load(texturePath) # 图像文件
tex = bpy.data.textures.new("Tex", 'IMAGE') # 纹理
tex.image = img # 图像和纹理关联

mat.texture_slots.add() # 材质添加 纹理槽
slot = mat.texture_slots[0]
slot.texture = tex # 关联纹理
slot.texture_coords =  'UV'
slot.mapping =  'FLAT'

bpy.ops

应用数据修改

# 将object的修改应用到mesh数据上
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)

导入 obj

bpy.ops.import_scene.obj(filepath='/test/xx.obj', axis_forward='Y', axis_up='Z', use_groups_as_vgroups=True)

另存为 blend 文件

bpy.ops.wm.save_as_mainfile(filepath="path/to/myfilename")

删除 object 及其所有数据

# 取消所有选中
bpy.ops.object.select_all(action='DESELECT')
# 选择需要删除 Object
bpy.data.objects['Camera'].select_set(True)
# 执行删除
bpy.ops.object.delete() 

切换 Area 类型

types = {'VIEW_3D', 'TIMELINE', 'GRAPH_EDITOR', 'DOPESHEET_EDITOR', 'NLA_EDITOR', 'IMAGE_EDITOR', 'SEQUENCE_EDITOR', 'CLIP_EDITOR', 'TEXT_EDITOR', 'NODE_EDITOR', 'LOGIC_EDITOR', 'PROPERTIES', 'OUTLINER', 'USER_PREFERENCES', 'INFO', 'FILE_BROWSER', 'CONSOLE'}

# save the current area
area = bpy.context.area.type
# 当前Area切换到 3D View
bpy.context.area.type = 'VIEW_3D'

Python Tips

Blender 后台运行(比如 渲染农场)

# 单纯运行,不引入 blend 文件
blender --background --python myscript.py
blender -b -P myscript.py

# 引入 blend 文件,直接修改该文件
blender myscene.blend --background --python myscript.py

# 渲染 blend 文件
blender -b hello.blend -o ./test -F PNG -x 1 -f 1

快速删除 list 元素

pop_index = 5

# 交换,原 pop_index 所指内容此时被交换为最后一个元素
my_list[-1], my_list[pop_index] = my_list[pop_index], my_list[-1]

# 移除最后一项 (原 pop_index 所指)
my_list.pop()

快速字符串操作

对于许多字符串进行合并是最快的,字符串格式化也非常快(更适合转换数据类型)。字符串的数学计算最慢。

不要使用

if line[0:5] == "vert ": ...

使用

if line.startswith("vert "):

循环中减少 try

try 明显比 if 慢,因为每次都必须设置一个异常,所以避免在 循环中执行 且是 多次运行 的代码区域使用 try

启动交互式 Python

在脚本的中间,您可能想要检查一些变量,运行一些函数,并大致了解发生了什么。

import code
code.interact(local=locals())

如果你想访问全局和局部变量,可以这样做…

import code
namespace = globals().copy()
namespace.update(locals())
code.interact(local=namespace)

下一个例子是上面脚本的等效单行版本,它更容易粘贴到你的代码中:

__import__('code').interact(local=dict(globals(), **locals()))