blender-modeling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBlender Modeling
Blender建模
Create geometry in Blender via natural language. You emit Python code that the Blender MCP executes; the patterns below cover the common 80%.
通过自然语言在Blender中创建几何体。你需要生成Blender MCP可执行的Python代码;以下模式涵盖了80%的常见场景。
Decision tree
决策树
What kind of geometry?
├── Hard-surface (vehicles, weapons, architecture, props)
│ → Cube primitive + Bevel + SubSurf modifier stack
│ → See "Hard-surface stack" recipe
│
├── Organic (characters, creatures, plants — block-out only)
│ → Ico Sphere + sculpting (or Voxel Remesh for shape)
│ → For sculpting strokes, redirect: it's gestural, not text-driven
│
├── Architectural / repeating (fences, columns, tile)
│ → Plane/Cube + Array modifier (+ Curve modifier for paths)
│ → See "Array along curve" recipe
│
├── Cylindrical (pipes, columns, bottles)
│ → Cylinder primitive, or Curve + bevel_object
│ → See "Sweep along path" — covered in wireframe-to-3d if needed
│
├── Holes / cuts in existing geometry
│ → Boolean modifier (DIFFERENCE)
│ → See "Boolean cut" recipe
│
└── Quick block-out from primitives only
→ Multiple primitive_*_add calls
→ See "Block-out scene" recipe要创建哪种几何体?
├── 硬表面(车辆、武器、建筑、道具)
│ → 立方体基础几何体 + Bevel + SubSurf修改器堆栈
│ → 参考「硬表面堆栈」方案
│
├── 有机模型(角色、生物、植物——仅用于粗模搭建)
│ → 二十面体球体 + 雕刻(或使用体素重构调整形状)
│ → 若涉及雕刻笔触,请引导用户:雕刻是手势操作,无法通过文本精准驱动
│
├── 建筑/重复类模型(围栏、柱子、瓷砖)
│ → 平面/立方体 + Array修改器(+ Curve修改器适配路径)
│ → 参考「沿曲线阵列」方案
│
├── 圆柱形模型(管道、柱子、瓶子)
│ → 圆柱体基础几何体,或曲线 + bevel_object
│ → 参考「沿路径扫掠」——若需要可查看wireframe-to-3d相关内容
│
├── 现有几何体上的孔洞/切割
│ → Boolean修改器(DIFFERENCE模式)
│ → 参考「布尔切割」方案
│
└── 仅用基础几何体快速搭建粗模
→ 多次调用primitive_*_add方法
→ 参考「场景粗模搭建」方案Code-execution rules (recap)
代码执行规则(回顾)
- Each call gets a fresh Python namespace. Re-import everything; identify objects by
mcp__blender__execute_blender_code.bpy.data.objects['name'] - Always name objects with prefix. Never leave
GEO-.Cube.027 - Print structured output back so you can parse results.
- Chunk long sequences into multiple calls.
- 每次调用都会获得全新的Python命名空间。需重新导入所有模块;通过
mcp__blender__execute_blender_code识别对象。bpy.data.objects['name'] - 所有对象名称必须以为前缀。绝对不能保留默认的
GEO-这类名称。Cube.027 - 返回结构化输出,以便解析结果。
- 将长序列拆分为多次调用。
Recipes
方案指南
Critical: axis orientation for elongated objects
重点:细长物体的轴方向
For any elongated/asymmetric subject (sword blade, knife, bottle, plank, bone, screwdriver tip, etc.), three axes have different meaning:
- Long axis — the length of the object (78cm for a sword blade)
- Broad axis — the wider face axis, what's visible from the "useful" viewing angle (4.5cm for a blade — the flat side you'd lay on a table)
- Thin axis — the narrower cross-section axis (0.8cm for a blade — the cutting edge)
Always orient elongated objects so the broad axis faces the camera in hero shots. A sword viewed edge-on (camera looking down the thin axis) renders as a thin pole and looks nothing like a sword. The recipes below use this convention:
| Convention | X (left-right of object's local space) | Y (front-back of object's local space) | Z (up-down) |
|---|---|---|---|
| Sword blade | thin (0.8cm) | broad (4.5cm) | long (78cm) — vertical |
| Knife blade | thin | broad | long — horizontal |
| Plank | thin | broad | long |
| Bottle | symmetric (radius) | symmetric (radius) | long (height) |
After building, rotate the object so the broad axis points roughly toward the camera. For a sword standing upright with camera in front (camera in -Y direction): rotate the blade 90° around Z so its local Y (broad) → world X, then the broad face is visible from the camera's perspective.
对于任何细长/不对称的对象(剑刃、刀具、瓶子、木板、骨头、螺丝刀头等),三个轴具有不同的含义:
- 长轴——物体的长度方向(例如剑刃长78cm)
- 宽轴——物体较宽面的轴向,即从“实用”视角可见的方向(例如剑刃宽4.5cm——可平放在桌面上的平面)
- 薄轴——物体横截面较窄的轴向(例如剑刃厚0.8cm——刀刃方向)
在主视角渲染时,务必让细长物体的宽轴朝向相机。如果相机沿薄轴方向观察剑(相机看向薄轴方向),剑会呈现为细杆,完全不像剑的样子。以下方案遵循此约定:
| 约定 | X(物体局部空间的左右方向) | Y(物体局部空间的前后方向) | Z(上下方向) |
|---|---|---|---|
| 剑刃 | 薄轴(0.8cm) | 宽轴(4.5cm) | 长轴(78cm)——垂直方向 |
| 刀刃 | 薄轴 | 宽轴 | 长轴——水平方向 |
| 木板 | 薄轴 | 宽轴 | 长轴 |
| 瓶子 | 对称(半径) | 对称(半径) | 长轴(高度) |
创建完成后,旋转物体使宽轴大致朝向相机。例如,剑直立放置且相机在前方(相机位于-Y方向):将剑刃绕Z轴旋转90°,使其局部Y轴(宽轴)指向世界X轴,这样宽面就能从相机视角看到。
Critical: connecting parts smoothly (no visible seams)
重点:平滑连接部件(无可见接缝)
When assembling a multi-part subject (sword = blade + guard + grip + pommel; chair = seat + back + 4 legs), separate primitives abutting at exactly-aligned face boundaries leave visible seams even though the math says they touch. Worse — different shape primitives (cylinder grip into cube guard) produce obvious "cylinder-on-rectangle" boundaries.
Two fixes, used together:
1. Overlap parts deeply at joins. Make adjacent primitives interpenetrate by 5–15mm at every connection. The hidden volume disappears inside the larger part, leaving no visible seam.
python
undefined组装多部件对象时(例如剑=剑刃+护手+握柄+柄头;椅子=座椅+靠背+4条腿),即使基础几何体的面完全对齐拼接,也会留下可见接缝——数学上它们是接触的,但视觉上有明显痕迹。更糟的是,不同形状的基础几何体(例如圆柱形握柄连接立方体护手)会产生明显的“圆柱-矩形”边界。
可结合以下两种修复方法:
1. 部件连接处深度重叠。让相邻的基础几何体在每个连接点相互穿插5–15mm。被遮挡的部分会隐藏在更大的部件内部,不会留下可见接缝。
python
undefinedSword example: grip extends 1.5cm INTO the guard above and 1cm INTO the pommel below
剑示例:握柄向上延伸1.5cm进入护手,向下延伸1cm进入柄头
GRIP_OVERLAP_INTO_GUARD = 0.015
GRIP_OVERLAP_INTO_POMMEL = 0.010
grip_total_len = GRIP_VISIBLE_LEN + GRIP_OVERLAP_INTO_GUARD + GRIP_OVERLAP_INTO_POMMEL
The cylinder grip's top 1.5cm is *inside* the guard cube — not visible from outside, so the transition you see is just gold-guard surface, no cylinder-meeting-rectangle artifact.
**2. Apply `shade_smooth()` to rounded parts** (cylinders, spheres, organic shapes). Shaded-flat cylinders show every facet boundary; smooth-shaded ones look continuous. Cubes and beveled hard-surface parts can stay shaded flat (or be partially smoothed via Auto Smooth on Blender 4.x; Blender 5.x removed `Mesh.use_auto_smooth` so use modifier-based smoothing or per-face flags).
```pythonGRIP_OVERLAP_INTO_GUARD = 0.015
GRIP_OVERLAP_INTO_POMMEL = 0.010
grip_total_len = GRIP_VISIBLE_LEN + GRIP_OVERLAP_INTO_GUARD + GRIP_OVERLAP_INTO_POMMEL
圆柱形握柄的顶部1.5cm位于护手立方体内部——从外部看不到,因此视觉上只会看到金色护手的表面,不会出现圆柱与矩形衔接的瑕疵。
**2. 对圆角部件应用`shade_smooth()`**(圆柱体、球体、有机形状)。平坦着色的圆柱体会显示每个面的边界;平滑着色的圆柱体会呈现连续的外观。立方体和带倒角的硬表面部件可保持平坦着色(或在Blender 4.x中通过Auto Smooth实现部分平滑;Blender 5.x移除了`Mesh.use_auto_smooth`,因此需使用基于修改器的平滑或逐面标记)。
```pythonAfter creating each rounded primitive
创建每个圆角基础几何体后执行
bpy.ops.object.shade_smooth()
**Anti-pattern** (visible seams):
```pythonbpy.ops.object.shade_smooth()
**反模式**(可见接缝):
```python❌ Pieces abut exactly — visible seam where surfaces meet
❌ 部件完全拼接——表面衔接处有可见接缝
pommel_z = -GRIP_LEN/2 - POMMEL_R # pommel top exactly at grip bottom
guard_z = GRIP_LEN/2 + GUARD_H/2 # guard bottom exactly at grip top
pommel_z = -GRIP_LEN/2 - POMMEL_R # 柄头顶部恰好与握柄底部对齐
guard_z = GRIP_LEN/2 + GUARD_H/2 # 护手底部恰好与握柄顶部对齐
Result: clear line where each pair of surfaces meets
结果:每对表面衔接处有清晰的线条
**Correct** (hidden seams via overlap):
```python
**正确做法**(通过重叠隐藏接缝):
```python✓ Pieces overlap by ~5-15mm; junction lines are inside other geometry
✓ 部件重叠约5-15mm;衔接线位于其他几何体内部
pommel_z = -GRIP_LEN/2 - POMMEL_R + 0.010 # pommel pushed up 1cm into grip
guard_z = GRIP_LEN/2 + GUARD_H/2 - 0.015 # guard pushed down to envelope grip top
For a **truly seamless** join (high-quality renders), Boolean Union the same-material parts: e.g. Boolean Union pommel + grip into a single mesh would eliminate the seam entirely. But this only works when both parts use the same material.pommel_z = -GRIP_LEN/2 - POMMEL_R + 0.010 # 柄头向上推入握柄1cm
guard_z = GRIP_LEN/2 + GUARD_H/2 - 0.015 # 护手向下包裹握柄顶部1.5cm
若要实现**真正无缝**的衔接(用于高质量渲染),可对相同材质的部件执行Boolean Union操作:例如将柄头和握柄通过Boolean Union合并为单个网格,可完全消除接缝。但此方法仅适用于材质相同的部件。Critical: tapering to a point (for blade tips)
重点:将尖端削成点(例如剑刃尖端)
Don't just scale the top vertices toward zero — that produces a "chiseled flat" tip. Pinch all top vertices to a single point and merge them:
python
import bpy
import bmesh
obj = bpy.data.objects['GEO-blade']
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(obj.data)
bm.verts.ensure_lookup_table()不要仅将顶部顶点缩放至零——这会产生“凿平的扁平”尖端。将所有顶部顶点捏合到单个点并合并:
python
import bpy
import bmesh
obj = bpy.data.objects['GEO-blade']
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(obj.data)
bm.verts.ensure_lookup_table()Find vertices at the top (highest local Z)
找到顶部的顶点(局部Z值最高的顶点)
max_z = max(v.co.z for v in bm.verts)
top_verts = [v for v in bm.verts if abs(v.co.z - max_z) < 0.001]
max_z = max(v.co.z for v in bm.verts)
top_verts = [v for v in bm.verts if abs(v.co.z - max_z) < 0.001]
Collapse them to centerline
将它们折叠到中心线
for v in top_verts:
v.co.x = 0.0
v.co.y = 0.0
bmesh.update_edit_mesh(obj.data)
for v in top_verts:
v.co.x = 0.0
v.co.y = 0.0
bmesh.update_edit_mesh(obj.data)
Merge the now-coincident vertices into a true single point
将重合的顶点合并为真正的单点
bpy.ops.mesh.select_all(action='DESELECT')
for v in top_verts:
v.select = True
bmesh.update_edit_mesh(obj.data)
bpy.ops.mesh.remove_doubles(threshold=0.001)
bpy.ops.object.mode_set(mode='OBJECT')
print(f"tapered:{obj.name}")
This produces a true geometric point. Without `remove_doubles`, the four collapsed verts stay as four distinct points at the same coordinate — the tip looks visually pointed but is degenerate topology.bpy.ops.mesh.select_all(action='DESELECT')
for v in top_verts:
v.select = True
bmesh.update_edit_mesh(obj.data)
bpy.ops.mesh.remove_doubles(threshold=0.001)
bpy.ops.object.mode_set(mode='OBJECT')
print(f"tapered:{obj.name}")
这样会生成真正的几何点。如果不执行`remove_doubles`,四个折叠后的顶点仍会是位于同一坐标的四个独立点——视觉上看起来是尖的,但拓扑结构是退化的。Recipe 1 — Add a primitive with a clean name
方案1 — 添加带规范名称的基础几何体
python
import bpypython
import bpyAdd cube
添加立方体
bpy.ops.mesh.primitive_cube_add(size=2.0, location=(0, 0, 1))
obj = bpy.context.active_object
obj.name = 'GEO-base_box'
print(f"created:{obj.name} verts:{len(obj.data.vertices)}")
Replace `primitive_cube_add` with: `_plane_`, `_uv_sphere_`, `_ico_sphere_`, `_cylinder_`, `_cone_`, `_torus_`, `_monkey_`. Each takes appropriate arguments (`radius`, `depth`, `vertices`, `segments`, `subdivisions`).bpy.ops.mesh.primitive_cube_add(size=2.0, location=(0, 0, 1))
obj = bpy.context.active_object
obj.name = 'GEO-base_box'
print(f"created:{obj.name} verts:{len(obj.data.vertices)}")
将`primitive_cube_add`替换为:`_plane_`、`_uv_sphere_`、`_ico_sphere_`、`_cylinder_`、`_cone_`、`_torus_`、`_monkey_`。每个方法接受相应的参数(`radius`、`depth`、`vertices`、`segments`、`subdivisions`)。Recipe 2 — Hard-surface stack (the "Bevel + SubSurf" pattern)
方案2 — 硬表面堆栈(“Bevel + SubSurf”模式)
python
import bpy
obj = bpy.data.objects['GEO-base_box']python
import bpy
obj = bpy.data.objects['GEO-base_box']1. Bevel modifier — round the sharp edges
1. Bevel修改器——圆滑锐利边缘
bevel = obj.modifiers.new('Bevel', type='BEVEL')
bevel.width = 0.02 # 2 cm round-over
bevel.segments = 3 # smoothness
bevel.limit_method = 'ANGLE' # only bevel edges sharper than threshold
bevel.angle_limit = 0.523599 # 30° in radians
bevel = obj.modifiers.new('Bevel', type='BEVEL')
bevel.width = 0.02 # 2cm圆角
bevel.segments = 3 # 平滑度
bevel.limit_method = 'ANGLE' # 仅倒角角度超过阈值的边缘
bevel.angle_limit = 0.523599 # 30°(弧度制)
2. Subdivision Surface AFTER bevel (critical order)
2. 细分曲面修改器(必须在Bevel之后添加)
subsurf = obj.modifiers.new('SubSurf', type='SUBSURF')
subsurf.levels = 2
subsurf.render_levels = 3
subsurf = obj.modifiers.new('SubSurf', type='SUBSURF')
subsurf.levels = 2
subsurf.render_levels = 3
3. Smooth shading
3. 平滑着色
bpy.context.view_layer.objects.active = obj
bpy.ops.object.shade_smooth()
print(f"hardsurface:{obj.name}")
**Critical**: Bevel before SubSurf. Reverse this and you get pinching artifacts.bpy.context.view_layer.objects.active = obj
bpy.ops.object.shade_smooth()
print(f"hardsurface:{obj.name}")
**重点**:先添加Bevel再添加SubSurf。顺序颠倒会产生收缩瑕疵。Recipe 3 — Edit-mode operations (extrude, inset, loop cut)
方案3 — 编辑模式操作(挤出、内插、环切)
python
import bpy
obj = bpy.data.objects['GEO-base_box']
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')python
import bpy
obj = bpy.data.objects['GEO-base_box']
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')Select all faces, then extrude up by 1m
选择所有面,向上挤出1m
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.extrude_region_move(
TRANSFORM_OT_translate={'value': (0, 0, 1.0)}
)
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.extrude_region_move(
TRANSFORM_OT_translate={'value': (0, 0, 1.0)}
)
Inset all selected faces by 0.1m
将所有选中的面向内插0.1m
bpy.ops.mesh.inset(thickness=0.1, depth=0)
bpy.ops.mesh.inset(thickness=0.1, depth=0)
Add a loop cut around the middle
在中间添加环切
bpy.ops.mesh.loopcut_slide(
MESH_OT_loopcut={'number_cuts': 1, 'edge_index': 0},
TRANSFORM_OT_edge_slide={'value': 0.0},
)
bpy.ops.object.mode_set(mode='OBJECT')
print(f"edited:{obj.name} verts:{len(obj.data.vertices)}")
undefinedbpy.ops.mesh.loopcut_slide(
MESH_OT_loopcut={'number_cuts': 1, 'edge_index': 0},
TRANSFORM_OT_edge_slide={'value': 0.0},
)
bpy.ops.object.mode_set(mode='OBJECT')
print(f"edited:{obj.name} verts:{len(obj.data.vertices)}")
undefinedRecipe 4 — Boolean cut (drilling a hole)
方案4 — 布尔切割(钻孔)
python
import bpy
target = bpy.data.objects['GEO-base_box']
cutter = bpy.data.objects.get('GEO-cutter')
if cutter is None:
bpy.ops.mesh.primitive_cylinder_add(radius=0.3, depth=3.0, location=(0, 0, 1))
cutter = bpy.context.active_object
cutter.name = 'GEO-cutter'python
import bpy
target = bpy.data.objects['GEO-base_box']
cutter = bpy.data.objects.get('GEO-cutter')
if cutter is None:
bpy.ops.mesh.primitive_cylinder_add(radius=0.3, depth=3.0, location=(0, 0, 1))
cutter = bpy.context.active_object
cutter.name = 'GEO-cutter'Apply boolean
应用布尔修改器
mod = target.modifiers.new('Boolean', type='BOOLEAN')
mod.operation = 'DIFFERENCE'
mod.object = cutter
mod.solver = 'EXACT'
bpy.context.view_layer.objects.active = target
bpy.ops.object.modifier_apply(modifier=mod.name)
mod = target.modifiers.new('Boolean', type='BOOLEAN')
mod.operation = 'DIFFERENCE'
mod.object = cutter
mod.solver = 'EXACT'
bpy.context.view_layer.objects.active = target
bpy.ops.object.modifier_apply(modifier=mod.name)
Hide cutter from render
隐藏切割体,使其不参与渲染
cutter.hide_viewport = True
cutter.hide_render = True
print(f"booleaned:{target.name}")
undefinedcutter.hide_viewport = True
cutter.hide_render = True
print(f"booleaned:{target.name}")
undefinedRecipe 5 — Mirror modifier (only model half)
方案5 — Mirror修改器(仅建模一半)
python
import bpy
obj = bpy.data.objects['GEO-character_half']
mod = obj.modifiers.new('Mirror', type='MIRROR')
mod.use_axis[0] = True # mirror across X
mod.use_clip = True # snap vertices on axis
mod.use_mirror_merge = True
mod.merge_threshold = 0.001
print(f"mirrored:{obj.name}")Place Mirror first in the stack (before Bevel/SubSurf).
python
import bpy
obj = bpy.data.objects['GEO-character_half']
mod = obj.modifiers.new('Mirror', type='MIRROR')
mod.use_axis[0] = True # 沿X轴镜像
mod.use_clip = True # 对齐轴上的顶点
mod.use_mirror_merge = True
mod.merge_threshold = 0.001
print(f"mirrored:{obj.name}")将Mirror修改器放在堆栈的最前面(在Bevel/SubSurf之前)。
Recipe 6 — Array along curve (chains, fences, beads)
方案6 — 沿曲线阵列(链条、围栏、珠子)
python
import bpypython
import bpy1. The base unit
1. 基础单元
bpy.ops.mesh.primitive_cube_add(size=0.2, location=(0, 0, 0))
unit = bpy.context.active_object
unit.name = 'GEO-bead'
bpy.ops.mesh.primitive_cube_add(size=0.2, location=(0, 0, 0))
unit = bpy.context.active_object
unit.name = 'GEO-bead'
2. The path (assume it exists; user provides or we add a Bezier)
2. 路径(假设已存在;用户提供或我们添加贝塞尔曲线)
path = bpy.data.objects.get('GEO-path')
if path is None:
bpy.ops.curve.primitive_bezier_curve_add()
path = bpy.context.active_object
path.name = 'GEO-path'
path = bpy.data.objects.get('GEO-path')
if path is None:
bpy.ops.curve.primitive_bezier_curve_add()
path = bpy.context.active_object
path.name = 'GEO-path'
3. Array modifier (count or fit to length)
3. Array修改器(按数量或适配长度)
arr = unit.modifiers.new('Array', type='ARRAY')
arr.fit_type = 'FIT_CURVE'
arr.curve = path
arr.relative_offset_displace = (1.0, 0, 0)
arr = unit.modifiers.new('Array', type='ARRAY')
arr.fit_type = 'FIT_CURVE'
arr.curve = path
arr.relative_offset_displace = (1.0, 0, 0)
4. Curve modifier — bends the array along the path
4. Curve修改器——使阵列沿路径弯曲
crv = unit.modifiers.new('Curve', type='CURVE')
crv.object = path
crv.deform_axis = 'POS_X'
print(f"arrayed:{unit.name}")
undefinedcrv = unit.modifiers.new('Curve', type='CURVE')
crv.object = path
crv.deform_axis = 'POS_X'
print(f"arrayed:{unit.name}")
undefinedRecipe 7 — Block-out (rapid composition test)
方案7 — 粗模搭建(快速构图测试)
python
import bpypython
import bpyFloor
地面
bpy.ops.mesh.primitive_plane_add(size=10)
bpy.context.active_object.name = 'GEO-floor'
bpy.ops.mesh.primitive_plane_add(size=10)
bpy.context.active_object.name = 'GEO-floor'
Hero subject
主体对象
bpy.ops.mesh.primitive_cube_add(size=1.5, location=(0, 0, 0.75))
bpy.context.active_object.name = 'GEO-subject'
bpy.ops.mesh.primitive_cube_add(size=1.5, location=(0, 0, 0.75))
bpy.context.active_object.name = 'GEO-subject'
Background prop
背景道具
bpy.ops.mesh.primitive_cylinder_add(radius=0.5, depth=2, location=(2, 1.5, 1))
bpy.context.active_object.name = 'GEO-prop_pillar'
print('blockout:done')
undefinedbpy.ops.mesh.primitive_cylinder_add(radius=0.5, depth=2, location=(2, 1.5, 1))
bpy.context.active_object.name = 'GEO-prop_pillar'
print('blockout:done')
undefinedRecipe 8 — Cleanup after curve→mesh or boolean
方案8 — 曲线转网格或布尔操作后的清理
python
import bpy
obj = bpy.data.objects['GEO-target']
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles(threshold=0.0001)
bpy.ops.mesh.normals_make_consistent(inside=False)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.shade_smooth()
print(f"cleanup:{obj.name} verts:{len(obj.data.vertices)}")python
import bpy
obj = bpy.data.objects['GEO-target']
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles(threshold=0.0001)
bpy.ops.mesh.normals_make_consistent(inside=False)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.shade_smooth()
print(f"cleanup:{obj.name} verts:{len(obj.data.vertices)}")Modifier stack order (memorize this)
修改器堆栈顺序(务必牢记)
Mirror → Array → Solidify → Bevel → Subdivision Surface → (Boolean if needed)Wrong order = artifacts. The single most common amateur mistake is SubSurf before Bevel.
Mirror → Array → Solidify → Bevel → Subdivision Surface →(必要时添加Boolean)顺序错误会产生瑕疵。新手最常见的错误就是先添加SubSurf再添加Bevel。
Common pitfalls
常见问题
| Symptom | Fix |
|---|---|
| Default-cube look | Add Bevel (0.02m, 3 segments) and SubSurf |
| Sharp pinch on round shapes | Bevel before SubSurf, not after |
| Black faces in render | Recompute normals ( |
| Boolean creates n-gons | Apply Bool, switch to Edit, fix to quads, then SubSurf |
| Symmetry breaks | Use Mirror modifier, not duplicate-and-flip |
| Mesh has hidden interior faces | |
| 症状 | 修复方法 |
|---|---|
| 模型看起来像默认立方体 | 添加Bevel(0.02m,3段)和SubSurf修改器 |
| 圆角形状出现尖锐收缩 | 先添加Bevel再添加SubSurf,不要颠倒顺序 |
| 渲染时出现黑面 | 重新计算法线( |
| 布尔操作产生n边形 | 应用布尔修改器,切换到编辑模式,将n边形修复为四边形,再添加SubSurf |
| 对称性失效 | 使用Mirror修改器,不要复制后翻转 |
| 网格存在隐藏的内部面 | 执行 |
When to load references/overview.md
references/overview.md何时加载references/overview.md
references/overview.mdLoad when:
- The recipes here don't match the request (need bmesh-level precision, custom ops)
- Topology requirements are stricter than usual (animation-ready, game LODs)
- Performance matters (foreach_set, batch ops needed)
- The user references operators not in the recipes
The reference covers: bmesh.ops cookbook, all operators worth knowing, hard-surface workflow with MESHmachine-style chamfering, retopology guidelines, mesh-clean checklist.
bpy.ops.mesh.*在以下情况加载:
- 本指南中的方案无法匹配需求(需要bmesh级别的精度、自定义操作)
- 拓扑要求比常规更严格(适用于动画、游戏LOD模型)
- 性能至关重要(需要使用foreach_set、批量操作)
- 用户提及本指南未涵盖的操作符
参考文档包含:bmesh.ops使用手册、所有值得了解的操作符、MESHmachine风格倒角的硬表面工作流、拓扑重构指南、网格清理检查清单。
bpy.ops.mesh.*What this skill is NOT for
本技能不适用的场景
- Wireframe drawing → 3D model: use
wireframe-to-3d - Sculpting strokes: Blender's sculpt mode is gestural; can't be driven well from text
- Sweep-along-path / lofting / curve-driven shapes: covered in
wireframe-to-3d/references/blender-patterns.md - Materials / lighting / rendering: redirect to those skills
- 线框绘图转3D模型:使用技能
wireframe-to-3d - 雕刻笔触:Blender的雕刻模式是手势操作,无法通过文本很好地驱动
- 沿路径扫掠/放样/曲线驱动形状:请查看
wireframe-to-3d/references/blender-patterns.md - 材质/灯光/渲染:引导至对应技能