@faicad/faijs 0.33.1 → 0.35.2

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 (392) hide show
  1. package/dist/api/api-namespace.d.ts +14 -14
  2. package/dist/api/api-namespace.d.ts.map +1 -1
  3. package/dist/api/api-namespace.js +40 -14
  4. package/dist/api/api-namespace.js.map +1 -1
  5. package/dist/api/appearance.d.ts +47 -6
  6. package/dist/api/appearance.d.ts.map +1 -1
  7. package/dist/api/appearance.js.map +1 -1
  8. package/dist/api/assembly/solve-tree.d.ts +1 -0
  9. package/dist/api/assembly/solve-tree.d.ts.map +1 -1
  10. package/dist/api/assembly/solve-tree.js +42 -17
  11. package/dist/api/assembly/solve-tree.js.map +1 -1
  12. package/dist/api/assembly/solve.d.ts +1 -0
  13. package/dist/api/assembly/solve.d.ts.map +1 -1
  14. package/dist/api/assembly/solve.js.map +1 -1
  15. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  16. package/dist/api/assembly/solvers/global-solver.js +130 -23
  17. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  18. package/dist/api/assembly/solvers/pose-from-delta.d.ts +9 -0
  19. package/dist/api/assembly/solvers/pose-from-delta.d.ts.map +1 -1
  20. package/dist/api/assembly/solvers/pose-from-delta.js +23 -0
  21. package/dist/api/assembly/solvers/pose-from-delta.js.map +1 -1
  22. package/dist/api/assembly/solvers/types.d.ts +20 -2
  23. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  24. package/dist/api/assembly/solvers/types.js.map +1 -1
  25. package/dist/api/chamfer.d.ts +7 -4
  26. package/dist/api/chamfer.d.ts.map +1 -1
  27. package/dist/api/chamfer.js +57 -13
  28. package/dist/api/chamfer.js.map +1 -1
  29. package/dist/api/draft.d.ts +7 -4
  30. package/dist/api/draft.d.ts.map +1 -1
  31. package/dist/api/draft.js +11 -6
  32. package/dist/api/draft.js.map +1 -1
  33. package/dist/api/edge-ref.d.ts +4 -4
  34. package/dist/api/edge-ref.js +4 -4
  35. package/dist/api/edge-ref.js.map +1 -1
  36. package/dist/api/extrude.d.ts +10 -6
  37. package/dist/api/extrude.d.ts.map +1 -1
  38. package/dist/api/extrude.js +50 -25
  39. package/dist/api/extrude.js.map +1 -1
  40. package/dist/api/face-ref.d.ts +4 -4
  41. package/dist/api/face-ref.js +4 -4
  42. package/dist/api/face-ref.js.map +1 -1
  43. package/dist/api/feature-repair.d.ts +6 -3
  44. package/dist/api/feature-repair.d.ts.map +1 -1
  45. package/dist/api/feature-repair.js +12 -7
  46. package/dist/api/feature-repair.js.map +1 -1
  47. package/dist/api/fillet-variable.d.ts +6 -2
  48. package/dist/api/fillet-variable.d.ts.map +1 -1
  49. package/dist/api/fillet-variable.js +24 -6
  50. package/dist/api/fillet-variable.js.map +1 -1
  51. package/dist/api/fillet.d.ts +7 -4
  52. package/dist/api/fillet.d.ts.map +1 -1
  53. package/dist/api/fillet.js +45 -12
  54. package/dist/api/fillet.js.map +1 -1
  55. package/dist/api/helix.d.ts +13 -13
  56. package/dist/api/helix.d.ts.map +1 -1
  57. package/dist/api/helix.js +19 -24
  58. package/dist/api/helix.js.map +1 -1
  59. package/dist/api/import-brep.d.ts +10 -18
  60. package/dist/api/import-brep.d.ts.map +1 -1
  61. package/dist/api/import-brep.js +17 -25
  62. package/dist/api/import-brep.js.map +1 -1
  63. package/dist/api/import-step.d.ts +10 -15
  64. package/dist/api/import-step.d.ts.map +1 -1
  65. package/dist/api/import-step.js +24 -29
  66. package/dist/api/import-step.js.map +1 -1
  67. package/dist/api/index.js +2 -2
  68. package/dist/api/index.js.map +1 -1
  69. package/dist/api/internal/export-members.js.map +1 -1
  70. package/dist/api/loft-advanced.d.ts +4 -0
  71. package/dist/api/loft-advanced.d.ts.map +1 -1
  72. package/dist/api/loft-advanced.js +4 -0
  73. package/dist/api/loft-advanced.js.map +1 -1
  74. package/dist/api/loft.d.ts +5 -3
  75. package/dist/api/loft.d.ts.map +1 -1
  76. package/dist/api/loft.js +5 -3
  77. package/dist/api/loft.js.map +1 -1
  78. package/dist/api/meta.d.ts +42 -6
  79. package/dist/api/meta.d.ts.map +1 -1
  80. package/dist/api/meta.js.map +1 -1
  81. package/dist/api/punch-hole.d.ts +5 -2
  82. package/dist/api/punch-hole.d.ts.map +1 -1
  83. package/dist/api/punch-hole.js +4 -1
  84. package/dist/api/punch-hole.js.map +1 -1
  85. package/dist/api/replicate.d.ts +4 -5
  86. package/dist/api/replicate.d.ts.map +1 -1
  87. package/dist/api/replicate.js +4 -5
  88. package/dist/api/replicate.js.map +1 -1
  89. package/dist/api/selectors-to-refs.d.ts +83 -0
  90. package/dist/api/selectors-to-refs.d.ts.map +1 -0
  91. package/dist/api/selectors-to-refs.js +211 -0
  92. package/dist/api/selectors-to-refs.js.map +1 -0
  93. package/dist/api/shell.d.ts +17 -8
  94. package/dist/api/shell.d.ts.map +1 -1
  95. package/dist/api/shell.js +45 -15
  96. package/dist/api/shell.js.map +1 -1
  97. package/dist/api/sketch-on-face.d.ts +12 -6
  98. package/dist/api/sketch-on-face.d.ts.map +1 -1
  99. package/dist/api/sketch-on-face.js +31 -4
  100. package/dist/api/sketch-on-face.js.map +1 -1
  101. package/dist/api/sketch-on-plane.d.ts +3 -0
  102. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  103. package/dist/api/sketch-on-plane.js +3 -0
  104. package/dist/api/sketch-on-plane.js.map +1 -1
  105. package/dist/api/sketch-on-surface.d.ts +4 -1
  106. package/dist/api/sketch-on-surface.d.ts.map +1 -1
  107. package/dist/api/sketch-on-surface.js +4 -1
  108. package/dist/api/sketch-on-surface.js.map +1 -1
  109. package/dist/api/view/view-projection.d.ts.map +1 -1
  110. package/dist/api/view/view-projection.js +9 -2
  111. package/dist/api/view/view-projection.js.map +1 -1
  112. package/dist/brep/brep-chain.js +2 -2
  113. package/dist/brep/brep-chain.js.map +1 -1
  114. package/dist/brep/brep-ops.d.ts +1 -1
  115. package/dist/brep/brep-ops.js +1 -1
  116. package/dist/brep/brep-ops.js.map +1 -1
  117. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  118. package/dist/brep/engine/adapters/brep-mock.js +45 -0
  119. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  120. package/dist/brep/engine/primitives.d.ts +87 -3
  121. package/dist/brep/engine/primitives.d.ts.map +1 -1
  122. package/dist/brep/engine/primitives.js +1 -1
  123. package/dist/brep/engine/primitives.js.map +1 -1
  124. package/dist/brep/engine/registry.d.ts +33 -7
  125. package/dist/brep/engine/registry.d.ts.map +1 -1
  126. package/dist/brep/engine/registry.js +47 -16
  127. package/dist/brep/engine/registry.js.map +1 -1
  128. package/dist/brep/handle-bridge.d.ts +14 -15
  129. package/dist/brep/handle-bridge.d.ts.map +1 -1
  130. package/dist/brep/handle-bridge.js +35 -15
  131. package/dist/brep/handle-bridge.js.map +1 -1
  132. package/dist/brep/primitives-brep.js +2 -2
  133. package/dist/brep/primitives-brep.js.map +1 -1
  134. package/dist/brep/text/text-to-solid.d.ts +40 -3
  135. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  136. package/dist/brep/text/text-to-solid.js +104 -24
  137. package/dist/brep/text/text-to-solid.js.map +1 -1
  138. package/dist/brepkit-kernel/brepkitKernel.d.ts +2 -2
  139. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  140. package/dist/brepkit-kernel/brepkitKernel.js +315 -36
  141. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  142. package/dist/brepkit-kernel/brepkitWasm.js +7 -7
  143. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  144. package/dist/brepkit-kernel/multi-version-test.d.ts +2 -2
  145. package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
  146. package/dist/brepkit-kernel/multi-version-test.js +6 -6
  147. package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
  148. package/dist/browser.d.ts +2 -3
  149. package/dist/browser.d.ts.map +1 -1
  150. package/dist/browser.js +1 -2
  151. package/dist/browser.js.map +1 -1
  152. package/dist/cad-runtime/admit-compat-lib.d.ts +9 -1
  153. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  154. package/dist/cad-runtime/admit-compat-lib.js +11 -1
  155. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  156. package/dist/cad-runtime/browser-lib-loader.d.ts +16 -11
  157. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  158. package/dist/cad-runtime/browser-lib-loader.js +16 -8
  159. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  160. package/dist/cad-runtime/direct-executor.d.ts +62 -5
  161. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  162. package/dist/cad-runtime/direct-executor.js +617 -42
  163. package/dist/cad-runtime/direct-executor.js.map +1 -1
  164. package/dist/cad-runtime/interp/closure.d.ts +3 -2
  165. package/dist/cad-runtime/interp/closure.d.ts.map +1 -1
  166. package/dist/cad-runtime/interp/closure.js.map +1 -1
  167. package/dist/cad-runtime/interp/env.d.ts +9 -6
  168. package/dist/cad-runtime/interp/env.d.ts.map +1 -1
  169. package/dist/cad-runtime/interp/env.js +4 -2
  170. package/dist/cad-runtime/interp/env.js.map +1 -1
  171. package/dist/cad-runtime/lib-decl.d.ts +121 -0
  172. package/dist/cad-runtime/lib-decl.d.ts.map +1 -0
  173. package/dist/cad-runtime/lib-decl.js +100 -0
  174. package/dist/cad-runtime/lib-decl.js.map +1 -0
  175. package/dist/cad-runtime/ports.d.ts +12 -0
  176. package/dist/cad-runtime/ports.d.ts.map +1 -1
  177. package/dist/cad-runtime/ports.js.map +1 -1
  178. package/dist/cad-runtime/runtime.d.ts +59 -5
  179. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  180. package/dist/cad-runtime/runtime.js +237 -18
  181. package/dist/cad-runtime/runtime.js.map +1 -1
  182. package/dist/extra/browser.d.ts +9 -0
  183. package/dist/extra/browser.d.ts.map +1 -0
  184. package/dist/extra/browser.js +9 -0
  185. package/dist/extra/browser.js.map +1 -0
  186. package/dist/extra/editor-ops.d.ts +22 -0
  187. package/dist/extra/editor-ops.d.ts.map +1 -0
  188. package/dist/extra/editor-ops.js +21 -0
  189. package/dist/extra/editor-ops.js.map +1 -0
  190. package/dist/extra/extras/svg-extrude.d.ts +45 -0
  191. package/dist/extra/extras/svg-extrude.d.ts.map +1 -0
  192. package/dist/extra/extras/svg-extrude.js +110 -0
  193. package/dist/extra/extras/svg-extrude.js.map +1 -0
  194. package/dist/extra/extras/text-cjk.d.ts +36 -0
  195. package/dist/extra/extras/text-cjk.d.ts.map +1 -0
  196. package/dist/extra/extras/text-cjk.js +86 -0
  197. package/dist/extra/extras/text-cjk.js.map +1 -0
  198. package/dist/extra/extras/text-geometry.d.ts +69 -0
  199. package/dist/extra/extras/text-geometry.d.ts.map +1 -0
  200. package/dist/extra/extras/text-geometry.js +188 -0
  201. package/dist/extra/extras/text-geometry.js.map +1 -0
  202. package/dist/extra/index.d.ts +40 -0
  203. package/dist/extra/index.d.ts.map +1 -0
  204. package/dist/extra/index.js +40 -0
  205. package/dist/extra/index.js.map +1 -0
  206. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts +94 -0
  207. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts.map +1 -0
  208. package/dist/extra/mesh/drill-hole/DrillHoleCore.js +282 -0
  209. package/dist/extra/mesh/drill-hole/DrillHoleCore.js.map +1 -0
  210. package/dist/extra/mesh/drill-hole/drill-types.d.ts +34 -0
  211. package/dist/extra/mesh/drill-hole/drill-types.d.ts.map +1 -0
  212. package/dist/extra/mesh/drill-hole/drill-types.js +7 -0
  213. package/dist/extra/mesh/drill-hole/drill-types.js.map +1 -0
  214. package/dist/extra/mesh/engrave-decoration.d.ts +42 -0
  215. package/dist/extra/mesh/engrave-decoration.d.ts.map +1 -0
  216. package/dist/extra/mesh/engrave-decoration.js +39 -0
  217. package/dist/extra/mesh/engrave-decoration.js.map +1 -0
  218. package/dist/extra/mesh/fai_drill.d.ts +21 -0
  219. package/dist/extra/mesh/fai_drill.d.ts.map +1 -0
  220. package/dist/extra/mesh/fai_drill.js +89 -0
  221. package/dist/extra/mesh/fai_drill.js.map +1 -0
  222. package/dist/extra/mesh/fai_extrude.d.ts +24 -0
  223. package/dist/extra/mesh/fai_extrude.d.ts.map +1 -0
  224. package/dist/extra/mesh/fai_extrude.js +42 -0
  225. package/dist/extra/mesh/fai_extrude.js.map +1 -0
  226. package/dist/extra/mesh/fai_split.d.ts +164 -0
  227. package/dist/extra/mesh/fai_split.d.ts.map +1 -0
  228. package/dist/extra/mesh/fai_split.js +269 -0
  229. package/dist/extra/mesh/fai_split.js.map +1 -0
  230. package/dist/extra/mesh/primitives.d.ts +29 -0
  231. package/dist/extra/mesh/primitives.d.ts.map +1 -0
  232. package/dist/extra/mesh/primitives.js +41 -0
  233. package/dist/extra/mesh/primitives.js.map +1 -0
  234. package/dist/extra/op-names.d.ts +37 -0
  235. package/dist/extra/op-names.d.ts.map +1 -0
  236. package/dist/extra/op-names.js +46 -0
  237. package/dist/extra/op-names.js.map +1 -0
  238. package/dist/extra/ops/compound.d.ts +140 -0
  239. package/dist/extra/ops/compound.d.ts.map +1 -0
  240. package/dist/extra/ops/compound.js +167 -0
  241. package/dist/extra/ops/compound.js.map +1 -0
  242. package/dist/extra/ops/copy.d.ts +40 -0
  243. package/dist/extra/ops/copy.d.ts.map +1 -0
  244. package/dist/extra/ops/copy.js +83 -0
  245. package/dist/extra/ops/copy.js.map +1 -0
  246. package/dist/extra/ops/fai_drill.d.ts +51 -0
  247. package/dist/extra/ops/fai_drill.d.ts.map +1 -0
  248. package/dist/extra/ops/fai_drill.js +233 -0
  249. package/dist/extra/ops/fai_drill.js.map +1 -0
  250. package/dist/extra/ops/fai_extrude.d.ts +36 -0
  251. package/dist/extra/ops/fai_extrude.d.ts.map +1 -0
  252. package/dist/extra/ops/fai_extrude.js +84 -0
  253. package/dist/extra/ops/fai_extrude.js.map +1 -0
  254. package/dist/extra/ops/fai_split.d.ts +46 -0
  255. package/dist/extra/ops/fai_split.d.ts.map +1 -0
  256. package/dist/extra/ops/fai_split.js +235 -0
  257. package/dist/extra/ops/fai_split.js.map +1 -0
  258. package/dist/extra/ops/load.d.ts +49 -0
  259. package/dist/extra/ops/load.d.ts.map +1 -0
  260. package/dist/extra/ops/load.js +385 -0
  261. package/dist/extra/ops/load.js.map +1 -0
  262. package/dist/extra/ops/svg-extrude.d.ts +32 -0
  263. package/dist/extra/ops/svg-extrude.d.ts.map +1 -0
  264. package/dist/extra/ops/svg-extrude.js +74 -0
  265. package/dist/extra/ops/svg-extrude.js.map +1 -0
  266. package/dist/extra/ops/text.d.ts +34 -0
  267. package/dist/extra/ops/text.d.ts.map +1 -0
  268. package/dist/extra/ops/text.js +100 -0
  269. package/dist/extra/ops/text.js.map +1 -0
  270. package/dist/geometry2d/bridge/lift-on-plane.d.ts +8 -5
  271. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  272. package/dist/geometry2d/bridge/lift-on-plane.js +8 -5
  273. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  274. package/dist/index.d.ts +6 -2
  275. package/dist/index.d.ts.map +1 -1
  276. package/dist/index.js +8 -2
  277. package/dist/index.js.map +1 -1
  278. package/dist/lang/symbol-table.d.ts +3 -3
  279. package/dist/lang/symbol-table.generated.d.ts +10 -0
  280. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  281. package/dist/lang/symbol-table.generated.js +10 -0
  282. package/dist/lang/symbol-table.generated.js.map +1 -1
  283. package/dist/lang/symbol-table.js +3 -3
  284. package/dist/lang/symbol-table.js.map +1 -1
  285. package/dist/math3d/index.d.ts +1 -1
  286. package/dist/math3d/index.js +1 -1
  287. package/dist/math3d/index.js.map +1 -1
  288. package/dist/mesh/engrave.d.ts +2 -3
  289. package/dist/mesh/engrave.d.ts.map +1 -1
  290. package/dist/mesh/engrave.js +4 -11
  291. package/dist/mesh/engrave.js.map +1 -1
  292. package/dist/mesh/index.d.ts +0 -2
  293. package/dist/mesh/index.d.ts.map +1 -1
  294. package/dist/mesh/index.js +0 -2
  295. package/dist/mesh/index.js.map +1 -1
  296. package/dist/mesh/primitives.d.ts +1 -1
  297. package/dist/mesh/primitives.js +1 -1
  298. package/dist/mesh/primitives.js.map +1 -1
  299. package/dist/node-host/cli.d.ts +20 -4
  300. package/dist/node-host/cli.d.ts.map +1 -1
  301. package/dist/node-host/cli.js +84 -35
  302. package/dist/node-host/cli.js.map +1 -1
  303. package/dist/node-host/execute-script.d.ts.map +1 -1
  304. package/dist/node-host/execute-script.js +3 -4
  305. package/dist/node-host/execute-script.js.map +1 -1
  306. package/dist/node-host/lib-package-json.d.ts +36 -0
  307. package/dist/node-host/lib-package-json.d.ts.map +1 -0
  308. package/dist/node-host/lib-package-json.js +73 -0
  309. package/dist/node-host/lib-package-json.js.map +1 -0
  310. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  311. package/dist/occt-kernel/occt-primitives.js +41 -0
  312. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  313. package/dist/occt-kernel/occtKernel.d.ts +1 -1
  314. package/dist/occt-kernel/occtKernel.js +1 -1
  315. package/dist/occt-kernel/occtKernel.js.map +1 -1
  316. package/dist/runtime-state.d.ts +28 -1
  317. package/dist/runtime-state.d.ts.map +1 -1
  318. package/dist/runtime-state.js +14 -1
  319. package/dist/runtime-state.js.map +1 -1
  320. package/dist/sdk.d.ts +2 -2
  321. package/dist/sdk.d.ts.map +1 -1
  322. package/dist/sdk.js +11 -2
  323. package/dist/sdk.js.map +1 -1
  324. package/dist/sketch/bspline.d.ts +58 -0
  325. package/dist/sketch/bspline.d.ts.map +1 -0
  326. package/dist/sketch/bspline.js +104 -0
  327. package/dist/sketch/bspline.js.map +1 -0
  328. package/dist/sketch/canonical.d.ts +239 -0
  329. package/dist/sketch/canonical.d.ts.map +1 -0
  330. package/dist/sketch/canonical.js +17 -0
  331. package/dist/sketch/canonical.js.map +1 -0
  332. package/dist/sketch/contour.d.ts +43 -0
  333. package/dist/sketch/contour.d.ts.map +1 -0
  334. package/dist/sketch/contour.js +202 -0
  335. package/dist/sketch/contour.js.map +1 -0
  336. package/dist/sketch/dim-spec.d.ts +32 -0
  337. package/dist/sketch/dim-spec.d.ts.map +1 -0
  338. package/dist/sketch/dim-spec.js +112 -0
  339. package/dist/sketch/dim-spec.js.map +1 -0
  340. package/dist/sketch/faces.d.ts +45 -0
  341. package/dist/sketch/faces.d.ts.map +1 -0
  342. package/dist/sketch/faces.js +108 -0
  343. package/dist/sketch/faces.js.map +1 -0
  344. package/dist/sketch/fcstd-types.d.ts +194 -0
  345. package/dist/sketch/fcstd-types.d.ts.map +1 -0
  346. package/dist/sketch/fcstd-types.js +67 -0
  347. package/dist/sketch/fcstd-types.js.map +1 -0
  348. package/dist/sketch/index.d.ts +46 -0
  349. package/dist/sketch/index.d.ts.map +1 -0
  350. package/dist/sketch/index.js +39 -0
  351. package/dist/sketch/index.js.map +1 -0
  352. package/dist/sketch/node.d.ts +14 -0
  353. package/dist/sketch/node.d.ts.map +1 -0
  354. package/dist/sketch/node.js +43 -0
  355. package/dist/sketch/node.js.map +1 -0
  356. package/dist/sketch/op.d.ts +111 -0
  357. package/dist/sketch/op.d.ts.map +1 -0
  358. package/dist/sketch/op.js +185 -0
  359. package/dist/sketch/op.js.map +1 -0
  360. package/dist/sketch/planegcs-backend.d.ts +69 -0
  361. package/dist/sketch/planegcs-backend.d.ts.map +1 -0
  362. package/dist/sketch/planegcs-backend.js +812 -0
  363. package/dist/sketch/planegcs-backend.js.map +1 -0
  364. package/dist/sketch/project.d.ts +176 -0
  365. package/dist/sketch/project.d.ts.map +1 -0
  366. package/dist/sketch/project.js +656 -0
  367. package/dist/sketch/project.js.map +1 -0
  368. package/dist/sketch/shapes.d.ts +370 -0
  369. package/dist/sketch/shapes.d.ts.map +1 -0
  370. package/dist/sketch/shapes.js +959 -0
  371. package/dist/sketch/shapes.js.map +1 -0
  372. package/dist/sketch/solve.d.ts +21 -0
  373. package/dist/sketch/solve.d.ts.map +1 -0
  374. package/dist/sketch/solve.js +144 -0
  375. package/dist/sketch/solve.js.map +1 -0
  376. package/dist/sketch/solver-loader.d.ts +47 -0
  377. package/dist/sketch/solver-loader.d.ts.map +1 -0
  378. package/dist/sketch/solver-loader.js +77 -0
  379. package/dist/sketch/solver-loader.js.map +1 -0
  380. package/dist/sketch/solver.d.ts +63 -0
  381. package/dist/sketch/solver.d.ts.map +1 -0
  382. package/dist/sketch/solver.js +28 -0
  383. package/dist/sketch/solver.js.map +1 -0
  384. package/dist/sketch/verify.d.ts +53 -0
  385. package/dist/sketch/verify.d.ts.map +1 -0
  386. package/dist/sketch/verify.js +71 -0
  387. package/dist/sketch/verify.js.map +1 -0
  388. package/dist/weapp.d.ts +1 -1
  389. package/dist/weapp.d.ts.map +1 -1
  390. package/dist/weapp.js +1 -1
  391. package/dist/weapp.js.map +1 -1
  392. package/package.json +43 -11
@@ -9,7 +9,7 @@
9
9
  * `api/surface/engine-method-map.json` 的 aligned/dialect 条目)。brepkit 独有
10
10
  * 能力(chamfer2d/chamferV2/filletV2/sketch* 族、serializeSolid、meshBoolean、
11
11
  * minkowskiSum …)与单方语义(loft、平面 section/split 之外的 splitter 语义…)
12
- * 都不在本对象里——平台代码经原生面 `getBrepkitKernel()`(D3)访问。
12
+ * 都不在本对象里——平台代码经原生面 `getBrepKitKernel()`(D3)访问。
13
13
  *
14
14
  * 设计要点(对应 3d_editor 项目的 weapp-voice-ai-modeling 设计计划 §5):
15
15
  * - 句柄:brepkit u32 句柄与 faijs BrepHandle(number) 同构,直通零转换;
@@ -68,6 +68,19 @@ const withKind = (kind, n) => {
68
68
  }
69
69
  };
70
70
  const arr = (x) => Array.from(x);
71
+ /**
72
+ * L1 向量形参的静态校验:`BrepVec3 = {x,y,z}` **对象**,不是元组、更不是布尔。
73
+ *
74
+ * 包侧旧口径(`loft(wires, isSolid?, ruled?)` 之类)会把标量/布尔塞进向量位,进内核
75
+ * 后只剩一句无指向的 wasm 报错(实测 `cannot normalize zero vector`)。编译期管不住的
76
+ * 调用点(跨包 `as unknown as` 注入)在此静态判一次,给可指路的错误。
77
+ */
78
+ const isBrepVec3 = (v) => {
79
+ if (typeof v !== 'object' || v === null)
80
+ return false;
81
+ const o = v;
82
+ return typeof o.x === 'number' && typeof o.y === 'number' && typeof o.z === 'number';
83
+ };
71
84
  /** 适配器内部的显式失败(替代旧 unsupported 桩:能力缺失一律在静态判定拦截,不在实现体里伪装)。 */
72
85
  function fail(detail) {
73
86
  throw new Error(`[brepkit-kernel] ${detail}`);
@@ -331,6 +344,12 @@ export async function createBrepkitPrimitives() {
331
344
  const derivedFaces = new Set();
332
345
  // 虚拟 compound 句柄计数器(非实体子句柄不进内核 makeCompound,见 makeCompound GOTCHA)。
333
346
  const knownCompounds = new Map();
347
+ // 虚拟 compound 句柄 → 真内核 compound 句柄(exportStep 等 IO 需要真句柄;几何分发全走虚拟句柄)。
348
+ // 2026-10-13:brepkit 句柄按**类型分命名空间**(同文件 356 行 GOTCHA),compound 命名空间从 0 计数,
349
+ // 与 solid 命名空间**重号**(实测 5 成员 solid [0..4] 的 compound 句柄 = 0)——knownCompounds 以
350
+ // 内核句柄为 key 会在「查询同号的另一 solid」时误判成 compound(textToSolid 'Hello' translate 后
351
+ // 只剩 1 成员即此:copySolid(0) 被当成员 solid 复制)。故 compound 一律用 0x20000000+ 虚拟句柄。
352
+ const kernelCompoundHandles = new Map();
334
353
  let virtualCompoundCounter = 0;
335
354
  // GOTCHA(2026-09-26):brepkit 句柄按**类型分命名空间**——solid/face/wire/edge 各自从 0 计数
336
355
  // (实测 edge=wire=face=solid=0 可共存)。因此「某编号 N 在 knownFaces」与「某编号 N 是 solid」
@@ -554,8 +573,41 @@ export async function createBrepkitPrimitives() {
554
573
  }
555
574
  return markSolid(kernel.copySolid(shape));
556
575
  };
557
- /** 深拷贝 + 原地仿射变换(matrix 已经 toKernelMatrix 归一为 16 元素 4×4)。 */
576
+ /** 成员句柄数组 → compound(solid-only 内核直通;face/wire/edge 混合走虚拟句柄)。
577
+ * makeCompound 适配器与 cloneAndTransform 的 compound 分支共用(同一分发逻辑一份)。
578
+ *
579
+ * GOTCHA(2026-10-13):**所有** compound 一律返回虚拟句柄(0x20000000+)——brepkit
580
+ * 的 compound 句柄与 solid 句柄**分命名空间且可重号**(见 356 行 GOTCHA:实测成员
581
+ * [0..4] 的 compound 内核句柄 = 0),knownCompounds 若以内核句柄为 key,查询同号的
582
+ * 另一 solid 时会误判成 compound('Hello' translate 后只剩 1 成员的根因)。真内核
583
+ * compound 句柄仅保留在 kernelCompoundHandles,供 exportStep 等 IO 使用。 */
584
+ const compoundOf = (kids) => {
585
+ virtualCompoundCounter++;
586
+ const v = 0x20000000 + virtualCompoundCounter;
587
+ const hasNonSolid = kids.some((k) => knownFaces.has(k) || knownWires.has(k) || knownEdges.has(k) || knownCompounds.has(k));
588
+ if (!hasNonSolid) {
589
+ const c = kernel.makeCompound(Int32Array.from(kids));
590
+ kernelCompoundHandles.set(v, c);
591
+ }
592
+ knownCompounds.set(v, kids);
593
+ return v;
594
+ };
595
+ /**
596
+ * 深拷贝 + 原地仿射变换(matrix 已经 toKernelMatrix 归一为 16 元素 4×4)。
597
+ *
598
+ * compound 分支(2026-10-13 修复):brepkit 的 copySolid/transformSolid 只吃
599
+ * **solid** 句柄——整体传 compound 会静默丢成员(实测 textToSolid 的 'Hello'
600
+ * 5 成员 compound 经 translate 居中后只剩 1 个,真机 3D 文字只剩最后一个字符)。
601
+ * 必须逐成员深拷贝 + 变换后再 compoundOf 重组。
602
+ */
558
603
  const cloneAndTransform = (shape, matrix16, kind = KIND_SOLID) => {
604
+ const kids = knownCompounds.get(shape);
605
+ if (kids) {
606
+ // kids 是裸句柄号(无类型标签,kindOf 恒 0);子成员类型由 cloneShape 的
607
+ // knownFaces/knownWires 集合兜底分发(集合 key 即裸号),故递归传默认 kind。
608
+ const t = kids.map((k) => cloneAndTransform(k, matrix16));
609
+ return compoundOf(t);
610
+ }
559
611
  const c = cloneShape(shape, kind);
560
612
  const m = Float64Array.from(matrix16);
561
613
  if (kind === KIND_FACE || knownFaces.has(c))
@@ -707,12 +759,12 @@ export async function createBrepkitPrimitives() {
707
759
  return asHandle(markSolid(kernel.extrude(s, dx / len, dy / len, dz / len, len)));
708
760
  },
709
761
  revolveVec(shape, center, direction, angleDeg) {
710
- // 方言归一:brepkit revolve 只吃 face(与 extrude 同族断言)。
711
- const s = asNum(shape);
712
- if (!knownFaces.has(s)) {
713
- fail('revolveVec requires a face input; got a handle that is not a known face');
714
- }
715
- return asHandle(markSolid(kernel.revolve(s, center.x, center.y, center.z, direction.x, direction.y, direction.z, angleDeg)));
762
+ // 方言归一(与 sweep / loft 同款):brepkit 原生 revolve 只吃 face,而 L1 调用方
763
+ // 传的是**闭合轮廓 wire**(如 faijs-fasteners 的 revolveProfile 直传 wire);
764
+ // occt 侧原生 revolve 两者都吃。方言在适配器消化:wire → makeFaceFromWire 升面,
765
+ // 升面失败(开口 wire)由内核报错,不在适配器预判(与 sweep 同一纪律)。
766
+ const faceNum = profileFaceOf(shape, 'revolveVec');
767
+ return asHandle(markSolid(kernel.revolve(faceNum, center.x, center.y, center.z, direction.x, direction.y, direction.z, angleDeg)));
716
768
  },
717
769
  sweep(profile, spine) {
718
770
  // L1 中立 sweep:occt 侧走 sweepPipeShell;brepkit 只吃 (face, 路径 edge)
@@ -730,19 +782,21 @@ export async function createBrepkitPrimitives() {
730
782
  }
731
783
  // ① 各截面 → face。
732
784
  const faces = sections.map((s) => profileFaceOf(s, 'loft'));
733
- // ② brepkit loft 要求各截面**顶点数一致**。内核自己也会抛,但报错不含「哪几个
734
- // 截面、差多少」——执行前静态判一次,给出可指路的错误;不静默降级、不换引擎
735
- // (方案 §5②,红线:静态可判的输入约束必须在执行前报错)。
736
- const counts = faces.map((f) => arr(kernel.getFaceVertices(f)).length);
737
- const ref = counts[0];
738
- if (counts.some((c) => c !== ref)) {
739
- fail('E_LOFT_SECTION_MISMATCH: brepkit loft requires every section to have the same ' +
740
- `vertex count, got [${counts.join(', ')}] — use cad.loftAdvanced (occt) for ` +
741
- 'sections with different vertex counts');
742
- }
785
+ // ② 顶点数不一致的截面(如圆 → 方)直接放行:brepkit 内核
786
+ // (operations/loft.rs)会把所有截面重采样到最大顶点数再蒙皮,
787
+ // wasm 绑定层无额外校验。不再执行前拦截(原 E_LOFT_SECTION_MISMATCH
788
+ // 门禁已移除,2026-10-14)。
743
789
  const farr = Uint32Array.from(faces);
744
790
  // ③ 选项映射:endPoint → loftWithOptions;ruled=false → loftSmooth。
745
791
  if (endPoint !== undefined) {
792
+ // 契约守卫:L1 的第三参是 `endPoint: BrepVec3`,而包侧旧口径是
793
+ // `loft(wires, isSolid?, ruled?)`(faijs-gears `kernel/gears.ts` 的
794
+ // `loft(wires, false, false)` 即如此)。布尔量落进 endPoint 位后会一路进内核,
795
+ // 只得到一句无指向的 wasm 报错(实测 `cannot normalize zero vector`)——
796
+ // 静态可判的输入约束必须在执行前显式失败(方案 §5② 红线),不进内核猜。
797
+ if (!isBrepVec3(endPoint)) {
798
+ fail(`E_LOFT_BAD_ENDPOINT: loft endPoint must be a BrepVec3 ({x,y,z}), got ${JSON.stringify(endPoint)}`);
799
+ }
746
800
  return asHandle(markSolid(kernel.loftWithOptions(farr, JSON.stringify({ ruled, endPoint: [endPoint.x, endPoint.y, endPoint.z] }))));
747
801
  }
748
802
  return asHandle(markSolid(ruled ? kernel.loft(farr) : kernel.loftSmooth(farr)));
@@ -761,6 +815,38 @@ export async function createBrepkitPrimitives() {
761
815
  hullFromPoints(points, _tolerance) {
762
816
  return asHandle(markSolid(kernel.convexHull(flattenPoints(points))));
763
817
  },
818
+ // ── 样条面 / 体构造补缺(2026-10-13 进 L1)──
819
+ bsplineSurface(points, rows, cols) {
820
+ // §7 决策点 1 选**插值**(interpolateSurface):L1 语义锚是 occt 的过点
821
+ // GeomAPI_PointsToBSplineSurface。不用 approximateSurfaceLspia——那是逼近,语义不同。
822
+ // 阶数:brepkit 要求 degree < 该方向点数,缺省 3 并夹紧(点少时降阶,不崩)。
823
+ const degU = Math.max(1, Math.min(3, rows - 1));
824
+ const degV = Math.max(1, Math.min(3, cols - 1));
825
+ if (points.length !== rows * cols) {
826
+ fail(`bsplineSurface: expected ${rows * cols} points (${rows}×${cols}), got ${points.length}`);
827
+ }
828
+ const f = kernel.interpolateSurface(flattenPoints(points), rows, cols, degU, degV);
829
+ knownFaces.add(f);
830
+ return asFace(f);
831
+ },
832
+ makeSolid(shell) {
833
+ const n = asNum(shell);
834
+ // 方言归一:brepkit 的 revolve / extrude / loft 已直接产出实体(markSolid 登记),
835
+ // 而 occt 的 revolve 产 shell、须 MakeSolid 固化。中立调用方统一写成
836
+ // `makeSolid(revolve(...))`(faijs-fasteners 的 revolveProfile 即如此),故此处对
837
+ // **已是实体**的输入幂等返回——不是吞错:非 shell 的输入仍交给内核报错。
838
+ if (knownSolids.has(n))
839
+ return shell;
840
+ return asHandle(markSolid(kernel.solidFromShell(n)));
841
+ },
842
+ thicken(shape, thickness, tolerance) {
843
+ // brepkit 原生 thicken 只有 (face, thickness),**无 tolerance 参数** ——
844
+ // 传非零容差即显式失败,不静默丢弃(与 sweep/loft 的显式失败同一纪律)。
845
+ if (tolerance !== undefined && tolerance !== 0) {
846
+ fail(`thicken: brepkit has no tolerance parameter (got ${tolerance}); pass 0 or omit it`);
847
+ }
848
+ return asHandle(markSolid(kernel.thicken(asNum(shape), thickness)));
849
+ },
764
850
  // ── 布尔与分割 ──
765
851
  fuse(a, b) { return asHandle(markSolid(trackFallback(kernel.fuse(asNum(a), asNum(b))))); },
766
852
  cut(a, b) { return asHandle(markSolid(trackFallback(kernel.cut(asNum(a), asNum(b))))); },
@@ -859,6 +945,11 @@ export async function createBrepkitPrimitives() {
859
945
  mirror(shape, point, normal) {
860
946
  return withKind(kindOf(shape), kernel.mirror(asNum(shape), point.x, point.y, point.z, normal.x, normal.y, normal.z));
861
947
  },
948
+ rotate(shape, axis, angleRad) {
949
+ // brepkit 无 rotate 原语 → 适配器组 Rodrigues 3×4 矩阵后走既有 cloneAndTransform
950
+ // (toKernelMatrix 仍是唯一方言转换点;与 translate/scale 同一条路径)。
951
+ return withKind(kindOf(shape), cloneAndTransform(asNum(shape), toKernelMatrix(rotationMatrix(axis.point, axis.direction, angleRad)), kindOf(shape)));
952
+ },
862
953
  // ── 阵列 ──
863
954
  // brepkit wasm 的 pattern 内核函数都返回 compound(含全部副本)→ 经 getCompoundSolids 拆成数组。
864
955
  linearPattern(shape, direction, spacing, count) {
@@ -937,6 +1028,90 @@ export async function createBrepkitPrimitives() {
937
1028
  knownEdges.add(e);
938
1029
  return asEdge(e);
939
1030
  },
1031
+ makeCircleArc(center, normal, radius, startAngle, endAngle) {
1032
+ // 方言消化:L1 吃 (圆心, 法向, 半径, 起止角);brepkit makeCircleArc3d 吃
1033
+ // (start, end, center, axis)。先在法向的垂直平面里建正交基 (u,v),
1034
+ // 起点/终点由角度算,axis 取归一化法向(右手:θ 增大绕 axis 逆时针)。
1035
+ const len = Math.hypot(normal.x, normal.y, normal.z);
1036
+ if (!(len > 0))
1037
+ fail('makeCircleArc: normal must be a non-zero vector');
1038
+ const n = { x: normal.x / len, y: normal.y / len, z: normal.z / len };
1039
+ let u;
1040
+ const ax = Math.abs(n.x);
1041
+ const ay = Math.abs(n.y);
1042
+ const az = Math.abs(n.z);
1043
+ if (ax <= ay && ax <= az)
1044
+ u = { x: 0, y: -n.z, z: n.y };
1045
+ else if (ay <= az)
1046
+ u = { x: -n.z, y: 0, z: n.x };
1047
+ else
1048
+ u = { x: n.y, y: -n.x, z: 0 };
1049
+ const ul = Math.hypot(u.x, u.y, u.z);
1050
+ u = { x: u.x / ul, y: u.y / ul, z: u.z / ul };
1051
+ const v = {
1052
+ x: n.y * u.z - n.z * u.y,
1053
+ y: n.z * u.x - n.x * u.z,
1054
+ z: n.x * u.y - n.y * u.x,
1055
+ };
1056
+ const at = (ang) => {
1057
+ const cs = Math.cos(ang) * radius;
1058
+ const sn = Math.sin(ang) * radius;
1059
+ return {
1060
+ x: center.x + u.x * cs + v.x * sn,
1061
+ y: center.y + u.y * cs + v.y * sn,
1062
+ z: center.z + u.z * cs + v.z * sn,
1063
+ };
1064
+ };
1065
+ const start = at(startAngle);
1066
+ const end = at(endAngle);
1067
+ const e = kernel.makeCircleArc3d(start.x, start.y, start.z, end.x, end.y, end.z, center.x, center.y, center.z, n.x, n.y, n.z);
1068
+ knownEdges.add(e);
1069
+ return asEdge(e);
1070
+ },
1071
+ makeHelixWire(origin, axis, pitch, height, radius, leftHanded) {
1072
+ // 左手显式失败:brepkit 无带手性螺旋原语,而采样拟合补镜像属「静默换算法」
1073
+ // (同 pitch/height/radius 下左右旋互为镜像,报错比悄悄换构造更安全)。
1074
+ // 这是**形参级**缺口:右手在 brepkit 上仍然可用,故 op 侧不声明 engines:['occt']
1075
+ // ——声明了会把右手一并拒掉。缺口在实现体内显式报错(同 extrude 拒绝非 face 输入)。
1076
+ if (leftHanded) {
1077
+ fail('makeHelixWire: left-handed helix requires the occt engine ' +
1078
+ '(brepkit has no handed helix primitive; no mirror fallback by design)');
1079
+ }
1080
+ // §7 决策点 2 选 (a):解析螺旋采样 → interpolatePoints 造 NURBS edge → makeWire。
1081
+ // brepkit 的 helicalSweep 是**扫掠成体**,不能用于 1D wire。
1082
+ // 偏差 = 采样弦高(近似,非解析),由 helix 一致性测试钉 band。
1083
+ const pts = sampleHelixPoints(origin, axis, pitch, height, radius);
1084
+ const degree = Math.min(3, pts.length - 1);
1085
+ const e = kernel.interpolatePoints(flattenPoints(pts), degree);
1086
+ knownEdges.add(e);
1087
+ const w = kernel.makeWire(Int32Array.from([e]), false);
1088
+ knownWires.add(w);
1089
+ return asWire(w);
1090
+ },
1091
+ approximatePoints(points, tolerance) {
1092
+ // 方言消化:L1 吃 (点列, 容差);brepkit approximateCurveLspia 还要
1093
+ // degree / num_control_points / max_iterations —— 由适配器给缺省
1094
+ // (degree 3 夹紧、numCps 取点数、迭代 100),容差直接落 tolerance。
1095
+ const n = points.length;
1096
+ if (n < 2)
1097
+ fail(`approximatePoints: need at least 2 points, got ${n}`);
1098
+ const degree = Math.max(1, Math.min(3, n - 1));
1099
+ const e = kernel.approximateCurveLspia(flattenPoints(points), degree, n, tolerance ?? 1e-2, 100);
1100
+ knownEdges.add(e);
1101
+ return asEdge(e);
1102
+ },
1103
+ interpolatePointsWithTangents(points, _startTangent, _endTangent) {
1104
+ // ⚠️ 退化实现(§7 决策点 3 选 (a)):brepkit 无「带端点切向约束的插值」原语,
1105
+ // 这里退化为普通 interpolatePoints(degree 3)—— **两端切向被丢弃**,端点
1106
+ // 斜率与 occt 的 GeomAPI_Interpolate(scale=True) 不同。这是有记录的近似
1107
+ // (HAND_MAP note + 偏差 band 双钉),不是静默降级。
1108
+ const n = points.length;
1109
+ if (n < 2)
1110
+ fail(`interpolatePointsWithTangents: need at least 2 points, got ${n}`);
1111
+ const e = kernel.interpolatePoints(flattenPoints(points), Math.min(3, n - 1));
1112
+ knownEdges.add(e);
1113
+ return asEdge(e);
1114
+ },
940
1115
  // ── 拓扑构造 ──
941
1116
  makeWire(edges) {
942
1117
  const w = kernel.makeWire(Int32Array.from(edges.map(asNum)), false);
@@ -952,18 +1127,13 @@ export async function createBrepkitPrimitives() {
952
1127
  const kids = arr(shapesList.map(asNum));
953
1128
  // GOTCHA(2026-09-26):brepkit makeCompound 只接受 **solid** 句柄——把 face/wire
954
1129
  // (sectionByPlane 截面面组)塞进去即抛 "invalid solid handle"。非实体子句柄时
955
- // 不调内核,改用高段虚拟句柄(0x20000000+,避开类型标签 bit26..28),仅靠 knownCompounds 表分发
956
- // meshShape/wireframe/getSubShapes/getBoundingBox,不触达内核。
957
- const hasNonSolid = kids.some((k) => knownFaces.has(k) || knownWires.has(k) || knownEdges.has(k) || knownCompounds.has(k));
958
- if (hasNonSolid) {
959
- virtualCompoundCounter++;
960
- const v = 0x20000000 + virtualCompoundCounter;
961
- knownCompounds.set(v, kids);
962
- return asHandle(v);
963
- }
964
- const c = kernel.makeCompound(Int32Array.from(kids));
965
- knownCompounds.set(c, kids);
966
- return asHandle(c);
1130
+ // 不调内核;且 compound 与 solid 分命名空间会**重号**(2026-10-13 实测成员 [0..4]
1131
+ // 的 compound 内核句柄 = 0),真句柄进 knownCompounds 会让同号 solid 查询误判。
1132
+ // 故**一律**走高段虚拟句柄(0x20000000+),仅靠 knownCompounds 表分发
1133
+ // meshShape/wireframe/getSubShapes/getBoundingBox,不触达内核;真内核句柄由
1134
+ // compoundOf 保留在 kernelCompoundHandles 供 exportStep 映射。分发逻辑与
1135
+ // cloneAndTransform 的 compound 分支共用 compoundOf(一份实现)。
1136
+ return asHandle(compoundOf(kids));
967
1137
  },
968
1138
  addHolesInFace(face, holeWires) {
969
1139
  // addHolesToFace 返回**新 face 句柄**(同曲面 + 内孔 wire),必须登记进 knownFaces,
@@ -977,6 +1147,13 @@ export async function createBrepkitPrimitives() {
977
1147
  knownFaces.add(f);
978
1148
  return asFace(f);
979
1149
  },
1150
+ makeNonPlanarFace(wire) {
1151
+ // brepkit 的 makeFaceFromWire 不区分平面/非平面(与 makeFace 同一原生),
1152
+ // 但 L1 保留独立中立名:occt 侧 makeFace 是平面路径,语义不同。
1153
+ const f = kernel.makeFaceFromWire(asNum(wire));
1154
+ knownFaces.add(f);
1155
+ return asFace(f);
1156
+ },
980
1157
  // ── 三角化(BREP→mesh 唯一出口) ──
981
1158
  meshShape(shape, options) {
982
1159
  const deflection = options?.linearDeflection ?? DEFAULT_LINEAR_DEFLECTION.as(mm);
@@ -1270,6 +1447,9 @@ export async function createBrepkitPrimitives() {
1270
1447
  return false;
1271
1448
  }
1272
1449
  },
1450
+ subShapeCount(shape, type) {
1451
+ return api.getSubShapes(shape, type).length;
1452
+ },
1273
1453
  shapeType(shape) {
1274
1454
  try {
1275
1455
  const s = arr(kernel.getSolidFaces(asNum(shape)));
@@ -1502,7 +1682,15 @@ export async function createBrepkitPrimitives() {
1502
1682
  },
1503
1683
  getSurfaceArea(shape) {
1504
1684
  // 方言映射:L1 getSurfaceArea ↔ brepkit surfaceArea(solid, deflection)。
1505
- return Number(kernel.surfaceArea(asNum(shape), 0.05));
1685
+ // ⚠️ brepkit 的 surfaceArea **只吃 solid**(传 face 报 `invalid solid handle:
1686
+ // index 0 is out of bounds`),而 L1 的语义锚(occt getSurfaceArea)也吃 face
1687
+ // —— gears / fasteners 大量对面调 getSurfaceArea。故 face 走 brepkit 原生
1688
+ // faceArea(同名不同参,属方言消化,不是静默降级)。
1689
+ const n = asNum(shape);
1690
+ // faceArea(face, deflection) —— deflection 与 surfaceArea 同一口径(0.05)。
1691
+ if (resolveKind(shape, n) === KIND_FACE)
1692
+ return Number(kernel.faceArea(n, 0.05));
1693
+ return Number(kernel.surfaceArea(n, 0.05));
1506
1694
  },
1507
1695
  getLength(shape) {
1508
1696
  // 唯一 edge 弧长之和(与 occt 适配器同口径,D5)。
@@ -1561,14 +1749,23 @@ export async function createBrepkitPrimitives() {
1561
1749
  const solids = arr(kernel.importStep(bytes));
1562
1750
  if (solids.length === 0)
1563
1751
  fail('importStep: kernel returned no solid');
1564
- const c = solids.length === 1 ? solids[0] : kernel.makeCompound(Uint32Array.from(solids));
1752
+ // 多实体 → compoundOf(虚拟句柄):compound 与 solid 分命名空间会重号,真句柄
1753
+ // 登记 knownCompounds 会在查询同号 solid 时误判(2026-10-13 修复,同 makeCompound)。
1754
+ // ⚠️ 每个成员 solid 必须先 markSolid:否则 buildCompoundTopologyRuntime 枚举成员面
1755
+ // (面号进 derivedFaces)后再 getSubShapes(member,'edge'),isFaceLike 会因成员号撞
1756
+ // 面号且不在 knownSolids 而误判 → getFaceEdges 只回一个面的 4 条边(faceCount=0,
1757
+ // edgeNaming.faces=null),真机选成员2 的边倒角报「no adjacent-face lineage」。
1565
1758
  if (solids.length > 1)
1566
- knownCompounds.set(c, solids);
1567
- return asHandle(markSolid(c));
1759
+ return asHandle(compoundOf(markSolids(solids)));
1760
+ return asHandle(markSolid(solids[0]));
1568
1761
  },
1569
1762
  exportStep(shape) {
1763
+ // 虚拟 compound(0x20000000+)需映射回真内核句柄——compound 与 solid 分命名空间,
1764
+ // 内核 exportStep 不认虚拟句柄(2026-10-13 compoundOf 虚拟化后补映射)。
1765
+ const s = asNum(shape);
1766
+ const real = kernelCompoundHandles.get(s) ?? s;
1570
1767
  // brepkit exportStep 返回 UTF-8 字节(Uint8Array),需解码为 STEP 文本(2026-09-19 实测)
1571
- const bytes = kernel.exportStep(asNum(shape));
1768
+ const bytes = kernel.exportStep(real);
1572
1769
  return typeof bytes === 'string' ? bytes : new TextDecoder().decode(bytes);
1573
1770
  },
1574
1771
  importStl(data) {
@@ -1634,6 +1831,88 @@ function translationMatrix(dx, dy, dz) {
1634
1831
  0, 0, 1, dz,
1635
1832
  ];
1636
1833
  }
1834
+ /**
1835
+ * 3×4 行主序旋转矩阵(绕**任意轴** axis={point,direction} 转 angleRad,右手)。
1836
+ *
1837
+ * 与 `engine-compat/harness.ts` 的 rotate 测试桩同算法(Rodrigues),保证 brepkit
1838
+ * 侧与 occt 侧 `rotate` 可对照:
1839
+ * R = I·cosθ + (d⊗d)(1−cosθ) + [d]×·sinθ ,平移 t = P − R·P(轴上的点不动)。
1840
+ */
1841
+ function rotationMatrix(point, direction, angleRad) {
1842
+ const len = Math.hypot(direction.x, direction.y, direction.z);
1843
+ if (!(len > 0))
1844
+ fail('rotate: axis direction must be a non-zero vector');
1845
+ const d = { x: direction.x / len, y: direction.y / len, z: direction.z / len };
1846
+ const c = Math.cos(angleRad);
1847
+ const s = Math.sin(angleRad);
1848
+ const t = 1 - c;
1849
+ const r00 = c + d.x * d.x * t;
1850
+ const r01 = d.x * d.y * t - d.z * s;
1851
+ const r02 = d.x * d.z * t + d.y * s;
1852
+ const r10 = d.x * d.y * t + d.z * s;
1853
+ const r11 = c + d.y * d.y * t;
1854
+ const r12 = d.y * d.z * t - d.x * s;
1855
+ const r20 = d.x * d.z * t - d.y * s;
1856
+ const r21 = d.y * d.z * t + d.x * s;
1857
+ const r22 = c + d.z * d.z * t;
1858
+ return [
1859
+ r00, r01, r02, point.x - (r00 * point.x + r01 * point.y + r02 * point.z),
1860
+ r10, r11, r12, point.y - (r10 * point.x + r11 * point.y + r12 * point.z),
1861
+ r20, r21, r22, point.z - (r20 * point.x + r21 * point.y + r22 * point.z),
1862
+ ];
1863
+ }
1864
+ /**
1865
+ * 右手圆柱螺旋线采样点(解析式,供 brepkit 侧 makeHelixWire 拟合用)。
1866
+ *
1867
+ * 参数化:θ ∈ [0, 2π·turns],turns = height / pitch;
1868
+ * P(θ) = origin + u·r·cosθ + v·r·sinθ + â·(pitch·θ / 2π)
1869
+ * 其中 (u, v, â) 是右手正交基,â = axis/|axis|。θ 到终点时沿轴推进量恰为 height。
1870
+ *
1871
+ * 段数按圈数取(每圈 `SEGMENTS_PER_TURN` 段,下限 8 段)—— 采样弦高即偏差来源,
1872
+ * 由 helix 一致性测试钉 band。
1873
+ */
1874
+ function sampleHelixPoints(origin, axis, pitch, height, radius, segmentsPerTurn = 36) {
1875
+ const len = Math.hypot(axis.x, axis.y, axis.z);
1876
+ if (!(len > 0))
1877
+ fail('makeHelixWire: axis must be a non-zero vector');
1878
+ if (!(pitch !== 0))
1879
+ fail('makeHelixWire: pitch must be non-zero');
1880
+ const a = { x: axis.x / len, y: axis.y / len, z: axis.z / len };
1881
+ // 与 makePlanarFaceTool(occt 侧)同一取轴策略:取分量绝对值最小的坐标构造正交基,
1882
+ // 避免 axis 轴对齐时退化。
1883
+ const ax = Math.abs(a.x);
1884
+ const ay = Math.abs(a.y);
1885
+ const az = Math.abs(a.z);
1886
+ let u;
1887
+ if (ax <= ay && ax <= az)
1888
+ u = { x: 0, y: -a.z, z: a.y };
1889
+ else if (ay <= az)
1890
+ u = { x: -a.z, y: 0, z: a.x };
1891
+ else
1892
+ u = { x: a.y, y: -a.x, z: 0 };
1893
+ const ul = Math.hypot(u.x, u.y, u.z);
1894
+ u = { x: u.x / ul, y: u.y / ul, z: u.z / ul };
1895
+ const v = {
1896
+ x: a.y * u.z - a.z * u.y,
1897
+ y: a.z * u.x - a.x * u.z,
1898
+ z: a.x * u.y - a.y * u.x,
1899
+ };
1900
+ const turns = height / pitch;
1901
+ const total = Math.max(8, Math.ceil(Math.abs(turns) * segmentsPerTurn));
1902
+ const out = [];
1903
+ for (let i = 0; i <= total; i++) {
1904
+ const th = (2 * Math.PI * turns * i) / total;
1905
+ const cs = Math.cos(th);
1906
+ const sn = Math.sin(th);
1907
+ const axial = (pitch * th) / (2 * Math.PI);
1908
+ out.push({
1909
+ x: origin.x + (u.x * cs + v.x * sn) * radius + a.x * axial,
1910
+ y: origin.y + (u.y * cs + v.y * sn) * radius + a.y * axial,
1911
+ z: origin.z + (u.z * cs + v.z * sn) * radius + a.z * axial,
1912
+ });
1913
+ }
1914
+ return out;
1915
+ }
1637
1916
  /** 3×4 行主序缩放矩阵(绕 center 缩放;faijs 接口方言,12 元素)。 */
1638
1917
  function scaleMatrix(center, factor) {
1639
1918
  return [
@@ -1679,7 +1958,7 @@ let memoizedKernel = null;
1679
1958
  *
1680
1959
  * @returns the live brepkit wasm kernel singleton.
1681
1960
  */
1682
- export function getBrepkitKernel() {
1961
+ export function getBrepKitKernel() {
1683
1962
  if (!liveKernel) {
1684
1963
  throw new Error('[brepkit-kernel] kernel not initialized: call createBrepkitPrimitives() first');
1685
1964
  }