blender-modeling について
blender-modelingは、自然言語の依頼をもとにBlenderのジオメトリを作成・編集するスキルです。Blender MCPで実行するPythonコードを使い、メッシュやモディファイアの手順を示す一方、スカルプトなど対象外の作業も明記しています。
主な機能
- 01自然言語によるジオメトリ作成
- 02Pythonによるメッシュ編集
- 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 を優先して使用し、タスク全体を通して選択したバックエンドを維持してください。レシピ内のツール名はクライアント/レガシーの例です。参照先とエージェントホストガイドを使って対応付けてください。
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のままにしないでください。 - 結果を解析できるよう、構造化して出力してください。
- 長い一連の処理は複数回の呼び出しに分けてください。
レシピ
重要:細長いオブジェクトの軸の向き
細長い/非対称な対象(剣の刃、ナイフ、ボトル、板、骨、ドライバーの先端など)では、3 つの軸がそれぞれ異なる意味を持ちます。
- 長軸 — オブジェクトの長さ(剣の刃の場合は 78cm)
- 幅軸 — 幅の広い面の軸。「適切な」視点から見える面(刃の場合は 4.5cm — テーブルに置くときに下にする平らな面)
- 薄軸 — 幅の狭い断面の軸(刃の場合は 0.8cm — 刃先)
ヒーローショットでは、細長いオブジェクトの幅軸がカメラを向くように配置してください。 刃を真横から(カメラが薄軸の方向から見るように)撮影すると、細い棒のようにレンダリングされ、剣とはまったく違って見えます。以下のレシピでは、この規則を使用しています。
| 規則 | X(オブジェクトのローカル空間の左右) | Y(オブジェクトのローカル空間の前後) | Z(上下) |
|---|---|---|---|
| 剣の刃 | 薄(0.8cm) | 幅広(4.5cm) | 長(78cm)— 垂直 |
| ナイフの刃 | 薄 | 幅広 | 長 — 水平 |
| 板 | 薄 | 幅広 | 長 |
| ボトル | 対称(半径) | 対称(半径) | 長(高さ) |
作成後、幅軸がおおよそカメラを向くようにオブジェクトを回転させてください。 カメラが前方(-Y 方向)にある状態で剣を直立させる場合は、刃を Z 軸の周りに 90° 回転させ、ローカル Y(幅広)をワールド X に向けます。これでカメラの視点から幅広の面が見えるようになります。
重要:パーツを滑らかにつなぐ(継ぎ目を見せない)
複数のパーツで構成される対象(剣=刀身+鍔+柄+柄頭、椅子=座面+背もたれ+4本の脚)を組み立てるとき、プリミティブ同士を面の境界でぴったり接するように配置すると、数学的には接していても目に見える継ぎ目ができます。さらに悪いことに、異なる形状のプリミティブ(円柱の柄を立方体の鍔に接続するなど)では、「円柱が長方形に乗っている」ような境界が目立ちます。
2つの修正方法を併用します。
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
完全に継ぎ目のない接合(高品質なレンダリング向け)にするには、同じマテリアルのパーツをブーリアン結合します。たとえば、柄頭と柄をブーリアン結合して単一のメッシュにすると、継ぎ目を完全になくせます。ただし、この方法が使えるのは両方のパーツに同じマテリアルを使用している場合だけです。
重要:先端を尖らせる(刀身の切っ先など)
上部の頂点をゼロに近づけるようにスケールするだけでは、「彫刻刀で削ったような平らな」先端になります。上部の頂点すべてを1点に集めてマージします。
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を使わないと、つぶした4つの頂点が同じ座標にある別々の点として残ります。先端は見た目上尖っていても、トポロジーは不正になります。
レシピ 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}")
重要:SubSurfより先にBevelを適用します。順序を逆にすると、ピンチングのアーティファクトが発生します。
レシピ 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)
順序が間違っているとアーティファクトが発生します。初心者に最もよくある間違いは、Bevelより先にSubSurfを適用することです。
よくある問題
| 症状 | 修正方法 |
|---|---|
| デフォルトの立方体のような見た目 | Bevel(0.02m、3セグメント)とSubSurfを追加します |
| 丸い形状に鋭いピンチができる | Bevelは後ではなく、SubSurfより先に適用します |
| レンダリングで面が黒くなる | 法線を再計算します(mesh.normals_make_consistent) |
| ブーリアンでNゴンができる | 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で扱います - マテリアル/ライティング/レンダリング:該当するスキルに案内します