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.cosmath.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)