@faicad/faijs 0.14.1 → 0.16.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.
Files changed (338) hide show
  1. package/dist/api/api-namespace.d.ts +7 -0
  2. package/dist/api/api-namespace.d.ts.map +1 -1
  3. package/dist/api/api-namespace.js +23 -22
  4. package/dist/api/api-namespace.js.map +1 -1
  5. package/dist/api/boolean.d.ts.map +1 -1
  6. package/dist/api/boolean.js +26 -8
  7. package/dist/api/boolean.js.map +1 -1
  8. package/dist/api/chamfer.d.ts.map +1 -1
  9. package/dist/api/chamfer.js +4 -1
  10. package/dist/api/chamfer.js.map +1 -1
  11. package/dist/api/generated/cad/script-face.d.ts +1 -1
  12. package/dist/api/generated/cad/script-face.d.ts.map +1 -1
  13. package/dist/api/generated/cad/script-face.js +1 -2
  14. package/dist/api/generated/cad/script-face.js.map +1 -1
  15. package/dist/api/generated/operations.js +16 -16
  16. package/dist/api/generated/operations.js.map +1 -1
  17. package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
  18. package/dist/api/generated/script-face-manifest.js +0 -1
  19. package/dist/api/generated/script-face-manifest.js.map +1 -1
  20. package/dist/api/generated/script-face.d.ts +1 -4
  21. package/dist/api/generated/script-face.d.ts.map +1 -1
  22. package/dist/api/generated/script-face.js +2 -3
  23. package/dist/api/generated/script-face.js.map +1 -1
  24. package/dist/api/generated/sketching.js +1 -1
  25. package/dist/api/generated/sketching.js.map +1 -1
  26. package/dist/api/generated/topology.d.ts +0 -8
  27. package/dist/api/generated/topology.d.ts.map +1 -1
  28. package/dist/api/generated/topology.js +19 -26
  29. package/dist/api/generated/topology.js.map +1 -1
  30. package/dist/api/index.d.ts +1 -10
  31. package/dist/api/index.d.ts.map +1 -1
  32. package/dist/api/index.js +10 -18
  33. package/dist/api/index.js.map +1 -1
  34. package/dist/api/internal/compat-projection.d.ts +3 -1
  35. package/dist/api/internal/compat-projection.d.ts.map +1 -1
  36. package/dist/api/internal/compat-projection.js +8 -5
  37. package/dist/api/internal/compat-projection.js.map +1 -1
  38. package/dist/api/internal/replica-role-table.d.ts +36 -0
  39. package/dist/api/internal/replica-role-table.d.ts.map +1 -0
  40. package/dist/api/internal/replica-role-table.js +73 -0
  41. package/dist/api/internal/replica-role-table.js.map +1 -0
  42. package/dist/api/internal/result-unwrap.d.ts +3 -1
  43. package/dist/api/internal/result-unwrap.d.ts.map +1 -1
  44. package/dist/api/internal/result-unwrap.js +2 -2
  45. package/dist/api/internal/result-unwrap.js.map +1 -1
  46. package/dist/api/occt-kernel-bridge.d.ts +105 -27
  47. package/dist/api/occt-kernel-bridge.d.ts.map +1 -1
  48. package/dist/api/occt-kernel-bridge.js +255 -41
  49. package/dist/api/occt-kernel-bridge.js.map +1 -1
  50. package/dist/api/pattern.d.ts.map +1 -1
  51. package/dist/api/pattern.js +25 -61
  52. package/dist/api/pattern.js.map +1 -1
  53. package/dist/api/replicate.d.ts +145 -0
  54. package/dist/api/replicate.d.ts.map +1 -0
  55. package/dist/api/replicate.js +351 -0
  56. package/dist/api/replicate.js.map +1 -0
  57. package/dist/api/revolve.d.ts +36 -0
  58. package/dist/api/revolve.d.ts.map +1 -0
  59. package/dist/api/revolve.js +165 -0
  60. package/dist/api/revolve.js.map +1 -0
  61. package/dist/api/surface/arg-spec.d.ts +8 -0
  62. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  63. package/dist/api/surface/arg-spec.js +37 -36
  64. package/dist/api/surface/arg-spec.js.map +1 -1
  65. package/dist/api/surface/projection-overrides.d.ts.map +1 -1
  66. package/dist/api/surface/projection-overrides.js +6 -0
  67. package/dist/api/surface/projection-overrides.js.map +1 -1
  68. package/dist/boolean/deriveNormals.d.ts +5 -4
  69. package/dist/boolean/deriveNormals.d.ts.map +1 -1
  70. package/dist/boolean/deriveNormals.js +24 -7
  71. package/dist/boolean/deriveNormals.js.map +1 -1
  72. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  73. package/dist/brep/engine/adapters/brep-mock.js +58 -0
  74. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  75. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  76. package/dist/brep/engine/adapters/brepkit.js +39 -1
  77. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  78. package/dist/brep/engine/adapters/occt.d.ts +1 -5
  79. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  80. package/dist/brep/engine/adapters/occt.js +232 -18
  81. package/dist/brep/engine/adapters/occt.js.map +1 -1
  82. package/dist/brep/engine/primitives.d.ts +79 -0
  83. package/dist/brep/engine/primitives.d.ts.map +1 -1
  84. package/dist/brep/engine/primitives.js.map +1 -1
  85. package/dist/brep/engine/types.d.ts +18 -1
  86. package/dist/brep/engine/types.d.ts.map +1 -1
  87. package/dist/brep/engine/types.js.map +1 -1
  88. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  89. package/dist/brepkit-kernel/brepkitKernel.js +81 -11
  90. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  91. package/dist/browser.d.ts +6 -28
  92. package/dist/browser.d.ts.map +1 -1
  93. package/dist/browser.js +6 -17
  94. package/dist/browser.js.map +1 -1
  95. package/dist/cad-runtime/admit-compat-lib.d.ts +13 -18
  96. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  97. package/dist/cad-runtime/admit-compat-lib.js +25 -18
  98. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  99. package/dist/cad-runtime/backend-dispatch.d.ts +4 -2
  100. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  101. package/dist/cad-runtime/backend-dispatch.js +2 -0
  102. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  103. package/dist/cad-runtime/browser-lib-loader.d.ts +4 -6
  104. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  105. package/dist/cad-runtime/browser-lib-loader.js +4 -9
  106. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  107. package/dist/cad-runtime/ports.d.ts +0 -7
  108. package/dist/cad-runtime/ports.d.ts.map +1 -1
  109. package/dist/cad-runtime/ports.js.map +1 -1
  110. package/dist/cad-runtime/runtime.d.ts +1 -3
  111. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  112. package/dist/cad-runtime/runtime.js +13 -18
  113. package/dist/cad-runtime/runtime.js.map +1 -1
  114. package/dist/env-agnostic.d.ts +38 -0
  115. package/dist/env-agnostic.d.ts.map +1 -0
  116. package/dist/env-agnostic.js +29 -0
  117. package/dist/env-agnostic.js.map +1 -0
  118. package/dist/fcstd/codegen.d.ts.map +1 -1
  119. package/dist/fcstd/codegen.js +8 -1
  120. package/dist/fcstd/codegen.js.map +1 -1
  121. package/dist/fcstd/expressions.d.ts +24 -0
  122. package/dist/fcstd/expressions.d.ts.map +1 -1
  123. package/dist/fcstd/expressions.js +91 -0
  124. package/dist/fcstd/expressions.js.map +1 -1
  125. package/dist/fcstd/feature-translate.d.ts.map +1 -1
  126. package/dist/fcstd/feature-translate.js +16 -2
  127. package/dist/fcstd/feature-translate.js.map +1 -1
  128. package/dist/fcstd/structural-types.d.ts.map +1 -1
  129. package/dist/fcstd/structural-types.js +5 -0
  130. package/dist/fcstd/structural-types.js.map +1 -1
  131. package/dist/index.d.ts +7 -24
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +10 -16
  134. package/dist/index.js.map +1 -1
  135. package/dist/lang/determinism-scanner.d.ts +9 -0
  136. package/dist/lang/determinism-scanner.d.ts.map +1 -1
  137. package/dist/lang/determinism-scanner.js +7 -1
  138. package/dist/lang/determinism-scanner.js.map +1 -1
  139. package/dist/lang/symbol-table.d.ts +31 -0
  140. package/dist/lang/symbol-table.d.ts.map +1 -1
  141. package/dist/lang/symbol-table.generated.d.ts +6 -16
  142. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  143. package/dist/lang/symbol-table.generated.js +6 -16
  144. package/dist/lang/symbol-table.generated.js.map +1 -1
  145. package/dist/lang/symbol-table.js +50 -1
  146. package/dist/lang/symbol-table.js.map +1 -1
  147. package/dist/mesh/creased-normals.d.ts +50 -0
  148. package/dist/mesh/creased-normals.d.ts.map +1 -0
  149. package/dist/mesh/creased-normals.js +114 -0
  150. package/dist/mesh/creased-normals.js.map +1 -0
  151. package/dist/mesh/decoration-provider.d.ts +53 -0
  152. package/dist/mesh/decoration-provider.d.ts.map +1 -0
  153. package/dist/mesh/decoration-provider.js +21 -0
  154. package/dist/mesh/decoration-provider.js.map +1 -0
  155. package/dist/mesh/engrave.d.ts +4 -0
  156. package/dist/mesh/engrave.d.ts.map +1 -1
  157. package/dist/mesh/engrave.js +22 -31
  158. package/dist/mesh/engrave.js.map +1 -1
  159. package/dist/mesh/index.d.ts +5 -14
  160. package/dist/mesh/index.d.ts.map +1 -1
  161. package/dist/mesh/index.js +7 -19
  162. package/dist/mesh/index.js.map +1 -1
  163. package/dist/mesh/io.d.ts +2 -1
  164. package/dist/mesh/io.d.ts.map +1 -1
  165. package/dist/mesh/io.js +5 -7
  166. package/dist/mesh/io.js.map +1 -1
  167. package/dist/mesh/primitives.d.ts +5 -18
  168. package/dist/mesh/primitives.d.ts.map +1 -1
  169. package/dist/mesh/primitives.js +4 -48
  170. package/dist/mesh/primitives.js.map +1 -1
  171. package/dist/mesh/stl-loader.d.ts +23 -0
  172. package/dist/mesh/stl-loader.d.ts.map +1 -0
  173. package/dist/mesh/stl-loader.js +139 -0
  174. package/dist/mesh/stl-loader.js.map +1 -0
  175. package/dist/module-resolver/parse-imports.d.ts +37 -0
  176. package/dist/module-resolver/parse-imports.d.ts.map +1 -0
  177. package/dist/module-resolver/parse-imports.js +39 -0
  178. package/dist/module-resolver/parse-imports.js.map +1 -0
  179. package/dist/module-resolver/resolver.d.ts +1 -1
  180. package/dist/module-resolver/resolver.js +2 -2
  181. package/dist/module-resolver/resolver.js.map +1 -1
  182. package/dist/node-host/cli.d.ts.map +1 -1
  183. package/dist/node-host/cli.js +1 -22
  184. package/dist/node-host/cli.js.map +1 -1
  185. package/dist/primitives/text/cjk-font.d.ts +42 -0
  186. package/dist/primitives/text/cjk-font.d.ts.map +1 -0
  187. package/dist/primitives/text/cjk-font.js +86 -0
  188. package/dist/primitives/text/cjk-font.js.map +1 -0
  189. package/dist/sdk.d.ts +2 -2
  190. package/dist/sdk.js +2 -2
  191. package/dist/sdk.js.map +1 -1
  192. package/dist/symbol-table.d.ts +15 -0
  193. package/dist/symbol-table.d.ts.map +1 -0
  194. package/dist/symbol-table.js +14 -0
  195. package/dist/symbol-table.js.map +1 -0
  196. package/dist/topology/naming/lineage-resolve.js +1 -1
  197. package/dist/topology/naming/lineage-resolve.js.map +1 -1
  198. package/dist/vendored/brepjs/kernel/index.d.ts +5 -0
  199. package/dist/vendored/brepjs/kernel/index.d.ts.map +1 -1
  200. package/dist/vendored/brepjs/kernel/index.js +11 -0
  201. package/dist/vendored/brepjs/kernel/index.js.map +1 -1
  202. package/dist/weapp.d.ts +3 -3
  203. package/dist/weapp.d.ts.map +1 -1
  204. package/dist/weapp.js +6 -3
  205. package/dist/weapp.js.map +1 -1
  206. package/package.json +16 -14
  207. package/dist/api/compat/index.d.ts +0 -173
  208. package/dist/api/compat/index.d.ts.map +0 -1
  209. package/dist/api/compat/index.js +0 -222
  210. package/dist/api/compat/index.js.map +0 -1
  211. package/dist/api/compound.d.ts +0 -110
  212. package/dist/api/compound.d.ts.map +0 -1
  213. package/dist/api/compound.js +0 -164
  214. package/dist/api/compound.js.map +0 -1
  215. package/dist/api/copy.d.ts +0 -40
  216. package/dist/api/copy.d.ts.map +0 -1
  217. package/dist/api/copy.js +0 -83
  218. package/dist/api/copy.js.map +0 -1
  219. package/dist/api/fai_drill.d.ts +0 -46
  220. package/dist/api/fai_drill.d.ts.map +0 -1
  221. package/dist/api/fai_drill.js +0 -243
  222. package/dist/api/fai_drill.js.map +0 -1
  223. package/dist/api/fai_extrude.d.ts +0 -36
  224. package/dist/api/fai_extrude.d.ts.map +0 -1
  225. package/dist/api/fai_extrude.js +0 -79
  226. package/dist/api/fai_extrude.js.map +0 -1
  227. package/dist/api/fai_split.d.ts +0 -46
  228. package/dist/api/fai_split.d.ts.map +0 -1
  229. package/dist/api/fai_split.js +0 -254
  230. package/dist/api/fai_split.js.map +0 -1
  231. package/dist/api/load.d.ts +0 -41
  232. package/dist/api/load.d.ts.map +0 -1
  233. package/dist/api/load.js +0 -84
  234. package/dist/api/load.js.map +0 -1
  235. package/dist/api/svgExtrude.d.ts +0 -32
  236. package/dist/api/svgExtrude.d.ts.map +0 -1
  237. package/dist/api/svgExtrude.js +0 -74
  238. package/dist/api/svgExtrude.js.map +0 -1
  239. package/dist/api/text.d.ts +0 -34
  240. package/dist/api/text.d.ts.map +0 -1
  241. package/dist/api/text.js +0 -101
  242. package/dist/api/text.js.map +0 -1
  243. package/dist/brep/text/fontTestHelper.d.ts +0 -30
  244. package/dist/brep/text/fontTestHelper.d.ts.map +0 -1
  245. package/dist/brep/text/fontTestHelper.js +0 -57
  246. package/dist/brep/text/fontTestHelper.js.map +0 -1
  247. package/dist/cad-runtime/module-executor.d.ts +0 -271
  248. package/dist/cad-runtime/module-executor.d.ts.map +0 -1
  249. package/dist/cad-runtime/module-executor.js +0 -630
  250. package/dist/cad-runtime/module-executor.js.map +0 -1
  251. package/dist/cad-runtime/terminal-dag.d.ts +0 -65
  252. package/dist/cad-runtime/terminal-dag.d.ts.map +0 -1
  253. package/dist/cad-runtime/terminal-dag.js +0 -167
  254. package/dist/cad-runtime/terminal-dag.js.map +0 -1
  255. package/dist/faqts/browser.d.ts +0 -16
  256. package/dist/faqts/browser.d.ts.map +0 -1
  257. package/dist/faqts/browser.js +0 -13
  258. package/dist/faqts/browser.js.map +0 -1
  259. package/dist/faqts/exec-blob.d.ts +0 -14
  260. package/dist/faqts/exec-blob.d.ts.map +0 -1
  261. package/dist/faqts/exec-blob.js +0 -22
  262. package/dist/faqts/exec-blob.js.map +0 -1
  263. package/dist/faqts/exec-node.d.ts +0 -15
  264. package/dist/faqts/exec-node.d.ts.map +0 -1
  265. package/dist/faqts/exec-node.js +0 -29
  266. package/dist/faqts/exec-node.js.map +0 -1
  267. package/dist/faqts/imports.d.ts +0 -74
  268. package/dist/faqts/imports.d.ts.map +0 -1
  269. package/dist/faqts/imports.js +0 -95
  270. package/dist/faqts/imports.js.map +0 -1
  271. package/dist/faqts/index.d.ts +0 -22
  272. package/dist/faqts/index.d.ts.map +0 -1
  273. package/dist/faqts/index.js +0 -21
  274. package/dist/faqts/index.js.map +0 -1
  275. package/dist/faqts/node.d.ts +0 -23
  276. package/dist/faqts/node.d.ts.map +0 -1
  277. package/dist/faqts/node.js +0 -23
  278. package/dist/faqts/node.js.map +0 -1
  279. package/dist/faqts/run.d.ts +0 -62
  280. package/dist/faqts/run.d.ts.map +0 -1
  281. package/dist/faqts/run.js +0 -62
  282. package/dist/faqts/run.js.map +0 -1
  283. package/dist/faqts/transform.d.ts +0 -43
  284. package/dist/faqts/transform.d.ts.map +0 -1
  285. package/dist/faqts/transform.js +0 -35
  286. package/dist/faqts/transform.js.map +0 -1
  287. package/dist/lang/compile.d.ts +0 -50
  288. package/dist/lang/compile.d.ts.map +0 -1
  289. package/dist/lang/compile.js +0 -368
  290. package/dist/lang/compile.js.map +0 -1
  291. package/dist/lang/keep.d.ts +0 -109
  292. package/dist/lang/keep.d.ts.map +0 -1
  293. package/dist/lang/keep.js +0 -226
  294. package/dist/lang/keep.js.map +0 -1
  295. package/dist/lang/parser.d.ts +0 -91
  296. package/dist/lang/parser.d.ts.map +0 -1
  297. package/dist/lang/parser.js +0 -1594
  298. package/dist/lang/parser.js.map +0 -1
  299. package/dist/mesh/drill-hole/DrillHoleCore.d.ts +0 -90
  300. package/dist/mesh/drill-hole/DrillHoleCore.d.ts.map +0 -1
  301. package/dist/mesh/drill-hole/DrillHoleCore.js +0 -287
  302. package/dist/mesh/drill-hole/DrillHoleCore.js.map +0 -1
  303. package/dist/mesh/drill-hole/drill-types.d.ts +0 -34
  304. package/dist/mesh/drill-hole/drill-types.d.ts.map +0 -1
  305. package/dist/mesh/drill-hole/drill-types.js +0 -7
  306. package/dist/mesh/drill-hole/drill-types.js.map +0 -1
  307. package/dist/mesh/fai_drill.d.ts +0 -21
  308. package/dist/mesh/fai_drill.d.ts.map +0 -1
  309. package/dist/mesh/fai_drill.js +0 -92
  310. package/dist/mesh/fai_drill.js.map +0 -1
  311. package/dist/mesh/fai_extrude.d.ts +0 -24
  312. package/dist/mesh/fai_extrude.d.ts.map +0 -1
  313. package/dist/mesh/fai_extrude.js +0 -42
  314. package/dist/mesh/fai_extrude.js.map +0 -1
  315. package/dist/mesh/fai_split.d.ts +0 -164
  316. package/dist/mesh/fai_split.d.ts.map +0 -1
  317. package/dist/mesh/fai_split.js +0 -269
  318. package/dist/mesh/fai_split.js.map +0 -1
  319. package/dist/primitives/svg-extrude.d.ts +0 -43
  320. package/dist/primitives/svg-extrude.d.ts.map +0 -1
  321. package/dist/primitives/svg-extrude.js +0 -78
  322. package/dist/primitives/svg-extrude.js.map +0 -1
  323. package/dist/primitives/text/cjk.d.ts +0 -61
  324. package/dist/primitives/text/cjk.d.ts.map +0 -1
  325. package/dist/primitives/text/cjk.js +0 -215
  326. package/dist/primitives/text/cjk.js.map +0 -1
  327. package/dist/primitives/text-geometry.d.ts +0 -47
  328. package/dist/primitives/text-geometry.d.ts.map +0 -1
  329. package/dist/primitives/text-geometry.js +0 -127
  330. package/dist/primitives/text-geometry.js.map +0 -1
  331. package/dist/test-helpers.d.ts +0 -31
  332. package/dist/test-helpers.d.ts.map +0 -1
  333. package/dist/test-helpers.js +0 -55
  334. package/dist/test-helpers.js.map +0 -1
  335. package/dist/vendored/brepjs/core/kernelReentrancy.d.ts +0 -41
  336. package/dist/vendored/brepjs/core/kernelReentrancy.d.ts.map +0 -1
  337. package/dist/vendored/brepjs/core/kernelReentrancy.js +0 -68
  338. package/dist/vendored/brepjs/core/kernelReentrancy.js.map +0 -1
@@ -1,65 +1,279 @@
1
1
  /**
2
- * L3 bridge — occt-wasm kernel single-instance injection (D10).
2
+ * L3 bridge — vendored kernel registry injection (engine-neutral, Phase 2 P2-5).
3
3
  *
4
- * The ported `kernel/occtWasm` adapter is constructor-injected (DI form, never
5
- * imports `occt-wasm` itself). This file is the **only** faijs-side place
6
- * wiring the two together (boundary rule D8/R5: core side may import the
7
- * vendored tree only from `api/`):
4
+ * 原 occt-kernel-bridge 的职责是「把 vendored kernel registry 冻结绑定到 occt-wasm
5
+ * 单实例」(D10)。Phase 2 起改为**跟随当前 BREP 引擎**:装配期把 registry 里当前
6
+ * 引擎(occt / brepkit / mock)的 `BrepEngineApi` 适配器包装为 brepjs `KernelAdapter`
7
+ * 形态注册进 vendored registry,使 `vendoredRegistry.getKernel()` 返回当前引擎——
8
+ * vendored 函数全部逻辑(命名/角色表/Result)原样保留、零改动。
8
9
  *
9
- * initOcctWasm() ──same instance──▶ OcctWasmAdapter ──▶ registerKernel
10
- * (faijs existing (vendored, DI) (vendored kernel
11
- * occt singleton) registry, D10)
10
+ * 边界规则(D8/R5)不变:本文件是 faijs 侧唯一把 vendored kernel registry 与
11
+ * faijs 引擎接线的地方;core 侧只从 `api/` import vendored 树。
12
12
  *
13
- * `occtKernel.getKernel()` returns the faijs singleton `OcctKernel`; building
14
- * the adapter over that exact instance guarantees the single-instance ban
15
- * (D10: two wasm instances would put handles in different pointer spaces and
16
- * silently desync `hasBrep`/`brepOf`/face evolution).
17
- *
18
- * See docs/plans/2026-09-01-layered-api-architecture.md §D10 / §D8.
13
+ * 装配期完整性检查(方案 §Phase 2.5):KernelAdapter 是 211 方法大接口,但 vendored
14
+ * 面存在大量**辅助构造方法**(createVector3d / createPoint3d / createDirection3d /
15
+ * createAxis1 / createAxis2 / createAxis3,见 vendored core/kernelBoundary.ts)——
16
+ * 它们不落在能力名体系内(BrepMethodKind 之外)、无法由 op 声明覆盖,任何 compat
17
+ * op / TS compat 面都可能触发。⇒ 注入前必须断言这些胶水方法在适配器上齐备,缺失
18
+ * 则在**装配期**报错(而非执行期崩)。清单见 {@link GLUE_METHODS}。
19
19
  */
20
20
  import { getKernel as getFaijsKernel } from '../occt-kernel/occtKernel.js';
21
+ import { getBrepEngine } from '../brep/engine/registry.js';
21
22
  import { OcctWasmAdapter } from '../vendored/brepjs/kernel/occtWasm/occtWasmAdapter.js';
22
- import { freezeKernels, getActiveKernelId, getKernel as getVendoredKernel, registerKernel, syncRegistryFromGlobal, syncRegistryToGlobal, } from '../vendored/brepjs/kernel/index.js';
23
- let _bound = false;
23
+ import { freezeKernels, getActiveKernelId, getKernel as getVendoredKernel, registerKernel, syncRegistryFromGlobal, syncRegistryToGlobal, __resetKernelRegistryForTests, } from '../vendored/brepjs/kernel/index.js';
24
+ /** occt-wasm 适配器在 vendored registry 中的注册 id。这是 vendored 注册表的
25
+ * 槽位名(宿主侧判据 + D10 globalThis 单例兼容),**不是**引擎身份标识——
26
+ * 实际引擎由注入的 adapter 决定(vendored 面全部无参 `getKernel()` 取默认)。 */
27
+ export const VENDORED_OCCT_KERNEL_ID = 'occt-wasm';
24
28
  /**
25
- * Bind the ported kernel registry to the faijs single occt-wasm instance.
29
+ * 装配期完整性检查清单——vendored 面辅助构造/生命周期胶水方法。
26
30
  *
27
- * Idempotent: the first call registers the adapter and freezes the registry
28
- * (D10 冻结); subsequent calls return the already-bound adapter without
29
- * re-registering. Call after `initOcctWasm()` has been run (e.g. inside
30
- * `registerOcctBrepEngine()` host assembly).
31
+ * 这些方法不在 `BrepMethodKind` 能力名体系内(能力判定无法覆盖),但 vendored 面
32
+ * 大量使用(kernelBoundary.ts / wrapperFns / castShape 等)。当前引擎的
33
+ * KernelAdapter 包装必须全部具备,否则对应 compat op / TS compat 面会在执行期崩。
31
34
  *
32
- * @returns the registered kernel adapter.
35
+ * Phase 0 盘点实证:36 个 compat op 的 vendored 函数(capability-map 64 方法)与
36
+ * kernelBoundary 都不需要 createAxis*(2D sketcher / TS compat 面需要)——清单按
37
+ * 「vendored 面实际触发面」保守枚举,缺即装配期报错。
33
38
  */
34
- export function bindOcctKernel() {
35
- // Check the SHARED registry first (globalThis singleton): a CDN-bundled faijs
36
- // instance has its own module-level `_bound = false`, but the host bundle may
37
- // already have registered+bound 'occt-wasm'. Re-registering would throw
38
- // "registry frozen" — treat an existing binding as bound instead.
39
+ const GLUE_METHODS = [
40
+ 'createVector3d',
41
+ 'createPoint3d',
42
+ 'createDirection3d',
43
+ 'createAxis1',
44
+ 'createAxis2',
45
+ 'createAxis3',
46
+ ];
47
+ let _injected = false;
48
+ /**
49
+ * Inject the currently-registered BREP engine into the vendored kernel registry
50
+ * (replaces the old occt-only `bindOcctKernel()` fixed binding, Phase 2 P2-5).
51
+ *
52
+ * 装配期调用(在 `registerOcctBrepEngine()` / 其它引擎注册之后)。从引擎注册表取
53
+ * 当前默认 BREP 引擎,按其 id 构造 KernelAdapter 形态注册进 vendored registry:
54
+ *
55
+ * - occt:`OcctWasmAdapter.fromKernel(当前引擎 primitives)`——同一 occt-wasm 单实例
56
+ * (D10 不变),211 方法完整适配器,vendored 函数行为与旧 bindOcctKernel 完全一致;
57
+ * - 其它引擎(brepkit/mock):将 BrepEngineApi 透传包装为 KernelAdapter 形态
58
+ * (`dispose`→`release` 等方法名映射 + pattern 返回形态适配),**不做方法伪造**;
59
+ * - 任一引擎注入前都做**装配期完整性检查**(GLUE_METHODS 齐备断言)。
60
+ *
61
+ * 幂等:首次调用后注册并冻结;重复调用返回已注入的适配器。
62
+ *
63
+ * @returns 注册进 vendored registry 的 kernel adapter。
64
+ * @throws 无 BREP 引擎注册;或完整性检查失败(胶水方法缺失)——装配期报错。
65
+ */
66
+ export async function injectCurrentBrepEngineAsKernel() {
67
+ // CDN 宿主跨实例同步:host bundle 已注入则直接复用(同旧 bindOcctKernel 语义)。
68
+ // 短路判据与 isKernelInjected() 一致(含 registry 侧激活 id 分支),避免
69
+ // 「registry 已注入但模块级 _injected=false」时走完整路径撞 frozen 抛错。
39
70
  syncRegistryFromGlobal();
40
- if (_bound)
41
- return getVendoredKernel('occt-wasm');
42
- const faijsKernel = getFaijsKernel();
43
- const adapter = OcctWasmAdapter.fromKernel(faijsKernel);
44
- registerKernel('occt-wasm', adapter);
71
+ if (isKernelInjected())
72
+ return getVendoredKernel();
73
+ const engine = await getBrepEngine();
74
+ const adapter = buildKernelAdapter(engine);
75
+ assertGlueMethodsComplete(engine.id, adapter);
76
+ registerKernel(VENDORED_OCCT_KERNEL_ID, adapter);
45
77
  freezeKernels();
46
- _bound = true;
78
+ _injected = true;
47
79
  syncRegistryToGlobal();
48
80
  return adapter;
49
81
  }
50
82
  /**
51
- * Whether the vendored kernel registry has been bound (D10).
52
- * @returns true once bound to the occt-wasm kernel.
83
+ * 按引擎 id 构造 KernelAdapter 形态(occt 走完整适配器;其它引擎透传包装)。
84
+ *
85
+ * occt 分支保持旧 bindOcctKernel 行为:OcctWasmAdapter.fromKernel 需要 occt-wasm
86
+ * 实例(OcctKernelOwner)。当前引擎的 primitives 即 initOcctWasm 单例(occtApi 是
87
+ * 同一实例的实例覆盖,方法面完整),转换安全。
88
+ *
89
+ * 其它引擎分支:BrepEngineApi → KernelAdapter 契约面——
90
+ * - `dispose` → `release`(vendored 面用 dispose,BrepEngineApi 用 release);
91
+ * - `linearPattern` / `circularPattern` 的方向/中心/轴参数是 Vec3 对象(BrepEngineApi
92
+ * 口径),vendored 面传 [x,y,z] 三元组——包装为对象再转发;
93
+ * - 返回 BrepHandle[](BrepEngineApi)→ KernelShape[](vendored castResultShape 消费
94
+ * `.wrapped` + `.type`)——包装为 `{ wrapped, type: 'solid' }`;
95
+ * - `gridPattern` 返回单 BrepHandle → 单 KernelShape(compound 语义一致)。
96
+ * 不声明 `rectangularPattern`(纯 JS 组合,不调内核——capability-map 实证)。
97
+ *
98
+ * ⚠️ 不伪造:BrepEngineApi 未提供的方法**不**补桩;vendored 函数若触发,由
99
+ * compat op 的静态能力判定(backend-dispatch,Phase 1)在执行前拦截。
100
+ *
101
+ * @param engine - 当前 BREP 引擎(装配期从引擎注册表取得)。
102
+ * @returns 该引擎的 vendored KernelAdapter(occt → OcctWasmAdapter.fromKernel;
103
+ * 其它引擎 → BrepEngineApi 透传包装,pattern 族 Vec3↔三元组适配)。
104
+ */
105
+ export function buildKernelAdapter(engine) {
106
+ if (engine.id === 'occt') {
107
+ const faijsKernel = engine.primitives;
108
+ return OcctWasmAdapter.fromKernel(faijsKernel);
109
+ }
110
+ return wrapBrepEngineApi(engine.primitives);
111
+ }
112
+ /** No-op `delete` for synthesized glue objects (mirrors vendored `noop`). */
113
+ const noop = () => { };
114
+ /**
115
+ * vendored kernel methods with no source capability in BrepEngineApi.
116
+ * Registered explicitly (not silently undefined): tests assert this list and
117
+ * the engine-contract gap is a separate decision, not a wrapping bug. No
118
+ * stubs, no fake zeros — a silent 0 is worse than a crash.
53
119
  */
54
- export function isOcctKernelBound() {
55
- return _bound && getActiveKernelId() === 'occt-wasm';
120
+ export const UNMAPPED_VENDORED_MEASURE_METHODS = [
121
+ 'area',
122
+ 'length',
123
+ 'linearCenterOfMass',
124
+ ];
125
+ /** Unwrap a vendored KernelShape (handle view or bare number) to a BrepHandle. */
126
+ function unwrapHandle(h) {
127
+ if (typeof h === 'number')
128
+ return h;
129
+ const view = h;
130
+ return typeof view.id === 'number' ? view.id : h;
131
+ }
132
+ /**
133
+ * Map vendored measure method names/shapes onto BrepEngineApi capabilities.
134
+ * The vendored measure face calls `kernel.volume/area/length/centerOfMass/...`
135
+ * (its own naming); the occt adapter carries an internal mapping layer — this
136
+ * is the engine-neutral equivalent for any wrapped BrepEngineApi. Only real
137
+ * BrepEngineApi capabilities are mapped; the rest stay in the gap registry.
138
+ */
139
+ function mapMeasureMethods(adapter, api) {
140
+ adapter['volume'] = (s) => api.getVolume(unwrapHandle(s));
141
+ adapter['centerOfMass'] = (s) => {
142
+ const v = api.getCenterOfMass(unwrapHandle(s));
143
+ return [v.x, v.y, v.z];
144
+ };
145
+ adapter['boundingBox'] = (s) => {
146
+ const bb = api.getBoundingBox(unwrapHandle(s), true);
147
+ return {
148
+ min: [bb.xmin, bb.ymin, bb.zmin],
149
+ max: [bb.xmax, bb.ymax, bb.zmax],
150
+ };
151
+ };
152
+ // shapeType / isNull: same name, same semantics — already covered by the
153
+ // transparent pass-through in wrapBrepEngineApi; listed here for docs only.
154
+ // Known contract gaps (UNMAPPED_VENDORED_MEASURE_METHODS) are NOT stubbed:
155
+ // they remain undefined so tests can pin the gap explicitly.
56
156
  }
57
157
  /**
58
- * Access the currently bound vendored kernel adapter (reads the registry).
59
- * @throws If the bridge has not been bound.
60
- * @returns the vendored occt-wasm kernel adapter.
158
+ * Synthesize the vendored glue/auxiliary construction methods over any engine's
159
+ * primitives. These 6 methods are pure JS data-literal constructors in the
160
+ * vendored surface (zero kernel calls — see vendored constructionOps.ts), i.e.
161
+ * a *calling convention*, not a kernel capability — so they are synthesized at
162
+ * the faijs wrapper layer (engine-neutral) rather than added to BrepEngineApi.
163
+ * Field shapes are copied verbatim from the vendored occt adapter; `delete` is
164
+ * mandatory (kernelBoundary's with* helpers call it in `finally`).
165
+ */
166
+ function synthesizeGlueMethods(adapter) {
167
+ const pnt = (x, y, z, __type) => ({ x, y, z, __type, delete: noop });
168
+ adapter['createPoint3d'] = (x, y, z) => pnt(x, y, z, 'point3d');
169
+ adapter['createDirection3d'] = (x, y, z) => pnt(x, y, z, 'direction3d');
170
+ adapter['createVector3d'] = (x, y, z) => pnt(x, y, z, 'vector3d');
171
+ adapter['createAxis1'] = (cx, cy, cz, dx, dy, dz) => ({
172
+ origin: { x: cx, y: cy, z: cz },
173
+ direction: { x: dx, y: dy, z: dz },
174
+ __type: 'axis1',
175
+ delete: noop,
176
+ });
177
+ // axis2/axis3: 6- or 9-arg forms (origin + zDir + optional xDir).
178
+ const makeAxis = (__type) => (ox, oy, oz, zx, zy, zz, xx, xy, xz) => ({
179
+ origin: { x: ox, y: oy, z: oz },
180
+ zDir: { x: zx, y: zy, z: zz },
181
+ xDir: xx !== undefined ? { x: xx, y: xy, z: xz } : undefined,
182
+ __type,
183
+ delete: noop,
184
+ });
185
+ adapter['createAxis2'] = makeAxis('axis2');
186
+ adapter['createAxis3'] = makeAxis('axis3');
187
+ }
188
+ /** 把 BrepEngineApi 透传包装为 KernelAdapter 形态(非 occt 引擎)。 */
189
+ function wrapBrepEngineApi(api) {
190
+ const adapter = {
191
+ // 生命周期:vendored 面统一用 dispose(BrepEngineApi 用 release)。
192
+ dispose: (h) => api.release(h),
193
+ };
194
+ synthesizeGlueMethods(adapter);
195
+ for (const key of Object.keys(api)) {
196
+ if (key === 'release')
197
+ continue; // 上面已映射为 dispose
198
+ adapter[key] = api[key];
199
+ }
200
+ // 测量面映射在透传之后追加,覆盖同名键(vendored 名 → BrepEngineApi 名 + 形态转换)。
201
+ mapMeasureMethods(adapter, api);
202
+ // pattern 族形态适配(BrepEngineApi 对象 Vec3 ↔ vendored 三元组)。
203
+ adapter['linearPattern'] = (shape, direction, spacing, count) => api.linearPattern(shape, { x: direction[0], y: direction[1], z: direction[2] }, spacing, count).map((h) => ({ wrapped: h, type: 'solid' }));
204
+ adapter['circularPattern'] = (shape, center, axis, angleStep, count) => api.circularPattern(shape, { x: center[0], y: center[1], z: center[2] }, { x: axis[0], y: axis[1], z: axis[2] }, angleStep, count).map((h) => ({ wrapped: h, type: 'solid' }));
205
+ adapter['gridPattern'] = (shape, directionX, directionY, spacingX, spacingY, countX, countY) => ({
206
+ wrapped: api.gridPattern(shape, { x: directionX[0], y: directionX[1], z: directionX[2] }, { x: directionY[0], y: directionY[1], z: directionY[2] }, spacingX, spacingY, countX, countY),
207
+ type: 'compound',
208
+ });
209
+ return adapter;
210
+ }
211
+ /**
212
+ * 装配期完整性检查:KernelAdapter 胶水方法齐备断言。
213
+ *
214
+ * @param id - 引擎注册 id(报错时定位到引擎)。
215
+ * @param adapter - 待注入 vendored registry 的 KernelAdapter。
216
+ * @throws 缺失任一胶水方法 → 装配期报错(列出引擎 id 与缺失方法名)。
217
+ */
218
+ export function assertGlueMethodsComplete(id, adapter) {
219
+ const missing = GLUE_METHODS.filter((m) => typeof adapter[m] !== 'function');
220
+ if (missing.length > 0) {
221
+ throw new Error(`[faijs] BREP engine '${id}' cannot back the vendored compat surface: KernelAdapter ` +
222
+ `missing glue method(s): ${missing.join(', ')}. These auxiliary construction methods ` +
223
+ `(createVector3d / createPoint3d / createDirection3d / createAxis1/2/3) are required by ` +
224
+ `the vendored kernel boundary and cannot be covered by capability declarations. ` +
225
+ `Fix the adapter (add real implementations) or do not inject this engine into the vendored registry.`);
226
+ }
227
+ }
228
+ /**
229
+ * Test-only: clear the injection cache and reset the vendored kernel registry
230
+ * so a re-assembly (e.g. switching engines in tests) re-runs buildKernelAdapter
231
+ * + assertGlueMethodsComplete for the new engine. Never called in prod.
232
+ */
233
+ export function __resetKernelInjectionForTests() {
234
+ _injected = false;
235
+ __resetKernelRegistryForTests();
236
+ }
237
+ /**
238
+ * Whether the vendored kernel registry has been injected (engine-neutral D10).
239
+ *
240
+ * 取代旧的 `isOcctKernelBound()`(其判据 `_bound && getActiveKernelId() === 'occt-wasm'`
241
+ * 把注入面写死为 occt)。新判据只问「vendored registry 是否已注入当前引擎」——
242
+ * 不关心引擎 id,装配期换引擎(brepkit/mock)同样成立。
243
+ *
244
+ * @returns 注入是否已完成(vendored registry 已装配当前 BREP 引擎)。
245
+ */
246
+ export function isKernelInjected() {
247
+ syncRegistryFromGlobal();
248
+ return _injected || getActiveKernelId() !== null;
249
+ }
250
+ /**
251
+ * Access the currently injected vendored kernel adapter (reads the registry).
252
+ * @throws If the bridge has not been injected.
253
+ * @returns the vendored kernel adapter for the current BREP engine.
61
254
  */
62
255
  export function getBrepjsKernel() {
63
- return getVendoredKernel('occt-wasm');
256
+ return getVendoredKernel();
257
+ }
258
+ /**
259
+ * 固定绑定 occt 内核到 vendored registry(Phase 2 前的装配方式)。
260
+ *
261
+ * @deprecated Phase 2 P2-5:固定绑定已被引擎中立的 injectCurrentBrepEngineAsKernel
262
+ * 取代。保留导出仅为兼容旧调用点(适配器层迁移期);新代码一律用注入函数。
263
+ * @returns 恒抛错——本函数已移除,仅保留签名占位。
264
+ */
265
+ export function bindOcctKernel() {
266
+ void getFaijsKernel;
267
+ throw new Error('[faijs] bindOcctKernel() removed (Phase 2 P2-5): use injectCurrentBrepEngineAsKernel() ' +
268
+ 'during host assembly to inject the current BREP engine into the vendored registry.');
269
+ }
270
+ /**
271
+ * 旧 occt 专用注入判据(Phase 2 前语义:绑定且激活内核为 occt-wasm)。
272
+ *
273
+ * @deprecated Phase 2 P2-5:occt 专用判据已被引擎中立的 isKernelInjected() 取代。
274
+ * @returns 当前是否已注入(透传 isKernelInjected())。
275
+ */
276
+ export function isOcctKernelBound() {
277
+ return isKernelInjected();
64
278
  }
65
279
  //# sourceMappingURL=occt-kernel-bridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"occt-kernel-bridge.js","sourceRoot":"","sources":["../../src/api/occt-kernel-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AACvF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,SAAS,IAAI,iBAAiB,EAC9B,cAAc,EACd,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,oCAAoC,CAAA;AAG3C,IAAI,MAAM,GAAG,KAAK,CAAA;AAElB;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc;IAC5B,8EAA8E;IAC9E,8EAA8E;IAC9E,wEAAwE;IACxE,kEAAkE;IAClE,sBAAsB,EAAE,CAAC;IACzB,IAAI,MAAM;QAAE,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAA;IAEjD,MAAM,WAAW,GAAG,cAAc,EAAgC,CAAA;IAClE,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IACvD,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IACpC,aAAa,EAAE,CAAA;IACf,MAAM,GAAG,IAAI,CAAA;IACb,oBAAoB,EAAE,CAAA;IACtB,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,MAAM,IAAI,iBAAiB,EAAE,KAAK,WAAW,CAAA;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAA;AACvC,CAAC","sourcesContent":["/**\n * L3 bridge — occt-wasm kernel single-instance injection (D10).\n *\n * The ported `kernel/occtWasm` adapter is constructor-injected (DI form, never\n * imports `occt-wasm` itself). This file is the **only** faijs-side place\n * wiring the two together (boundary rule D8/R5: core side may import the\n * vendored tree only from `api/`):\n *\n * initOcctWasm() ──same instance──▶ OcctWasmAdapter ──▶ registerKernel\n * (faijs existing (vendored, DI) (vendored kernel\n * occt singleton) registry, D10)\n *\n * `occtKernel.getKernel()` returns the faijs singleton `OcctKernel`; building\n * the adapter over that exact instance guarantees the single-instance ban\n * (D10: two wasm instances would put handles in different pointer spaces and\n * silently desync `hasBrep`/`brepOf`/face evolution).\n *\n * See docs/plans/2026-09-01-layered-api-architecture.md §D10 / §D8.\n */\n\nimport { getKernel as getFaijsKernel } from '../occt-kernel/occtKernel'\nimport type { OcctKernelOwner } from '../vendored/brepjs/kernel/occtWasm/occtWasmAdapter.js'\nimport { OcctWasmAdapter } from '../vendored/brepjs/kernel/occtWasm/occtWasmAdapter.js'\nimport {\n freezeKernels,\n getActiveKernelId,\n getKernel as getVendoredKernel,\n registerKernel,\n syncRegistryFromGlobal,\n syncRegistryToGlobal,\n} from '../vendored/brepjs/kernel/index.js'\nimport type { KernelAdapter } from '../vendored/brepjs/kernel/types.js'\n\nlet _bound = false\n\n/**\n * Bind the ported kernel registry to the faijs single occt-wasm instance.\n *\n * Idempotent: the first call registers the adapter and freezes the registry\n * (D10 冻结); subsequent calls return the already-bound adapter without\n * re-registering. Call after `initOcctWasm()` has been run (e.g. inside\n * `registerOcctBrepEngine()` host assembly).\n *\n * @returns the registered kernel adapter.\n */\nexport function bindOcctKernel(): KernelAdapter {\n // Check the SHARED registry first (globalThis singleton): a CDN-bundled faijs\n // instance has its own module-level `_bound = false`, but the host bundle may\n // already have registered+bound 'occt-wasm'. Re-registering would throw\n // \"registry frozen\" — treat an existing binding as bound instead.\n syncRegistryFromGlobal();\n if (_bound) return getVendoredKernel('occt-wasm')\n\n const faijsKernel = getFaijsKernel() as unknown as OcctKernelOwner\n const adapter = OcctWasmAdapter.fromKernel(faijsKernel)\n registerKernel('occt-wasm', adapter)\n freezeKernels()\n _bound = true\n syncRegistryToGlobal()\n return adapter\n}\n\n/**\n * Whether the vendored kernel registry has been bound (D10).\n * @returns true once bound to the occt-wasm kernel.\n */\nexport function isOcctKernelBound(): boolean {\n return _bound && getActiveKernelId() === 'occt-wasm'\n}\n\n/**\n * Access the currently bound vendored kernel adapter (reads the registry).\n * @throws If the bridge has not been bound.\n * @returns the vendored occt-wasm kernel adapter.\n */\nexport function getBrepjsKernel(): KernelAdapter {\n return getVendoredKernel('occt-wasm')\n}"]}
1
+ {"version":3,"file":"occt-kernel-bridge.js","sourceRoot":"","sources":["../../src/api/occt-kernel-bridge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * L3 bridge — vendored kernel registry injection (engine-neutral, Phase 2 P2-5).\n *\n * 原 occt-kernel-bridge 的职责是「把 vendored kernel registry 冻结绑定到 occt-wasm\n * 单实例」(D10)。Phase 2 起改为**跟随当前 BREP 引擎**:装配期把 registry 里当前\n * 引擎(occt / brepkit / mock)的 `BrepEngineApi` 适配器包装为 brepjs `KernelAdapter`\n * 形态注册进 vendored registry,使 `vendoredRegistry.getKernel()` 返回当前引擎——\n * vendored 函数全部逻辑(命名/角色表/Result)原样保留、零改动。\n *\n * 边界规则(D8/R5)不变:本文件是 faijs 侧唯一把 vendored kernel registry 与\n * faijs 引擎接线的地方;core 侧只从 `api/` import vendored 树。\n *\n * 装配期完整性检查(方案 §Phase 2.5):KernelAdapter 是 211 方法大接口,但 vendored\n * 面存在大量**辅助构造方法**(createVector3d / createPoint3d / createDirection3d /\n * createAxis1 / createAxis2 / createAxis3,见 vendored core/kernelBoundary.ts)——\n * 它们不落在能力名体系内(BrepMethodKind 之外)、无法由 op 声明覆盖,任何 compat\n * op / TS compat 面都可能触发。⇒ 注入前必须断言这些胶水方法在适配器上齐备,缺失\n * 则在**装配期**报错(而非执行期崩)。清单见 {@link GLUE_METHODS}。\n */\n\nimport { getKernel as getFaijsKernel } from '../occt-kernel/occtKernel'\nimport type { OcctKernelOwner } from '../vendored/brepjs/kernel/occtWasm/occtWasmAdapter.js'\nimport { getBrepEngine, type BrepEngine } from '../brep/engine/registry'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { OcctWasmAdapter } from '../vendored/brepjs/kernel/occtWasm/occtWasmAdapter.js'\nimport {\n freezeKernels,\n getActiveKernelId,\n getKernel as getVendoredKernel,\n registerKernel,\n syncRegistryFromGlobal,\n syncRegistryToGlobal,\n __resetKernelRegistryForTests,\n} from '../vendored/brepjs/kernel/index.js'\nimport type { KernelAdapter } from '../vendored/brepjs/kernel/types.js'\n\n/** occt-wasm 适配器在 vendored registry 中的注册 id。这是 vendored 注册表的\n * 槽位名(宿主侧判据 + D10 globalThis 单例兼容),**不是**引擎身份标识——\n * 实际引擎由注入的 adapter 决定(vendored 面全部无参 `getKernel()` 取默认)。 */\nexport const VENDORED_OCCT_KERNEL_ID = 'occt-wasm'\n\n/**\n * 装配期完整性检查清单——vendored 面辅助构造/生命周期胶水方法。\n *\n * 这些方法不在 `BrepMethodKind` 能力名体系内(能力判定无法覆盖),但 vendored 面\n * 大量使用(kernelBoundary.ts / wrapperFns / castShape 等)。当前引擎的\n * KernelAdapter 包装必须全部具备,否则对应 compat op / TS compat 面会在执行期崩。\n *\n * Phase 0 盘点实证:36 个 compat op 的 vendored 函数(capability-map 64 方法)与\n * kernelBoundary 都不需要 createAxis*(2D sketcher / TS compat 面需要)——清单按\n * 「vendored 面实际触发面」保守枚举,缺即装配期报错。\n */\nconst GLUE_METHODS = [\n 'createVector3d',\n 'createPoint3d',\n 'createDirection3d',\n 'createAxis1',\n 'createAxis2',\n 'createAxis3',\n] as const\n\nlet _injected = false\n\n/**\n * Inject the currently-registered BREP engine into the vendored kernel registry\n * (replaces the old occt-only `bindOcctKernel()` fixed binding, Phase 2 P2-5).\n *\n * 装配期调用(在 `registerOcctBrepEngine()` / 其它引擎注册之后)。从引擎注册表取\n * 当前默认 BREP 引擎,按其 id 构造 KernelAdapter 形态注册进 vendored registry:\n *\n * - occt:`OcctWasmAdapter.fromKernel(当前引擎 primitives)`——同一 occt-wasm 单实例\n * (D10 不变),211 方法完整适配器,vendored 函数行为与旧 bindOcctKernel 完全一致;\n * - 其它引擎(brepkit/mock):将 BrepEngineApi 透传包装为 KernelAdapter 形态\n * (`dispose`→`release` 等方法名映射 + pattern 返回形态适配),**不做方法伪造**;\n * - 任一引擎注入前都做**装配期完整性检查**(GLUE_METHODS 齐备断言)。\n *\n * 幂等:首次调用后注册并冻结;重复调用返回已注入的适配器。\n *\n * @returns 注册进 vendored registry 的 kernel adapter。\n * @throws 无 BREP 引擎注册;或完整性检查失败(胶水方法缺失)——装配期报错。\n */\nexport async function injectCurrentBrepEngineAsKernel(): Promise<KernelAdapter> {\n // CDN 宿主跨实例同步:host bundle 已注入则直接复用(同旧 bindOcctKernel 语义)。\n // 短路判据与 isKernelInjected() 一致(含 registry 侧激活 id 分支),避免\n // 「registry 已注入但模块级 _injected=false」时走完整路径撞 frozen 抛错。\n syncRegistryFromGlobal()\n if (isKernelInjected()) return getVendoredKernel()\n\n const engine = await getBrepEngine()\n const adapter = buildKernelAdapter(engine)\n assertGlueMethodsComplete(engine.id, adapter)\n\n registerKernel(VENDORED_OCCT_KERNEL_ID, adapter)\n freezeKernels()\n _injected = true\n syncRegistryToGlobal()\n return adapter\n}\n\n/**\n * 按引擎 id 构造 KernelAdapter 形态(occt 走完整适配器;其它引擎透传包装)。\n *\n * occt 分支保持旧 bindOcctKernel 行为:OcctWasmAdapter.fromKernel 需要 occt-wasm\n * 实例(OcctKernelOwner)。当前引擎的 primitives 即 initOcctWasm 单例(occtApi 是\n * 同一实例的实例覆盖,方法面完整),转换安全。\n *\n * 其它引擎分支:BrepEngineApi → KernelAdapter 契约面——\n * - `dispose` → `release`(vendored 面用 dispose,BrepEngineApi 用 release);\n * - `linearPattern` / `circularPattern` 的方向/中心/轴参数是 Vec3 对象(BrepEngineApi\n * 口径),vendored 面传 [x,y,z] 三元组——包装为对象再转发;\n * - 返回 BrepHandle[](BrepEngineApi)→ KernelShape[](vendored castResultShape 消费\n * `.wrapped` + `.type`)——包装为 `{ wrapped, type: 'solid' }`;\n * - `gridPattern` 返回单 BrepHandle → 单 KernelShape(compound 语义一致)。\n * 不声明 `rectangularPattern`(纯 JS 组合,不调内核——capability-map 实证)。\n *\n * ⚠️ 不伪造:BrepEngineApi 未提供的方法**不**补桩;vendored 函数若触发,由\n * compat op 的静态能力判定(backend-dispatch,Phase 1)在执行前拦截。\n *\n * @param engine - 当前 BREP 引擎(装配期从引擎注册表取得)。\n * @returns 该引擎的 vendored KernelAdapter(occt → OcctWasmAdapter.fromKernel;\n * 其它引擎 → BrepEngineApi 透传包装,pattern 族 Vec3↔三元组适配)。\n */\nexport function buildKernelAdapter(engine: BrepEngine): KernelAdapter {\n if (engine.id === 'occt') {\n const faijsKernel = engine.primitives as unknown as OcctKernelOwner\n return OcctWasmAdapter.fromKernel(faijsKernel)\n }\n return wrapBrepEngineApi(engine.primitives)\n}\n\n/** No-op `delete` for synthesized glue objects (mirrors vendored `noop`). */\nconst noop = (): void => {}\n\n/**\n * vendored kernel methods with no source capability in BrepEngineApi.\n * Registered explicitly (not silently undefined): tests assert this list and\n * the engine-contract gap is a separate decision, not a wrapping bug. No\n * stubs, no fake zeros — a silent 0 is worse than a crash.\n */\nexport const UNMAPPED_VENDORED_MEASURE_METHODS = [\n 'area',\n 'length',\n 'linearCenterOfMass',\n] as const\n\n/** Unwrap a vendored KernelShape (handle view or bare number) to a BrepHandle. */\nfunction unwrapHandle(h: unknown): unknown {\n if (typeof h === 'number') return h\n const view = h as { id?: unknown }\n return typeof view.id === 'number' ? view.id : h\n}\n\n/**\n * Map vendored measure method names/shapes onto BrepEngineApi capabilities.\n * The vendored measure face calls `kernel.volume/area/length/centerOfMass/...`\n * (its own naming); the occt adapter carries an internal mapping layer — this\n * is the engine-neutral equivalent for any wrapped BrepEngineApi. Only real\n * BrepEngineApi capabilities are mapped; the rest stay in the gap registry.\n */\nfunction mapMeasureMethods(adapter: Record<string, unknown>, api: BrepEngineApi): void {\n adapter['volume'] = (s: unknown) => api.getVolume(unwrapHandle(s) as never)\n adapter['centerOfMass'] = (s: unknown): [number, number, number] => {\n const v = api.getCenterOfMass(unwrapHandle(s) as never)\n return [v.x, v.y, v.z]\n }\n adapter['boundingBox'] = (s: unknown) => {\n const bb = api.getBoundingBox(unwrapHandle(s) as never, true)\n return {\n min: [bb.xmin, bb.ymin, bb.zmin],\n max: [bb.xmax, bb.ymax, bb.zmax],\n }\n }\n // shapeType / isNull: same name, same semantics — already covered by the\n // transparent pass-through in wrapBrepEngineApi; listed here for docs only.\n // Known contract gaps (UNMAPPED_VENDORED_MEASURE_METHODS) are NOT stubbed:\n // they remain undefined so tests can pin the gap explicitly.\n}\n\n/**\n * Synthesize the vendored glue/auxiliary construction methods over any engine's\n * primitives. These 6 methods are pure JS data-literal constructors in the\n * vendored surface (zero kernel calls — see vendored constructionOps.ts), i.e.\n * a *calling convention*, not a kernel capability — so they are synthesized at\n * the faijs wrapper layer (engine-neutral) rather than added to BrepEngineApi.\n * Field shapes are copied verbatim from the vendored occt adapter; `delete` is\n * mandatory (kernelBoundary's with* helpers call it in `finally`).\n */\nfunction synthesizeGlueMethods(adapter: Record<string, unknown>): void {\n const pnt = (x: number, y: number, z: number, __type: string) => ({ x, y, z, __type, delete: noop })\n adapter['createPoint3d'] = (x: number, y: number, z: number) => pnt(x, y, z, 'point3d')\n adapter['createDirection3d'] = (x: number, y: number, z: number) => pnt(x, y, z, 'direction3d')\n adapter['createVector3d'] = (x: number, y: number, z: number) => pnt(x, y, z, 'vector3d')\n adapter['createAxis1'] = (cx: number, cy: number, cz: number, dx: number, dy: number, dz: number) => ({\n origin: { x: cx, y: cy, z: cz },\n direction: { x: dx, y: dy, z: dz },\n __type: 'axis1',\n delete: noop,\n })\n // axis2/axis3: 6- or 9-arg forms (origin + zDir + optional xDir).\n const makeAxis = (__type: 'axis2' | 'axis3') =>\n (ox: number, oy: number, oz: number, zx: number, zy: number, zz: number, xx?: number, xy?: number, xz?: number) => ({\n origin: { x: ox, y: oy, z: oz },\n zDir: { x: zx, y: zy, z: zz },\n xDir: xx !== undefined ? { x: xx, y: xy as number, z: xz as number } : undefined,\n __type,\n delete: noop,\n })\n adapter['createAxis2'] = makeAxis('axis2')\n adapter['createAxis3'] = makeAxis('axis3')\n}\n\n/** 把 BrepEngineApi 透传包装为 KernelAdapter 形态(非 occt 引擎)。 */\nfunction wrapBrepEngineApi(api: BrepEngineApi): KernelAdapter {\n const adapter: Record<string, unknown> = {\n // 生命周期:vendored 面统一用 dispose(BrepEngineApi 用 release)。\n dispose: (h: unknown) => api.release(h as never),\n }\n synthesizeGlueMethods(adapter)\n for (const key of Object.keys(api)) {\n if (key === 'release') continue // 上面已映射为 dispose\n adapter[key] = (api as unknown as Record<string, unknown>)[key]\n }\n // 测量面映射在透传之后追加,覆盖同名键(vendored 名 → BrepEngineApi 名 + 形态转换)。\n mapMeasureMethods(adapter, api)\n // pattern 族形态适配(BrepEngineApi 对象 Vec3 ↔ vendored 三元组)。\n adapter['linearPattern'] = (\n shape: unknown,\n direction: [number, number, number],\n spacing: number,\n count: number,\n ) =>\n api.linearPattern(\n shape as never,\n { x: direction[0], y: direction[1], z: direction[2] },\n spacing,\n count,\n ).map((h) => ({ wrapped: h, type: 'solid' }))\n adapter['circularPattern'] = (\n shape: unknown,\n center: [number, number, number],\n axis: [number, number, number],\n angleStep: number,\n count: number,\n ) =>\n api.circularPattern(\n shape as never,\n { x: center[0], y: center[1], z: center[2] },\n { x: axis[0], y: axis[1], z: axis[2] },\n angleStep,\n count,\n ).map((h) => ({ wrapped: h, type: 'solid' }))\n adapter['gridPattern'] = (\n shape: unknown,\n directionX: [number, number, number],\n directionY: [number, number, number],\n spacingX: number,\n spacingY: number,\n countX: number,\n countY: number,\n ) => ({\n wrapped: api.gridPattern(\n shape as never,\n { x: directionX[0], y: directionX[1], z: directionX[2] },\n { x: directionY[0], y: directionY[1], z: directionY[2] },\n spacingX,\n spacingY,\n countX,\n countY,\n ),\n type: 'compound',\n })\n return adapter as unknown as KernelAdapter\n}\n\n/**\n * 装配期完整性检查:KernelAdapter 胶水方法齐备断言。\n *\n * @param id - 引擎注册 id(报错时定位到引擎)。\n * @param adapter - 待注入 vendored registry 的 KernelAdapter。\n * @throws 缺失任一胶水方法 → 装配期报错(列出引擎 id 与缺失方法名)。\n */\nexport function assertGlueMethodsComplete(id: string, adapter: KernelAdapter): void {\n const missing = GLUE_METHODS.filter((m) => typeof (adapter as unknown as Record<string, unknown>)[m] !== 'function')\n if (missing.length > 0) {\n throw new Error(\n `[faijs] BREP engine '${id}' cannot back the vendored compat surface: KernelAdapter ` +\n `missing glue method(s): ${missing.join(', ')}. These auxiliary construction methods ` +\n `(createVector3d / createPoint3d / createDirection3d / createAxis1/2/3) are required by ` +\n `the vendored kernel boundary and cannot be covered by capability declarations. ` +\n `Fix the adapter (add real implementations) or do not inject this engine into the vendored registry.`\n )\n }\n}\n\n/**\n * Test-only: clear the injection cache and reset the vendored kernel registry\n * so a re-assembly (e.g. switching engines in tests) re-runs buildKernelAdapter\n * + assertGlueMethodsComplete for the new engine. Never called in prod.\n */\nexport function __resetKernelInjectionForTests(): void {\n _injected = false\n __resetKernelRegistryForTests()\n}\n\n/**\n * Whether the vendored kernel registry has been injected (engine-neutral D10).\n *\n * 取代旧的 `isOcctKernelBound()`(其判据 `_bound && getActiveKernelId() === 'occt-wasm'`\n * 把注入面写死为 occt)。新判据只问「vendored registry 是否已注入当前引擎」——\n * 不关心引擎 id,装配期换引擎(brepkit/mock)同样成立。\n *\n * @returns 注入是否已完成(vendored registry 已装配当前 BREP 引擎)。\n */\nexport function isKernelInjected(): boolean {\n syncRegistryFromGlobal()\n return _injected || getActiveKernelId() !== null\n}\n\n/**\n * Access the currently injected vendored kernel adapter (reads the registry).\n * @throws If the bridge has not been injected.\n * @returns the vendored kernel adapter for the current BREP engine.\n */\nexport function getBrepjsKernel(): KernelAdapter {\n return getVendoredKernel()\n}\n\n/**\n * 固定绑定 occt 内核到 vendored registry(Phase 2 前的装配方式)。\n *\n * @deprecated Phase 2 P2-5:固定绑定已被引擎中立的 injectCurrentBrepEngineAsKernel\n * 取代。保留导出仅为兼容旧调用点(适配器层迁移期);新代码一律用注入函数。\n * @returns 恒抛错——本函数已移除,仅保留签名占位。\n */\nexport function bindOcctKernel(): KernelAdapter {\n void getFaijsKernel\n throw new Error(\n '[faijs] bindOcctKernel() removed (Phase 2 P2-5): use injectCurrentBrepEngineAsKernel() ' +\n 'during host assembly to inject the current BREP engine into the vendored registry.'\n )\n}\n\n/**\n * 旧 occt 专用注入判据(Phase 2 前语义:绑定且激活内核为 occt-wasm)。\n *\n * @deprecated Phase 2 P2-5:occt 专用判据已被引擎中立的 isKernelInjected() 取代。\n * @returns 当前是否已注入(透传 isKernelInjected())。\n */\nexport function isOcctKernelBound(): boolean {\n return isKernelInjected()\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/api/pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAgGhD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa;;CAKxB,CAAA"}
1
+ {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/api/pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAqDhD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa;;CAUxB,CAAA"}
@@ -9,10 +9,10 @@
9
9
  * 倍数即得 k;再按「面内坐标」(centroid − t·dir)匹配输入面对应面,回投其 inner role。
10
10
  */
11
11
  import { solidToShape } from '../brep/brep-ops.js';
12
- import { getFaceHashes } from '../brep/face-evolution.js';
13
- import { getBackends, getCurrentStmt } from '../runtime-state.js';
14
- import { fromBrep, brepOf, inputRoleTable } from '../shape.js';
12
+ import { getBackends, getCurrentStmt, keep } from '../runtime-state.js';
13
+ import { fromBrep, brepOf } from '../shape.js';
15
14
  import { defineOp } from '../sdk.js';
15
+ import { buildReplicaRoleTable } from './internal/replica-role-table.js';
16
16
  /** 归一化向量(零向量 → [0,0,1] 兜底)。 */
17
17
  function norm(v) {
18
18
  const len = Math.hypot(v[0], v[1], v[2]);
@@ -30,69 +30,28 @@ function linearPatternBrep(input, direction, count, spacing) {
30
30
  throw new Error('[stdlib/pattern] input is not BREP');
31
31
  // Phase 1.6:origin = 本次语句 StmtId。
32
32
  const outStmt = String(getCurrentStmt()?.id ?? '');
33
- const inputTable = inputRoleTable(input);
34
- // 输入面角色(hash → role)用于回投 inner
35
- const inputHashes = getFaceHashes(kernel, inputSolid);
36
- const inputHashToRole = new Map();
37
- if (inputTable) {
38
- for (const roles of inputTable.values()) {
39
- for (const [role, hashes] of roles)
40
- for (const h of hashes)
41
- inputHashToRole.set(h, role);
42
- }
43
- }
44
- // 输入面质心(用于按面内坐标回投 inner role)
45
- const inputFaces = kernel.getSubShapes(inputSolid, 'face');
46
- const inputCentroids = inputFaces.map((f) => kernel.getSurfaceCenterOfMass(f));
47
- // 取 count 份副本(内核原生 linearPattern:brepkit 返回 BrepHandle[],occt-wasm
48
- // 返回已 fused 的 BrepHandle —— 两种形态都按结果面质心聚类,故兼容)
33
+ // 取 count 份副本。Phase 2:BrepEngineApi.linearPattern 契约统一返回 BrepHandle[]
34
+ // (两内核原生都返回 compound,由适配器拆成数组)——不再有「单句柄 fused」形态。
49
35
  const dir = norm(direction);
50
- const raw = kernel.linearPattern(inputSolid, [dir[0], dir[1], dir[2]], spacing, count);
36
+ const raw = kernel.linearPattern(inputSolid, { x: dir[0], y: dir[1], z: dir[2] }, spacing, count);
51
37
  let resultSolid;
52
- if (Array.isArray(raw)) {
53
- try {
54
- resultSolid = kernel.fuseAll(raw);
55
- }
56
- finally {
57
- for (const c of raw)
58
- kernel.release(c);
59
- }
38
+ try {
39
+ resultSolid = kernel.fuseAll(raw);
60
40
  }
61
- else {
62
- resultSolid = raw;
41
+ finally {
42
+ for (const c of raw)
43
+ kernel.release(c);
63
44
  }
64
- // 结果面 hash / 质心
65
- const resultHashes = getFaceHashes(kernel, resultSolid);
66
- const resultFaces = kernel.getSubShapes(resultSolid, 'face');
67
- const resultCentroids = resultFaces.map((f) => kernel.getSurfaceCenterOfMass(f));
68
- const roleTable = new Map();
69
- const inner = new Map();
70
- for (let i = 0; i < resultHashes.length; i++) {
71
- const c = resultCentroids[i];
72
- // 沿 dir 投影得到份数坐标 t,四舍五入到 spacing 倍数 → k
73
- const t = c.x * dir[0] + c.y * dir[1] + c.z * dir[2];
74
- const k = Math.round(t / spacing);
75
- // 面内坐标 = centroid − t·dir
76
- const inPlane = [c.x - t * dir[0], c.y - t * dir[1], c.z - t * dir[2]];
77
- // 匹配输入面(最近面内坐标)→ inner role
78
- let bestRole;
79
- let bestDist = Infinity;
80
- for (let j = 0; j < inputCentroids.length; j++) {
81
- const ic = inputCentroids[j];
82
- const it = ic.x * dir[0] + ic.y * dir[1] + ic.z * dir[2];
83
- const ii = [ic.x - it * dir[0], ic.y - it * dir[1], ic.z - it * dir[2]];
84
- const d = (inPlane[0] - ii[0]) ** 2 + (inPlane[1] - ii[1]) ** 2 + (inPlane[2] - ii[2]) ** 2;
85
- if (d < bestDist) {
86
- bestDist = d;
87
- bestRole = inputHashToRole.get(inputHashes[j]);
88
- }
89
- }
90
- const role = `replica[${k}]/${bestRole ?? 'face'}`;
91
- if (!inner.has(role))
92
- inner.set(role, []);
93
- inner.get(role).push(resultHashes[i]);
45
+ // 第 k 份副本是输入沿 dir 平移 k*spacing:质心反投回输入坐标系(T_k⁻¹)。
46
+ const replicas = [];
47
+ for (let k = 0; k < count; k++) {
48
+ const off = k * spacing;
49
+ replicas.push({
50
+ label: `replica[${k}]`,
51
+ inverse: (c) => ({ x: c.x - off * dir[0], y: c.y - off * dir[1], z: c.z - off * dir[2] }),
52
+ });
94
53
  }
95
- roleTable.set(outStmt, inner);
54
+ const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt);
96
55
  return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable });
97
56
  }
98
57
  /**
@@ -114,8 +73,13 @@ function linearPatternBrep(input, direction, count, spacing) {
114
73
  */
115
74
  export const linearPattern = defineOp({
116
75
  brep(input, direction, count, spacing) {
76
+ // copy-like keep semantics: replicate ops preserve their source shape.
77
+ keep(input);
117
78
  return linearPatternBrep(input, direction, count, spacing);
118
79
  },
80
+ // Phase 1(Brep 引擎可切换重构):能力前置判定——linearPattern 需要内核的
81
+ // 线性阵列方法(BrepMethodKind),brepkit 装配下缺失时执行前静态报错。
82
+ capabilities: ['linearPattern'],
119
83
  naming: { kind: 'replicate', k: 0 },
120
84
  });
121
85
  //# sourceMappingURL=pattern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/api/pattern.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib pattern — linearPattern(手写覆盖生成投影,Phase 3: L3 `replica[k]` 角色表)\n *\n * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径\n * 用质心聚类把结果面按份数 k 分组、回投影到输入面角色,产出 `replica[k]/<inner>`。\n *\n * 机制(无内核历史,纯几何推理):pattern 的每份副本都是输入的精确平移,副本面\n * 几何相同但质心不同。结果面沿 pattern 方向投影得到份数坐标 t,四舍五入到 spacing\n * 倍数即得 k;再按「面内坐标」(centroid − t·dir)匹配输入面对应面,回投其 inner role。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getFaceHashes } from '../brep/face-evolution'\nimport { getBackends, getCurrentStmt } from '../runtime-state'\nimport { fromBrep, brepOf, inputRoleTable } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { RoleTable } from '../topology/naming/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\n\n/** 归一化向量(零向量 → [0,0,1] 兜底)。 */\nfunction norm(v: Vec3): [number, number, number] {\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\n/** BREP 路径:沿 direction 复制 count 份,质心聚类回投输入面角色。 */\nfunction linearPatternBrep(input: Shape, direction: Vec3, count: number, spacing: number): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/pattern] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/pattern] input is not BREP')\n\n // Phase 1.6:origin = 本次语句 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n const inputTable = inputRoleTable(input) as RoleTable | undefined\n\n // 输入面角色(hash → role)用于回投 inner\n const inputHashes = getFaceHashes(kernel, inputSolid)\n const inputHashToRole = new Map<number, string>()\n if (inputTable) {\n for (const roles of inputTable.values()) {\n for (const [role, hashes] of roles) for (const h of hashes) inputHashToRole.set(h, role)\n }\n }\n // 输入面质心(用于按面内坐标回投 inner role)\n const inputFaces = kernel.getSubShapes(inputSolid, 'face')\n const inputCentroids = inputFaces.map((f) => kernel.getSurfaceCenterOfMass(f))\n\n // 取 count 份副本(内核原生 linearPattern:brepkit 返回 BrepHandle[],occt-wasm\n // 返回已 fused 的 BrepHandle —— 两种形态都按结果面质心聚类,故兼容)\n const dir = norm(direction)\n const raw = (kernel as unknown as {\n linearPattern(s: BrepHandle, d: number[], sp: number, n: number): unknown\n }).linearPattern(inputSolid, [dir[0], dir[1], dir[2]], spacing, count)\n\n let resultSolid: BrepHandle\n if (Array.isArray(raw)) {\n try {\n resultSolid = kernel.fuseAll(raw)\n } finally {\n for (const c of raw) kernel.release(c)\n }\n } else {\n resultSolid = raw as BrepHandle\n }\n\n // 结果面 hash / 质心\n const resultHashes = getFaceHashes(kernel, resultSolid)\n const resultFaces = kernel.getSubShapes(resultSolid, 'face')\n const resultCentroids = resultFaces.map((f) => kernel.getSurfaceCenterOfMass(f))\n\n const roleTable = new Map<string, Map<string, number[]>>()\n const inner = new Map<string, number[]>()\n\n for (let i = 0; i < resultHashes.length; i++) {\n const c = resultCentroids[i]!\n // 沿 dir 投影得到份数坐标 t,四舍五入到 spacing 倍数 → k\n const t = c.x * dir[0] + c.y * dir[1] + c.z * dir[2]\n const k = Math.round(t / spacing)\n // 面内坐标 = centroid − t·dir\n const inPlane: [number, number, number] = [c.x - t * dir[0], c.y - t * dir[1], c.z - t * dir[2]]\n // 匹配输入面(最近面内坐标)→ inner role\n let bestRole: string | undefined\n let bestDist = Infinity\n for (let j = 0; j < inputCentroids.length; j++) {\n const ic = inputCentroids[j]!\n const it = ic.x * dir[0] + ic.y * dir[1] + ic.z * dir[2]\n const ii: [number, number, number] = [ic.x - it * dir[0], ic.y - it * dir[1], ic.z - it * dir[2]]\n const d = (inPlane[0] - ii[0]) ** 2 + (inPlane[1] - ii[1]) ** 2 + (inPlane[2] - ii[2]) ** 2\n if (d < bestDist) {\n bestDist = d\n bestRole = inputHashToRole.get(inputHashes[j]!)\n }\n }\n const role = `replica[${k}]/${bestRole ?? 'face'}`\n if (!inner.has(role)) inner.set(role, [])\n inner.get(role)!.push(resultHashes[i]!)\n }\n roleTable.set(outStmt, inner)\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n}\n\n/**\n * 线性阵列:沿 direction 复制 count 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name linearPattern\n * @note BREP-only:非 BREP 输入抛 E_MESH_UNSUPPORTED。结果面按份数 k 回投影到输入面\n * 角色,产出 `replica[k]/<inner>`(Phase 3 L3 抗重放词汇)。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param direction - 阵列方向。type:[x,y,z] required:true\n * @param count - 副本总数(含原位置)。type:number required:true\n * @param spacing - 副本间距。type:number required:true\n * @example\n * const p = await cad.linearPattern(part0, [1, 0, 0], 3, 20)\n */\nexport const linearPattern = defineOp({\n brep(input: Shape, direction: Vec3, count: number, spacing: number) {\n return linearPatternBrep(input, direction, count, spacing)\n },\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/api/pattern.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib pattern — linearPattern(手写覆盖生成投影,Phase 3: L3 `replica[k]` 角色表)\n *\n * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径\n * 用质心聚类把结果面按份数 k 分组、回投影到输入面角色,产出 `replica[k]/<inner>`。\n *\n * 机制(无内核历史,纯几何推理):pattern 的每份副本都是输入的精确平移,副本面\n * 几何相同但质心不同。结果面沿 pattern 方向投影得到份数坐标 t,四舍五入到 spacing\n * 倍数即得 k;再按「面内坐标」(centroid − t·dir)匹配输入面对应面,回投其 inner role。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBackends, getCurrentStmt, keep } from '../runtime-state'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { buildReplicaRoleTable, type ReplicaTransform } from './internal/replica-role-table'\n\n/** 归一化向量(零向量 → [0,0,1] 兜底)。 */\nfunction norm(v: Vec3): [number, number, number] {\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\n/** BREP 路径:沿 direction 复制 count 份,质心聚类回投输入面角色。 */\nfunction linearPatternBrep(input: Shape, direction: Vec3, count: number, spacing: number): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/pattern] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/pattern] input is not BREP')\n\n // Phase 1.6:origin = 本次语句 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n\n // 取 count 份副本。Phase 2:BrepEngineApi.linearPattern 契约统一返回 BrepHandle[]\n // (两内核原生都返回 compound,由适配器拆成数组)——不再有「单句柄 fused」形态。\n const dir = norm(direction)\n const raw = kernel.linearPattern(inputSolid, { x: dir[0], y: dir[1], z: dir[2] }, spacing, 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 // 第 k 份副本是输入沿 dir 平移 k*spacing:质心反投回输入坐标系(T_k⁻¹)。\n const replicas: ReplicaTransform[] = []\n for (let k = 0; k < count; k++) {\n const off = k * spacing\n replicas.push({\n label: `replica[${k}]`,\n inverse: (c) => ({ x: c.x - off * dir[0], y: c.y - off * dir[1], z: c.z - off * dir[2] }),\n })\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n}\n\n/**\n * 线性阵列:沿 direction 复制 count 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name linearPattern\n * @note BREP-only:非 BREP 输入抛 E_MESH_UNSUPPORTED。结果面按份数 k 回投影到输入面\n * 角色,产出 `replica[k]/<inner>`(Phase 3 L3 抗重放词汇)。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param direction - 阵列方向。type:[x,y,z] required:true\n * @param count - 副本总数(含原位置)。type:number required:true\n * @param spacing - 副本间距。type:number required:true\n * @example\n * const p = await cad.linearPattern(part0, [1, 0, 0], 3, 20)\n */\nexport const linearPattern = defineOp({\n brep(input: Shape, direction: Vec3, count: number, spacing: number) {\n // copy-like keep semantics: replicate ops preserve their source shape.\n keep(input)\n return linearPatternBrep(input, direction, count, spacing)\n },\n // Phase 1(Brep 引擎可切换重构):能力前置判定——linearPattern 需要内核的\n // 线性阵列方法(BrepMethodKind),brepkit 装配下缺失时执行前静态报错。\n capabilities: ['linearPattern'],\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n"]}