@jojonadam/dsh-blender 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,6 +43,13 @@ python3 skills/blender-studio/scripts/blender_client.py run \
43
43
  | `blender-5x-pitfalls` | 5.x 的 API 变更与已知坑 |
44
44
  | `blender-asset-pipeline` | 程序化资产、批量、LOD、glTF 导出、连续网格反模式 |
45
45
  | `blender-mcp-bridge` | 需要实时操控打开着的 Blender 时接 MCP |
46
+ | `blender-triage` | 按症状排障:渲染黑图、导不出去、卡住、材质不对,附「做不到什么」清单 |
47
+
48
+ 另带三样交付工具:
49
+
50
+ - **6 份表格与工序单**(`blender-sop/templates/`):资产清单、建模参数、命名导出、交付检查、UV 展开、布光曝光——不开 Blender 也能填完交付。
51
+ - **跨表咬合检查器**(`blender-sop/scripts/check_table_consistency.py`):七字段逐项对表,矛盾带行号;自带 `--selftest` 反向验证。
52
+ - **MCP 执行器**(`blender-mcp-bridge/scripts/blender_mcp_exec.py`):对运行中的 Blender 执行任意 bpy 代码,输出可重定向落盘。
46
53
 
47
54
  ## 设计边界
48
55
 
package/locale/en.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "DSH Blender Production Pack",
4
+ "description": "Production pack for Blender: headless bpy runner, render/export, modeling cookbook and Blender 5.x pitfalls."
5
+ }
6
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "DSH Blender 生产包",
4
+ "description": "Blender 生产包:headless bpy runner、渲染导出、建模手册与 5.x 踩坑。"
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@jojonadam/dsh-blender",
3
- "version": "0.1.1",
4
- "description": "Blender production pack for DeepSeek Harness: headless bpy runner, render/export helpers, modeling cookbook, 5.x pitfalls and procedural asset pipeline. 本地建模 · 零依赖客户端 · 5.2 LTS 校准。",
3
+ "version": "0.2.0",
4
+ "description": "Blender production pack for DeepSeek Harness: headless bpy runner, render/export helpers, modeling cookbook, 5.x pitfalls, procedural asset pipeline, symptom-first triage, and delivery checklists with a cross-table consistency checker.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
8
8
  ".": "./lib/index.js",
9
9
  "./cordis.patch.yml": "./cordis.patch.yml",
10
- "./package.json": "./package.json"
10
+ "./package.json": "./package.json",
11
+ "./locale/*.json": "./locale/*.json"
11
12
  },
12
13
  "files": [
13
14
  "lib",
@@ -15,7 +16,8 @@
15
16
  "cordis.patch.yml",
16
17
  "icon.svg",
17
18
  "README.md",
18
- "LICENSE"
19
+ "LICENSE",
20
+ "locale"
19
21
  ],
20
22
  "keywords": [
21
23
  "dsh-plugin",
@@ -50,5 +52,6 @@
50
52
  "bundle": {
51
53
  "patch": "./cordis.patch.yml"
52
54
  }
53
- }
55
+ },
56
+ "icon": "icon.svg"
54
57
  }
@@ -1,23 +1,152 @@
1
1
  ---
2
2
  name: blender-5x-pitfalls
3
- description: "Blender 5.x 踩坑清单(锚定 5.2 LTS):Bevel 引用与限角陷阱、bevel_weight 移除、材质节点创建、Principled 无 Transmission、glTF 丢色 bug、transform_apply 方向陷阱。"
4
- whenToUse: "Blender 5.x / 版本升级 / Bevel / 材质 / glTF 导出 / transform_apply 时"
3
+ description: "Blender 5.x 踩坑清单(锚定 5.2 LTS):Bevel 引用/限角陷阱、bevel_weight 移除、材质节点创建、Principled 无 Transmission、glTF 顶点色降位(附买家自检)、连续网格 vs 逐立方体、transform_apply 方向陷阱。快速避坑。"
4
+ whenToUse: "Blender 建模 / 渲染 / 导出 / 排障 / MCP 接线 时"
5
5
  license: MIT
6
6
  ---
7
7
 
8
-
9
8
  # Blender 5.x 踩坑清单(blender-5x-pitfalls)
10
9
 
11
- > DSH 执行层(headless 跑 Blender、渲染、导出):见 `blender-studio` 技能。
12
-
13
-
14
10
  **锚定 5.2 LTS。** 本环境已踩过的真实 bug,建脚本前先查,避免重蹈。详见 `blender-sop` / `blender-asset-pipeline` / `blender-modeling-cookbook`。
15
11
 
16
12
  ## 🔴 致命级(必踩无疑,先读)
17
13
 
18
14
  1. **Bevel 引用**:用 `obj.modifiers.new(name="Bevel", type='BEVEL')` 拿引用,不用 `bpy.ops.object.modifier_add(type='BEVEL')` 后按名 `obj.modifiers["Bevel"]` 取 —— 5.x 报 `key "Bevel" not found`。
19
15
  2. **Bevel 必须限角**:`limit_method='ANGLE'` + `angle_limit`(如 40°)。默认 `NONE` 会把**所有边(含平顶内部网格线)全倒角** → 平顶重引缝。限角后只磨圆崖壁/外缘(90°),平顶 0° 不动。
20
- 3. **glTF 色导出 bug(5.2)**:顶点色→白色 `COLOR_0`(ubyte)+畸形 `COLOR_1`(ushort);纯色材质→无 `pbrMetallicRoughness`。**对策:GLB 只出几何,颜色全在下游引擎侧套。** `export_scene.gltf` **无 `export_colors` 参数**(5.x 已移除)→ 用 `export_format='GLB', export_materials='EXPORT'`。
16
+ 3. **glTF 顶点色降位(5.2 实测,有解)**:默认参数导出时,顶点色会变成 `COLOR_0`(componentType **5121 / ubyte**),并额外冒出一个畸形的 `COLOR_1`(5123 / ushort),精度掉一档,引擎侧看就是偏色发白。
17
+ - **根因不是修不了的 bug**:Blender 导出时会自己打一行警告 `The active Vertex Color will not be exported, as it is not used in the node tree of the material`——**顶点色没被材质节点树引用时,导出器会补一个 ubyte 的 `COLOR_0` 兜底**,把真实顶点色挤到 `COLOR_1`。
18
+ - **解法(实测均有效,二选一)**:① 把顶点色真的接进材质:`ShaderNodeVertexColor`(`layer_name` 填属性名)→ Principled 的 `Base Color`;② 导出时显式 `export_vertex_color='ACTIVE'`。
19
+ - **纯色材质不受影响**:实测 `pbrMetallicRoughness` 与 `baseColorFactor` 正常存在。(此前本文写「纯色材质→无 `pbrMetallicRoughness`」,在 5.2.1 LTS 上**未复现**,已更正。)
20
+ - **保守策略**:若下游需要精确控色,仍可「GLB 只出几何、颜色到引擎侧套」——最稳,但不是唯一解,别为此放弃在 Blender 侧上色。
21
+ - `export_scene.gltf` **无 `export_colors` 参数**(5.x 已移除)→ 用 `export_format='GLB'`、`export_materials='EXPORT'`,顶点色开关走 `export_vertex_color`。
22
+ - 🔍 **你的环境丢不丢,跑下面这段自检就知道**(一次 GLB 导出 + 一次 JSON chunk 解析;跑完按名字还原选择与活动物体):
23
+ ```python
24
+ # 把这段整体丢给 execute_blender_code 跑。它不会在你的场景里留下任何东西:
25
+ # 只建一个临时四面体、导一个小 GLB、就地解析 JSON chunk,
26
+ # 跑完删掉临时物体/网格/材质与临时文件,并把选择与活动物体按名字还原。
27
+ # 注意:还原做不到的部分它会直说(例如文件被标记「已修改」)。
28
+ def _verify_gltf():
29
+ import bpy, json, struct, os, tempfile
30
+ from contextlib import suppress
31
+
32
+ # ① 只在 Object Mode 下跑 —— EDIT/SCULPT 等模式下 select_set 会直接抛异常
33
+ if bpy.context.mode != 'OBJECT':
34
+ print("⚠️ 当前是 %s 模式,本自检未执行、场景未改动。"
35
+ "请先按 Tab 切到 Object Mode 再跑。" % bpy.context.mode)
36
+ return
37
+
38
+ vl = bpy.context.view_layer
39
+ # ② 快照用户的选择与活动物体(存名字,跑完按名字还原)
40
+ # ⚠️ 这里必须跳过 None:买家场景里可能本来就带失效项(删过物体但槽没清),
41
+ # 不跳过的话会在「还没建任何东西」之前就抛 AttributeError,
42
+ # 等于把下面 ④ 才防住的同一个坑留在了上游。
43
+ sel = [o.name for o in list(vl.objects) if o is not None and o.select_get()]
44
+ act = vl.objects.active.name if vl.objects.active else None
45
+ dirty_before = bpy.data.is_dirty
46
+
47
+ p = os.path.join(tempfile.gettempdir(), "_verify_gltf.glb")
48
+ ob = me = mt = None
49
+ try:
50
+ me = bpy.data.meshes.new("_verify_me")
51
+ me.from_pydata(
52
+ [(0,0,0),(1,0,0),(0,1,0),(0,0,1)], [],
53
+ [(0,1,2),(0,1,3),(0,2,3),(1,2,3)])
54
+ me.update()
55
+ ob = bpy.data.objects.new("_verify_ob", me)
56
+ bpy.context.scene.collection.objects.link(ob)
57
+ ca = me.color_attributes.new(name="Col", type='BYTE_COLOR', domain='CORNER')
58
+ for d in ca.data: d.color = (0.1, 0.9, 0.3, 1.0)
59
+ me.color_attributes.active_color = ca
60
+ mt = bpy.data.materials.new("_verify_mat")
61
+ if mt.node_tree is None: # 5.x 新材质自带节点树 → 正常不会走到这行
62
+ mt.use_nodes = True # 5.x 直接赋 True 会打 DeprecationWarning,故先判断
63
+ nt = mt.node_tree
64
+ if nt and "Principled BSDF" in nt.nodes:
65
+ nt.nodes["Principled BSDF"].inputs["Base Color"].default_value = (0.8,0.2,0.2,1)
66
+ ob.data.materials.append(mt)
67
+
68
+ for o in list(vl.objects):
69
+ if o is not None: o.select_set(False)
70
+ ob.select_set(True); vl.objects.active = ob
71
+ # 导出器本身可能不可用(买家把内置 glTF 插件关了,或参数不被当前版本支持)。
72
+ # 这时不能把原始 traceback 甩给买家 —— 场景仍会由 finally 还原,但要让他看懂发生了什么。
73
+ try:
74
+ bpy.ops.export_scene.gltf(
75
+ filepath=p, export_format='GLB',
76
+ export_materials='EXPORT', use_selection=True)
77
+ except Exception as e:
78
+ print("⚠️ GLB 导出失败,本自检未完成 —— 卡在导出环节,与颜色是否丢失无关。")
79
+ print(" 常见原因:内置 glTF 插件被禁用;或 export_materials 等参数不被当前 Blender 版本支持。")
80
+ print(" 你的场景与选择会在本段结束时照常还原。")
81
+ print(" 原始错误:%r" % (e,))
82
+ return
83
+
84
+ with open(p, "rb") as f:
85
+ f.read(12); clen, _ = struct.unpack("<II", f.read(8))
86
+ g = json.loads(f.read(clen).decode("utf-8"))
87
+ ct = {}
88
+ for pr in g["meshes"][0]["primitives"]:
89
+ for k, v in pr["attributes"].items():
90
+ if k.startswith("COLOR"): ct[k] = g["accessors"][v]["componentType"]
91
+ NM = {5120:"byte",5121:"ubyte",5122:"short",5123:"ushort",5125:"uint",5126:"float"}
92
+ pbr = any("pbrMetallicRoughness" in (m or {}) for m in g.get("materials", []))
93
+ bad = any(v == 5121 for v in ct.values()) or len(ct) > 1
94
+ print("COLOR 属性:", {k: NM.get(v, v) for k, v in ct.items()})
95
+ print("有 pbrMetallicRoughness:", pbr)
96
+ print("判定:", "🔴 丢色(COLOR_0 被降为 ubyte 或出现多层 COLOR_x)" if bad else "🟢 不丢色")
97
+ print("本次用的临时样本(GLB,跑完即删除,可用 glTF 查看器对照):", p)
98
+ finally:
99
+ # ③ 清理顺序:物体 → 网格 → 材质
100
+ # 只删物体会让 _verify_me / _verify_mat 变孤儿继续留在 bpy.data
101
+ for db, blk in ((bpy.data.objects, ob), (bpy.data.meshes, me),
102
+ (bpy.data.materials, mt)):
103
+ if blk is not None:
104
+ with suppress(Exception): db.remove(blk)
105
+ with suppress(Exception): os.remove(p)
106
+ # ③.5 让 view_layer 重新求值。
107
+ # 背景:`objects.remove()` 只删数据块,`view_layer.objects` 会短暂留一个「死槽」,
108
+ # 此刻遍历会拿到 None(实测:删完 len=1 / list=[None],update() 后 len=0 / list=[])。
109
+ # 下面 ④ 已经对 None 做了防御,所以**不调这一行也能跑通**;这里是保险——
110
+ # 让槽真正清掉,而不是只跳过它,避免后续自己遍历时又撞上。
111
+ with suppress(Exception): bpy.context.view_layer.update()
112
+ # ④ 还原选择与活动物体(快照里已被删掉的物体自动跳过)
113
+ # 逐物体 try:一个失败不阻断其余;**失败时绝不打印「已还原」**
114
+ errs = []
115
+ for o in list(vl.objects):
116
+ # 即便上面 update() 已清槽,这里仍保留 None 判断:买家场景可能本就带失效项。
117
+ # 对它调 select_set 会抛,再在 except 里读 o.name 会二次抛,
118
+ # 第二次是从 except 里逃逸的,会带着整个还原段一起中断(早期版本实测踩过)。
119
+ if o is None:
120
+ continue
121
+ try: o.select_set(False)
122
+ except Exception as e: errs.append("取消选择 %s: %r" % (getattr(o, "name", "失效对象"), e))
123
+ for n in sel:
124
+ o = bpy.data.objects.get(n)
125
+ if o is None or n not in vl.objects:
126
+ continue
127
+ try: o.select_set(True)
128
+ except Exception as e: errs.append("选中 %s: %r" % (n, e))
129
+ try:
130
+ vl.objects.active = bpy.data.objects.get(act) if act else None
131
+ except Exception as e:
132
+ errs.append("设置 active: %r" % (e,))
133
+ if not errs:
134
+ print("已还原选择与活动物体 —— 原选中:", sel, "原 active:", act)
135
+ else:
136
+ print("⚠️ 还原未完成,选择或活动物体可能已被改动,请手动核对:",
137
+ ";".join(errs), "|快照: 原选中", sel, "原 active", act)
138
+ if bpy.data.is_dirty != dirty_before:
139
+ print("⚠️ 本次自检让文件被标记为「已修改」(is_dirty 无法可靠复位,"
140
+ "不假装能还原);不想保存就别保存。")
141
+
142
+ _verify_gltf()
143
+ ```
144
+
145
+ **怎么读结果**:
146
+ - `COLOR_0: ubyte` + 多一个 `COLOR_1: ushort` → 你的环境**复现**该降位,按上面解法 ①/② 处理。
147
+ - `COLOR_0` 是 `ushort` 或 `float` 且只有一层 → 你的环境**不丢色**,可直接在 Blender 侧上色。
148
+ - `有 pbrMetallicRoughness: False` → 纯色材质也被吞了,属另一个问题,把 Blender 版本号与这段输出一起报给技术支持。
149
+
21
150
  4. **`transform_apply(location=True)` 把 `obj.location` 归零**:apply 之后用 `obj.location.x/y` 判方向会符号全翻 → 整块所有竖直棱被误选。**改用顶点包围盒中心** `0.5*(min+max)` 判方向。
22
151
 
23
152
  ## 🟠 高频级
@@ -29,12 +158,33 @@ license: MIT
29
158
  9. **Eevee 已重写(EEVEE-Next)**:不假设 4.x 旧 Eevee 行为;灯光/材质节点差异。
30
159
  10. **`look` 回传被过滤**:部分环境 "model does not support images" → agent 无法视觉自检,靠客观 DIAG/PROOF(法线分布/坐标/渐变顶点数)+ 用户眼睛终审。
31
160
 
161
+ ## 🟠 高频级 · 无头 API 注记(round 2 实机复现,禁删改语义)
162
+
163
+ 10a. **`bpy.ops.mesh.loopcut_slide` 无头 segfault(rc=139)**:try/except 拦不住(进程直接崩)→ 等价 `bmesh.ops.subdivide_edges`。〔无头实测·实录 2.0 候选〕
164
+ 10b. **`bpy.ops.sculpt.brush_stroke` 无头 `poll() failed`**:需 UI 上下文,拒绝初始化 stroke → 无头用 bmesh 位移(`vert.co += …`)等价。〔无头实测·实录 2.0 候选〕
165
+ 10c. **`bmesh.ops.smooth_vert` 5.2 无 `iterations` 参数**:传了报错 → 手动循环多次调用。〔无头实测·实录 2.0 候选〕
166
+ 10d. **glTF/STL 导出自动三角化,FBX 保留四边**:回读判据别拿四边面数直比,按**三角计数**比对(`Σ(len(p.vertices)-2)` 三角化前后不变)。〔无头实测;与评测集 A9 判据呼应〕
167
+
32
168
  ## 🟡 架构级(反模式)
33
169
 
34
170
  11. **逐立方体各自顶点色 = 缝 + 色糊**:地面/地形必须用一整张连续 heightfield,顶点色 splat 只在边界带、块中心纯色。
35
171
  12. **bmesh 跨会话 bevel 报 `BMEdge has been removed`**:选中+bevel+to_mesh+free 必须在**单 bmesh 会话内**完成。
36
172
  13. **过渡名无拓扑后缀互相覆盖**:加 `_inland/_side/_corner` 区分。
37
173
 
174
+ ## 🔵 用户可感知的 5.x 变化(不是脚本坑,是操作差异)
175
+
176
+ **这几条是用户从 4.x 升上来最常踩的:**
177
+
178
+ | 变化 | 用户会怎么感觉到 | 怎么办 |
179
+ |---|---|---|
180
+ | **Eevee 已重写(EEVEE-Next)** | 同样的灯光设置,渲染结果和 4.x 不一样;阴影更实 | 别拿 4.x 经验直接套,重新调一次灯光强度与阴影 |
181
+ | **Principled BSDF 无 Transmission** | 做玻璃/水找不到 Transmission 滑块 | 用 Alpha + Blend Mode;或改用 Cycles 折射 |
182
+ | **bevel_weight 边权重移除** | 4.x 的按权重倒角教程做不出来 | 用 Bevel 修改器的 Angle 模式 |
183
+ | **export_colors 参数移除** | 想控制 glTF 导出颜色,发现没这选项 | 用 `export_vertex_color`(`'ACTIVE'` / `'MATERIAL'` / `'NONE'`)+ `export_materials`;详见致命级第 3 条 |
184
+ | **材质面板布局调整** | 找不到某个设置 | 认准 Material Properties 顶部三个 tab:Surface / Volume / Settings |
185
+
186
+ **升级建议**:4.x 项目迁 5.x,先在副本上跑一遍完整渲染对比,别直接开原文件。
187
+
38
188
  ## 关联
39
189
 
40
190
  - 版本/渲染器/导出纪律总纲 → `blender-sop` §1/§2/§4。
@@ -1,19 +1,15 @@
1
1
  ---
2
2
  name: blender-asset-pipeline
3
- description: "Agent 驱动的程序化资产管线:先设计再动手,AI 写参数化 bpy 脚本 + 自检 + glTF 导出,人负责美术方向。覆盖三硬限制、Bevel 圆角、CC0 拉取、LOD 导出与连续网格反模式。"
4
- whenToUse: "Blender 资产管线 / 程序化生成 / 游戏资产 / glTF / LOD / 批量 时"
3
+ description: "Agent 驱动的 Blender 程序化游戏资产管线:先设计再动手,AI 写参数化 bpy 脚本 + `look` 自检 + 导出 glTF,用户定美术方向。覆盖三硬限制、Bevel 圆角、CC0 直拉、glTF/LOD 导出、连续网格反模式。已通用化(剥离项目夹具)。"
4
+ whenToUse: "Blender 建模 / 渲染 / 导出 / 排障 / MCP 接线 时"
5
5
  license: MIT
6
6
  ---
7
7
 
8
-
9
8
  # Blender 资产管线 · 设计优先的协作建模
10
9
 
11
- > DSH 执行层(headless 跑 Blender、渲染、导出):见 `blender-studio` 技能。
12
-
13
-
14
10
  **先设计,再动手;代码即资产表征,用户定美术方向。**
15
11
 
16
- 本技能把「Agent 用 Blender 建模」的圈内先进经验固化为可复用流程。核心思想来自 LL3M(arXiv 2508,把 3D 生成重定义为写可解释 bpy 代码)、AAA Blender Modeling Playbook(参数化优先 + 精修循环)、StraySpark(数百小时实战的三条硬限制)。**本版已通用化**:剥离了原 Seele 小岛项目的 6×6 演示夹具、TYPE_MAP/HEIGHT_MAP 硬编码、Godot 侧上色段落与项目红线,仅保留可复用的技法与纪律。
12
+ 本技能把「Agent 用 Blender 建模」的圈内先进经验固化为可复用流程。核心思想来自 LL3M(arXiv:2508.08228,Lu 等,2025——把 3D 生成重定义为写可解释的 bpy 代码)、AAA Blender Modeling Playbook(参数化优先 + 精修循环)、行业实践中的三条硬限制。**本版已通用化**:剥离了某商业项目的 6×6 演示夹具、TYPE_MAP/HEIGHT_MAP 硬编码、下游引擎侧上色段落与项目红线,仅保留可复用的技法与纪律。
17
13
 
18
14
  ## 适用场景
19
15
 
@@ -34,7 +30,7 @@ license: MIT
34
30
  - **Spec 表锚定数值**:尺寸(如 1×1 grid 单位)、三角预算(tile ≤ 200、树 ≤ 1500)、配色、pivot。数值写死 → agent 行为确定、可复现。
35
31
  - **参数化 > 生成式 > 基元**:优先用参数化库/脚本;外部 AI 生成(`generate_3d` / Hunyuan3D)次之;纯基元 blockout 仅做占位。
36
32
 
37
- ## 三条硬限制(必守,来自 StraySpark)
33
+ ## 三条硬限制(必守)
38
34
 
39
35
  1. **创意拓扑不是 agent 的活**:LLM 出不了生产级拓扑。agent 只出 blockout / 占位 / low-poly 代理;圆润比例、轮廓、配色由用户定。手动重拓扑/UV/绑定/动画必须人审。
40
36
  2. **重操作会超时**:细分(Subsurf)、重拓扑、纹理烘焙可能超过 MCP 工具超时(通常 60–120s)。大任务拆小步;或手动跑长任务。
@@ -47,7 +43,7 @@ license: MIT
47
43
  | A 简报+参考 | 定 1–3 张参考图 + 写 Spec 表(尺寸/三角预算/配色/pivot) | 用户给方向 | Spec 表 |
48
44
  | B 参数化构建 | bpy + Bevel 生成 low-poly,或 `generate_3d` 拉云端模型进来精修 | agent | .blend |
49
45
  | C 截图检视 | `look` 渲 turntable/接触表,对照 Spec 自检 3 个最高影响问题 | agent | 截图+缺陷清单 |
50
- | D 导出 | glb → 资产目录,apply transform + 可选 Decimate LOD | agent | .glb(几何-only) |
46
+ | D 导出 | glb → 资产目录,apply transform + 顶点色接进材质 + 可选 Decimate LOD | agent | .glb |
51
47
  | E 引擎实测 | 引擎内替换占位、跑场景看比例/锚点/视觉 | 用户+agent | 修订项 |
52
48
 
53
49
  > ⚠️ 工具名对齐 mcp-for-blender:阶段 C 用 `look`(非旧版 `get_viewport_screenshot`);阶段 B 云端造模用 `generate_3d`(非旧版 `generate_hyper3d_model`);CC0 直拉用 `search_assets`(非旧版 `get_polyhaven_assets`)。
@@ -86,15 +82,15 @@ license: MIT
86
82
  - 判竖直棱:两顶点 `abs(x1-x2)<eps and abs(y1-y2)<eps`(忽略 z 差)→ 竖直;其 `xs=sign(x-中心x)`、`ys=sign(y-中心y)` 决定属于哪侧。
87
83
 
88
84
  ### 导出坑(已修)
89
- - **Blender 5.2 glTF 色导出 bug**:顶点色→白色 `COLOR_0`(ubyte)+畸形 `COLOR_1`(ushort);纯色材质→无 `pbrMetallicRoughness`。**对策:GLB 只出几何,颜色全在下游引擎(Godot/Maya/Unity)侧套** `StandardMaterial3D` / PBR。不要在 Blender 侧烤色。
85
+ - **Blender 5.2 glTF 顶点色降位**:默认导出时顶点色变 `COLOR_0`(ubyte) + 多出畸形 `COLOR_1`(ushort)。根因=顶点色**没被材质节点树引用**。**对策:把顶点色接进材质(`ShaderNodeVertexColor` → Base Color)或 `export_vertex_color='ACTIVE'`**;下游要精确控色时,仍可「GLB 只出几何、颜色在下游引擎侧套」。纯色材质 `pbrMetallicRoughness` 实测正常。
90
86
  - bmesh 跨会话 bevel 报 `BMEdge has been removed` → 选中+bevel+to_mesh+free 必须在**单 bmesh 会话内**完成。
91
87
  - 过渡名无拓扑后缀互相覆盖 → 加 `_inland/_side/_corner` 后缀区分。
92
88
 
93
89
  ## 连接与工具(mcp-for-blender)
94
90
 
95
- - MCP 配置:`~/.workbuddy/mcp.json` 的 `blender` 节点(`command: uvx blender-mcp`, `BLENDER_PORT=9876`)。
96
- - 插件:`~/Library/Application Support/Blender/5.2/scripts/addons/blender_mcp_addon.py`(Blender 内 Edit→Preferences→Add-ons 启用 "Blender MCP",N 面板 BlenderMCP → Start MCP Server)。
97
- - **可复用 helper**:`/Users/jojo/AI_Projects/Seele/tools/blender_mcp_exec.py` — 读 .py 脚本或 stdin,经 `uvx blender-mcp` 桥在 Blender 内执行并返回输出:`python3 blender_mcp_exec.py script.py`(需 Blender 已开 + 插件服务端已启动)。
91
+ - MCP 配置:`~/.workbuddy/mcp.json` 的 `blender` 节点(`command: uvx mcp-for-blender`, `BLENDER_PORT=9876`)。
92
+ - 插件:`uvx mcp-for-blender install-addon` 自动装到 Blender 的 addons 目录(`uvx mcp-for-blender addon-paths` 可查实际路径)→ Blender 内 Preferences → Add-ons 启用 `Interface: MCP for Blender` → N 面板点 Start MCP Server。
93
+ - **可复用 helper**:`scripts/blender_mcp_exec.py` — 读 .py 脚本或 stdin,经 `uvx mcp-for-blender` 桥在 Blender 内执行并返回输出:`python3 scripts/blender_mcp_exec.py script.py`(需 Blender 已开 + 插件服务端已启动)。
98
94
  - 视觉自检:`look`(rendered 通道,返回场景渲图)替代旧 `get_viewport_screenshot`。
99
95
 
100
96
  ## CC0 素材直拉(mcp-for-blender 内集成)
@@ -111,3 +107,13 @@ license: MIT
111
107
  - 新资产类别(树/屋/角色)沉淀为可复用 bpy 函数片段,附在本技能或独立参考文件。
112
108
  - 用户美术方向偏好(配色、轮廓、圆角强度)→ 记入 Spec 表默认模板。
113
109
  - 不擅自推翻 `blender-sop` 级红线;涉及决策变更先与主理人(艾芙琳)对齐。
110
+
111
+ ## 无 Blender 时的资产交付
112
+
113
+ 连不上 MCP、或买家还没装 Blender 时,**资产管线照样能交**:
114
+
115
+ - 按 `templates/asset_list.md` 填资产清单(类型用 `SM_` / `ENV_` / `CH_` 三档,别自造)
116
+ - 按 `templates/naming_export.md` 定前缀与 **glTF 导出参数**(+Y up、米、三角化、切线、是否含动画)
117
+ - 交付的是**建模的人能照着开工**的清单,不是"听起来专业"的描述
118
+
119
+ **不许只回「请先安装 Blender」。** 先给清单,再谈建模。
@@ -1,24 +1,20 @@
1
1
  ---
2
2
  name: blender-mcp-bridge
3
- description: "把 mcp-for-blender 接到 DSH:uvx 启动、Blender 5.2 插件、连接前提、真实工具名对齐、连通性验证与按需加载。用于需要实时操控 Blender 的交互场景。"
4
- whenToUse: "Blender MCP / 实时操控 / 交互式 / uvx / 插件 / 连接失败 时"
3
+ description: "接线 mcp-for-blender(uvx mcp-for-blender + 5.2 插件):连接前提、真实工具名对齐(非旧版 blender-mcp)、连接证明、按需加载。让工作室能真正操控 Blender。"
4
+ whenToUse: "Blender 建模 / 渲染 / 导出 / 排障 / MCP 接线 时"
5
5
  license: MIT
6
6
  ---
7
7
 
8
-
9
8
  # Blender MCP 接线(blender-mcp-bridge)
10
9
 
11
- > DSH 执行层(headless 跑 Blender、渲染、导出):见 `blender-studio` 技能。
12
-
13
-
14
- 让团队能**在运行中的 Blender 5.2 内**被智能体驱动。本机操控层是增强版 **mcp-for-blender**(经 `uvx blender-mcp` 安装,工具命名空间 `mcp__blender__*`),**不是**社区基础版 `blender-mcp`(ahujasid)。
10
+ 让团队能**在运行中的 Blender 5.2 内**被智能体驱动。本机操控层是增强版 **mcp-for-blender**(经 `uvx mcp-for-blender` 安装,工具命名空间 `mcp__blender__*`),**不是**社区基础版 `blender-mcp`(ahujasid)。
15
11
 
16
12
  ## 配置现状(本机已就绪)
17
13
 
18
- - **MCP 配置**:`~/.workbuddy/mcp.json` 的 `blender` 节点:`command: uvx blender-mcp`,`BLENDER_PORT=9876`,`disabled:false`。
19
- - **本地插件**:`~/Library/Application Support/Blender/5.2/scripts/addons/blender_mcp_addon.py`(175KB,2026-09-14)。
20
- - **连接前提**:Blender 必须**开着**且插件服务端**已启动**(N 面板 → BlenderMCP → Start MCP Server)。当前没开 → 实测 `get_addon_status` 返回「Could not connect to Blender」。这与 Godot 当初"误判无 MCP"同一剧本——操控层存在,只是需用户先开软件。
21
- - **没有** Godot 那种编辑器自动拉起;Blender MCP 需用户在 Blender 内手动点启动(或后续研究能否 CLI 拉起 + 触发服务端)。
14
+ - **MCP 配置**:`~/.workbuddy/mcp.json` 的 `blender` 节点:`command: uvx mcp-for-blender`,`BLENDER_PORT=9876`,`disabled:false`。
15
+ - **本地插件**:`uvx mcp-for-blender install-addon` 自动装到 Blender 的 addons 目录;`uvx mcp-for-blender addon-paths` 可查实际路径。插件与服务端的协议版本必须一致,不一致时连接报错很含糊——这是首跑失败最常见的原因。
16
+ - **连接前提**:Blender 必须**开着**且插件服务端**已启动**(N 面板 → `MCP for Blender`(旧版显示为 BlenderMCP)→ Start MCP Server)。当前没开 → 实测 `get_addon_status` 返回「Could not connect to Blender」。这不是「没有 MCP」,而是操控层已经存在、只差用户先把软件开起来。
17
+ - **没有**编辑器自动拉起这回事;Blender MCP 需用户在 Blender 内手动点启动(或后续研究能否 CLI 拉起 + 触发服务端)。
22
18
 
23
19
  ## 连接证明(Phase 0.5 闸门)
24
20
 
@@ -36,7 +32,16 @@ license: MIT
36
32
  | `look` | 渲图看场景:viewport/camera/多角度/帧序列,solid/material/rendered/wireframe/xray | **视觉反馈通道**(替代旧 `get_viewport_screenshot`,更强) |
37
33
  | `search_assets` | 搜 polyhaven(CC0)/sketchfab/Polypizza(CC0/CC-BY) | CC0 资产直拉 |
38
34
  | `generate_3d` | 文本/图像→带贴图 3D 模型,tripo/hunyuan3d/hyper3d,Premium 档 | AI 造模(独有道具),再进 Blender 精修 |
39
- | (导出/导入) | glTF/GLB/FBX/OBJ/STL/USD/ABC/PLY | 资产出 Blender → 引擎/AR/打印 |
35
+ | `import_asset` | 把 `search_assets` 搜到的资产下载并**导入**当前场景 | 资产落进场景 |
36
+ | `disable_telemetry` | 关掉 prompt/代码/截图/场景数据的采集 | 隐私合规 |
37
+ | `record_trajectory_feedback` | 对某一轨迹步记录评价反馈 | 团队自查 |
38
+
39
+ **上表即全部 9 个工具,一个不多一个不少**(2026-10-22 实机 `tools/list` 核验:PyPI 最新 `mcp-for-blender` 2.2.2,`serverInfo` 自报 `1.30.0`)。
40
+
41
+ > 🔴 **没有独立的 export 工具,也没有 import 工具之外的任何「文件转换」工具。**
42
+ > 导出 glTF/GLB/FBX/OBJ/STL/USD/ABC/PLY 一律由 `execute_blender_code` 调 `bpy.ops.export_scene.*` 完成,
43
+ > 格式能不能出取决于你的 Blender 装没装对应插件(glTF/USD 内置,FBX/OBJ/STL 内置,ABC/PLY 多数版本内置)。
44
+ > **别去找 `export_gltf` / `export` / `(导出/导入)` 这种工具,它不存在。** 照着不存在的工具写脚本,买家只会拿到一句「工具不存在」。
40
45
 
41
46
  > ⚠️ **与旧基础版 blender-mcp 的工具名差异**(建脚本/技能时务必对齐本表):
42
47
  > 旧 `get_viewport_screenshot` → 现 `look`;旧 `get_polyhaven_assets` → 现 `search_assets`;旧 `generate_hyper3d_model` → 现 `generate_3d`。直接照搬旧名会调不到工具。
@@ -45,8 +50,8 @@ license: MIT
45
50
 
46
51
  | 成员 | 常用工具 |
47
52
  |---|---|
48
- | blender-tech-mcp | get_addon_status / execute_blender_code / 导出全系 / search_assets / generate_3d |
49
- | blender-modeling | execute_blender_code / get_scene_info / look / generate_3d / export glTF |
53
+ | blender-tech-mcp | get_addon_status / execute_blender_code(导出全系走这里)/ search_assets / import_asset / generate_3d |
54
+ | blender-modeling | execute_blender_code(导出 glTF 走这里)/ get_scene_info / look / generate_3d |
50
55
  | blender-shading | execute_blender_code / get_scene_info / look / search_assets |
51
56
  | blender-rig-anim | execute_blender_code / get_scene_info / look |
52
57
  | blender-light-render | execute_blender_code / get_scene_info / look |
@@ -55,12 +60,14 @@ license: MIT
55
60
  ## 按需加载(对抗小模型幻觉)
56
61
 
57
62
  - 只亮少量核心工具(get_addon_status / get_scene_info / execute_blender_code / look),重工具经 `search_assets` / `generate_3d` 调用。
58
- - 范本来例:StraySpark Blender MCP Server v4.0(556 工具/39 类,只开 22 个开门工具,其余经 search 按需加载,上下文压到 9.5K token)。这套技能不照搬其 556 工具,但**同一哲学**:工具多 ≠ 全塞上下文。
59
- - 复用 Godot 团教训:seele-godot 131 工具全量注入小模型 → 幻觉。Blender 团避免。
63
+ - 经验上,工具数多的 MCP server 会做「按需加载」来控制上下文,本团不照搬其工具数。
64
+ - 工具全量注入会显著抬高小模型幻觉率:只亮核心几个,重工具按需取。本团照此执行。
60
65
 
61
66
  ## 可复用 helper
62
67
 
63
- `/Users/jojo/AI_Projects/Seele/tools/blender_mcp_exec.py` — 读 .py 或 stdin,经 `uvx blender-mcp` 桥在 Blender 内执行并返回输出:`python3 blender_mcp_exec.py script.py`。可作团队脚本资源(注意:需 Blender 已开 + 插件服务端已启动)。
68
+ `scripts/blender_mcp_exec.py` — 读 .py 或 stdin,经 `uvx mcp-for-blender` 桥在 Blender 内执行并返回输出:`python3 scripts/blender_mcp_exec.py script.py`。可作团队脚本资源(注意:需 Blender 已开 + 插件服务端已启动)。
69
+
70
+ **输出落盘约定(审计/验证命令必做)**:凡用该 helper 跑审计、验证、对比类命令,输出原文必须重定向落盘,例:`python3 scripts/blender_mcp_exec.py script.py > 派单/回执_01_audit.log 2>&1`;回执正文只报「做了什么 + 产物路径」,**不许把输出转述/摘要进正文充当证据**——证据必须可复查(带路径,可带行号)。
64
71
 
65
72
  ## 红线
66
73
  - 默认本地优先(127.0.0.1);云端造模(`generate_3d` / fal.ai)经 `uvx` 运行时,须显式告知用户数据出站。
@@ -0,0 +1,40 @@
1
+ """控制台编码兜底(v1.5.8)。
2
+
3
+ ## 为什么需要这个
4
+
5
+ README 写着**支持 Windows**(Python 3.9+,官网安装包)。但中文 Windows 的控制台默认代码页是
6
+ **cp936(GBK)**,而 GBK **不含** `✅`(U+2705) / `❌`(U+274C) —— 于是第一句
7
+ `print(" ✅ ...")` 就抛:
8
+
9
+ ```
10
+ UnicodeEncodeError: 'gbk' codec can't encode character '\u2705' in position 2
11
+ ```
12
+
13
+ **表现不是"符号显示成方块",是脚本当场崩、一条断言都没跑。**
14
+ 本机用 `PYTHONIOENCODING=gbk` 复现过:自检第一条就炸。
15
+
16
+ ## 做法
17
+
18
+ 把 stdout / stderr 切成 UTF-8(`errors="replace"` 兜底)。三件事要说清:
19
+
20
+ 1. `reconfigure` 是 3.7+ 的方法,本产品要求 3.9+,可用
21
+ 2. 切的是**输出流编码**,不改文件读写(文件本来都是显式 `encoding="utf-8"`)
22
+ 3. 万一环境不支持(老版本 / 被重定向成非 TextIOWrapper),**静默跳过**——
23
+ 宁可符号显示异常,也不能因此让出稿失败
24
+
25
+ ## 为什么放在 import 处而不是 `main()`
26
+
27
+ 有些脚本的主要输出在 `selftest()` 或模块级代码里(比如四份样本的基线打印),
28
+ 放在 `main()` 会漏掉。放在 import 处是幂等的,被当库导入时也无害。
29
+ """
30
+ import sys
31
+
32
+
33
+ def ensure_utf8() -> None:
34
+ """把 stdout/stderr 切到 UTF-8(失败则忽略)。可重复调用。"""
35
+ for stream in (sys.stdout, sys.stderr):
36
+ try:
37
+ stream.reconfigure(encoding="utf-8", errors="replace")
38
+ except (AttributeError, ValueError, OSError):
39
+ # 老版本没有 reconfigure / 流被重定向成非文本流 —— 跳过,不影响出稿
40
+ pass