@faicad/faijs 0.22.2 → 0.29.3

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 (448) 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/assert.d.ts +2 -2
  7. package/dist/api/assert.js +8 -8
  8. package/dist/api/assert.js.map +1 -1
  9. package/dist/api/asset.d.ts +1 -1
  10. package/dist/api/asset.js +2 -2
  11. package/dist/api/asset.js.map +1 -1
  12. package/dist/api/boolean.d.ts +1 -1
  13. package/dist/api/boolean.d.ts.map +1 -1
  14. package/dist/api/boolean.js +128 -16
  15. package/dist/api/boolean.js.map +1 -1
  16. package/dist/api/cadquery-selectors/borrow-bridge.d.ts +14 -0
  17. package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -0
  18. package/dist/api/cadquery-selectors/borrow-bridge.js +52 -0
  19. package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -0
  20. package/dist/api/cadquery-selectors/edge.d.ts +40 -0
  21. package/dist/api/cadquery-selectors/edge.d.ts.map +1 -0
  22. package/dist/api/cadquery-selectors/edge.js +70 -0
  23. package/dist/api/cadquery-selectors/edge.js.map +1 -0
  24. package/dist/api/cadquery-selectors/entity.d.ts +121 -0
  25. package/dist/api/cadquery-selectors/entity.d.ts.map +1 -0
  26. package/dist/api/cadquery-selectors/entity.js +167 -0
  27. package/dist/api/cadquery-selectors/entity.js.map +1 -0
  28. package/dist/api/cadquery-selectors/face.d.ts +33 -0
  29. package/dist/api/cadquery-selectors/face.d.ts.map +1 -0
  30. package/dist/api/cadquery-selectors/face.js +353 -0
  31. package/dist/api/cadquery-selectors/face.js.map +1 -0
  32. package/dist/api/cadquery-selectors/grammar.d.ts +50 -0
  33. package/dist/api/cadquery-selectors/grammar.d.ts.map +1 -0
  34. package/dist/api/cadquery-selectors/grammar.js +345 -0
  35. package/dist/api/cadquery-selectors/grammar.js.map +1 -0
  36. package/dist/api/cadquery-selectors/index.d.ts +18 -0
  37. package/dist/api/cadquery-selectors/index.d.ts.map +1 -0
  38. package/dist/api/cadquery-selectors/index.js +17 -0
  39. package/dist/api/cadquery-selectors/index.js.map +1 -0
  40. package/dist/api/cadquery-selectors/predicates.d.ts +76 -0
  41. package/dist/api/cadquery-selectors/predicates.d.ts.map +1 -0
  42. package/dist/api/cadquery-selectors/predicates.js +85 -0
  43. package/dist/api/cadquery-selectors/predicates.js.map +1 -0
  44. package/dist/api/cadquery-selectors/resolve.d.ts +41 -0
  45. package/dist/api/cadquery-selectors/resolve.d.ts.map +1 -0
  46. package/dist/api/cadquery-selectors/resolve.js +243 -0
  47. package/dist/api/cadquery-selectors/resolve.js.map +1 -0
  48. package/dist/api/cadquery-selectors/types.d.ts +96 -0
  49. package/dist/api/cadquery-selectors/types.d.ts.map +1 -0
  50. package/dist/api/cadquery-selectors/types.js +11 -0
  51. package/dist/api/cadquery-selectors/types.js.map +1 -0
  52. package/dist/api/chamfer.d.ts +13 -5
  53. package/dist/api/chamfer.d.ts.map +1 -1
  54. package/dist/api/chamfer.js +63 -7
  55. package/dist/api/chamfer.js.map +1 -1
  56. package/dist/api/compound-geom.d.ts +1 -1
  57. package/dist/api/compound-geom.js +1 -1
  58. package/dist/api/compound-geom.js.map +1 -1
  59. package/dist/api/draft.d.ts +1 -1
  60. package/dist/api/draft.js +1 -1
  61. package/dist/api/draft.js.map +1 -1
  62. package/dist/api/edge-ref.d.ts +1 -1
  63. package/dist/api/edge-ref.d.ts.map +1 -1
  64. package/dist/api/edge-ref.js +11 -3
  65. package/dist/api/edge-ref.js.map +1 -1
  66. package/dist/api/engrave.d.ts +1 -1
  67. package/dist/api/engrave.js +7 -7
  68. package/dist/api/engrave.js.map +1 -1
  69. package/dist/api/extrude.d.ts +6 -1
  70. package/dist/api/extrude.d.ts.map +1 -1
  71. package/dist/api/extrude.js +59 -5
  72. package/dist/api/extrude.js.map +1 -1
  73. package/dist/api/face-ref.d.ts +1 -1
  74. package/dist/api/face-ref.js +1 -1
  75. package/dist/api/face-ref.js.map +1 -1
  76. package/dist/api/feature-repair.d.ts +1 -1
  77. package/dist/api/feature-repair.js +1 -1
  78. package/dist/api/feature-repair.js.map +1 -1
  79. package/dist/api/fillet-variable.d.ts +1 -1
  80. package/dist/api/fillet-variable.js +1 -1
  81. package/dist/api/fillet-variable.js.map +1 -1
  82. package/dist/api/fillet.d.ts +28 -8
  83. package/dist/api/fillet.d.ts.map +1 -1
  84. package/dist/api/fillet.js +64 -9
  85. package/dist/api/fillet.js.map +1 -1
  86. package/dist/api/geom.d.ts +1 -1
  87. package/dist/api/geom.js +1 -1
  88. package/dist/api/geom.js.map +1 -1
  89. package/dist/api/helix.d.ts +1 -1
  90. package/dist/api/helix.js +1 -1
  91. package/dist/api/helix.js.map +1 -1
  92. package/dist/api/import-brep.d.ts +20 -2
  93. package/dist/api/import-brep.d.ts.map +1 -1
  94. package/dist/api/import-brep.js +28 -3
  95. package/dist/api/import-brep.js.map +1 -1
  96. package/dist/api/import-step.d.ts +17 -2
  97. package/dist/api/import-step.d.ts.map +1 -1
  98. package/dist/api/import-step.js +23 -3
  99. package/dist/api/import-step.js.map +1 -1
  100. package/dist/api/index.d.ts +2 -1
  101. package/dist/api/index.d.ts.map +1 -1
  102. package/dist/api/index.js +5 -2
  103. package/dist/api/index.js.map +1 -1
  104. package/dist/api/internal/compat-op.js +1 -1
  105. package/dist/api/internal/compat-op.js.map +1 -1
  106. package/dist/api/internal/mesh-solid-op.d.ts +236 -0
  107. package/dist/api/internal/mesh-solid-op.d.ts.map +1 -0
  108. package/dist/api/internal/mesh-solid-op.js +352 -0
  109. package/dist/api/internal/mesh-solid-op.js.map +1 -0
  110. package/dist/api/internal/svg-asset-resolver.d.ts +1 -1
  111. package/dist/api/internal/svg-asset-resolver.js +1 -1
  112. package/dist/api/internal/svg-asset-resolver.js.map +1 -1
  113. package/dist/api/knurl.d.ts +1 -1
  114. package/dist/api/knurl.js +2 -2
  115. package/dist/api/knurl.js.map +1 -1
  116. package/dist/api/loft.d.ts +1 -1
  117. package/dist/api/loft.js +1 -1
  118. package/dist/api/loft.js.map +1 -1
  119. package/dist/api/measurement/index.d.ts +9 -5
  120. package/dist/api/measurement/index.d.ts.map +1 -1
  121. package/dist/api/measurement/index.js +47 -20
  122. package/dist/api/measurement/index.js.map +1 -1
  123. package/dist/api/pattern.d.ts +5 -3
  124. package/dist/api/pattern.d.ts.map +1 -1
  125. package/dist/api/pattern.js +32 -4
  126. package/dist/api/pattern.js.map +1 -1
  127. package/dist/api/place.d.ts +1 -1
  128. package/dist/api/place.js +1 -1
  129. package/dist/api/place.js.map +1 -1
  130. package/dist/api/primitives.d.ts +1 -1
  131. package/dist/api/primitives.js +2 -2
  132. package/dist/api/primitives.js.map +1 -1
  133. package/dist/api/profile.d.ts +39 -12
  134. package/dist/api/profile.d.ts.map +1 -1
  135. package/dist/api/profile.js +4 -4
  136. package/dist/api/profile.js.map +1 -1
  137. package/dist/api/reconcile.d.ts +1 -1
  138. package/dist/api/reconcile.js +1 -1
  139. package/dist/api/reconcile.js.map +1 -1
  140. package/dist/api/replicate.d.ts.map +1 -1
  141. package/dist/api/replicate.js +122 -1
  142. package/dist/api/replicate.js.map +1 -1
  143. package/dist/api/screw.d.ts +1 -1
  144. package/dist/api/screw.js +3 -3
  145. package/dist/api/screw.js.map +1 -1
  146. package/dist/api/sdf.d.ts +1 -1
  147. package/dist/api/sdf.js +2 -2
  148. package/dist/api/sdf.js.map +1 -1
  149. package/dist/api/section-by-plane.d.ts +1 -1
  150. package/dist/api/section-by-plane.d.ts.map +1 -1
  151. package/dist/api/section-by-plane.js +2 -1
  152. package/dist/api/section-by-plane.js.map +1 -1
  153. package/dist/api/shell.d.ts +11 -4
  154. package/dist/api/shell.d.ts.map +1 -1
  155. package/dist/api/shell.js +53 -7
  156. package/dist/api/shell.js.map +1 -1
  157. package/dist/api/sketch-on-face.d.ts +41 -0
  158. package/dist/api/sketch-on-face.d.ts.map +1 -1
  159. package/dist/api/sketch-on-face.js +100 -1
  160. package/dist/api/sketch-on-face.js.map +1 -1
  161. package/dist/api/sketch-on-plane.d.ts +7 -5
  162. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  163. package/dist/api/sketch-on-plane.js +6 -7
  164. package/dist/api/sketch-on-plane.js.map +1 -1
  165. package/dist/api/split-by-plane.d.ts +1 -1
  166. package/dist/api/split-by-plane.d.ts.map +1 -1
  167. package/dist/api/split-by-plane.js +2 -1
  168. package/dist/api/split-by-plane.js.map +1 -1
  169. package/dist/api/split.d.ts +1 -1
  170. package/dist/api/split.js +2 -2
  171. package/dist/api/split.js.map +1 -1
  172. package/dist/api/sweep.d.ts +1 -1
  173. package/dist/api/sweep.js +1 -1
  174. package/dist/api/sweep.js.map +1 -1
  175. package/dist/api/thicken.d.ts +1 -1
  176. package/dist/api/thicken.js +1 -1
  177. package/dist/api/thicken.js.map +1 -1
  178. package/dist/api/topo-resolve.d.ts +74 -1
  179. package/dist/api/topo-resolve.d.ts.map +1 -1
  180. package/dist/api/topo-resolve.js +180 -2
  181. package/dist/api/topo-resolve.js.map +1 -1
  182. package/dist/api/transform.d.ts +5 -1
  183. package/dist/api/transform.d.ts.map +1 -1
  184. package/dist/api/transform.js +62 -11
  185. package/dist/api/transform.js.map +1 -1
  186. package/dist/api/wire.d.ts +1 -1
  187. package/dist/api/wire.js +1 -1
  188. package/dist/api/wire.js.map +1 -1
  189. package/dist/brep/brep-ops.d.ts +9 -7
  190. package/dist/brep/brep-ops.d.ts.map +1 -1
  191. package/dist/brep/brep-ops.js +23 -24
  192. package/dist/brep/brep-ops.js.map +1 -1
  193. package/dist/brep/brep-topology.d.ts +5 -4
  194. package/dist/brep/brep-topology.d.ts.map +1 -1
  195. package/dist/brep/brep-topology.js +6 -5
  196. package/dist/brep/brep-topology.js.map +1 -1
  197. package/dist/brep/effective-deflection.d.ts +35 -0
  198. package/dist/brep/effective-deflection.d.ts.map +1 -0
  199. package/dist/brep/effective-deflection.js +49 -0
  200. package/dist/brep/effective-deflection.js.map +1 -0
  201. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  202. package/dist/brep/engine/adapters/brep-mock.js +27 -0
  203. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  204. package/dist/brep/engine/adapters/brepkit.d.ts +18 -0
  205. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  206. package/dist/brep/engine/adapters/brepkit.js +46 -1
  207. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  208. package/dist/brep/engine/adapters/occt.d.ts +1 -1
  209. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  210. package/dist/brep/engine/adapters/occt.js +3 -1
  211. package/dist/brep/engine/adapters/occt.js.map +1 -1
  212. package/dist/brep/engine/primitives.d.ts +29 -7
  213. package/dist/brep/engine/primitives.d.ts.map +1 -1
  214. package/dist/brep/engine/primitives.js.map +1 -1
  215. package/dist/brep/engine/registry.d.ts +24 -1
  216. package/dist/brep/engine/registry.d.ts.map +1 -1
  217. package/dist/brep/engine/registry.js +24 -0
  218. package/dist/brep/engine/registry.js.map +1 -1
  219. package/dist/brep/engine/types.d.ts +54 -3
  220. package/dist/brep/engine/types.d.ts.map +1 -1
  221. package/dist/brep/engine/types.js +10 -0
  222. package/dist/brep/engine/types.js.map +1 -1
  223. package/dist/brep/export/export-model.d.ts.map +1 -1
  224. package/dist/brep/export/export-model.js +6 -5
  225. package/dist/brep/export/export-model.js.map +1 -1
  226. package/dist/brep/face-evolution.d.ts +1 -1
  227. package/dist/brep/face-evolution.d.ts.map +1 -1
  228. package/dist/brep/face-evolution.js +20 -1
  229. package/dist/brep/face-evolution.js.map +1 -1
  230. package/dist/brep/handle-bridge.d.ts +1 -1
  231. package/dist/brep/handle-bridge.js +1 -1
  232. package/dist/brep/handle-bridge.js.map +1 -1
  233. package/dist/brep/mesh-solid.d.ts +218 -0
  234. package/dist/brep/mesh-solid.d.ts.map +1 -0
  235. package/dist/brep/mesh-solid.js +229 -0
  236. package/dist/brep/mesh-solid.js.map +1 -0
  237. package/dist/brep/text/fontRegistry.d.ts +32 -1
  238. package/dist/brep/text/fontRegistry.d.ts.map +1 -1
  239. package/dist/brep/text/fontRegistry.js +51 -1
  240. package/dist/brep/text/fontRegistry.js.map +1 -1
  241. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  242. package/dist/brep/text/text-to-solid.js +8 -3
  243. package/dist/brep/text/text-to-solid.js.map +1 -1
  244. package/dist/brepkit-kernel/brepkitKernel.d.ts +18 -2
  245. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  246. package/dist/brepkit-kernel/brepkitKernel.js +449 -123
  247. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  248. package/dist/brepkit-kernel/brepkitWasm.d.ts +8 -0
  249. package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
  250. package/dist/brepkit-kernel/brepkitWasm.js +10 -0
  251. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  252. package/dist/browser-host/browser-font-provider.d.ts +12 -0
  253. package/dist/browser-host/browser-font-provider.d.ts.map +1 -1
  254. package/dist/browser-host/browser-font-provider.js +25 -0
  255. package/dist/browser-host/browser-font-provider.js.map +1 -1
  256. package/dist/browser.d.ts +6 -3
  257. package/dist/browser.d.ts.map +1 -1
  258. package/dist/browser.js +10 -3
  259. package/dist/browser.js.map +1 -1
  260. package/dist/cad-runtime/backend-dispatch.d.ts +28 -3
  261. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  262. package/dist/cad-runtime/backend-dispatch.js +119 -4
  263. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  264. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  265. package/dist/cad-runtime/direct-executor.d.ts +15 -3
  266. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  267. package/dist/cad-runtime/direct-executor.js +33 -1
  268. package/dist/cad-runtime/direct-executor.js.map +1 -1
  269. package/dist/cad-runtime/ports.d.ts +3 -3
  270. package/dist/cad-runtime/ports.d.ts.map +1 -1
  271. package/dist/cad-runtime/ports.js.map +1 -1
  272. package/dist/cad-runtime/preview-exec.d.ts +4 -4
  273. package/dist/cad-runtime/preview-exec.js +2 -2
  274. package/dist/cad-runtime/preview-exec.js.map +1 -1
  275. package/dist/cad-runtime/runtime.d.ts +42 -7
  276. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  277. package/dist/cad-runtime/runtime.js +68 -5
  278. package/dist/cad-runtime/runtime.js.map +1 -1
  279. package/dist/define-op.d.ts +15 -1
  280. package/dist/define-op.d.ts.map +1 -1
  281. package/dist/define-op.js +10 -1
  282. package/dist/define-op.js.map +1 -1
  283. package/dist/env-agnostic.d.ts +2 -2
  284. package/dist/env-agnostic.d.ts.map +1 -1
  285. package/dist/env-agnostic.js +1 -1
  286. package/dist/env-agnostic.js.map +1 -1
  287. package/dist/geometry2d/adapt.d.ts +39 -4
  288. package/dist/geometry2d/adapt.d.ts.map +1 -1
  289. package/dist/geometry2d/adapt.js +14 -3
  290. package/dist/geometry2d/adapt.js.map +1 -1
  291. package/dist/geometry2d/blueprint.d.ts +2 -2
  292. package/dist/geometry2d/blueprint.js +2 -2
  293. package/dist/geometry2d/blueprint.js.map +1 -1
  294. package/dist/geometry2d/bridge/lift-on-plane.d.ts +18 -8
  295. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  296. package/dist/geometry2d/bridge/lift-on-plane.js +65 -12
  297. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  298. package/dist/geometry2d/bridge/plane.d.ts +17 -0
  299. package/dist/geometry2d/bridge/plane.d.ts.map +1 -1
  300. package/dist/geometry2d/bridge/plane.js +22 -0
  301. package/dist/geometry2d/bridge/plane.js.map +1 -1
  302. package/dist/geometry2d/curve2d.d.ts +25 -0
  303. package/dist/geometry2d/curve2d.d.ts.map +1 -1
  304. package/dist/geometry2d/curve2d.js +41 -5
  305. package/dist/geometry2d/curve2d.js.map +1 -1
  306. package/dist/index.d.ts +6 -2
  307. package/dist/index.d.ts.map +1 -1
  308. package/dist/index.js +10 -3
  309. package/dist/index.js.map +1 -1
  310. package/dist/io/bytes-node.d.ts +11 -0
  311. package/dist/io/bytes-node.d.ts.map +1 -0
  312. package/dist/io/bytes-node.js +28 -0
  313. package/dist/io/bytes-node.js.map +1 -0
  314. package/dist/io/bytes.d.ts +33 -0
  315. package/dist/io/bytes.d.ts.map +1 -0
  316. package/dist/io/bytes.js +41 -0
  317. package/dist/io/bytes.js.map +1 -0
  318. package/dist/io/fai-zip/container-read.d.ts +102 -0
  319. package/dist/io/fai-zip/container-read.d.ts.map +1 -0
  320. package/dist/io/fai-zip/container-read.js +305 -0
  321. package/dist/io/fai-zip/container-read.js.map +1 -0
  322. package/dist/io/fai-zip/container-write.d.ts +70 -0
  323. package/dist/io/fai-zip/container-write.d.ts.map +1 -0
  324. package/dist/io/fai-zip/container-write.js +186 -0
  325. package/dist/io/fai-zip/container-write.js.map +1 -0
  326. package/dist/io/fai-zip/container.d.ts +107 -0
  327. package/dist/io/fai-zip/container.d.ts.map +1 -0
  328. package/dist/io/fai-zip/container.js +89 -0
  329. package/dist/io/fai-zip/container.js.map +1 -0
  330. package/dist/io/fai-zip/index.d.ts +18 -0
  331. package/dist/io/fai-zip/index.d.ts.map +1 -0
  332. package/dist/io/fai-zip/index.js +4 -0
  333. package/dist/io/fai-zip/index.js.map +1 -0
  334. package/dist/io/index.d.ts +10 -0
  335. package/dist/io/index.d.ts.map +1 -0
  336. package/dist/io/index.js +13 -0
  337. package/dist/io/index.js.map +1 -0
  338. package/dist/io/zip.d.ts +68 -0
  339. package/dist/io/zip.d.ts.map +1 -0
  340. package/dist/io/zip.js +147 -0
  341. package/dist/io/zip.js.map +1 -0
  342. package/dist/lang/code-to-args.d.ts +1 -1
  343. package/dist/lang/code-to-args.js +1 -1
  344. package/dist/lang/code-to-args.js.map +1 -1
  345. package/dist/lang/statement-summary.d.ts +1 -1
  346. package/dist/lang/statement-summary.js +1 -1
  347. package/dist/lang/statement-summary.js.map +1 -1
  348. package/dist/lang/types.d.ts +1 -1
  349. package/dist/lang/types.js +1 -1
  350. package/dist/lang/types.js.map +1 -1
  351. package/dist/mesh/index.d.ts +2 -1
  352. package/dist/mesh/index.d.ts.map +1 -1
  353. package/dist/mesh/index.js +2 -1
  354. package/dist/mesh/index.js.map +1 -1
  355. package/dist/mesh/io.d.ts +7 -0
  356. package/dist/mesh/io.d.ts.map +1 -1
  357. package/dist/mesh/io.js +14 -17
  358. package/dist/mesh/io.js.map +1 -1
  359. package/dist/mesh/reconcile.d.ts +1 -1
  360. package/dist/mesh/reconcile.js +1 -1
  361. package/dist/mesh/reconcile.js.map +1 -1
  362. package/dist/mesh/rigid-transform.d.ts +3 -3
  363. package/dist/mesh/rigid-transform.js +3 -3
  364. package/dist/mesh/rigid-transform.js.map +1 -1
  365. package/dist/mesh/stl-unit.d.ts +24 -0
  366. package/dist/mesh/stl-unit.d.ts.map +1 -0
  367. package/dist/mesh/stl-unit.js +17 -0
  368. package/dist/mesh/stl-unit.js.map +1 -0
  369. package/dist/mesh/threemf-bambu.d.ts +142 -0
  370. package/dist/mesh/threemf-bambu.d.ts.map +1 -0
  371. package/dist/mesh/threemf-bambu.js +334 -0
  372. package/dist/mesh/threemf-bambu.js.map +1 -0
  373. package/dist/mesh/threemf-loader.d.ts +42 -7
  374. package/dist/mesh/threemf-loader.d.ts.map +1 -1
  375. package/dist/mesh/threemf-loader.js +565 -100
  376. package/dist/mesh/threemf-loader.js.map +1 -1
  377. package/dist/mesh/threemf-view.d.ts +71 -0
  378. package/dist/mesh/threemf-view.d.ts.map +1 -0
  379. package/dist/mesh/threemf-view.js +100 -0
  380. package/dist/mesh/threemf-view.js.map +1 -0
  381. package/dist/node-host/cli.d.ts +44 -6
  382. package/dist/node-host/cli.d.ts.map +1 -1
  383. package/dist/node-host/cli.js +76 -26
  384. package/dist/node-host/cli.js.map +1 -1
  385. package/dist/node-host/font-family-index.d.ts +93 -0
  386. package/dist/node-host/font-family-index.d.ts.map +1 -0
  387. package/dist/node-host/font-family-index.js +273 -0
  388. package/dist/node-host/font-family-index.js.map +1 -0
  389. package/dist/node-host/fs-asset-resolver.d.ts +8 -3
  390. package/dist/node-host/fs-asset-resolver.d.ts.map +1 -1
  391. package/dist/node-host/fs-asset-resolver.js +13 -5
  392. package/dist/node-host/fs-asset-resolver.js.map +1 -1
  393. package/dist/node-host/index.d.ts +8 -0
  394. package/dist/node-host/index.d.ts.map +1 -1
  395. package/dist/node-host/index.js +1 -0
  396. package/dist/node-host/index.js.map +1 -1
  397. package/dist/node-host/node-font-provider.d.ts +28 -0
  398. package/dist/node-host/node-font-provider.d.ts.map +1 -1
  399. package/dist/node-host/node-font-provider.js +49 -0
  400. package/dist/node-host/node-font-provider.js.map +1 -1
  401. package/dist/node.d.ts +1 -0
  402. package/dist/node.d.ts.map +1 -1
  403. package/dist/node.js +1 -0
  404. package/dist/node.js.map +1 -1
  405. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  406. package/dist/occt-kernel/occt-primitives.js +35 -2
  407. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  408. package/dist/occt-kernel/occtKernel.d.ts +18 -13
  409. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  410. package/dist/occt-kernel/occtKernel.js +18 -31
  411. package/dist/occt-kernel/occtKernel.js.map +1 -1
  412. package/dist/occt-kernel/stepColorParser.d.ts +18 -0
  413. package/dist/occt-kernel/stepColorParser.d.ts.map +1 -1
  414. package/dist/occt-kernel/stepColorParser.js +38 -0
  415. package/dist/occt-kernel/stepColorParser.js.map +1 -1
  416. package/dist/occt-kernel/topologyExt.d.ts +1 -1
  417. package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
  418. package/dist/occt-kernel/topologyExt.js +4 -5
  419. package/dist/occt-kernel/topologyExt.js.map +1 -1
  420. package/dist/primitives/text/cjk-font.d.ts +2 -15
  421. package/dist/primitives/text/cjk-font.d.ts.map +1 -1
  422. package/dist/primitives/text/cjk-font.js +13 -1
  423. package/dist/primitives/text/cjk-font.js.map +1 -1
  424. package/dist/runtime-state.d.ts +85 -9
  425. package/dist/runtime-state.d.ts.map +1 -1
  426. package/dist/runtime-state.js +72 -2
  427. package/dist/runtime-state.js.map +1 -1
  428. package/dist/sdk.d.ts +3 -3
  429. package/dist/sdk.d.ts.map +1 -1
  430. package/dist/sdk.js +5 -5
  431. package/dist/sdk.js.map +1 -1
  432. package/dist/shape.d.ts +97 -2
  433. package/dist/shape.d.ts.map +1 -1
  434. package/dist/shape.js +126 -1
  435. package/dist/shape.js.map +1 -1
  436. package/dist/topology/naming/lineage.d.ts +6 -0
  437. package/dist/topology/naming/lineage.d.ts.map +1 -1
  438. package/dist/topology/naming/lineage.js +8 -0
  439. package/dist/topology/naming/lineage.js.map +1 -1
  440. package/dist/topology/naming/resolve-edge.d.ts +20 -1
  441. package/dist/topology/naming/resolve-edge.d.ts.map +1 -1
  442. package/dist/topology/naming/resolve-edge.js +54 -20
  443. package/dist/topology/naming/resolve-edge.js.map +1 -1
  444. package/dist/weapp.d.ts +6 -2
  445. package/dist/weapp.d.ts.map +1 -1
  446. package/dist/weapp.js +7 -1
  447. package/dist/weapp.js.map +1 -1
  448. package/package.json +18 -2
@@ -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
  *
@@ -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 * - 本模块(stdlib)是「活 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 } from '../topology/naming/lineage'\nimport { resolveViaLineage } from '../topology/naming/lineage-resolve'\nimport { asStmtId } 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 * 从活 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) {\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) 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 * 从 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 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) {\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) 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) 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) 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,5 +1,5 @@
1
1
  /**
2
- * stdlib transform — 变换对象库函数(translate/rotate_euler/scale/scale3d)
2
+ * api transform — 变换对象库函数(translate/rotate_euler/scale/scale3d)
3
3
  *
4
4
  * 平台分层(narrowing plan Phase 5,D11 + 2026-09-28 D 批降级):
5
5
  * - `translate` / `scale`:**中立 op**(不再声明 `engines:['occt']`)。BREP 路径按引擎
@@ -17,6 +17,10 @@
17
17
  *
18
18
  * dispatchPath 静态判定 brep/mesh,
19
19
  * BREP 路径用 brepOf(input) 取输入实体、fromBrep 登记输出实体。
20
+ *
21
+ * 网格链(方案 2026-10-01 §4 Phase 4 / B3 批):`mesh:` 实现分两支——**网格实体**
22
+ * 走网格后端内核变换句柄(保持网格零件身份与近似拓扑),**裸网格**维持既有的顶点
23
+ * 烘焙(manifold 链,无身份可言)。两支靠 `hasMeshSolid` 区分,不靠"能不能跑"试错。
20
24
  */
21
25
  import type { Shape } from '../mesh/types.js';
22
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/api/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAqBhD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE3E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKxE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQvE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQzE;AA0FD;;;;;;;;;;;;;IAaI;AACJ,eAAO,MAAM,SAAS;;CAiBpB,CAAA;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY;;CAgBvB,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,KAAK;;CAkBhB,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,OAAO;;CAkBlB,CAAA"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/api/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAsBhD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE3E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKxE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQvE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQzE;AA0HD;;;;;;;;;;;;;IAaI;AACJ,eAAO,MAAM,SAAS;;CAmBpB,CAAA;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY;;CAkBvB,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,KAAK;;CAoBhB,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,OAAO;;CAoBlB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * stdlib transform — 变换对象库函数(translate/rotate_euler/scale/scale3d)
2
+ * api transform — 变换对象库函数(translate/rotate_euler/scale/scale3d)
3
3
  *
4
4
  * 平台分层(narrowing plan Phase 5,D11 + 2026-09-28 D 批降级):
5
5
  * - `translate` / `scale`:**中立 op**(不再声明 `engines:['occt']`)。BREP 路径按引擎
@@ -17,6 +17,10 @@
17
17
  *
18
18
  * dispatchPath 静态判定 brep/mesh,
19
19
  * BREP 路径用 brepOf(input) 取输入实体、fromBrep 登记输出实体。
20
+ *
21
+ * 网格链(方案 2026-10-01 §4 Phase 4 / B3 批):`mesh:` 实现分两支——**网格实体**
22
+ * 走网格后端内核变换句柄(保持网格零件身份与近似拓扑),**裸网格**维持既有的顶点
23
+ * 烘焙(manifold 链,无身份可言)。两支靠 `hasMeshSolid` 区分,不靠"能不能跑"试错。
20
24
  */
21
25
  import { cad } from '../mesh/index.js';
22
26
  import { translateBrep, rotateBrep, scaleBrep, solidToShape } from '../brep/brep-ops.js';
@@ -24,10 +28,11 @@ import { identityEvolution, identityHashEvolution, scaleWithHashEvolution, trans
24
28
  import { getBrepApi } from '../brep/handle-bridge.js';
25
29
  import { getBackends } from '../runtime-state.js';
26
30
  import { engineCapabilitySet } from '../cad-runtime/backend-dispatch.js';
27
- import { fromBrep, brepOf, inputRoleTable } from '../shape.js';
31
+ import { fromBrep, brepOf, inputRoleTable, hasMeshSolid } from '../shape.js';
28
32
  import { propagateAllOrigins } from '../topology/naming/roles.js';
29
33
  import { defineOp } from '../sdk.js';
30
34
  import { assertVec3, assertPositiveNumber } from './assert.js';
35
+ import { meshSolidBasicEntry, meshSolidProduct } from './internal/mesh-solid-op.js';
31
36
  /**
32
37
  * Validate translate parameters: `offset` must be a vec3.
33
38
  * @param params - the raw translate operation parameters.
@@ -94,7 +99,7 @@ function transformBrep(op, input, params) {
94
99
  const kernel = getBrepApi();
95
100
  const inputSolid = brepOf(input);
96
101
  if (!inputSolid)
97
- throw new Error('[stdlib/transform] input is not BREP');
102
+ throw new Error('[api/transform] input is not BREP');
98
103
  // 静态双轨(无运行时 try-catch 回退——按引擎**声明**的能力集在执行前定轨):
99
104
  // - occt(声明 *WithHistory)→ 权威历史路径(产内核面映射 + roleTable)。
100
105
  // - brepkit(裸 translate/scale 是真实现,无 *WithHistory)→ L1 裸调用 + identityHashEvolution。
@@ -156,6 +161,40 @@ function transformBrep(op, input, params) {
156
161
  roleTable,
157
162
  });
158
163
  }
164
+ /**
165
+ * 网格实体路径:把同一个变换应用到网格实体的**句柄**上(方案 2026-10-01 §4 Phase 4 / B3 批)。
166
+ *
167
+ * 为什么不复用 `cad.translate` 那套顶点烘焙:那套只动 `positions`、不碰身份槽——
168
+ * 对一个网格零件用它,等于把"网格实体 + 近似拓扑"静默降级成"裸网格"(下游每一个
169
+ * 网格 op 都会因此失去选面/选边的能力)。网格链的正确姿势与 BREP 侧完全一致:
170
+ * **变换句柄**(内核 `translate`/`transform` 带 kind tag 返回新实体),再由
171
+ * `meshSolidProduct` 重新三角化 + 重建近似拓扑。
172
+ *
173
+ * 面演化在这里**如实缺席**:变换按定义 1:1 保面序,但没有 hash 演化可言(近似拓扑
174
+ * 没有内核 hash)——不造恒等映射,也不传播 roleTable(网格链上没有 roleTable)。
175
+ *
176
+ * @param op - the transform operation name.
177
+ * @param input - the mesh-solid input.
178
+ * @param params - the validated operation parameters.
179
+ * @returns the transformed mesh solid as a new mesh part.
180
+ */
181
+ function transformMeshSolid(op, input, params) {
182
+ const entry = meshSolidBasicEntry(input, op);
183
+ let result;
184
+ if (op === 'translate') {
185
+ result = translateBrep(entry.kernel, entry.solid, params.offset);
186
+ }
187
+ else if (op === 'rotate_euler') {
188
+ result = rotateBrep(entry.kernel, entry.solid, params.angles, params.pivot);
189
+ }
190
+ else if (op === 'scale') {
191
+ result = scaleBrep(entry.kernel, entry.solid, params.factor, params.center);
192
+ }
193
+ else {
194
+ result = scaleBrep(entry.kernel, entry.solid, params.factor, params.center);
195
+ }
196
+ return meshSolidProduct(entry, result);
197
+ }
159
198
  /**
160
199
  * 平移几何体。
161
200
  * @group 变换
@@ -172,15 +211,18 @@ function transformBrep(op, input, params) {
172
211
  */
173
212
  export const translate = defineOp({
174
213
  name: 'translate',
214
+ meshEngines: ['brepkit'],
175
215
  mesh: (input, params) => {
176
216
  if (!input)
177
- throw new Error('[stdlib/translate] no input geometry');
217
+ throw new Error('[api/translate] no input geometry');
178
218
  assertTranslateParams(params);
219
+ if (hasMeshSolid(input))
220
+ return transformMeshSolid('translate', input, params);
179
221
  return cad.translate(input, params.offset);
180
222
  },
181
223
  brep: (input, params) => {
182
224
  if (!input)
183
- throw new Error('[stdlib/translate] no input geometry');
225
+ throw new Error('[api/translate] no input geometry');
184
226
  assertTranslateParams(params);
185
227
  return transformBrep('translate', input, params);
186
228
  },
@@ -208,15 +250,18 @@ export const translate = defineOp({
208
250
  */
209
251
  export const rotate_euler = defineOp({
210
252
  name: 'rotate_euler',
253
+ meshEngines: ['brepkit'],
211
254
  mesh: (input, params) => {
212
255
  if (!input)
213
- throw new Error('[stdlib/rotate_euler] no input geometry');
256
+ throw new Error('[api/rotate_euler] no input geometry');
214
257
  assertRotateParams(params);
258
+ if (hasMeshSolid(input))
259
+ return transformMeshSolid('rotate_euler', input, params);
215
260
  return cad.rotate_euler(input, params.angles, params.pivot);
216
261
  },
217
262
  brep: (input, params) => {
218
263
  if (!input)
219
- throw new Error('[stdlib/rotate_euler] no input geometry');
264
+ throw new Error('[api/rotate_euler] no input geometry');
220
265
  assertRotateParams(params);
221
266
  return transformBrep('rotate_euler', input, params);
222
267
  },
@@ -244,15 +289,18 @@ export const rotate_euler = defineOp({
244
289
  */
245
290
  export const scale = defineOp({
246
291
  name: 'scale',
292
+ meshEngines: ['brepkit'],
247
293
  mesh: (input, params) => {
248
294
  if (!input)
249
- throw new Error('[stdlib/scale] no input geometry');
295
+ throw new Error('[api/scale] no input geometry');
250
296
  assertScaleParams(params);
297
+ if (hasMeshSolid(input))
298
+ return transformMeshSolid('scale', input, params);
251
299
  return cad.scale(input, params.factor, params.center);
252
300
  },
253
301
  brep: (input, params) => {
254
302
  if (!input)
255
- throw new Error('[stdlib/scale] no input geometry');
303
+ throw new Error('[api/scale] no input geometry');
256
304
  assertScaleParams(params);
257
305
  return transformBrep('scale', input, params);
258
306
  },
@@ -282,15 +330,18 @@ export const scale = defineOp({
282
330
  */
283
331
  export const scale3d = defineOp({
284
332
  name: 'scale3d',
333
+ meshEngines: ['brepkit'],
285
334
  mesh: (input, params) => {
286
335
  if (!input)
287
- throw new Error('[stdlib/scale3d] no input geometry');
336
+ throw new Error('[api/scale3d] no input geometry');
288
337
  assertScale3dParams(params);
338
+ if (hasMeshSolid(input))
339
+ return transformMeshSolid('scale3d', input, params);
289
340
  return cad.scale3d(input, params.factor, params.center);
290
341
  },
291
342
  brep: (input, params) => {
292
343
  if (!input)
293
- throw new Error('[stdlib/scale3d] no input geometry');
344
+ throw new Error('[api/scale3d] no input geometry');
294
345
  assertScale3dParams(params);
295
346
  return transformBrep('scale3d', input, params);
296
347
  },