blender · git:20261015.5c73bb3 · 2026-10-15 · sha256 fe73a3b52637e5b8
blender git:20261015.5c73bb3A
Immutable. This exact content never changes and is served at /api/v1/blob/fe73a3b52637e5b8.
---
name: blender
description: "Use when building or batch-processing 3D scenes with Blender's Python bpy API: constructing meshes and objects, Geometry Nodes procedural modeling, converting GIS data (GeoJSON/Shapefile) into building massing, developing add-ons, and exporting glTF/OBJ/STL in headless mode. Blender is the leading open-source 3D creation suite."
tags:
- 3d
- blender
- python
- bpy
- geometry-nodes
- gltf
- headless
- addon
- gis
- procedural
---
> **项目地址:** <https://github.com/blender/blender>
>
> **官方文档:** <https://docs.blender.org/>
>
> **Python API:** <https://docs.blender.org/api/current/>
>
> **许可证:** GPL-2.0-or-later
>
> **最新稳定版:** 5.2.2 LTS(2026-09-15 发布,见 [GitHub Tags](https://github.com/blender/blender/tags);上一 LTS 系列为 4.5)
## 概述
Blender 是开源 3D 创作套件,通过内置 Python 解释器暴露完整的 `bpy` API:脚本可读写全部场景数据、调用几乎全部界面功能,适合程序化建模、GIS 数据三维化与无头批处理。Python API 随 Blender 版本发布(当前 5.2.2 LTS),无需单独安装。
核心模块:
| 模块 | 用途 |
|------|------|
| `bpy.data` | 数据块访问(objects、meshes、materials、node_groups…) |
| `bpy.context` | 当前上下文(场景、视图层、选中对象、模式) |
| `bpy.ops` | 操作符(建模、导入导出、渲染、文件管理) |
| `bpy.types` | 类型定义(Object、Mesh、Operator、NodeTree…) |
| `bpy.msgbus` | 消息总线(订阅数据块属性变更) |
| `mathutils` | Vector / Matrix / Quaternion / Euler 数学库 |
| `bpy_extras` | 辅助工具(io_utils、object_utils、view3d_utils) |
常用交换格式:.blend、glTF 2.0(.gltf/.glb)、OBJ、STL、FBX、PLY、USD、Alembic、SVG。
---
## 环境准备
**桌面安装**
```bash
# Windows:官网安装包或 winget
winget install BlenderFoundation.Blender
# macOS
brew install --cask blender
# Linux(Ubuntu 官方推荐 snap)
sudo snap install blender --classic
# 或使用官网 tar.xz(免 root):<https://www.blender.org/download/>
# 发行版仓库的 blender 包通常滞后于官网版本,建议 snap 或官网包
```
**无头(headless)运行**
- `blender -b`(`--background`)不创建窗口,渲染、导入导出、脚本执行均可用,适合服务器与 CI。
- 无头环境不需要显示器;Linux 服务器建议使用官网 tar.xz 并补齐基础运行库。
- Blender 内置独立 Python,不依赖系统 Python;脚本中直接 `import bpy` 即可。
**验证**
```bash
blender --version
blender -b --python-expr "import bpy; print(bpy.app.version_string)"
```
---
## 核心 API/命令
### 命令行运行脚本
```bash
blender -b scene.blend -P build.py # 打开文件并执行脚本
blender -b -P gen.py -- --count 100 --out out.glb # 脚本参数置于 -- 之后,脚本内用 sys.argv 读取
blender -b --python-expr "import bpy; print(len(bpy.data.objects))"
blender -b --python-exit-code 1 -P pipeline.py # 脚本异常时以非零码退出,便于 CI 判断
```
`-P` 等价于 `--python <filepath>`;另有 `--python-text <name>`(执行文本块)与 `--python-console`(交互控制台)。
### 数据访问与对象创建
```python
import bpy
from mathutils import Vector
# 无头场景:清空为工厂空设置
bpy.ops.wm.read_factory_settings(use_empty=True)
# 由顶点/面创建网格数据块
mesh = bpy.data.meshes.new("Facade")
mesh.from_pydata([(0, 0, 0), (10, 0, 0), (10, 6, 0), (0, 6, 0)], [], [(0, 1, 2, 3)])
mesh.validate()
# 创建对象并链接到当前集合
obj = bpy.data.objects.new("Building", mesh)
bpy.context.collection.objects.link(obj)
obj.location = Vector((100.0, 50.0, 0.0))
obj.scale = (1.0, 1.0, 3.0) # 简易拉高
```
`bpy.data` 集合既可按名称索引(`bpy.data.objects["Cube"]`)也可按序号索引;序号可能随运行变化,脚本中优先用名称或变量引用。
### 网格与几何操作
```python
mesh = obj.data
mesh.validate() # 检查并修复非法几何
mesh.calc_loop_triangles() # 计算三角剖分(导出前需要)
# 变换优先改对象属性,避免依赖上下文的 bpy.ops
obj.rotation_euler = (0.0, 0.0, 1.5708) # 绕 Z 轴 90 度
bpy.context.view_layer.update() # 属性改动后刷新依赖图
```
### 导出 glTF / OBJ / STL
```python
# glTF 2.0(.glb 单文件,Web 首选)
bpy.ops.export_scene.gltf(filepath="out.glb", export_format='GLB', use_selection=False)
# OBJ(4.0 起为新的导入导出器)
bpy.ops.wm.obj_export(filepath="out.obj", export_selected_objects=False)
# STL(4.1 起为新的导入导出器)
bpy.ops.wm.stl_export(filepath="out.stl", export_selected_objects=False)
# 保存 .blend
bpy.ops.wm.save_as_mainfile(filepath="scene.blend")
```
### Geometry Nodes 基础(脚本创建节点组)
```python
# 新建几何节点组(GeometryNodeTree)
group = bpy.data.node_groups.new("GN_Extrude", 'GeometryNodeTree')
# 4.0 起用 interface.new_socket 定义输入/输出接口
group.interface.new_socket("Geometry", in_out='INPUT', socket_type='NodeSocketGeometry')
group.interface.new_socket("Geometry", in_out='OUTPUT', socket_type='NodeSocketGeometry')
node_in = group.nodes.new("NodeGroupInput")
node_out = group.nodes.new("NodeGroupOutput")
cube = group.nodes.new("GeometryNodeMeshCube") # 立方体节点
extrude = group.nodes.new("GeometryNodeExtrudeMesh") # 挤出网格节点
group.links.new(node_in.outputs["Geometry"], extrude.inputs["Mesh"])
group.links.new(extrude.outputs["Mesh"], node_out.inputs["Geometry"])
```
```python
# 将节点组挂到对象修饰器上
obj = bpy.data.objects.new("GN_Object", None)
bpy.context.collection.objects.link(obj)
mod = obj.modifiers.new("GeometryNodes", 'NODES')
mod.node_group = group
# 取评估后网格(应用修饰器结果,用于导出/统计)
depsgraph = bpy.context.evaluated_depsgraph_get()
obj_eval = obj.evaluated_get(depsgraph)
mesh_eval = bpy.data.meshes.new_from_object(obj_eval)
```
### 插件开发框架
```python
bl_info = {
"name": "My GIS Tool",
"author": "you",
"version": (1, 0, 0),
"blender": (5, 2, 0),
"category": "Object",
}
import bpy
class OBJECT_OT_build_from_footprint(bpy.types.Operator):
bl_idname = "object.build_from_footprint"
bl_label = "Build from Footprint"
def execute(self, context):
self.report({'INFO'}, "done")
return {'FINISHED'}
def register():
bpy.utils.register_class(OBJECT_OT_build_from_footprint)
def unregister():
bpy.utils.unregister_class(OBJECT_OT_build_from_footprint)
if __name__ == "__main__":
register()
```
传统插件用 `bl_info` + `register()/unregister()`(结构取自官方 Add-on Tutorial);4.2 起新式扩展(Extensions)改用 `blender_manifest.toml` 声明元数据,`register/unregister` 约定不变。
### GIS 数据结合(GeoJSON 生成建筑体块)
```python
import json
import bpy
# 解析 GeoJSON(标准库 json 即可)
with open("footprints.geojson", encoding="utf-8") as f:
gj = json.load(f)
def add_building(ring, height, name):
"""ring: [[lon, lat], ...] 外环;按等距近似投影为米"""
verts = [(x * 111320.0, y * 110540.0, 0.0) for x, y in ring[:-1]] # 去掉闭合点
n = len(verts)
verts += [(x, y, height) for x, y, _ in verts]
faces = [[i, (i + 1) % n, (i + 1) % n + n, i + n] for i in range(n)]
faces.append([i + n for i in range(n)]) # 顶面
mesh = bpy.data.meshes.new(name)
mesh.from_pydata(verts, [], faces)
mesh.validate()
obj = bpy.data.objects.new(name, mesh)
bpy.context.collection.objects.link(obj)
for i, feat in enumerate(gj["features"]):
geom = feat["geometry"]
if geom["type"] == "Polygon":
add_building(geom["coordinates"][0], feat["properties"].get("height", 10.0), f"B_{i}")
bpy.ops.export_scene.gltf(filepath="city.glb", export_format='GLB')
```
- 上述经纬度转米为等距近似,跨区域或高精度场景应先用 pyproj/GDAL 做投影(UTM/Web Mercator)再写入 `verts`。
- Shapefile 可用 [BlenderGIS](https://github.com/domlysz/BlenderGIS) 插件导入:`bpy.ops.importgis.shapefile(filepath="districts.shp")`(bl_idname 为 `importgis.shapefile`),该插件同时支持 GeoTIFF 与 OSM。
- 大数据量建议先在 GDAL/QGIS 中裁剪、简化、转 GeoJSON,再交给 Blender 生成体块。
---
## 典型工作流
1. **准备环境**:无头服务器用官网包安装,`blender -b --python-expr "import bpy"` 验证可用。
2. **编写脚本**:以 `bpy.ops.wm.read_factory_settings(use_empty=True)` 开始,用 `bpy.data` 创建网格/对象并 `link` 到集合。
3. **建模**:简单体块直接 `from_pydata`;参数化或迭代规则用 Geometry Nodes 节点组 + 修饰器。
4. **材质与变换**:设置 `obj.location/rotation_euler/scale` 与材质槽,`view_layer.update()` 刷新。
5. **导出**:按目标平台选择 `export_scene.gltf` / `wm.obj_export` / `wm.stl_export`,显式指定格式与选择参数。
6. **批处理**:`blender -b -P pipeline.py -- <args>` 循环处理数据集,配合 `--python-exit-code` 接入 CI。
---
## 最佳实践
1. **脚本优先 `bpy.data`,而非 `bpy.ops`**:`bpy.ops` 依赖上下文(模式、选中、区域),无头环境下易报 `context is incorrect`;必须用操作符时通过 `bpy.context.temp_override(...)` 显式提供上下文。
2. **导出参数写全**:glTF 用 `export_format='GLB'` 控制单文件;OBJ/STL 用 `export_selected_objects` 控制范围;导出前确认对象已链接到场景集合。
3. **Geometry Nodes 结果需评估**:修饰器不修改原始网格,导出或统计前经 `evaluated_depsgraph_get()` + `new_from_object()` 取评估网格。
4. **单位与坐标**:Blender 内部为米、Z 轴向上;glTF 导出默认转 Y 轴向上,写入 GIS 数据(东-北-高)时保持 Z-up 约定。
5. **无头稳定性**:CI 中加 `--python-exit-code 1`;批处理循环用 `try/except` 包装,单个要素失败不中断整批。
6. **第三方库**:Blender 使用内置 Python,不加载系统 site-packages;纯数据解析优先标准库(json、csv),复杂投影/几何处理可调用外部 GDAL 生成中间文件。
---
## 常见问题
| 问题 | 解决 |
|------|------|
| snap 安装后 `blender: command not found` | snap 版路径为 `/snap/bin/blender`,确认 PATH 或使用绝对路径 |
| 无头下 `bpy.ops` 报 `context is incorrect` | 改用 `bpy.data` 直接操作,或用 `bpy.context.temp_override(...)` 提供所需上下文 |
| 脚本报 `ModuleNotFoundError`(第三方包) | Blender 使用内置 Python,不加载系统 site-packages;改用标准库或外部工具生成中间数据 |
| `-P` 脚本执行完但没有输出文件 | 后台模式不自动保存;需显式调用 `wm.save_as_mainfile` 或导出操作符 |
| 导出的 glTF 没有材质 | 材质需使用 Principled BSDF 节点;检查导出参数 `export_materials` 未被关闭 |
| Geometry Nodes 修饰器无效果 | 确认节点组输出已连接 `Group Output`,且对象有输入几何;用 depsgraph 取评估网格验证 |
| 脚本参数没有传入 | 参数须放在 `--` 之后(`blender -b -P s.py -- a b`),脚本内从 `sys.argv` 读取 |
| 4.x 旧脚本在 5.x 报错 | 节点组接口:旧式 `inputs/outputs` 改为 `interface.new_socket`;导入导出核对 `wm.obj_export`/`wm.stl_export` 名称 |
---
## 参考资源
- 官方手册(脚本与扩展章节):<https://docs.blender.org/manual/en/latest/advanced/scripting/index.html>
- Python API 文档:<https://docs.blender.org/api/current/>
- API Quickstart:<https://docs.blender.org/api/current/info_quickstart.html>
- 命令行参数:<https://docs.blender.org/manual/en/latest/advanced/command_line/arguments.html>
- Add-on 教程:<https://docs.blender.org/manual/en/latest/advanced/scripting/addon_tutorial.html>
- 扩展(Extensions)指南:<https://docs.blender.org/manual/en/latest/advanced/extensions/getting_started.html>
- 下载与版本:<https://www.blender.org/download/>
---
## 相关技能
- **freecad** — 参数化 CAD 与 BIM(精确实体建模,与 Blender 网格流程互补):[../freecad/SKILL.md](../freecad/SKILL.md)
- **openscad** — 声明式 CSG 建模(快速生成体块后导入 Blender 渲染):[../openscad/SKILL.md](../openscad/SKILL.md)
- **cadquery** — Python 参数化 CAD(精确 B-Rep,可与 Blender 交换 glTF/OBJ):[../cadquery/SKILL.md](../cadquery/SKILL.md)
- **occt** — 底层 OCCT 几何内核(精确几何运算):[../occt/SKILL.md](../occt/SKILL.md)
---
## AI 使用建议
- **推荐工作流模式**:AI 生成 Blender 脚本时先确定运行模式(GUI 交互或 `blender -b -P` 无头),无头脚本一律从 `bpy.data` 出发;GIS 类任务先输出 GeoJSON 中间文件再生成体块脚本,避免在 Blender 内做重投影。
- **关键注意事项**:① `bpy.ops` 依赖上下文,无头环境优先 `bpy.data`;② 修改属性后调用 `bpy.context.view_layer.update()` 或重新获取 depsgraph;③ 导出操作符参数(`export_format`、`export_selected_objects`)必须显式给出;④ Blender 内置 Python 不加载系统第三方包;⑤ 版本差异集中在节点组接口(`interface.new_socket`)与导入导出操作符名称(`wm.obj_export`/`wm.stl_export`),生成代码前确认目标版本。
- **常用代码模式**:`read_factory_settings(use_empty=True)` → `bpy.data.meshes.new` + `from_pydata` → `objects.new` + `collection.objects.link` → 设置变换/修饰器 → `export_scene.gltf` / `wm.stl_export`;批处理外壳 `blender -b --python-exit-code 1 -P pipeline.py -- <args>`。