@faicad/faijs 0.33.2 → 0.35.8

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 (429) 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/entities.js +14 -4
  9. package/dist/api/assembly/entities.js.map +1 -1
  10. package/dist/api/assembly/solve-tree.d.ts +1 -0
  11. package/dist/api/assembly/solve-tree.d.ts.map +1 -1
  12. package/dist/api/assembly/solve-tree.js +42 -17
  13. package/dist/api/assembly/solve-tree.js.map +1 -1
  14. package/dist/api/assembly/solve.d.ts +1 -0
  15. package/dist/api/assembly/solve.d.ts.map +1 -1
  16. package/dist/api/assembly/solve.js.map +1 -1
  17. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  18. package/dist/api/assembly/solvers/global-solver.js +130 -23
  19. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  20. package/dist/api/assembly/solvers/pose-from-delta.d.ts +9 -0
  21. package/dist/api/assembly/solvers/pose-from-delta.d.ts.map +1 -1
  22. package/dist/api/assembly/solvers/pose-from-delta.js +23 -0
  23. package/dist/api/assembly/solvers/pose-from-delta.js.map +1 -1
  24. package/dist/api/assembly/solvers/types.d.ts +20 -2
  25. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  26. package/dist/api/assembly/solvers/types.js.map +1 -1
  27. package/dist/api/chamfer.d.ts +7 -4
  28. package/dist/api/chamfer.d.ts.map +1 -1
  29. package/dist/api/chamfer.js +57 -13
  30. package/dist/api/chamfer.js.map +1 -1
  31. package/dist/api/draft.d.ts +7 -4
  32. package/dist/api/draft.d.ts.map +1 -1
  33. package/dist/api/draft.js +11 -6
  34. package/dist/api/draft.js.map +1 -1
  35. package/dist/api/edge-ref.d.ts +4 -4
  36. package/dist/api/edge-ref.js +4 -4
  37. package/dist/api/edge-ref.js.map +1 -1
  38. package/dist/api/extrude.d.ts +10 -6
  39. package/dist/api/extrude.d.ts.map +1 -1
  40. package/dist/api/extrude.js +54 -26
  41. package/dist/api/extrude.js.map +1 -1
  42. package/dist/api/face-ref.d.ts +4 -4
  43. package/dist/api/face-ref.js +4 -4
  44. package/dist/api/face-ref.js.map +1 -1
  45. package/dist/api/feature-repair.d.ts +6 -3
  46. package/dist/api/feature-repair.d.ts.map +1 -1
  47. package/dist/api/feature-repair.js +12 -7
  48. package/dist/api/feature-repair.js.map +1 -1
  49. package/dist/api/fillet-variable.d.ts +6 -2
  50. package/dist/api/fillet-variable.d.ts.map +1 -1
  51. package/dist/api/fillet-variable.js +24 -6
  52. package/dist/api/fillet-variable.js.map +1 -1
  53. package/dist/api/fillet.d.ts +7 -4
  54. package/dist/api/fillet.d.ts.map +1 -1
  55. package/dist/api/fillet.js +92 -12
  56. package/dist/api/fillet.js.map +1 -1
  57. package/dist/api/generated/script-face-manifest.js +1 -1
  58. package/dist/api/generated/script-face-manifest.js.map +1 -1
  59. package/dist/api/generated/topology.js +1 -1
  60. package/dist/api/generated/topology.js.map +1 -1
  61. package/dist/api/helix.d.ts +13 -13
  62. package/dist/api/helix.d.ts.map +1 -1
  63. package/dist/api/helix.js +19 -24
  64. package/dist/api/helix.js.map +1 -1
  65. package/dist/api/import-brep.d.ts +10 -18
  66. package/dist/api/import-brep.d.ts.map +1 -1
  67. package/dist/api/import-brep.js +17 -25
  68. package/dist/api/import-brep.js.map +1 -1
  69. package/dist/api/import-step.d.ts +10 -15
  70. package/dist/api/import-step.d.ts.map +1 -1
  71. package/dist/api/import-step.js +24 -29
  72. package/dist/api/import-step.js.map +1 -1
  73. package/dist/api/index.js +2 -2
  74. package/dist/api/index.js.map +1 -1
  75. package/dist/api/internal/export-members.js.map +1 -1
  76. package/dist/api/loft-advanced.d.ts +4 -0
  77. package/dist/api/loft-advanced.d.ts.map +1 -1
  78. package/dist/api/loft-advanced.js +4 -0
  79. package/dist/api/loft-advanced.js.map +1 -1
  80. package/dist/api/loft.d.ts +5 -3
  81. package/dist/api/loft.d.ts.map +1 -1
  82. package/dist/api/loft.js +5 -3
  83. package/dist/api/loft.js.map +1 -1
  84. package/dist/api/meta.d.ts +42 -6
  85. package/dist/api/meta.d.ts.map +1 -1
  86. package/dist/api/meta.js.map +1 -1
  87. package/dist/api/primitives.d.ts +3 -2
  88. package/dist/api/primitives.d.ts.map +1 -1
  89. package/dist/api/primitives.js +3 -2
  90. package/dist/api/primitives.js.map +1 -1
  91. package/dist/api/punch-hole.d.ts +5 -2
  92. package/dist/api/punch-hole.d.ts.map +1 -1
  93. package/dist/api/punch-hole.js +4 -1
  94. package/dist/api/punch-hole.js.map +1 -1
  95. package/dist/api/replicate.d.ts +4 -5
  96. package/dist/api/replicate.d.ts.map +1 -1
  97. package/dist/api/replicate.js +4 -5
  98. package/dist/api/replicate.js.map +1 -1
  99. package/dist/api/selectors-to-refs.d.ts +83 -0
  100. package/dist/api/selectors-to-refs.d.ts.map +1 -0
  101. package/dist/api/selectors-to-refs.js +211 -0
  102. package/dist/api/selectors-to-refs.js.map +1 -0
  103. package/dist/api/shell.d.ts +17 -8
  104. package/dist/api/shell.d.ts.map +1 -1
  105. package/dist/api/shell.js +45 -15
  106. package/dist/api/shell.js.map +1 -1
  107. package/dist/api/sketch-on-face.d.ts +12 -6
  108. package/dist/api/sketch-on-face.d.ts.map +1 -1
  109. package/dist/api/sketch-on-face.js +31 -4
  110. package/dist/api/sketch-on-face.js.map +1 -1
  111. package/dist/api/sketch-on-plane.d.ts +3 -0
  112. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  113. package/dist/api/sketch-on-plane.js +3 -0
  114. package/dist/api/sketch-on-plane.js.map +1 -1
  115. package/dist/api/sketch-on-surface.d.ts +4 -1
  116. package/dist/api/sketch-on-surface.d.ts.map +1 -1
  117. package/dist/api/sketch-on-surface.js +4 -1
  118. package/dist/api/sketch-on-surface.js.map +1 -1
  119. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  120. package/dist/api/surface/arg-spec.js +5 -6
  121. package/dist/api/surface/arg-spec.js.map +1 -1
  122. package/dist/api/topo-resolve.d.ts.map +1 -1
  123. package/dist/api/topo-resolve.js +24 -5
  124. package/dist/api/topo-resolve.js.map +1 -1
  125. package/dist/api/view/view-projection.d.ts.map +1 -1
  126. package/dist/api/view/view-projection.js +9 -2
  127. package/dist/api/view/view-projection.js.map +1 -1
  128. package/dist/brep/brep-chain.js +2 -2
  129. package/dist/brep/brep-chain.js.map +1 -1
  130. package/dist/brep/brep-ops.d.ts +1 -1
  131. package/dist/brep/brep-ops.js +1 -1
  132. package/dist/brep/brep-ops.js.map +1 -1
  133. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  134. package/dist/brep/engine/adapters/brep-mock.js +45 -0
  135. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  136. package/dist/brep/engine/primitives.d.ts +87 -3
  137. package/dist/brep/engine/primitives.d.ts.map +1 -1
  138. package/dist/brep/engine/primitives.js +1 -1
  139. package/dist/brep/engine/primitives.js.map +1 -1
  140. package/dist/brep/engine/registry.d.ts +33 -7
  141. package/dist/brep/engine/registry.d.ts.map +1 -1
  142. package/dist/brep/engine/registry.js +47 -16
  143. package/dist/brep/engine/registry.js.map +1 -1
  144. package/dist/brep/handle-bridge.d.ts +14 -15
  145. package/dist/brep/handle-bridge.d.ts.map +1 -1
  146. package/dist/brep/handle-bridge.js +35 -15
  147. package/dist/brep/handle-bridge.js.map +1 -1
  148. package/dist/brep/primitives-brep.js +2 -2
  149. package/dist/brep/primitives-brep.js.map +1 -1
  150. package/dist/brep/text/text-to-solid.d.ts +40 -3
  151. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  152. package/dist/brep/text/text-to-solid.js +104 -24
  153. package/dist/brep/text/text-to-solid.js.map +1 -1
  154. package/dist/brepkit-kernel/brepkitKernel.d.ts +2 -2
  155. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  156. package/dist/brepkit-kernel/brepkitKernel.js +328 -38
  157. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  158. package/dist/brepkit-kernel/brepkitWasm.d.ts +3 -1
  159. package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
  160. package/dist/brepkit-kernel/brepkitWasm.js +13 -9
  161. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  162. package/dist/brepkit-kernel/multi-version-test.d.ts +2 -2
  163. package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
  164. package/dist/brepkit-kernel/multi-version-test.js +6 -6
  165. package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
  166. package/dist/browser.d.ts +2 -3
  167. package/dist/browser.d.ts.map +1 -1
  168. package/dist/browser.js +1 -2
  169. package/dist/browser.js.map +1 -1
  170. package/dist/cad-runtime/admit-compat-lib.d.ts +9 -1
  171. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  172. package/dist/cad-runtime/admit-compat-lib.js +11 -1
  173. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  174. package/dist/cad-runtime/browser-lib-loader.d.ts +16 -11
  175. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  176. package/dist/cad-runtime/browser-lib-loader.js +16 -8
  177. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  178. package/dist/cad-runtime/direct-executor.d.ts +62 -5
  179. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  180. package/dist/cad-runtime/direct-executor.js +617 -42
  181. package/dist/cad-runtime/direct-executor.js.map +1 -1
  182. package/dist/cad-runtime/interp/closure.d.ts +3 -2
  183. package/dist/cad-runtime/interp/closure.d.ts.map +1 -1
  184. package/dist/cad-runtime/interp/closure.js.map +1 -1
  185. package/dist/cad-runtime/interp/env.d.ts +9 -6
  186. package/dist/cad-runtime/interp/env.d.ts.map +1 -1
  187. package/dist/cad-runtime/interp/env.js +4 -2
  188. package/dist/cad-runtime/interp/env.js.map +1 -1
  189. package/dist/cad-runtime/lib-decl.d.ts +121 -0
  190. package/dist/cad-runtime/lib-decl.d.ts.map +1 -0
  191. package/dist/cad-runtime/lib-decl.js +100 -0
  192. package/dist/cad-runtime/lib-decl.js.map +1 -0
  193. package/dist/cad-runtime/ports.d.ts +12 -0
  194. package/dist/cad-runtime/ports.d.ts.map +1 -1
  195. package/dist/cad-runtime/ports.js.map +1 -1
  196. package/dist/cad-runtime/runtime.d.ts +59 -5
  197. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  198. package/dist/cad-runtime/runtime.js +252 -20
  199. package/dist/cad-runtime/runtime.js.map +1 -1
  200. package/dist/extra/browser.d.ts +9 -0
  201. package/dist/extra/browser.d.ts.map +1 -0
  202. package/dist/extra/browser.js +9 -0
  203. package/dist/extra/browser.js.map +1 -0
  204. package/dist/extra/editor-ops.d.ts +22 -0
  205. package/dist/extra/editor-ops.d.ts.map +1 -0
  206. package/dist/extra/editor-ops.js +21 -0
  207. package/dist/extra/editor-ops.js.map +1 -0
  208. package/dist/extra/extras/svg-extrude.d.ts +45 -0
  209. package/dist/extra/extras/svg-extrude.d.ts.map +1 -0
  210. package/dist/extra/extras/svg-extrude.js +110 -0
  211. package/dist/extra/extras/svg-extrude.js.map +1 -0
  212. package/dist/extra/extras/text-cjk.d.ts +36 -0
  213. package/dist/extra/extras/text-cjk.d.ts.map +1 -0
  214. package/dist/extra/extras/text-cjk.js +86 -0
  215. package/dist/extra/extras/text-cjk.js.map +1 -0
  216. package/dist/extra/extras/text-geometry.d.ts +69 -0
  217. package/dist/extra/extras/text-geometry.d.ts.map +1 -0
  218. package/dist/extra/extras/text-geometry.js +188 -0
  219. package/dist/extra/extras/text-geometry.js.map +1 -0
  220. package/dist/extra/index.d.ts +40 -0
  221. package/dist/extra/index.d.ts.map +1 -0
  222. package/dist/extra/index.js +40 -0
  223. package/dist/extra/index.js.map +1 -0
  224. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts +94 -0
  225. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts.map +1 -0
  226. package/dist/extra/mesh/drill-hole/DrillHoleCore.js +282 -0
  227. package/dist/extra/mesh/drill-hole/DrillHoleCore.js.map +1 -0
  228. package/dist/extra/mesh/drill-hole/drill-types.d.ts +34 -0
  229. package/dist/extra/mesh/drill-hole/drill-types.d.ts.map +1 -0
  230. package/dist/extra/mesh/drill-hole/drill-types.js +7 -0
  231. package/dist/extra/mesh/drill-hole/drill-types.js.map +1 -0
  232. package/dist/extra/mesh/engrave-decoration.d.ts +42 -0
  233. package/dist/extra/mesh/engrave-decoration.d.ts.map +1 -0
  234. package/dist/extra/mesh/engrave-decoration.js +39 -0
  235. package/dist/extra/mesh/engrave-decoration.js.map +1 -0
  236. package/dist/extra/mesh/fai_drill.d.ts +21 -0
  237. package/dist/extra/mesh/fai_drill.d.ts.map +1 -0
  238. package/dist/extra/mesh/fai_drill.js +89 -0
  239. package/dist/extra/mesh/fai_drill.js.map +1 -0
  240. package/dist/extra/mesh/fai_extrude.d.ts +24 -0
  241. package/dist/extra/mesh/fai_extrude.d.ts.map +1 -0
  242. package/dist/extra/mesh/fai_extrude.js +42 -0
  243. package/dist/extra/mesh/fai_extrude.js.map +1 -0
  244. package/dist/extra/mesh/fai_split.d.ts +164 -0
  245. package/dist/extra/mesh/fai_split.d.ts.map +1 -0
  246. package/dist/extra/mesh/fai_split.js +269 -0
  247. package/dist/extra/mesh/fai_split.js.map +1 -0
  248. package/dist/extra/mesh/primitives.d.ts +29 -0
  249. package/dist/extra/mesh/primitives.d.ts.map +1 -0
  250. package/dist/extra/mesh/primitives.js +41 -0
  251. package/dist/extra/mesh/primitives.js.map +1 -0
  252. package/dist/extra/op-names.d.ts +37 -0
  253. package/dist/extra/op-names.d.ts.map +1 -0
  254. package/dist/extra/op-names.js +46 -0
  255. package/dist/extra/op-names.js.map +1 -0
  256. package/dist/extra/ops/compound.d.ts +140 -0
  257. package/dist/extra/ops/compound.d.ts.map +1 -0
  258. package/dist/extra/ops/compound.js +167 -0
  259. package/dist/extra/ops/compound.js.map +1 -0
  260. package/dist/extra/ops/copy.d.ts +40 -0
  261. package/dist/extra/ops/copy.d.ts.map +1 -0
  262. package/dist/extra/ops/copy.js +83 -0
  263. package/dist/extra/ops/copy.js.map +1 -0
  264. package/dist/extra/ops/fai_drill.d.ts +51 -0
  265. package/dist/extra/ops/fai_drill.d.ts.map +1 -0
  266. package/dist/extra/ops/fai_drill.js +233 -0
  267. package/dist/extra/ops/fai_drill.js.map +1 -0
  268. package/dist/extra/ops/fai_extrude.d.ts +36 -0
  269. package/dist/extra/ops/fai_extrude.d.ts.map +1 -0
  270. package/dist/extra/ops/fai_extrude.js +84 -0
  271. package/dist/extra/ops/fai_extrude.js.map +1 -0
  272. package/dist/extra/ops/fai_split.d.ts +46 -0
  273. package/dist/extra/ops/fai_split.d.ts.map +1 -0
  274. package/dist/extra/ops/fai_split.js +235 -0
  275. package/dist/extra/ops/fai_split.js.map +1 -0
  276. package/dist/extra/ops/load.d.ts +49 -0
  277. package/dist/extra/ops/load.d.ts.map +1 -0
  278. package/dist/extra/ops/load.js +423 -0
  279. package/dist/extra/ops/load.js.map +1 -0
  280. package/dist/extra/ops/svg-extrude.d.ts +32 -0
  281. package/dist/extra/ops/svg-extrude.d.ts.map +1 -0
  282. package/dist/extra/ops/svg-extrude.js +74 -0
  283. package/dist/extra/ops/svg-extrude.js.map +1 -0
  284. package/dist/extra/ops/text.d.ts +34 -0
  285. package/dist/extra/ops/text.d.ts.map +1 -0
  286. package/dist/extra/ops/text.js +100 -0
  287. package/dist/extra/ops/text.js.map +1 -0
  288. package/dist/geometry2d/bridge/lift-on-plane.d.ts +8 -5
  289. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  290. package/dist/geometry2d/bridge/lift-on-plane.js +8 -5
  291. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  292. package/dist/index.d.ts +6 -2
  293. package/dist/index.d.ts.map +1 -1
  294. package/dist/index.js +8 -2
  295. package/dist/index.js.map +1 -1
  296. package/dist/lang/symbol-table.d.ts +3 -3
  297. package/dist/lang/symbol-table.generated.d.ts +10 -0
  298. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  299. package/dist/lang/symbol-table.generated.js +10 -0
  300. package/dist/lang/symbol-table.generated.js.map +1 -1
  301. package/dist/lang/symbol-table.js +3 -3
  302. package/dist/lang/symbol-table.js.map +1 -1
  303. package/dist/math3d/index.d.ts +1 -1
  304. package/dist/math3d/index.js +1 -1
  305. package/dist/math3d/index.js.map +1 -1
  306. package/dist/mesh/engrave.d.ts +2 -3
  307. package/dist/mesh/engrave.d.ts.map +1 -1
  308. package/dist/mesh/engrave.js +4 -11
  309. package/dist/mesh/engrave.js.map +1 -1
  310. package/dist/mesh/index.d.ts +0 -2
  311. package/dist/mesh/index.d.ts.map +1 -1
  312. package/dist/mesh/index.js +0 -2
  313. package/dist/mesh/index.js.map +1 -1
  314. package/dist/mesh/primitives.d.ts +7 -5
  315. package/dist/mesh/primitives.d.ts.map +1 -1
  316. package/dist/mesh/primitives.js +16 -9
  317. package/dist/mesh/primitives.js.map +1 -1
  318. package/dist/mesh/types.d.ts +4 -3
  319. package/dist/mesh/types.d.ts.map +1 -1
  320. package/dist/mesh/types.js.map +1 -1
  321. package/dist/node-host/cli.d.ts +11 -4
  322. package/dist/node-host/cli.d.ts.map +1 -1
  323. package/dist/node-host/cli.js +53 -28
  324. package/dist/node-host/cli.js.map +1 -1
  325. package/dist/node-host/execute-script.d.ts.map +1 -1
  326. package/dist/node-host/execute-script.js +3 -4
  327. package/dist/node-host/execute-script.js.map +1 -1
  328. package/dist/node-host/lib-package-json.d.ts +36 -0
  329. package/dist/node-host/lib-package-json.d.ts.map +1 -0
  330. package/dist/node-host/lib-package-json.js +73 -0
  331. package/dist/node-host/lib-package-json.js.map +1 -0
  332. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  333. package/dist/occt-kernel/occt-primitives.js +41 -0
  334. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  335. package/dist/occt-kernel/occtKernel.d.ts +1 -1
  336. package/dist/occt-kernel/occtKernel.js +1 -1
  337. package/dist/occt-kernel/occtKernel.js.map +1 -1
  338. package/dist/primitives/brep-primitives.d.ts.map +1 -1
  339. package/dist/primitives/brep-primitives.js +39 -12
  340. package/dist/primitives/brep-primitives.js.map +1 -1
  341. package/dist/runtime-state.d.ts +28 -1
  342. package/dist/runtime-state.d.ts.map +1 -1
  343. package/dist/runtime-state.js +14 -1
  344. package/dist/runtime-state.js.map +1 -1
  345. package/dist/sdk.d.ts +2 -2
  346. package/dist/sdk.d.ts.map +1 -1
  347. package/dist/sdk.js +11 -2
  348. package/dist/sdk.js.map +1 -1
  349. package/dist/sketch/bspline.d.ts +58 -0
  350. package/dist/sketch/bspline.d.ts.map +1 -0
  351. package/dist/sketch/bspline.js +104 -0
  352. package/dist/sketch/bspline.js.map +1 -0
  353. package/dist/sketch/canonical.d.ts +239 -0
  354. package/dist/sketch/canonical.d.ts.map +1 -0
  355. package/dist/sketch/canonical.js +17 -0
  356. package/dist/sketch/canonical.js.map +1 -0
  357. package/dist/sketch/contour.d.ts +43 -0
  358. package/dist/sketch/contour.d.ts.map +1 -0
  359. package/dist/sketch/contour.js +202 -0
  360. package/dist/sketch/contour.js.map +1 -0
  361. package/dist/sketch/dim-spec.d.ts +32 -0
  362. package/dist/sketch/dim-spec.d.ts.map +1 -0
  363. package/dist/sketch/dim-spec.js +112 -0
  364. package/dist/sketch/dim-spec.js.map +1 -0
  365. package/dist/sketch/faces.d.ts +45 -0
  366. package/dist/sketch/faces.d.ts.map +1 -0
  367. package/dist/sketch/faces.js +108 -0
  368. package/dist/sketch/faces.js.map +1 -0
  369. package/dist/sketch/fcstd-types.d.ts +194 -0
  370. package/dist/sketch/fcstd-types.d.ts.map +1 -0
  371. package/dist/sketch/fcstd-types.js +67 -0
  372. package/dist/sketch/fcstd-types.js.map +1 -0
  373. package/dist/sketch/index.d.ts +46 -0
  374. package/dist/sketch/index.d.ts.map +1 -0
  375. package/dist/sketch/index.js +39 -0
  376. package/dist/sketch/index.js.map +1 -0
  377. package/dist/sketch/node.d.ts +14 -0
  378. package/dist/sketch/node.d.ts.map +1 -0
  379. package/dist/sketch/node.js +43 -0
  380. package/dist/sketch/node.js.map +1 -0
  381. package/dist/sketch/op.d.ts +111 -0
  382. package/dist/sketch/op.d.ts.map +1 -0
  383. package/dist/sketch/op.js +185 -0
  384. package/dist/sketch/op.js.map +1 -0
  385. package/dist/sketch/planegcs-backend.d.ts +69 -0
  386. package/dist/sketch/planegcs-backend.d.ts.map +1 -0
  387. package/dist/sketch/planegcs-backend.js +812 -0
  388. package/dist/sketch/planegcs-backend.js.map +1 -0
  389. package/dist/sketch/project.d.ts +176 -0
  390. package/dist/sketch/project.d.ts.map +1 -0
  391. package/dist/sketch/project.js +656 -0
  392. package/dist/sketch/project.js.map +1 -0
  393. package/dist/sketch/shapes.d.ts +370 -0
  394. package/dist/sketch/shapes.d.ts.map +1 -0
  395. package/dist/sketch/shapes.js +959 -0
  396. package/dist/sketch/shapes.js.map +1 -0
  397. package/dist/sketch/solve.d.ts +21 -0
  398. package/dist/sketch/solve.d.ts.map +1 -0
  399. package/dist/sketch/solve.js +144 -0
  400. package/dist/sketch/solve.js.map +1 -0
  401. package/dist/sketch/solver-loader.d.ts +47 -0
  402. package/dist/sketch/solver-loader.d.ts.map +1 -0
  403. package/dist/sketch/solver-loader.js +77 -0
  404. package/dist/sketch/solver-loader.js.map +1 -0
  405. package/dist/sketch/solver.d.ts +63 -0
  406. package/dist/sketch/solver.d.ts.map +1 -0
  407. package/dist/sketch/solver.js +28 -0
  408. package/dist/sketch/solver.js.map +1 -0
  409. package/dist/sketch/verify.d.ts +53 -0
  410. package/dist/sketch/verify.d.ts.map +1 -0
  411. package/dist/sketch/verify.js +71 -0
  412. package/dist/sketch/verify.js.map +1 -0
  413. package/dist/topology/naming/geom-hint.d.ts +12 -0
  414. package/dist/topology/naming/geom-hint.d.ts.map +1 -1
  415. package/dist/topology/naming/geom-hint.js +1 -1
  416. package/dist/topology/naming/geom-hint.js.map +1 -1
  417. package/dist/topology/naming/lineage.d.ts +1 -0
  418. package/dist/topology/naming/lineage.d.ts.map +1 -1
  419. package/dist/topology/naming/lineage.js +37 -1
  420. package/dist/topology/naming/lineage.js.map +1 -1
  421. package/dist/topology/naming/resolve-face.d.ts +13 -2
  422. package/dist/topology/naming/resolve-face.d.ts.map +1 -1
  423. package/dist/topology/naming/resolve-face.js +18 -2
  424. package/dist/topology/naming/resolve-face.js.map +1 -1
  425. package/dist/weapp.d.ts +1 -1
  426. package/dist/weapp.d.ts.map +1 -1
  427. package/dist/weapp.js +1 -1
  428. package/dist/weapp.js.map +1 -1
  429. package/package.json +43 -11
@@ -1 +1 @@
1
- {"version":3,"file":"topo-resolve.d.ts","sourceRoot":"","sources":["../../src/api/topo-resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAG1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAItD,OAAO,EAAY,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAML,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAEtB,KAAK,QAAQ,EAEb,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAA;AAE3B,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,8CAA8C;IAC9C,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AA2CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAmB9C;AA+DD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,aAAa,GAAG,IAAI,EAC5B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CAsB/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CA0C/B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CAc/B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CAQ/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,SAAS,CAAC,EAAE,SAAS,GACpB,iBAAiB,CAyBnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,GAAG,IAAI,EAC5B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,WAAW,GACf,oBAAoB,CAoDtB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAE1D"}
1
+ {"version":3,"file":"topo-resolve.d.ts","sourceRoot":"","sources":["../../src/api/topo-resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAG1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAItD,OAAO,EAAY,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAOL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAEtB,KAAK,QAAQ,EAEb,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAA;AAE3B,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,8CAA8C;IAC9C,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AA2CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAmB9C;AA+DD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,aAAa,GAAG,IAAI,EAC5B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CA+B/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CA0C/B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CAc/B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,iBAAiB,GAAG,SAAS,CAQ/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,SAAS,CAAC,EAAE,SAAS,GACpB,iBAAiB,CAyBnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,GAAG,IAAI,EAC5B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,WAAW,GACf,oBAAoB,CA8DtB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAE1D"}
@@ -18,7 +18,7 @@ import { HASH_UPPER_BOUND } from '../brep/face-evolution.js';
18
18
  import { runtimeLineage, isHashEvolution } from '../topology/naming/lineage.js';
19
19
  import { resolveViaLineage } from '../topology/naming/lineage-resolve.js';
20
20
  import { asStmtId } from '../identity.js';
21
- import { resolveTopoRef, captureFaceHint, captureEdgeHint, faceRowToHint, TopoRefError, } from '../topology/naming/index.js';
21
+ import { resolveTopoRef, captureFaceHint, captureCylinderFaceAxis, captureEdgeHint, faceRowToHint, TopoRefError, } from '../topology/naming/index.js';
22
22
  /**
23
23
  * roleTable miss 时沿血缘回走重算(1.10 前置③:缓存降级)。
24
24
  *
@@ -199,7 +199,16 @@ export function buildShapeResolutionContext(kernel, shape) {
199
199
  if (kernel && solid !== undefined) {
200
200
  const handles = kernel.getSubShapes(solid, 'face');
201
201
  const hashes = Array.from(kernel.subShapeHashes(solid, 'face', HASH_UPPER_BOUND));
202
- const faces = handles.map((handle, i) => ({ ordinal: i + 1, hash: hashes[i] ?? 0, handle }));
202
+ // 行 hint 快照同带(§3.6):brepkit 的 uvBounds 对平面返回 ±1e6 哨兵,
203
+ // kernel 现场的 surfaceCenterOfMass 退化成参数原点求值——center 错(法向
204
+ // 碰巧对,因为平面法向在参数域是常数)→ 非居中模型上兜底打分全拒 →
205
+ // `topo ref (face) not found`。故打分与 exact 后取几何一律 row 优先
206
+ // (toScoringCandidate / 本文件 resolveFaceGeometry)。
207
+ // 序号同序:TopExp 枚举序 ↔ FaceRow 的 o1.fN(FaceCandidateEntry.ordinal
208
+ // 注释即此约定),2026-10-16 实测逐字一致。handle 仍保留——exact 命中后
209
+ // 要回传活句柄给调用方(resolver.ts 的 entity.handle)。
210
+ const rows = slot.faceHints;
211
+ const faces = handles.map((handle, i) => ({ ordinal: i + 1, hash: hashes[i] ?? 0, handle, row: rows?.[i] }));
203
212
  return { kernel, faces, roleTable };
204
213
  }
205
214
  const hints = slot.faceHints;
@@ -403,8 +412,10 @@ export function resolveFaceGeometry(kernel, shape, ref) {
403
412
  if (!entry) {
404
413
  throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `resolved ordinal ${entity.ordinal} has no candidate in context (origin=${ref.origin}, role=${ref.role})`);
405
414
  }
406
- // BREAK 现场:capture 出当前法向/中心(圆柱面含轴)
407
- if (entry.handle && ctx.kernel) {
415
+ // 行快照优先:与打分同口径(toScoringCandidate),同帧且几何正确——
416
+ // brepkit 的 kernel 现场 center 会退化(uvBounds ±1e6 哨兵 → 参数原点求值),
417
+ // 2026-10-16 实测非居中盒上 `[20,20,0]` 退化成 `[0,0,0]`。
418
+ if (entry.row === undefined && entry.handle && ctx.kernel) {
408
419
  const hint = captureFaceHint(ctx.kernel, entry.handle);
409
420
  return {
410
421
  surfaceType: hint.surfaceType,
@@ -416,11 +427,19 @@ export function resolveFaceGeometry(kernel, shape, ref) {
416
427
  // mesh/行快照:直接用行几何(axis 由宿主行注入,缺省 undefined)
417
428
  const ext = entry.row;
418
429
  const hint = ext ? faceRowToHint(ext) : undefined;
430
+ // 圆柱轴补采:行快照不带 axis,而圆柱的轴一向现场采(captureFaceHint 的
431
+ // cylinder 分支)——它由 pointOnSurface + getFaceCylinderData 量出,**不经
432
+ // 过退化的 surfaceCenterOfMass**,现场值可靠。故 row 优先只管 center/normal,
433
+ // 圆柱轴缺行值时补采,守住 P0①(圆柱侧壁 hint 含 axis)。
434
+ let axis = hint?.axis;
435
+ if (axis === undefined && hint?.surfaceType === 'cylinder' && entry.handle && ctx.kernel) {
436
+ axis = captureCylinderFaceAxis(ctx.kernel, entry.handle);
437
+ }
419
438
  return {
420
439
  surfaceType: hint?.surfaceType,
421
440
  center: hint?.center ?? [0, 0, 0],
422
441
  normal: hint?.normal ?? [0, 0, 1],
423
- ...(hint?.axis ? { axis: hint.axis } : {}),
442
+ ...(axis ? { axis } : {}),
424
443
  };
425
444
  }
426
445
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"topo-resolve.js","sourceRoot":"","sources":["../../src/api/topo-resolve.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * topo-resolve — 运行期 TopoRef 解析(装配/钻孔等面引用 op 共享,§6.2)\n *\n * 与 core/topology/naming 的分工:\n * - naming(core)负责纯解析:给 ReactsContext + FaceTopoRef → ordinal/handle;\n * - 本模块(api 层)是「活 Shape → React块(ResolutionContext)」的引擎胶水:\n * 从 Shape 身份槽读出运行期数据(BREP 活句柄 + RoleTable,或 setTopology 注入的\n * 面 hint 快照),并把解析结果还原成求解需要的几何(center/normal/surfaceType)。\n *\n * 这样 drill(面 → 法向)与 compound/assembly(约束固定/移动面 → 几何)共用同一\n * 条「TopoRef 执行期派生」通道,且不动 core 的纯 naming 层职责。\n *\n * 任何一步定不了案 → 抛 TopoRefError(三态错误码),绝不静默拿序号硬取。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { getSlot } from '../shape'\nimport { nameOf } from '../runtime-state'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { HASH_UPPER_BOUND } from '../brep/face-evolution'\nimport { runtimeLineage, isHashEvolution } from '../topology/naming/lineage'\nimport { resolveViaLineage } from '../topology/naming/lineage-resolve'\nimport { asStmtId, type PartName, type StmtId } from '../identity'\nimport {\n resolveTopoRef,\n captureFaceHint,\n captureEdgeHint,\n faceRowToHint,\n TopoRefError,\n type FaceTopoRef,\n type ResolutionContext,\n type FaceHint,\n type AxisHint,\n type EdgeCandidateEntry,\n type RoleTable,\n} from '../topology/naming'\n\n/** 求解面需要的当前几何(执行期派生):与旧契约 fixedFace/movingFace 的 surfaceType/center/normal 同形。 */\nexport interface ResolvedFaceGeometry {\n surfaceType?: string\n center: [number, number, number]\n normal: [number, number, number]\n /** 圆柱/回转面的轴(装配轴约束用;平面/球面缺省,mesh 行快照由宿主注入)。 */\n axis?: AxisHint\n}\n\n/**\n * roleTable miss 时沿血缘回走重算(1.10 前置③:缓存降级)。\n *\n * 「产物上的 roleTable 不再是身份的唯一来源」的落点:精确解析读不到\n * `roleTable[origin][role]` 时,按血缘 DAG 从 origin 语句回走推进到当前 part,\n * 产出该 role 的 hash 集合并**回填缓存**——miss 可恢复,不再是无名错误。\n * 回走失败(链断 / 无演化)返回 undefined,调用方落到几何兜底(既有三态语义不变)。\n *\n * @param ref - the face TopoRef being resolved.\n * @param shape - the live part shape being resolved against.\n * @param kernel - the OCCT kernel (hash 换算需要;null 时回走不可用).\n * @returns the recomputed hash list, or undefined when lineage re-walk cannot produce one.\n */\nfunction recomputeViaLineage(\n ref: FaceTopoRef,\n shape: object,\n kernel: BrepEngineApi | null,\n): readonly number[] | undefined {\n if (!kernel) return undefined\n const part = nameOf(shape)\n if (!part) return undefined\n const result = resolveViaLineage(runtimeLineage, asStmtId(ref.origin), ref.role, part, {\n // 回走链上的中间产物句柄:优先血缘图旁挂(本仓 op 执行时记录),\n // 兜底读 runtime 全局 nameOf 反查(slot.solid)。\n brepOf: (p) => {\n const stmt = runtimeLineage.stmtOf(p)\n const h = stmt ? runtimeLineage.outputHandleOf(stmt) : undefined\n if (h !== undefined) return h\n return undefined\n },\n faceHashes: (handle) =>\n Array.from(kernel.subShapeHashes(handle as BrepHandle, 'face', HASH_UPPER_BOUND)),\n roleTableOf: (p) => {\n const stmt = runtimeLineage.stmtOf(p)\n return stmt ? runtimeLineage.outputTableOf(stmt) : undefined\n },\n })\n if (!('hashes' in result)) return undefined\n return result.hashes\n}\n\n/**\n * 边路径「无血统邻面」恢复(1.10 前置③ 推广到边路径)。\n *\n * `edgeRef` 正查 `findOriginRole(table, ordinalToHash, fo)`(面 hash → `(origin, role)`)\n * 失败,通常因为**目标 part** 的 roleTable 缓存**残缺**(丢了该面的条目),而**根节点**\n * (名字的诞生处)的表是完整的:该面的 `(origin, role)` 真实存在,只是没被缓存到目标 part\n * 的表副本里(drift / 中间 op 原样带走旧 hash 表)。\n *\n * 与面路径 `recomputeViaLineage` 同构、方向相反——已知面 hash、不知道它属于哪个\n * `(origin, role)`。恢复策略:遍历血缘图所有候选 `(origin, role)`,沿 DAG 从根走到目标\n * part,把根序(该 role 的 hash 集)推进到目标序、换算成目标 hash 集,取**含该面当前 hash**\n * 者,即该面的真实身份。\n *\n * 推进规则(自带,不依赖 `resolveViaLineage` 的严格契约):\n * - 中间节点有 ordinal 演化(Map)→ 照用;\n * - 中间节点是 identity 类(copy/place/transform)但**未挂演化**(既有缺口,见\n * `place.ts` 经 compat 路径未 `attachEvolution`)→ 按 1:1 推进(语义正确:identity 不改\n * 面序);\n * - 其余无演化 → 放弃该候选(不乱猜)。\n *\n * 命中即回填 `{origin, role}` 让 `resolveEdgeTopo` 继续(exact 或几何兜底);未命中返回\n * undefined,调用方保持原 `no role lineage` 报错——零回归。仅跑在 `findOriginRole` 失败\n * 之后(错误路径),不进热路径。\n *\n * @param kernel - the OCCT kernel (hash 换算需要).\n * @param part - the live part whose adjacent face we are recovering.\n * @param faceOrdinal - the 1-based face ordinal whose role is missing.\n * @param ordinalToHash - the part's current face ordinal → hash array.\n * @returns the recovered `{origin, role}`, or undefined when no lineage walk matches.\n */\nexport function recoverEdgeFaceRole(\n kernel: BrepEngineApi,\n part: PartName,\n faceOrdinal: number,\n ordinalToHash: readonly number[],\n): { origin: StmtId; role: string } | undefined {\n const targetHash = ordinalToHash[faceOrdinal - 1]\n if (targetHash === undefined) return undefined\n\n // 候选 (origin, role):血缘图所有节点的输出表(根节点诞生名字处)\n const candidates: Array<{ origin: string; role: string }> = []\n for (const stmt of runtimeLineage.stmtIds()) {\n const tbl = runtimeLineage.outputTableOf(stmt)\n if (!tbl) continue\n for (const [origin, roles] of tbl) {\n for (const roleLine of roles.keys()) candidates.push({ origin, role: roleLine })\n }\n }\n\n for (const c of candidates) {\n const hashes = lineageHashesAt(kernel, c.origin, c.role, part)\n if (hashes && hashes.includes(targetHash)) return { origin: asStmtId(c.origin), role: c.role }\n }\n return undefined\n}\n\n/**\n * 沿血缘从 `(origin, role)` 的根走到 `targetPart`,把根序推进到目标序、换算成目标 hash 集。\n *\n * @returns the target part's face hashes for this role, or undefined when the\n * chain cannot be walked (unreachable / non-identity node without evolution).\n */\nfunction lineageHashesAt(\n kernel: BrepEngineApi,\n origin: string,\n roleLine: string,\n targetPart: PartName,\n): readonly number[] | undefined {\n const root = runtimeLineage.node(asStmtId(origin))\n if (!root) return undefined\n const rootPart = root.outputs[0]\n if (!rootPart) return undefined\n const rootHandle = runtimeLineage.outputHandleOf(asStmtId(origin))\n const rootTable = runtimeLineage.outputTableOf(asStmtId(origin))\n if (rootHandle === undefined || !rootTable) return undefined\n\n const rootHashes = rootTable.get(origin)?.get(roleLine)\n if (rootHashes === undefined || rootHashes.length === 0) return undefined\n const rootAll = Array.from(kernel.subShapeHashes(rootHandle as BrepHandle, 'face', HASH_UPPER_BOUND))\n let ordinals: number[] = []\n for (const h of rootHashes) {\n const idx = rootAll.indexOf(h)\n if (idx >= 0) ordinals.push(idx + 1) // ordinal 1 起\n }\n if (ordinals.length === 0) return undefined\n\n // 逐节点推进:root → targetPart(带访问守卫,防异常 DAG 环路挂死执行)\n const seen = new Set<PartName>()\n let currentPart: PartName = rootPart\n while (currentPart !== targetPart) {\n if (seen.has(currentPart)) return undefined\n seen.add(currentPart)\n const consumer = runtimeLineage.nodeConsuming(currentPart)\n if (!consumer) return undefined\n const evo = consumer.evolution\n if (evo && !isHashEvolution(evo)) {\n ordinals = ordinals.flatMap((o) => evo.get(o) ?? [o])\n } else if (consumer.provenance.kind === 'identity') {\n // identity 类未挂演化 → 1:1 推进(语义正确)\n } else {\n return undefined\n }\n const carry = consumer.outputs.includes(targetPart) ? targetPart : consumer.outputs[0]!\n currentPart = carry\n }\n\n const targetHandle = runtimeLineage.outputHandleOf(runtimeLineage.stmtOf(targetPart) ?? asStmtId(''))\n if (targetHandle === undefined) return undefined\n const targetAll = Array.from(kernel.subShapeHashes(targetHandle as BrepHandle, 'face', HASH_UPPER_BOUND))\n const hashes: number[] = []\n for (const o of ordinals) {\n const h = targetAll[o - 1]\n if (h !== undefined) hashes.push(h)\n }\n return hashes.length > 0 ? hashes : undefined\n}\n\n/**\n * 从活 Shape 的组装槽构建 ResolutionContext(BREAK 或 mesh/primitive 两条路)。\n *\n * - BREAK:`slot.solid` + `slot.roleTable` → 内核现场句柄 + hash(exact 路径);\n * - mesh/primitive:`slot.faceHints`(setTopology 注入时提炼写入)→ 行快照(geometric 路径)。\n *\n * 无命名槽 → undefined(调用方按 not-found 抛错)。\n *\n * @param kernel - the OCCT kernel (null on the mesh/primitive path).\n * @param shape - the live input shape whose naming slot is read.\n * @returns the resolution context (live BREP or hint rows), or undefined when the shape has no naming slot.\n */\nexport function buildShapeResolutionContext(\n kernel: BrepEngineApi | null,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n if (!slot) return undefined\n // 1.10 前置③:roleTable 权威落点在血缘图旁挂(part 键),slot 缓存字段已删。\n const part = nameOf(shape)\n const roleTable = (part ? runtimeLineage.tableOfPart(part) : undefined) as RoleTable | undefined\n\n const solid = slot.solid as BrepHandle | undefined\n if (kernel && solid !== undefined) {\n const handles = kernel.getSubShapes(solid, 'face')\n const hashes = Array.from(kernel.subShapeHashes(solid, 'face', HASH_UPPER_BOUND))\n const faces = handles.map((handle, i) => ({ ordinal: i + 1, hash: hashes[i] ?? 0, handle }))\n return { kernel, faces, roleTable }\n }\n\n const hints = slot.faceHints as FaceHint[] | undefined\n if (Array.isArray(hints) && hints.length > 0) {\n const faces = hints.map((row, i) => ({ ordinal: i + 1, row }))\n return { kernel: null, faces, roleTable }\n }\n return undefined\n}\n\n/**\n * 为 BREP 现场构建带边候选与邻接表的 ResolutionContext(edge TopoRef 解析用)。\n *\n * 与 `buildBrepResolutionContext` 的面候选同源(同一枚举序),并补充:\n * - `edges`:边候选表(ordinal 1 起,含活句柄 + length/midpoint hint);\n * - `faceEdgeAdjacency` / `edgeFaceAdjacency`:邻接表(edge lineage 解析用,M3)。\n *\n * 只支持 BREP 现场(edge lineage 需要 face→edge 邻接);mesh/primitive 路径\n * 没有邻接能力(build-mesh-topology.ts:262,§5.3)→ 返回 undefined,调用方\n * 按 E_TOPO_NOT_FOUND 处理。\n *\n * @param kernel - the OCCT kernel.\n * @param shape - the live input shape whose naming slot is read.\n * @returns the edge-enabled resolution context, or undefined when the shape has\n * no BREP naming slot.\n */\nexport function buildEdgeResolutionContext(\n kernel: BrepEngineApi,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n if (!slot) return undefined\n // 1.10 前置③:roleTable 权威落点在血缘图旁挂(part 键),slot 缓存字段已删。\n const edgePart = nameOf(shape)\n const roleTable = (edgePart ? runtimeLineage.tableOfPart(edgePart) : undefined) as RoleTable | undefined\n const solid = slot.solid as BrepHandle | undefined\n if (solid === undefined) return undefined\n\n const faceHandles = kernel.getSubShapes(solid, 'face')\n const faceHashes = Array.from(kernel.subShapeHashes(solid, 'face', HASH_UPPER_BOUND))\n const faces = faceHandles.map((handle, i) => ({ ordinal: i + 1, hash: faceHashes[i] ?? 0, handle }))\n\n const edgeHandles = kernel.getSubShapes(solid, 'edge')\n const edges: EdgeCandidateEntry[] = edgeHandles.map((handle, i) => ({\n ordinal: i + 1,\n handle,\n hint: captureEdgeHint(kernel, handle),\n }))\n const liveEdges = edges.filter((e): e is EdgeCandidateEntry & { handle: BrepHandle } => e.handle !== undefined)\n\n // face → 邻接 edges(ordinal 1 起)。mesh 无 face→edge 邻接,这里 BREP 现场直取。\n const faceHandlesArr = faceHandles.map((h, hi) => ({ handle: h, ordinal: hi + 1 }))\n\n const faceEdgeAdjacency = faceHandlesArr.map(({ handle }) => {\n const sub = kernel.getSubShapes(handle, 'edge')\n return sub\n .map((eh) => liveEdges.find((e) => kernel.isSame(eh, e.handle))?.ordinal)\n .filter((v): v is number => v !== undefined)\n })\n const edgeFaceAdjacency = liveEdges.map(({ handle }) => {\n const adj: number[] = []\n for (const f of faceHandlesArr) {\n if (kernel.getSubShapes(f.handle, 'edge').some((fe) => kernel.isSame(fe, handle))) {\n adj.push(f.ordinal)\n }\n }\n return adj\n })\n\n return { kernel, faces, edges, roleTable, faceEdgeAdjacency, edgeFaceAdjacency }\n}\n\n/**\n * 为**网格实体**构建带边候选的 ResolutionContext(近似拓扑的边解析入口)。\n *\n * 与 `buildEdgeResolutionContext` 的差别只有两点,两点都是\"网格零件没有 role 层\"\n * 的直接后果:\n * 1. 句柄来自 `slot.meshSolid`(网格实体句柄)而不是 `slot.solid`(BREP 句柄);\n * 2. **刻意不给 `faceEdgeAdjacency` / `edgeFaceAdjacency`**。\n *\n * 第 2 点是有意的,不是省事:邻接表存在的意义是\"两面之交 = 一条边\",\n * 而 `EdgeTopoRef.faces` 是两个 **RoleQualifier**——网格零件没有 role\n * (Phase 1.8:primitive/mesh 行 origin/role 显式为 null),限定符只是占位。\n * 带上邻接表反而会让 `resolveEdgeTopo` 走进\"按角色取公共边\"的分支并必然 not-found;\n * 不带它,解析就走「无 role 层 → 整个边表的纯几何匹配」(resolve-edge.ts 明写)。\n * 边身份只能几何,这是如实的能力边界。\n *\n * @param kernel - the mesh backend's L1 kernel (live edge handles come from it).\n * @param shape - the live mesh-solid shape whose naming slot is read.\n * @returns the edge-enabled resolution context, or undefined when the shape is not a mesh solid.\n */\nexport function buildMeshEdgeResolutionContext(\n kernel: BrepEngineApi,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n const solid = slot?.meshSolid as BrepHandle | undefined\n if (solid === undefined) return undefined\n\n const faceHandles = kernel.getSubShapes(solid, 'face')\n const faces = faceHandles.map((handle, i) => ({ ordinal: i + 1, handle }))\n const edges: EdgeCandidateEntry[] = kernel.getSubShapes(solid, 'edge').map((handle, i) => ({\n ordinal: i + 1,\n handle,\n hint: captureEdgeHint(kernel, handle),\n }))\n return { kernel, faces, edges }\n}\n\n/**\n * 为**网格实体**构建面解析上下文(`sketchOnFace` 的网格链入口)。\n *\n * 面候选直接来自 `slot.meshSolid` 的 `getSubShapes(solid,'face')` 现场句柄——\n * 与 `buildMeshEdgeResolutionContext` 的面表同源(同一枚举序)。**刻意不给\n * `roleTable` / 邻接**:网格零件没有 role 层(Phase 1.8),带上 roleTable 只会让\n * `resolveFaceTopo` 走进 exact 分支并必然落空;不带它,解析就走「全形状按 hint\n * 几何打分」(resolve-face.ts 步骤 2),命中即 `geometric-fallback`。\n *\n * 也因此,网格链上的面只能用**几何**识别(法向 / 中心 / 面积)——这是如实的能力\n * 边界,不是省事:同尺寸的两个平行面(如立方体的顶面与底面)在几何上无法区分,\n * 调用方应改用序号。\n *\n * @param kernel - the mesh backend's L1 kernel (live face handles come from it).\n * @param shape - the live mesh-solid shape whose naming slot is read.\n * @returns the face resolution context, or undefined when the shape is not a mesh solid.\n */\nexport function buildMeshFaceResolutionContext(\n kernel: BrepEngineApi,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n const solid = slot?.meshSolid as BrepHandle | undefined\n if (solid === undefined) return undefined\n\n const faces = kernel.getSubShapes(solid, 'face').map((handle, i) => ({ ordinal: i + 1, handle }))\n return { kernel, faces }\n}\n\n/**\n * 从 BREP 现场句柄建带边候选/邻接的 ResolutionContext(twoDistances 逐边重建用)。\n *\n * 与 `buildEdgeResolutionContext` 相同,但直接接收 live solid 句柄而非 Shape 槽——\n * 用于真机逐边构建后,输入已从上一次结果演化,Shape 槽里的 roleTable/hash 不再\n * 与当前句柄对应(§3.6 逐边构建,后续边要重新 resolve)。\n *\n * @param kernel - the OCCT kernel.\n * @param solid - the live BREP solid handle.\n * @param roleTable - optional role table to carry over (not used for strict matching).\n * @returns the edge-enabled resolution context (faces/edges/adjacency live from `solid`).\n */\nexport function buildEdgeContextFromSolid(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n roleTable?: RoleTable,\n): ResolutionContext {\n const faceHandles = kernel.getSubShapes(solid, 'face')\n const faces = faceHandles.map((handle, i) => ({ ordinal: i + 1, hash: undefined, handle }))\n const edgeHandles = kernel.getSubShapes(solid, 'edge')\n const edges: EdgeCandidateEntry[] = edgeHandles.map((handle, i) => ({\n ordinal: i + 1,\n handle,\n hint: captureEdgeHint(kernel, handle),\n }))\n const liveEdges = edges.filter((e): e is EdgeCandidateEntry & { handle: BrepHandle } => e.handle !== undefined)\n const faceHandlesArr = faceHandles.map((h, hi) => ({ handle: h, ordinal: hi + 1 }))\n const faceEdgeAdjacency = faceHandlesArr.map(({ handle }) => {\n const sub = kernel.getSubShapes(handle, 'edge')\n return sub\n .map((eh) => liveEdges.find((e) => kernel.isSame(eh, e.handle))?.ordinal)\n .filter((v): v is number => v !== undefined)\n })\n const edgeFaceAdjacency = liveEdges.map(({ handle }) => {\n const adj: number[] = []\n for (const f of faceHandlesArr) {\n if (kernel.getSubShapes(f.handle, 'edge').some((fe) => kernel.isSame(fe, handle))) adj.push(f.ordinal)\n }\n return adj\n })\n return { kernel, faces, edges, roleTable, faceEdgeAdjacency, edgeFaceAdjacency }\n}\n\n/**\n * 解析一个 face TopoRef 到「当前几何」,并从解析出的候选面派生求解几何。\n *\n * 结果与命名行的 surfaceType/center/normal 同口径(BREAK 现场 captureFaceHint /\n * mesh 行快照),保证两侧派生值一致。\n *\n * @param kernel - the OCCT kernel (can be null on the mesh/primitive path).\n * @param shape - the live input shape whose naming slot is being resolved.\n * @param ref - the FaceTopoRef captured earlier.\n * @returns the current face geometry (center/normal/surfaceType).\n */\nexport function resolveFaceGeometry(\n kernel: BrepEngineApi | null,\n shape: Shape,\n ref: FaceTopoRef,\n): ResolvedFaceGeometry {\n // 1.10 前置③:roleTable 是解析缓存。origin/role 条目 miss 时先沿血缘回走\n // 重算并回填(miss 可恢复),再进解析——不再是\"缓存 miss = 无名\"。\n let ctx = buildShapeResolutionContext(kernel, shape)\n if (!ctx) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n `no naming context on input shape (origin=${ref.origin}, role=${ref.role})`,\n )\n }\n // 1.10 前置③:roleTable 是解析缓存。origin/role 条目 miss 时先沿血缘回走\n // 重算并回填(miss 可恢复),再进解析——不再是\"缓存 miss = 无名\"。\n if (ctx.roleTable && kernel) {\n const entry0 = ctx.roleTable.get(ref.origin)?.get(ref.role)\n if (entry0 === undefined) {\n const recomputed = recomputeViaLineage(ref, shape, kernel)\n if (recomputed) {\n const merged = new Map(ctx.roleTable as ReadonlyMap<string, ReadonlyMap<string, readonly number[]>>)\n merged.set(ref.origin, new Map([...(ctx.roleTable.get(ref.origin) ?? new Map()), [ref.role, recomputed]]))\n ctx = { ...ctx, roleTable: merged as unknown as typeof ctx.roleTable }\n }\n }\n }\n const entity = resolveTopoRef(ref, ctx)\n const entry = ctx.faces[entity.ordinal - 1]\n if (!entry) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n `resolved ordinal ${entity.ordinal} has no candidate in context (origin=${ref.origin}, role=${ref.role})`,\n )\n }\n // BREAK 现场:capture 出当前法向/中心(圆柱面含轴)\n if (entry.handle && ctx.kernel) {\n const hint = captureFaceHint(ctx.kernel, entry.handle)\n return {\n surfaceType: hint.surfaceType,\n center: hint.center ?? [0, 0, 0],\n normal: hint.normal ?? [0, 0, 1],\n ...(hint.axis ? { axis: hint.axis } : {}),\n }\n }\n // mesh/行快照:直接用行几何(axis 由宿主行注入,缺省 undefined)\n const ext = entry.row\n const hint = ext ? faceRowToHint(ext) : undefined\n return {\n surfaceType: hint?.surfaceType,\n center: hint?.center ?? [0, 0, 0],\n normal: hint?.normal ?? [0, 0, 1],\n ...(hint?.axis ? { axis: hint.axis } : {}),\n }\n}\n\n/**\n * FaceMateConstraint 面的等价重载:face 参数对象(`{topoRef}` 或旧快照)的守卫。\n *\n * @param v - the value to test.\n * @returns true when the value is a FaceTopoRef (kind === 'face').\n */\nexport function isFaceTopoRef(v: unknown): v is FaceTopoRef {\n return !!v && typeof v === 'object' && (v as { kind?: unknown }).kind === 'face'\n}"]}
1
+ {"version":3,"file":"topo-resolve.js","sourceRoot":"","sources":["../../src/api/topo-resolve.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * topo-resolve — 运行期 TopoRef 解析(装配/钻孔等面引用 op 共享,§6.2)\n *\n * 与 core/topology/naming 的分工:\n * - naming(core)负责纯解析:给 ReactsContext + FaceTopoRef → ordinal/handle;\n * - 本模块(api 层)是「活 Shape → React块(ResolutionContext)」的引擎胶水:\n * 从 Shape 身份槽读出运行期数据(BREP 活句柄 + RoleTable,或 setTopology 注入的\n * 面 hint 快照),并把解析结果还原成求解需要的几何(center/normal/surfaceType)。\n *\n * 这样 drill(面 → 法向)与 compound/assembly(约束固定/移动面 → 几何)共用同一\n * 条「TopoRef 执行期派生」通道,且不动 core 的纯 naming 层职责。\n *\n * 任何一步定不了案 → 抛 TopoRefError(三态错误码),绝不静默拿序号硬取。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { getSlot } from '../shape'\nimport { nameOf } from '../runtime-state'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { HASH_UPPER_BOUND } from '../brep/face-evolution'\nimport { runtimeLineage, isHashEvolution } from '../topology/naming/lineage'\nimport { resolveViaLineage } from '../topology/naming/lineage-resolve'\nimport { asStmtId, type PartName, type StmtId } from '../identity'\nimport {\n resolveTopoRef,\n captureFaceHint,\n captureCylinderFaceAxis,\n captureEdgeHint,\n faceRowToHint,\n TopoRefError,\n type FaceTopoRef,\n type ResolutionContext,\n type FaceHint,\n type AxisHint,\n type EdgeCandidateEntry,\n type RoleTable,\n} from '../topology/naming'\n\n/** 求解面需要的当前几何(执行期派生):与旧契约 fixedFace/movingFace 的 surfaceType/center/normal 同形。 */\nexport interface ResolvedFaceGeometry {\n surfaceType?: string\n center: [number, number, number]\n normal: [number, number, number]\n /** 圆柱/回转面的轴(装配轴约束用;平面/球面缺省,mesh 行快照由宿主注入)。 */\n axis?: AxisHint\n}\n\n/**\n * roleTable miss 时沿血缘回走重算(1.10 前置③:缓存降级)。\n *\n * 「产物上的 roleTable 不再是身份的唯一来源」的落点:精确解析读不到\n * `roleTable[origin][role]` 时,按血缘 DAG 从 origin 语句回走推进到当前 part,\n * 产出该 role 的 hash 集合并**回填缓存**——miss 可恢复,不再是无名错误。\n * 回走失败(链断 / 无演化)返回 undefined,调用方落到几何兜底(既有三态语义不变)。\n *\n * @param ref - the face TopoRef being resolved.\n * @param shape - the live part shape being resolved against.\n * @param kernel - the OCCT kernel (hash 换算需要;null 时回走不可用).\n * @returns the recomputed hash list, or undefined when lineage re-walk cannot produce one.\n */\nfunction recomputeViaLineage(\n ref: FaceTopoRef,\n shape: object,\n kernel: BrepEngineApi | null,\n): readonly number[] | undefined {\n if (!kernel) return undefined\n const part = nameOf(shape)\n if (!part) return undefined\n const result = resolveViaLineage(runtimeLineage, asStmtId(ref.origin), ref.role, part, {\n // 回走链上的中间产物句柄:优先血缘图旁挂(本仓 op 执行时记录),\n // 兜底读 runtime 全局 nameOf 反查(slot.solid)。\n brepOf: (p) => {\n const stmt = runtimeLineage.stmtOf(p)\n const h = stmt ? runtimeLineage.outputHandleOf(stmt) : undefined\n if (h !== undefined) return h\n return undefined\n },\n faceHashes: (handle) =>\n Array.from(kernel.subShapeHashes(handle as BrepHandle, 'face', HASH_UPPER_BOUND)),\n roleTableOf: (p) => {\n const stmt = runtimeLineage.stmtOf(p)\n return stmt ? runtimeLineage.outputTableOf(stmt) : undefined\n },\n })\n if (!('hashes' in result)) return undefined\n return result.hashes\n}\n\n/**\n * 边路径「无血统邻面」恢复(1.10 前置③ 推广到边路径)。\n *\n * `edgeRef` 正查 `findOriginRole(table, ordinalToHash, fo)`(面 hash → `(origin, role)`)\n * 失败,通常因为**目标 part** 的 roleTable 缓存**残缺**(丢了该面的条目),而**根节点**\n * (名字的诞生处)的表是完整的:该面的 `(origin, role)` 真实存在,只是没被缓存到目标 part\n * 的表副本里(drift / 中间 op 原样带走旧 hash 表)。\n *\n * 与面路径 `recomputeViaLineage` 同构、方向相反——已知面 hash、不知道它属于哪个\n * `(origin, role)`。恢复策略:遍历血缘图所有候选 `(origin, role)`,沿 DAG 从根走到目标\n * part,把根序(该 role 的 hash 集)推进到目标序、换算成目标 hash 集,取**含该面当前 hash**\n * 者,即该面的真实身份。\n *\n * 推进规则(自带,不依赖 `resolveViaLineage` 的严格契约):\n * - 中间节点有 ordinal 演化(Map)→ 照用;\n * - 中间节点是 identity 类(copy/place/transform)但**未挂演化**(既有缺口,见\n * `place.ts` 经 compat 路径未 `attachEvolution`)→ 按 1:1 推进(语义正确:identity 不改\n * 面序);\n * - 其余无演化 → 放弃该候选(不乱猜)。\n *\n * 命中即回填 `{origin, role}` 让 `resolveEdgeTopo` 继续(exact 或几何兜底);未命中返回\n * undefined,调用方保持原 `no role lineage` 报错——零回归。仅跑在 `findOriginRole` 失败\n * 之后(错误路径),不进热路径。\n *\n * @param kernel - the OCCT kernel (hash 换算需要).\n * @param part - the live part whose adjacent face we are recovering.\n * @param faceOrdinal - the 1-based face ordinal whose role is missing.\n * @param ordinalToHash - the part's current face ordinal → hash array.\n * @returns the recovered `{origin, role}`, or undefined when no lineage walk matches.\n */\nexport function recoverEdgeFaceRole(\n kernel: BrepEngineApi,\n part: PartName,\n faceOrdinal: number,\n ordinalToHash: readonly number[],\n): { origin: StmtId; role: string } | undefined {\n const targetHash = ordinalToHash[faceOrdinal - 1]\n if (targetHash === undefined) return undefined\n\n // 候选 (origin, role):血缘图所有节点的输出表(根节点诞生名字处)\n const candidates: Array<{ origin: string; role: string }> = []\n for (const stmt of runtimeLineage.stmtIds()) {\n const tbl = runtimeLineage.outputTableOf(stmt)\n if (!tbl) continue\n for (const [origin, roles] of tbl) {\n for (const roleLine of roles.keys()) candidates.push({ origin, role: roleLine })\n }\n }\n\n for (const c of candidates) {\n const hashes = lineageHashesAt(kernel, c.origin, c.role, part)\n if (hashes && hashes.includes(targetHash)) return { origin: asStmtId(c.origin), role: c.role }\n }\n return undefined\n}\n\n/**\n * 沿血缘从 `(origin, role)` 的根走到 `targetPart`,把根序推进到目标序、换算成目标 hash 集。\n *\n * @returns the target part's face hashes for this role, or undefined when the\n * chain cannot be walked (unreachable / non-identity node without evolution).\n */\nfunction lineageHashesAt(\n kernel: BrepEngineApi,\n origin: string,\n roleLine: string,\n targetPart: PartName,\n): readonly number[] | undefined {\n const root = runtimeLineage.node(asStmtId(origin))\n if (!root) return undefined\n const rootPart = root.outputs[0]\n if (!rootPart) return undefined\n const rootHandle = runtimeLineage.outputHandleOf(asStmtId(origin))\n const rootTable = runtimeLineage.outputTableOf(asStmtId(origin))\n if (rootHandle === undefined || !rootTable) return undefined\n\n const rootHashes = rootTable.get(origin)?.get(roleLine)\n if (rootHashes === undefined || rootHashes.length === 0) return undefined\n const rootAll = Array.from(kernel.subShapeHashes(rootHandle as BrepHandle, 'face', HASH_UPPER_BOUND))\n let ordinals: number[] = []\n for (const h of rootHashes) {\n const idx = rootAll.indexOf(h)\n if (idx >= 0) ordinals.push(idx + 1) // ordinal 1 起\n }\n if (ordinals.length === 0) return undefined\n\n // 逐节点推进:root → targetPart(带访问守卫,防异常 DAG 环路挂死执行)\n const seen = new Set<PartName>()\n let currentPart: PartName = rootPart\n while (currentPart !== targetPart) {\n if (seen.has(currentPart)) return undefined\n seen.add(currentPart)\n const consumer = runtimeLineage.nodeConsuming(currentPart)\n if (!consumer) return undefined\n const evo = consumer.evolution\n if (evo && !isHashEvolution(evo)) {\n ordinals = ordinals.flatMap((o) => evo.get(o) ?? [o])\n } else if (consumer.provenance.kind === 'identity') {\n // identity 类未挂演化 → 1:1 推进(语义正确)\n } else {\n return undefined\n }\n const carry = consumer.outputs.includes(targetPart) ? targetPart : consumer.outputs[0]!\n currentPart = carry\n }\n\n const targetHandle = runtimeLineage.outputHandleOf(runtimeLineage.stmtOf(targetPart) ?? asStmtId(''))\n if (targetHandle === undefined) return undefined\n const targetAll = Array.from(kernel.subShapeHashes(targetHandle as BrepHandle, 'face', HASH_UPPER_BOUND))\n const hashes: number[] = []\n for (const o of ordinals) {\n const h = targetAll[o - 1]\n if (h !== undefined) hashes.push(h)\n }\n return hashes.length > 0 ? hashes : undefined\n}\n\n/**\n * 从活 Shape 的组装槽构建 ResolutionContext(BREAK 或 mesh/primitive 两条路)。\n *\n * - BREAK:`slot.solid` + `slot.roleTable` → 内核现场句柄 + hash(exact 路径);\n * - mesh/primitive:`slot.faceHints`(setTopology 注入时提炼写入)→ 行快照(geometric 路径)。\n *\n * 无命名槽 → undefined(调用方按 not-found 抛错)。\n *\n * @param kernel - the OCCT kernel (null on the mesh/primitive path).\n * @param shape - the live input shape whose naming slot is read.\n * @returns the resolution context (live BREP or hint rows), or undefined when the shape has no naming slot.\n */\nexport function buildShapeResolutionContext(\n kernel: BrepEngineApi | null,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n if (!slot) return undefined\n // 1.10 前置③:roleTable 权威落点在血缘图旁挂(part 键),slot 缓存字段已删。\n const part = nameOf(shape)\n const roleTable = (part ? runtimeLineage.tableOfPart(part) : undefined) as RoleTable | undefined\n\n const solid = slot.solid as BrepHandle | undefined\n if (kernel && solid !== undefined) {\n const handles = kernel.getSubShapes(solid, 'face')\n const hashes = Array.from(kernel.subShapeHashes(solid, 'face', HASH_UPPER_BOUND))\n // 行 hint 快照同带(§3.6):brepkit 的 uvBounds 对平面返回 ±1e6 哨兵,\n // kernel 现场的 surfaceCenterOfMass 退化成参数原点求值——center 错(法向\n // 碰巧对,因为平面法向在参数域是常数)→ 非居中模型上兜底打分全拒 →\n // `topo ref (face) not found`。故打分与 exact 后取几何一律 row 优先\n // (toScoringCandidate / 本文件 resolveFaceGeometry)。\n // 序号同序:TopExp 枚举序 ↔ FaceRow 的 o1.fN(FaceCandidateEntry.ordinal\n // 注释即此约定),2026-10-16 实测逐字一致。handle 仍保留——exact 命中后\n // 要回传活句柄给调用方(resolver.ts 的 entity.handle)。\n const rows = slot.faceHints as FaceHint[] | undefined\n const faces = handles.map((handle, i) => ({ ordinal: i + 1, hash: hashes[i] ?? 0, handle, row: rows?.[i] }))\n return { kernel, faces, roleTable }\n }\n\n const hints = slot.faceHints as FaceHint[] | undefined\n if (Array.isArray(hints) && hints.length > 0) {\n const faces = hints.map((row, i) => ({ ordinal: i + 1, row }))\n return { kernel: null, faces, roleTable }\n }\n return undefined\n}\n\n/**\n * 为 BREP 现场构建带边候选与邻接表的 ResolutionContext(edge TopoRef 解析用)。\n *\n * 与 `buildBrepResolutionContext` 的面候选同源(同一枚举序),并补充:\n * - `edges`:边候选表(ordinal 1 起,含活句柄 + length/midpoint hint);\n * - `faceEdgeAdjacency` / `edgeFaceAdjacency`:邻接表(edge lineage 解析用,M3)。\n *\n * 只支持 BREP 现场(edge lineage 需要 face→edge 邻接);mesh/primitive 路径\n * 没有邻接能力(build-mesh-topology.ts:262,§5.3)→ 返回 undefined,调用方\n * 按 E_TOPO_NOT_FOUND 处理。\n *\n * @param kernel - the OCCT kernel.\n * @param shape - the live input shape whose naming slot is read.\n * @returns the edge-enabled resolution context, or undefined when the shape has\n * no BREP naming slot.\n */\nexport function buildEdgeResolutionContext(\n kernel: BrepEngineApi,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n if (!slot) return undefined\n // 1.10 前置③:roleTable 权威落点在血缘图旁挂(part 键),slot 缓存字段已删。\n const edgePart = nameOf(shape)\n const roleTable = (edgePart ? runtimeLineage.tableOfPart(edgePart) : undefined) as RoleTable | undefined\n const solid = slot.solid as BrepHandle | undefined\n if (solid === undefined) return undefined\n\n const faceHandles = kernel.getSubShapes(solid, 'face')\n const faceHashes = Array.from(kernel.subShapeHashes(solid, 'face', HASH_UPPER_BOUND))\n const faces = faceHandles.map((handle, i) => ({ ordinal: i + 1, hash: faceHashes[i] ?? 0, handle }))\n\n const edgeHandles = kernel.getSubShapes(solid, 'edge')\n const edges: EdgeCandidateEntry[] = edgeHandles.map((handle, i) => ({\n ordinal: i + 1,\n handle,\n hint: captureEdgeHint(kernel, handle),\n }))\n const liveEdges = edges.filter((e): e is EdgeCandidateEntry & { handle: BrepHandle } => e.handle !== undefined)\n\n // face → 邻接 edges(ordinal 1 起)。mesh 无 face→edge 邻接,这里 BREP 现场直取。\n const faceHandlesArr = faceHandles.map((h, hi) => ({ handle: h, ordinal: hi + 1 }))\n\n const faceEdgeAdjacency = faceHandlesArr.map(({ handle }) => {\n const sub = kernel.getSubShapes(handle, 'edge')\n return sub\n .map((eh) => liveEdges.find((e) => kernel.isSame(eh, e.handle))?.ordinal)\n .filter((v): v is number => v !== undefined)\n })\n const edgeFaceAdjacency = liveEdges.map(({ handle }) => {\n const adj: number[] = []\n for (const f of faceHandlesArr) {\n if (kernel.getSubShapes(f.handle, 'edge').some((fe) => kernel.isSame(fe, handle))) {\n adj.push(f.ordinal)\n }\n }\n return adj\n })\n\n return { kernel, faces, edges, roleTable, faceEdgeAdjacency, edgeFaceAdjacency }\n}\n\n/**\n * 为**网格实体**构建带边候选的 ResolutionContext(近似拓扑的边解析入口)。\n *\n * 与 `buildEdgeResolutionContext` 的差别只有两点,两点都是\"网格零件没有 role 层\"\n * 的直接后果:\n * 1. 句柄来自 `slot.meshSolid`(网格实体句柄)而不是 `slot.solid`(BREP 句柄);\n * 2. **刻意不给 `faceEdgeAdjacency` / `edgeFaceAdjacency`**。\n *\n * 第 2 点是有意的,不是省事:邻接表存在的意义是\"两面之交 = 一条边\",\n * 而 `EdgeTopoRef.faces` 是两个 **RoleQualifier**——网格零件没有 role\n * (Phase 1.8:primitive/mesh 行 origin/role 显式为 null),限定符只是占位。\n * 带上邻接表反而会让 `resolveEdgeTopo` 走进\"按角色取公共边\"的分支并必然 not-found;\n * 不带它,解析就走「无 role 层 → 整个边表的纯几何匹配」(resolve-edge.ts 明写)。\n * 边身份只能几何,这是如实的能力边界。\n *\n * @param kernel - the mesh backend's L1 kernel (live edge handles come from it).\n * @param shape - the live mesh-solid shape whose naming slot is read.\n * @returns the edge-enabled resolution context, or undefined when the shape is not a mesh solid.\n */\nexport function buildMeshEdgeResolutionContext(\n kernel: BrepEngineApi,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n const solid = slot?.meshSolid as BrepHandle | undefined\n if (solid === undefined) return undefined\n\n const faceHandles = kernel.getSubShapes(solid, 'face')\n const faces = faceHandles.map((handle, i) => ({ ordinal: i + 1, handle }))\n const edges: EdgeCandidateEntry[] = kernel.getSubShapes(solid, 'edge').map((handle, i) => ({\n ordinal: i + 1,\n handle,\n hint: captureEdgeHint(kernel, handle),\n }))\n return { kernel, faces, edges }\n}\n\n/**\n * 为**网格实体**构建面解析上下文(`sketchOnFace` 的网格链入口)。\n *\n * 面候选直接来自 `slot.meshSolid` 的 `getSubShapes(solid,'face')` 现场句柄——\n * 与 `buildMeshEdgeResolutionContext` 的面表同源(同一枚举序)。**刻意不给\n * `roleTable` / 邻接**:网格零件没有 role 层(Phase 1.8),带上 roleTable 只会让\n * `resolveFaceTopo` 走进 exact 分支并必然落空;不带它,解析就走「全形状按 hint\n * 几何打分」(resolve-face.ts 步骤 2),命中即 `geometric-fallback`。\n *\n * 也因此,网格链上的面只能用**几何**识别(法向 / 中心 / 面积)——这是如实的能力\n * 边界,不是省事:同尺寸的两个平行面(如立方体的顶面与底面)在几何上无法区分,\n * 调用方应改用序号。\n *\n * @param kernel - the mesh backend's L1 kernel (live face handles come from it).\n * @param shape - the live mesh-solid shape whose naming slot is read.\n * @returns the face resolution context, or undefined when the shape is not a mesh solid.\n */\nexport function buildMeshFaceResolutionContext(\n kernel: BrepEngineApi,\n shape: object | undefined,\n): ResolutionContext | undefined {\n if (!shape) return undefined\n const slot = getSlot(shape)\n const solid = slot?.meshSolid as BrepHandle | undefined\n if (solid === undefined) return undefined\n\n const faces = kernel.getSubShapes(solid, 'face').map((handle, i) => ({ ordinal: i + 1, handle }))\n return { kernel, faces }\n}\n\n/**\n * 从 BREP 现场句柄建带边候选/邻接的 ResolutionContext(twoDistances 逐边重建用)。\n *\n * 与 `buildEdgeResolutionContext` 相同,但直接接收 live solid 句柄而非 Shape 槽——\n * 用于真机逐边构建后,输入已从上一次结果演化,Shape 槽里的 roleTable/hash 不再\n * 与当前句柄对应(§3.6 逐边构建,后续边要重新 resolve)。\n *\n * @param kernel - the OCCT kernel.\n * @param solid - the live BREP solid handle.\n * @param roleTable - optional role table to carry over (not used for strict matching).\n * @returns the edge-enabled resolution context (faces/edges/adjacency live from `solid`).\n */\nexport function buildEdgeContextFromSolid(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n roleTable?: RoleTable,\n): ResolutionContext {\n const faceHandles = kernel.getSubShapes(solid, 'face')\n const faces = faceHandles.map((handle, i) => ({ ordinal: i + 1, hash: undefined, handle }))\n const edgeHandles = kernel.getSubShapes(solid, 'edge')\n const edges: EdgeCandidateEntry[] = edgeHandles.map((handle, i) => ({\n ordinal: i + 1,\n handle,\n hint: captureEdgeHint(kernel, handle),\n }))\n const liveEdges = edges.filter((e): e is EdgeCandidateEntry & { handle: BrepHandle } => e.handle !== undefined)\n const faceHandlesArr = faceHandles.map((h, hi) => ({ handle: h, ordinal: hi + 1 }))\n const faceEdgeAdjacency = faceHandlesArr.map(({ handle }) => {\n const sub = kernel.getSubShapes(handle, 'edge')\n return sub\n .map((eh) => liveEdges.find((e) => kernel.isSame(eh, e.handle))?.ordinal)\n .filter((v): v is number => v !== undefined)\n })\n const edgeFaceAdjacency = liveEdges.map(({ handle }) => {\n const adj: number[] = []\n for (const f of faceHandlesArr) {\n if (kernel.getSubShapes(f.handle, 'edge').some((fe) => kernel.isSame(fe, handle))) adj.push(f.ordinal)\n }\n return adj\n })\n return { kernel, faces, edges, roleTable, faceEdgeAdjacency, edgeFaceAdjacency }\n}\n\n/**\n * 解析一个 face TopoRef 到「当前几何」,并从解析出的候选面派生求解几何。\n *\n * 结果与命名行的 surfaceType/center/normal 同口径(BREAK 现场 captureFaceHint /\n * mesh 行快照),保证两侧派生值一致。\n *\n * @param kernel - the OCCT kernel (can be null on the mesh/primitive path).\n * @param shape - the live input shape whose naming slot is being resolved.\n * @param ref - the FaceTopoRef captured earlier.\n * @returns the current face geometry (center/normal/surfaceType).\n */\nexport function resolveFaceGeometry(\n kernel: BrepEngineApi | null,\n shape: Shape,\n ref: FaceTopoRef,\n): ResolvedFaceGeometry {\n // 1.10 前置③:roleTable 是解析缓存。origin/role 条目 miss 时先沿血缘回走\n // 重算并回填(miss 可恢复),再进解析——不再是\"缓存 miss = 无名\"。\n let ctx = buildShapeResolutionContext(kernel, shape)\n if (!ctx) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n `no naming context on input shape (origin=${ref.origin}, role=${ref.role})`,\n )\n }\n // 1.10 前置③:roleTable 是解析缓存。origin/role 条目 miss 时先沿血缘回走\n // 重算并回填(miss 可恢复),再进解析——不再是\"缓存 miss = 无名\"。\n if (ctx.roleTable && kernel) {\n const entry0 = ctx.roleTable.get(ref.origin)?.get(ref.role)\n if (entry0 === undefined) {\n const recomputed = recomputeViaLineage(ref, shape, kernel)\n if (recomputed) {\n const merged = new Map(ctx.roleTable as ReadonlyMap<string, ReadonlyMap<string, readonly number[]>>)\n merged.set(ref.origin, new Map([...(ctx.roleTable.get(ref.origin) ?? new Map()), [ref.role, recomputed]]))\n ctx = { ...ctx, roleTable: merged as unknown as typeof ctx.roleTable }\n }\n }\n }\n const entity = resolveTopoRef(ref, ctx)\n const entry = ctx.faces[entity.ordinal - 1]\n if (!entry) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n `resolved ordinal ${entity.ordinal} has no candidate in context (origin=${ref.origin}, role=${ref.role})`,\n )\n }\n // 行快照优先:与打分同口径(toScoringCandidate),同帧且几何正确——\n // brepkit 的 kernel 现场 center 会退化(uvBounds ±1e6 哨兵 → 参数原点求值),\n // 2026-10-16 实测非居中盒上 `[20,20,0]` 退化成 `[0,0,0]`。\n if (entry.row === undefined && entry.handle && ctx.kernel) {\n const hint = captureFaceHint(ctx.kernel, entry.handle)\n return {\n surfaceType: hint.surfaceType,\n center: hint.center ?? [0, 0, 0],\n normal: hint.normal ?? [0, 0, 1],\n ...(hint.axis ? { axis: hint.axis } : {}),\n }\n }\n // mesh/行快照:直接用行几何(axis 由宿主行注入,缺省 undefined)\n const ext = entry.row\n const hint = ext ? faceRowToHint(ext) : undefined\n // 圆柱轴补采:行快照不带 axis,而圆柱的轴一向现场采(captureFaceHint 的\n // cylinder 分支)——它由 pointOnSurface + getFaceCylinderData 量出,**不经\n // 过退化的 surfaceCenterOfMass**,现场值可靠。故 row 优先只管 center/normal,\n // 圆柱轴缺行值时补采,守住 P0①(圆柱侧壁 hint 含 axis)。\n let axis = hint?.axis\n if (axis === undefined && hint?.surfaceType === 'cylinder' && entry.handle && ctx.kernel) {\n axis = captureCylinderFaceAxis(ctx.kernel, entry.handle)\n }\n return {\n surfaceType: hint?.surfaceType,\n center: hint?.center ?? [0, 0, 0],\n normal: hint?.normal ?? [0, 0, 1],\n ...(axis ? { axis } : {}),\n }\n}\n\n/**\n * FaceMateConstraint 面的等价重载:face 参数对象(`{topoRef}` 或旧快照)的守卫。\n *\n * @param v - the value to test.\n * @returns true when the value is a FaceTopoRef (kind === 'face').\n */\nexport function isFaceTopoRef(v: unknown): v is FaceTopoRef {\n return !!v && typeof v === 'object' && (v as { kind?: unknown }).kind === 'face'\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"view-projection.d.ts","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAK7C,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AAU5D,0BAA0B;AAC1B,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC9C,eAAe;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AA8MD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAE,kBAAuB,GAAG,aAAa,CA2BzG;AAED;;;;;;;;;;;;;;;;;;;IAmBI;AACJ,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAE3F"}
1
+ {"version":3,"file":"view-projection.d.ts","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAK7C,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AAU5D,0BAA0B;AAC1B,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC9C,eAAe;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAqND;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAE,kBAAuB,GAAG,aAAa,CA2BzG;AAED;;;;;;;;;;;;;;;;;;;IAmBI;AACJ,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAE3F"}
@@ -28,8 +28,15 @@ import { brepOf } from '../../shape.js';
28
28
  import { getBrepApi } from '../../brep/handle-bridge.js';
29
29
  import { getBackends } from '../../runtime-state.js';
30
30
  import { resolveCamera } from './view-camera.js';
31
- /** 每条边的 3D 采样点数(直线 2 点;曲线分段近似)。 */
32
- const EDGE_SAMPLES = 5;
31
+ /**
32
+ * 每条边的 3D 采样点数(occt compound 通道的曲线分段近似;brepkit 原生
33
+ * 通道由内核输出折线,不经本参数)。
34
+ *
35
+ * 2026-10-14 修复:5 点时圆/椭圆轮廓被离散成五边形/八边形级折线——web 端
36
+ * 工程图实测圆柱 iso 轴测图呈多面体感、top 俯视图圆环呈菱形。提高到 48 点
37
+ * 后椭圆视觉光滑。直线边多点采样点仍共线,无视觉差异,故不做边类型分流。
38
+ */
39
+ const EDGE_SAMPLES = 48;
33
40
  /** 3D 点 → 相机平面 2D 坐标。
34
41
  *
35
42
  * GOTCHA: occt-wasm 的 HLR projectEdges 已把边投影到相机平面,输出坐标 =
@@ -1 +1 @@
1
- {"version":3,"file":"view-projection.js","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * view-projection — 单视图投影 → SVG 线稿(faijs 视图投影能力,路径 A)\n *\n * projectView(shape, view, opts?) 返回**纯数据 SVG 字符串**(非 Shape):\n * - 直连 core 引擎的 HLR 投影(`BrepEngineApi.projectEdges`,OCCT\n * HLRBRep 隐线消除):可见 / 隐藏两组边(sharp/smooth/outline compound);\n * - 每组边 → 3D 曲线采样折线(`curveParameters` + `curvePointAtParam`)→\n * 投影到相机平面(正交投影,坐标 = 相对 camera.origin 在 xAxis/yAxis 上的分量);\n * - 序列化为一个完整 SVG:可见轮廓实线 + 隐藏线虚线(stroke-dasharray)。\n *\n * 返回字符串绕开 arg-spec 对 projectEdges/makeProjectedEdges 的 skip 障碍\n * (Edge 句柄数组 + compound 生命周期无法静态收养——本 op 只在内部消费,\n * 产物是 2D 纯文本,无收养问题)。\n *\n * 2026-09-25 core-decouple wrapup(§3.1 A 案):不再依赖 brepjs 的 HLR+2D\n * drawing 链——HLR 由 core 引擎原生提供(occt-wasm projectEdges),2D SVG\n * 序列化为本地实现(曲线边以采样折线近似)。\n *\n * 2026-10-11 双方言通道(方案 docs/plans/2026-10-11-brepkit-svg-view.md,与\n * STEP 引擎中立化同基调:按引擎 id 静态分派通道,无门禁、无 engines 声明、\n * 不因内核缺特性报错):\n * - occt:HLR compound 句柄 → getSubShapes → 3D 曲线采样 → 相机平面投影;\n * - brepkit:内核原生 `projectEdges` 直接返回已投影 2D 折线 JSON\n * `{\"visible\":[[x,y,…],…],\"hidden\":[…]}`(每条折线 = 扁平 x,y 点对数组;\n * y 轴 = x_axis × view,与 occt 输出坐标约定同构),解析后直接序列化。\n */\n\nimport type { Shape } from '../../mesh/types'\nimport { brepOf } from '../../shape'\nimport { getBrepApi } from '../../brep/handle-bridge'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport { getBackends } from '../../runtime-state'\nimport { resolveCamera, type ViewSpec } from './view-camera'\n\n/** 投影相机(与 view-camera 输出同构)。 */\ninterface Camera {\n readonly position: [number, number, number]\n readonly direction: [number, number, number]\n readonly xAxis: [number, number, number]\n readonly yAxis: [number, number, number]\n}\n\n/** projectView 的序列化选项。 */\nexport interface ProjectViewOptions {\n /** viewBox 四周留白(单位 = 投影平面坐标单位;缺省 1)。 */\n margin?: number\n /** 可见/隐藏线 stroke-width(像素;缺省 1)。 */\n strokeWidth?: number\n /** 隐藏线虚线样式(SVG stroke-dasharray;缺省 '4,4')。 */\n dash?: string\n /** 隐藏线透明度(缺省 0.6)。 */\n hiddenOpacity?: number\n /** 输出 SVG 宽度(缺省 = viewBox 宽度)。 */\n width?: number\n /** 输出 SVG 高度(缺省 = viewBox 高度)。 */\n height?: number\n}\n\n/** 单视图投影的结构化结果(projectSheet 复用)。 */\nexport interface ProjectionSvg {\n /** 完整 SVG 字符串。 */\n svg: string\n /** viewBox 属性值('minX minY w h';可见 ∪ 隐藏线并集 + margin)。 */\n viewBox: string\n /** 各 path d 串:可见实线 / 隐藏虚线。 */\n paths: { visible: string[]; hidden: string[] }\n /** 输出宽度/高度。 */\n width: number\n height: number\n}\n\n/** 每条边的 3D 采样点数(直线 2 点;曲线分段近似)。 */\nconst EDGE_SAMPLES = 5\n\ntype Vec3 = readonly [number, number, number]\n\n/** 3D 点 → 相机平面 2D 坐标。\n *\n * GOTCHA: occt-wasm 的 HLR projectEdges 已把边投影到相机平面,输出坐标 =\n * (沿 xAxis 的水平分量, 沿 cross(direction, xAxis) 的垂直分量, 沿 direction\n * 的深度分量≈0)——不是世界坐标。因此 2D 坐标直接取输出的前两分量,不再做\n * dot 二次投影(否则会把垂直信息读丢——垂直在 p.y 而非 p.z)。\n */\nfunction projectTo2D(p: Vec3, _cam: Camera): [number, number] {\n return [p[0], p[1]]\n}\n\n/** 引擎 projectEdges 的返回结构(occt-wasm:6 组 compound 的 arena id)。 */\ninterface ProjectEdgesResult {\n visibleSharp: number\n visibleSmooth: number\n visibleOutline: number\n hiddenSharp: number\n hiddenSmooth: number\n hiddenOutline: number\n}\n\nconst COMPOUND_KEYS = [\n ['visibleSharp', 'visible'],\n ['visibleSmooth', 'visible'],\n ['visibleOutline', 'visible'],\n ['hiddenSharp', 'hidden'],\n ['hiddenSmooth', 'hidden'],\n ['hiddenOutline', 'hidden'],\n] as const\n\n/**\n * HLR 投影 shape → 可见/隐藏 2D 折线(SVG d 串)。\n * 按引擎 id 静态分派方言通道(见文件头 2026-10-11 注):\n * - brepkit → 内核原生折线 JSON 通道;\n * - 其余(含 occt)→ compound 句柄采样通道(现状)。\n * 无引擎门禁:分派只选通道,不因内核缺特性报错。\n */\nfunction projectPolylines(shape: Shape, view: ViewSpec): { visible: string[]; hidden: string[] } {\n const solid = brepOf(shape) as BrepHandle | undefined\n if (solid === undefined) {\n throw new Error(\n '[faijs/view-projection] E_BREP_ONLY_INPUT: operation requires a BREP-backed shape ' +\n '(mesh-only input cannot be projected)',\n )\n }\n const api = getBrepApi()\n const cam = resolveCamera(view) as unknown as Camera\n const engineId = getBackends().config.brepEngineId\n if (engineId === 'brepkit') {\n return projectPolylinesNative(api, solid, cam)\n }\n return projectPolylinesCompound(api, solid, cam)\n}\n\n/** projectEdges 的公共调用参数(两方言同构,签名见 brep/engine/primitives.ts)。 */\nfunction projectEdgesArgs(cam: Camera) {\n return [\n { x: cam.position[0], y: cam.position[1], z: cam.position[2] },\n { x: cam.direction[0], y: cam.direction[1], z: cam.direction[2] },\n { x: cam.xAxis[0], y: cam.xAxis[1], z: cam.xAxis[2] },\n true,\n 0.1,\n ] as const\n}\n\n/**\n * brepkit 原生通道:内核 projectEdges 返回 JSON 字符串\n * `{\"visible\":[[x,y,…],…],\"hidden\":[…]}`(每条折线 = 扁平 x,y 点对数组,已是\n * 相机平面 2D 坐标),解析后直接转 SVG path d 串。内核返回非法 JSON 属实现\n * 缺陷,直接抛错暴露(非\"缺特性\",不受无门禁基调豁免)。\n */\nfunction projectPolylinesNative(\n api: ReturnType<typeof getBrepApi>,\n solid: BrepHandle,\n cam: Camera,\n): { visible: string[]; hidden: string[] } {\n const [origin, direction, xAxis] = projectEdgesArgs(cam)\n const raw = api.projectEdges(solid, origin, direction, xAxis, true, 0.1)\n const parsed = parseNativeProjection(raw)\n return {\n visible: parsed.visible.map(polylineToPath),\n hidden: parsed.hidden.map(polylineToPath),\n }\n}\n\n/** 解析 brepkit projectEdges 的折线 JSON(结构错误一律抛错暴露)。 */\nfunction parseNativeProjection(raw: unknown): { visible: number[][]; hidden: number[][] } {\n if (typeof raw !== 'string') {\n throw new Error(\n `[faijs/view-projection] E_PROJECTION_DIALECT: native projectEdges returned ${typeof raw}, expected JSON string`,\n )\n }\n const obj = JSON.parse(raw) as { visible?: unknown; hidden?: unknown }\n const flat = (v: unknown): number[][] => {\n if (!Array.isArray(v)) throw new Error('[faijs/view-projection] E_PROJECTION_DIALECT: malformed native projection JSON')\n return v.filter((p): p is number[] => Array.isArray(p) && p.length >= 4)\n }\n return { visible: flat(obj.visible), hidden: flat(obj.hidden) }\n}\n\n/** 扁平 x,y 点对数组 → SVG path d 串(M + L 序列)。 */\nfunction polylineToPath(poly: number[]): string {\n let d = `M ${poly[0].toFixed(4)} ${poly[1].toFixed(4)}`\n for (let i = 2; i + 1 < poly.length; i += 2) {\n d += ` L ${poly[i].toFixed(4)} ${poly[i + 1].toFixed(4)}`\n }\n return d\n}\n\n/**\n * occt compound 通道(现状,逐字节不变):HLR 输出 6 组 compound 的 arena id,\n * 逐 compound 取边 → 3D 曲线采样 → 相机平面投影。\n * 全部句柄在本函数内释放(compound + 边;输入 shape 不消费)。\n */\nfunction projectPolylinesCompound(\n api: ReturnType<typeof getBrepApi>,\n solid: BrepHandle,\n cam: Camera,\n): { visible: string[]; hidden: string[] } {\n const [origin, direction, xAxis] = projectEdgesArgs(cam)\n const r = api.projectEdges(solid, origin, direction, xAxis, true, 0.1) as ProjectEdgesResult\n\n const out: { visible: string[]; hidden: string[] } = { visible: [], hidden: [] }\n const toHandle = (id: number): BrepHandle => id as BrepHandle\n try {\n for (const [key, group] of COMPOUND_KEYS) {\n const compoundId = r[key]\n if (typeof compoundId !== 'number' || compoundId === 0) continue\n const edges = api.getSubShapes(toHandle(compoundId), 'edge')\n for (const edge of edges) {\n const d = edgeToPath(api, edge, cam)\n if (d !== null) out[group].push(d)\n }\n // 释放 compound slot(幂等)\n try {\n api.release(toHandle(compoundId))\n } catch {\n // already released\n }\n }\n } finally {\n void 0\n }\n return out\n}\n\n/** 单条边 → SVG path d 串(3D 曲线采样折线投影到相机平面)。 */\nfunction edgeToPath(api: ReturnType<typeof getBrepApi>, edge: BrepHandle, cam: Camera): string | null {\n let cp\n try {\n cp = api.curveParameters(edge)\n } catch {\n return null // 退化边(如孤立顶点线)无曲线参数\n }\n const { first, last } = cp\n const span = last - first\n const pts: [number, number][] = []\n for (let i = 0; i < EDGE_SAMPLES; i += 1) {\n const t = first + (span * i) / (EDGE_SAMPLES - 1)\n const p = api.curvePointAtParam(edge, t)\n pts.push(projectTo2D([p.x, p.y, p.z], cam))\n }\n if (pts.length < 2) return null\n let d = `M ${pts[0][0].toFixed(4)} ${pts[0][1].toFixed(4)}`\n for (let i = 1; i < pts.length; i += 1) {\n d += ` L ${pts[i][0].toFixed(4)} ${pts[i][1].toFixed(4)}`\n }\n return d\n}\n\n/** 解析 'minX minY w h' 为数值数组。 */\nfunction parseViewBox(vb: string): [number, number, number, number] | undefined {\n const parts = vb.trim().split(/\\s+/).map(Number)\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n))) return undefined\n return [parts[0], parts[1], parts[2], parts[3]]\n}\n\n/** 折线点集 bbox → viewBox(统一坐标系;margin 再外扩)。 */\nfunction viewBoxOfPaths(paths: string[], margin: number): string {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const d of paths) {\n const nums = d.match(/[-+]?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?/g) ?? []\n for (let i = 0; i + 1 < nums.length; i += 2) {\n const x = Number(nums[i])\n const y = Number(nums[i + 1])\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue\n minX = Math.min(minX, x)\n minY = Math.min(minY, y)\n maxX = Math.max(maxX, x)\n maxY = Math.max(maxY, y)\n }\n }\n if (!Number.isFinite(minX)) return '0 0 0 0' // 空投影(如空 shape)\n return `${minX - margin} ${minY - margin} ${maxX - minX + 2 * margin} ${maxY - minY + 2 * margin}`\n}\n\n/**\n * 单视图投影(结构化结果)。\n *\n * @param shape - 待投影的 faijs Shape(必须带 BREP 槽;mesh-only 输入抛 E_BREP_ONLY_INPUT)。\n * @param view - 视图规格(标准视图 / iso / 轴对平面 / 方向对象)。\n * @param opts - 序列化选项。\n * @returns 结构化投影结果(svg/viewBox/paths/尺寸)。\n */\nexport function projectViewSvg(shape: Shape, view: ViewSpec, opts: ProjectViewOptions = {}): ProjectionSvg {\n const { visible: visiblePaths, hidden: hiddenPaths } = projectPolylines(shape, view)\n const margin = opts.margin ?? 1\n const viewBox = viewBoxOfPaths([...visiblePaths, ...hiddenPaths], margin)\n const parsed = parseViewBox(viewBox) ?? [0, 0, 0, 0]\n const width = opts.width ?? parsed[2]\n const height = opts.height ?? parsed[3]\n const strokeWidth = opts.strokeWidth ?? 1\n const dash = opts.dash ?? '4,4'\n const hiddenOpacity = opts.hiddenOpacity ?? 0.6\n const visibleMarkup = visiblePaths\n .map((d) => `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" />`)\n .join('\\n ')\n const hiddenMarkup = hiddenPaths\n .map(\n (d) =>\n `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" stroke-dasharray=\"${dash}\" opacity=\"${hiddenOpacity}\" />`,\n )\n .join('\\n ')\n const svg = [\n `<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox}\" width=\"${width}\" height=\"${height}\" fill=\"none\" stroke=\"black\" stroke-width=\"0.6%\" vector-effect=\"non-scaling-stroke\">`,\n ` <g stroke=\"#000\" fill=\"none\">`,\n ` ${visibleMarkup}${hiddenMarkup === '' ? '' : `\\n ${hiddenMarkup}`}`,\n ` </g>`,\n `</svg>`,\n ].join('\\n')\n return { svg, viewBox, paths: { visible: visiblePaths, hidden: hiddenPaths }, width, height }\n}\n\n/**\n * 单视图投影 → SVG 线稿字符串(纯数据,不消费/修改 shape;规则 1 下裸调用不消费输入)。\n * @group 查询\n * @inputs 1\n * @async false\n * @qual ok\n * @name projectView\n * @returns SVG 字符串(<svg viewBox=\"…\"> + 可见实线 <path> + 隐藏虚线 <path>)。裸调用 cad.projectView(part0, 'front') 不消费 part0(规则 1),part 仍留在 canvas。\n * @param shape - 目标几何(必须有 BREP 槽;mesh-only 抛 E_BREP_ONLY_INPUT)。type:Shape required:true\n * @param view - 视图规格(同 viewCamera:标准视图名 / iso / 轴对平面 / 方向对象)。type:string|{dir,xAxis?} required:true\n * @param opts.strokeWidth - 可见线宽(stroke-width)。type:number 默认 1\n * @param opts.dash - 隐藏线虚线样式(stroke-dasharray)。type:string 默认 '4,4'\n * @param opts.hiddenOpacity - 隐藏线透明度。type:number 默认 0.6\n * @param opts.margin - viewBox 外扩边距。type:number 默认 1\n * @param opts.width - 输出宽度(缺省 = viewBox 宽度)。type:number\n * @param opts.height - 输出高度(缺省 = viewBox 高度)。type:number\n * @example\n * const svg = cad.projectView(part0, 'front')\n * const svg = cad.projectView(part0, 'iso', { strokeWidth: 1, dash: '4,4', hiddenOpacity: 0.6 })\n */\nexport function projectView(shape: Shape, view: ViewSpec, opts?: ProjectViewOptions): string {\n return projectViewSvg(shape, view, opts).svg\n}\n"]}
1
+ {"version":3,"file":"view-projection.js","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * view-projection — 单视图投影 → SVG 线稿(faijs 视图投影能力,路径 A)\n *\n * projectView(shape, view, opts?) 返回**纯数据 SVG 字符串**(非 Shape):\n * - 直连 core 引擎的 HLR 投影(`BrepEngineApi.projectEdges`,OCCT\n * HLRBRep 隐线消除):可见 / 隐藏两组边(sharp/smooth/outline compound);\n * - 每组边 → 3D 曲线采样折线(`curveParameters` + `curvePointAtParam`)→\n * 投影到相机平面(正交投影,坐标 = 相对 camera.origin 在 xAxis/yAxis 上的分量);\n * - 序列化为一个完整 SVG:可见轮廓实线 + 隐藏线虚线(stroke-dasharray)。\n *\n * 返回字符串绕开 arg-spec 对 projectEdges/makeProjectedEdges 的 skip 障碍\n * (Edge 句柄数组 + compound 生命周期无法静态收养——本 op 只在内部消费,\n * 产物是 2D 纯文本,无收养问题)。\n *\n * 2026-09-25 core-decouple wrapup(§3.1 A 案):不再依赖 brepjs 的 HLR+2D\n * drawing 链——HLR 由 core 引擎原生提供(occt-wasm projectEdges),2D SVG\n * 序列化为本地实现(曲线边以采样折线近似)。\n *\n * 2026-10-11 双方言通道(方案 docs/plans/2026-10-11-brepkit-svg-view.md,与\n * STEP 引擎中立化同基调:按引擎 id 静态分派通道,无门禁、无 engines 声明、\n * 不因内核缺特性报错):\n * - occt:HLR compound 句柄 → getSubShapes → 3D 曲线采样 → 相机平面投影;\n * - brepkit:内核原生 `projectEdges` 直接返回已投影 2D 折线 JSON\n * `{\"visible\":[[x,y,…],…],\"hidden\":[…]}`(每条折线 = 扁平 x,y 点对数组;\n * y 轴 = x_axis × view,与 occt 输出坐标约定同构),解析后直接序列化。\n */\n\nimport type { Shape } from '../../mesh/types'\nimport { brepOf } from '../../shape'\nimport { getBrepApi } from '../../brep/handle-bridge'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport { getBackends } from '../../runtime-state'\nimport { resolveCamera, type ViewSpec } from './view-camera'\n\n/** 投影相机(与 view-camera 输出同构)。 */\ninterface Camera {\n readonly position: [number, number, number]\n readonly direction: [number, number, number]\n readonly xAxis: [number, number, number]\n readonly yAxis: [number, number, number]\n}\n\n/** projectView 的序列化选项。 */\nexport interface ProjectViewOptions {\n /** viewBox 四周留白(单位 = 投影平面坐标单位;缺省 1)。 */\n margin?: number\n /** 可见/隐藏线 stroke-width(像素;缺省 1)。 */\n strokeWidth?: number\n /** 隐藏线虚线样式(SVG stroke-dasharray;缺省 '4,4')。 */\n dash?: string\n /** 隐藏线透明度(缺省 0.6)。 */\n hiddenOpacity?: number\n /** 输出 SVG 宽度(缺省 = viewBox 宽度)。 */\n width?: number\n /** 输出 SVG 高度(缺省 = viewBox 高度)。 */\n height?: number\n}\n\n/** 单视图投影的结构化结果(projectSheet 复用)。 */\nexport interface ProjectionSvg {\n /** 完整 SVG 字符串。 */\n svg: string\n /** viewBox 属性值('minX minY w h';可见 ∪ 隐藏线并集 + margin)。 */\n viewBox: string\n /** 各 path d 串:可见实线 / 隐藏虚线。 */\n paths: { visible: string[]; hidden: string[] }\n /** 输出宽度/高度。 */\n width: number\n height: number\n}\n\n/**\n * 每条边的 3D 采样点数(occt compound 通道的曲线分段近似;brepkit 原生\n * 通道由内核输出折线,不经本参数)。\n *\n * 2026-10-14 修复:5 点时圆/椭圆轮廓被离散成五边形/八边形级折线——web 端\n * 工程图实测圆柱 iso 轴测图呈多面体感、top 俯视图圆环呈菱形。提高到 48 点\n * 后椭圆视觉光滑。直线边多点采样点仍共线,无视觉差异,故不做边类型分流。\n */\nconst EDGE_SAMPLES = 48\n\ntype Vec3 = readonly [number, number, number]\n\n/** 3D 点 → 相机平面 2D 坐标。\n *\n * GOTCHA: occt-wasm 的 HLR projectEdges 已把边投影到相机平面,输出坐标 =\n * (沿 xAxis 的水平分量, 沿 cross(direction, xAxis) 的垂直分量, 沿 direction\n * 的深度分量≈0)——不是世界坐标。因此 2D 坐标直接取输出的前两分量,不再做\n * dot 二次投影(否则会把垂直信息读丢——垂直在 p.y 而非 p.z)。\n */\nfunction projectTo2D(p: Vec3, _cam: Camera): [number, number] {\n return [p[0], p[1]]\n}\n\n/** 引擎 projectEdges 的返回结构(occt-wasm:6 组 compound 的 arena id)。 */\ninterface ProjectEdgesResult {\n visibleSharp: number\n visibleSmooth: number\n visibleOutline: number\n hiddenSharp: number\n hiddenSmooth: number\n hiddenOutline: number\n}\n\nconst COMPOUND_KEYS = [\n ['visibleSharp', 'visible'],\n ['visibleSmooth', 'visible'],\n ['visibleOutline', 'visible'],\n ['hiddenSharp', 'hidden'],\n ['hiddenSmooth', 'hidden'],\n ['hiddenOutline', 'hidden'],\n] as const\n\n/**\n * HLR 投影 shape → 可见/隐藏 2D 折线(SVG d 串)。\n * 按引擎 id 静态分派方言通道(见文件头 2026-10-11 注):\n * - brepkit → 内核原生折线 JSON 通道;\n * - 其余(含 occt)→ compound 句柄采样通道(现状)。\n * 无引擎门禁:分派只选通道,不因内核缺特性报错。\n */\nfunction projectPolylines(shape: Shape, view: ViewSpec): { visible: string[]; hidden: string[] } {\n const solid = brepOf(shape) as BrepHandle | undefined\n if (solid === undefined) {\n throw new Error(\n '[faijs/view-projection] E_BREP_ONLY_INPUT: operation requires a BREP-backed shape ' +\n '(mesh-only input cannot be projected)',\n )\n }\n const api = getBrepApi()\n const cam = resolveCamera(view) as unknown as Camera\n const engineId = getBackends().config.brepEngineId\n if (engineId === 'brepkit') {\n return projectPolylinesNative(api, solid, cam)\n }\n return projectPolylinesCompound(api, solid, cam)\n}\n\n/** projectEdges 的公共调用参数(两方言同构,签名见 brep/engine/primitives.ts)。 */\nfunction projectEdgesArgs(cam: Camera) {\n return [\n { x: cam.position[0], y: cam.position[1], z: cam.position[2] },\n { x: cam.direction[0], y: cam.direction[1], z: cam.direction[2] },\n { x: cam.xAxis[0], y: cam.xAxis[1], z: cam.xAxis[2] },\n true,\n 0.1,\n ] as const\n}\n\n/**\n * brepkit 原生通道:内核 projectEdges 返回 JSON 字符串\n * `{\"visible\":[[x,y,…],…],\"hidden\":[…]}`(每条折线 = 扁平 x,y 点对数组,已是\n * 相机平面 2D 坐标),解析后直接转 SVG path d 串。内核返回非法 JSON 属实现\n * 缺陷,直接抛错暴露(非\"缺特性\",不受无门禁基调豁免)。\n */\nfunction projectPolylinesNative(\n api: ReturnType<typeof getBrepApi>,\n solid: BrepHandle,\n cam: Camera,\n): { visible: string[]; hidden: string[] } {\n const [origin, direction, xAxis] = projectEdgesArgs(cam)\n const raw = api.projectEdges(solid, origin, direction, xAxis, true, 0.1)\n const parsed = parseNativeProjection(raw)\n return {\n visible: parsed.visible.map(polylineToPath),\n hidden: parsed.hidden.map(polylineToPath),\n }\n}\n\n/** 解析 brepkit projectEdges 的折线 JSON(结构错误一律抛错暴露)。 */\nfunction parseNativeProjection(raw: unknown): { visible: number[][]; hidden: number[][] } {\n if (typeof raw !== 'string') {\n throw new Error(\n `[faijs/view-projection] E_PROJECTION_DIALECT: native projectEdges returned ${typeof raw}, expected JSON string`,\n )\n }\n const obj = JSON.parse(raw) as { visible?: unknown; hidden?: unknown }\n const flat = (v: unknown): number[][] => {\n if (!Array.isArray(v)) throw new Error('[faijs/view-projection] E_PROJECTION_DIALECT: malformed native projection JSON')\n return v.filter((p): p is number[] => Array.isArray(p) && p.length >= 4)\n }\n return { visible: flat(obj.visible), hidden: flat(obj.hidden) }\n}\n\n/** 扁平 x,y 点对数组 → SVG path d 串(M + L 序列)。 */\nfunction polylineToPath(poly: number[]): string {\n let d = `M ${poly[0].toFixed(4)} ${poly[1].toFixed(4)}`\n for (let i = 2; i + 1 < poly.length; i += 2) {\n d += ` L ${poly[i].toFixed(4)} ${poly[i + 1].toFixed(4)}`\n }\n return d\n}\n\n/**\n * occt compound 通道(现状,逐字节不变):HLR 输出 6 组 compound 的 arena id,\n * 逐 compound 取边 → 3D 曲线采样 → 相机平面投影。\n * 全部句柄在本函数内释放(compound + 边;输入 shape 不消费)。\n */\nfunction projectPolylinesCompound(\n api: ReturnType<typeof getBrepApi>,\n solid: BrepHandle,\n cam: Camera,\n): { visible: string[]; hidden: string[] } {\n const [origin, direction, xAxis] = projectEdgesArgs(cam)\n const r = api.projectEdges(solid, origin, direction, xAxis, true, 0.1) as ProjectEdgesResult\n\n const out: { visible: string[]; hidden: string[] } = { visible: [], hidden: [] }\n const toHandle = (id: number): BrepHandle => id as BrepHandle\n try {\n for (const [key, group] of COMPOUND_KEYS) {\n const compoundId = r[key]\n if (typeof compoundId !== 'number' || compoundId === 0) continue\n const edges = api.getSubShapes(toHandle(compoundId), 'edge')\n for (const edge of edges) {\n const d = edgeToPath(api, edge, cam)\n if (d !== null) out[group].push(d)\n }\n // 释放 compound slot(幂等)\n try {\n api.release(toHandle(compoundId))\n } catch {\n // already released\n }\n }\n } finally {\n void 0\n }\n return out\n}\n\n/** 单条边 → SVG path d 串(3D 曲线采样折线投影到相机平面)。 */\nfunction edgeToPath(api: ReturnType<typeof getBrepApi>, edge: BrepHandle, cam: Camera): string | null {\n let cp\n try {\n cp = api.curveParameters(edge)\n } catch {\n return null // 退化边(如孤立顶点线)无曲线参数\n }\n const { first, last } = cp\n const span = last - first\n const pts: [number, number][] = []\n for (let i = 0; i < EDGE_SAMPLES; i += 1) {\n const t = first + (span * i) / (EDGE_SAMPLES - 1)\n const p = api.curvePointAtParam(edge, t)\n pts.push(projectTo2D([p.x, p.y, p.z], cam))\n }\n if (pts.length < 2) return null\n let d = `M ${pts[0][0].toFixed(4)} ${pts[0][1].toFixed(4)}`\n for (let i = 1; i < pts.length; i += 1) {\n d += ` L ${pts[i][0].toFixed(4)} ${pts[i][1].toFixed(4)}`\n }\n return d\n}\n\n/** 解析 'minX minY w h' 为数值数组。 */\nfunction parseViewBox(vb: string): [number, number, number, number] | undefined {\n const parts = vb.trim().split(/\\s+/).map(Number)\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n))) return undefined\n return [parts[0], parts[1], parts[2], parts[3]]\n}\n\n/** 折线点集 bbox → viewBox(统一坐标系;margin 再外扩)。 */\nfunction viewBoxOfPaths(paths: string[], margin: number): string {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const d of paths) {\n const nums = d.match(/[-+]?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?/g) ?? []\n for (let i = 0; i + 1 < nums.length; i += 2) {\n const x = Number(nums[i])\n const y = Number(nums[i + 1])\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue\n minX = Math.min(minX, x)\n minY = Math.min(minY, y)\n maxX = Math.max(maxX, x)\n maxY = Math.max(maxY, y)\n }\n }\n if (!Number.isFinite(minX)) return '0 0 0 0' // 空投影(如空 shape)\n return `${minX - margin} ${minY - margin} ${maxX - minX + 2 * margin} ${maxY - minY + 2 * margin}`\n}\n\n/**\n * 单视图投影(结构化结果)。\n *\n * @param shape - 待投影的 faijs Shape(必须带 BREP 槽;mesh-only 输入抛 E_BREP_ONLY_INPUT)。\n * @param view - 视图规格(标准视图 / iso / 轴对平面 / 方向对象)。\n * @param opts - 序列化选项。\n * @returns 结构化投影结果(svg/viewBox/paths/尺寸)。\n */\nexport function projectViewSvg(shape: Shape, view: ViewSpec, opts: ProjectViewOptions = {}): ProjectionSvg {\n const { visible: visiblePaths, hidden: hiddenPaths } = projectPolylines(shape, view)\n const margin = opts.margin ?? 1\n const viewBox = viewBoxOfPaths([...visiblePaths, ...hiddenPaths], margin)\n const parsed = parseViewBox(viewBox) ?? [0, 0, 0, 0]\n const width = opts.width ?? parsed[2]\n const height = opts.height ?? parsed[3]\n const strokeWidth = opts.strokeWidth ?? 1\n const dash = opts.dash ?? '4,4'\n const hiddenOpacity = opts.hiddenOpacity ?? 0.6\n const visibleMarkup = visiblePaths\n .map((d) => `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" />`)\n .join('\\n ')\n const hiddenMarkup = hiddenPaths\n .map(\n (d) =>\n `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" stroke-dasharray=\"${dash}\" opacity=\"${hiddenOpacity}\" />`,\n )\n .join('\\n ')\n const svg = [\n `<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox}\" width=\"${width}\" height=\"${height}\" fill=\"none\" stroke=\"black\" stroke-width=\"0.6%\" vector-effect=\"non-scaling-stroke\">`,\n ` <g stroke=\"#000\" fill=\"none\">`,\n ` ${visibleMarkup}${hiddenMarkup === '' ? '' : `\\n ${hiddenMarkup}`}`,\n ` </g>`,\n `</svg>`,\n ].join('\\n')\n return { svg, viewBox, paths: { visible: visiblePaths, hidden: hiddenPaths }, width, height }\n}\n\n/**\n * 单视图投影 → SVG 线稿字符串(纯数据,不消费/修改 shape;规则 1 下裸调用不消费输入)。\n * @group 查询\n * @inputs 1\n * @async false\n * @qual ok\n * @name projectView\n * @returns SVG 字符串(<svg viewBox=\"…\"> + 可见实线 <path> + 隐藏虚线 <path>)。裸调用 cad.projectView(part0, 'front') 不消费 part0(规则 1),part 仍留在 canvas。\n * @param shape - 目标几何(必须有 BREP 槽;mesh-only 抛 E_BREP_ONLY_INPUT)。type:Shape required:true\n * @param view - 视图规格(同 viewCamera:标准视图名 / iso / 轴对平面 / 方向对象)。type:string|{dir,xAxis?} required:true\n * @param opts.strokeWidth - 可见线宽(stroke-width)。type:number 默认 1\n * @param opts.dash - 隐藏线虚线样式(stroke-dasharray)。type:string 默认 '4,4'\n * @param opts.hiddenOpacity - 隐藏线透明度。type:number 默认 0.6\n * @param opts.margin - viewBox 外扩边距。type:number 默认 1\n * @param opts.width - 输出宽度(缺省 = viewBox 宽度)。type:number\n * @param opts.height - 输出高度(缺省 = viewBox 高度)。type:number\n * @example\n * const svg = cad.projectView(part0, 'front')\n * const svg = cad.projectView(part0, 'iso', { strokeWidth: 1, dash: '4,4', hiddenOpacity: 0.6 })\n */\nexport function projectView(shape: Shape, view: ViewSpec, opts?: ProjectViewOptions): string {\n return projectViewSvg(shape, view, opts).svg\n}\n"]}
@@ -11,7 +11,7 @@
11
11
  * 生命周期:由 executeScript / executePart 创建,执行结束后释放所有中间句柄。
12
12
  * 终端句柄(如果有)由调用方保留用于导出。
13
13
  */
14
- import { getBrepEngine } from './engine/registry.js';
14
+ import { getActiveBrepEngine } from './engine/registry.js';
15
15
  import { ensureOcctDefaultEngine } from './engine/adapters/occt.js';
16
16
  // ─── CAD 格式静态判定 ───
17
17
  /**
@@ -66,7 +66,7 @@ export function createBrepChainState() {
66
66
  */
67
67
  export async function initBrepChainState() {
68
68
  await ensureOcctDefaultEngine();
69
- const engine = await getBrepEngine();
69
+ const engine = await getActiveBrepEngine();
70
70
  return {
71
71
  solidCache: new Map(),
72
72
  kernel: engine.primitives,
@@ -1 +1 @@
1
- {"version":3,"file":"brep-chain.js","sourceRoot":"","sources":["../../src/brep/brep-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAGhE,qBAAqB;AAErB;;;;GAIG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;AAEpD;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,IAA6B,EAC7B,QAAiB;IAEjB,sCAAsC;IACtC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAA;IAE3B,kBAAkB;IAClB,MAAM,MAAM,GAAG,IAAI,CAAC,MAA4B,CAAA;IAChD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;IAC9C,CAAC;IAED,sCAAsC;IACtC,MAAM,SAAS,GAAI,IAAI,CAAC,IAA2B,IAAK,IAAI,CAAC,GAA0B,IAAI,EAAE,CAAA;IAC7F,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;IAC3D,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAC7B,CAAC;AAoDD;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,UAAU,EAAE,IAAI,GAAG,EAAE;QACrB,MAAM,EAAE,IAAI;QACZ,kBAAkB,EAAE,IAAI,GAAG,EAAE;QAC7B,cAAc,EAAE,IAAI,GAAG,EAAE;QACzB,cAAc,EAAE,IAAI,GAAG,EAAE;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,uBAAuB,EAAE,CAAA;IAC/B,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAA;IACpC,OAAO;QACL,UAAU,EAAE,IAAI,GAAG,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC,UAAU;QACzB,kBAAkB,EAAE,IAAI,GAAG,EAAE;QAC7B,cAAc,EAAE,IAAI,GAAG,EAAE;QACzB,cAAc,EAAE,IAAI,GAAG,EAAE;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAqB;IACzD,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;IACH,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;IACxB,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,CAAA;AAC/B,CAAC","sourcesContent":["/**\n * BREP 链状态管理\n *\n * 在语句重放过程中跟踪 OCCT 精确实体句柄。\n * - solidCache: statementId → ShapeHandle(OCCT 实体句柄)\n *\n * BREP 状态是「逐 part」的:一个 part 是否仍为 BREP,\n * 由 solidCache 里是否有它的句柄唯一决定。\n * 不存在全局 brepActive 标志——兄弟 part 互不污染。\n *\n * 生命周期:由 executeScript / executePart 创建,执行结束后释放所有中间句柄。\n * 终端句柄(如果有)由调用方保留用于导出。\n */\n\nimport type { BrepHandle, BrepMeshResult } from './engine/types'\nimport type { BrepEngineApi } from './engine/primitives'\nimport { getBrepEngine } from './engine/registry'\nimport { ensureOcctDefaultEngine } from './engine/adapters/occt'\nimport type { PartName } from '../identity'\n\n// ─── CAD 格式静态判定 ───\n\n/**\n * CAD formats: files in these formats can be imported by the OCCT kernel as\n * exact solids (STEP/STP via importStep, BREP via fromBREP).\n * IGES is intentionally absent — occt-wasm does not link TKDEIGES.\n */\nconst CAD_FORMATS = new Set(['step', 'brep', 'stp'])\n\n/**\n * 静态判定 load 语句的源文件是否为 CAD 格式。\n *\n * 纯函数,按 args.format / 文件路径扩展名判定,\n * 不调用 OCCT、不 try-catch。\n *\n * @param args load 语句的参数表(key/path/url + format)\n * @param isSource buffer 是否为原始字节(可走 BREP 路径的前提)\n * @returns true 表示是 CAD 源(可走 BREP 路径)\n */\nexport function isCadFormat(\n args: Record<string, unknown>,\n isSource: boolean,\n): boolean {\n // 非 source buffer 是转换后的网格数据 → 非 CAD 源\n if (!isSource) return false\n\n // 优先用显式 format 参数\n const format = args.format as string | undefined\n if (format) {\n return CAD_FORMATS.has(format.toLowerCase())\n }\n\n // P4-1:按 path/url 的扩展名判定(fileRef 已移除)\n const pathOrUrl = (args.path as string | undefined) ?? (args.url as string | undefined) ?? ''\n const ext = pathOrUrl.split('.').pop()?.toLowerCase() ?? ''\n return CAD_FORMATS.has(ext)\n}\n\n// ─── BREP 链状态 ───\n\n/**\n * BREP 链状态:在语句重放过程中跟踪 OCCT 实体句柄。\n *\n * BREP 状态是「逐 part」的:\n * - solidCache 中存在该 part 的句柄 → 该 part 仍为 BREP\n * - solidCache 中不存在该 part 的句柄 → 该 part 已降级为 mesh\n *\n * 不再有全局 brepActive / breakReason 字段。\n * 一个 part 失去 BREP 状态,当且仅当:\n * - 它被 knurl/sdf(mesh-only op)产生(不写 solidCache),或\n * - 它的上游输入中至少有一个没有 BREP 实体。\n * 兄弟 part 之间互不污染。\n */\nexport interface BrepChainState {\n /** BREP 实体句柄缓存(PartName → BrepHandle)。存在即该 part 仍为 BREP;缺失即已降级为 mesh。 */\n solidCache: Map<PartName, BrepHandle>\n /** BREP 引擎实例(mesh 模式为 null —— 等价于「无 BREP 能力」)。 */\n kernel: BrepEngineApi | null\n /**\n * P5-2: 面演化映射缓存(statementId → FaceEvolution)。\n *\n * 每个布尔/变换操作执行后,存储面 ordinal 映射(输入 ordinal → 输出 ordinal 列表)。\n * 用于面引用在确定性重放下的稳定性验证和未来的面迁移功能。\n *\n * FaceEvolution = Map<number, number[]>(inOrdinal → outOrdinal[])\n */\n faceEvolutionCache?: Map<PartName, Map<number, number[]>>\n /**\n * 拓扑命名 RoleTable 持久缓存(PartName → RoleTable,§2.3 of\n *\n * 与 faceEvolutionCache 完全同生命周期:runtime 实例级持久、按语句增量同步、\n * dispose 一并 clear。RoleTable 是执行内状态,不序列化、不进 .fai.js、不进\n * ExecutionResult.naming(宿主只拿 §3.7 的纯数据)。hash 是会话内活句柄索引,\n * 跨实例/会话重建时整体重建。\n */\n roleTableCache?: Map<PartName, unknown>\n /**\n * 三角化缓存:PartName → WasmMesh(含 faceGroups)。\n *\n * BREP op 调用 solidToShape 三角化后,把完整 WasmMesh 缓存到此 Map。\n * buildBrepTopology 复用此缓存,避免二次 meshShape 导致拓扑 mesh ≠ 显示 mesh。\n *\n * 规则 1:拓扑数据生成所使用的 mesh,必须是当前用户看到的 mesh。\n * 三角化和拓扑生成都是 faijs 的职责,宿主不参与。\n */\n meshShapeCache?: Map<PartName, BrepMeshResult>\n}\n\n/**\n * Create an empty BREP chain state with no cached solids and no kernel.\n * @returns a new empty BrepChainState.\n */\nexport function createBrepChainState(): BrepChainState {\n return {\n solidCache: new Map(),\n kernel: null,\n faceEvolutionCache: new Map(),\n roleTableCache: new Map(),\n meshShapeCache: new Map(),\n }\n}\n\n/**\n * Initialize the BREP chain state asynchronously: resolve the active BREP\n * engine from the registry and initialize its kernel.\n * OCCT is the built-in default engine: when no engine is registered it is\n * assembled first (ensureOcctDefaultEngine is idempotent).\n * @returns a Promise resolving to an initialized BrepChainState.\n */\nexport async function initBrepChainState(): Promise<BrepChainState> {\n await ensureOcctDefaultEngine()\n const engine = await getBrepEngine()\n return {\n solidCache: new Map(),\n kernel: engine.primitives,\n faceEvolutionCache: new Map(),\n roleTableCache: new Map(),\n meshShapeCache: new Map(),\n }\n}\n\n/**\n * 释放 BREP 链状态中的所有句柄并清空 solidCache。\n *\n * 释放只发生在「重算顶替 / dispose」,不再需要\"保留终端、释放中间\"的选择性语义,\n * 因此 keepIds 参数已删除——调用方想保留任何 solid 时,不应再调用本函数。\n *\n * @param state BREP 链状态\n */\nexport function releaseBrepChainState(state: BrepChainState): void {\n for (const [, handle] of state.solidCache) {\n try {\n state.kernel?.release(handle)\n } catch {\n // 句柄可能已释放,忽略\n }\n }\n state.solidCache.clear()\n state.meshShapeCache?.clear()\n}\n"]}
1
+ {"version":3,"file":"brep-chain.js","sourceRoot":"","sources":["../../src/brep/brep-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAGhE,qBAAqB;AAErB;;;;GAIG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;AAEpD;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,IAA6B,EAC7B,QAAiB;IAEjB,sCAAsC;IACtC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAA;IAE3B,kBAAkB;IAClB,MAAM,MAAM,GAAG,IAAI,CAAC,MAA4B,CAAA;IAChD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;IAC9C,CAAC;IAED,sCAAsC;IACtC,MAAM,SAAS,GAAI,IAAI,CAAC,IAA2B,IAAK,IAAI,CAAC,GAA0B,IAAI,EAAE,CAAA;IAC7F,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;IAC3D,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAC7B,CAAC;AAoDD;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,UAAU,EAAE,IAAI,GAAG,EAAE;QACrB,MAAM,EAAE,IAAI;QACZ,kBAAkB,EAAE,IAAI,GAAG,EAAE;QAC7B,cAAc,EAAE,IAAI,GAAG,EAAE;QACzB,cAAc,EAAE,IAAI,GAAG,EAAE;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,uBAAuB,EAAE,CAAA;IAC/B,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAC1C,OAAO;QACL,UAAU,EAAE,IAAI,GAAG,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC,UAAU;QACzB,kBAAkB,EAAE,IAAI,GAAG,EAAE;QAC7B,cAAc,EAAE,IAAI,GAAG,EAAE;QACzB,cAAc,EAAE,IAAI,GAAG,EAAE;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAqB;IACzD,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;IACH,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;IACxB,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,CAAA;AAC/B,CAAC","sourcesContent":["/**\n * BREP 链状态管理\n *\n * 在语句重放过程中跟踪 OCCT 精确实体句柄。\n * - solidCache: statementId → ShapeHandle(OCCT 实体句柄)\n *\n * BREP 状态是「逐 part」的:一个 part 是否仍为 BREP,\n * 由 solidCache 里是否有它的句柄唯一决定。\n * 不存在全局 brepActive 标志——兄弟 part 互不污染。\n *\n * 生命周期:由 executeScript / executePart 创建,执行结束后释放所有中间句柄。\n * 终端句柄(如果有)由调用方保留用于导出。\n */\n\nimport type { BrepHandle, BrepMeshResult } from './engine/types'\nimport type { BrepEngineApi } from './engine/primitives'\nimport { getActiveBrepEngine } from './engine/registry'\nimport { ensureOcctDefaultEngine } from './engine/adapters/occt'\nimport type { PartName } from '../identity'\n\n// ─── CAD 格式静态判定 ───\n\n/**\n * CAD formats: files in these formats can be imported by the OCCT kernel as\n * exact solids (STEP/STP via importStep, BREP via fromBREP).\n * IGES is intentionally absent — occt-wasm does not link TKDEIGES.\n */\nconst CAD_FORMATS = new Set(['step', 'brep', 'stp'])\n\n/**\n * 静态判定 load 语句的源文件是否为 CAD 格式。\n *\n * 纯函数,按 args.format / 文件路径扩展名判定,\n * 不调用 OCCT、不 try-catch。\n *\n * @param args load 语句的参数表(key/path/url + format)\n * @param isSource buffer 是否为原始字节(可走 BREP 路径的前提)\n * @returns true 表示是 CAD 源(可走 BREP 路径)\n */\nexport function isCadFormat(\n args: Record<string, unknown>,\n isSource: boolean,\n): boolean {\n // 非 source buffer 是转换后的网格数据 → 非 CAD 源\n if (!isSource) return false\n\n // 优先用显式 format 参数\n const format = args.format as string | undefined\n if (format) {\n return CAD_FORMATS.has(format.toLowerCase())\n }\n\n // P4-1:按 path/url 的扩展名判定(fileRef 已移除)\n const pathOrUrl = (args.path as string | undefined) ?? (args.url as string | undefined) ?? ''\n const ext = pathOrUrl.split('.').pop()?.toLowerCase() ?? ''\n return CAD_FORMATS.has(ext)\n}\n\n// ─── BREP 链状态 ───\n\n/**\n * BREP 链状态:在语句重放过程中跟踪 OCCT 实体句柄。\n *\n * BREP 状态是「逐 part」的:\n * - solidCache 中存在该 part 的句柄 → 该 part 仍为 BREP\n * - solidCache 中不存在该 part 的句柄 → 该 part 已降级为 mesh\n *\n * 不再有全局 brepActive / breakReason 字段。\n * 一个 part 失去 BREP 状态,当且仅当:\n * - 它被 knurl/sdf(mesh-only op)产生(不写 solidCache),或\n * - 它的上游输入中至少有一个没有 BREP 实体。\n * 兄弟 part 之间互不污染。\n */\nexport interface BrepChainState {\n /** BREP 实体句柄缓存(PartName → BrepHandle)。存在即该 part 仍为 BREP;缺失即已降级为 mesh。 */\n solidCache: Map<PartName, BrepHandle>\n /** BREP 引擎实例(mesh 模式为 null —— 等价于「无 BREP 能力」)。 */\n kernel: BrepEngineApi | null\n /**\n * P5-2: 面演化映射缓存(statementId → FaceEvolution)。\n *\n * 每个布尔/变换操作执行后,存储面 ordinal 映射(输入 ordinal → 输出 ordinal 列表)。\n * 用于面引用在确定性重放下的稳定性验证和未来的面迁移功能。\n *\n * FaceEvolution = Map<number, number[]>(inOrdinal → outOrdinal[])\n */\n faceEvolutionCache?: Map<PartName, Map<number, number[]>>\n /**\n * 拓扑命名 RoleTable 持久缓存(PartName → RoleTable,§2.3 of\n *\n * 与 faceEvolutionCache 完全同生命周期:runtime 实例级持久、按语句增量同步、\n * dispose 一并 clear。RoleTable 是执行内状态,不序列化、不进 .fai.js、不进\n * ExecutionResult.naming(宿主只拿 §3.7 的纯数据)。hash 是会话内活句柄索引,\n * 跨实例/会话重建时整体重建。\n */\n roleTableCache?: Map<PartName, unknown>\n /**\n * 三角化缓存:PartName → WasmMesh(含 faceGroups)。\n *\n * BREP op 调用 solidToShape 三角化后,把完整 WasmMesh 缓存到此 Map。\n * buildBrepTopology 复用此缓存,避免二次 meshShape 导致拓扑 mesh ≠ 显示 mesh。\n *\n * 规则 1:拓扑数据生成所使用的 mesh,必须是当前用户看到的 mesh。\n * 三角化和拓扑生成都是 faijs 的职责,宿主不参与。\n */\n meshShapeCache?: Map<PartName, BrepMeshResult>\n}\n\n/**\n * Create an empty BREP chain state with no cached solids and no kernel.\n * @returns a new empty BrepChainState.\n */\nexport function createBrepChainState(): BrepChainState {\n return {\n solidCache: new Map(),\n kernel: null,\n faceEvolutionCache: new Map(),\n roleTableCache: new Map(),\n meshShapeCache: new Map(),\n }\n}\n\n/**\n * Initialize the BREP chain state asynchronously: resolve the active BREP\n * engine from the registry and initialize its kernel.\n * OCCT is the built-in default engine: when no engine is registered it is\n * assembled first (ensureOcctDefaultEngine is idempotent).\n * @returns a Promise resolving to an initialized BrepChainState.\n */\nexport async function initBrepChainState(): Promise<BrepChainState> {\n await ensureOcctDefaultEngine()\n const engine = await getActiveBrepEngine()\n return {\n solidCache: new Map(),\n kernel: engine.primitives,\n faceEvolutionCache: new Map(),\n roleTableCache: new Map(),\n meshShapeCache: new Map(),\n }\n}\n\n/**\n * 释放 BREP 链状态中的所有句柄并清空 solidCache。\n *\n * 释放只发生在「重算顶替 / dispose」,不再需要\"保留终端、释放中间\"的选择性语义,\n * 因此 keepIds 参数已删除——调用方想保留任何 solid 时,不应再调用本函数。\n *\n * @param state BREP 链状态\n */\nexport function releaseBrepChainState(state: BrepChainState): void {\n for (const [, handle] of state.solidCache) {\n try {\n state.kernel?.release(handle)\n } catch {\n // 句柄可能已释放,忽略\n }\n }\n state.solidCache.clear()\n state.meshShapeCache?.clear()\n}\n"]}
@@ -396,7 +396,7 @@ export declare function loadBrepAssembly(kernel: BrepEngineApi, buffer: ArrayBuf
396
396
  *
397
397
  * 分派规则(静态,无运行时回退):XCAF(`STEPCAFControl_Reader`)是 occt 内核的
398
398
  * 装配读取器,brepkit 没有;调用方按当前引擎 id 选择本函数还是 XCAF 版本
399
- * (`cad.load` 见 `packages/faijs-extra/src/ops/load.ts`),不靠 try-catch 探测。
399
+ * (`cad.load` 见 `packages/core/src/extra/ops/load.ts`),不靠 try-catch 探测。
400
400
  *
401
401
  * 句柄归属:返回的每个 `part.solid` 即内核枚举出的实体本身(生命周期交给调用方,
402
402
  * `fromBrep` 绑定后归 brepChain)。顶层包装句柄在本函数内释放——但**若顶层句柄
@@ -765,7 +765,7 @@ export async function loadBrepAssembly(kernel, buffer) {
765
765
  *
766
766
  * 分派规则(静态,无运行时回退):XCAF(`STEPCAFControl_Reader`)是 occt 内核的
767
767
  * 装配读取器,brepkit 没有;调用方按当前引擎 id 选择本函数还是 XCAF 版本
768
- * (`cad.load` 见 `packages/faijs-extra/src/ops/load.ts`),不靠 try-catch 探测。
768
+ * (`cad.load` 见 `packages/core/src/extra/ops/load.ts`),不靠 try-catch 探测。
769
769
  *
770
770
  * 句柄归属:返回的每个 `part.solid` 即内核枚举出的实体本身(生命周期交给调用方,
771
771
  * `fromBrep` 绑定后归 brepChain)。顶层包装句柄在本函数内释放——但**若顶层句柄