@faicad/faijs 0.22.2 → 0.29.5

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 (488) hide show
  1. package/LICENSE +202 -28
  2. package/dist/api/api-namespace.d.ts +5 -5
  3. package/dist/api/api-namespace.d.ts.map +1 -1
  4. package/dist/api/api-namespace.js +4 -4
  5. package/dist/api/api-namespace.js.map +1 -1
  6. package/dist/api/appearance.d.ts +138 -0
  7. package/dist/api/appearance.d.ts.map +1 -0
  8. package/dist/api/appearance.js +230 -0
  9. package/dist/api/appearance.js.map +1 -0
  10. package/dist/api/assert.d.ts +2 -2
  11. package/dist/api/assert.js +8 -8
  12. package/dist/api/assert.js.map +1 -1
  13. package/dist/api/asset.d.ts +1 -1
  14. package/dist/api/asset.js +2 -2
  15. package/dist/api/asset.js.map +1 -1
  16. package/dist/api/boolean.d.ts +1 -1
  17. package/dist/api/boolean.d.ts.map +1 -1
  18. package/dist/api/boolean.js +128 -16
  19. package/dist/api/boolean.js.map +1 -1
  20. package/dist/api/cadquery-selectors/borrow-bridge.d.ts +14 -0
  21. package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -0
  22. package/dist/api/cadquery-selectors/borrow-bridge.js +52 -0
  23. package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -0
  24. package/dist/api/cadquery-selectors/edge.d.ts +40 -0
  25. package/dist/api/cadquery-selectors/edge.d.ts.map +1 -0
  26. package/dist/api/cadquery-selectors/edge.js +70 -0
  27. package/dist/api/cadquery-selectors/edge.js.map +1 -0
  28. package/dist/api/cadquery-selectors/entity.d.ts +121 -0
  29. package/dist/api/cadquery-selectors/entity.d.ts.map +1 -0
  30. package/dist/api/cadquery-selectors/entity.js +167 -0
  31. package/dist/api/cadquery-selectors/entity.js.map +1 -0
  32. package/dist/api/cadquery-selectors/face.d.ts +33 -0
  33. package/dist/api/cadquery-selectors/face.d.ts.map +1 -0
  34. package/dist/api/cadquery-selectors/face.js +353 -0
  35. package/dist/api/cadquery-selectors/face.js.map +1 -0
  36. package/dist/api/cadquery-selectors/grammar.d.ts +50 -0
  37. package/dist/api/cadquery-selectors/grammar.d.ts.map +1 -0
  38. package/dist/api/cadquery-selectors/grammar.js +345 -0
  39. package/dist/api/cadquery-selectors/grammar.js.map +1 -0
  40. package/dist/api/cadquery-selectors/index.d.ts +18 -0
  41. package/dist/api/cadquery-selectors/index.d.ts.map +1 -0
  42. package/dist/api/cadquery-selectors/index.js +17 -0
  43. package/dist/api/cadquery-selectors/index.js.map +1 -0
  44. package/dist/api/cadquery-selectors/predicates.d.ts +76 -0
  45. package/dist/api/cadquery-selectors/predicates.d.ts.map +1 -0
  46. package/dist/api/cadquery-selectors/predicates.js +85 -0
  47. package/dist/api/cadquery-selectors/predicates.js.map +1 -0
  48. package/dist/api/cadquery-selectors/resolve.d.ts +41 -0
  49. package/dist/api/cadquery-selectors/resolve.d.ts.map +1 -0
  50. package/dist/api/cadquery-selectors/resolve.js +243 -0
  51. package/dist/api/cadquery-selectors/resolve.js.map +1 -0
  52. package/dist/api/cadquery-selectors/types.d.ts +96 -0
  53. package/dist/api/cadquery-selectors/types.d.ts.map +1 -0
  54. package/dist/api/cadquery-selectors/types.js +11 -0
  55. package/dist/api/cadquery-selectors/types.js.map +1 -0
  56. package/dist/api/chamfer.d.ts +13 -5
  57. package/dist/api/chamfer.d.ts.map +1 -1
  58. package/dist/api/chamfer.js +63 -7
  59. package/dist/api/chamfer.js.map +1 -1
  60. package/dist/api/compound-geom.d.ts +1 -1
  61. package/dist/api/compound-geom.js +1 -1
  62. package/dist/api/compound-geom.js.map +1 -1
  63. package/dist/api/draft.d.ts +1 -1
  64. package/dist/api/draft.js +1 -1
  65. package/dist/api/draft.js.map +1 -1
  66. package/dist/api/edge-ref.d.ts +1 -1
  67. package/dist/api/edge-ref.d.ts.map +1 -1
  68. package/dist/api/edge-ref.js +11 -3
  69. package/dist/api/edge-ref.js.map +1 -1
  70. package/dist/api/engrave.d.ts +1 -1
  71. package/dist/api/engrave.js +7 -7
  72. package/dist/api/engrave.js.map +1 -1
  73. package/dist/api/extrude.d.ts +6 -1
  74. package/dist/api/extrude.d.ts.map +1 -1
  75. package/dist/api/extrude.js +59 -5
  76. package/dist/api/extrude.js.map +1 -1
  77. package/dist/api/face-ref.d.ts +1 -1
  78. package/dist/api/face-ref.js +1 -1
  79. package/dist/api/face-ref.js.map +1 -1
  80. package/dist/api/feature-repair.d.ts +1 -1
  81. package/dist/api/feature-repair.js +1 -1
  82. package/dist/api/feature-repair.js.map +1 -1
  83. package/dist/api/fillet-variable.d.ts +1 -1
  84. package/dist/api/fillet-variable.js +1 -1
  85. package/dist/api/fillet-variable.js.map +1 -1
  86. package/dist/api/fillet.d.ts +28 -8
  87. package/dist/api/fillet.d.ts.map +1 -1
  88. package/dist/api/fillet.js +64 -9
  89. package/dist/api/fillet.js.map +1 -1
  90. package/dist/api/geom.d.ts +1 -1
  91. package/dist/api/geom.js +1 -1
  92. package/dist/api/geom.js.map +1 -1
  93. package/dist/api/helix.d.ts +1 -1
  94. package/dist/api/helix.js +1 -1
  95. package/dist/api/helix.js.map +1 -1
  96. package/dist/api/import-brep.d.ts +20 -2
  97. package/dist/api/import-brep.d.ts.map +1 -1
  98. package/dist/api/import-brep.js +28 -3
  99. package/dist/api/import-brep.js.map +1 -1
  100. package/dist/api/import-step.d.ts +17 -2
  101. package/dist/api/import-step.d.ts.map +1 -1
  102. package/dist/api/import-step.js +51 -3
  103. package/dist/api/import-step.js.map +1 -1
  104. package/dist/api/index.d.ts +6 -1
  105. package/dist/api/index.d.ts.map +1 -1
  106. package/dist/api/index.js +7 -2
  107. package/dist/api/index.js.map +1 -1
  108. package/dist/api/internal/compat-op.js +1 -1
  109. package/dist/api/internal/compat-op.js.map +1 -1
  110. package/dist/api/internal/mesh-solid-op.d.ts +236 -0
  111. package/dist/api/internal/mesh-solid-op.d.ts.map +1 -0
  112. package/dist/api/internal/mesh-solid-op.js +352 -0
  113. package/dist/api/internal/mesh-solid-op.js.map +1 -0
  114. package/dist/api/internal/svg-asset-resolver.d.ts +1 -1
  115. package/dist/api/internal/svg-asset-resolver.js +1 -1
  116. package/dist/api/internal/svg-asset-resolver.js.map +1 -1
  117. package/dist/api/knurl.d.ts +1 -1
  118. package/dist/api/knurl.js +2 -2
  119. package/dist/api/knurl.js.map +1 -1
  120. package/dist/api/loft.d.ts +1 -1
  121. package/dist/api/loft.js +1 -1
  122. package/dist/api/loft.js.map +1 -1
  123. package/dist/api/measurement/index.d.ts +9 -5
  124. package/dist/api/measurement/index.d.ts.map +1 -1
  125. package/dist/api/measurement/index.js +47 -20
  126. package/dist/api/measurement/index.js.map +1 -1
  127. package/dist/api/meta.d.ts +93 -0
  128. package/dist/api/meta.d.ts.map +1 -0
  129. package/dist/api/meta.js +99 -0
  130. package/dist/api/meta.js.map +1 -0
  131. package/dist/api/pattern.d.ts +5 -3
  132. package/dist/api/pattern.d.ts.map +1 -1
  133. package/dist/api/pattern.js +32 -4
  134. package/dist/api/pattern.js.map +1 -1
  135. package/dist/api/place.d.ts +1 -1
  136. package/dist/api/place.js +1 -1
  137. package/dist/api/place.js.map +1 -1
  138. package/dist/api/primitives.d.ts +1 -1
  139. package/dist/api/primitives.d.ts.map +1 -1
  140. package/dist/api/primitives.js +119 -4
  141. package/dist/api/primitives.js.map +1 -1
  142. package/dist/api/profile.d.ts +39 -12
  143. package/dist/api/profile.d.ts.map +1 -1
  144. package/dist/api/profile.js +4 -4
  145. package/dist/api/profile.js.map +1 -1
  146. package/dist/api/reconcile.d.ts +1 -1
  147. package/dist/api/reconcile.js +1 -1
  148. package/dist/api/reconcile.js.map +1 -1
  149. package/dist/api/replicate.d.ts.map +1 -1
  150. package/dist/api/replicate.js +122 -1
  151. package/dist/api/replicate.js.map +1 -1
  152. package/dist/api/screw.d.ts +1 -1
  153. package/dist/api/screw.js +3 -3
  154. package/dist/api/screw.js.map +1 -1
  155. package/dist/api/sdf.d.ts +1 -1
  156. package/dist/api/sdf.js +2 -2
  157. package/dist/api/sdf.js.map +1 -1
  158. package/dist/api/section-by-plane.d.ts +1 -1
  159. package/dist/api/section-by-plane.d.ts.map +1 -1
  160. package/dist/api/section-by-plane.js +2 -1
  161. package/dist/api/section-by-plane.js.map +1 -1
  162. package/dist/api/shell.d.ts +11 -4
  163. package/dist/api/shell.d.ts.map +1 -1
  164. package/dist/api/shell.js +53 -7
  165. package/dist/api/shell.js.map +1 -1
  166. package/dist/api/sketch-on-face.d.ts +41 -0
  167. package/dist/api/sketch-on-face.d.ts.map +1 -1
  168. package/dist/api/sketch-on-face.js +100 -1
  169. package/dist/api/sketch-on-face.js.map +1 -1
  170. package/dist/api/sketch-on-plane.d.ts +7 -5
  171. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  172. package/dist/api/sketch-on-plane.js +6 -7
  173. package/dist/api/sketch-on-plane.js.map +1 -1
  174. package/dist/api/split-by-plane.d.ts +1 -1
  175. package/dist/api/split-by-plane.d.ts.map +1 -1
  176. package/dist/api/split-by-plane.js +2 -1
  177. package/dist/api/split-by-plane.js.map +1 -1
  178. package/dist/api/split.d.ts +1 -1
  179. package/dist/api/split.js +2 -2
  180. package/dist/api/split.js.map +1 -1
  181. package/dist/api/sweep.d.ts +1 -1
  182. package/dist/api/sweep.js +1 -1
  183. package/dist/api/sweep.js.map +1 -1
  184. package/dist/api/thicken.d.ts +1 -1
  185. package/dist/api/thicken.js +1 -1
  186. package/dist/api/thicken.js.map +1 -1
  187. package/dist/api/topo-resolve.d.ts +74 -1
  188. package/dist/api/topo-resolve.d.ts.map +1 -1
  189. package/dist/api/topo-resolve.js +180 -2
  190. package/dist/api/topo-resolve.js.map +1 -1
  191. package/dist/api/transform.d.ts +5 -1
  192. package/dist/api/transform.d.ts.map +1 -1
  193. package/dist/api/transform.js +62 -11
  194. package/dist/api/transform.js.map +1 -1
  195. package/dist/api/wire.d.ts +1 -1
  196. package/dist/api/wire.js +1 -1
  197. package/dist/api/wire.js.map +1 -1
  198. package/dist/brep/brep-ops.d.ts +9 -7
  199. package/dist/brep/brep-ops.d.ts.map +1 -1
  200. package/dist/brep/brep-ops.js +50 -26
  201. package/dist/brep/brep-ops.js.map +1 -1
  202. package/dist/brep/brep-topology.d.ts +5 -4
  203. package/dist/brep/brep-topology.d.ts.map +1 -1
  204. package/dist/brep/brep-topology.js +6 -5
  205. package/dist/brep/brep-topology.js.map +1 -1
  206. package/dist/brep/effective-deflection.d.ts +35 -0
  207. package/dist/brep/effective-deflection.d.ts.map +1 -0
  208. package/dist/brep/effective-deflection.js +49 -0
  209. package/dist/brep/effective-deflection.js.map +1 -0
  210. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  211. package/dist/brep/engine/adapters/brep-mock.js +27 -0
  212. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  213. package/dist/brep/engine/adapters/brepkit.d.ts +18 -0
  214. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  215. package/dist/brep/engine/adapters/brepkit.js +46 -1
  216. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  217. package/dist/brep/engine/adapters/occt.d.ts +1 -1
  218. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  219. package/dist/brep/engine/adapters/occt.js +4 -2
  220. package/dist/brep/engine/adapters/occt.js.map +1 -1
  221. package/dist/brep/engine/primitives.d.ts +29 -7
  222. package/dist/brep/engine/primitives.d.ts.map +1 -1
  223. package/dist/brep/engine/primitives.js.map +1 -1
  224. package/dist/brep/engine/registry.d.ts +24 -1
  225. package/dist/brep/engine/registry.d.ts.map +1 -1
  226. package/dist/brep/engine/registry.js +24 -0
  227. package/dist/brep/engine/registry.js.map +1 -1
  228. package/dist/brep/engine/types.d.ts +54 -3
  229. package/dist/brep/engine/types.d.ts.map +1 -1
  230. package/dist/brep/engine/types.js +10 -0
  231. package/dist/brep/engine/types.js.map +1 -1
  232. package/dist/brep/export/export-model.d.ts +40 -0
  233. package/dist/brep/export/export-model.d.ts.map +1 -1
  234. package/dist/brep/export/export-model.js +274 -30
  235. package/dist/brep/export/export-model.js.map +1 -1
  236. package/dist/brep/export/step-meta-header.d.ts +102 -0
  237. package/dist/brep/export/step-meta-header.d.ts.map +1 -0
  238. package/dist/brep/export/step-meta-header.js +225 -0
  239. package/dist/brep/export/step-meta-header.js.map +1 -0
  240. package/dist/brep/export/step.d.ts +5 -1
  241. package/dist/brep/export/step.d.ts.map +1 -1
  242. package/dist/brep/export/step.js +11 -2
  243. package/dist/brep/export/step.js.map +1 -1
  244. package/dist/brep/face-evolution.d.ts +1 -1
  245. package/dist/brep/face-evolution.d.ts.map +1 -1
  246. package/dist/brep/face-evolution.js +20 -1
  247. package/dist/brep/face-evolution.js.map +1 -1
  248. package/dist/brep/handle-bridge.d.ts +1 -1
  249. package/dist/brep/handle-bridge.js +1 -1
  250. package/dist/brep/handle-bridge.js.map +1 -1
  251. package/dist/brep/mesh-solid.d.ts +218 -0
  252. package/dist/brep/mesh-solid.d.ts.map +1 -0
  253. package/dist/brep/mesh-solid.js +229 -0
  254. package/dist/brep/mesh-solid.js.map +1 -0
  255. package/dist/brep/text/fontRegistry.d.ts +32 -1
  256. package/dist/brep/text/fontRegistry.d.ts.map +1 -1
  257. package/dist/brep/text/fontRegistry.js +51 -1
  258. package/dist/brep/text/fontRegistry.js.map +1 -1
  259. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  260. package/dist/brep/text/text-to-solid.js +8 -3
  261. package/dist/brep/text/text-to-solid.js.map +1 -1
  262. package/dist/brepkit-kernel/brepkitKernel.d.ts +18 -2
  263. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  264. package/dist/brepkit-kernel/brepkitKernel.js +449 -123
  265. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  266. package/dist/brepkit-kernel/brepkitWasm.d.ts +8 -0
  267. package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
  268. package/dist/brepkit-kernel/brepkitWasm.js +10 -0
  269. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  270. package/dist/browser-host/browser-font-provider.d.ts +12 -0
  271. package/dist/browser-host/browser-font-provider.d.ts.map +1 -1
  272. package/dist/browser-host/browser-font-provider.js +25 -0
  273. package/dist/browser-host/browser-font-provider.js.map +1 -1
  274. package/dist/browser.d.ts +6 -3
  275. package/dist/browser.d.ts.map +1 -1
  276. package/dist/browser.js +10 -3
  277. package/dist/browser.js.map +1 -1
  278. package/dist/cad-runtime/backend-dispatch.d.ts +28 -3
  279. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  280. package/dist/cad-runtime/backend-dispatch.js +119 -4
  281. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  282. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  283. package/dist/cad-runtime/direct-executor.d.ts +15 -3
  284. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  285. package/dist/cad-runtime/direct-executor.js +33 -1
  286. package/dist/cad-runtime/direct-executor.js.map +1 -1
  287. package/dist/cad-runtime/ports.d.ts +3 -3
  288. package/dist/cad-runtime/ports.d.ts.map +1 -1
  289. package/dist/cad-runtime/ports.js.map +1 -1
  290. package/dist/cad-runtime/preview-exec.d.ts +4 -4
  291. package/dist/cad-runtime/preview-exec.js +2 -2
  292. package/dist/cad-runtime/preview-exec.js.map +1 -1
  293. package/dist/cad-runtime/runtime.d.ts +42 -7
  294. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  295. package/dist/cad-runtime/runtime.js +68 -5
  296. package/dist/cad-runtime/runtime.js.map +1 -1
  297. package/dist/define-op.d.ts +15 -1
  298. package/dist/define-op.d.ts.map +1 -1
  299. package/dist/define-op.js +73 -2
  300. package/dist/define-op.js.map +1 -1
  301. package/dist/env-agnostic.d.ts +2 -2
  302. package/dist/env-agnostic.d.ts.map +1 -1
  303. package/dist/env-agnostic.js +1 -1
  304. package/dist/env-agnostic.js.map +1 -1
  305. package/dist/geometry2d/adapt.d.ts +39 -4
  306. package/dist/geometry2d/adapt.d.ts.map +1 -1
  307. package/dist/geometry2d/adapt.js +14 -3
  308. package/dist/geometry2d/adapt.js.map +1 -1
  309. package/dist/geometry2d/blueprint.d.ts +2 -2
  310. package/dist/geometry2d/blueprint.js +2 -2
  311. package/dist/geometry2d/blueprint.js.map +1 -1
  312. package/dist/geometry2d/bridge/lift-on-plane.d.ts +18 -8
  313. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  314. package/dist/geometry2d/bridge/lift-on-plane.js +65 -12
  315. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  316. package/dist/geometry2d/bridge/plane.d.ts +17 -0
  317. package/dist/geometry2d/bridge/plane.d.ts.map +1 -1
  318. package/dist/geometry2d/bridge/plane.js +22 -0
  319. package/dist/geometry2d/bridge/plane.js.map +1 -1
  320. package/dist/geometry2d/curve2d.d.ts +25 -0
  321. package/dist/geometry2d/curve2d.d.ts.map +1 -1
  322. package/dist/geometry2d/curve2d.js +41 -5
  323. package/dist/geometry2d/curve2d.js.map +1 -1
  324. package/dist/index.d.ts +6 -2
  325. package/dist/index.d.ts.map +1 -1
  326. package/dist/index.js +10 -3
  327. package/dist/index.js.map +1 -1
  328. package/dist/io/bytes-node.d.ts +11 -0
  329. package/dist/io/bytes-node.d.ts.map +1 -0
  330. package/dist/io/bytes-node.js +28 -0
  331. package/dist/io/bytes-node.js.map +1 -0
  332. package/dist/io/bytes.d.ts +33 -0
  333. package/dist/io/bytes.d.ts.map +1 -0
  334. package/dist/io/bytes.js +41 -0
  335. package/dist/io/bytes.js.map +1 -0
  336. package/dist/io/fai-zip/container-read.d.ts +102 -0
  337. package/dist/io/fai-zip/container-read.d.ts.map +1 -0
  338. package/dist/io/fai-zip/container-read.js +305 -0
  339. package/dist/io/fai-zip/container-read.js.map +1 -0
  340. package/dist/io/fai-zip/container-write.d.ts +70 -0
  341. package/dist/io/fai-zip/container-write.d.ts.map +1 -0
  342. package/dist/io/fai-zip/container-write.js +186 -0
  343. package/dist/io/fai-zip/container-write.js.map +1 -0
  344. package/dist/io/fai-zip/container.d.ts +107 -0
  345. package/dist/io/fai-zip/container.d.ts.map +1 -0
  346. package/dist/io/fai-zip/container.js +89 -0
  347. package/dist/io/fai-zip/container.js.map +1 -0
  348. package/dist/io/fai-zip/index.d.ts +18 -0
  349. package/dist/io/fai-zip/index.d.ts.map +1 -0
  350. package/dist/io/fai-zip/index.js +4 -0
  351. package/dist/io/fai-zip/index.js.map +1 -0
  352. package/dist/io/index.d.ts +10 -0
  353. package/dist/io/index.d.ts.map +1 -0
  354. package/dist/io/index.js +13 -0
  355. package/dist/io/index.js.map +1 -0
  356. package/dist/io/zip.d.ts +68 -0
  357. package/dist/io/zip.d.ts.map +1 -0
  358. package/dist/io/zip.js +147 -0
  359. package/dist/io/zip.js.map +1 -0
  360. package/dist/lang/code-to-args.d.ts +1 -1
  361. package/dist/lang/code-to-args.js +1 -1
  362. package/dist/lang/code-to-args.js.map +1 -1
  363. package/dist/lang/metadata-extractor.d.ts.map +1 -1
  364. package/dist/lang/metadata-extractor.js +2 -21
  365. package/dist/lang/metadata-extractor.js.map +1 -1
  366. package/dist/lang/statement-summary.d.ts +1 -1
  367. package/dist/lang/statement-summary.js +1 -1
  368. package/dist/lang/statement-summary.js.map +1 -1
  369. package/dist/lang/types.d.ts +6 -7
  370. package/dist/lang/types.d.ts.map +1 -1
  371. package/dist/lang/types.js +1 -1
  372. package/dist/lang/types.js.map +1 -1
  373. package/dist/mesh/index.d.ts +2 -1
  374. package/dist/mesh/index.d.ts.map +1 -1
  375. package/dist/mesh/index.js +2 -1
  376. package/dist/mesh/index.js.map +1 -1
  377. package/dist/mesh/io.d.ts +13 -0
  378. package/dist/mesh/io.d.ts.map +1 -1
  379. package/dist/mesh/io.js +38 -17
  380. package/dist/mesh/io.js.map +1 -1
  381. package/dist/mesh/primitives.d.ts.map +1 -1
  382. package/dist/mesh/primitives.js +41 -6
  383. package/dist/mesh/primitives.js.map +1 -1
  384. package/dist/mesh/reconcile.d.ts +1 -1
  385. package/dist/mesh/reconcile.js +1 -1
  386. package/dist/mesh/reconcile.js.map +1 -1
  387. package/dist/mesh/rigid-transform.d.ts +3 -3
  388. package/dist/mesh/rigid-transform.js +3 -3
  389. package/dist/mesh/rigid-transform.js.map +1 -1
  390. package/dist/mesh/stl-unit.d.ts +24 -0
  391. package/dist/mesh/stl-unit.d.ts.map +1 -0
  392. package/dist/mesh/stl-unit.js +17 -0
  393. package/dist/mesh/stl-unit.js.map +1 -0
  394. package/dist/mesh/threemf-bambu.d.ts +142 -0
  395. package/dist/mesh/threemf-bambu.d.ts.map +1 -0
  396. package/dist/mesh/threemf-bambu.js +334 -0
  397. package/dist/mesh/threemf-bambu.js.map +1 -0
  398. package/dist/mesh/threemf-loader.d.ts +65 -7
  399. package/dist/mesh/threemf-loader.d.ts.map +1 -1
  400. package/dist/mesh/threemf-loader.js +738 -99
  401. package/dist/mesh/threemf-loader.js.map +1 -1
  402. package/dist/mesh/threemf-view.d.ts +71 -0
  403. package/dist/mesh/threemf-view.d.ts.map +1 -0
  404. package/dist/mesh/threemf-view.js +100 -0
  405. package/dist/mesh/threemf-view.js.map +1 -0
  406. package/dist/mesh/types.d.ts +38 -0
  407. package/dist/mesh/types.d.ts.map +1 -1
  408. package/dist/mesh/types.js.map +1 -1
  409. package/dist/node-host/cli.d.ts +44 -6
  410. package/dist/node-host/cli.d.ts.map +1 -1
  411. package/dist/node-host/cli.js +76 -26
  412. package/dist/node-host/cli.js.map +1 -1
  413. package/dist/node-host/font-family-index.d.ts +93 -0
  414. package/dist/node-host/font-family-index.d.ts.map +1 -0
  415. package/dist/node-host/font-family-index.js +273 -0
  416. package/dist/node-host/font-family-index.js.map +1 -0
  417. package/dist/node-host/fs-asset-resolver.d.ts +8 -3
  418. package/dist/node-host/fs-asset-resolver.d.ts.map +1 -1
  419. package/dist/node-host/fs-asset-resolver.js +13 -5
  420. package/dist/node-host/fs-asset-resolver.js.map +1 -1
  421. package/dist/node-host/index.d.ts +8 -0
  422. package/dist/node-host/index.d.ts.map +1 -1
  423. package/dist/node-host/index.js +1 -0
  424. package/dist/node-host/index.js.map +1 -1
  425. package/dist/node-host/node-font-provider.d.ts +28 -0
  426. package/dist/node-host/node-font-provider.d.ts.map +1 -1
  427. package/dist/node-host/node-font-provider.js +49 -0
  428. package/dist/node-host/node-font-provider.js.map +1 -1
  429. package/dist/node.d.ts +1 -0
  430. package/dist/node.d.ts.map +1 -1
  431. package/dist/node.js +1 -0
  432. package/dist/node.js.map +1 -1
  433. package/dist/occt-kernel/highLevelApi.d.ts +4 -1
  434. package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
  435. package/dist/occt-kernel/highLevelApi.js +4 -2
  436. package/dist/occt-kernel/highLevelApi.js.map +1 -1
  437. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  438. package/dist/occt-kernel/occt-primitives.js +36 -3
  439. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  440. package/dist/occt-kernel/occtKernel.d.ts +19 -14
  441. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  442. package/dist/occt-kernel/occtKernel.js +19 -32
  443. package/dist/occt-kernel/occtKernel.js.map +1 -1
  444. package/dist/occt-kernel/stepColorParser.d.ts +18 -0
  445. package/dist/occt-kernel/stepColorParser.d.ts.map +1 -1
  446. package/dist/occt-kernel/stepColorParser.js +38 -0
  447. package/dist/occt-kernel/stepColorParser.js.map +1 -1
  448. package/dist/occt-kernel/stepMetaParser.d.ts +44 -0
  449. package/dist/occt-kernel/stepMetaParser.d.ts.map +1 -0
  450. package/dist/occt-kernel/stepMetaParser.js +166 -0
  451. package/dist/occt-kernel/stepMetaParser.js.map +1 -0
  452. package/dist/occt-kernel/topologyExt.d.ts +1 -1
  453. package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
  454. package/dist/occt-kernel/topologyExt.js +4 -5
  455. package/dist/occt-kernel/topologyExt.js.map +1 -1
  456. package/dist/primitives/text/cjk-font.d.ts +2 -15
  457. package/dist/primitives/text/cjk-font.d.ts.map +1 -1
  458. package/dist/primitives/text/cjk-font.js +13 -1
  459. package/dist/primitives/text/cjk-font.js.map +1 -1
  460. package/dist/runtime-state.d.ts +85 -9
  461. package/dist/runtime-state.d.ts.map +1 -1
  462. package/dist/runtime-state.js +72 -2
  463. package/dist/runtime-state.js.map +1 -1
  464. package/dist/sdk.d.ts +3 -3
  465. package/dist/sdk.d.ts.map +1 -1
  466. package/dist/sdk.js +5 -5
  467. package/dist/sdk.js.map +1 -1
  468. package/dist/shape.d.ts +108 -5
  469. package/dist/shape.d.ts.map +1 -1
  470. package/dist/shape.js +130 -3
  471. package/dist/shape.js.map +1 -1
  472. package/dist/step/stepMetaParser.d.ts +55 -0
  473. package/dist/step/stepMetaParser.d.ts.map +1 -0
  474. package/dist/step/stepMetaParser.js +177 -0
  475. package/dist/step/stepMetaParser.js.map +1 -0
  476. package/dist/topology/naming/lineage.d.ts +6 -0
  477. package/dist/topology/naming/lineage.d.ts.map +1 -1
  478. package/dist/topology/naming/lineage.js +8 -0
  479. package/dist/topology/naming/lineage.js.map +1 -1
  480. package/dist/topology/naming/resolve-edge.d.ts +20 -1
  481. package/dist/topology/naming/resolve-edge.d.ts.map +1 -1
  482. package/dist/topology/naming/resolve-edge.js +54 -20
  483. package/dist/topology/naming/resolve-edge.js.map +1 -1
  484. package/dist/weapp.d.ts +6 -2
  485. package/dist/weapp.d.ts.map +1 -1
  486. package/dist/weapp.js +7 -1
  487. package/dist/weapp.js.map +1 -1
  488. package/package.json +19 -3
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib splitByPlane — 平面二分:把 solid 沿无限平面切成两半(手写中立 op,Phase 6.1)
2
+ * api splitByPlane — 平面二分:把 solid 沿无限平面切成两半(手写中立 op,Phase 6.1)
3
3
  *
4
4
  * 中立 op:L1 `splitByPlane(shape, point, normal)` 在 occt 与 brepkit 两侧均有
5
5
  * 真实现(occt-kernel/occt-primitives.ts / brepkit-kernel/brepkitKernel.ts)⇒
@@ -52,6 +52,7 @@ function splitByPlaneBrep(input, params) {
52
52
  export const splitByPlane = defineOp({
53
53
  capabilities: ['directEdit'],
54
54
  outputs: ['positive', 'negative'],
55
+ paramDims: { 'params.point': 'length', 'params.normal': 'length' },
55
56
  brep(input, params) {
56
57
  return splitByPlaneBrep(input, params);
57
58
  },
@@ -1 +1 @@
1
- {"version":3,"file":"split-by-plane.js","sourceRoot":"","sources":["../../src/api/split-by-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAajC,8DAA8D;AAC9D,SAAS,MAAM,CAAC,CAAO;IACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;IAC1F,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtC,CAAC;AAED,wCAAwC;AACxC,SAAS,gBAAgB,CAAC,KAAY,EAAE,MAA0B;IAChE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,IAAK,EAAyB,CAAA;IAC9D,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IACrD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IACvF,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACxE,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrF,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;KACtF,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;IACnC,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;IACjC,IAAI,CAAC,KAAY,EAAE,MAA0B;QAC3C,OAAO,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACxC,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAgB;CAC5C,CAAC,CAAA","sourcesContent":["/**\n * stdlib splitByPlane — 平面二分:把 solid 沿无限平面切成两半(手写中立 op,Phase 6.1)\n *\n * 中立 op:L1 `splitByPlane(shape, point, normal)` 在 occt 与 brepkit 两侧均有\n * 真实现(occt-kernel/occt-primitives.ts / brepkit-kernel/brepkitKernel.ts)⇒\n * 走 `getBrepApi()`(D12),不声明 engines(实现只经 L1 契约面)。\n *\n * 产物形态(设计原则 5):两半不是数组,是具名 `outputs: ['positive','negative']`\n * ——法向正侧 = positive(L1 契约 §3.7 口径,occt 适配器按质心投影分类)。\n * 先例:occt 适配器的 splitByPlane 直接返回 `{positive, negative}`。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle, BrepVec3 } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\n\ntype Vec3 = [number, number, number]\n\n/** `cad.splitByPlane` 参数。 */\nexport interface SplitByPlaneParams {\n /** 平面上一点(mm)。 */\n point: Vec3\n /** 平面法向(不必单位化;其正侧为 `positive`)。 */\n normal: Vec3\n}\n\n/** 元组 → BrepVec3 对象(GOTCHA:L1 向量形参是 {x,y,z} 对象,元组会被读成零向量)。 */\nfunction toVec3(v: Vec3): BrepVec3 {\n if (!Array.isArray(v) || v.length !== 3 || v.some((n) => typeof n !== 'number' || !Number.isFinite(n))) {\n throw new Error('E_SPLIT_BY_PLANE_BAD_VEC: point/normal must be [x,y,z] finite numbers')\n }\n return { x: v[0], y: v[1], z: v[2] }\n}\n\n/** BREP 路径:L1 splitByPlane → 两半各自收养。 */\nfunction splitByPlaneBrep(input: Shape, params: SplitByPlaneParams): Record<string, Shape> {\n const { point, normal } = params ?? ({} as SplitByPlaneParams)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error('E_SPLIT_BY_PLANE_NO_BREP: splitByPlane input is not BREP')\n const halves = kernel.splitByPlane(solid, toVec3(point), toVec3(normal))\n return {\n positive: fromBrep(solidToShape(kernel, halves.positive), { solid: halves.positive }),\n negative: fromBrep(solidToShape(kernel, halves.negative), { solid: halves.negative }),\n }\n}\n\n/**\n * 沿无限平面把实体切成两半,返回法向正/负两半(具名产物)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name splitByPlane\n * @note 中立 op:L1 splitByPlane 两引擎同实现。产物是具名两半\n * `{ positive, negative }`(不是数组);法向正侧 = positive。\n * @returns 具名产物 positive/negative。\n * @param input - 目标实体。type:Shape required:true\n * @param params.point - 平面上一点 [x,y,z](mm)。type:Vec3 required:true\n * @param params.normal - 平面法向 [x,y,z]。type:Vec3 required:true\n * @example\n * const { positive, negative } = await cad.splitByPlane(part0, { point: [0,0,5], normal: [0,0,1] })\n */\nexport const splitByPlane = defineOp({\n capabilities: ['directEdit'],\n outputs: ['positive', 'negative'],\n brep(input: Shape, params: SplitByPlaneParams) {\n return splitByPlaneBrep(input, params)\n },\n naming: { kind: 'subdivide' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"split-by-plane.js","sourceRoot":"","sources":["../../src/api/split-by-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAajC,8DAA8D;AAC9D,SAAS,MAAM,CAAC,CAAO;IACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;IAC1F,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtC,CAAC;AAED,wCAAwC;AACxC,SAAS,gBAAgB,CAAC,KAAY,EAAE,MAA0B;IAChE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,IAAK,EAAyB,CAAA;IAC9D,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IACrD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IACvF,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACxE,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrF,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;KACtF,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;IACnC,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;IACjC,SAAS,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE;IAClE,IAAI,CAAC,KAAY,EAAE,MAA0B;QAC3C,OAAO,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACxC,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAgB;CAC5C,CAAC,CAAA","sourcesContent":["/**\n * api splitByPlane — 平面二分:把 solid 沿无限平面切成两半(手写中立 op,Phase 6.1)\n *\n * 中立 op:L1 `splitByPlane(shape, point, normal)` 在 occt 与 brepkit 两侧均有\n * 真实现(occt-kernel/occt-primitives.ts / brepkit-kernel/brepkitKernel.ts)⇒\n * 走 `getBrepApi()`(D12),不声明 engines(实现只经 L1 契约面)。\n *\n * 产物形态(设计原则 5):两半不是数组,是具名 `outputs: ['positive','negative']`\n * ——法向正侧 = positive(L1 契约 §3.7 口径,occt 适配器按质心投影分类)。\n * 先例:occt 适配器的 splitByPlane 直接返回 `{positive, negative}`。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle, BrepVec3 } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\n\ntype Vec3 = [number, number, number]\n\n/** `cad.splitByPlane` 参数。 */\nexport interface SplitByPlaneParams {\n /** 平面上一点(mm)。 */\n point: Vec3\n /** 平面法向(不必单位化;其正侧为 `positive`)。 */\n normal: Vec3\n}\n\n/** 元组 → BrepVec3 对象(GOTCHA:L1 向量形参是 {x,y,z} 对象,元组会被读成零向量)。 */\nfunction toVec3(v: Vec3): BrepVec3 {\n if (!Array.isArray(v) || v.length !== 3 || v.some((n) => typeof n !== 'number' || !Number.isFinite(n))) {\n throw new Error('E_SPLIT_BY_PLANE_BAD_VEC: point/normal must be [x,y,z] finite numbers')\n }\n return { x: v[0], y: v[1], z: v[2] }\n}\n\n/** BREP 路径:L1 splitByPlane → 两半各自收养。 */\nfunction splitByPlaneBrep(input: Shape, params: SplitByPlaneParams): Record<string, Shape> {\n const { point, normal } = params ?? ({} as SplitByPlaneParams)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (!solid) throw new Error('E_SPLIT_BY_PLANE_NO_BREP: splitByPlane input is not BREP')\n const halves = kernel.splitByPlane(solid, toVec3(point), toVec3(normal))\n return {\n positive: fromBrep(solidToShape(kernel, halves.positive), { solid: halves.positive }),\n negative: fromBrep(solidToShape(kernel, halves.negative), { solid: halves.negative }),\n }\n}\n\n/**\n * 沿无限平面把实体切成两半,返回法向正/负两半(具名产物)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name splitByPlane\n * @note 中立 op:L1 splitByPlane 两引擎同实现。产物是具名两半\n * `{ positive, negative }`(不是数组);法向正侧 = positive。\n * @returns 具名产物 positive/negative。\n * @param input - 目标实体。type:Shape required:true\n * @param params.point - 平面上一点 [x,y,z](mm)。type:Vec3 required:true\n * @param params.normal - 平面法向 [x,y,z]。type:Vec3 required:true\n * @example\n * const { positive, negative } = await cad.splitByPlane(part0, { point: [0,0,5], normal: [0,0,1] })\n */\nexport const splitByPlane = defineOp({\n capabilities: ['directEdit'],\n outputs: ['positive', 'negative'],\n paramDims: { 'params.point': 'length', 'params.normal': 'length' },\n brep(input: Shape, params: SplitByPlaneParams) {\n return splitByPlaneBrep(input, params)\n },\n naming: { kind: 'subdivide' } as Provenance,\n})\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)
2
+ * api split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)
3
3
  *
4
4
  * @platform occt — 平台 op:内核原生 `split`(BRepAlgoAPI_Splitter)是 occt-only
5
5
  * (engine-method-map `split` → occt-only;L1 只有 `splitByPlane`)。本文件
package/dist/api/split.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)
2
+ * api split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)
3
3
  *
4
4
  * @platform occt — 平台 op:内核原生 `split`(BRepAlgoAPI_Splitter)是 occt-only
5
5
  * (engine-method-map `split` → occt-only;L1 只有 `splitByPlane`)。本文件
@@ -29,7 +29,7 @@ function splitBrep(input, tools) {
29
29
  const occtKernel = getOcctKernel();
30
30
  const inputSolid = brepOf(input);
31
31
  if (!inputSolid)
32
- throw new Error('[stdlib/split] input is not BREP');
32
+ throw new Error('[api/split] input is not BREP');
33
33
  const toolSolids = tools
34
34
  .map((t) => brepOf(t))
35
35
  .filter((s) => !!s);
@@ -1 +1 @@
1
- {"version":3,"file":"split.js","sourceRoot":"","sources":["../../src/api/split.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)\n *\n * @platform occt — 平台 op:内核原生 `split`(BRepAlgoAPI_Splitter)是 occt-only\n * (engine-method-map `split` → occt-only;L1 只有 `splitByPlane`)。本文件\n * 只取 L1 面做枚举/命名(getBrepApi),切分本身走平台面 getOcctKernel()(D3),\n * defineOp 声明 `engines: ['occt']`(D11),不声明 capabilities(互斥)。\n *\n * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径\n * 用内核原生 split(BRepAlgoAPI_Splitter)切分,存活面(hash 逐字不变)回投原\n * role,新造面(截面 + 被切细的侧面片)记 `splinter(#j)`,片序按质心排序保证跨\n * 重放稳定。\n *\n * 机制(无 splitWithHistory,纯 hash 比对 + 几何排序):`subdivide` 类零声明,\n * 新造面不对应任何输入面的因果坐标,故挂消费它的那条语句、用稳定的片序 `#j` 区分。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getFaceHashes } from '../brep/face-evolution'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { getCurrentStmt } from '../runtime-state'\nimport { fromBrep, brepOf, inputRoleTable } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { RoleTable } from '../topology/naming/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { getOcctKernel, type ShapeHandle } from '../occt-kernel/occtKernel'\n\n/** BREP 路径:用 tools 切分 input,存活面回投、新造面记 `splinter(#j)`。 */\nfunction splitBrep(input: Shape, tools: Shape[]): Shape {\n // L1 面:枚举/命名(getBrepApi,D12)。\n const kernel = getBrepApi()\n // 平台面:原生 split(occt-only,D3)。\n const occtKernel = getOcctKernel()\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/split] input is not BREP')\n const toolSolids = tools\n .map((t) => brepOf(t) as BrepHandle | undefined)\n .filter((s): s is BrepHandle => !!s)\n if (toolSolids.length === 0) return input\n\n // Phase 1.6:origin = 本次语句 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n const inputTable = inputRoleTable(input) as RoleTable | undefined\n\n const inputHashes = getFaceHashes(kernel, inputSolid)\n const inputHashSet = new Set(inputHashes)\n const inputHashToRole = new Map<number, string>()\n if (inputTable) {\n for (const roles of inputTable.values()) {\n for (const [role, hashes] of roles) for (const h of hashes) inputHashToRole.set(h, role)\n }\n }\n\n // 内核原生 split(BRepAlgoAPI_Splitter)返回包含所有碎片的 compound。\n // BrepHandle(branded number)与 occt-wasm ShapeHandle(branded number)运行时同构,\n // 品牌转换只发生在平台边界(occt-only 原生面,非跨引擎断言)。\n const resultSolid = occtKernel.split(\n inputSolid as unknown as ShapeHandle,\n toolSolids as unknown as ShapeHandle[],\n )\n\n const resultHashes = getFaceHashes(kernel, resultSolid as unknown as BrepHandle)\n const resultFaces = kernel.getSubShapes(resultSolid as unknown as BrepHandle, 'face')\n const resultCentroids = resultFaces.map((f) => kernel.surfaceCenterOfMass(f))\n\n const roleTable = new Map<string, Map<string, number[]>>()\n const inner = new Map<string, number[]>()\n\n // 存活面(hash 逐字不变)→ 回投原 role;其余 = 新造面 → splinter(#j)\n const newFaces: { hash: number; c: { x: number; y: number; z: number } }[] = []\n for (let i = 0; i < resultHashes.length; i++) {\n const h = resultHashes[i]!\n if (inputHashSet.has(h)) {\n const role = inputHashToRole.get(h)\n if (role) {\n if (!inner.has(role)) inner.set(role, [])\n inner.get(role)!.push(h)\n }\n } else {\n newFaces.push({ hash: h, c: resultCentroids[i]! })\n }\n }\n // 按质心 (x,y,z) 排序保证片序跨重放稳定\n newFaces.sort((a, b) => a.c.x - b.c.x || a.c.y - b.c.y || a.c.z - b.c.z)\n for (let j = 0; j < newFaces.length; j++) {\n const role = `splinter(#${j})`\n inner.set(role, [newFaces[j].hash])\n }\n roleTable.set(outStmt, inner)\n\n return fromBrep(solidToShape(kernel, resultSolid as unknown as BrepHandle), {\n solid: resultSolid as unknown as BrepHandle,\n roleTable,\n })\n}\n\n/**\n * 用工具几何切分目标几何(BRepAlgoAPI_Splitter),返回所有碎片组成的几何。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name split\n * @note BREP-only:非 BREP 输入抛 E_MESH_UNSUPPORTED。切分产生的截面 / 被切细的侧面\n * 片记 `splinter(#j)`(Phase 3 L4 抗重放词汇)。平台 op:仅 occt 引擎(原生 split)。\n * @returns Shape 切分后的几何(compound of pieces)。\n * @param input - 目标几何。type:Shape required:true\n * @param tools - 切刀几何(数组)。type:Shape[] required:true\n * @example\n * const pieces = await cad.split(part0, [part1])\n */\nexport const split = defineOp({\n brep(input: Shape, tools: Shape[]) {\n return splitBrep(input, tools)\n },\n engines: ['occt'],\n naming: { kind: 'subdivide' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../src/api/split.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)\n *\n * @platform occt — 平台 op:内核原生 `split`(BRepAlgoAPI_Splitter)是 occt-only\n * (engine-method-map `split` → occt-only;L1 只有 `splitByPlane`)。本文件\n * 只取 L1 面做枚举/命名(getBrepApi),切分本身走平台面 getOcctKernel()(D3),\n * defineOp 声明 `engines: ['occt']`(D11),不声明 capabilities(互斥)。\n *\n * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径\n * 用内核原生 split(BRepAlgoAPI_Splitter)切分,存活面(hash 逐字不变)回投原\n * role,新造面(截面 + 被切细的侧面片)记 `splinter(#j)`,片序按质心排序保证跨\n * 重放稳定。\n *\n * 机制(无 splitWithHistory,纯 hash 比对 + 几何排序):`subdivide` 类零声明,\n * 新造面不对应任何输入面的因果坐标,故挂消费它的那条语句、用稳定的片序 `#j` 区分。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getFaceHashes } from '../brep/face-evolution'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { getCurrentStmt } from '../runtime-state'\nimport { fromBrep, brepOf, inputRoleTable } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { RoleTable } from '../topology/naming/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { getOcctKernel, type ShapeHandle } from '../occt-kernel/occtKernel'\n\n/** BREP 路径:用 tools 切分 input,存活面回投、新造面记 `splinter(#j)`。 */\nfunction splitBrep(input: Shape, tools: Shape[]): Shape {\n // L1 面:枚举/命名(getBrepApi,D12)。\n const kernel = getBrepApi()\n // 平台面:原生 split(occt-only,D3)。\n const occtKernel = getOcctKernel()\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[api/split] input is not BREP')\n const toolSolids = tools\n .map((t) => brepOf(t) as BrepHandle | undefined)\n .filter((s): s is BrepHandle => !!s)\n if (toolSolids.length === 0) return input\n\n // Phase 1.6:origin = 本次语句 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n const inputTable = inputRoleTable(input) as RoleTable | undefined\n\n const inputHashes = getFaceHashes(kernel, inputSolid)\n const inputHashSet = new Set(inputHashes)\n const inputHashToRole = new Map<number, string>()\n if (inputTable) {\n for (const roles of inputTable.values()) {\n for (const [role, hashes] of roles) for (const h of hashes) inputHashToRole.set(h, role)\n }\n }\n\n // 内核原生 split(BRepAlgoAPI_Splitter)返回包含所有碎片的 compound。\n // BrepHandle(branded number)与 occt-wasm ShapeHandle(branded number)运行时同构,\n // 品牌转换只发生在平台边界(occt-only 原生面,非跨引擎断言)。\n const resultSolid = occtKernel.split(\n inputSolid as unknown as ShapeHandle,\n toolSolids as unknown as ShapeHandle[],\n )\n\n const resultHashes = getFaceHashes(kernel, resultSolid as unknown as BrepHandle)\n const resultFaces = kernel.getSubShapes(resultSolid as unknown as BrepHandle, 'face')\n const resultCentroids = resultFaces.map((f) => kernel.surfaceCenterOfMass(f))\n\n const roleTable = new Map<string, Map<string, number[]>>()\n const inner = new Map<string, number[]>()\n\n // 存活面(hash 逐字不变)→ 回投原 role;其余 = 新造面 → splinter(#j)\n const newFaces: { hash: number; c: { x: number; y: number; z: number } }[] = []\n for (let i = 0; i < resultHashes.length; i++) {\n const h = resultHashes[i]!\n if (inputHashSet.has(h)) {\n const role = inputHashToRole.get(h)\n if (role) {\n if (!inner.has(role)) inner.set(role, [])\n inner.get(role)!.push(h)\n }\n } else {\n newFaces.push({ hash: h, c: resultCentroids[i]! })\n }\n }\n // 按质心 (x,y,z) 排序保证片序跨重放稳定\n newFaces.sort((a, b) => a.c.x - b.c.x || a.c.y - b.c.y || a.c.z - b.c.z)\n for (let j = 0; j < newFaces.length; j++) {\n const role = `splinter(#${j})`\n inner.set(role, [newFaces[j].hash])\n }\n roleTable.set(outStmt, inner)\n\n return fromBrep(solidToShape(kernel, resultSolid as unknown as BrepHandle), {\n solid: resultSolid as unknown as BrepHandle,\n roleTable,\n })\n}\n\n/**\n * 用工具几何切分目标几何(BRepAlgoAPI_Splitter),返回所有碎片组成的几何。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name split\n * @note BREP-only:非 BREP 输入抛 E_MESH_UNSUPPORTED。切分产生的截面 / 被切细的侧面\n * 片记 `splinter(#j)`(Phase 3 L4 抗重放词汇)。平台 op:仅 occt 引擎(原生 split)。\n * @returns Shape 切分后的几何(compound of pieces)。\n * @param input - 目标几何。type:Shape required:true\n * @param tools - 切刀几何(数组)。type:Shape[] required:true\n * @example\n * const pieces = await cad.split(part0, [part1])\n */\nexport const split = defineOp({\n brep(input: Shape, tools: Shape[]) {\n return splitBrep(input, tools)\n },\n engines: ['occt'],\n naming: { kind: 'subdivide' } as Provenance,\n})\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib sweep — 扫掠:截面沿脊柱路径生成扫掠体(手写平台 op,Phase 4 → G5 core 直连)
2
+ * api sweep — 扫掠:截面沿脊柱路径生成扫掠体(手写平台 op,Phase 4 → G5 core 直连)
3
3
  *
4
4
  * @platform occt — 实现走 core 自有 `brep-mirror/sweepFns.ts#sweepBrep`
5
5
  * (occt-wasm simplePipe / sweepPipeShell;engine-method-map 里 `sweep` 为
package/dist/api/sweep.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib sweep — 扫掠:截面沿脊柱路径生成扫掠体(手写平台 op,Phase 4 → G5 core 直连)
2
+ * api sweep — 扫掠:截面沿脊柱路径生成扫掠体(手写平台 op,Phase 4 → G5 core 直连)
3
3
  *
4
4
  * @platform occt — 实现走 core 自有 `brep-mirror/sweepFns.ts#sweepBrep`
5
5
  * (occt-wasm simplePipe / sweepPipeShell;engine-method-map 里 `sweep` 为
@@ -1 +1 @@
1
- {"version":3,"file":"sweep.js","sourceRoot":"","sources":["../../src/api/sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAevD,+DAA+D;AAC/D,SAAS,SAAS,CAAC,OAAc,EAAE,KAAY,EAAE,IAAmB;IAClE,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IAC7F,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;IACpF,iCAAiC;IACjC,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAC9C,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;IAC1C,MAAM,CAAC,GAAG,eAAe,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAe,CAAA;IAChD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IACxD,CAAC;YAAS,CAAC;QACT,0CAA0C;QAC1C,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC;gBAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC;gBAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,OAAO;IACb,IAAI,CAAC,OAAc,EAAE,KAAY,EAAE,IAAmB;QACpD,OAAO,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IACxC,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,CAAC;IACjB,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,wCAAwC,EAAgB;CAC9F,CAAC,CAAA","sourcesContent":["/**\n * stdlib sweep — 扫掠:截面沿脊柱路径生成扫掠体(手写平台 op,Phase 4 → G5 core 直连)\n *\n * @platform occt — 实现走 core 自有 `brep-mirror/sweepFns.ts#sweepBrep`\n * (occt-wasm simplePipe / sweepPipeShell;engine-method-map 里 `sweep` 为\n * occt-only)⇒ 平台 op:defineOp 声明 `engines: ['occt']`(D11)。\n *\n * 为什么手写而不走生成投影:与 `api/loft.ts` 同因——截面最常见来源是\n * `cad.profile(...)`(产出 **face**),需「面 → 外环」输入适配\n * (`internal/profile-wire.ts` 的唯一步径)。脊柱容忍 face(FCStd 翻译把\n * 脊柱基对象 sketch 整圈外廓当路径)。\n *\n * core-decouple G5:vendored `sweep`(brepjs)替换为 brep-mirror 自有实现直连,\n * 产物经 `fromBrep` 收养(替代 l3-bridge adoptEntity)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep } from '../shape'\nimport { solidToShape } from '../brep/brep-ops'\nimport { sweepBrep as selfhostedSweep } from './brep-mirror/sweepFns'\nimport { toProfileWireView } from './internal/profile-wire'\nimport { unwrapResult } from './internal/result-unwrap'\nimport type { BrepHandle } from '../brep/engine/types'\n\n/** 扫掠配置(与 vendored SweepOptions 同形;本文件自持,去 brepjs 依赖)。 */\nexport interface SweepOptions {\n /** Frenet 参考系(默认 false)。 */\n frenet?: boolean\n /** 扫掠模式:'simple'(MakePipe)或 undefined(PipeShell)。 */\n mode?: 'simple'\n /** 过渡模式:仅支持默认 'right'(selfhost 后限制,见 sweepFns)。 */\n transitionMode?: string\n /** 公差等其余 vendored 字段(保留以兼容调用方)。 */\n tolerance?: number\n}\n\n/** BREP 路径:截面沿脊柱扫掠(wire 视图 → brep-mirror 直连 → fromBrep 收养)。 */\nfunction sweepBrep(profile: Shape, spine: Shape, opts?: SweepOptions): Shape {\n if (!profile) throw new Error('E_SWEEP_NO_PROFILE: sweep requires a profile (section) shape')\n if (!spine) throw new Error('E_SWEEP_NO_SPINE: sweep requires a spine (path) shape')\n // 截面 / 脊柱:wire 直用;面取外环(孔环不参与扫掠)。\n const profileWire = toProfileWireView(profile)\n const spineWire = toProfileWireView(spine)\n const r = selfhostedSweep(profileWire, spineWire, opts ?? {}, false)\n const h = unwrapResult(r, 'sweep') as BrepHandle\n const kernel = getBrepApi()\n try {\n return fromBrep(solidToShape(kernel, h), { solid: h })\n } finally {\n // 面→外环产出的 wire 是 arena 新句柄(曲线借用不 release)\n if (!profileWire.borrowed) {\n try { kernel.release(profileWire.wrapped) } catch { /* 已释放 */ }\n }\n if (!spineWire.borrowed) {\n try { kernel.release(spineWire.wrapped) } catch { /* 已释放 */ }\n }\n }\n}\n\n/**\n * 扫掠:截面沿脊柱路径生成扫掠体。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name sweep\n * @note 平台 op:仅 occt 引擎(BRepOffsetAPI_MakePipeShell / MakePipe)。截面接受\n * wire 或面(面取其外环);脊柱必须为 wire。非 occt 引擎执行前报错;\n * brep_mock 不拦截。`shellMode` 不暴露(元组产物跨不过单产物边界)。\n * @returns Shape 扫掠体。\n * @param profile - 截面几何(wire 或面;面取其外环)。type:Shape required:true\n * @param spine - 脊柱路径(wire)。type:Shape required:true\n * @param opts - 扫掠配置(frenet / mode / tolerance 等)。type:SweepOptions required:false\n * @example\n * const path = cad.wire([[0, 0, 0], [0, 0, 50]])\n * const section = cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -4, y1: -4, x2: 4, y2: -4 },\n * { kind: 'line', x1: 4, y1: -4, x2: 4, y2: 4 },\n * { kind: 'line', x1: 4, y1: 4, x2: -4, y2: 4 },\n * { kind: 'line', x1: -4, y1: 4, x2: -4, y2: -4 },\n * ] }] })\n * const body = await cad.sweep(section, path)\n */\nexport const sweep = defineOp({\n name: 'sweep',\n brep(profile: Shape, spine: Shape, opts?: SweepOptions) {\n return sweepBrep(profile, spine, opts)\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: 'swept-body face vocabulary not defined' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"sweep.js","sourceRoot":"","sources":["../../src/api/sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAevD,+DAA+D;AAC/D,SAAS,SAAS,CAAC,OAAc,EAAE,KAAY,EAAE,IAAmB;IAClE,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IAC7F,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;IACpF,iCAAiC;IACjC,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAC9C,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;IAC1C,MAAM,CAAC,GAAG,eAAe,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAe,CAAA;IAChD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IACxD,CAAC;YAAS,CAAC;QACT,0CAA0C;QAC1C,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC;gBAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC;gBAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,OAAO;IACb,IAAI,CAAC,OAAc,EAAE,KAAY,EAAE,IAAmB;QACpD,OAAO,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IACxC,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,CAAC;IACjB,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,wCAAwC,EAAgB;CAC9F,CAAC,CAAA","sourcesContent":["/**\n * api sweep — 扫掠:截面沿脊柱路径生成扫掠体(手写平台 op,Phase 4 → G5 core 直连)\n *\n * @platform occt — 实现走 core 自有 `brep-mirror/sweepFns.ts#sweepBrep`\n * (occt-wasm simplePipe / sweepPipeShell;engine-method-map 里 `sweep` 为\n * occt-only)⇒ 平台 op:defineOp 声明 `engines: ['occt']`(D11)。\n *\n * 为什么手写而不走生成投影:与 `api/loft.ts` 同因——截面最常见来源是\n * `cad.profile(...)`(产出 **face**),需「面 → 外环」输入适配\n * (`internal/profile-wire.ts` 的唯一步径)。脊柱容忍 face(FCStd 翻译把\n * 脊柱基对象 sketch 整圈外廓当路径)。\n *\n * core-decouple G5:vendored `sweep`(brepjs)替换为 brep-mirror 自有实现直连,\n * 产物经 `fromBrep` 收养(替代 l3-bridge adoptEntity)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep } from '../shape'\nimport { solidToShape } from '../brep/brep-ops'\nimport { sweepBrep as selfhostedSweep } from './brep-mirror/sweepFns'\nimport { toProfileWireView } from './internal/profile-wire'\nimport { unwrapResult } from './internal/result-unwrap'\nimport type { BrepHandle } from '../brep/engine/types'\n\n/** 扫掠配置(与 vendored SweepOptions 同形;本文件自持,去 brepjs 依赖)。 */\nexport interface SweepOptions {\n /** Frenet 参考系(默认 false)。 */\n frenet?: boolean\n /** 扫掠模式:'simple'(MakePipe)或 undefined(PipeShell)。 */\n mode?: 'simple'\n /** 过渡模式:仅支持默认 'right'(selfhost 后限制,见 sweepFns)。 */\n transitionMode?: string\n /** 公差等其余 vendored 字段(保留以兼容调用方)。 */\n tolerance?: number\n}\n\n/** BREP 路径:截面沿脊柱扫掠(wire 视图 → brep-mirror 直连 → fromBrep 收养)。 */\nfunction sweepBrep(profile: Shape, spine: Shape, opts?: SweepOptions): Shape {\n if (!profile) throw new Error('E_SWEEP_NO_PROFILE: sweep requires a profile (section) shape')\n if (!spine) throw new Error('E_SWEEP_NO_SPINE: sweep requires a spine (path) shape')\n // 截面 / 脊柱:wire 直用;面取外环(孔环不参与扫掠)。\n const profileWire = toProfileWireView(profile)\n const spineWire = toProfileWireView(spine)\n const r = selfhostedSweep(profileWire, spineWire, opts ?? {}, false)\n const h = unwrapResult(r, 'sweep') as BrepHandle\n const kernel = getBrepApi()\n try {\n return fromBrep(solidToShape(kernel, h), { solid: h })\n } finally {\n // 面→外环产出的 wire 是 arena 新句柄(曲线借用不 release)\n if (!profileWire.borrowed) {\n try { kernel.release(profileWire.wrapped) } catch { /* 已释放 */ }\n }\n if (!spineWire.borrowed) {\n try { kernel.release(spineWire.wrapped) } catch { /* 已释放 */ }\n }\n }\n}\n\n/**\n * 扫掠:截面沿脊柱路径生成扫掠体。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name sweep\n * @note 平台 op:仅 occt 引擎(BRepOffsetAPI_MakePipeShell / MakePipe)。截面接受\n * wire 或面(面取其外环);脊柱必须为 wire。非 occt 引擎执行前报错;\n * brep_mock 不拦截。`shellMode` 不暴露(元组产物跨不过单产物边界)。\n * @returns Shape 扫掠体。\n * @param profile - 截面几何(wire 或面;面取其外环)。type:Shape required:true\n * @param spine - 脊柱路径(wire)。type:Shape required:true\n * @param opts - 扫掠配置(frenet / mode / tolerance 等)。type:SweepOptions required:false\n * @example\n * const path = cad.wire([[0, 0, 0], [0, 0, 50]])\n * const section = cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -4, y1: -4, x2: 4, y2: -4 },\n * { kind: 'line', x1: 4, y1: -4, x2: 4, y2: 4 },\n * { kind: 'line', x1: 4, y1: 4, x2: -4, y2: 4 },\n * { kind: 'line', x1: -4, y1: 4, x2: -4, y2: -4 },\n * ] }] })\n * const body = await cad.sweep(section, path)\n */\nexport const sweep = defineOp({\n name: 'sweep',\n brep(profile: Shape, spine: Shape, opts?: SweepOptions) {\n return sweepBrep(profile, spine, opts)\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: 'swept-body face vocabulary not defined' } as Provenance,\n})\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib thicken — 加厚:把面(或壳)沿法向偏置成等厚实体(手写平台 op,Phase 4 → G5 core 直连)
2
+ * api thicken — 加厚:把面(或壳)沿法向偏置成等厚实体(手写平台 op,Phase 4 → G5 core 直连)
3
3
  *
4
4
  * @platform occt — 实现走 occt-wasm 原生 `thicken`(BRepOffsetAPI_MakeThickSolid;
5
5
  * engine-method-map 里 `thicken` 为 occt-only)⇒ 平台 op:defineOp 声明
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib thicken — 加厚:把面(或壳)沿法向偏置成等厚实体(手写平台 op,Phase 4 → G5 core 直连)
2
+ * api thicken — 加厚:把面(或壳)沿法向偏置成等厚实体(手写平台 op,Phase 4 → G5 core 直连)
3
3
  *
4
4
  * @platform occt — 实现走 occt-wasm 原生 `thicken`(BRepOffsetAPI_MakeThickSolid;
5
5
  * engine-method-map 里 `thicken` 为 occt-only)⇒ 平台 op:defineOp 声明
@@ -1 +1 @@
1
- {"version":3,"file":"thicken.js","sourceRoot":"","sources":["../../src/api/thicken.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAGzD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;IAC9B,IAAI,EAAE,SAAS;IACf,IAAI,CAAC,KAAY,EAAE,SAAiB;QAClC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;QACtF,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAA;QACzF,CAAC;QACD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;QACtD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAC3D,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC,OAAO,CAAC,MAAe,EAAE,SAAS,EAAE,IAAI,CAA0B,CAAA;QAC5F,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAU,CAAA;IACjE,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,CAAC;IACjB,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,4CAA4C,EAAgB;CAClG,CAAC,CAAA","sourcesContent":["/**\n * stdlib thicken — 加厚:把面(或壳)沿法向偏置成等厚实体(手写平台 op,Phase 4 → G5 core 直连)\n *\n * @platform occt — 实现走 occt-wasm 原生 `thicken`(BRepOffsetAPI_MakeThickSolid;\n * engine-method-map 里 `thicken` 为 occt-only)⇒ 平台 op:defineOp 声明\n * `engines: ['occt']`(D11)。\n *\n * core-decouple G5:vendored `thicken`(brepjs modifierFns,thickenWithHistory)\n * 替换为 occt-wasm 原生直连,产物经 `fromBrep` 收养(替代 l3-bridge adoptEntity)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, fromBrep } from '../shape'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getOcctKernel } from '../occt-kernel/occtKernel'\nimport type { BrepHandle } from '../brep/engine/types'\n\n/**\n * 加厚:把面(或壳)沿法向偏置成等厚实体。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name thicken\n * @note 平台 op:仅 occt 引擎(BRepOffset)。输入为面/壳 Shape(如 cad.profile 产物);\n * 正厚度沿法向、负厚度反向。非 occt 引擎执行前报错;brep_mock 不拦截。\n * @returns Shape 加厚后的实体。\n * @param input - 面/壳几何(cad.profile 产物等)。type:Shape required:true\n * @param thickness - 厚度(mm,≠0;正沿法向,负反向)。type:number required:true\n * @example\n * const face = cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -10, y1: -10, x2: 10, y2: -10 },\n * { kind: 'line', x1: 10, y1: -10, x2: 10, y2: 10 },\n * { kind: 'line', x1: 10, y1: 10, x2: -10, y2: 10 },\n * { kind: 'line', x1: -10, y1: 10, x2: -10, y2: -10 },\n * ] }] })\n * const solid = await cad.thicken(face, 2)\n */\nexport const thicken = defineOp({\n name: 'thicken',\n brep(input: Shape, thickness: number) {\n if (!input) throw new Error('E_THICKEN_NO_SHAPE: thicken requires a face/shell shape')\n if (typeof thickness !== 'number' || !Number.isFinite(thickness) || thickness === 0) {\n throw new Error('E_THICKEN_BAD_THICKNESS: thicken.thickness must be a non-zero number')\n }\n const kernel = getBrepApi()\n const handle = brepOf(input) as BrepHandle | undefined\n if (!handle) throw new Error('[thicken] input is not BREP')\n const h = getOcctKernel().thicken(handle as never, thickness, 1e-6) as unknown as BrepHandle\n return fromBrep(solidToShape(kernel, h), { solid: h }) as Shape\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: 'thickened-body face vocabulary not defined' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"thicken.js","sourceRoot":"","sources":["../../src/api/thicken.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAGzD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;IAC9B,IAAI,EAAE,SAAS;IACf,IAAI,CAAC,KAAY,EAAE,SAAiB;QAClC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;QACtF,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAA;QACzF,CAAC;QACD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;QACtD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAC3D,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC,OAAO,CAAC,MAAe,EAAE,SAAS,EAAE,IAAI,CAA0B,CAAA;QAC5F,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAU,CAAA;IACjE,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,CAAC;IACjB,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,4CAA4C,EAAgB;CAClG,CAAC,CAAA","sourcesContent":["/**\n * api thicken — 加厚:把面(或壳)沿法向偏置成等厚实体(手写平台 op,Phase 4 → G5 core 直连)\n *\n * @platform occt — 实现走 occt-wasm 原生 `thicken`(BRepOffsetAPI_MakeThickSolid;\n * engine-method-map 里 `thicken` 为 occt-only)⇒ 平台 op:defineOp 声明\n * `engines: ['occt']`(D11)。\n *\n * core-decouple G5:vendored `thicken`(brepjs modifierFns,thickenWithHistory)\n * 替换为 occt-wasm 原生直连,产物经 `fromBrep` 收养(替代 l3-bridge adoptEntity)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, fromBrep } from '../shape'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getOcctKernel } from '../occt-kernel/occtKernel'\nimport type { BrepHandle } from '../brep/engine/types'\n\n/**\n * 加厚:把面(或壳)沿法向偏置成等厚实体。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name thicken\n * @note 平台 op:仅 occt 引擎(BRepOffset)。输入为面/壳 Shape(如 cad.profile 产物);\n * 正厚度沿法向、负厚度反向。非 occt 引擎执行前报错;brep_mock 不拦截。\n * @returns Shape 加厚后的实体。\n * @param input - 面/壳几何(cad.profile 产物等)。type:Shape required:true\n * @param thickness - 厚度(mm,≠0;正沿法向,负反向)。type:number required:true\n * @example\n * const face = cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -10, y1: -10, x2: 10, y2: -10 },\n * { kind: 'line', x1: 10, y1: -10, x2: 10, y2: 10 },\n * { kind: 'line', x1: 10, y1: 10, x2: -10, y2: 10 },\n * { kind: 'line', x1: -10, y1: 10, x2: -10, y2: -10 },\n * ] }] })\n * const solid = await cad.thicken(face, 2)\n */\nexport const thicken = defineOp({\n name: 'thicken',\n brep(input: Shape, thickness: number) {\n if (!input) throw new Error('E_THICKEN_NO_SHAPE: thicken requires a face/shell shape')\n if (typeof thickness !== 'number' || !Number.isFinite(thickness) || thickness === 0) {\n throw new Error('E_THICKEN_BAD_THICKNESS: thicken.thickness must be a non-zero number')\n }\n const kernel = getBrepApi()\n const handle = brepOf(input) as BrepHandle | undefined\n if (!handle) throw new Error('[thicken] input is not BREP')\n const h = getOcctKernel().thicken(handle as never, thickness, 1e-6) as unknown as BrepHandle\n return fromBrep(solidToShape(kernel, h), { solid: h }) as Shape\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: 'thickened-body face vocabulary not defined' } as Provenance,\n})\n"]}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 与 core/topology/naming 的分工:
5
5
  * - naming(core)负责纯解析:给 ReactsContext + FaceTopoRef → ordinal/handle;
6
- * - 本模块(stdlib)是「活 Shape → React块(ResolutionContext)」的引擎胶水:
6
+ * - 本模块(api 层)是「活 Shape → React块(ResolutionContext)」的引擎胶水:
7
7
  * 从 Shape 身份槽读出运行期数据(BREP 活句柄 + RoleTable,或 setTopology 注入的
8
8
  * 面 hint 快照),并把解析结果还原成求解需要的几何(center/normal/surfaceType)。
9
9
  *
@@ -15,6 +15,7 @@
15
15
  import type { Shape } from '../mesh/types.js';
16
16
  import type { BrepEngineApi } from '../brep/engine/primitives.js';
17
17
  import type { BrepHandle } from '../brep/engine/types.js';
18
+ import { type PartName, type StmtId } from '../identity.js';
18
19
  import { type FaceTopoRef, type ResolutionContext, type AxisHint, type RoleTable } from '../topology/naming/index.js';
19
20
  /** 求解面需要的当前几何(执行期派生):与旧契约 fixedFace/movingFace 的 surfaceType/center/normal 同形。 */
20
21
  export interface ResolvedFaceGeometry {
@@ -24,6 +25,40 @@ export interface ResolvedFaceGeometry {
24
25
  /** 圆柱/回转面的轴(装配轴约束用;平面/球面缺省,mesh 行快照由宿主注入)。 */
25
26
  axis?: AxisHint;
26
27
  }
28
+ /**
29
+ * 边路径「无血统邻面」恢复(1.10 前置③ 推广到边路径)。
30
+ *
31
+ * `edgeRef` 正查 `findOriginRole(table, ordinalToHash, fo)`(面 hash → `(origin, role)`)
32
+ * 失败,通常因为**目标 part** 的 roleTable 缓存**残缺**(丢了该面的条目),而**根节点**
33
+ * (名字的诞生处)的表是完整的:该面的 `(origin, role)` 真实存在,只是没被缓存到目标 part
34
+ * 的表副本里(drift / 中间 op 原样带走旧 hash 表)。
35
+ *
36
+ * 与面路径 `recomputeViaLineage` 同构、方向相反——已知面 hash、不知道它属于哪个
37
+ * `(origin, role)`。恢复策略:遍历血缘图所有候选 `(origin, role)`,沿 DAG 从根走到目标
38
+ * part,把根序(该 role 的 hash 集)推进到目标序、换算成目标 hash 集,取**含该面当前 hash**
39
+ * 者,即该面的真实身份。
40
+ *
41
+ * 推进规则(自带,不依赖 `resolveViaLineage` 的严格契约):
42
+ * - 中间节点有 ordinal 演化(Map)→ 照用;
43
+ * - 中间节点是 identity 类(copy/place/transform)但**未挂演化**(既有缺口,见
44
+ * `place.ts` 经 compat 路径未 `attachEvolution`)→ 按 1:1 推进(语义正确:identity 不改
45
+ * 面序);
46
+ * - 其余无演化 → 放弃该候选(不乱猜)。
47
+ *
48
+ * 命中即回填 `{origin, role}` 让 `resolveEdgeTopo` 继续(exact 或几何兜底);未命中返回
49
+ * undefined,调用方保持原 `no role lineage` 报错——零回归。仅跑在 `findOriginRole` 失败
50
+ * 之后(错误路径),不进热路径。
51
+ *
52
+ * @param kernel - the OCCT kernel (hash 换算需要).
53
+ * @param part - the live part whose adjacent face we are recovering.
54
+ * @param faceOrdinal - the 1-based face ordinal whose role is missing.
55
+ * @param ordinalToHash - the part's current face ordinal → hash array.
56
+ * @returns the recovered `{origin, role}`, or undefined when no lineage walk matches.
57
+ */
58
+ export declare function recoverEdgeFaceRole(kernel: BrepEngineApi, part: PartName, faceOrdinal: number, ordinalToHash: readonly number[]): {
59
+ origin: StmtId;
60
+ role: string;
61
+ } | undefined;
27
62
  /**
28
63
  * 从活 Shape 的组装槽构建 ResolutionContext(BREAK 或 mesh/primitive 两条路)。
29
64
  *
@@ -54,6 +89,44 @@ export declare function buildShapeResolutionContext(kernel: BrepEngineApi | null
54
89
  * no BREP naming slot.
55
90
  */
56
91
  export declare function buildEdgeResolutionContext(kernel: BrepEngineApi, shape: object | undefined): ResolutionContext | undefined;
92
+ /**
93
+ * 为**网格实体**构建带边候选的 ResolutionContext(近似拓扑的边解析入口)。
94
+ *
95
+ * 与 `buildEdgeResolutionContext` 的差别只有两点,两点都是"网格零件没有 role 层"
96
+ * 的直接后果:
97
+ * 1. 句柄来自 `slot.meshSolid`(网格实体句柄)而不是 `slot.solid`(BREP 句柄);
98
+ * 2. **刻意不给 `faceEdgeAdjacency` / `edgeFaceAdjacency`**。
99
+ *
100
+ * 第 2 点是有意的,不是省事:邻接表存在的意义是"两面之交 = 一条边",
101
+ * 而 `EdgeTopoRef.faces` 是两个 **RoleQualifier**——网格零件没有 role
102
+ * (Phase 1.8:primitive/mesh 行 origin/role 显式为 null),限定符只是占位。
103
+ * 带上邻接表反而会让 `resolveEdgeTopo` 走进"按角色取公共边"的分支并必然 not-found;
104
+ * 不带它,解析就走「无 role 层 → 整个边表的纯几何匹配」(resolve-edge.ts 明写)。
105
+ * 边身份只能几何,这是如实的能力边界。
106
+ *
107
+ * @param kernel - the mesh backend's L1 kernel (live edge handles come from it).
108
+ * @param shape - the live mesh-solid shape whose naming slot is read.
109
+ * @returns the edge-enabled resolution context, or undefined when the shape is not a mesh solid.
110
+ */
111
+ export declare function buildMeshEdgeResolutionContext(kernel: BrepEngineApi, shape: object | undefined): ResolutionContext | undefined;
112
+ /**
113
+ * 为**网格实体**构建面解析上下文(`sketchOnFace` 的网格链入口)。
114
+ *
115
+ * 面候选直接来自 `slot.meshSolid` 的 `getSubShapes(solid,'face')` 现场句柄——
116
+ * 与 `buildMeshEdgeResolutionContext` 的面表同源(同一枚举序)。**刻意不给
117
+ * `roleTable` / 邻接**:网格零件没有 role 层(Phase 1.8),带上 roleTable 只会让
118
+ * `resolveFaceTopo` 走进 exact 分支并必然落空;不带它,解析就走「全形状按 hint
119
+ * 几何打分」(resolve-face.ts 步骤 2),命中即 `geometric-fallback`。
120
+ *
121
+ * 也因此,网格链上的面只能用**几何**识别(法向 / 中心 / 面积)——这是如实的能力
122
+ * 边界,不是省事:同尺寸的两个平行面(如立方体的顶面与底面)在几何上无法区分,
123
+ * 调用方应改用序号。
124
+ *
125
+ * @param kernel - the mesh backend's L1 kernel (live face handles come from it).
126
+ * @param shape - the live mesh-solid shape whose naming slot is read.
127
+ * @returns the face resolution context, or undefined when the shape is not a mesh solid.
128
+ */
129
+ export declare function buildMeshFaceResolutionContext(kernel: BrepEngineApi, shape: object | undefined): ResolutionContext | undefined;
57
130
  /**
58
131
  * 从 BREP 现场句柄建带边候选/邻接的 ResolutionContext(twoDistances 逐边重建用)。
59
132
  *
@@ -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;AAKtD,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;;;;;;;;;;;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;;;;;;;;;;;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,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"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 与 core/topology/naming 的分工:
5
5
  * - naming(core)负责纯解析:给 ReactsContext + FaceTopoRef → ordinal/handle;
6
- * - 本模块(stdlib)是「活 Shape → React块(ResolutionContext)」的引擎胶水:
6
+ * - 本模块(api 层)是「活 Shape → React块(ResolutionContext)」的引擎胶水:
7
7
  * 从 Shape 身份槽读出运行期数据(BREP 活句柄 + RoleTable,或 setTopology 注入的
8
8
  * 面 hint 快照),并把解析结果还原成求解需要的几何(center/normal/surfaceType)。
9
9
  *
@@ -15,7 +15,7 @@
15
15
  import { getSlot } from '../shape.js';
16
16
  import { nameOf } from '../runtime-state.js';
17
17
  import { HASH_UPPER_BOUND } from '../brep/face-evolution.js';
18
- import { runtimeLineage } from '../topology/naming/lineage.js';
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
21
  import { resolveTopoRef, captureFaceHint, captureEdgeHint, faceRowToHint, TopoRefError, } from '../topology/naming/index.js';
@@ -58,6 +58,122 @@ function recomputeViaLineage(ref, shape, kernel) {
58
58
  return undefined;
59
59
  return result.hashes;
60
60
  }
61
+ /**
62
+ * 边路径「无血统邻面」恢复(1.10 前置③ 推广到边路径)。
63
+ *
64
+ * `edgeRef` 正查 `findOriginRole(table, ordinalToHash, fo)`(面 hash → `(origin, role)`)
65
+ * 失败,通常因为**目标 part** 的 roleTable 缓存**残缺**(丢了该面的条目),而**根节点**
66
+ * (名字的诞生处)的表是完整的:该面的 `(origin, role)` 真实存在,只是没被缓存到目标 part
67
+ * 的表副本里(drift / 中间 op 原样带走旧 hash 表)。
68
+ *
69
+ * 与面路径 `recomputeViaLineage` 同构、方向相反——已知面 hash、不知道它属于哪个
70
+ * `(origin, role)`。恢复策略:遍历血缘图所有候选 `(origin, role)`,沿 DAG 从根走到目标
71
+ * part,把根序(该 role 的 hash 集)推进到目标序、换算成目标 hash 集,取**含该面当前 hash**
72
+ * 者,即该面的真实身份。
73
+ *
74
+ * 推进规则(自带,不依赖 `resolveViaLineage` 的严格契约):
75
+ * - 中间节点有 ordinal 演化(Map)→ 照用;
76
+ * - 中间节点是 identity 类(copy/place/transform)但**未挂演化**(既有缺口,见
77
+ * `place.ts` 经 compat 路径未 `attachEvolution`)→ 按 1:1 推进(语义正确:identity 不改
78
+ * 面序);
79
+ * - 其余无演化 → 放弃该候选(不乱猜)。
80
+ *
81
+ * 命中即回填 `{origin, role}` 让 `resolveEdgeTopo` 继续(exact 或几何兜底);未命中返回
82
+ * undefined,调用方保持原 `no role lineage` 报错——零回归。仅跑在 `findOriginRole` 失败
83
+ * 之后(错误路径),不进热路径。
84
+ *
85
+ * @param kernel - the OCCT kernel (hash 换算需要).
86
+ * @param part - the live part whose adjacent face we are recovering.
87
+ * @param faceOrdinal - the 1-based face ordinal whose role is missing.
88
+ * @param ordinalToHash - the part's current face ordinal → hash array.
89
+ * @returns the recovered `{origin, role}`, or undefined when no lineage walk matches.
90
+ */
91
+ export function recoverEdgeFaceRole(kernel, part, faceOrdinal, ordinalToHash) {
92
+ const targetHash = ordinalToHash[faceOrdinal - 1];
93
+ if (targetHash === undefined)
94
+ return undefined;
95
+ // 候选 (origin, role):血缘图所有节点的输出表(根节点诞生名字处)
96
+ const candidates = [];
97
+ for (const stmt of runtimeLineage.stmtIds()) {
98
+ const tbl = runtimeLineage.outputTableOf(stmt);
99
+ if (!tbl)
100
+ continue;
101
+ for (const [origin, roles] of tbl) {
102
+ for (const roleLine of roles.keys())
103
+ candidates.push({ origin, role: roleLine });
104
+ }
105
+ }
106
+ for (const c of candidates) {
107
+ const hashes = lineageHashesAt(kernel, c.origin, c.role, part);
108
+ if (hashes && hashes.includes(targetHash))
109
+ return { origin: asStmtId(c.origin), role: c.role };
110
+ }
111
+ return undefined;
112
+ }
113
+ /**
114
+ * 沿血缘从 `(origin, role)` 的根走到 `targetPart`,把根序推进到目标序、换算成目标 hash 集。
115
+ *
116
+ * @returns the target part's face hashes for this role, or undefined when the
117
+ * chain cannot be walked (unreachable / non-identity node without evolution).
118
+ */
119
+ function lineageHashesAt(kernel, origin, roleLine, targetPart) {
120
+ const root = runtimeLineage.node(asStmtId(origin));
121
+ if (!root)
122
+ return undefined;
123
+ const rootPart = root.outputs[0];
124
+ if (!rootPart)
125
+ return undefined;
126
+ const rootHandle = runtimeLineage.outputHandleOf(asStmtId(origin));
127
+ const rootTable = runtimeLineage.outputTableOf(asStmtId(origin));
128
+ if (rootHandle === undefined || !rootTable)
129
+ return undefined;
130
+ const rootHashes = rootTable.get(origin)?.get(roleLine);
131
+ if (rootHashes === undefined || rootHashes.length === 0)
132
+ return undefined;
133
+ const rootAll = Array.from(kernel.subShapeHashes(rootHandle, 'face', HASH_UPPER_BOUND));
134
+ let ordinals = [];
135
+ for (const h of rootHashes) {
136
+ const idx = rootAll.indexOf(h);
137
+ if (idx >= 0)
138
+ ordinals.push(idx + 1); // ordinal 1 起
139
+ }
140
+ if (ordinals.length === 0)
141
+ return undefined;
142
+ // 逐节点推进:root → targetPart(带访问守卫,防异常 DAG 环路挂死执行)
143
+ const seen = new Set();
144
+ let currentPart = rootPart;
145
+ while (currentPart !== targetPart) {
146
+ if (seen.has(currentPart))
147
+ return undefined;
148
+ seen.add(currentPart);
149
+ const consumer = runtimeLineage.nodeConsuming(currentPart);
150
+ if (!consumer)
151
+ return undefined;
152
+ const evo = consumer.evolution;
153
+ if (evo && !isHashEvolution(evo)) {
154
+ ordinals = ordinals.flatMap((o) => evo.get(o) ?? [o]);
155
+ }
156
+ else if (consumer.provenance.kind === 'identity') {
157
+ // identity 类未挂演化 → 1:1 推进(语义正确)
158
+ }
159
+ else {
160
+ return undefined;
161
+ }
162
+ const carry = consumer.outputs.includes(targetPart) ? targetPart : consumer.outputs[0];
163
+ currentPart = carry;
164
+ }
165
+ const targetHandle = runtimeLineage.outputHandleOf(runtimeLineage.stmtOf(targetPart) ?? asStmtId(''));
166
+ if (targetHandle === undefined)
167
+ return undefined;
168
+ const targetAll = Array.from(kernel.subShapeHashes(targetHandle, 'face', HASH_UPPER_BOUND));
169
+ const hashes = [];
170
+ for (const o of ordinals) {
171
+ const h = targetAll[o - 1];
172
+ if (h !== undefined)
173
+ hashes.push(h);
174
+ }
175
+ return hashes.length > 0 ? hashes : undefined;
176
+ }
61
177
  /**
62
178
  * 从活 Shape 的组装槽构建 ResolutionContext(BREAK 或 mesh/primitive 两条路)。
63
179
  *
@@ -150,6 +266,68 @@ export function buildEdgeResolutionContext(kernel, shape) {
150
266
  });
151
267
  return { kernel, faces, edges, roleTable, faceEdgeAdjacency, edgeFaceAdjacency };
152
268
  }
269
+ /**
270
+ * 为**网格实体**构建带边候选的 ResolutionContext(近似拓扑的边解析入口)。
271
+ *
272
+ * 与 `buildEdgeResolutionContext` 的差别只有两点,两点都是"网格零件没有 role 层"
273
+ * 的直接后果:
274
+ * 1. 句柄来自 `slot.meshSolid`(网格实体句柄)而不是 `slot.solid`(BREP 句柄);
275
+ * 2. **刻意不给 `faceEdgeAdjacency` / `edgeFaceAdjacency`**。
276
+ *
277
+ * 第 2 点是有意的,不是省事:邻接表存在的意义是"两面之交 = 一条边",
278
+ * 而 `EdgeTopoRef.faces` 是两个 **RoleQualifier**——网格零件没有 role
279
+ * (Phase 1.8:primitive/mesh 行 origin/role 显式为 null),限定符只是占位。
280
+ * 带上邻接表反而会让 `resolveEdgeTopo` 走进"按角色取公共边"的分支并必然 not-found;
281
+ * 不带它,解析就走「无 role 层 → 整个边表的纯几何匹配」(resolve-edge.ts 明写)。
282
+ * 边身份只能几何,这是如实的能力边界。
283
+ *
284
+ * @param kernel - the mesh backend's L1 kernel (live edge handles come from it).
285
+ * @param shape - the live mesh-solid shape whose naming slot is read.
286
+ * @returns the edge-enabled resolution context, or undefined when the shape is not a mesh solid.
287
+ */
288
+ export function buildMeshEdgeResolutionContext(kernel, shape) {
289
+ if (!shape)
290
+ return undefined;
291
+ const slot = getSlot(shape);
292
+ const solid = slot?.meshSolid;
293
+ if (!solid)
294
+ return undefined;
295
+ const faceHandles = kernel.getSubShapes(solid, 'face');
296
+ const faces = faceHandles.map((handle, i) => ({ ordinal: i + 1, handle }));
297
+ const edges = kernel.getSubShapes(solid, 'edge').map((handle, i) => ({
298
+ ordinal: i + 1,
299
+ handle,
300
+ hint: captureEdgeHint(kernel, handle),
301
+ }));
302
+ return { kernel, faces, edges };
303
+ }
304
+ /**
305
+ * 为**网格实体**构建面解析上下文(`sketchOnFace` 的网格链入口)。
306
+ *
307
+ * 面候选直接来自 `slot.meshSolid` 的 `getSubShapes(solid,'face')` 现场句柄——
308
+ * 与 `buildMeshEdgeResolutionContext` 的面表同源(同一枚举序)。**刻意不给
309
+ * `roleTable` / 邻接**:网格零件没有 role 层(Phase 1.8),带上 roleTable 只会让
310
+ * `resolveFaceTopo` 走进 exact 分支并必然落空;不带它,解析就走「全形状按 hint
311
+ * 几何打分」(resolve-face.ts 步骤 2),命中即 `geometric-fallback`。
312
+ *
313
+ * 也因此,网格链上的面只能用**几何**识别(法向 / 中心 / 面积)——这是如实的能力
314
+ * 边界,不是省事:同尺寸的两个平行面(如立方体的顶面与底面)在几何上无法区分,
315
+ * 调用方应改用序号。
316
+ *
317
+ * @param kernel - the mesh backend's L1 kernel (live face handles come from it).
318
+ * @param shape - the live mesh-solid shape whose naming slot is read.
319
+ * @returns the face resolution context, or undefined when the shape is not a mesh solid.
320
+ */
321
+ export function buildMeshFaceResolutionContext(kernel, shape) {
322
+ if (!shape)
323
+ return undefined;
324
+ const slot = getSlot(shape);
325
+ const solid = slot?.meshSolid;
326
+ if (!solid)
327
+ return undefined;
328
+ const faces = kernel.getSubShapes(solid, 'face').map((handle, i) => ({ ordinal: i + 1, handle }));
329
+ return { kernel, faces };
330
+ }
153
331
  /**
154
332
  * 从 BREP 现场句柄建带边候选/邻接的 ResolutionContext(twoDistances 逐边重建用)。
155
333
  *