3D 建模软件 Blender Python 脚本自动化
FreeGuideOnline
最新
2026-07-08
python import bpy
列出场景中所有对象
print(bpy.data.objects.keys())
你会看到类似 `['Camera', 'Cube', 'Light']` 的输出。现在尝试获取并修改立方体的位置:
```python
cube = bpy.data.objects['Cube']
cube.location.x = 3
按 Enter 后,立刻在 3D 视口看到立方体沿 X 轴移动。这种即时反馈让学习过程非常直观。
脚本化基础:从创建物体到修改几何
创建第一个脚本
不要仅在控制台单行输入,我们可以将完整脚本放入文本编辑器执行。点击文本编辑器中的 + New,创建一个新文本,命名为 my_first_script.py,写入:
import bpy
import math
# 清除默认立方体(如果存在)
if 'Cube' in bpy.data.objects:
bpy.data.objects.remove(bpy.data.objects['Cube'])
# 创建10个排列成圆形的立方体
count = 10
radius = 3
for i in range(count):
angle = i * (2 * math.pi / count)
x = radius * math.cos(angle)
y = radius * math.sin(angle)
bpy.ops.mesh.primitive_cube_add(
size=1,
location=(x, y, 0)
)
点击文本编辑器顶部的 Run Script 按钮(或按 Alt+P),视图中立即出现一个由立方体组成的圆环。
代码解析
bpy.ops.mesh.primitive_cube_add()调用的是操作符(Operator),它模拟用户界面中的“添加网格 > 立方体”命令。- 操作符的参数
location将新生成的立方体直接定位。 math.cos和math.sin用于计算圆周上的坐标。- 开头清除已有立方体,便于重复运行脚本而不产生重合物体。
深入:修改网格数据
除了使用内置操作符,更高效的方式是直接创建和修改网格数据。
import bpy
import bmesh
# 创建空网格和空对象
mesh = bpy.data.meshes.new("MyPyramid")
obj = bpy.data.objects.new("Pyramid", mesh)
# 将对象链接到场景
bpy.context.collection.objects.link(obj)
# 用bmesh模块构建几何体
bm = bmesh.new()
# 定义顶点坐标
v1 = bm.verts.new((0, 0, 0))
v2 = bm.verts.new((1, 0, 0))
v3 = bm.verts.new((0.5, 1, 0))
v4 = bm.verts.new((0.5, 0.5, 1))
# 通过顶点创建面
bm.faces.new((v1, v2, v3)) # 底面三角形
bm.faces.new((v1, v2, v4))
bm.faces.new((v2, v3, v4))
bm.faces.new((v3, v1, v4))
# 写入网格数据并释放bmesh
bm.to_mesh(mesh)
bm.free()
# 设置对象位置
obj.location = (2, 2, 0)
运行此脚本后,你会得到一个三角形的金字塔。这里 bmesh 是 Blender 对几何数据进行底层操作的库,适合程序化生成复杂模型。
操作符与上下文:安全调用必备
许多操作符依赖当前激活的上下文,比如 bpy.ops.object.modifier_add() 需要有一个被选中的物体。当上下文不正确时会触发 RuntimeError。为避免此问题,必须在调用前正确设置选择状态。
import bpy
# 假设场景中有一个名为'Cube'的物体
cube = bpy.data.objects.get('Cube')
if not cube:
print("没有找到Cube")
else:
# 清空选择并激活对象
bpy.ops.object.select_all(action='DESELECT')
cube.select_set(True)
bpy.context.view_layer.objects.active = cube
# 安全地添加倒角修改器
bpy.ops.object.modifier_add(type='BEVEL')
cube.modifiers['Bevel'].width = 0.1
cube.modifiers['Bevel'].segments = 3
以上代码演示了正确设置 active 对象和 selected 状态,是使用用户界面操作符的关键步骤。
自动化工作流:批量处理与参数化
批量重命名对象
场景中杂乱的对象名称会让管理变得痛苦。用 Python 可以一键规范化命名。
import bpy
for i, obj in enumerate(bpy.data.objects):
if obj.type == 'MESH':
obj.name = f'Mesh_{i:03d}'
obj.data.name = f'MeshData_{i:03d}'
print("重命名完成")
批量应用修改器
一个常见需求:将所有带修改器的可视网格物体“应用”修改器(塌陷为实际几何)。
# 注意:此操作不可逆,运行前请保存文件
import bpy
for obj in bpy.data.objects:
if obj.type == 'MESH' and obj.modifiers:
# 设置为激活物体并选中
bpy.ops.object.select_all(action='DESELECT')
obj.select_set(True)
bpy.context.view_layer.objects.active = obj
# 遍历修改器,逐个应用
for mod in obj.modifiers:
try:
bpy.ops.object.modifier_apply(modifier=mod.name)
except RuntimeError:
print(f"无法应用 {obj.name} 的修改器 {mod.name}")
print("所有修改器已尝试应用")
参数化生成:一个可复用的函数
将生成逻辑封装成函数,让脚本更像一个自定义工具。
import bpy
import bmesh
import math
def create_gear(teeth=10, radius=1, height=0.2,
location=(0,0,0)):
mesh = bpy.data.meshes.new("Gear")
obj = bpy.data.objects.new("Gear", mesh)
bpy.context.collection.objects.link(obj)
bm = bmesh.new()
# 中心圆柱体
bmesh.ops.create_circle(bm, cap_tris=True, segments=32, radius=radius)
bmesh.ops.extrude_face_region(bm, geom=[f for f in bm.faces],
vec=(0,0,height))
# 牙齿:在圆周上添加立方体
for i in range(teeth):
angle = i * (2*math.pi/teeth)
x = radius * math.cos(angle)
y = radius * math.sin(angle)
bmesh.ops.create_cube(bm, size=0.2,
matrix=mathutils.Matrix.Translation((x,y,0)))
bm.to_mesh(mesh)
bm.free()
obj.location = location
return obj
# 使用函数生成5个不同参数的齿轮
for j in range(5):
create_gear(teeth=6+j*2, radius=1+j*1.5,
height=0.3, location=(j*3, 0, 0))
实用脚本:从材质到渲染
批量设置材质
import bpy
# 创建一个红色材质
mat = bpy.data.materials.new(name="RedMat")
mat.diffuse_color = (1, 0, 0, 1) # RGBA
# 为所有网格物体赋予此材质
for obj in bpy.data.objects:
if obj.type == 'MESH':
if obj.data.materials:
obj.data.materials[0] = mat
else:
obj.data.materials.append(mat)
自动设置渲染输出
import bpy
scene = bpy.context.scene
scene.render.filepath = "//render_output.png"
scene.render.image_settings.file_format = 'PNG'
scene.render.resolution_x = 1920
scene.render.resolution_y = 1080
scene.render.resolution_percentage = 100
print("渲染设置完成,路径:", scene.render.filepath)