Blender Python编程技巧
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) # add to scene
ob.location.y += 5
object数学变换
# 获取旋转四元数
ob.rotation_euler.to_quaternion()
文件读写
https://docs.blender.org/api/blender_python_api_current/bpy.types.BlendDataLibraries.html
# 链接所有以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 = 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 = 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
# swap so the pop_index is last.
my_list[-1], my_list[pop_index] = my_list[pop_index], my_list[-1]
# remove last item (pop_index)
my_list.pop()
快速字符串操作
Join is fastest on many strings, string formatting is quite fast too (better for converting data types). String arithmetic is slowest.
rather than…
if line[0:5] == "vert ": ...
use…
if line.startswith("vert "):
循环中减少try
try is significantly slower than an if since an exception has to be set each time, so avoid using try in areas of your code that execute in a loop and runs many times.
启动交互式Python
In the middle of a script you may want to inspect some variables, run some function and generally dig about to see whats going on.
import code
code.interact(local=locals())
If you want to access both global and local variables do this…
import code
namespace = globals().copy()
namespace.update(locals())
code.interact(local=namespace)
The next example is an equivalent single line version of the script above which is easier to paste into your code:
__import__('code').interact(local=dict(globals(), **locals()))