关于 blender-modeling
blender-modeling 是用于通过自然语言请求创建和编辑 Blender 几何体的技能,并由 Blender MCP 执行 Python 代码。它提供网格、修改器和硬表面建模流程,也明确说明雕刻等不适用的任务。
主要功能
- 01通过自然语言创建几何体
- 02使用 Python 编辑网格
- 03基于基本体的建模配方
- 04修改器堆栈指导
- 05布尔、镜像与阵列流程
适用场景
- 01制作硬表面道具和建筑
- 02通过挤出或内插编辑网格
- 03用布尔切割创建孔洞
- 04用粗模测试场景构图
MCP 相关
该技能将 Python 代码交由 Blender MCP 执行。它要求首次调用 Blender 前查阅后端参考,并在整个任务中沿用选定的后端。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ roble3/ cc-blender-skill --skill blender-modeling安装后在 Claude Code 中输入/blender-modeling确认已加载。
附带文件evals/evals.jsonreferences/overview.md
详细介绍
MCP 后端
适用于:在 Blender 中创建几何体、编辑网格或处理修改器堆栈。不适用于将线框转换为 3D(请使用 wireframe-to-3d),也不适用于雕刻笔触(Blender 的雕刻模式基于手势操作,而非文本驱动)。
首次调用 Blender 前,请阅读 ../text-to-blender/references/mcp-backends.md。对于共享功能,优先使用官方 MCP;整个任务期间请保持所选后端不变。配方中的工具名称是客户端/旧版示例:请根据该参考文档及其 Agent 宿主指南进行映射。
Blender 建模
通过自然语言在 Blender 中创建几何体。你将输出由 Blender MCP 执行的 Python 代码;以下模式涵盖了常见的 80% 情况。
决策树
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
代码执行规则(回顾)
- 每次后端代码执行调用都会获得一个全新的 Python 命名空间。请重新导入所有内容;使用
bpy.data.objects['name']标识对象。 - 对象名称始终使用
GEO-前缀。绝不要留下Cube.027。 - 打印结构化输出,以便解析结果。
- 将较长的序列拆分为多次调用。
配方
关键:细长物体的轴向
对于任何细长/不对称的对象(剑刃、刀刃、瓶子、木板、骨头、螺丝刀尖端等),三个轴的含义各不相同:
- 长轴——物体的长度(剑刃为 78cm)
- 宽轴——较宽的表面轴,即从“实用”视角能看到的方向(剑刃为 4.5cm——将其平放在桌上时朝上的平面)
- 薄轴——较窄的横截面轴(剑刃为 0.8cm——刀刃)
拍摄主体特写时,细长物体的宽轴始终应朝向摄像机。 如果从刀刃侧面观察一把剑(摄像机沿薄轴方向拍摄),它渲染出来就会像一根细杆,完全不像剑。以下配方遵循此约定:
| 约定 | X(物体局部空间中的左右方向) | Y(物体局部空间中的前后方向) | Z(上下方向) |
|---|---|---|---|
| 剑刃 | 薄(0.8cm) | 宽(4.5cm) | 长(78cm)——垂直 |
| 刀刃 | 薄 | 宽 | 长——水平 |
| 木板 | 薄 | 宽 | 长 |
| 瓶子 | 对称(半径) | 对称(半径) | 长(高度) |
建模完成后,旋转物体,使宽轴大致朝向摄像机。对于一把直立的剑,若摄像机位于前方(摄像机朝向 -Y 方向),则将剑刃绕 Z 轴旋转 90°,使其局部 Y(宽)轴指向世界 X 轴,这样从摄像机视角就能看到宽面。
关键:让部件平滑连接(不留可见接缝)
组装由多个部分组成的物体时(剑 = 刀刃 + 护手 + 握柄 + 剑首;椅子 = 座面 + 靠背 + 4 条椅腿),若分离的基本体恰好沿着对齐的面边界相接,就会留下可见接缝,尽管从数学上看它们确实相接。更糟的是,不同形状的基本体(圆柱形握柄接入立方体护手)会产生明显的“圆柱接矩形”边界。
两种修复方法,配合使用:
1. 在连接处让部件充分重叠。 在每个连接处,让相邻的基本体相互穿插 5–15mm。隐藏的体积会消失在较大的部件内部,不留下可见接缝。
# Sword example: grip extends 1.5cm INTO the guard above and 1cm INTO the pommel below
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
圆柱形握柄顶部的 1.5cm 位于护手立方体内部——从外部看不见,因此你看到的过渡只是金色护手表面,不会出现圆柱与矩形相接的瑕疵。
2. 对圆润部件应用 shade_smooth()(圆柱体、球体、有机形状)。平面着色的圆柱体会显露每条面片边界;平滑着色则看起来连续。立方体和带倒角的硬表面部件可以保持平面着色(也可以通过 Blender 4.x 中的 Auto Smooth 部分平滑;Blender 5.x 已移除 Mesh.use_auto_smooth,因此请使用基于修改器的平滑或逐面标志)。
# After creating each rounded primitive
bpy.ops.object.shade_smooth()
反面模式(出现可见接缝):
# ❌ 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
# Result: clear line where each pair of surfaces meets
正确做法(通过重叠隐藏接缝):
# ✓ Pieces overlap by ~5-15mm; junction lines are inside other geometry
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
若要实现真正无缝的连接(用于高质量渲染),可对相同材质的部件执行布尔并集:例如,将剑首和握柄布尔并集为单个网格,即可彻底消除接缝。但这只适用于两个部件使用相同材质的情况。
关键:收尖至一点(用于刀刃尖端)
不要只把顶部顶点缩放至接近零——那样会产生“凿平”的尖端。将所有顶部顶点收拢到同一个点并合并:
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)
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)
# 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}")
这样会生成真正的几何尖点。如果不使用 remove_doubles,收拢后的四个顶点仍会作为位于同一坐标的四个独立点保留——尖端看起来是尖的,但拓扑是退化的。
配方 1 — 添加命名清晰的基本体
import bpy
# Add 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)}")
将 primitive_cube_add 替换为:_plane_、_uv_sphere_、_ico_sphere_、_cylinder_、_cone_、_torus_、_monkey_。每种基本体都接受相应的参数(radius、depth、vertices、segments、subdivisions)。
配方 2 — 硬表面修改器堆栈(“Bevel + SubSurf”模式)
import bpy
obj = bpy.data.objects['GEO-base_box']
# 1. Bevel modifier — round the sharp edges
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
# 2. Subdivision Surface AFTER bevel (critical order)
subsurf = obj.modifiers.new('SubSurf', type='SUBSURF')
subsurf.levels = 2
subsurf.render_levels = 3
# 3. Smooth shading
bpy.context.view_layer.objects.active = obj
bpy.ops.object.shade_smooth()
print(f"hardsurface:{obj.name}")
关键:先 Bevel,再 SubSurf。顺序颠倒会产生挤压伪影。
配方 3 — 编辑模式操作(挤出、内插面、环切)
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
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
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)}")
配方 4 — 布尔切割(钻孔)
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)
# Hide cutter from render
cutter.hide_viewport = True
cutter.hide_render = True
print(f"booleaned:{target.name}")
配方 5 — 镜像修改器(只建模一半)
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}")
将 Mirror 放在堆栈最前面(位于 Bevel/SubSurf 之前)。
配方 6 — 沿曲线阵列(链条、栅栏、珠子)
import bpy
# 1. The base unit
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)
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)
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
crv = unit.modifiers.new('Curve', type='CURVE')
crv.object = path
crv.deform_axis = 'POS_X'
print(f"arrayed:{unit.name}")
配方 7 — 初步建模(快速构图测试)
import bpy
# 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'
# 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')
配方 8 — 曲线→网格或布尔运算后的清理
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)}")
修改器堆栈顺序(记住这个顺序)
Mirror → Array → Solidify → Bevel → Subdivision Surface → (Boolean if needed)
顺序错误 = 伪影。最常见的新手错误是先 SubSurf,后 Bevel。
常见问题
| 症状 | 修复方法 |
|---|---|
| 默认立方体的外观 | 添加 Bevel(0.02m,3 个分段)和 SubSurf |
| 圆形造型上出现尖锐挤压 | 先 Bevel,再 SubSurf,而不是反过来 |
| 渲染中出现黑面 | 重新计算法线(mesh.normals_make_consistent) |
| 布尔运算生成 n-gon | 应用 Bool,切换到编辑模式,修复为四边形,然后 SubSurf |
| 对称性被破坏 | 使用 Mirror 修改器,而不是复制并翻转 |
| 网格中有隐藏的内部面 | Mesh → Clean Up → Delete Loose |
何时加载 references/overview.md
在以下情况加载:
- 此处的配方不符合请求(需要 bmesh 级别的精度或自定义操作)
- 拓扑要求比通常情况更严格(适用于动画或游戏 LOD)
- 需要考虑性能(需要使用 foreach_set、批量操作)
- 用户提到了配方中没有的运算符
该参考文档涵盖:bmesh.ops 操作指南、所有值得了解的 bpy.ops.mesh.* 运算符、采用 MESHmachine 风格倒角的硬表面工作流、重拓扑指南、网格清理检查清单。
此技能不适用于
- 线框绘图 → 3D 模型:请使用
wireframe-to-3d - 雕刻笔触:Blender 的雕刻模式依赖手势,难以通过文本有效驱动
- 沿路径扫掠 / 放样 / 曲线驱动的形状:请参阅
wireframe-to-3d/references/blender-patterns.md - 材质 / 灯光 / 渲染:请转到相应技能