@faicad/faijs 0.30.9 → 0.31.1

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.
Files changed (284) hide show
  1. package/dist/api/align/index.d.ts +64 -0
  2. package/dist/api/align/index.d.ts.map +1 -0
  3. package/dist/api/align/index.js +101 -0
  4. package/dist/api/align/index.js.map +1 -0
  5. package/dist/api/api-namespace.d.ts +5 -4
  6. package/dist/api/api-namespace.d.ts.map +1 -1
  7. package/dist/api/api-namespace.js +36 -4
  8. package/dist/api/api-namespace.js.map +1 -1
  9. package/dist/api/boolean-op/index.d.ts +65 -0
  10. package/dist/api/boolean-op/index.d.ts.map +1 -0
  11. package/dist/api/boolean-op/index.js +113 -0
  12. package/dist/api/boolean-op/index.js.map +1 -0
  13. package/dist/api/boolean.d.ts.map +1 -1
  14. package/dist/api/boolean.js +15 -27
  15. package/dist/api/boolean.js.map +1 -1
  16. package/dist/api/brep-operations/healingFns.d.ts +13 -0
  17. package/dist/api/brep-operations/healingFns.d.ts.map +1 -1
  18. package/dist/api/brep-operations/healingFns.js +28 -1
  19. package/dist/api/brep-operations/healingFns.js.map +1 -1
  20. package/dist/api/brep-operations/topologyFns.d.ts +27 -6
  21. package/dist/api/brep-operations/topologyFns.d.ts.map +1 -1
  22. package/dist/api/brep-operations/topologyFns.js +46 -22
  23. package/dist/api/brep-operations/topologyFns.js.map +1 -1
  24. package/dist/api/chamfer.d.ts +5 -4
  25. package/dist/api/chamfer.d.ts.map +1 -1
  26. package/dist/api/chamfer.js +12 -11
  27. package/dist/api/chamfer.js.map +1 -1
  28. package/dist/api/curve-sketch/index.d.ts.map +1 -1
  29. package/dist/api/curve-sketch/index.js +9 -3
  30. package/dist/api/curve-sketch/index.js.map +1 -1
  31. package/dist/api/draft.d.ts.map +1 -1
  32. package/dist/api/draft.js +1 -3
  33. package/dist/api/draft.js.map +1 -1
  34. package/dist/api/engrave.d.ts.map +1 -1
  35. package/dist/api/engrave.js +3 -13
  36. package/dist/api/engrave.js.map +1 -1
  37. package/dist/api/export-3mf.d.ts +73 -0
  38. package/dist/api/export-3mf.d.ts.map +1 -0
  39. package/dist/api/export-3mf.js +121 -0
  40. package/dist/api/export-3mf.js.map +1 -0
  41. package/dist/api/export-brep.d.ts +6 -0
  42. package/dist/api/export-brep.d.ts.map +1 -1
  43. package/dist/api/export-brep.js +11 -2
  44. package/dist/api/export-brep.js.map +1 -1
  45. package/dist/api/export-step.d.ts +67 -0
  46. package/dist/api/export-step.d.ts.map +1 -0
  47. package/dist/api/export-step.js +98 -0
  48. package/dist/api/export-step.js.map +1 -0
  49. package/dist/api/export-stl.d.ts +8 -0
  50. package/dist/api/export-stl.d.ts.map +1 -1
  51. package/dist/api/export-stl.js +23 -8
  52. package/dist/api/export-stl.js.map +1 -1
  53. package/dist/api/feature-repair.d.ts +1 -1
  54. package/dist/api/feature-repair.d.ts.map +1 -1
  55. package/dist/api/feature-repair.js +1 -7
  56. package/dist/api/feature-repair.js.map +1 -1
  57. package/dist/api/fillet-variable.d.ts.map +1 -1
  58. package/dist/api/fillet-variable.js +0 -1
  59. package/dist/api/fillet-variable.js.map +1 -1
  60. package/dist/api/fillet.d.ts +3 -3
  61. package/dist/api/fillet.d.ts.map +1 -1
  62. package/dist/api/fillet.js +3 -4
  63. package/dist/api/fillet.js.map +1 -1
  64. package/dist/api/generated/operations.js +6 -6
  65. package/dist/api/generated/operations.js.map +1 -1
  66. package/dist/api/generated/script-face-manifest.d.ts +1 -1
  67. package/dist/api/generated/script-face-manifest.js +3 -3
  68. package/dist/api/generated/script-face-manifest.js.map +1 -1
  69. package/dist/api/generated/script-face.d.ts +1 -1
  70. package/dist/api/generated/script-face.js +1 -1
  71. package/dist/api/generated/script-face.js.map +1 -1
  72. package/dist/api/generated/sketching.js +1 -1
  73. package/dist/api/generated/sketching.js.map +1 -1
  74. package/dist/api/generated/topology.js +10 -10
  75. package/dist/api/generated/topology.js.map +1 -1
  76. package/dist/api/helix.d.ts +1 -1
  77. package/dist/api/helix.js +1 -1
  78. package/dist/api/helix.js.map +1 -1
  79. package/dist/api/index.d.ts +4 -1
  80. package/dist/api/index.d.ts.map +1 -1
  81. package/dist/api/index.js +16 -4
  82. package/dist/api/index.js.map +1 -1
  83. package/dist/api/internal/compat-op.d.ts +6 -6
  84. package/dist/api/internal/compat-op.d.ts.map +1 -1
  85. package/dist/api/internal/compat-op.js +7 -9
  86. package/dist/api/internal/compat-op.js.map +1 -1
  87. package/dist/api/internal/export-members.d.ts +80 -0
  88. package/dist/api/internal/export-members.d.ts.map +1 -0
  89. package/dist/api/internal/export-members.js +104 -0
  90. package/dist/api/internal/export-members.js.map +1 -0
  91. package/dist/api/internal/l3-bridge.d.ts +17 -0
  92. package/dist/api/internal/l3-bridge.d.ts.map +1 -1
  93. package/dist/api/internal/l3-bridge.js +23 -1
  94. package/dist/api/internal/l3-bridge.js.map +1 -1
  95. package/dist/api/measure-query/index.d.ts +262 -0
  96. package/dist/api/measure-query/index.d.ts.map +1 -0
  97. package/dist/api/measure-query/index.js +390 -0
  98. package/dist/api/measure-query/index.js.map +1 -0
  99. package/dist/api/pattern.d.ts.map +1 -1
  100. package/dist/api/pattern.js +0 -3
  101. package/dist/api/pattern.js.map +1 -1
  102. package/dist/api/primitives.d.ts +6 -6
  103. package/dist/api/primitives.d.ts.map +1 -1
  104. package/dist/api/primitives.js +12 -11
  105. package/dist/api/primitives.js.map +1 -1
  106. package/dist/api/profile.d.ts.map +1 -1
  107. package/dist/api/profile.js +0 -1
  108. package/dist/api/profile.js.map +1 -1
  109. package/dist/api/punch-hole.d.ts.map +1 -1
  110. package/dist/api/punch-hole.js +0 -1
  111. package/dist/api/punch-hole.js.map +1 -1
  112. package/dist/api/replicate.d.ts +5 -7
  113. package/dist/api/replicate.d.ts.map +1 -1
  114. package/dist/api/replicate.js +18 -56
  115. package/dist/api/replicate.js.map +1 -1
  116. package/dist/api/section-by-plane.d.ts.map +1 -1
  117. package/dist/api/section-by-plane.js +0 -1
  118. package/dist/api/section-by-plane.js.map +1 -1
  119. package/dist/api/shell.d.ts +1 -1
  120. package/dist/api/shell.d.ts.map +1 -1
  121. package/dist/api/shell.js +11 -2
  122. package/dist/api/shell.js.map +1 -1
  123. package/dist/api/sketch-on-face.d.ts +3 -3
  124. package/dist/api/sketch-on-face.d.ts.map +1 -1
  125. package/dist/api/sketch-on-face.js +6 -4
  126. package/dist/api/sketch-on-face.js.map +1 -1
  127. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  128. package/dist/api/sketch-on-plane.js +0 -1
  129. package/dist/api/sketch-on-plane.js.map +1 -1
  130. package/dist/api/split-by-plane.d.ts.map +1 -1
  131. package/dist/api/split-by-plane.js +0 -1
  132. package/dist/api/split-by-plane.js.map +1 -1
  133. package/dist/api/split.d.ts +1 -1
  134. package/dist/api/split.js +1 -1
  135. package/dist/api/split.js.map +1 -1
  136. package/dist/api/surface/arg-spec.d.ts +3 -12
  137. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  138. package/dist/api/surface/arg-spec.js +19 -26
  139. package/dist/api/surface/arg-spec.js.map +1 -1
  140. package/dist/api/sweep.d.ts +15 -3
  141. package/dist/api/sweep.d.ts.map +1 -1
  142. package/dist/api/sweep.js +5 -3
  143. package/dist/api/sweep.js.map +1 -1
  144. package/dist/api/thicken.d.ts.map +1 -1
  145. package/dist/api/thicken.js +11 -2
  146. package/dist/api/thicken.js.map +1 -1
  147. package/dist/api/transform.d.ts +3 -3
  148. package/dist/api/transform.d.ts.map +1 -1
  149. package/dist/api/transform.js +47 -17
  150. package/dist/api/transform.js.map +1 -1
  151. package/dist/boolean/index.d.ts +23 -0
  152. package/dist/boolean/index.d.ts.map +1 -0
  153. package/dist/boolean/index.js +27 -0
  154. package/dist/boolean/index.js.map +1 -0
  155. package/dist/brep/brep-chain.d.ts +1 -19
  156. package/dist/brep/brep-chain.d.ts.map +1 -1
  157. package/dist/brep/brep-chain.js +0 -1
  158. package/dist/brep/brep-chain.js.map +1 -1
  159. package/dist/brep/brep-ops.d.ts +4 -1
  160. package/dist/brep/brep-ops.d.ts.map +1 -1
  161. package/dist/brep/brep-ops.js +9 -5
  162. package/dist/brep/brep-ops.js.map +1 -1
  163. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  164. package/dist/brep/engine/adapters/brep-mock.js +0 -3
  165. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  166. package/dist/brep/engine/adapters/brepkit.d.ts +4 -3
  167. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  168. package/dist/brep/engine/adapters/brepkit.js +4 -98
  169. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  170. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  171. package/dist/brep/engine/adapters/occt.js +0 -144
  172. package/dist/brep/engine/adapters/occt.js.map +1 -1
  173. package/dist/brep/engine/native-history.d.ts +27 -0
  174. package/dist/brep/engine/native-history.d.ts.map +1 -0
  175. package/dist/brep/engine/native-history.js +54 -0
  176. package/dist/brep/engine/native-history.js.map +1 -0
  177. package/dist/brep/engine/registry.d.ts +2 -4
  178. package/dist/brep/engine/registry.d.ts.map +1 -1
  179. package/dist/brep/engine/registry.js +1 -1
  180. package/dist/brep/engine/registry.js.map +1 -1
  181. package/dist/brep/engine/types.d.ts +35 -77
  182. package/dist/brep/engine/types.d.ts.map +1 -1
  183. package/dist/brep/engine/types.js.map +1 -1
  184. package/dist/brep/export/export-model.d.ts +21 -0
  185. package/dist/brep/export/export-model.d.ts.map +1 -1
  186. package/dist/brep/export/export-model.js +171 -73
  187. package/dist/brep/export/export-model.js.map +1 -1
  188. package/dist/brep/export/step.d.ts +17 -1
  189. package/dist/brep/export/step.d.ts.map +1 -1
  190. package/dist/brep/export/step.js +133 -0
  191. package/dist/brep/export/step.js.map +1 -1
  192. package/dist/brep/export/stl.d.ts +22 -1
  193. package/dist/brep/export/stl.d.ts.map +1 -1
  194. package/dist/brep/export/stl.js +58 -10
  195. package/dist/brep/export/stl.js.map +1 -1
  196. package/dist/brep/export/transform12.d.ts +47 -0
  197. package/dist/brep/export/transform12.d.ts.map +1 -0
  198. package/dist/brep/export/transform12.js +87 -0
  199. package/dist/brep/export/transform12.js.map +1 -0
  200. package/dist/brep/face-evolution.d.ts +53 -0
  201. package/dist/brep/face-evolution.d.ts.map +1 -1
  202. package/dist/brep/face-evolution.js +65 -0
  203. package/dist/brep/face-evolution.js.map +1 -1
  204. package/dist/browser-host/index.d.ts +4 -1
  205. package/dist/browser-host/index.d.ts.map +1 -1
  206. package/dist/browser-host/index.js +7 -1
  207. package/dist/browser-host/index.js.map +1 -1
  208. package/dist/browser.d.ts +4 -8
  209. package/dist/browser.d.ts.map +1 -1
  210. package/dist/browser.js +4 -26
  211. package/dist/browser.js.map +1 -1
  212. package/dist/cad-runtime/backend-dispatch.d.ts +13 -58
  213. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  214. package/dist/cad-runtime/backend-dispatch.js +22 -80
  215. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  216. package/dist/cad-runtime/content-key.d.ts +3 -3
  217. package/dist/cad-runtime/content-key.js +3 -3
  218. package/dist/cad-runtime/content-key.js.map +1 -1
  219. package/dist/cad-runtime/ports.d.ts +28 -0
  220. package/dist/cad-runtime/ports.d.ts.map +1 -1
  221. package/dist/cad-runtime/ports.js.map +1 -1
  222. package/dist/cad-runtime/runtime.d.ts +33 -12
  223. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  224. package/dist/cad-runtime/runtime.js +44 -48
  225. package/dist/cad-runtime/runtime.js.map +1 -1
  226. package/dist/define-op.d.ts +6 -11
  227. package/dist/define-op.d.ts.map +1 -1
  228. package/dist/define-op.js +3 -20
  229. package/dist/define-op.js.map +1 -1
  230. package/dist/env-agnostic.d.ts +2 -2
  231. package/dist/env-agnostic.d.ts.map +1 -1
  232. package/dist/env-agnostic.js +1 -1
  233. package/dist/env-agnostic.js.map +1 -1
  234. package/dist/index.d.ts +13 -64
  235. package/dist/index.d.ts.map +1 -1
  236. package/dist/index.js +17 -75
  237. package/dist/index.js.map +1 -1
  238. package/dist/lang/symbol-table.generated.d.ts +17 -0
  239. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  240. package/dist/lang/symbol-table.generated.js +17 -0
  241. package/dist/lang/symbol-table.generated.js.map +1 -1
  242. package/dist/mesh/index.d.ts +18 -23
  243. package/dist/mesh/index.d.ts.map +1 -1
  244. package/dist/mesh/index.js +18 -20
  245. package/dist/mesh/index.js.map +1 -1
  246. package/dist/mesh/io.d.ts +42 -14
  247. package/dist/mesh/io.d.ts.map +1 -1
  248. package/dist/mesh/io.js +77 -13
  249. package/dist/mesh/io.js.map +1 -1
  250. package/dist/mesh/threemf-loader.d.ts +38 -4
  251. package/dist/mesh/threemf-loader.d.ts.map +1 -1
  252. package/dist/mesh/threemf-loader.js +115 -34
  253. package/dist/mesh/threemf-loader.js.map +1 -1
  254. package/dist/mesh/types.d.ts +30 -0
  255. package/dist/mesh/types.d.ts.map +1 -1
  256. package/dist/mesh/types.js.map +1 -1
  257. package/dist/node-host/execute-script.d.ts +2 -1
  258. package/dist/node-host/execute-script.d.ts.map +1 -1
  259. package/dist/node-host/execute-script.js +5 -4
  260. package/dist/node-host/execute-script.js.map +1 -1
  261. package/dist/node-host/index.d.ts +1 -0
  262. package/dist/node-host/index.d.ts.map +1 -1
  263. package/dist/node-host/index.js +4 -0
  264. package/dist/node-host/index.js.map +1 -1
  265. package/dist/primitives/index.d.ts +19 -0
  266. package/dist/primitives/index.d.ts.map +1 -0
  267. package/dist/primitives/index.js +21 -0
  268. package/dist/primitives/index.js.map +1 -0
  269. package/dist/runtime-state.d.ts +63 -29
  270. package/dist/runtime-state.d.ts.map +1 -1
  271. package/dist/runtime-state.js +57 -0
  272. package/dist/runtime-state.js.map +1 -1
  273. package/dist/sdf/index.d.ts +12 -0
  274. package/dist/sdf/index.d.ts.map +1 -0
  275. package/dist/sdf/index.js +13 -0
  276. package/dist/sdf/index.js.map +1 -0
  277. package/dist/sdk.d.ts +0 -1
  278. package/dist/sdk.d.ts.map +1 -1
  279. package/dist/sdk.js.map +1 -1
  280. package/dist/weapp.d.ts +2 -2
  281. package/dist/weapp.d.ts.map +1 -1
  282. package/dist/weapp.js +1 -1
  283. package/dist/weapp.js.map +1 -1
  284. package/package.json +276 -35
@@ -18,18 +18,16 @@
18
18
  * also build `replica[*]/<inner>` role tables (same treatment as linearPattern,
19
19
  * via the shared buildReplicaRoleTable helper).
20
20
  * - Single-copy ops (mirror / clone / transformCopy): thin overrides that keep
21
- * the input and delegate to the generated compatOp (adopt/capabilities/
22
- * naming preserved).
21
+ * the input and delegate to the generated compatOp (adopt/engines/naming
22
+ * preserved).
23
23
  *
24
24
  * The generated files stay untouched; overrides win via api-namespace spread
25
25
  * (same precedent as cut / split / linearPattern).
26
26
  *
27
27
  * 平台分层(narrowing plan Phase 5,D11):
28
- * - mirrorJoin / mirror:平台 op(依赖 occt-only `mirrorWithHistory`)→
29
- * `engines: ['occt']`,不声明 capabilities(能力由平台身份本身界定)。
30
- * - circularPattern / gridPattern / rectangularPattern / clone:中立 op(实现
31
- * 只用 L1 核心面)→ capabilities 收窄到真实 L1 名(删除 isNull/iterShapes/
32
- * section/translateWithHistory 等 occt-only 虚名,capability-map 实证实现不依赖)。
28
+ * - mirrorJoin / mirror / circularPattern / gridPattern / rectangularPattern /
29
+ * clone:中立 op(实现只用 L1 核心面)→ 无 engines、无能力声明;
30
+ * 面演化轨由 `hasNativeHistory` 在 mirrorBrep 内部按引擎事实静态分叉。
33
31
  */
34
32
  import { solidToShape } from '../brep/brep-ops.js';
35
33
  import { getBrepApi } from '../brep/handle-bridge.js';
@@ -154,18 +152,7 @@ export const circularPattern = defineOp({
154
152
  const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt);
155
153
  return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable });
156
154
  },
157
- // 中立 op(D11):capabilities 收窄到实现真实调用的 L1 名(删除 isNull/iterShapes/
158
- // section 等 occt-only 虚名——实现只调 kernel.circularPattern/fuseAll)。
159
- capabilities: [
160
- 'circularPattern',
161
- 'dispose',
162
- 'fuseAll',
163
- 'hashCode',
164
- 'surfaceCenterOfMass',
165
- 'surfaceNormal',
166
- 'surfaceType',
167
- 'uvBounds',
168
- ],
155
+ // 中立 op(D11):实现只用 L1 核心面(kernel.circularPattern/fuseAll)。
169
156
  naming: { kind: 'replicate', k: 0 },
170
157
  });
171
158
  // ── gridPattern ─────────────────────────────────────────────────────────────
@@ -235,17 +222,7 @@ export const gridPattern = defineOp({
235
222
  const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt);
236
223
  return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable });
237
224
  },
238
- capabilities: [
239
- 'dispose',
240
- 'fuseAll',
241
- 'gridPattern',
242
- 'hashCode',
243
- 'linearPattern',
244
- 'surfaceCenterOfMass',
245
- 'surfaceNormal',
246
- 'surfaceType',
247
- 'uvBounds',
248
- ],
225
+ // 中立 op(D11):实现只用 L1 核心面(kernel.gridPattern/translate/fuseAll)。
249
226
  naming: { kind: 'replicate', k: 0 },
250
227
  });
251
228
  /**
@@ -289,8 +266,7 @@ export const rectangularPattern = defineOp({
289
266
  const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options;
290
267
  const dx = norm(xDir);
291
268
  const dy = norm(yDir);
292
- // 旧 rectangularPattern 是纯 JS 组合(translate + fuseAll),内核不声明
293
- // 该方法——与旧版同口径:逐份 translate 再 fuseAll。
269
+ // 实现为纯 JS 组合:逐份 translate 再 fuseAll,不依赖内核的 rectangularPattern 方法。
294
270
  const copies = [];
295
271
  try {
296
272
  for (let ix = 0; ix < xCount; ix++) {
@@ -324,17 +300,7 @@ export const rectangularPattern = defineOp({
324
300
  kernel.release(c);
325
301
  }
326
302
  },
327
- capabilities: [
328
- 'dispose',
329
- 'fuse',
330
- 'fuseAll',
331
- 'fuseWithHistory',
332
- 'hashCode',
333
- 'surfaceCenterOfMass',
334
- 'surfaceNormal',
335
- 'surfaceType',
336
- 'uvBounds',
337
- ],
303
+ // 中立 op(D11):实现只用 L1 核心面(kernel.translate/fuseAll)。
338
304
  naming: { kind: 'replicate', k: 0 },
339
305
  });
340
306
  /**
@@ -381,11 +347,10 @@ export const mirrorJoin = defineOp({
381
347
  const { kernel, solid, outStmt } = prelude(input, 'mirrorJoin');
382
348
  const n = norm(options?.normal ?? [1, 0, 0]);
383
349
  const o = toBrepVec(options?.at ?? [0, 0, 0]);
384
- // 2026-09-26 C 批降级:原实现直调 getOcctKernel().mirrorWithHistory(occt-only history
385
- // 镜像,返回 modified/newFaces 供细粒度 roleTable)。按用户指示「有没有历史 withhistory
386
- // 并不重要」,降级为 L1 kernel.mirror(brepkit 已声明 mirror 能力)——几何结果一致,
387
- // roleTable 仍由 buildReplicaRoleTable 经质心聚类重建(引擎无关),仅丢失 history 级
388
- // modified 面映射(不影响几何与产物有效性)。
350
+ // replicate 的 role table 经质心聚类重建(引擎无关),mirror history 对
351
+ // role table 无增量收益,故走 L1 kernel.mirror(两引擎的 L1 契约面均提供
352
+ // `mirror`;`mirrorWithHistory` 不参与本 op,与引擎身份无关)。
353
+ // 面演化由 mirrorBrep(topologyFns.ts)双轨接入,replicate 不重复消费。
389
354
  const mirrored = kernel.mirror(solid, o, toBrepVec(n));
390
355
  try {
391
356
  const resultSolid = kernel.fuse(solid, mirrored);
@@ -400,9 +365,8 @@ export const mirrorJoin = defineOp({
400
365
  kernel.release(mirrored);
401
366
  }
402
367
  },
403
- // 2026-09-26 C 批:从 engines:[occt] 降级为 capabilities:['mirror','fuse'](L1 中立面,
404
- // brepkit 已声明二者)。history 语义丢失(见上注释),几何不回退。
405
- capabilities: ['mirror', 'fuse'],
368
+ // 中立 op(D11):实现只用 L1 核心面(kernel.mirror/fuse)。replicate 的
369
+ // role table 不消费 mirror history(见上注释),面演化由 mirrorBrep 双轨接入。
406
370
  naming: { kind: 'replicate', k: 2 },
407
371
  });
408
372
  // ── single-copy thin overrides(keep + 委托生成 op)─────────────────────────
@@ -440,10 +404,8 @@ export const mirror = defineOp({
440
404
  keep(input);
441
405
  return (await generatedMirror(input, options));
442
406
  },
443
- // 2026-09-26 B 批:generatedMirror 已降级为 L1 kernel.mirror(brepkit 已声明 mirror
444
- // 能力),薄 override 同步从 engines:[occt] 降级为 capabilities:['mirror']——
445
- // 与 clone 薄 override 同模式(外层门不拦 brepkit,内层 generatedMirror 已按能力路由)。
446
- capabilities: ['mirror'],
407
+ // 薄 override:generatedMirror 走 L1 kernel.mirror,与 clone 薄 override 同模式
408
+ // (无能力门,内层实现自行按引擎事实分叉)。面演化由 mirrorBrep 双轨接入。
447
409
  naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
448
410
  });
449
411
  /**
@@ -477,7 +439,7 @@ export const clone = defineOp({
477
439
  keep(input);
478
440
  return (await generatedClone(input));
479
441
  },
480
- capabilities: ['copyShape', 'dispose'],
442
+ // 中立 op(D11):实现只用 L1 核心面(kernel.copyShape)。
481
443
  naming: { kind: 'identity' },
482
444
  });
483
445
  //# sourceMappingURL=replicate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"replicate.js","sourceRoot":"","sources":["../../src/api/replicate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * replicate — handwritten overrides for the copy-family ops (keep semantics +\n * replica[k] role tables).\n *\n * @platform occt — 本文件 import occt-kernel(mirrorJoin 走 `mirrorWithHistory`\n * 平台面,D3)。文件级标注满足守卫①(平台 import 自证身份);文件内的**中立 op**\n * (circularPattern/gridPattern/rectangularPattern/clone 只用 L1 核心面)不声明\n * engines,运行时不拦截——标注只约束平台 import,不改变函数级中立性\n * (与 face-evolution.ts 同口径)。\n *\n * All 9 copy-like ops must NOT consume their input (same as `copy`): each brep\n * body declares `keep(input)` (function-body keep → KeepRegistry → live-shapes),\n * so the source stays a live terminal in both runtime and UI.\n *\n * Two groups:\n * - Multi-replica patterns (circularPattern / gridPattern / rectangularPattern /\n * mirrorJoin): promoted from generated compatOps to handwritten defineOps that\n * also build `replica[*]/<inner>` role tables (same treatment as linearPattern,\n * via the shared buildReplicaRoleTable helper).\n * - Single-copy ops (mirror / clone / transformCopy): thin overrides that keep\n * the input and delegate to the generated compatOp (adopt/capabilities/\n * naming preserved).\n *\n * The generated files stay untouched; overrides win via api-namespace spread\n * (same precedent as cut / split / linearPattern).\n *\n * 平台分层(narrowing plan Phase 5,D11):\n * - mirrorJoin / mirror:平台 op(依赖 occt-only `mirrorWithHistory`)→\n * `engines: ['occt']`,不声明 capabilities(能力由平台身份本身界定)。\n * - circularPattern / gridPattern / rectangularPattern / clone:中立 op(实现\n * 只用 L1 核心面)→ capabilities 收窄到真实 L1 名(删除 isNull/iterShapes/\n * section/translateWithHistory 等 occt-only 虚名,capability-map 实证实现不依赖)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { getCurrentStmt, keep, keepHidden } from '../runtime-state'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle, BrepVec3 } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { buildReplicaRoleTable, type ReplicaTransform } from './internal/replica-role-table'\nimport {\n meshKernelFailure,\n meshPatternProduct,\n meshSolidBasicEntry,\n meshSolidProduct,\n} from './internal/mesh-solid-op'\n// Generated compatOps (delegation targets for the thin single-copy overrides).\n// NOTE: transformCopy is NOT a script-face op (arg-spec skip: ComposedTransform\n// is not constructible in .fai.js); it stays a TS-library-only re-export.\nimport {\n mirror as generatedMirror,\n clone as generatedClone,\n} from './generated/topology'\n/** 镜像面参数(与旧 MirrorOptions 同形;G5 去外部依赖后本地自持)。 */\ninterface MirrorOptions {\n /** 镜像面法向。默认 [0,0,1]。 */\n normal?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** 镜像面过点。默认 [0,0,0]。 */\n at?: readonly [number, number, number] | { x: number; y: number; z: number }\n}\n\n/** Normalize a vector (zero vector → [0,0,1] fallback, same as pattern.ts). */\nfunction norm(v: Vec3): Vec3 {\n const len = Math.hypot(v[0], v[1], v[2])\n if (len < 1e-9) return [0, 0, 1]\n return [v[0] / len, v[1] / len, v[2] / len]\n}\n\nfunction toBrepVec(v: Vec3): BrepVec3 {\n return { x: v[0], y: v[1], z: v[2] }\n}\n\n/**\n * `MirrorOptions` 的宽松向量形态(只读元组或 `{x,y,z}`)→ `Vec3`。\n *\n * 生成的 compatOp 自己吃得下这两种形态,网格路径要自己换算,故收在一处。\n *\n * @param v - the loosely typed vector from the op's options.\n * @param fallback - the default vector.\n * @returns the vector as a plain tuple.\n */\nfunction optionVec(\n v: readonly [number, number, number] | { x: number; y: number; z: number } | undefined,\n fallback: Vec3,\n): Vec3 {\n if (!v) return fallback\n if (Array.isArray(v)) return [v[0] as number, v[1] as number, v[2] as number]\n const o = v as { x: number; y: number; z: number }\n return [o.x, o.y, o.z]\n}\n\n/** Shared prelude: L1 kernel(getBrepApi,D12)+ BREP input handle + output statement id. */\nfunction prelude(input: Shape, tag: string): { kernel: BrepEngineApi; solid: BrepHandle; outStmt: string } {\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error(`[api/${tag}] input is not BREP`)\n return { kernel, solid, outStmt: String(getCurrentStmt()?.id ?? '') }\n}\n\n/** Rotate point p around the axis line (point `center`, unit direction `u`) by theta radians. */\nfunction rotateAroundAxis(p: BrepVec3, center: BrepVec3, u: Vec3, theta: number): BrepVec3 {\n const vx = p.x - center.x\n const vy = p.y - center.y\n const vz = p.z - center.z\n const cos = Math.cos(theta)\n const sin = Math.sin(theta)\n const dot = vx * u[0] + vy * u[1] + vz * u[2]\n // u × v\n const cx = u[1] * vz - u[2] * vy\n const cy = u[2] * vx - u[0] * vz\n const cz = u[0] * vy - u[1] * vx\n return {\n x: center.x + vx * cos + cx * sin + u[0] * dot * (1 - cos),\n y: center.y + vy * cos + cy * sin + u[1] * dot * (1 - cos),\n z: center.z + vz * cos + cz * sin + u[2] * dot * (1 - cos),\n }\n}\n\n/** Reflect point p across the plane (point `o`, unit normal `n`). Self-inverse. */\nfunction reflectAcrossPlane(p: BrepVec3, o: BrepVec3, n: Vec3): BrepVec3 {\n const d = (p.x - o.x) * n[0] + (p.y - o.y) * n[1] + (p.z - o.z) * n[2]\n return { x: p.x - 2 * d * n[0], y: p.y - 2 * d * n[1], z: p.z - 2 * d * n[2] }\n}\n\n// ── circularPattern ─────────────────────────────────────────────────────────\n\n/**\n * 环形阵列:绕 axis 均分 fullAngle(度,缺省 360)复制 count 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name circularPattern\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[k]/<inner>`。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param axis - 旋转轴方向。type:[x,y,z] required:true\n * @param count - 副本总数(含原位置)。type:number required:true\n * @param fullAngle - 总角度(度,缺省 360)。type:number required:false\n * @param center - 旋转轴上一点(缺省原点)。type:[x,y,z] required:false\n * @example\n * const p = await cad.circularPattern(part0, [0, 0, 1], 6)\n */\nexport const circularPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, axis: Vec3, count: number, fullAngle: number = 360, center: Vec3 = [0, 0, 0]) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'circularPattern')\n const u = norm(axis)\n const step = fullAngle / count\n // 网格链:内核返回 count 份副本(含原位置),融合成一个网格零件;近似拓扑没有\n // role 层,故不产 `replica[k]/<inner>` 命名(如实缺席)。\n return meshPatternProduct(entry, 'circularPattern', 'E_PATTERN_FAILED', () =>\n entry.kernel.circularPattern(entry.solid, toBrepVec(center), toBrepVec(u), step, count),\n )\n },\n brep(input: Shape, axis: Vec3, count: number, fullAngle: number = 360, center: Vec3 = [0, 0, 0]) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'circularPattern')\n const u = norm(axis)\n const step = fullAngle / count\n const raw = kernel.circularPattern(solid, toBrepVec(center), toBrepVec(u), step, count)\n\n let resultSolid: BrepHandle\n try {\n resultSolid = kernel.fuseAll(raw)\n } finally {\n for (const c of raw) kernel.release(c)\n }\n\n const replicas: ReplicaTransform[] = []\n for (let k = 0; k < count; k++) {\n const theta = (-k * step * Math.PI) / 180\n replicas.push({\n label: `replica[${k}]`,\n inverse: (c) => rotateAroundAxis(c, toBrepVec(center), u, theta),\n })\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n },\n // 中立 op(D11):capabilities 收窄到实现真实调用的 L1 名(删除 isNull/iterShapes/\n // section 等 occt-only 虚名——实现只调 kernel.circularPattern/fuseAll)。\n capabilities: [\n 'circularPattern',\n 'dispose',\n 'fuseAll',\n 'hashCode',\n 'surfaceCenterOfMass',\n 'surfaceNormal',\n 'surfaceType',\n 'uvBounds',\n ],\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n\n// ── gridPattern ─────────────────────────────────────────────────────────────\n\n/**\n * 二维栅格阵列:沿 directionX × directionY 复制 countX×countY 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name gridPattern\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[ix_iy]/<inner>`。\n * @returns Shape 全部副本的 compound。\n * @param input - 目标几何。type:Shape required:true\n * @param directionX - 第一方向。type:[x,y,z] required:true\n * @param directionY - 第二方向。type:[x,y,z] required:true\n * @param countX - X 向副本数。type:number required:true\n * @param countY - Y 向副本数。type:number required:true\n * @param spacingX - X 向间距。type:number required:true\n * @param spacingY - Y 向间距。type:number required:true\n * @example\n * const p = await cad.gridPattern(part0, [1, 0, 0], [0, 1, 0], 3, 2, 20, 20)\n */\nexport const gridPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(\n input: Shape,\n directionX: Vec3,\n directionY: Vec3,\n countX: number,\n countY: number,\n spacingX: number,\n spacingY: number,\n ) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'gridPattern')\n const dx = norm(directionX)\n const dy = norm(directionY)\n // 网格链走\"逐份平移 + fuseAll\"(与 rectangularPattern 同口径),不用内核的\n // `gridPattern`——那支返回**单个 compound 句柄**,近似拓扑无法把 compound 讲成\n // 一个网格零件;逐份平移则得到与线性/环形阵列同形的单一融合实体。\n return meshPatternProduct(entry, 'gridPattern', 'E_PATTERN_FAILED', () => {\n const copies: BrepHandle[] = []\n for (let ix = 0; ix < countX; ix++) {\n for (let iy = 0; iy < countY; iy++) {\n const ox = ix * spacingX\n const oy = iy * spacingY\n copies.push(entry.kernel.translate(\n entry.solid,\n ox * dx[0] + oy * dy[0],\n ox * dx[1] + oy * dy[1],\n ox * dx[2] + oy * dy[2],\n ))\n }\n }\n return copies\n })\n },\n brep(\n input: Shape,\n directionX: Vec3,\n directionY: Vec3,\n countX: number,\n countY: number,\n spacingX: number,\n spacingY: number,\n ) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'gridPattern')\n const dx = norm(directionX)\n const dy = norm(directionY)\n // kernel.gridPattern 返回 compound 单句柄(含全部副本),无需 fuse。\n const resultSolid = kernel.gridPattern(\n solid,\n toBrepVec(dx),\n toBrepVec(dy),\n spacingX,\n spacingY,\n countX,\n countY,\n )\n\n const replicas: ReplicaTransform[] = []\n for (let ix = 0; ix < countX; ix++) {\n for (let iy = 0; iy < countY; iy++) {\n const ox = ix * spacingX\n const oy = iy * spacingY\n replicas.push({\n label: `replica[${ix}_${iy}]`,\n inverse: (c) => ({\n x: c.x - (ox * dx[0] + oy * dy[0]),\n y: c.y - (ox * dx[1] + oy * dy[1]),\n z: c.z - (ox * dx[2] + oy * dy[2]),\n }),\n })\n }\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n },\n capabilities: [\n 'dispose',\n 'fuseAll',\n 'gridPattern',\n 'hashCode',\n 'linearPattern',\n 'surfaceCenterOfMass',\n 'surfaceNormal',\n 'surfaceType',\n 'uvBounds',\n ],\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n\n// ── rectangularPattern ──────────────────────────────────────────────────────\n\ninterface RectangularPatternOptions {\n xDir: Vec3\n xCount: number\n xSpacing: number\n yDir: Vec3\n yCount: number\n ySpacing: number\n}\n\n/**\n * 矩形阵列:按 options(xDir/xCount/xSpacing/yDir/yCount/ySpacing)复制并 fuse。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name rectangularPattern\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[ix_iy]/<inner>`。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param options - 阵列参数。type:RectangularPatternOptions required:true\n * @example\n * const p = await cad.rectangularPattern(part0, { xDir: [1,0,0], xCount: 3, xSpacing: 20, yDir: [0,1,0], yCount: 2, ySpacing: 15 })\n */\nexport const rectangularPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, options: RectangularPatternOptions) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'rectangularPattern')\n const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options\n const dx = norm(xDir)\n const dy = norm(yDir)\n // 与 BREP 路径同一手法(逐份 translate 再 fuseAll),只是句柄来自网格后端。\n return meshPatternProduct(entry, 'rectangularPattern', 'E_PATTERN_FAILED', () => {\n const copies: BrepHandle[] = []\n for (let ix = 0; ix < xCount; ix++) {\n for (let iy = 0; iy < yCount; iy++) {\n const ox = ix * xSpacing\n const oy = iy * ySpacing\n copies.push(entry.kernel.translate(\n entry.solid,\n ox * dx[0] + oy * dy[0],\n ox * dx[1] + oy * dy[1],\n ox * dx[2] + oy * dy[2],\n ))\n }\n }\n return copies\n })\n },\n brep(input: Shape, options: RectangularPatternOptions) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'rectangularPattern')\n const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options\n const dx = norm(xDir)\n const dy = norm(yDir)\n// 旧 rectangularPattern 是纯 JS 组合(translate + fuseAll),内核不声明\n// 该方法——与旧版同口径:逐份 translate 再 fuseAll。\n const copies: BrepHandle[] = []\n try {\n for (let ix = 0; ix < xCount; ix++) {\n for (let iy = 0; iy < yCount; iy++) {\n const ox = ix * xSpacing\n const oy = iy * ySpacing\n copies.push(kernel.translate(solid, ox * dx[0] + oy * dy[0], ox * dx[1] + oy * dy[1], ox * dx[2] + oy * dy[2]))\n }\n }\n const resultSolid = kernel.fuseAll(copies)\n\n const replicas: ReplicaTransform[] = []\n for (let ix = 0; ix < xCount; ix++) {\n for (let iy = 0; iy < yCount; iy++) {\n const ox = ix * xSpacing\n const oy = iy * ySpacing\n replicas.push({\n label: `replica[${ix}_${iy}]`,\n inverse: (c) => ({\n x: c.x - (ox * dx[0] + oy * dy[0]),\n y: c.y - (ox * dx[1] + oy * dy[1]),\n z: c.z - (ox * dx[2] + oy * dy[2]),\n }),\n })\n }\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n } finally {\n for (const c of copies) kernel.release(c)\n }\n },\n capabilities: [\n 'dispose',\n 'fuse',\n 'fuseAll',\n 'fuseWithHistory',\n 'hashCode',\n 'surfaceCenterOfMass',\n 'surfaceNormal',\n 'surfaceType',\n 'uvBounds',\n ],\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n\n// ── mirrorJoin ──────────────────────────────────────────────────────────────\n\ninterface MirrorJoinOptions {\n normal?: Vec3\n at?: Vec3\n}\n\n/**\n * 镜像并融合:原物(replica[0])+ 沿平面镜像(replica[1])fuse 成一体。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name mirrorJoin\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[0|1]/<inner>`。\n * @returns Shape fuse 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param options - { normal?, at? } 镜像面法向与面上一点。type:MirrorJoinOptions required:false\n * @example\n * const p = await cad.mirrorJoin(part0, { normal: [1, 0, 0] })\n */\nexport const mirrorJoin = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, options?: MirrorJoinOptions) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'mirrorJoin')\n const n = norm(optionVec(options?.normal, [1, 0, 0]))\n const o = toBrepVec(optionVec(options?.at, [0, 0, 0]))\n // 输入句柄**不释放**(keep 语义);只释放本次自造的镜像副本。\n let mirrored: BrepHandle\n try {\n mirrored = entry.kernel.mirror(entry.solid, o, toBrepVec(n))\n } catch (cause) {\n throw meshKernelFailure('mirrorJoin', 'E_MIRROR_FAILED', `mirror across normal [${n.join(', ')}]`, cause)\n }\n try {\n return meshSolidProduct(entry, entry.kernel.fuse(entry.solid, mirrored))\n } catch (cause) {\n throw meshKernelFailure('mirrorJoin', 'E_MIRROR_FAILED', 'fusing the mirrored copy', cause)\n } finally {\n entry.backend.release(mirrored)\n }\n },\n brep(input: Shape, options?: MirrorJoinOptions) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'mirrorJoin')\n const n = norm(options?.normal ?? [1, 0, 0])\n const o = toBrepVec(options?.at ?? [0, 0, 0])\n // 2026-09-26 C 批降级:原实现直调 getOcctKernel().mirrorWithHistory(occt-only history\n // 镜像,返回 modified/newFaces 供细粒度 roleTable)。按用户指示「有没有历史 withhistory\n // 并不重要」,降级为 L1 kernel.mirror(brepkit 已声明 mirror 能力)——几何结果一致,\n // roleTable 仍由 buildReplicaRoleTable 经质心聚类重建(引擎无关),仅丢失 history 级\n // modified 面映射(不影响几何与产物有效性)。\n const mirrored = kernel.mirror(solid, o, toBrepVec(n))\n try {\n const resultSolid = kernel.fuse(solid, mirrored)\n\n const replicas: ReplicaTransform[] = [\n { label: 'replica[0]', inverse: (c) => ({ x: c.x, y: c.y, z: c.z }) },\n { label: 'replica[1]', inverse: (c) => reflectAcrossPlane(c, o, n) },\n ]\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n } finally {\n kernel.release(mirrored)\n }\n },\n // 2026-09-26 C 批:从 engines:[occt] 降级为 capabilities:['mirror','fuse'](L1 中立面,\n // brepkit 已声明二者)。history 语义丢失(见上注释),几何不回退。\n capabilities: ['mirror', 'fuse'],\n naming: { kind: 'replicate', k: 2 } as Provenance,\n})\n\n// ── single-copy thin overrides(keep + 委托生成 op)─────────────────────────\n\n/**\n * 镜像:返回镜像后的新 Shape(源保留)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name mirror\n * @note BREP-only。keep 语义:不消费输入(薄 override 委托生成 op,行为不变)。\n * @returns Shape 镜像后的新几何。\n * @param input - 目标几何。type:Shape required:true\n * @param options - { normal?, at? } 镜像面。type:MirrorOptions required:false\n * @example\n * const p = await cad.mirror(part0, { normal: [1, 0, 0] })\n */\nexport const mirror = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, options?: MirrorOptions) {\n keep(input)\n const entry = meshSolidBasicEntry(input, 'mirror')\n const n = norm(optionVec(options?.normal, [1, 0, 0]))\n const o = toBrepVec(optionVec(options?.at, [0, 0, 0]))\n let result: BrepHandle\n try {\n result = entry.kernel.mirror(entry.solid, o, toBrepVec(n))\n } catch (cause) {\n throw meshKernelFailure('mirror', 'E_MIRROR_FAILED', `mirror across normal [${n.join(', ')}]`, cause)\n }\n return meshSolidProduct(entry, result)\n },\n async brep(input: Shape, options?: MirrorOptions) {\n keep(input)\n return (await generatedMirror(input, options)) as Shape\n },\n // 2026-09-26 B 批:generatedMirror 已降级为 L1 kernel.mirror(brepkit 已声明 mirror\n // 能力),薄 override 同步从 engines:[occt] 降级为 capabilities:['mirror']——\n // 与 clone 薄 override 同模式(外层门不拦 brepkit,内层 generatedMirror 已按能力路由)。\n capabilities: ['mirror'],\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * 深拷贝句柄:返回独立副本(源保留)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name clone\n * @note BREP-only。keep 语义:不消费输入(薄 override 委托生成 op,行为不变)。\n * @returns Shape 克隆的新几何。\n * @param input - 目标几何。type:Shape required:true\n * @example\n * const p = await cad.clone(part0)\n */\nexport const clone = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape) {\n keep(input)\n const entry = meshSolidBasicEntry(input, 'clone')\n let result: BrepHandle\n try {\n result = entry.kernel.copyShape(entry.solid)\n } catch (cause) {\n throw meshKernelFailure('clone', 'E_CLONE_FAILED', 'copying the mesh solid handle', cause)\n }\n return meshSolidProduct(entry, result)\n },\n async brep(input: Shape) {\n keep(input)\n return (await generatedClone(input)) as Shape\n },\n capabilities: ['copyShape', 'dispose'],\n naming: { kind: 'identity' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"replicate.js","sourceRoot":"","sources":["../../src/api/replicate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * replicate — handwritten overrides for the copy-family ops (keep semantics +\n * replica[k] role tables).\n *\n * @platform occt — 本文件 import occt-kernel(mirrorJoin 走 `mirrorWithHistory`\n * 平台面,D3)。文件级标注满足守卫①(平台 import 自证身份);文件内的**中立 op**\n * (circularPattern/gridPattern/rectangularPattern/clone 只用 L1 核心面)不声明\n * engines,运行时不拦截——标注只约束平台 import,不改变函数级中立性\n * (与 face-evolution.ts 同口径)。\n *\n * All 9 copy-like ops must NOT consume their input (same as `copy`): each brep\n * body declares `keep(input)` (function-body keep → KeepRegistry → live-shapes),\n * so the source stays a live terminal in both runtime and UI.\n *\n * Two groups:\n * - Multi-replica patterns (circularPattern / gridPattern / rectangularPattern /\n * mirrorJoin): promoted from generated compatOps to handwritten defineOps that\n * also build `replica[*]/<inner>` role tables (same treatment as linearPattern,\n * via the shared buildReplicaRoleTable helper).\n * - Single-copy ops (mirror / clone / transformCopy): thin overrides that keep\n * the input and delegate to the generated compatOp (adopt/engines/naming\n * preserved).\n *\n * The generated files stay untouched; overrides win via api-namespace spread\n * (same precedent as cut / split / linearPattern).\n *\n * 平台分层(narrowing plan Phase 5,D11):\n * - mirrorJoin / mirror / circularPattern / gridPattern / rectangularPattern /\n * clone:中立 op(实现只用 L1 核心面)→ 无 engines、无能力声明;\n * 面演化轨由 `hasNativeHistory` 在 mirrorBrep 内部按引擎事实静态分叉。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { getCurrentStmt, keep, keepHidden } from '../runtime-state'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle, BrepVec3 } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { buildReplicaRoleTable, type ReplicaTransform } from './internal/replica-role-table'\nimport {\n meshKernelFailure,\n meshPatternProduct,\n meshSolidBasicEntry,\n meshSolidProduct,\n} from './internal/mesh-solid-op'\n// Generated compatOps (delegation targets for the thin single-copy overrides).\n// NOTE: transformCopy is NOT a script-face op (arg-spec skip: ComposedTransform\n// is not constructible in .fai.js); it stays a TS-library-only re-export.\nimport {\n mirror as generatedMirror,\n clone as generatedClone,\n} from './generated/topology'\n/** 镜像面参数(与旧 MirrorOptions 同形;G5 去外部依赖后本地自持)。 */\ninterface MirrorOptions {\n /** 镜像面法向。默认 [0,0,1]。 */\n normal?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** 镜像面过点。默认 [0,0,0]。 */\n at?: readonly [number, number, number] | { x: number; y: number; z: number }\n}\n\n/** Normalize a vector (zero vector → [0,0,1] fallback, same as pattern.ts). */\nfunction norm(v: Vec3): Vec3 {\n const len = Math.hypot(v[0], v[1], v[2])\n if (len < 1e-9) return [0, 0, 1]\n return [v[0] / len, v[1] / len, v[2] / len]\n}\n\nfunction toBrepVec(v: Vec3): BrepVec3 {\n return { x: v[0], y: v[1], z: v[2] }\n}\n\n/**\n * `MirrorOptions` 的宽松向量形态(只读元组或 `{x,y,z}`)→ `Vec3`。\n *\n * 生成的 compatOp 自己吃得下这两种形态,网格路径要自己换算,故收在一处。\n *\n * @param v - the loosely typed vector from the op's options.\n * @param fallback - the default vector.\n * @returns the vector as a plain tuple.\n */\nfunction optionVec(\n v: readonly [number, number, number] | { x: number; y: number; z: number } | undefined,\n fallback: Vec3,\n): Vec3 {\n if (!v) return fallback\n if (Array.isArray(v)) return [v[0] as number, v[1] as number, v[2] as number]\n const o = v as { x: number; y: number; z: number }\n return [o.x, o.y, o.z]\n}\n\n/** Shared prelude: L1 kernel(getBrepApi,D12)+ BREP input handle + output statement id. */\nfunction prelude(input: Shape, tag: string): { kernel: BrepEngineApi; solid: BrepHandle; outStmt: string } {\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error(`[api/${tag}] input is not BREP`)\n return { kernel, solid, outStmt: String(getCurrentStmt()?.id ?? '') }\n}\n\n/** Rotate point p around the axis line (point `center`, unit direction `u`) by theta radians. */\nfunction rotateAroundAxis(p: BrepVec3, center: BrepVec3, u: Vec3, theta: number): BrepVec3 {\n const vx = p.x - center.x\n const vy = p.y - center.y\n const vz = p.z - center.z\n const cos = Math.cos(theta)\n const sin = Math.sin(theta)\n const dot = vx * u[0] + vy * u[1] + vz * u[2]\n // u × v\n const cx = u[1] * vz - u[2] * vy\n const cy = u[2] * vx - u[0] * vz\n const cz = u[0] * vy - u[1] * vx\n return {\n x: center.x + vx * cos + cx * sin + u[0] * dot * (1 - cos),\n y: center.y + vy * cos + cy * sin + u[1] * dot * (1 - cos),\n z: center.z + vz * cos + cz * sin + u[2] * dot * (1 - cos),\n }\n}\n\n/** Reflect point p across the plane (point `o`, unit normal `n`). Self-inverse. */\nfunction reflectAcrossPlane(p: BrepVec3, o: BrepVec3, n: Vec3): BrepVec3 {\n const d = (p.x - o.x) * n[0] + (p.y - o.y) * n[1] + (p.z - o.z) * n[2]\n return { x: p.x - 2 * d * n[0], y: p.y - 2 * d * n[1], z: p.z - 2 * d * n[2] }\n}\n\n// ── circularPattern ─────────────────────────────────────────────────────────\n\n/**\n * 环形阵列:绕 axis 均分 fullAngle(度,缺省 360)复制 count 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name circularPattern\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[k]/<inner>`。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param axis - 旋转轴方向。type:[x,y,z] required:true\n * @param count - 副本总数(含原位置)。type:number required:true\n * @param fullAngle - 总角度(度,缺省 360)。type:number required:false\n * @param center - 旋转轴上一点(缺省原点)。type:[x,y,z] required:false\n * @example\n * const p = await cad.circularPattern(part0, [0, 0, 1], 6)\n */\nexport const circularPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, axis: Vec3, count: number, fullAngle: number = 360, center: Vec3 = [0, 0, 0]) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'circularPattern')\n const u = norm(axis)\n const step = fullAngle / count\n // 网格链:内核返回 count 份副本(含原位置),融合成一个网格零件;近似拓扑没有\n // role 层,故不产 `replica[k]/<inner>` 命名(如实缺席)。\n return meshPatternProduct(entry, 'circularPattern', 'E_PATTERN_FAILED', () =>\n entry.kernel.circularPattern(entry.solid, toBrepVec(center), toBrepVec(u), step, count),\n )\n },\n brep(input: Shape, axis: Vec3, count: number, fullAngle: number = 360, center: Vec3 = [0, 0, 0]) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'circularPattern')\n const u = norm(axis)\n const step = fullAngle / count\n const raw = kernel.circularPattern(solid, toBrepVec(center), toBrepVec(u), step, count)\n\n let resultSolid: BrepHandle\n try {\n resultSolid = kernel.fuseAll(raw)\n } finally {\n for (const c of raw) kernel.release(c)\n }\n\n const replicas: ReplicaTransform[] = []\n for (let k = 0; k < count; k++) {\n const theta = (-k * step * Math.PI) / 180\n replicas.push({\n label: `replica[${k}]`,\n inverse: (c) => rotateAroundAxis(c, toBrepVec(center), u, theta),\n })\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n },\n // 中立 op(D11):实现只用 L1 核心面(kernel.circularPattern/fuseAll)。\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n\n// ── gridPattern ─────────────────────────────────────────────────────────────\n\n/**\n * 二维栅格阵列:沿 directionX × directionY 复制 countX×countY 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name gridPattern\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[ix_iy]/<inner>`。\n * @returns Shape 全部副本的 compound。\n * @param input - 目标几何。type:Shape required:true\n * @param directionX - 第一方向。type:[x,y,z] required:true\n * @param directionY - 第二方向。type:[x,y,z] required:true\n * @param countX - X 向副本数。type:number required:true\n * @param countY - Y 向副本数。type:number required:true\n * @param spacingX - X 向间距。type:number required:true\n * @param spacingY - Y 向间距。type:number required:true\n * @example\n * const p = await cad.gridPattern(part0, [1, 0, 0], [0, 1, 0], 3, 2, 20, 20)\n */\nexport const gridPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(\n input: Shape,\n directionX: Vec3,\n directionY: Vec3,\n countX: number,\n countY: number,\n spacingX: number,\n spacingY: number,\n ) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'gridPattern')\n const dx = norm(directionX)\n const dy = norm(directionY)\n // 网格链走\"逐份平移 + fuseAll\"(与 rectangularPattern 同口径),不用内核的\n // `gridPattern`——那支返回**单个 compound 句柄**,近似拓扑无法把 compound 讲成\n // 一个网格零件;逐份平移则得到与线性/环形阵列同形的单一融合实体。\n return meshPatternProduct(entry, 'gridPattern', 'E_PATTERN_FAILED', () => {\n const copies: BrepHandle[] = []\n for (let ix = 0; ix < countX; ix++) {\n for (let iy = 0; iy < countY; iy++) {\n const ox = ix * spacingX\n const oy = iy * spacingY\n copies.push(entry.kernel.translate(\n entry.solid,\n ox * dx[0] + oy * dy[0],\n ox * dx[1] + oy * dy[1],\n ox * dx[2] + oy * dy[2],\n ))\n }\n }\n return copies\n })\n },\n brep(\n input: Shape,\n directionX: Vec3,\n directionY: Vec3,\n countX: number,\n countY: number,\n spacingX: number,\n spacingY: number,\n ) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'gridPattern')\n const dx = norm(directionX)\n const dy = norm(directionY)\n // kernel.gridPattern 返回 compound 单句柄(含全部副本),无需 fuse。\n const resultSolid = kernel.gridPattern(\n solid,\n toBrepVec(dx),\n toBrepVec(dy),\n spacingX,\n spacingY,\n countX,\n countY,\n )\n\n const replicas: ReplicaTransform[] = []\n for (let ix = 0; ix < countX; ix++) {\n for (let iy = 0; iy < countY; iy++) {\n const ox = ix * spacingX\n const oy = iy * spacingY\n replicas.push({\n label: `replica[${ix}_${iy}]`,\n inverse: (c) => ({\n x: c.x - (ox * dx[0] + oy * dy[0]),\n y: c.y - (ox * dx[1] + oy * dy[1]),\n z: c.z - (ox * dx[2] + oy * dy[2]),\n }),\n })\n }\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n },\n // 中立 op(D11):实现只用 L1 核心面(kernel.gridPattern/translate/fuseAll)。\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n// ── rectangularPattern ──────────────────────────────────────────────────────\n\ninterface RectangularPatternOptions {\n xDir: Vec3\n xCount: number\n xSpacing: number\n yDir: Vec3\n yCount: number\n ySpacing: number\n}\n\n/**\n * 矩形阵列:按 options(xDir/xCount/xSpacing/yDir/yCount/ySpacing)复制并 fuse。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name rectangularPattern\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[ix_iy]/<inner>`。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param options - 阵列参数。type:RectangularPatternOptions required:true\n * @example\n * const p = await cad.rectangularPattern(part0, { xDir: [1,0,0], xCount: 3, xSpacing: 20, yDir: [0,1,0], yCount: 2, ySpacing: 15 })\n */\nexport const rectangularPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, options: RectangularPatternOptions) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'rectangularPattern')\n const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options\n const dx = norm(xDir)\n const dy = norm(yDir)\n // 与 BREP 路径同一手法(逐份 translate 再 fuseAll),只是句柄来自网格后端。\n return meshPatternProduct(entry, 'rectangularPattern', 'E_PATTERN_FAILED', () => {\n const copies: BrepHandle[] = []\n for (let ix = 0; ix < xCount; ix++) {\n for (let iy = 0; iy < yCount; iy++) {\n const ox = ix * xSpacing\n const oy = iy * ySpacing\n copies.push(entry.kernel.translate(\n entry.solid,\n ox * dx[0] + oy * dy[0],\n ox * dx[1] + oy * dy[1],\n ox * dx[2] + oy * dy[2],\n ))\n }\n }\n return copies\n })\n },\n brep(input: Shape, options: RectangularPatternOptions) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'rectangularPattern')\n const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options\n const dx = norm(xDir)\n const dy = norm(yDir)\n // 实现为纯 JS 组合:逐份 translate 再 fuseAll,不依赖内核的 rectangularPattern 方法。\n const copies: BrepHandle[] = []\n try {\n for (let ix = 0; ix < xCount; ix++) {\n for (let iy = 0; iy < yCount; iy++) {\n const ox = ix * xSpacing\n const oy = iy * ySpacing\n copies.push(kernel.translate(solid, ox * dx[0] + oy * dy[0], ox * dx[1] + oy * dy[1], ox * dx[2] + oy * dy[2]))\n }\n }\n const resultSolid = kernel.fuseAll(copies)\n\n const replicas: ReplicaTransform[] = []\n for (let ix = 0; ix < xCount; ix++) {\n for (let iy = 0; iy < yCount; iy++) {\n const ox = ix * xSpacing\n const oy = iy * ySpacing\n replicas.push({\n label: `replica[${ix}_${iy}]`,\n inverse: (c) => ({\n x: c.x - (ox * dx[0] + oy * dy[0]),\n y: c.y - (ox * dx[1] + oy * dy[1]),\n z: c.z - (ox * dx[2] + oy * dy[2]),\n }),\n })\n }\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n } finally {\n for (const c of copies) kernel.release(c)\n }\n },\n // 中立 op(D11):实现只用 L1 核心面(kernel.translate/fuseAll)。\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n\n// ── mirrorJoin ──────────────────────────────────────────────────────────────\n\ninterface MirrorJoinOptions {\n normal?: Vec3\n at?: Vec3\n}\n\n/**\n * 镜像并融合:原物(replica[0])+ 沿平面镜像(replica[1])fuse 成一体。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name mirrorJoin\n * @note BREP-only。keep 语义:不消费输入。结果面回投输入面角色,产出 `replica[0|1]/<inner>`。\n * @returns Shape fuse 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param options - { normal?, at? } 镜像面法向与面上一点。type:MirrorJoinOptions required:false\n * @example\n * const p = await cad.mirrorJoin(part0, { normal: [1, 0, 0] })\n */\nexport const mirrorJoin = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, options?: MirrorJoinOptions) {\n keepHidden(input)\n const entry = meshSolidBasicEntry(input, 'mirrorJoin')\n const n = norm(optionVec(options?.normal, [1, 0, 0]))\n const o = toBrepVec(optionVec(options?.at, [0, 0, 0]))\n // 输入句柄**不释放**(keep 语义);只释放本次自造的镜像副本。\n let mirrored: BrepHandle\n try {\n mirrored = entry.kernel.mirror(entry.solid, o, toBrepVec(n))\n } catch (cause) {\n throw meshKernelFailure('mirrorJoin', 'E_MIRROR_FAILED', `mirror across normal [${n.join(', ')}]`, cause)\n }\n try {\n return meshSolidProduct(entry, entry.kernel.fuse(entry.solid, mirrored))\n } catch (cause) {\n throw meshKernelFailure('mirrorJoin', 'E_MIRROR_FAILED', 'fusing the mirrored copy', cause)\n } finally {\n entry.backend.release(mirrored)\n }\n },\n brep(input: Shape, options?: MirrorJoinOptions) {\n keepHidden(input)\n const { kernel, solid, outStmt } = prelude(input, 'mirrorJoin')\n const n = norm(options?.normal ?? [1, 0, 0])\n const o = toBrepVec(options?.at ?? [0, 0, 0])\n // replicate 的 role table 经质心聚类重建(引擎无关),mirror history 对\n // role table 无增量收益,故走 L1 kernel.mirror(两引擎的 L1 契约面均提供\n // `mirror`;`mirrorWithHistory` 不参与本 op,与引擎身份无关)。\n // 面演化由 mirrorBrep(topologyFns.ts)双轨接入,replicate 不重复消费。\n const mirrored = kernel.mirror(solid, o, toBrepVec(n))\n try {\n const resultSolid = kernel.fuse(solid, mirrored)\n\n const replicas: ReplicaTransform[] = [\n { label: 'replica[0]', inverse: (c) => ({ x: c.x, y: c.y, z: c.z }) },\n { label: 'replica[1]', inverse: (c) => reflectAcrossPlane(c, o, n) },\n ]\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n } finally {\n kernel.release(mirrored)\n }\n },\n // 中立 op(D11):实现只用 L1 核心面(kernel.mirror/fuse)。replicate 的\n // role table 不消费 mirror history(见上注释),面演化由 mirrorBrep 双轨接入。\n naming: { kind: 'replicate', k: 2 } as Provenance,\n})\n\n// ── single-copy thin overrides(keep + 委托生成 op)─────────────────────────\n\n/**\n * 镜像:返回镜像后的新 Shape(源保留)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name mirror\n * @note BREP-only。keep 语义:不消费输入(薄 override 委托生成 op,行为不变)。\n * @returns Shape 镜像后的新几何。\n * @param input - 目标几何。type:Shape required:true\n * @param options - { normal?, at? } 镜像面。type:MirrorOptions required:false\n * @example\n * const p = await cad.mirror(part0, { normal: [1, 0, 0] })\n */\nexport const mirror = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, options?: MirrorOptions) {\n keep(input)\n const entry = meshSolidBasicEntry(input, 'mirror')\n const n = norm(optionVec(options?.normal, [1, 0, 0]))\n const o = toBrepVec(optionVec(options?.at, [0, 0, 0]))\n let result: BrepHandle\n try {\n result = entry.kernel.mirror(entry.solid, o, toBrepVec(n))\n } catch (cause) {\n throw meshKernelFailure('mirror', 'E_MIRROR_FAILED', `mirror across normal [${n.join(', ')}]`, cause)\n }\n return meshSolidProduct(entry, result)\n },\n async brep(input: Shape, options?: MirrorOptions) {\n keep(input)\n return (await generatedMirror(input, options)) as Shape\n },\n // 薄 override:generatedMirror 走 L1 kernel.mirror,与 clone 薄 override 同模式\n // (无能力门,内层实现自行按引擎事实分叉)。面演化由 mirrorBrep 双轨接入。\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * 深拷贝句柄:返回独立副本(源保留)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name clone\n * @note BREP-only。keep 语义:不消费输入(薄 override 委托生成 op,行为不变)。\n * @returns Shape 克隆的新几何。\n * @param input - 目标几何。type:Shape required:true\n * @example\n * const p = await cad.clone(part0)\n */\nexport const clone = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape) {\n keep(input)\n const entry = meshSolidBasicEntry(input, 'clone')\n let result: BrepHandle\n try {\n result = entry.kernel.copyShape(entry.solid)\n } catch (cause) {\n throw meshKernelFailure('clone', 'E_CLONE_FAILED', 'copying the mesh solid handle', cause)\n }\n return meshSolidProduct(entry, result)\n },\n async brep(input: Shape) {\n keep(input)\n return (await generatedClone(input)) as Shape\n },\n // 中立 op(D11):实现只用 L1 核心面(kernel.copyShape)。\n naming: { kind: 'identity' } as Provenance,\n})\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"section-by-plane.d.ts","sourceRoot":"","sources":["../../src/api/section-by-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAQ1C,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEpC,+BAA+B;AAC/B,MAAM,WAAW,oBAAoB;IACnC,iBAAiB;IACjB,KAAK,EAAE,IAAI,CAAA;IACX,mBAAmB;IACnB,MAAM,EAAE,IAAI,CAAA;CACb;AAwBD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;CAOzB,CAAA"}
1
+ {"version":3,"file":"section-by-plane.d.ts","sourceRoot":"","sources":["../../src/api/section-by-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAQ1C,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEpC,+BAA+B;AAC/B,MAAM,WAAW,oBAAoB;IACnC,iBAAiB;IACjB,KAAK,EAAE,IAAI,CAAA;IACX,mBAAmB;IACnB,MAAM,EAAE,IAAI,CAAA;CACb;AAwBD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;CAMzB,CAAA"}
@@ -52,7 +52,6 @@ function sectionByPlaneBrep(input, params) {
52
52
  * const sec = await cad.sectionByPlane(part0, { point: [0,0,5], normal: [0,0,1] })
53
53
  */
54
54
  export const sectionByPlane = defineOp({
55
- capabilities: ['directEdit'],
56
55
  paramDims: { 'params.point': 'length', 'params.normal': 'length' },
57
56
  brep(input, params) {
58
57
  return sectionByPlaneBrep(input, params);
@@ -1 +1 @@
1
- {"version":3,"file":"section-by-plane.js","sourceRoot":"","sources":["../../src/api/section-by-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAajC,8DAA8D;AAC9D,SAAS,MAAM,CAAC,CAAO;IACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAA;IAC5F,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtC,CAAC;AAED,wEAAwE;AACxE,SAAS,kBAAkB,CAAC,KAAY,EAAE,MAA4B;IACpE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,IAAK,EAA2B,CAAA;IAChE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IACrD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IAC3F,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAC1E,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAA;IAC3F,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;IAC5C,OAAO,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;AAC3E,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;IACrC,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,SAAS,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE;IAClE,IAAI,CAAC,KAAY,EAAE,MAA4B;QAC7C,OAAO,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC1C,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,gDAAgD,EAAgB;CACtG,CAAC,CAAA","sourcesContent":["/**\n * api sectionByPlane — 平面截面:solid 与无限平面的精确交线(手写中立 op,Phase 6.2)\n *\n * 中立 op:L1 `sectionByPlane(shape, point, normal)` 在 occt 与 brepkit 两侧均有\n * 真实现 ⇒ 走 `getBrepApi()`(D12),不声明 engines。\n *\n * 产物形态(设计原则 5 + §2.4①):L1 返回交线句柄**数组**(occt 适配器把\n * compound 逐条 downcast 成 edge/wire),数组过不了单产物边界 —— 收拢为\n * **1D compound**(`makeCompound(edges)`)经 `fromBrepCurve` 登记为\n * `kind:'curve'`(Phase 3 判别位;wire/edge 载荷为空,显示走 L1 `wireframe`)。\n * 无交线(平面不与体相交)显式报错 —— 不返回假空产物(原则 9)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle, BrepVec3 } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, fromBrepCurve } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\n\ntype Vec3 = [number, number, number]\n\n/** `cad.sectionByPlane` 参数。 */\nexport interface SectionByPlaneParams {\n /** 平面上一点(mm)。 */\n point: Vec3\n /** 平面法向(不必单位化)。 */\n normal: Vec3\n}\n\n/** 元组 → BrepVec3 对象(同 split-by-plane:L1 向量形参是 {x,y,z} 对象)。 */\nfunction toVec3(v: Vec3): BrepVec3 {\n if (!Array.isArray(v) || v.length !== 3 || v.some((n) => typeof n !== 'number' || !Number.isFinite(n))) {\n throw new Error('E_SECTION_BY_PLANE_BAD_VEC: point/normal must be [x,y,z] finite numbers')\n }\n return { x: v[0], y: v[1], z: v[2] }\n}\n\n/** BREP 路径:L1 sectionByPlane → 交线收拢为 1D compound → fromBrepCurve 登记。 */\nfunction sectionByPlaneBrep(input: Shape, params: SectionByPlaneParams): Shape {\n const { point, normal } = params ?? ({} as SectionByPlaneParams)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error('E_SECTION_BY_PLANE_NO_BREP: sectionByPlane input is not BREP')\n const curves = kernel.sectionByPlane(solid, toVec3(point), toVec3(normal))\n if (!curves || curves.length === 0) {\n throw new Error('E_SECTION_BY_PLANE_NO_INTERSECTION: plane does not intersect the shape')\n }\n const compound = kernel.makeCompound(curves)\n return fromBrepCurve(solidToShape(kernel, compound), { solid: compound })\n}\n\n/**\n * 求实体与无限平面的精确截面线(1D 曲线,可继续建模/导出 STEP)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name sectionByPlane\n * @note 中立 op:L1 sectionByPlane 两引擎同实现。产物是 1D 曲线(kind:'curve',\n * 全部交线收拢为一个 compound);平面不与体相交时显式报错。\n * @returns Shape 1D 截面曲线。\n * @param input - 目标实体。type:Shape required:true\n * @param params.point - 平面上一点 [x,y,z](mm)。type:Vec3 required:true\n * @param params.normal - 平面法向 [x,y,z]。type:Vec3 required:true\n * @example\n * const sec = await cad.sectionByPlane(part0, { point: [0,0,5], normal: [0,0,1] })\n */\nexport const sectionByPlane = defineOp({\n capabilities: ['directEdit'],\n paramDims: { 'params.point': 'length', 'params.normal': 'length' },\n brep(input: Shape, params: SectionByPlaneParams) {\n return sectionByPlaneBrep(input, params)\n },\n naming: { kind: 'unmodeled', reason: '1D section curves have no face role vocabulary' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"section-by-plane.js","sourceRoot":"","sources":["../../src/api/section-by-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAajC,8DAA8D;AAC9D,SAAS,MAAM,CAAC,CAAO;IACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAA;IAC5F,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtC,CAAC;AAED,wEAAwE;AACxE,SAAS,kBAAkB,CAAC,KAAY,EAAE,MAA4B;IACpE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,IAAK,EAA2B,CAAA;IAChE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IACrD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IAC3F,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAC1E,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAA;IAC3F,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;IAC5C,OAAO,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;AAC3E,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;IACrC,SAAS,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE;IAClE,IAAI,CAAC,KAAY,EAAE,MAA4B;QAC7C,OAAO,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC1C,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,gDAAgD,EAAgB;CACtG,CAAC,CAAA","sourcesContent":["/**\n * api sectionByPlane — 平面截面:solid 与无限平面的精确交线(手写中立 op,Phase 6.2)\n *\n * 中立 op:L1 `sectionByPlane(shape, point, normal)` 在 occt 与 brepkit 两侧均有\n * 真实现 ⇒ 走 `getBrepApi()`(D12),不声明 engines。\n *\n * 产物形态(设计原则 5 + §2.4①):L1 返回交线句柄**数组**(occt 适配器把\n * compound 逐条 downcast 成 edge/wire),数组过不了单产物边界 —— 收拢为\n * **1D compound**(`makeCompound(edges)`)经 `fromBrepCurve` 登记为\n * `kind:'curve'`(Phase 3 判别位;wire/edge 载荷为空,显示走 L1 `wireframe`)。\n * 无交线(平面不与体相交)显式报错 —— 不返回假空产物(原则 9)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle, BrepVec3 } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, fromBrepCurve } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\n\ntype Vec3 = [number, number, number]\n\n/** `cad.sectionByPlane` 参数。 */\nexport interface SectionByPlaneParams {\n /** 平面上一点(mm)。 */\n point: Vec3\n /** 平面法向(不必单位化)。 */\n normal: Vec3\n}\n\n/** 元组 → BrepVec3 对象(同 split-by-plane:L1 向量形参是 {x,y,z} 对象)。 */\nfunction toVec3(v: Vec3): BrepVec3 {\n if (!Array.isArray(v) || v.length !== 3 || v.some((n) => typeof n !== 'number' || !Number.isFinite(n))) {\n throw new Error('E_SECTION_BY_PLANE_BAD_VEC: point/normal must be [x,y,z] finite numbers')\n }\n return { x: v[0], y: v[1], z: v[2] }\n}\n\n/** BREP 路径:L1 sectionByPlane → 交线收拢为 1D compound → fromBrepCurve 登记。 */\nfunction sectionByPlaneBrep(input: Shape, params: SectionByPlaneParams): Shape {\n const { point, normal } = params ?? ({} as SectionByPlaneParams)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error('E_SECTION_BY_PLANE_NO_BREP: sectionByPlane input is not BREP')\n const curves = kernel.sectionByPlane(solid, toVec3(point), toVec3(normal))\n if (!curves || curves.length === 0) {\n throw new Error('E_SECTION_BY_PLANE_NO_INTERSECTION: plane does not intersect the shape')\n }\n const compound = kernel.makeCompound(curves)\n return fromBrepCurve(solidToShape(kernel, compound), { solid: compound })\n}\n\n/**\n * 求实体与无限平面的精确截面线(1D 曲线,可继续建模/导出 STEP)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name sectionByPlane\n * @note 中立 op:L1 sectionByPlane 两引擎同实现。产物是 1D 曲线(kind:'curve',\n * 全部交线收拢为一个 compound);平面不与体相交时显式报错。\n * @returns Shape 1D 截面曲线。\n * @param input - 目标实体。type:Shape required:true\n * @param params.point - 平面上一点 [x,y,z](mm)。type:Vec3 required:true\n * @param params.normal - 平面法向 [x,y,z]。type:Vec3 required:true\n * @example\n * const sec = await cad.sectionByPlane(part0, { point: [0,0,5], normal: [0,0,1] })\n */\nexport const sectionByPlane = defineOp({\n paramDims: { 'params.point': 'length', 'params.normal': 'length' },\n brep(input: Shape, params: SectionByPlaneParams) {\n return sectionByPlaneBrep(input, params)\n },\n naming: { kind: 'unmodeled', reason: '1D section curves have no face role vocabulary' } as Provenance,\n})\n"]}
@@ -4,7 +4,7 @@
4
4
  * 中立 op:L1 `shell(solid, facesToRemove, thickness, tolerance)` 在 occt 与
5
5
  * brepkit 两侧均有真实现(engine-method-map 实测 `dialect`)⇒ 走 `getBrepApi()`
6
6
  * (D12),不声明 engines(中立 op:实现只经 L1 契约面)。相对现状是
7
- * 能力升级——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。
7
+ * 覆盖面扩大——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。
8
8
  *
9
9
  * 选面口径(设计原则 4):`openFaces: FaceTopoRef[]`(`cad.faceRef` 产物),
10
10
  * 与 `fillet` 的 `EdgeTopoRef[]` / `extrude` 的 `upTo` 同族;不复刻旧
@@ -1 +1 @@
1
- {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAM1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAMrD,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,WAAW,CAAA;AAEpD,sBAAsB;AACtB,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,SAAS,EAAE,iBAAiB,EAAE,CAAA;IAC9B,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA6ED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,KAAK;;CAUhB,CAAA"}
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAQ1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAMrD,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,WAAW,CAAA;AAEpD,sBAAsB;AACtB,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,SAAS,EAAE,iBAAiB,EAAE,CAAA;IAC9B,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqFD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,KAAK;;CAShB,CAAA"}
package/dist/api/shell.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * 中立 op:L1 `shell(solid, facesToRemove, thickness, tolerance)` 在 occt 与
5
5
  * brepkit 两侧均有真实现(engine-method-map 实测 `dialect`)⇒ 走 `getBrepApi()`
6
6
  * (D12),不声明 engines(中立 op:实现只经 L1 契约面)。相对现状是
7
- * 能力升级——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。
7
+ * 覆盖面扩大——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。
8
8
  *
9
9
  * 选面口径(设计原则 4):`openFaces: FaceTopoRef[]`(`cad.faceRef` 产物),
10
10
  * 与 `fillet` 的 `EdgeTopoRef[]` / `extrude` 的 `upTo` 同族;不复刻旧
@@ -16,8 +16,10 @@
16
16
  */
17
17
  import { solidToShape } from '../brep/brep-ops.js';
18
18
  import { getBrepApi } from '../brep/handle-bridge.js';
19
+ import { shellWithHashEvolution } from '../brep/face-evolution.js';
19
20
  import { brepOf, fromBrep } from '../shape.js';
20
21
  import { defineOp } from '../sdk.js';
22
+ import { hasNativeHistory } from '../brep/engine/native-history.js';
21
23
  import { resolveTopoRef, TopoRefError } from '../topology/naming/index.js';
22
24
  import { buildEdgeResolutionContext } from './topo-resolve.js';
23
25
  import { meshKernelFailure, meshSolidBasicEntry, meshSolidProduct, resolveMeshFaces } from './internal/mesh-solid-op.js';
@@ -57,6 +59,14 @@ function shellBrep(input, params) {
57
59
  }
58
60
  return r.handle;
59
61
  });
62
+ // C5 实现面接入(静态双轨,无运行时 try-catch):
63
+ // - occt 原生有 `shellWithHistory` → 走权威面演化(血缘更准);
64
+ // - brepkit 没有 → 显式回退裸 L1 `shell`(**不报错**),不伪造面演化
65
+ // (抽壳是毁面重造,恒等映射不真实)。
66
+ if (hasNativeHistory('shellWithHistory')) {
67
+ const r = shellWithHashEvolution(kernel, solid, faceHandles, thickness, tolerance ?? 1e-6);
68
+ return fromBrep(solidToShape(kernel, r.result), { solid: r.result, faceEvolution: r.faceEvolution });
69
+ }
60
70
  const result = kernel.shell(solid, faceHandles, thickness, tolerance ?? 1e-6);
61
71
  return fromBrep(solidToShape(kernel, result), { solid: result });
62
72
  }
@@ -106,7 +116,6 @@ function shellMeshSolid(input, params) {
106
116
  * const sm = await cad.shell(meshPart, { openFaces: [4], thickness: 2 })
107
117
  */
108
118
  export const shell = defineOp({
109
- capabilities: ['directEdit'],
110
119
  meshEngines: ['brepkit'],
111
120
  mesh(input, params) {
112
121
  return shellMeshSolid(input, params);
@@ -1 +1 @@
1
- {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api shell — 抽壳:按面移除生成等厚薄壁(手写中立 op,Phase 5)\n *\n * 中立 op:L1 `shell(solid, facesToRemove, thickness, tolerance)` 在 occt 与\n * brepkit 两侧均有真实现(engine-method-map 实测 `dialect`)⇒ 走 `getBrepApi()`\n * (D12),不声明 engines(中立 op:实现只经 L1 契约面)。相对现状是\n * 能力升级——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。\n *\n * 选面口径(设计原则 4):`openFaces: FaceTopoRef[]`(`cad.faceRef` 产物),\n * 与 `fillet` 的 `EdgeTopoRef[]` / `extrude` 的 `upTo` 同族;不复刻旧\n * `Face[]` 句柄入参。解析在 op 内一处完成(`buildEdgeResolutionContext` 现场枚举\n * + `resolveTopoRef`)。\n *\n * 网格链(方案 2026-10-01 §4 Phase 4 / B3 批):`mesh:` 实现走网格后端,面按\n * **序号或 FaceTopoRef** 解析(近似拓扑没有 role 层),产物是新的网格零件。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { resolveTopoRef, TopoRefError } from '../topology/naming'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { buildEdgeResolutionContext } from './topo-resolve'\nimport { meshKernelFailure, meshSolidBasicEntry, meshSolidProduct, resolveMeshFaces } from './internal/mesh-solid-op'\n\n/** 抽壳时移除的面选择器:精度链用 `FaceTopoRef`;网格链也可用 1 起序号。 */\nexport type ShellFaceSelector = number | FaceTopoRef\n\n/** `cad.shell` 参数。 */\nexport interface ShellParams {\n /** 抽壳时移除的面(FaceTopoRef[],`cad.faceRef` 产物;空数组 = 全封闭薄壁)。 */\n openFaces: ShellFaceSelector[]\n /** 壁厚(mm,>0,向内偏置)。 */\n thickness: number\n /** 容差(mm,可选;默认走内核约定值)。 */\n tolerance?: number\n}\n\n/** 参数共校验(两条路径共用;`openFaces` 为空数组合法 = 全封闭薄壁)。 */\nfunction assertShellParams(params: ShellParams): void {\n const { openFaces, thickness } = params ?? ({} as ShellParams)\n if (!Array.isArray(openFaces)) {\n throw new Error('E_SHELL_BAD_OPEN_FACES: shell.openFaces must be an array of FaceTopoRef or ordinals')\n }\n if (typeof thickness !== 'number' || !Number.isFinite(thickness) || thickness <= 0) {\n throw new Error('E_SHELL_BAD_THICKNESS: shell.thickness must be a positive number')\n }\n}\n\n/** BREP 路径:解析面引用 → L1 shell → 收养。 */\nfunction shellBrep(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error('E_SHELL_NO_BREP: shell input is not BREP')\n\n const ctx = buildEdgeResolutionContext(kernel, input as object)\n if (!ctx) throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'shell: input has no BREP naming context')\n const faceHandles = openFaces.map((ref) => {\n // 精度链不开序号口子:BREP 的面身份是 `(origin, role)`,序号只是本次枚举序。\n if (typeof ref === 'number') {\n throw new Error(\n 'E_SHELL_BAD_OPEN_FACES: an ordinal face selector is only available on the mesh chain — ' +\n 'a precision-chain face is identified by its role line (cad.faceRef)',\n )\n }\n if (!ref || (ref as { kind?: unknown }).kind !== 'face') {\n throw new Error('E_SHELL_BAD_OPEN_FACES: every openFaces entry must be a FaceTopoRef (cad.faceRef)')\n }\n const r = resolveTopoRef(ref, ctx)\n if (r.handle === undefined) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `shell: face resolved without handle (${ref.origin}/${ref.role})`)\n }\n return r.handle as BrepHandle\n })\n\n const result = kernel.shell(solid, faceHandles, thickness, tolerance ?? 1e-6)\n return fromBrep(solidToShape(kernel, result), { solid: result })\n}\n\n/**\n * 网格实体路径:按序号或几何选出要开口的面,交网格后端抽壳。\n *\n * 与 BREP 路径同一条 L1 契约面(`shell(solid, faces, thickness, tolerance)`),\n * 差别只在选面方式:近似拓扑没有 role 层,面靠**序号**(拓扑 `faces` 数组下标 + 1)\n * 或 `FaceTopoRef` 的几何匹配(法向/中心/面积)指认。产物是新网格零件,\n * 近似拓扑由 `meshSolidProduct` 重建。\n *\n * @param input - the mesh-solid input.\n * @param params - the shell parameters.\n * @returns the shelled mesh solid as a new mesh part.\n */\nfunction shellMeshSolid(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const entry = meshSolidBasicEntry(input, 'shell')\n const faceHandles = resolveMeshFaces(entry.kernel, input, openFaces, 'shell')\n\n let result: BrepHandle\n try {\n result = entry.kernel.shell(entry.solid, faceHandles, thickness, tolerance ?? 1e-6)\n } catch (cause) {\n throw meshKernelFailure(\n 'shell',\n 'E_SHELL_FAILED',\n `shell(thickness=${thickness}) removing ${faceHandles.length} face(s)`,\n cause,\n )\n }\n return meshSolidProduct(entry, result)\n}\n\n/**\n * 抽壳:移除指定面并把余下面偏置成等厚薄壁。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name shell\n * @note 中立 op:L1 shell 两引擎同实现。`openFaces` 为空数组时生成全封闭薄壁。\n * 精度链按 role 线路选面(`cad.faceRef`);网格链按序号或几何选面——网格零件\n * 没有 role 层,序号是唯一无歧义的指认方式。\n * @returns Shape 抽壳后的薄壁体。\n * @param input - 目标几何。type:Shape required:true\n * @param params.openFaces - 要移除的面(FaceTopoRef[],cad.faceRef 产物;网格链可用 1 起序号)。type:FaceTopoRef[] required:true\n * @param params.thickness - 壁厚(mm,>0)。type:number required:true\n * @param params.tolerance - 容差(mm)。type:number required:false\n * @example\n * const sh = await cad.shell(part0, { openFaces: [cad.faceRef(part0, 1)], thickness: 2 })\n * const sm = await cad.shell(meshPart, { openFaces: [4], thickness: 2 })\n */\nexport const shell = defineOp({\n capabilities: ['directEdit'],\n meshEngines: ['brepkit'],\n mesh(input: Shape, params: ShellParams) {\n return shellMeshSolid(input, params)\n },\n brep(input: Shape, params: ShellParams) {\n return shellBrep(input, params)\n },\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api shell — 抽壳:按面移除生成等厚薄壁(手写中立 op,Phase 5)\n *\n * 中立 op:L1 `shell(solid, facesToRemove, thickness, tolerance)` 在 occt 与\n * brepkit 两侧均有真实现(engine-method-map 实测 `dialect`)⇒ 走 `getBrepApi()`\n * (D12),不声明 engines(中立 op:实现只经 L1 契约面)。相对现状是\n * 覆盖面扩大——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。\n *\n * 选面口径(设计原则 4):`openFaces: FaceTopoRef[]`(`cad.faceRef` 产物),\n * 与 `fillet` 的 `EdgeTopoRef[]` / `extrude` 的 `upTo` 同族;不复刻旧\n * `Face[]` 句柄入参。解析在 op 内一处完成(`buildEdgeResolutionContext` 现场枚举\n * + `resolveTopoRef`)。\n *\n * 网格链(方案 2026-10-01 §4 Phase 4 / B3 批):`mesh:` 实现走网格后端,面按\n * **序号或 FaceTopoRef** 解析(近似拓扑没有 role 层),产物是新的网格零件。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { shellWithHashEvolution } from '../brep/face-evolution'\nimport { brepOf, fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\nimport { hasNativeHistory } from '../brep/engine/native-history'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { resolveTopoRef, TopoRefError } from '../topology/naming'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { buildEdgeResolutionContext } from './topo-resolve'\nimport { meshKernelFailure, meshSolidBasicEntry, meshSolidProduct, resolveMeshFaces } from './internal/mesh-solid-op'\n\n/** 抽壳时移除的面选择器:精度链用 `FaceTopoRef`;网格链也可用 1 起序号。 */\nexport type ShellFaceSelector = number | FaceTopoRef\n\n/** `cad.shell` 参数。 */\nexport interface ShellParams {\n /** 抽壳时移除的面(FaceTopoRef[],`cad.faceRef` 产物;空数组 = 全封闭薄壁)。 */\n openFaces: ShellFaceSelector[]\n /** 壁厚(mm,>0,向内偏置)。 */\n thickness: number\n /** 容差(mm,可选;默认走内核约定值)。 */\n tolerance?: number\n}\n\n/** 参数共校验(两条路径共用;`openFaces` 为空数组合法 = 全封闭薄壁)。 */\nfunction assertShellParams(params: ShellParams): void {\n const { openFaces, thickness } = params ?? ({} as ShellParams)\n if (!Array.isArray(openFaces)) {\n throw new Error('E_SHELL_BAD_OPEN_FACES: shell.openFaces must be an array of FaceTopoRef or ordinals')\n }\n if (typeof thickness !== 'number' || !Number.isFinite(thickness) || thickness <= 0) {\n throw new Error('E_SHELL_BAD_THICKNESS: shell.thickness must be a positive number')\n }\n}\n\n/** BREP 路径:解析面引用 → L1 shell → 收养。 */\nfunction shellBrep(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error('E_SHELL_NO_BREP: shell input is not BREP')\n\n const ctx = buildEdgeResolutionContext(kernel, input as object)\n if (!ctx) throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'shell: input has no BREP naming context')\n const faceHandles = openFaces.map((ref) => {\n // 精度链不开序号口子:BREP 的面身份是 `(origin, role)`,序号只是本次枚举序。\n if (typeof ref === 'number') {\n throw new Error(\n 'E_SHELL_BAD_OPEN_FACES: an ordinal face selector is only available on the mesh chain — ' +\n 'a precision-chain face is identified by its role line (cad.faceRef)',\n )\n }\n if (!ref || (ref as { kind?: unknown }).kind !== 'face') {\n throw new Error('E_SHELL_BAD_OPEN_FACES: every openFaces entry must be a FaceTopoRef (cad.faceRef)')\n }\n const r = resolveTopoRef(ref, ctx)\n if (r.handle === undefined) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `shell: face resolved without handle (${ref.origin}/${ref.role})`)\n }\n return r.handle as BrepHandle\n })\n\n // C5 实现面接入(静态双轨,无运行时 try-catch):\n // - occt 原生有 `shellWithHistory` → 走权威面演化(血缘更准);\n // - brepkit 没有 → 显式回退裸 L1 `shell`(**不报错**),不伪造面演化\n // (抽壳是毁面重造,恒等映射不真实)。\n if (hasNativeHistory('shellWithHistory')) {\n const r = shellWithHashEvolution(kernel, solid, faceHandles, thickness, tolerance ?? 1e-6)\n return fromBrep(solidToShape(kernel, r.result), { solid: r.result, faceEvolution: r.faceEvolution })\n }\n const result = kernel.shell(solid, faceHandles, thickness, tolerance ?? 1e-6)\n return fromBrep(solidToShape(kernel, result), { solid: result })\n}\n\n/**\n * 网格实体路径:按序号或几何选出要开口的面,交网格后端抽壳。\n *\n * 与 BREP 路径同一条 L1 契约面(`shell(solid, faces, thickness, tolerance)`),\n * 差别只在选面方式:近似拓扑没有 role 层,面靠**序号**(拓扑 `faces` 数组下标 + 1)\n * 或 `FaceTopoRef` 的几何匹配(法向/中心/面积)指认。产物是新网格零件,\n * 近似拓扑由 `meshSolidProduct` 重建。\n *\n * @param input - the mesh-solid input.\n * @param params - the shell parameters.\n * @returns the shelled mesh solid as a new mesh part.\n */\nfunction shellMeshSolid(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const entry = meshSolidBasicEntry(input, 'shell')\n const faceHandles = resolveMeshFaces(entry.kernel, input, openFaces, 'shell')\n\n let result: BrepHandle\n try {\n result = entry.kernel.shell(entry.solid, faceHandles, thickness, tolerance ?? 1e-6)\n } catch (cause) {\n throw meshKernelFailure(\n 'shell',\n 'E_SHELL_FAILED',\n `shell(thickness=${thickness}) removing ${faceHandles.length} face(s)`,\n cause,\n )\n }\n return meshSolidProduct(entry, result)\n}\n\n/**\n * 抽壳:移除指定面并把余下面偏置成等厚薄壁。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name shell\n * @note 中立 op:L1 shell 两引擎同实现。`openFaces` 为空数组时生成全封闭薄壁。\n * 精度链按 role 线路选面(`cad.faceRef`);网格链按序号或几何选面——网格零件\n * 没有 role 层,序号是唯一无歧义的指认方式。\n * @returns Shape 抽壳后的薄壁体。\n * @param input - 目标几何。type:Shape required:true\n * @param params.openFaces - 要移除的面(FaceTopoRef[],cad.faceRef 产物;网格链可用 1 起序号)。type:FaceTopoRef[] required:true\n * @param params.thickness - 壁厚(mm,>0)。type:number required:true\n * @param params.tolerance - 容差(mm)。type:number required:false\n * @example\n * const sh = await cad.shell(part0, { openFaces: [cad.faceRef(part0, 1)], thickness: 2 })\n * const sm = await cad.shell(meshPart, { openFaces: [4], thickness: 2 })\n */\nexport const shell = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, params: ShellParams) {\n return shellMeshSolid(input, params)\n },\n brep(input: Shape, params: ShellParams) {\n return shellBrep(input, params)\n },\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n"]}
@@ -13,9 +13,9 @@
13
13
  *
14
14
  * v1 scope: the on-surface primitive is surface-type-independent, but the result
15
15
  * face is built with `makeFace` on the interpolated wire, so it is exact for
16
- * planar faces; embedding the wire into a genuinely curved host face
17
- * (`fixWireOnFace`) is a follow-up. The op declares `engines: ['occt']`
18
- * (surface sampling needs the BREP platform).
16
+ * planar faces; for curved host faces the wire is snapped to the surface via
17
+ * `fixWireOnFace` (occt-wasm 5.6) before `makeFace`. The op declares
18
+ * `engines: ['occt']` (surface sampling needs the BREP platform).
19
19
  *
20
20
  * **Two chains, two mechanisms** (plan 2026-10-01 §4 Phase 3). The BREP branch
21
21
  * above maps the contour into the host face's UV domain. The **mesh branch**
@@ -1 +1 @@
1
- {"version":3,"file":"sketch-on-face.d.ts","sourceRoot":"","sources":["../../src/api/sketch-on-face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAMtD,OAAO,EAAgC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAKnF,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAGxF,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAStF,wGAAwG;AACxG,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,CAAA;AAE/C,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,sFAAsF;IACtF,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,qDAAqD;IACrD,EAAE,EAAE,KAAK,CAAA;IACT,+EAA+E;IAC/E,IAAI,EAAE,YAAY,CAAA;IAClB,8GAA8G;IAC9G,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,gHAAgH;IAChH,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,GAAG,UAAU,CA0BtG;AA6BD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,WAAW,EAAE,GACtB,UAAU,EAAE,CAMd;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,kBAAkB,GAAG,KAAK,CAyB9F;AAoCD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,KAAK,CAgDvE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY;;CAavB,CAAA"}
1
+ {"version":3,"file":"sketch-on-face.d.ts","sourceRoot":"","sources":["../../src/api/sketch-on-face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAMtD,OAAO,EAAgC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAKnF,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAGxF,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAUtF,wGAAwG;AACxG,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,CAAA;AAE/C,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,sFAAsF;IACtF,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,qDAAqD;IACrD,EAAE,EAAE,KAAK,CAAA;IACT,+EAA+E;IAC/E,IAAI,EAAE,YAAY,CAAA;IAClB,8GAA8G;IAC9G,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,gHAAgH;IAChH,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,GAAG,UAAU,CA0BtG;AA+BD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,WAAW,EAAE,GACtB,UAAU,EAAE,CAMd;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,kBAAkB,GAAG,KAAK,CAyB9F;AAoCD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,KAAK,CAgDvE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY;;CAYvB,CAAA"}
@@ -11,6 +11,7 @@ import { assembleWireOnFace } from '../geometry2d/bridge/on-surface.js';
11
11
  import { assembleWire } from '../geometry2d/bridge/lift-on-plane.js';
12
12
  import { profileSegToCurve } from '../geometry2d/adapt.js';
13
13
  import { assertProfileParams, toContourBlueprints } from './profile.js';
14
+ import { fixWireOnFaceBrep } from './brep-operations/healingFns.js';
14
15
  import { MeshUnsupportedError, getCurrentStmt } from '../runtime-state.js';
15
16
  import { meshBackendOrThrow, meshFacePlane, meshFaceProduct, resolveMeshFaceHandle, } from './internal/mesh-solid-op.js';
16
17
  /**
@@ -62,13 +63,15 @@ function orientLikeHost(kernel, host, face) {
62
63
  /** Build one face (outer + optional holes) on the host face for an organised contour entry. */
63
64
  function buildOnFace(kernel, host, mode, entry) {
64
65
  if (entry instanceof CompoundBlueprint) {
65
- let face = orientLikeHost(kernel, host, kernel.makeFace(assembleWireOnFace(kernel, host, mode, entry.blueprints[0]).wire));
66
- const holes = entry.blueprints.slice(1).map((h) => assembleWireOnFace(kernel, host, mode, h).wire);
66
+ const outerWire = fixWireOnFaceBrep(assembleWireOnFace(kernel, host, mode, entry.blueprints[0]).wire, host);
67
+ let face = orientLikeHost(kernel, host, kernel.makeFace(outerWire));
68
+ const holes = entry.blueprints.slice(1).map((h) => fixWireOnFaceBrep(assembleWireOnFace(kernel, host, mode, h).wire, host));
67
69
  if (holes.length > 0)
68
70
  face = kernel.addHolesInFace(face, holes);
69
71
  return face;
70
72
  }
71
- return orientLikeHost(kernel, host, kernel.makeFace(assembleWireOnFace(kernel, host, mode, entry).wire));
73
+ const wire = fixWireOnFaceBrep(assembleWireOnFace(kernel, host, mode, entry).wire, host);
74
+ return orientLikeHost(kernel, host, kernel.makeFace(wire));
72
75
  }
73
76
  /**
74
77
  * Place `contours` onto the UV space of the host face and return one BREP face
@@ -219,7 +222,6 @@ export function buildSketchOnFaceMesh(params) {
219
222
  * @param params.as - `'face'` (default) or `'wire'` (outer loop only).type:string required:false
220
223
  */
221
224
  export const sketchOnFace = defineOp({
222
- capabilities: ['directEdit'],
223
225
  engines: ['occt'],
224
226
  meshEngines: ['brepkit'],
225
227
  mesh(params) {