@faicad/faijs 0.29.5 → 0.30.9

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 (582) hide show
  1. package/NOTICE +6 -5
  2. package/dist/api/api-namespace.d.ts +1 -1
  3. package/dist/api/api-namespace.d.ts.map +1 -1
  4. package/dist/api/api-namespace.js +53 -1
  5. package/dist/api/api-namespace.js.map +1 -1
  6. package/dist/api/appearance.d.ts +0 -2
  7. package/dist/api/appearance.d.ts.map +1 -1
  8. package/dist/api/appearance.js +0 -2
  9. package/dist/api/appearance.js.map +1 -1
  10. package/dist/api/assembly/entities.d.ts +1 -1
  11. package/dist/api/assembly/entities.js +1 -1
  12. package/dist/api/assembly/entities.js.map +1 -1
  13. package/dist/api/assembly/index.d.ts +1 -1
  14. package/dist/api/assembly/index.js +1 -1
  15. package/dist/api/assembly/index.js.map +1 -1
  16. package/dist/api/assembly/joints.d.ts +33 -15
  17. package/dist/api/assembly/joints.d.ts.map +1 -1
  18. package/dist/api/assembly/joints.js +31 -13
  19. package/dist/api/assembly/joints.js.map +1 -1
  20. package/dist/api/assembly/preview.d.ts +1 -1
  21. package/dist/api/assembly/preview.js +1 -1
  22. package/dist/api/assembly/preview.js.map +1 -1
  23. package/dist/api/assembly/solve.d.ts +1 -1
  24. package/dist/api/assembly/solve.js +1 -1
  25. package/dist/api/assembly/solve.js.map +1 -1
  26. package/dist/api/assembly/solvers/assembly-tree.d.ts +1 -1
  27. package/dist/api/assembly/solvers/assembly-tree.js +1 -1
  28. package/dist/api/assembly/solvers/assembly-tree.js.map +1 -1
  29. package/dist/api/assembly/solvers/chain-solver.d.ts +2 -2
  30. package/dist/api/assembly/solvers/chain-solver.js.map +1 -1
  31. package/dist/api/assembly/solvers/global-solver.d.ts +1 -2
  32. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  33. package/dist/api/assembly/solvers/global-solver.js +3 -4
  34. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  35. package/dist/api/assembly/solvers/joints-kinematics.js +1 -1
  36. package/dist/api/assembly/solvers/joints-kinematics.js.map +1 -1
  37. package/dist/api/assembly/solvers/linalg.d.ts +2 -2
  38. package/dist/api/assembly/solvers/linalg.js +2 -2
  39. package/dist/api/assembly/solvers/linalg.js.map +1 -1
  40. package/dist/api/assembly/solvers/types.d.ts +2 -5
  41. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  42. package/dist/api/assembly/solvers/types.js +1 -4
  43. package/dist/api/assembly/solvers/types.js.map +1 -1
  44. package/dist/api/boolean.d.ts.map +1 -1
  45. package/dist/api/boolean.js +7 -6
  46. package/dist/api/boolean.js.map +1 -1
  47. package/dist/api/brep-mirror/booleanFns.d.ts +3 -3
  48. package/dist/api/brep-mirror/booleanFns.js +5 -5
  49. package/dist/api/brep-mirror/booleanFns.js.map +1 -1
  50. package/dist/api/brep-mirror/compoundFns.d.ts +1 -1
  51. package/dist/api/brep-mirror/compoundFns.js +4 -4
  52. package/dist/api/brep-mirror/compoundFns.js.map +1 -1
  53. package/dist/api/brep-mirror/healingFns.d.ts +4 -4
  54. package/dist/api/brep-mirror/healingFns.js +4 -4
  55. package/dist/api/brep-mirror/healingFns.js.map +1 -1
  56. package/dist/api/brep-mirror/hullFns.d.ts +2 -2
  57. package/dist/api/brep-mirror/hullFns.js +2 -2
  58. package/dist/api/brep-mirror/hullFns.js.map +1 -1
  59. package/dist/api/brep-mirror/patternFns.d.ts +5 -5
  60. package/dist/api/brep-mirror/patternFns.js +10 -10
  61. package/dist/api/brep-mirror/patternFns.js.map +1 -1
  62. package/dist/api/brep-mirror/primitiveFns.d.ts +4 -4
  63. package/dist/api/brep-mirror/primitiveFns.js +4 -4
  64. package/dist/api/brep-mirror/primitiveFns.js.map +1 -1
  65. package/dist/api/brep-mirror/roofFns.d.ts +3 -3
  66. package/dist/api/brep-mirror/roofFns.js +7 -7
  67. package/dist/api/brep-mirror/roofFns.js.map +1 -1
  68. package/dist/api/brep-mirror/sweepFns.d.ts +7 -7
  69. package/dist/api/brep-mirror/sweepFns.js +14 -14
  70. package/dist/api/brep-mirror/sweepFns.js.map +1 -1
  71. package/dist/api/brep-mirror/threadFns.d.ts +1 -1
  72. package/dist/api/brep-mirror/threadFns.js +1 -1
  73. package/dist/api/brep-mirror/threadFns.js.map +1 -1
  74. package/dist/api/brep-mirror/topologyFns.d.ts +5 -5
  75. package/dist/api/brep-mirror/topologyFns.js +8 -8
  76. package/dist/api/brep-mirror/topologyFns.js.map +1 -1
  77. package/dist/api/brep-operations/booleanFns.d.ts +40 -0
  78. package/dist/api/brep-operations/booleanFns.d.ts.map +1 -0
  79. package/dist/api/brep-operations/booleanFns.js +104 -0
  80. package/dist/api/brep-operations/booleanFns.js.map +1 -0
  81. package/dist/api/brep-operations/brepHelpers.d.ts +55 -0
  82. package/dist/api/brep-operations/brepHelpers.d.ts.map +1 -0
  83. package/dist/api/brep-operations/brepHelpers.js +131 -0
  84. package/dist/api/brep-operations/brepHelpers.js.map +1 -0
  85. package/dist/api/brep-operations/compoundFns.d.ts +46 -0
  86. package/dist/api/brep-operations/compoundFns.d.ts.map +1 -0
  87. package/dist/api/brep-operations/compoundFns.js +299 -0
  88. package/dist/api/brep-operations/compoundFns.js.map +1 -0
  89. package/dist/api/brep-operations/healingFns.d.ts +78 -0
  90. package/dist/api/brep-operations/healingFns.d.ts.map +1 -0
  91. package/dist/api/brep-operations/healingFns.js +294 -0
  92. package/dist/api/brep-operations/healingFns.js.map +1 -0
  93. package/dist/api/brep-operations/hullFns.d.ts +20 -0
  94. package/dist/api/brep-operations/hullFns.d.ts.map +1 -0
  95. package/dist/api/brep-operations/hullFns.js +46 -0
  96. package/dist/api/brep-operations/hullFns.js.map +1 -0
  97. package/dist/api/brep-operations/joinery-brep.d.ts +172 -0
  98. package/dist/api/brep-operations/joinery-brep.d.ts.map +1 -0
  99. package/dist/api/brep-operations/joinery-brep.js +463 -0
  100. package/dist/api/brep-operations/joinery-brep.js.map +1 -0
  101. package/dist/api/brep-operations/patternFns.d.ts +43 -0
  102. package/dist/api/brep-operations/patternFns.d.ts.map +1 -0
  103. package/dist/api/brep-operations/patternFns.js +178 -0
  104. package/dist/api/brep-operations/patternFns.js.map +1 -0
  105. package/dist/api/brep-operations/primitiveFns.d.ts +42 -0
  106. package/dist/api/brep-operations/primitiveFns.d.ts.map +1 -0
  107. package/dist/api/brep-operations/primitiveFns.js +104 -0
  108. package/dist/api/brep-operations/primitiveFns.js.map +1 -0
  109. package/dist/api/brep-operations/roofFns.d.ts +24 -0
  110. package/dist/api/brep-operations/roofFns.d.ts.map +1 -0
  111. package/dist/api/brep-operations/roofFns.js +229 -0
  112. package/dist/api/brep-operations/roofFns.js.map +1 -0
  113. package/dist/api/brep-operations/straightSkeleton.d.ts +36 -0
  114. package/dist/api/brep-operations/straightSkeleton.d.ts.map +1 -0
  115. package/dist/api/brep-operations/straightSkeleton.js +431 -0
  116. package/dist/api/brep-operations/straightSkeleton.js.map +1 -0
  117. package/dist/api/brep-operations/sweepFns.d.ts +60 -0
  118. package/dist/api/brep-operations/sweepFns.d.ts.map +1 -0
  119. package/dist/api/brep-operations/sweepFns.js +323 -0
  120. package/dist/api/brep-operations/sweepFns.js.map +1 -0
  121. package/dist/api/brep-operations/threadFns.d.ts +83 -0
  122. package/dist/api/brep-operations/threadFns.d.ts.map +1 -0
  123. package/dist/api/brep-operations/threadFns.js +138 -0
  124. package/dist/api/brep-operations/threadFns.js.map +1 -0
  125. package/dist/api/brep-operations/topologyFns.d.ts +90 -0
  126. package/dist/api/brep-operations/topologyFns.d.ts.map +1 -0
  127. package/dist/api/brep-operations/topologyFns.js +276 -0
  128. package/dist/api/brep-operations/topologyFns.js.map +1 -0
  129. package/dist/api/brep-topology.d.ts +1 -1
  130. package/dist/api/brep-topology.d.ts.map +1 -1
  131. package/dist/api/brep-topology.js +1 -1
  132. package/dist/api/brep-topology.js.map +1 -1
  133. package/dist/api/brepjs-compat/index.d.ts +1 -1
  134. package/dist/api/brepjs-compat/index.js +3 -3
  135. package/dist/api/brepjs-compat/index.js.map +1 -1
  136. package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -1
  137. package/dist/api/cadquery-selectors/borrow-bridge.js +3 -4
  138. package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -1
  139. package/dist/api/curve-sketch/index.d.ts +235 -0
  140. package/dist/api/curve-sketch/index.d.ts.map +1 -0
  141. package/dist/api/curve-sketch/index.js +487 -0
  142. package/dist/api/curve-sketch/index.js.map +1 -0
  143. package/dist/api/engrave.d.ts.map +1 -1
  144. package/dist/api/engrave.js +3 -2
  145. package/dist/api/engrave.js.map +1 -1
  146. package/dist/api/export-brep.d.ts +41 -0
  147. package/dist/api/export-brep.d.ts.map +1 -0
  148. package/dist/api/export-brep.js +58 -0
  149. package/dist/api/export-brep.js.map +1 -0
  150. package/dist/api/export-stl.d.ts +50 -0
  151. package/dist/api/export-stl.d.ts.map +1 -0
  152. package/dist/api/export-stl.js +99 -0
  153. package/dist/api/export-stl.js.map +1 -0
  154. package/dist/api/extrude.d.ts +8 -11
  155. package/dist/api/extrude.d.ts.map +1 -1
  156. package/dist/api/extrude.js +11 -14
  157. package/dist/api/extrude.js.map +1 -1
  158. package/dist/api/fillet-variable.d.ts +2 -2
  159. package/dist/api/fillet-variable.js +2 -2
  160. package/dist/api/fillet-variable.js.map +1 -1
  161. package/dist/api/fillet.d.ts +2 -4
  162. package/dist/api/fillet.d.ts.map +1 -1
  163. package/dist/api/fillet.js +2 -4
  164. package/dist/api/fillet.js.map +1 -1
  165. package/dist/api/generated/2d.d.ts +4 -0
  166. package/dist/api/generated/2d.d.ts.map +1 -1
  167. package/dist/api/generated/2d.js +4 -0
  168. package/dist/api/generated/2d.js.map +1 -1
  169. package/dist/api/generated/core.d.ts +4 -0
  170. package/dist/api/generated/core.d.ts.map +1 -1
  171. package/dist/api/generated/core.js +4 -0
  172. package/dist/api/generated/core.js.map +1 -1
  173. package/dist/api/generated/gear.d.ts +4 -0
  174. package/dist/api/generated/gear.d.ts.map +1 -1
  175. package/dist/api/generated/gear.js +4 -0
  176. package/dist/api/generated/gear.js.map +1 -1
  177. package/dist/api/generated/io.d.ts +4 -0
  178. package/dist/api/generated/io.d.ts.map +1 -1
  179. package/dist/api/generated/io.js +4 -0
  180. package/dist/api/generated/io.js.map +1 -1
  181. package/dist/api/generated/kernel.d.ts +4 -0
  182. package/dist/api/generated/kernel.d.ts.map +1 -1
  183. package/dist/api/generated/kernel.js +4 -0
  184. package/dist/api/generated/kernel.js.map +1 -1
  185. package/dist/api/generated/measurement.d.ts +21 -21
  186. package/dist/api/generated/measurement.d.ts.map +1 -1
  187. package/dist/api/generated/measurement.js +25 -21
  188. package/dist/api/generated/measurement.js.map +1 -1
  189. package/dist/api/generated/ns.d.ts +4 -0
  190. package/dist/api/generated/ns.d.ts.map +1 -1
  191. package/dist/api/generated/ns.js +4 -0
  192. package/dist/api/generated/ns.js.map +1 -1
  193. package/dist/api/generated/operations.d.ts +32 -32
  194. package/dist/api/generated/operations.d.ts.map +1 -1
  195. package/dist/api/generated/operations.js +52 -48
  196. package/dist/api/generated/operations.js.map +1 -1
  197. package/dist/api/generated/projection.d.ts +4 -0
  198. package/dist/api/generated/projection.d.ts.map +1 -1
  199. package/dist/api/generated/projection.js +4 -0
  200. package/dist/api/generated/projection.js.map +1 -1
  201. package/dist/api/generated/query.d.ts +4 -0
  202. package/dist/api/generated/query.d.ts.map +1 -1
  203. package/dist/api/generated/query.js +4 -0
  204. package/dist/api/generated/query.js.map +1 -1
  205. package/dist/api/generated/sketching.d.ts +2 -2
  206. package/dist/api/generated/sketching.d.ts.map +1 -1
  207. package/dist/api/generated/sketching.js +7 -3
  208. package/dist/api/generated/sketching.js.map +1 -1
  209. package/dist/api/generated/text.d.ts +4 -0
  210. package/dist/api/generated/text.d.ts.map +1 -1
  211. package/dist/api/generated/text.js +4 -0
  212. package/dist/api/generated/text.js.map +1 -1
  213. package/dist/api/generated/topology.d.ts +45 -45
  214. package/dist/api/generated/topology.d.ts.map +1 -1
  215. package/dist/api/generated/topology.js +67 -63
  216. package/dist/api/generated/topology.js.map +1 -1
  217. package/dist/api/generated/view.d.ts +4 -0
  218. package/dist/api/generated/view.d.ts.map +1 -1
  219. package/dist/api/generated/view.js +4 -0
  220. package/dist/api/generated/view.js.map +1 -1
  221. package/dist/api/geom-types/constants.d.ts +11 -0
  222. package/dist/api/geom-types/constants.d.ts.map +1 -0
  223. package/dist/api/geom-types/constants.js +11 -0
  224. package/dist/api/geom-types/constants.js.map +1 -0
  225. package/dist/api/geom-types/index.d.ts +21 -0
  226. package/dist/api/geom-types/index.d.ts.map +1 -0
  227. package/dist/api/geom-types/index.js +22 -0
  228. package/dist/api/geom-types/index.js.map +1 -0
  229. package/dist/api/geom-types/planeOps.d.ts +98 -0
  230. package/dist/api/geom-types/planeOps.d.ts.map +1 -0
  231. package/dist/api/geom-types/planeOps.js +170 -0
  232. package/dist/api/geom-types/planeOps.js.map +1 -0
  233. package/dist/api/geom-types/planeTypes.d.ts +24 -0
  234. package/dist/api/geom-types/planeTypes.d.ts.map +1 -0
  235. package/dist/api/geom-types/planeTypes.js +8 -0
  236. package/dist/api/geom-types/planeTypes.js.map +1 -0
  237. package/dist/api/geom-types/types.d.ts +64 -0
  238. package/dist/api/geom-types/types.d.ts.map +1 -0
  239. package/dist/api/geom-types/types.js +48 -0
  240. package/dist/api/geom-types/types.js.map +1 -0
  241. package/dist/api/geom-types/vecOps.d.ts +124 -0
  242. package/dist/api/geom-types/vecOps.d.ts.map +1 -0
  243. package/dist/api/geom-types/vecOps.js +202 -0
  244. package/dist/api/geom-types/vecOps.js.map +1 -0
  245. package/dist/api/geom.d.ts.map +1 -1
  246. package/dist/api/geom.js +6 -5
  247. package/dist/api/geom.js.map +1 -1
  248. package/dist/api/half-space.d.ts +56 -0
  249. package/dist/api/half-space.d.ts.map +1 -0
  250. package/dist/api/half-space.js +82 -0
  251. package/dist/api/half-space.js.map +1 -0
  252. package/dist/api/helix.d.ts +10 -1
  253. package/dist/api/helix.d.ts.map +1 -1
  254. package/dist/api/helix.js +19 -3
  255. package/dist/api/helix.js.map +1 -1
  256. package/dist/api/index.d.ts +15 -6
  257. package/dist/api/index.d.ts.map +1 -1
  258. package/dist/api/index.js +29 -8
  259. package/dist/api/index.js.map +1 -1
  260. package/dist/api/internal/compat-op.d.ts +4 -30
  261. package/dist/api/internal/compat-op.d.ts.map +1 -1
  262. package/dist/api/internal/compat-op.js +10 -42
  263. package/dist/api/internal/compat-op.js.map +1 -1
  264. package/dist/api/internal/compat-projection.d.ts +5 -5
  265. package/dist/api/internal/compat-projection.js +5 -5
  266. package/dist/api/internal/compat-projection.js.map +1 -1
  267. package/dist/api/internal/dual-form-args.d.ts +0 -2
  268. package/dist/api/internal/dual-form-args.d.ts.map +1 -1
  269. package/dist/api/internal/dual-form-args.js +1 -3
  270. package/dist/api/internal/dual-form-args.js.map +1 -1
  271. package/dist/api/internal/l3-bridge.d.ts +5 -37
  272. package/dist/api/internal/l3-bridge.d.ts.map +1 -1
  273. package/dist/api/internal/l3-bridge.js +7 -76
  274. package/dist/api/internal/l3-bridge.js.map +1 -1
  275. package/dist/api/internal/profile-wire.d.ts +1 -1
  276. package/dist/api/internal/profile-wire.js +1 -1
  277. package/dist/api/internal/profile-wire.js.map +1 -1
  278. package/dist/api/internal/result-unwrap.d.ts +4 -6
  279. package/dist/api/internal/result-unwrap.d.ts.map +1 -1
  280. package/dist/api/internal/result-unwrap.js +4 -6
  281. package/dist/api/internal/result-unwrap.js.map +1 -1
  282. package/dist/api/knurl.d.ts.map +1 -1
  283. package/dist/api/knurl.js +5 -3
  284. package/dist/api/knurl.js.map +1 -1
  285. package/dist/api/loft.d.ts +2 -2
  286. package/dist/api/loft.d.ts.map +1 -1
  287. package/dist/api/loft.js +2 -2
  288. package/dist/api/loft.js.map +1 -1
  289. package/dist/api/measurement/index.d.ts +3 -3
  290. package/dist/api/measurement/index.js +3 -3
  291. package/dist/api/measurement/index.js.map +1 -1
  292. package/dist/api/meta.d.ts +0 -2
  293. package/dist/api/meta.d.ts.map +1 -1
  294. package/dist/api/meta.js +0 -2
  295. package/dist/api/meta.js.map +1 -1
  296. package/dist/api/offset2d.d.ts +49 -0
  297. package/dist/api/offset2d.d.ts.map +1 -0
  298. package/dist/api/offset2d.js +86 -0
  299. package/dist/api/offset2d.js.map +1 -0
  300. package/dist/api/pattern.js +3 -3
  301. package/dist/api/pattern.js.map +1 -1
  302. package/dist/api/primitives.d.ts.map +1 -1
  303. package/dist/api/primitives.js +7 -6
  304. package/dist/api/primitives.js.map +1 -1
  305. package/dist/api/replicate.d.ts +2 -2
  306. package/dist/api/replicate.d.ts.map +1 -1
  307. package/dist/api/replicate.js +12 -12
  308. package/dist/api/replicate.js.map +1 -1
  309. package/dist/api/result.d.ts +1 -1
  310. package/dist/api/result.js +1 -1
  311. package/dist/api/result.js.map +1 -1
  312. package/dist/api/revolve.d.ts +2 -2
  313. package/dist/api/revolve.js +3 -3
  314. package/dist/api/revolve.js.map +1 -1
  315. package/dist/api/screw.d.ts +1 -1
  316. package/dist/api/screw.d.ts.map +1 -1
  317. package/dist/api/screw.js +5 -4
  318. package/dist/api/screw.js.map +1 -1
  319. package/dist/api/sdf.d.ts.map +1 -1
  320. package/dist/api/sdf.js +3 -2
  321. package/dist/api/sdf.js.map +1 -1
  322. package/dist/api/shape-type/index.d.ts +141 -0
  323. package/dist/api/shape-type/index.d.ts.map +1 -0
  324. package/dist/api/shape-type/index.js +182 -0
  325. package/dist/api/shape-type/index.js.map +1 -0
  326. package/dist/api/shell.d.ts +2 -2
  327. package/dist/api/shell.js +2 -2
  328. package/dist/api/shell.js.map +1 -1
  329. package/dist/api/solid-from-faces.d.ts +45 -0
  330. package/dist/api/solid-from-faces.d.ts.map +1 -0
  331. package/dist/api/solid-from-faces.js +72 -0
  332. package/dist/api/solid-from-faces.js.map +1 -0
  333. package/dist/api/solid-offset/index.d.ts +67 -0
  334. package/dist/api/solid-offset/index.d.ts.map +1 -0
  335. package/dist/api/solid-offset/index.js +132 -0
  336. package/dist/api/solid-offset/index.js.map +1 -0
  337. package/dist/api/surface/arg-spec.d.ts +35 -33
  338. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  339. package/dist/api/surface/arg-spec.js +222 -224
  340. package/dist/api/surface/arg-spec.js.map +1 -1
  341. package/dist/api/surface-face/index.d.ts +104 -0
  342. package/dist/api/surface-face/index.d.ts.map +1 -0
  343. package/dist/api/surface-face/index.js +217 -0
  344. package/dist/api/surface-face/index.js.map +1 -0
  345. package/dist/api/surface.d.ts +44 -0
  346. package/dist/api/surface.d.ts.map +1 -0
  347. package/dist/api/surface.js +66 -0
  348. package/dist/api/surface.js.map +1 -0
  349. package/dist/api/sweep.d.ts +59 -9
  350. package/dist/api/sweep.d.ts.map +1 -1
  351. package/dist/api/sweep.js +11 -6
  352. package/dist/api/sweep.js.map +1 -1
  353. package/dist/api/thicken.d.ts +1 -1
  354. package/dist/api/thicken.js +1 -1
  355. package/dist/api/thicken.js.map +1 -1
  356. package/dist/api/transform.d.ts +5 -5
  357. package/dist/api/transform.d.ts.map +1 -1
  358. package/dist/api/transform.js +11 -10
  359. package/dist/api/transform.js.map +1 -1
  360. package/dist/api/view/cameraFns.d.ts +1 -1
  361. package/dist/api/view/cameraFns.d.ts.map +1 -1
  362. package/dist/api/view/cameraFns.js +1 -1
  363. package/dist/api/view/cameraFns.js.map +1 -1
  364. package/dist/api/view/index.d.ts +0 -2
  365. package/dist/api/view/index.d.ts.map +1 -1
  366. package/dist/api/view/index.js +0 -2
  367. package/dist/api/view/index.js.map +1 -1
  368. package/dist/api/view/projectionPlanes.d.ts +1 -1
  369. package/dist/api/view/projectionPlanes.d.ts.map +1 -1
  370. package/dist/api/view/projectionPlanes.js.map +1 -1
  371. package/dist/api/view/view-camera.d.ts +7 -9
  372. package/dist/api/view/view-camera.d.ts.map +1 -1
  373. package/dist/api/view/view-camera.js +4 -6
  374. package/dist/api/view/view-camera.js.map +1 -1
  375. package/dist/api/view/view-projection.d.ts +0 -2
  376. package/dist/api/view/view-projection.d.ts.map +1 -1
  377. package/dist/api/view/view-projection.js +0 -2
  378. package/dist/api/view/view-projection.js.map +1 -1
  379. package/dist/api/view/view-sheet.d.ts +0 -2
  380. package/dist/api/view/view-sheet.d.ts.map +1 -1
  381. package/dist/api/view/view-sheet.js +0 -2
  382. package/dist/api/view/view-sheet.js.map +1 -1
  383. package/dist/api/view-export/index.d.ts +97 -0
  384. package/dist/api/view-export/index.d.ts.map +1 -0
  385. package/dist/api/view-export/index.js +118 -0
  386. package/dist/api/view-export/index.js.map +1 -0
  387. package/dist/brep/brep-ops.d.ts +89 -1
  388. package/dist/brep/brep-ops.d.ts.map +1 -1
  389. package/dist/brep/brep-ops.js +176 -10
  390. package/dist/brep/brep-ops.js.map +1 -1
  391. package/dist/brep/brep-topology.d.ts +20 -0
  392. package/dist/brep/brep-topology.d.ts.map +1 -1
  393. package/dist/brep/brep-topology.js +46 -0
  394. package/dist/brep/brep-topology.js.map +1 -1
  395. package/dist/brep/engine/adapters/occt.d.ts +1 -1
  396. package/dist/brep/engine/adapters/occt.js +7 -7
  397. package/dist/brep/engine/adapters/occt.js.map +1 -1
  398. package/dist/brep/engine/primitives.d.ts +2 -3
  399. package/dist/brep/engine/primitives.d.ts.map +1 -1
  400. package/dist/brep/engine/primitives.js +1 -2
  401. package/dist/brep/engine/primitives.js.map +1 -1
  402. package/dist/brep/engine/registry.d.ts +1 -1
  403. package/dist/brep/engine/registry.js +1 -1
  404. package/dist/brep/engine/registry.js.map +1 -1
  405. package/dist/brep/engine/types.d.ts +2 -2
  406. package/dist/brep/engine/types.js.map +1 -1
  407. package/dist/brep/handle-bridge.d.ts +2 -2
  408. package/dist/brep/handle-bridge.js +2 -2
  409. package/dist/brep/handle-bridge.js.map +1 -1
  410. package/dist/brep/index.d.ts +6 -3
  411. package/dist/brep/index.d.ts.map +1 -1
  412. package/dist/brep/index.js +6 -3
  413. package/dist/brep/index.js.map +1 -1
  414. package/dist/brepkit-kernel/brepkitKernel.d.ts +1 -1
  415. package/dist/brepkit-kernel/brepkitKernel.js +2 -2
  416. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  417. package/dist/browser.d.ts +2 -2
  418. package/dist/browser.d.ts.map +1 -1
  419. package/dist/browser.js +5 -4
  420. package/dist/browser.js.map +1 -1
  421. package/dist/cad-runtime/admit-compat-lib.d.ts +3 -10
  422. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  423. package/dist/cad-runtime/admit-compat-lib.js +3 -9
  424. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  425. package/dist/cad-runtime/backend-dispatch.js +12 -3
  426. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  427. package/dist/cad-runtime/direct-executor.d.ts +6 -3
  428. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  429. package/dist/cad-runtime/direct-executor.js +31 -9
  430. package/dist/cad-runtime/direct-executor.js.map +1 -1
  431. package/dist/cad-runtime/interp/env.d.ts +1 -1
  432. package/dist/cad-runtime/interp/env.js.map +1 -1
  433. package/dist/cad-runtime/lib-id.d.ts +0 -2
  434. package/dist/cad-runtime/lib-id.d.ts.map +1 -1
  435. package/dist/cad-runtime/lib-id.js +0 -2
  436. package/dist/cad-runtime/lib-id.js.map +1 -1
  437. package/dist/cad-runtime/live-shapes.d.ts +3 -5
  438. package/dist/cad-runtime/live-shapes.d.ts.map +1 -1
  439. package/dist/cad-runtime/live-shapes.js +8 -10
  440. package/dist/cad-runtime/live-shapes.js.map +1 -1
  441. package/dist/cad-runtime/ports.d.ts +3 -3
  442. package/dist/cad-runtime/ports.js.map +1 -1
  443. package/dist/cad-runtime/runtime.d.ts +21 -7
  444. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  445. package/dist/cad-runtime/runtime.js +45 -6
  446. package/dist/cad-runtime/runtime.js.map +1 -1
  447. package/dist/define-op.d.ts +4 -3
  448. package/dist/define-op.d.ts.map +1 -1
  449. package/dist/define-op.js +2 -2
  450. package/dist/define-op.js.map +1 -1
  451. package/dist/geometry2d/bridge/plane.d.ts +1 -1
  452. package/dist/geometry2d/bridge/plane.js +1 -1
  453. package/dist/geometry2d/bridge/plane.js.map +1 -1
  454. package/dist/geometry2d/curve2d.d.ts +1 -1
  455. package/dist/geometry2d/curve2d.js +1 -1
  456. package/dist/geometry2d/curve2d.js.map +1 -1
  457. package/dist/index.d.ts +1 -1
  458. package/dist/index.d.ts.map +1 -1
  459. package/dist/index.js +10 -4
  460. package/dist/index.js.map +1 -1
  461. package/dist/io/fai-zip/container-read.d.ts +16 -0
  462. package/dist/io/fai-zip/container-read.d.ts.map +1 -1
  463. package/dist/io/fai-zip/container-read.js +22 -0
  464. package/dist/io/fai-zip/container-read.js.map +1 -1
  465. package/dist/io/fai-zip/index.d.ts +1 -1
  466. package/dist/io/fai-zip/index.d.ts.map +1 -1
  467. package/dist/io/fai-zip/index.js +1 -1
  468. package/dist/io/fai-zip/index.js.map +1 -1
  469. package/dist/lang/code-to-args.d.ts.map +1 -1
  470. package/dist/lang/code-to-args.js +10 -1
  471. package/dist/lang/code-to-args.js.map +1 -1
  472. package/dist/lang/determinism-scanner.d.ts.map +1 -1
  473. package/dist/lang/determinism-scanner.js +22 -9
  474. package/dist/lang/determinism-scanner.js.map +1 -1
  475. package/dist/lang/metadata-extractor.d.ts +27 -6
  476. package/dist/lang/metadata-extractor.d.ts.map +1 -1
  477. package/dist/lang/metadata-extractor.js +88 -8
  478. package/dist/lang/metadata-extractor.js.map +1 -1
  479. package/dist/lang/parse-error.d.ts +4 -0
  480. package/dist/lang/parse-error.d.ts.map +1 -1
  481. package/dist/lang/parse-error.js.map +1 -1
  482. package/dist/lang/security-scanner.d.ts +27 -2
  483. package/dist/lang/security-scanner.d.ts.map +1 -1
  484. package/dist/lang/security-scanner.js +29 -2
  485. package/dist/lang/security-scanner.js.map +1 -1
  486. package/dist/lang/source-edit.d.ts +2 -2
  487. package/dist/lang/source-edit.js.map +1 -1
  488. package/dist/lang/symbol-table.generated.d.ts +36 -0
  489. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  490. package/dist/lang/symbol-table.generated.js +36 -0
  491. package/dist/lang/symbol-table.generated.js.map +1 -1
  492. package/dist/mesh/import-model.d.ts +94 -0
  493. package/dist/mesh/import-model.d.ts.map +1 -0
  494. package/dist/mesh/import-model.js +15 -0
  495. package/dist/mesh/import-model.js.map +1 -0
  496. package/dist/mesh/index.d.ts +19 -58
  497. package/dist/mesh/index.d.ts.map +1 -1
  498. package/dist/mesh/index.js +19 -70
  499. package/dist/mesh/index.js.map +1 -1
  500. package/dist/mesh/io.d.ts +33 -16
  501. package/dist/mesh/io.d.ts.map +1 -1
  502. package/dist/mesh/io.js +144 -39
  503. package/dist/mesh/io.js.map +1 -1
  504. package/dist/mesh/primitives.js +1 -1
  505. package/dist/mesh/primitives.js.map +1 -1
  506. package/dist/mesh/threemf-bambu.d.ts +12 -1
  507. package/dist/mesh/threemf-bambu.d.ts.map +1 -1
  508. package/dist/mesh/threemf-bambu.js +68 -16
  509. package/dist/mesh/threemf-bambu.js.map +1 -1
  510. package/dist/mesh/threemf-loader.d.ts +14 -1
  511. package/dist/mesh/threemf-loader.d.ts.map +1 -1
  512. package/dist/mesh/threemf-loader.js +24 -7
  513. package/dist/mesh/threemf-loader.js.map +1 -1
  514. package/dist/mesh/transform.d.ts +1 -1
  515. package/dist/mesh/transform.js +1 -1
  516. package/dist/mesh/transform.js.map +1 -1
  517. package/dist/mesh/types.d.ts +5 -5
  518. package/dist/mesh/types.d.ts.map +1 -1
  519. package/dist/mesh/types.js.map +1 -1
  520. package/dist/node-host/cli.d.ts +49 -1
  521. package/dist/node-host/cli.d.ts.map +1 -1
  522. package/dist/node-host/cli.js +125 -19
  523. package/dist/node-host/cli.js.map +1 -1
  524. package/dist/node-host/execute-script.d.ts +55 -0
  525. package/dist/node-host/execute-script.d.ts.map +1 -0
  526. package/dist/node-host/execute-script.js +46 -0
  527. package/dist/node-host/execute-script.js.map +1 -0
  528. package/dist/node.d.ts +2 -0
  529. package/dist/node.d.ts.map +1 -1
  530. package/dist/node.js +3 -0
  531. package/dist/node.js.map +1 -1
  532. package/dist/occt-kernel/generated/occtPlatform.generated.d.ts +260 -0
  533. package/dist/occt-kernel/generated/occtPlatform.generated.d.ts.map +1 -0
  534. package/dist/occt-kernel/generated/occtPlatform.generated.js +875 -0
  535. package/dist/occt-kernel/generated/occtPlatform.generated.js.map +1 -0
  536. package/dist/occt-kernel/hullGeometry.d.ts +2 -2
  537. package/dist/occt-kernel/hullGeometry.js +2 -3
  538. package/dist/occt-kernel/hullGeometry.js.map +1 -1
  539. package/dist/occt-kernel/hullOps.d.ts +3 -3
  540. package/dist/occt-kernel/hullOps.js +4 -4
  541. package/dist/occt-kernel/hullOps.js.map +1 -1
  542. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  543. package/dist/occt-kernel/occt-primitives.js +31 -4
  544. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  545. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  546. package/dist/occt-kernel/occtKernel.js +18 -0
  547. package/dist/occt-kernel/occtKernel.js.map +1 -1
  548. package/dist/occt-scan/recognize.d.ts +58 -0
  549. package/dist/occt-scan/recognize.d.ts.map +1 -0
  550. package/dist/occt-scan/recognize.js +216 -0
  551. package/dist/occt-scan/recognize.js.map +1 -0
  552. package/dist/primitives/brep-primitives.js +7 -7
  553. package/dist/primitives/brep-primitives.js.map +1 -1
  554. package/dist/result/bug.d.ts +1 -1
  555. package/dist/result/bug.js +1 -1
  556. package/dist/result/bug.js.map +1 -1
  557. package/dist/result/errors.d.ts +2 -2
  558. package/dist/result/errors.d.ts.map +1 -1
  559. package/dist/result/errors.js +1 -1
  560. package/dist/result/errors.js.map +1 -1
  561. package/dist/result/vec3.d.ts +1 -1
  562. package/dist/result/vec3.js +1 -1
  563. package/dist/result/vec3.js.map +1 -1
  564. package/dist/runtime-state.d.ts +16 -0
  565. package/dist/runtime-state.d.ts.map +1 -1
  566. package/dist/runtime-state.js +27 -0
  567. package/dist/runtime-state.js.map +1 -1
  568. package/dist/script-globals.d.ts +24 -0
  569. package/dist/script-globals.d.ts.map +1 -0
  570. package/dist/script-globals.js +24 -0
  571. package/dist/script-globals.js.map +1 -0
  572. package/dist/shape.d.ts +24 -0
  573. package/dist/shape.d.ts.map +1 -1
  574. package/dist/shape.js +40 -0
  575. package/dist/shape.js.map +1 -1
  576. package/dist/topology/naming/lineage.d.ts +3 -2
  577. package/dist/topology/naming/lineage.d.ts.map +1 -1
  578. package/dist/topology/naming/lineage.js.map +1 -1
  579. package/dist/weapp.d.ts +1 -1
  580. package/dist/weapp.js +1 -1
  581. package/dist/weapp.js.map +1 -1
  582. package/package.json +8 -10
@@ -1 +1 @@
1
- {"version":3,"file":"result-unwrap.js","sourceRoot":"","sources":["../../../src/api/internal/result-unwrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAK;IAChC,6CAA6C;IACpC,EAAE,CAAQ;IACnB,2EAA2E;IAClE,IAAI,CAAQ;IACrB,YAAY,EAAU,EAAE,IAAY,EAAE,OAAe,EAAE,OAA6B;QAClF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAA;QACrB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,OAAQ,CAAsB,CAAC,EAAE,KAAK,SAAS,CAAA;AAC/F,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,GAAY;IAClD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAA;QAC7C,MAAM,MAAM,GAAG,cAAc,IAAI,KAAK,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;QACnF,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,CAAA;IACxC,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,cAAc,IAAI,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,GAAY;IACpD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAA;QAC7C,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAA;QAC/D,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK,OAAO,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACrF,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,cAAc,IAAI,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AAC5F,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,CAAU,EAAE,IAAY;IACnD,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAA;IAC9B,IAAI,CAAC,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC,KAAK,CAAA;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAwC,CAAA;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,aAAa,CAAA;IACpC,MAAM,IAAI,OAAO,CACf,IAAI,EACJ,IAAI,EACJ,yBAAyB,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,OAAO,IAAI,kBAAkB,EAAE,CAC7E,CAAA;AACH,CAAC","sourcesContent":["/**\n * result-unwrap — the single Result→throw bridge shared by every faijs\n * statement boundary (D1).\n *\n * Design: docs/plans/2026-09-03-faijs-brepjs-compat-api.md §5.1 / §5.2\n *\n * Three-layer error semantics (§5.1):\n * library internals / TS compat face → `Result<T>` native (BrepError)\n * statement boundary → `err` unwrapped into a throw\n * faijs-specific op impls → may return `Result`; same unwrap\n *\n * This module is a **leaf**: it imports nothing, so both the SDK layer\n * (`src/define-op.ts`, whose `dist/sdk.js` must stay free of heavy static\n * imports) and the compat bridge (`api/internal/compat-op.ts`) can share one\n * implementation. Having two copies would let the two boundaries drift.\n *\n * @module\n */\n\n/** Structural shape of the vendored `Ok`/`Err` records (`vendored/brepjs/core/result.ts:12-21`). */\nexport type ResultLike =\n | { ok: true; value: unknown }\n | { ok: false; error: { code?: string; message?: string } }\n\n/**\n * Statement-boundary op failure (D1 unwrap / compat adoption).\n *\n * An `err` Result unwrapped at the statement boundary used to be thrown as a\n * plain `Error`, which `CadRuntime.runWithFailureHandling` (recognizing only\n * `BrepUnsupportedError`/`MeshUnsupportedError` by `instanceof`) re-threw out\n * of `execute()` instead of converting it into `ExecutionResult.failedAt`.\n * This class is the engine-recognizable carrier: defined in this leaf module\n * (zero imports) so both `define-op` and the compat bridge can throw it while\n * CadRuntime can catch it without importing anything heavier.\n *\n * A thrown `Error` that is *not* an `OpError` keeps its old meaning: an\n * unexpected implementation bug that must propagate (Result 体系 — expected\n * failures are `err` values, exceptions are bugs).\n */\nexport class OpError extends Error {\n /** The op name that produced the failure. */\n readonly op: string\n /** The `BrepError.code`, or `'E_OP_FAILED'` when the library sent none. */\n readonly code: string\n constructor(op: string, code: string, message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'OpError'\n this.op = op\n this.code = code\n }\n}\n\n/**\n * Structural test for a Result value.\n *\n * Only the `ok: boolean` discriminant is checked — the vendored `Result` is a\n * plain record, so no `instanceof` and no import is needed (which is what keeps\n * this module a leaf).\n *\n * @param v - the candidate value.\n * @returns true when `v` looks like an Ok/Err record.\n */\nexport function isResultLike(v: unknown): v is ResultLike {\n return typeof v === 'object' && v !== null && typeof (v as { ok?: unknown }).ok === 'boolean'\n}\n\n/**\n * Render an error thrown by (or returned from) an implementation as a\n * statement-level failure.\n *\n * The op name and the `BrepError.code` (when present) are always kept so the\n * engine's statement-level catch reports the same shape the plan's trace A/B\n * describe (`[faijs/brepjs-compat] <op>: <CODE>: <message>`).\n *\n * @param name - the op name.\n * @param err - the thrown value (Error or anything else).\n * @returns an Error carrying the op context.\n */\nexport function toOpError(name: string, err: unknown): Error {\n if (err instanceof Error) {\n const code = (err as { code?: unknown }).code\n const prefix = `[faijs/op] ${name}: ${typeof code === 'string' ? code + ': ' : ''}`\n return new Error(prefix + err.message)\n }\n return new Error(`[faijs/op] ${name}: E_OP_FAILED: ${String(err)}`)\n}\n\n/**\n * Wrap an implementation-thrown exception as an {@link OpError} (statement-\n * level failure carrier). Used by `define-op.ts` `runImpl` so that\n * `CadRuntime.directFailedAtOrThrow` recognizes the error as an op failure\n * (not a bug to re-throw).\n *\n * @param name - the op name.\n * @param err - the thrown value.\n * @returns an OpError carrying the op context and code.\n */\nexport function toOpFailure(name: string, err: unknown): OpError {\n if (err instanceof Error) {\n const code = (err as { code?: unknown }).code\n const codeStr = typeof code === 'string' ? code : 'E_OP_FAILED'\n return new OpError(name, codeStr, `[faijs/op] ${name}: ${codeStr}: ${err.message}`)\n }\n return new OpError(name, 'E_OP_FAILED', `[faijs/op] ${name}: E_OP_FAILED: ${String(err)}`)\n}\n\n/**\n * Statement-boundary unwrap (D1).\n *\n * - a non-Result product → returned untouched (plain-data ops, mesh products);\n * - `ok` → `.value`;\n * - `err` → throws an {@link OpError} carrying the op name and BrepError code\n * (the engine converts `OpError` into `ExecutionResult.failedAt`).\n *\n * @param r - the implementation product.\n * @param name - the op name (error messages).\n * @returns the unwrapped value, or the input when it was not a Result.\n * @throws an {@link OpError} when `r` is an `Err`.\n */\nexport function unwrapResult(r: unknown, name: string): unknown {\n if (!isResultLike(r)) return r\n if (r.ok) return r.value\n const e = (r.error ?? {}) as { code?: string; message?: string }\n const code = e.code ?? 'E_OP_FAILED'\n throw new OpError(\n name,\n code,\n `[faijs/brepjs-compat] ${name}: ${code}: ${e.message ?? 'operation failed'}`,\n )\n}\n"]}
1
+ {"version":3,"file":"result-unwrap.js","sourceRoot":"","sources":["../../../src/api/internal/result-unwrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAK;IAChC,6CAA6C;IACpC,EAAE,CAAQ;IACnB,2EAA2E;IAClE,IAAI,CAAQ;IACrB,YAAY,EAAU,EAAE,IAAY,EAAE,OAAe,EAAE,OAA6B;QAClF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAA;QACrB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,OAAQ,CAAsB,CAAC,EAAE,KAAK,SAAS,CAAA;AAC/F,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,GAAY;IAClD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAA;QAC7C,MAAM,MAAM,GAAG,cAAc,IAAI,KAAK,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;QACnF,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,CAAA;IACxC,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,cAAc,IAAI,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,GAAY;IACpD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAA;QAC7C,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAA;QAC/D,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK,OAAO,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACrF,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,cAAc,IAAI,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AAC5F,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,CAAU,EAAE,IAAY;IACnD,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAA;IAC9B,IAAI,CAAC,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC,KAAK,CAAA;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAwC,CAAA;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,aAAa,CAAA;IACpC,MAAM,IAAI,OAAO,CACf,IAAI,EACJ,IAAI,EACJ,cAAc,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,OAAO,IAAI,kBAAkB,EAAE,CAClE,CAAA;AACH,CAAC","sourcesContent":["/**\n * result-unwrap — the single Result→throw bridge shared by every faijs\n * statement boundary (D1).\n *\n * Three-layer error semantics:\n * library internals / TS compat face → `Result<T>` native (BrepError)\n * statement boundary → `err` unwrapped into a throw\n * faijs-specific op impls → may return `Result`; same unwrap\n *\n * This module is a **leaf**: it imports nothing, so both the SDK layer\n * (`src/define-op.ts`, whose `dist/sdk.js` must stay free of heavy static\n * imports) and the compat bridge (`api/internal/compat-op.ts`) can share one\n * implementation. Having two copies would let the two boundaries drift.\n *\n * @module\n */\n\n/** Structural shape of the compat `Ok`/`Err` records (`brepjs/core/result.ts:12-21`). */\nexport type ResultLike =\n | { ok: true; value: unknown }\n | { ok: false; error: { code?: string; message?: string } }\n\n/**\n * Statement-boundary op failure (D1 unwrap / compat adoption).\n *\n * An `err` Result unwrapped at the statement boundary used to be thrown as a\n * plain `Error`, which `CadRuntime.runWithFailureHandling` (recognizing only\n * `BrepUnsupportedError`/`MeshUnsupportedError` by `instanceof`) re-threw out\n * of `execute()` instead of converting it into `ExecutionResult.failedAt`.\n * This class is the engine-recognizable carrier: defined in this leaf module\n * (zero imports) so both `define-op` and the compat bridge can throw it while\n * CadRuntime can catch it without importing anything heavier.\n *\n * A thrown `Error` that is *not* an `OpError` keeps its old meaning: an\n * unexpected implementation bug that must propagate (Result 体系 — expected\n * failures are `err` values, exceptions are bugs).\n */\nexport class OpError extends Error {\n /** The op name that produced the failure. */\n readonly op: string\n /** The `BrepError.code`, or `'E_OP_FAILED'` when the library sent none. */\n readonly code: string\n constructor(op: string, code: string, message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'OpError'\n this.op = op\n this.code = code\n }\n}\n\n/**\n * Structural test for a Result value.\n *\n * Only the `ok: boolean` discriminant is checked — the compat `Result` is a\n * plain record, so no `instanceof` and no import is needed (which is what keeps\n * this module a leaf).\n *\n * @param v - the candidate value.\n * @returns true when `v` looks like an Ok/Err record.\n */\nexport function isResultLike(v: unknown): v is ResultLike {\n return typeof v === 'object' && v !== null && typeof (v as { ok?: unknown }).ok === 'boolean'\n}\n\n/**\n * Render an error thrown by (or returned from) an implementation as a\n * statement-level failure.\n *\n * The op name and the `BrepError.code` (when present) are always kept so the\n * engine's statement-level catch reports the same shape the plan's trace A/B\n * describe (`[faijs/op] <op>: <CODE>: <message>`).\n *\n * @param name - the op name.\n * @param err - the thrown value (Error or anything else).\n * @returns an Error carrying the op context.\n */\nexport function toOpError(name: string, err: unknown): Error {\n if (err instanceof Error) {\n const code = (err as { code?: unknown }).code\n const prefix = `[faijs/op] ${name}: ${typeof code === 'string' ? code + ': ' : ''}`\n return new Error(prefix + err.message)\n }\n return new Error(`[faijs/op] ${name}: E_OP_FAILED: ${String(err)}`)\n}\n\n/**\n * Wrap an implementation-thrown exception as an {@link OpError} (statement-\n * level failure carrier). Used by `define-op.ts` `runImpl` so that\n * `CadRuntime.directFailedAtOrThrow` recognizes the error as an op failure\n * (not a bug to re-throw).\n *\n * @param name - the op name.\n * @param err - the thrown value.\n * @returns an OpError carrying the op context and code.\n */\nexport function toOpFailure(name: string, err: unknown): OpError {\n if (err instanceof Error) {\n const code = (err as { code?: unknown }).code\n const codeStr = typeof code === 'string' ? code : 'E_OP_FAILED'\n return new OpError(name, codeStr, `[faijs/op] ${name}: ${codeStr}: ${err.message}`)\n }\n return new OpError(name, 'E_OP_FAILED', `[faijs/op] ${name}: E_OP_FAILED: ${String(err)}`)\n}\n\n/**\n * Statement-boundary unwrap (D1).\n *\n * - a non-Result product → returned untouched (plain-data ops, mesh products);\n * - `ok` → `.value`;\n * - `err` → throws an {@link OpError} carrying the op name and BrepError code\n * (the engine converts `OpError` into `ExecutionResult.failedAt`).\n *\n * @param r - the implementation product.\n * @param name - the op name (error messages).\n * @returns the unwrapped value, or the input when it was not a Result.\n * @throws an {@link OpError} when `r` is an `Err`.\n */\nexport function unwrapResult(r: unknown, name: string): unknown {\n if (!isResultLike(r)) return r\n if (r.ok) return r.value\n const e = (r.error ?? {}) as { code?: string; message?: string }\n const code = e.code ?? 'E_OP_FAILED'\n throw new OpError(\n name,\n code,\n `[faijs/op] ${name}: ${code}: ${e.message ?? 'operation failed'}`,\n )\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"knurl.d.ts","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAOhD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvE;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,eAAO,MAAM,KAAK;;CAsBhB,CAAA"}
1
+ {"version":3,"file":"knurl.d.ts","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAShD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvE;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,eAAO,MAAM,KAAK;;CAsBhB,CAAA"}
package/dist/api/knurl.js CHANGED
@@ -5,7 +5,9 @@
5
5
  * knurl 无 BREP 实现(mesh-only)——dispatchPath 在 brep 模式下调用前抛错。
6
6
  * part-brep-lost 事件由引擎统一发(P4,库不再 emit)。
7
7
  */
8
- import { cad } from '../mesh/index.js';
8
+ // B3 correction (2026-10-06): no library-face cad aggregate — import the impl from its own module.
9
+ import * as meshEngrave from '../mesh/engrave.js';
10
+ import * as meshQuery from '../mesh/query.js';
9
11
  import { reconcileBrepInputs } from './reconcile.js';
10
12
  import { defineOp } from '../sdk.js';
11
13
  import { assertPositiveNumber } from './assert.js';
@@ -45,9 +47,9 @@ export const knurl = defineOp({
45
47
  // 断链时刻(用户点名场景):BREP 建模的模型最后做滚花 → BREP 输入必须先归约为
46
48
  // 合法 2-manifold 网格再进 mesh 路径(reconcileBrepInputs 对 mesh 侧输入原样透传)
47
49
  const [meshInput] = reconcileBrepInputs([input]);
48
- return cad.knurl(meshInput, {
50
+ return meshEngrave.knurl(meshInput, {
49
51
  face: {
50
- center: params.faceCenter ?? cad.bboxCenter(meshInput),
52
+ center: params.faceCenter ?? meshQuery.bboxCenter(meshInput),
51
53
  normal: params.faceNormal ?? [0, 0, 1],
52
54
  },
53
55
  knurlTextureHeight: params.knurlTextureHeight ?? 0.5,
@@ -1 +1 @@
1
- {"version":3,"file":"knurl.js","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE/C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,oBAAoB,CAAC,MAAM,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,EAAE,KAAY,EAAE,MAA+B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;QAC5D,iBAAiB,CAAC,MAAM,CAAC,CAAA;QACzB,+CAA+C;QAC/C,iEAAiE;QACjE,MAAM,CAAC,SAAS,CAAC,GAAG,mBAAmB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAChD,OAAO,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE;YAC1B,IAAI,EAAE;gBACJ,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;gBAC5E,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aAC7D;YACD,kBAAkB,EAAG,MAAM,CAAC,kBAAyC,IAAI,GAAG;YAC5E,uBAAuB,EAAG,MAAM,CAAC,uBAA+C,IAAI,KAAK;YACzF,iBAAiB,EAAG,MAAM,CAAC,iBAAwC,IAAI,GAAG;YAC1E,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,gBAAgB,EAAG,MAAM,CAAC,gBAAuC,IAAI,CAAC;SACvE,CAAC,CAAA;IACJ,CAAC;IACD,SAAS,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE;IACxE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,2CAA2C,EAAgB;CACjG,CAAC,CAAA","sourcesContent":["/**\n * api knurl — 滚花库函数(mesh-only)\n *\n *\n * knurl 无 BREP 实现(mesh-only)——dispatchPath 在 brep 模式下调用前抛错。\n * part-brep-lost 事件由引擎统一发(P4,库不再 emit)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { reconcileBrepInputs } from './reconcile'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { assertPositiveNumber } from './assert'\n\n/**\n * Validate knurl parameters: `knurlTextureHeight` must be a positive number.\n * @param params - the raw knurl operation parameters.\n */\nexport function assertKnurlParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.knurlTextureHeight, 'knurl.knurlTextureHeight')\n}\n\n/**\n * 施加滚花(顶点位移,非布尔)。mesh-only。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual warn\n * @name knurl\n * @note knurl 无 BREP 实现(mesh-only),本质是顶点位移(网格操作),网格参数可接受;brep 模式下调用前抛 BrepUnsupportedError。面锚定建议用几何引用。\n * @returns Shape 滚花后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.knurlTextureHeight - 纹路高度(mm)。type:number 默认 0.5\n * @param params.knurlScaleU - 纹路 U 向频率。type:number 默认 0.15\n * @param params.knurlScaleV - 纹路 V 向频率。type:number 默认 0.15\n * @param params.knurlInvertDisplacement - 反向位移。type:boolean 默认 false\n * @param params.knurlRefineLength - 细分长度(mm)。type:number 默认 1.0\n * @param params.knurlMappingMode - UV 映射模式。type:number 默认 5\n * @param params.faceCenter - 面锚点中心。type:[x,y,z] 默认 bboxCenter\n * @param params.faceNormal - 面法向。type:[x,y,z] 默认 [0,0,1]\n * @example\n * const p = await cad.knurl(part0, { knurlTextureHeight: 0.5, knurlScaleU: 0.15, knurlScaleV: 0.15, knurlInvertDisplacement: false, knurlRefineLength: 1.0, knurlMappingMode: 5 })\n */\nexport const knurl = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[api/knurl] no input geometry')\n assertKnurlParams(params)\n // 断链时刻(用户点名场景):BREP 建模的模型最后做滚花 → BREP 输入必须先归约为\n // 合法 2-manifold 网格再进 mesh 路径(reconcileBrepInputs 对 mesh 侧输入原样透传)\n const [meshInput] = reconcileBrepInputs([input])\n return cad.knurl(meshInput, {\n face: {\n center: (params.faceCenter as Vec3 | undefined) ?? cad.bboxCenter(meshInput),\n normal: (params.faceNormal as Vec3 | undefined) ?? [0, 0, 1],\n },\n knurlTextureHeight: (params.knurlTextureHeight as number | undefined) ?? 0.5,\n knurlInvertDisplacement: (params.knurlInvertDisplacement as boolean | undefined) ?? false,\n knurlRefineLength: (params.knurlRefineLength as number | undefined) ?? 1.0,\n knurlScaleU: (params.knurlScaleU as number | undefined) ?? 0.15,\n knurlScaleV: (params.knurlScaleV as number | undefined) ?? 0.15,\n knurlMappingMode: (params.knurlMappingMode as number | undefined) ?? 5,\n })\n },\n paramDims: { knurlTextureHeight: 'length', knurlRefineLength: 'length' },\n naming: { kind: 'unmodeled', reason: 'knurl is mesh-only, no BREP face identity' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"knurl.js","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,mGAAmG;AACnG,OAAO,KAAK,WAAW,MAAM,iBAAiB,CAAA;AAC9C,OAAO,KAAK,SAAS,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE/C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,oBAAoB,CAAC,MAAM,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,EAAE,KAAY,EAAE,MAA+B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;QAC5D,iBAAiB,CAAC,MAAM,CAAC,CAAA;QACzB,+CAA+C;QAC/C,iEAAiE;QACjE,MAAM,CAAC,SAAS,CAAC,GAAG,mBAAmB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAChD,OAAO,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE;YAClC,IAAI,EAAE;gBACJ,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC;gBAClF,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aAC7D;YACD,kBAAkB,EAAG,MAAM,CAAC,kBAAyC,IAAI,GAAG;YAC5E,uBAAuB,EAAG,MAAM,CAAC,uBAA+C,IAAI,KAAK;YACzF,iBAAiB,EAAG,MAAM,CAAC,iBAAwC,IAAI,GAAG;YAC1E,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,gBAAgB,EAAG,MAAM,CAAC,gBAAuC,IAAI,CAAC;SACvE,CAAC,CAAA;IACJ,CAAC;IACD,SAAS,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE;IACxE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,2CAA2C,EAAgB;CACjG,CAAC,CAAA","sourcesContent":["/**\n * api knurl — 滚花库函数(mesh-only)\n *\n *\n * knurl 无 BREP 实现(mesh-only)——dispatchPath 在 brep 模式下调用前抛错。\n * part-brep-lost 事件由引擎统一发(P4,库不再 emit)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\n// B3 correction (2026-10-06): no library-face cad aggregate — import the impl from its own module.\nimport * as meshEngrave from '../mesh/engrave'\nimport * as meshQuery from '../mesh/query'\nimport { reconcileBrepInputs } from './reconcile'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { assertPositiveNumber } from './assert'\n\n/**\n * Validate knurl parameters: `knurlTextureHeight` must be a positive number.\n * @param params - the raw knurl operation parameters.\n */\nexport function assertKnurlParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.knurlTextureHeight, 'knurl.knurlTextureHeight')\n}\n\n/**\n * 施加滚花(顶点位移,非布尔)。mesh-only。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual warn\n * @name knurl\n * @note knurl 无 BREP 实现(mesh-only),本质是顶点位移(网格操作),网格参数可接受;brep 模式下调用前抛 BrepUnsupportedError。面锚定建议用几何引用。\n * @returns Shape 滚花后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.knurlTextureHeight - 纹路高度(mm)。type:number 默认 0.5\n * @param params.knurlScaleU - 纹路 U 向频率。type:number 默认 0.15\n * @param params.knurlScaleV - 纹路 V 向频率。type:number 默认 0.15\n * @param params.knurlInvertDisplacement - 反向位移。type:boolean 默认 false\n * @param params.knurlRefineLength - 细分长度(mm)。type:number 默认 1.0\n * @param params.knurlMappingMode - UV 映射模式。type:number 默认 5\n * @param params.faceCenter - 面锚点中心。type:[x,y,z] 默认 bboxCenter\n * @param params.faceNormal - 面法向。type:[x,y,z] 默认 [0,0,1]\n * @example\n * const p = await cad.knurl(part0, { knurlTextureHeight: 0.5, knurlScaleU: 0.15, knurlScaleV: 0.15, knurlInvertDisplacement: false, knurlRefineLength: 1.0, knurlMappingMode: 5 })\n */\nexport const knurl = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[api/knurl] no input geometry')\n assertKnurlParams(params)\n // 断链时刻(用户点名场景):BREP 建模的模型最后做滚花 → BREP 输入必须先归约为\n // 合法 2-manifold 网格再进 mesh 路径(reconcileBrepInputs 对 mesh 侧输入原样透传)\n const [meshInput] = reconcileBrepInputs([input])\n return meshEngrave.knurl(meshInput, {\n face: {\n center: (params.faceCenter as Vec3 | undefined) ?? meshQuery.bboxCenter(meshInput),\n normal: (params.faceNormal as Vec3 | undefined) ?? [0, 0, 1],\n },\n knurlTextureHeight: (params.knurlTextureHeight as number | undefined) ?? 0.5,\n knurlInvertDisplacement: (params.knurlInvertDisplacement as boolean | undefined) ?? false,\n knurlRefineLength: (params.knurlRefineLength as number | undefined) ?? 1.0,\n knurlScaleU: (params.knurlScaleU as number | undefined) ?? 0.15,\n knurlScaleV: (params.knurlScaleV as number | undefined) ?? 0.15,\n knurlMappingMode: (params.knurlMappingMode as number | undefined) ?? 5,\n })\n },\n paramDims: { knurlTextureHeight: 'length', knurlRefineLength: 'length' },\n naming: { kind: 'unmodeled', reason: 'knurl is mesh-only, no BREP face identity' } as Provenance,\n})\n"]}
@@ -9,11 +9,11 @@
9
9
  * `cad.profile(...)`(产出 **face**),内核 `loft(wires, …)` 只吃 wire ⇒
10
10
  * 需要「面 → 外环」输入适配(`internal/profile-wire.ts` 的唯一步径)。
11
11
  *
12
- * core-decouple G5:vendored `loft`(brepjs)替换为 occt-wasm 原生直连,
12
+ * core-decouple G5:旧 `loft`(brepjs)替换为 occt-wasm 原生直连,
13
13
  * 产物经 `fromBrep` 收养(替代 l3-bridge adoptEntity)。
14
14
  */
15
15
  import type { Shape } from '../mesh/types.js';
16
- /** 放样配置(与 vendored LoftOptions 同形;本文件自持,去 brepjs 依赖)。 */
16
+ /** 放样配置(与旧 LoftOptions 同形;本文件自持,去外部依赖)。 */
17
17
  export interface LoftOptions {
18
18
  /** 直线插值(ruled)。默认 true。 */
19
19
  ruled?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"loft.d.ts","sourceRoot":"","sources":["../../src/api/loft.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAU1C,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mBAAmB;IACnB,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpF,mBAAmB;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClF,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAiDD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,IAAI;;CAOf,CAAA"}
1
+ {"version":3,"file":"loft.d.ts","sourceRoot":"","sources":["../../src/api/loft.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAU1C,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mBAAmB;IACnB,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpF,mBAAmB;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClF,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAiDD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,IAAI;;CAOf,CAAA"}
package/dist/api/loft.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * `cad.profile(...)`(产出 **face**),内核 `loft(wires, …)` 只吃 wire ⇒
10
10
  * 需要「面 → 外环」输入适配(`internal/profile-wire.ts` 的唯一步径)。
11
11
  *
12
- * core-decouple G5:vendored `loft`(brepjs)替换为 occt-wasm 原生直连,
12
+ * core-decouple G5:旧 `loft`(brepjs)替换为 occt-wasm 原生直连,
13
13
  * 产物经 `fromBrep` 收养(替代 l3-bridge adoptEntity)。
14
14
  */
15
15
  import { defineOp } from '../sdk.js';
@@ -18,7 +18,7 @@ import { fromBrep } from '../shape.js';
18
18
  import { solidToShape } from '../brep/brep-ops.js';
19
19
  import { getOcctKernel } from '../occt-kernel/occtKernel.js';
20
20
  import { toProfileWireView } from './internal/profile-wire.js';
21
- /** PointInput → [x,y,z](vendored toVec3 同口径)。 */
21
+ /** PointInput → [x,y,z](旧 toVec3 同口径)。 */
22
22
  function toVec3(p) {
23
23
  if (Array.isArray(p) && p.length >= 3)
24
24
  return [p[0], p[1], p[2]];
@@ -1 +1 @@
1
- {"version":3,"file":"loft.js","sourceRoot":"","sources":["../../src/api/loft.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api loft — 放样:多个截面之间蒙皮生成体(手写平台 op,Phase 4 → G5 core 直连)\n *\n * @platform occt — 实现走 core 直连 `occt-wasm loft` / `loftWithVertices`\n * (BRepOffsetAPI_ThruSections;engine-method-map 里 `loft` 为 occt-only)⇒ 平台 op:\n * defineOp 声明 `engines: ['occt']`(D11)。\n *\n * 为什么手写而不走生成投影:与 `api/sweep.ts` 同因——截面最常见来源是\n * `cad.profile(...)`(产出 **face**),内核 `loft(wires, …)` 只吃 wire ⇒\n * 需要「面 → 外环」输入适配(`internal/profile-wire.ts` 的唯一步径)。\n *\n * core-decouple G5:vendored `loft`(brepjs)替换为 occt-wasm 原生直连,\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 { getOcctKernel } from '../occt-kernel/occtKernel'\nimport { toProfileWireView } from './internal/profile-wire'\nimport type { BrepHandle } from '../brep/engine/types'\n\n/** 放样配置(与 vendored LoftOptions 同形;本文件自持,去 brepjs 依赖)。 */\nexport interface LoftOptions {\n /** 直线插值(ruled)。默认 true。 */\n ruled?: boolean\n /** 起点(退化到点的蒙皮)。 */\n startPoint?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** 终点(退化到点的蒙皮)。 */\n endPoint?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** ThruSections 缝合公差。默认 1e-6。 */\n tolerance?: number\n}\n\n/** PointInput → [x,y,z](vendored toVec3 同口径)。 */\nfunction toVec3(p: LoftOptions['startPoint']): [number, number, number] {\n if (Array.isArray(p) && p.length >= 3) return [p[0]!, p[1]!, p[2]!]\n const o = p as { x: number; y: number; z: number }\n return [o.x, o.y, o.z]\n}\n\n/** BREP 路径:按序蒙皮各截面(wire 视图 → occt-wasm 直连 → fromBrep 收养)。 */\nfunction loftBrep(sections: Shape[], opts?: LoftOptions): Shape {\n if (!Array.isArray(sections) || sections.length === 0) {\n throw new Error('E_LOFT_NO_SECTIONS: loft requires a non-empty array of section shapes')\n }\n // 每截面:wire 直用;面取外环(孔环不参与放样)。\n const wireViews = sections.map((s) => toProfileWireView(s))\n const { ruled = true, startPoint, endPoint } = opts ?? {}\n const kernel = getBrepApi()\n const k = getOcctKernel()\n const wireHandles = wireViews.map((w) => w.wrapped as never)\n\n try {\n let h: unknown\n if (startPoint !== undefined || endPoint !== undefined) {\n const startVertex = startPoint !== undefined ? k.makeVertex(...toVec3(startPoint)) : undefined\n const endVertex = endPoint !== undefined ? k.makeVertex(...toVec3(endPoint)) : undefined\n try {\n h = k.loftWithVertices(wireHandles, true, ruled, startVertex as never, endVertex as never)\n } finally {\n if (startVertex !== undefined) k.release(startVertex)\n if (endVertex !== undefined) k.release(endVertex)\n }\n } else {\n h = k.loft(wireHandles, true, ruled)\n }\n return fromBrep(solidToShape(kernel, h as BrepHandle), { solid: h as BrepHandle })\n } catch (e) {\n const raw = e instanceof Error ? e.message : String(e)\n throw new Error(`E_LOFT_FAILED: loft failed: ${raw}`, { cause: e })\n } finally {\n // 面→外环产出的 wire 是 arena 新句柄(曲线借用不 release)\n for (const w of wireViews) {\n if (!w.borrowed) {\n try { kernel.release(w.wrapped) } catch { /* 已释放 */ }\n }\n }\n }\n}\n\n/**\n * 放样:按给定顺序在截面之间蒙皮生成体。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name loft\n * @note 平台 op:仅 occt 引擎(BRepOffsetAPI_ThruSections)。截面可为 wire 或面\n * (面取其外环),至少 2 个;`startPoint` / `endPoint` 可做退化到点的蒙皮。\n * 非 occt 引擎执行前报错;brep_mock 不拦截。不做 `loftAll`(数组产物)。\n * @returns Shape 放样体。\n * @param sections - 有序截面集合(wire 或面;面取其外环)。type:Shape[] required:true\n * @param opts - 放样配置(ruled / startPoint / endPoint / tolerance)。type:LoftOptions required:false\n * @example\n * const bottom = cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -5, y1: -5, x2: 5, y2: -5 },\n * { kind: 'line', x1: 5, y1: -5, x2: 5, y2: 5 },\n * { kind: 'line', x1: 5, y1: 5, x2: -5, y2: 5 },\n * { kind: 'line', x1: -5, y1: 5, x2: -5, y2: -5 },\n * ] }] })\n * const top = cad.translate(cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -3, y1: -3, x2: 3, y2: -3 },\n * { kind: 'line', x1: 3, y1: -3, x2: 3, y2: 3 },\n * { kind: 'line', x1: 3, y1: 3, x2: -3, y2: 3 },\n * { kind: 'line', x1: -3, y1: 3, x2: -3, y2: -3 },\n * ] }] }), [0, 0, 20])\n * const body = await cad.loft([bottom, top])\n */\nexport const loft = defineOp({\n name: 'loft',\n brep(sections: Shape[], opts?: LoftOptions) {\n return loftBrep(sections, opts)\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: 'lofted-body face vocabulary not defined' } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"loft.js","sourceRoot":"","sources":["../../src/api/loft.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;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,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAe3D,0CAA0C;AAC1C,SAAS,MAAM,CAAC,CAA4B;IAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;IACnE,MAAM,CAAC,GAAG,CAAwC,CAAA;IAClD,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AACxB,CAAC;AAED,6DAA6D;AAC7D,SAAS,QAAQ,CAAC,QAAiB,EAAE,IAAkB;IACrD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;IAC1F,CAAC;IACD,6BAA6B;IAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3D,MAAM,EAAE,KAAK,GAAG,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,IAAI,EAAE,CAAA;IACzD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,CAAC,GAAG,aAAa,EAAE,CAAA;IACzB,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAA;IAE5D,IAAI,CAAC;QACH,IAAI,CAAU,CAAA;QACd,IAAI,UAAU,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACvD,MAAM,WAAW,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;YAC9F,MAAM,SAAS,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;YACxF,IAAI,CAAC;gBACH,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,WAAoB,EAAE,SAAkB,CAAC,CAAA;YAC5F,CAAC;oBAAS,CAAC;gBACT,IAAI,WAAW,KAAK,SAAS;oBAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;gBACrD,IAAI,SAAS,KAAK,SAAS;oBAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YACnD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,CAAe,CAAC,EAAE,EAAE,KAAK,EAAE,CAAe,EAAE,CAAC,CAAA;IACpF,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACtD,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IACrE,CAAC;YAAS,CAAC;QACT,0CAA0C;QAC1C,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAChB,IAAI,CAAC;oBAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,QAAQ,CAAC;IAC3B,IAAI,EAAE,MAAM;IACZ,IAAI,CAAC,QAAiB,EAAE,IAAkB;QACxC,OAAO,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,CAAC;IACjB,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,yCAAyC,EAAgB;CAC/F,CAAC,CAAA","sourcesContent":["/**\n * api loft — 放样:多个截面之间蒙皮生成体(手写平台 op,Phase 4 → G5 core 直连)\n *\n * @platform occt — 实现走 core 直连 `occt-wasm loft` / `loftWithVertices`\n * (BRepOffsetAPI_ThruSections;engine-method-map 里 `loft` 为 occt-only)⇒ 平台 op:\n * defineOp 声明 `engines: ['occt']`(D11)。\n *\n * 为什么手写而不走生成投影:与 `api/sweep.ts` 同因——截面最常见来源是\n * `cad.profile(...)`(产出 **face**),内核 `loft(wires, …)` 只吃 wire ⇒\n * 需要「面 → 外环」输入适配(`internal/profile-wire.ts` 的唯一步径)。\n *\n * core-decouple G5:旧 `loft`(brepjs)替换为 occt-wasm 原生直连,\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 { getOcctKernel } from '../occt-kernel/occtKernel'\nimport { toProfileWireView } from './internal/profile-wire'\nimport type { BrepHandle } from '../brep/engine/types'\n\n/** 放样配置(与旧 LoftOptions 同形;本文件自持,去外部依赖)。 */\nexport interface LoftOptions {\n /** 直线插值(ruled)。默认 true。 */\n ruled?: boolean\n /** 起点(退化到点的蒙皮)。 */\n startPoint?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** 终点(退化到点的蒙皮)。 */\n endPoint?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** ThruSections 缝合公差。默认 1e-6。 */\n tolerance?: number\n}\n\n/** PointInput → [x,y,z](旧 toVec3 同口径)。 */\nfunction toVec3(p: LoftOptions['startPoint']): [number, number, number] {\n if (Array.isArray(p) && p.length >= 3) return [p[0]!, p[1]!, p[2]!]\n const o = p as { x: number; y: number; z: number }\n return [o.x, o.y, o.z]\n}\n\n/** BREP 路径:按序蒙皮各截面(wire 视图 → occt-wasm 直连 → fromBrep 收养)。 */\nfunction loftBrep(sections: Shape[], opts?: LoftOptions): Shape {\n if (!Array.isArray(sections) || sections.length === 0) {\n throw new Error('E_LOFT_NO_SECTIONS: loft requires a non-empty array of section shapes')\n }\n // 每截面:wire 直用;面取外环(孔环不参与放样)。\n const wireViews = sections.map((s) => toProfileWireView(s))\n const { ruled = true, startPoint, endPoint } = opts ?? {}\n const kernel = getBrepApi()\n const k = getOcctKernel()\n const wireHandles = wireViews.map((w) => w.wrapped as never)\n\n try {\n let h: unknown\n if (startPoint !== undefined || endPoint !== undefined) {\n const startVertex = startPoint !== undefined ? k.makeVertex(...toVec3(startPoint)) : undefined\n const endVertex = endPoint !== undefined ? k.makeVertex(...toVec3(endPoint)) : undefined\n try {\n h = k.loftWithVertices(wireHandles, true, ruled, startVertex as never, endVertex as never)\n } finally {\n if (startVertex !== undefined) k.release(startVertex)\n if (endVertex !== undefined) k.release(endVertex)\n }\n } else {\n h = k.loft(wireHandles, true, ruled)\n }\n return fromBrep(solidToShape(kernel, h as BrepHandle), { solid: h as BrepHandle })\n } catch (e) {\n const raw = e instanceof Error ? e.message : String(e)\n throw new Error(`E_LOFT_FAILED: loft failed: ${raw}`, { cause: e })\n } finally {\n // 面→外环产出的 wire 是 arena 新句柄(曲线借用不 release)\n for (const w of wireViews) {\n if (!w.borrowed) {\n try { kernel.release(w.wrapped) } catch { /* 已释放 */ }\n }\n }\n }\n}\n\n/**\n * 放样:按给定顺序在截面之间蒙皮生成体。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name loft\n * @note 平台 op:仅 occt 引擎(BRepOffsetAPI_ThruSections)。截面可为 wire 或面\n * (面取其外环),至少 2 个;`startPoint` / `endPoint` 可做退化到点的蒙皮。\n * 非 occt 引擎执行前报错;brep_mock 不拦截。不做 `loftAll`(数组产物)。\n * @returns Shape 放样体。\n * @param sections - 有序截面集合(wire 或面;面取其外环)。type:Shape[] required:true\n * @param opts - 放样配置(ruled / startPoint / endPoint / tolerance)。type:LoftOptions required:false\n * @example\n * const bottom = cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -5, y1: -5, x2: 5, y2: -5 },\n * { kind: 'line', x1: 5, y1: -5, x2: 5, y2: 5 },\n * { kind: 'line', x1: 5, y1: 5, x2: -5, y2: 5 },\n * { kind: 'line', x1: -5, y1: 5, x2: -5, y2: -5 },\n * ] }] })\n * const top = cad.translate(cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -3, y1: -3, x2: 3, y2: -3 },\n * { kind: 'line', x1: 3, y1: -3, x2: 3, y2: 3 },\n * { kind: 'line', x1: 3, y1: 3, x2: -3, y2: 3 },\n * { kind: 'line', x1: -3, y1: 3, x2: -3, y2: -3 },\n * ] }] }), [0, 0, 20])\n * const body = await cad.loft([bottom, top])\n */\nexport const loft = defineOp({\n name: 'loft',\n brep(sections: Shape[], opts?: LoftOptions) {\n return loftBrep(sections, opts)\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: 'lofted-body face vocabulary not defined' } as Provenance,\n})\n"]}
@@ -9,9 +9,9 @@
9
9
  * - volume(shape) → 体积(getVolume);
10
10
  * - centerOfMass(shape) → 质心坐标(getCenterOfMass,BrepVec3 {x,y,z})。
11
11
  *
12
- * 与 vendored 测量面(api/generated/measurement.ts 的 measureArea / measureLength)
13
- * 的区别:那些 op 经 l3-bridge 借入层 + vendored 函数绑定 occt-wasm,整体 occt-only
14
- * (Phase 6 已声明 engines: ['occt']);本模块直接调 L1 方法,无借入层、无引擎绑定,
12
+ * 与旧测量面(api/generated/measurement.ts 的 measureArea / measureLength)
13
+ * 的区别:那些 op 挂在生成投影面上,整体 occt-only(Phase 6 已声明 engines: ['occt']);
14
+ * 本模块直接调 L1 方法,不经来源实现、无引擎绑定,
15
15
  * 是脚本面的中立测量入口。返回纯数字,不产出 Shape、不消费 shape。
16
16
  *
17
17
  * 三源一致(B1):本模块经 arg-spec 的 `scriptFace: true` 条目(kind 'faijs')登记,
@@ -9,9 +9,9 @@
9
9
  * - volume(shape) → 体积(getVolume);
10
10
  * - centerOfMass(shape) → 质心坐标(getCenterOfMass,BrepVec3 {x,y,z})。
11
11
  *
12
- * 与 vendored 测量面(api/generated/measurement.ts 的 measureArea / measureLength)
13
- * 的区别:那些 op 经 l3-bridge 借入层 + vendored 函数绑定 occt-wasm,整体 occt-only
14
- * (Phase 6 已声明 engines: ['occt']);本模块直接调 L1 方法,无借入层、无引擎绑定,
12
+ * 与旧测量面(api/generated/measurement.ts 的 measureArea / measureLength)
13
+ * 的区别:那些 op 挂在生成投影面上,整体 occt-only(Phase 6 已声明 engines: ['occt']);
14
+ * 本模块直接调 L1 方法,不经来源实现、无引擎绑定,
15
15
  * 是脚本面的中立测量入口。返回纯数字,不产出 Shape、不消费 shape。
16
16
  *
17
17
  * 三源一致(B1):本模块经 arg-spec 的 `scriptFace: true` 条目(kind 'faijs')登记,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/measurement/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAgBjD;;;;;;;;;;;;GAYG;AACH,SAAS,wBAAwB,CAAC,KAAY,EAAE,EAAU;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IACpD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IAC9D,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAA2B,CAAA;IACzD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC,MAAM,CAAC,SAAyC,CAAA;QAC9E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,uBAAuB,EAAE,qEAAqE;gBAC9F,mCAAmC,CACpC,CAAA;QACH,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IAChE,CAAC;IACD,MAAM,IAAI,KAAK,CACb,uBAAuB,EAAE,8EAA8E;QACvG,iEAAiE,CAClE,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,KAAY;IACrC,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACjD,OAAO,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAY;IACvC,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACnD,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAY;IACvC,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACnD,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAY;IAC7C,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAA;IACzD,OAAO,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAC3C,CAAC","sourcesContent":["/**\n * measurement — cad 脚本面测量 op(Phase 7,narrowing plan §Phase 7 / Q4)\n *\n * 补齐 §1.5 的反向缺口:BrepEngineApi 的 L1 测量面(getSurfaceArea / getLength)\n * 在脚本面此前没有任何入口——脚本里量不出面积、长度。本模块提供两个**中立**测量\n * op(走 getBrepApi() 的 L1 契约面,occt / brepkit / 小程序端同一份 .fai.js 都可跑):\n * - area(shape) → 表面积(getSurfaceArea);\n * - length(shape) → 边长/线长(getLength);\n * - volume(shape) → 体积(getVolume);\n * - centerOfMass(shape) → 质心坐标(getCenterOfMass,BrepVec3 {x,y,z})。\n *\n * 与 vendored 测量面(api/generated/measurement.ts 的 measureArea / measureLength)\n * 的区别:那些 op 经 l3-bridge 借入层 + vendored 函数绑定 occt-wasm,整体 occt-only\n * (Phase 6 已声明 engines: ['occt']);本模块直接调 L1 方法,无借入层、无引擎绑定,\n * 是脚本面的中立测量入口。返回纯数字,不产出 Shape、不消费 shape。\n *\n * 三源一致(B1):本模块经 arg-spec 的 `scriptFace: true` 条目(kind 'faijs')登记,\n * 由 gen-l3-surface.ts re-export 进 api/generated/script-face.ts / script-face-manifest.ts,\n * gen-symbol-table.ts 同步 check() 符号表——cad 命名空间、manifest、符号表三处同源。\n */\n\nimport { brepOf, meshSolidOf } from '../../shape'\nimport { getBrepApi } from '../../brep/handle-bridge'\nimport { getBackends } from '../../runtime-state'\nimport type { MeshSolidBackend } from '../../brep/mesh-solid'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { Shape } from '../../mesh/types'\nimport type { BrepHandle, BrepVec3 } from '../../brep/engine/types'\n\n/** 量测目标:句柄 + 读它的内核(精度链用 BREP 引擎,网格链用网格后端)。 */\ninterface MeasurementTarget {\n /** 读该句柄的 L1 契约面。 */\n readonly kernel: BrepEngineApi\n /** 被量测的句柄。 */\n readonly handle: BrepHandle\n /** 量测所在链(`mesh` = 网格零件,量的是面片几何)。 */\n readonly chain: 'brep' | 'mesh'\n}\n\n/**\n * 取量测目标:精度链句柄优先,其次是网格零件句柄;两者都没有 → 显式报错。\n *\n * 网格零件(方案 2026-10-01 §4 Phase 4 / B4 批)走**网格后端**的 L1 内核。它的\n * 量测值是对**面片几何**的精确量(STL 的曲面本来就是离散的:立方体 1000 与解析值\n * 一致,圆柱侧面则是 32 个面片之和)——不是对原始设计的还原,也不是估算。所以\n * 这里如实量、如实说,不额外加\"近似\"折扣,也不静默返回 0。\n *\n * @param shape - the shape being measured.\n * @param op - the measurement op name (error messages).\n * @returns the handle to measure plus the kernel that can read it.\n * @throws {Error} `E_MEASUREMENT_NO_HANDLE` when the shape carries neither chain handle.\n */\nfunction requireMeasurementTarget(shape: Shape, op: string): MeasurementTarget {\n const brep = brepOf(shape) as BrepHandle | undefined\n if (brep !== undefined) {\n return { kernel: getBrepApi(), handle: brep, chain: 'brep' }\n }\n const mesh = meshSolidOf(shape) as BrepHandle | undefined\n if (mesh !== undefined) {\n const backend = getBackends().kernel.meshSolid as MeshSolidBackend | undefined\n if (!backend) {\n throw new Error(\n `[faijs/measurement] ${op}: E_MESH_SOLID_UNSUPPORTED: this shape is a mesh solid but no mesh ` +\n 'backend is assembled in this host',\n )\n }\n return { kernel: backend.kernel, handle: mesh, chain: 'mesh' }\n }\n throw new Error(\n `[faijs/measurement] ${op}: E_MEASUREMENT_NO_HANDLE: measurement requires a shape with a chain handle ` +\n '(a bare mesh has neither a BREP handle nor a mesh solid handle)',\n )\n}\n\n/**\n * 测量形状的表面积(L1 getSurfaceArea,两引擎同口径)。\n *\n * @param shape - 被测量的形状(Face / Shape3D / compound / 网格零件)。\n * @returns 表面积(mm²;网格零件按面片几何计)。\n */\nexport async function area(shape: Shape): Promise<number> {\n const t = requireMeasurementTarget(shape, 'area')\n return t.kernel.getSurfaceArea(t.handle)\n}\n\n/**\n * 测量形状的边长/线长(L1 getLength,两引擎同口径)。\n *\n * 口径 = **shape 中所有唯一 edge 的弧长之和**:edge 取自身弧长,wire 取其边之和,\n * face 取边界边之和,solid 取全部边之和,compound 取各子实体之和。两个 BREP 引擎\n * 在此口径下逐位一致(2026-10-02 归一化,见 occt / brepkit 适配器的 getLength)。\n *\n * @param shape - 被测量的形状(edge / wire / face / solid / compound)。\n * @returns 长度(mm)。\n */\nexport async function length(shape: Shape): Promise<number> {\n const t = requireMeasurementTarget(shape, 'length')\n return t.kernel.getLength(t.handle)\n}\n\n/**\n * 测量形状的体素体积(L1 getVolume,两引擎同口径)。\n *\n * @param shape - 被测量的形状(solid / compound;对 wire / face 内核按自身口径计,可能返回 0)。\n * @returns 体积(mm³;网格零件按面片几何计)。\n */\nexport async function volume(shape: Shape): Promise<number> {\n const t = requireMeasurementTarget(shape, 'volume')\n return t.kernel.getVolume(t.handle)\n}\n\n/**\n * 测量形状的质心(L1 getCenterOfMass,两引擎同口径)。\n *\n * @param shape - 被测量的形状(solid / compound / face / 网格零件)。\n * @returns 质心坐标(mm,BREP 中立形态 {x,y,z})。\n */\nexport async function centerOfMass(shape: Shape): Promise<BrepVec3> {\n const t = requireMeasurementTarget(shape, 'centerOfMass')\n return t.kernel.getCenterOfMass(t.handle)\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/measurement/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAgBjD;;;;;;;;;;;;GAYG;AACH,SAAS,wBAAwB,CAAC,KAAY,EAAE,EAAU;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IACpD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IAC9D,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAA2B,CAAA;IACzD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC,MAAM,CAAC,SAAyC,CAAA;QAC9E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,uBAAuB,EAAE,qEAAqE;gBAC9F,mCAAmC,CACpC,CAAA;QACH,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IAChE,CAAC;IACD,MAAM,IAAI,KAAK,CACb,uBAAuB,EAAE,8EAA8E;QACvG,iEAAiE,CAClE,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,KAAY;IACrC,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACjD,OAAO,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAY;IACvC,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACnD,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAY;IACvC,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACnD,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAY;IAC7C,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAA;IACzD,OAAO,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAC3C,CAAC","sourcesContent":["/**\n * measurement — cad 脚本面测量 op(Phase 7,narrowing plan §Phase 7 / Q4)\n *\n * 补齐 §1.5 的反向缺口:BrepEngineApi 的 L1 测量面(getSurfaceArea / getLength)\n * 在脚本面此前没有任何入口——脚本里量不出面积、长度。本模块提供两个**中立**测量\n * op(走 getBrepApi() 的 L1 契约面,occt / brepkit / 小程序端同一份 .fai.js 都可跑):\n * - area(shape) → 表面积(getSurfaceArea);\n * - length(shape) → 边长/线长(getLength);\n * - volume(shape) → 体积(getVolume);\n * - centerOfMass(shape) → 质心坐标(getCenterOfMass,BrepVec3 {x,y,z})。\n *\n * 与旧测量面(api/generated/measurement.ts 的 measureArea / measureLength)\n * 的区别:那些 op 挂在生成投影面上,整体 occt-only(Phase 6 已声明 engines: ['occt']);\n * 本模块直接调 L1 方法,不经来源实现、无引擎绑定,\n * 是脚本面的中立测量入口。返回纯数字,不产出 Shape、不消费 shape。\n *\n * 三源一致(B1):本模块经 arg-spec 的 `scriptFace: true` 条目(kind 'faijs')登记,\n * 由 gen-l3-surface.ts re-export 进 api/generated/script-face.ts / script-face-manifest.ts,\n * gen-symbol-table.ts 同步 check() 符号表——cad 命名空间、manifest、符号表三处同源。\n */\n\nimport { brepOf, meshSolidOf } from '../../shape'\nimport { getBrepApi } from '../../brep/handle-bridge'\nimport { getBackends } from '../../runtime-state'\nimport type { MeshSolidBackend } from '../../brep/mesh-solid'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { Shape } from '../../mesh/types'\nimport type { BrepHandle, BrepVec3 } from '../../brep/engine/types'\n\n/** 量测目标:句柄 + 读它的内核(精度链用 BREP 引擎,网格链用网格后端)。 */\ninterface MeasurementTarget {\n /** 读该句柄的 L1 契约面。 */\n readonly kernel: BrepEngineApi\n /** 被量测的句柄。 */\n readonly handle: BrepHandle\n /** 量测所在链(`mesh` = 网格零件,量的是面片几何)。 */\n readonly chain: 'brep' | 'mesh'\n}\n\n/**\n * 取量测目标:精度链句柄优先,其次是网格零件句柄;两者都没有 → 显式报错。\n *\n * 网格零件(方案 2026-10-01 §4 Phase 4 / B4 批)走**网格后端**的 L1 内核。它的\n * 量测值是对**面片几何**的精确量(STL 的曲面本来就是离散的:立方体 1000 与解析值\n * 一致,圆柱侧面则是 32 个面片之和)——不是对原始设计的还原,也不是估算。所以\n * 这里如实量、如实说,不额外加\"近似\"折扣,也不静默返回 0。\n *\n * @param shape - the shape being measured.\n * @param op - the measurement op name (error messages).\n * @returns the handle to measure plus the kernel that can read it.\n * @throws {Error} `E_MEASUREMENT_NO_HANDLE` when the shape carries neither chain handle.\n */\nfunction requireMeasurementTarget(shape: Shape, op: string): MeasurementTarget {\n const brep = brepOf(shape) as BrepHandle | undefined\n if (brep !== undefined) {\n return { kernel: getBrepApi(), handle: brep, chain: 'brep' }\n }\n const mesh = meshSolidOf(shape) as BrepHandle | undefined\n if (mesh !== undefined) {\n const backend = getBackends().kernel.meshSolid as MeshSolidBackend | undefined\n if (!backend) {\n throw new Error(\n `[faijs/measurement] ${op}: E_MESH_SOLID_UNSUPPORTED: this shape is a mesh solid but no mesh ` +\n 'backend is assembled in this host',\n )\n }\n return { kernel: backend.kernel, handle: mesh, chain: 'mesh' }\n }\n throw new Error(\n `[faijs/measurement] ${op}: E_MEASUREMENT_NO_HANDLE: measurement requires a shape with a chain handle ` +\n '(a bare mesh has neither a BREP handle nor a mesh solid handle)',\n )\n}\n\n/**\n * 测量形状的表面积(L1 getSurfaceArea,两引擎同口径)。\n *\n * @param shape - 被测量的形状(Face / Shape3D / compound / 网格零件)。\n * @returns 表面积(mm²;网格零件按面片几何计)。\n */\nexport async function area(shape: Shape): Promise<number> {\n const t = requireMeasurementTarget(shape, 'area')\n return t.kernel.getSurfaceArea(t.handle)\n}\n\n/**\n * 测量形状的边长/线长(L1 getLength,两引擎同口径)。\n *\n * 口径 = **shape 中所有唯一 edge 的弧长之和**:edge 取自身弧长,wire 取其边之和,\n * face 取边界边之和,solid 取全部边之和,compound 取各子实体之和。两个 BREP 引擎\n * 在此口径下逐位一致(2026-10-02 归一化,见 occt / brepkit 适配器的 getLength)。\n *\n * @param shape - 被测量的形状(edge / wire / face / solid / compound)。\n * @returns 长度(mm)。\n */\nexport async function length(shape: Shape): Promise<number> {\n const t = requireMeasurementTarget(shape, 'length')\n return t.kernel.getLength(t.handle)\n}\n\n/**\n * 测量形状的体素体积(L1 getVolume,两引擎同口径)。\n *\n * @param shape - 被测量的形状(solid / compound;对 wire / face 内核按自身口径计,可能返回 0)。\n * @returns 体积(mm³;网格零件按面片几何计)。\n */\nexport async function volume(shape: Shape): Promise<number> {\n const t = requireMeasurementTarget(shape, 'volume')\n return t.kernel.getVolume(t.handle)\n}\n\n/**\n * 测量形状的质心(L1 getCenterOfMass,两引擎同口径)。\n *\n * @param shape - 被测量的形状(solid / compound / face / 网格零件)。\n * @returns 质心坐标(mm,BREP 中立形态 {x,y,z})。\n */\nexport async function centerOfMass(shape: Shape): Promise<BrepVec3> {\n const t = requireMeasurementTarget(shape, 'centerOfMass')\n return t.kernel.getCenterOfMass(t.handle)\n}\n"]}
@@ -1,8 +1,6 @@
1
1
  /**
2
2
  * api/meta — faijs 零件名称/描述/料号 与 整体文件元数据 权威类型与 Shape 方法
3
3
  *
4
- * 设计文档:docs/plans/2026-10-05-faijs-meta-name-note-api-design.md
5
- *
6
4
  * 定位(与 api/appearance.ts 同款方法模式):
7
5
  * - 名称/描述设置**不是 op**(不进 defineOp/api-namespace/args-schema),是 Shape
8
6
  * 实例方法(`box1.setName('…')`,复用 `asm1.solve()` 的成员调用语句形态)。
@@ -1 +1 @@
1
- {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/api/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAI1C,gDAAgD;AAChD,MAAM,WAAW,SAAS;IACxB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IAC9B,uCAAuC;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,8CAA8C;IAC9C,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,qCAAqC;IACrC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,sEAAsE;IACtE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,+BAA+B;IAC/B,OAAO,IAAI,QAAQ,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;CAC3C;AAID;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,CAuBhF;AAID;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,gBAAgB,CA2BxE"}
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/api/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAI1C,gDAAgD;AAChD,MAAM,WAAW,SAAS;IACxB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IAC9B,uCAAuC;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,8CAA8C;IAC9C,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,qCAAqC;IACrC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,sEAAsE;IACtE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,+BAA+B;IAC/B,OAAO,IAAI,QAAQ,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;CAC3C;AAID;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,CAuBhF;AAID;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,gBAAgB,CA2BxE"}
package/dist/api/meta.js CHANGED
@@ -1,8 +1,6 @@
1
1
  /**
2
2
  * api/meta — faijs 零件名称/描述/料号 与 整体文件元数据 权威类型与 Shape 方法
3
3
  *
4
- * 设计文档:docs/plans/2026-10-05-faijs-meta-name-note-api-design.md
5
- *
6
4
  * 定位(与 api/appearance.ts 同款方法模式):
7
5
  * - 名称/描述设置**不是 op**(不进 defineOp/api-namespace/args-schema),是 Shape
8
6
  * 实例方法(`box1.setName('…')`,复用 `asm1.solve()` 的成员调用语句形态)。
@@ -1 +1 @@
1
- {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/api/meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api/meta — faijs 零件名称/描述/料号 与 整体文件元数据 权威类型与 Shape 方法\n *\n * 设计文档:docs/plans/2026-10-05-faijs-meta-name-note-api-design.md\n *\n * 定位(与 api/appearance.ts 同款方法模式):\n * - 名称/描述设置**不是 op**(不进 defineOp/api-namespace/args-schema),是 Shape\n * 实例方法(`box1.setName('…')`,复用 `asm1.solve()` 的成员调用语句形态)。\n * - `ShapeMeta`(零件级)与 `FileMeta`(整体级)引擎无关、JSON 可序列化;\n * `Shape.meta` 随 Shape 走 mesh/brep 双链路,编辑器/查看器只读字段。\n * - 本文件零依赖(不 import THREE / occt / store);唯一 import 是 mesh/types\n * 的 `Shape` 类型(type-only),mesh/types 亦只 type-import 本文件的类型,\n * 两者为类型环、无运行时环(值依赖单向:shape.ts → api/meta.ts)。\n *\n * 命名约定(camelCase,faijs 全 TS/JS 生态):\n * - 零件级:`name` / `description` / `partNumber` / `metadata`(键值)。\n * - 方法:`setName` / `setDescription` / `setPartNumber` / `setMetaField` /\n * `setMeta` / `getMeta`。字段名与 3MF/STEP 规范一致(不用 note)。\n * 空串 = 清除:`setName('')` 删除 name(与「undefined 不覆盖」互补,用户可\n * 显式去掉继承来的名称)。\n */\n\nimport type { Shape } from '../mesh/types'\n\n// ── 类型 ──\n\n/** 零件级说明性元数据 —— 引擎无关、JSON 可序列化、随 Shape 走双链路。 */\nexport interface ShapeMeta {\n /** 零件名:3MF `<object name>` / STEP `PRODUCT().name`。 */\n name?: string\n /** 描述:STEP `PRODUCT.description`;3MF 写 `faijs:description` metadatagroup。 */\n description?: string\n /** 料号:3MF `<object partnumber>`;STEP `PRODUCT_IDENTIFICATION` 或 UDA。 */\n partNumber?: string\n /**\n * 自定义键值:3MF `<object><metadatagroup>`(vendor 前缀);STEP UDA。\n * 键为规范/厂商原始名(3MF 含命名空间前缀);faijs 不解释值语义,\n * 读入保留、写出回写。\n */\n metadata?: Record<string, string>\n}\n\n/**\n * 整体/文档级说明性元数据 —— 导入结果 / 导出选项,不挂 Shape。\n *\n * 不叫 `ModelMeta`:CAD 直觉里 \"model\" 偏单个零件(那是 `ShapeMeta` 的活);\n * 本类型承载整个交换文件(3MF `<model>` / STEP P21 header)的元数据,故用\n * `FileMeta`。\n */\nexport interface FileMeta {\n title?: string // 3MF Title / STEP FILE_NAME.name\n description?: string // 3MF Description / STEP FILE_DESCRIPTION.description\n designer?: string // 3MF Designer / STEP FILE_NAME.originator\n author?: string // STEP FILE_NAME.author(3MF 无对应;跨格式不互转)\n organization?: string // STEP FILE_NAME.organization(3MF 无对应)\n copyright?: string // 3MF Copyright(STEP 无标准位置)\n licenseTerms?: string // 3MF LicenseTerms(STEP 无标准位置)\n rating?: string // 3MF Rating(STEP 无标准位置)\n creationDate?: string // 3MF CreationDate / STEP FILE_NAME.timestamp\n modificationDate?: string // 3MF ModificationDate(STEP 无标准位置)\n application?: string // 3MF Application / STEP FILE_NAME.preprocessor\n /** 未知/厂商自定义 metadata 兜底(3MF model 级带前缀名;STEP header 其余字段)。 */\n metadata?: Record<string, string>\n}\n\n/** Shape 元数据方法签名(运行时由 attachMetaMethods 挂载;纯数据判定不受影响)。 */\nexport interface ShapeMetaMethods {\n /** 合并 meta:`{...cur, ...spec}`,spec 中 undefined 字段保留旧值。 */\n setMeta(spec: ShapeMeta): this\n /** 便捷:等价 setMeta({ name })(空串视为清除)。 */\n setName(name: string): this\n /** 便捷:等价 setMeta({ description })(空串视为清除)。 */\n setDescription(description: string): this\n /** 便捷:等价 setMeta({ partNumber })。 */\n setPartNumber(partNumber: string): this\n /** 便捷:等价 setMeta({ metadata: {...cur.metadata, ...kv} });值为空串的键删除。 */\n setMetaField(key: string, value: string): this\n /** 读取当前 meta(可能 undefined)。 */\n getMeta(): Readonly<ShapeMeta> | undefined\n}\n\n// ── 合并 ──\n\n/**\n * 合并零件级元数据:spec 中 undefined 字段不覆盖旧值;空串覆盖为清除。\n * @param cur 当前 meta(可为 undefined)\n * @param spec 待合并字段(undefined 字段跳过;'' 显式清除)\n * @returns 合并后的 meta(新对象;cur 为 undefined 时仅含 spec 非空字段)\n */\nexport function mergeMeta(cur: ShapeMeta | undefined, spec: ShapeMeta): ShapeMeta {\n const clean: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(spec)) {\n if (v === undefined) continue\n if (k === 'metadata' && v && typeof v === 'object') {\n // 键值子合并:保留旧 metadata 的未覆盖键。\n const base: Record<string, string> = { ...((cur?.metadata as Record<string, string> | undefined) ?? {}) }\n for (const [kk, vv] of Object.entries(v as Record<string, string>)) {\n if (vv === '') delete base[kk] // 空串清除该键\n else base[kk] = vv\n }\n clean[k] = base\n continue\n }\n if (v === '') clean[k] = undefined as unknown as string // 空串清除顶层字段\n else clean[k] = v\n }\n const merged = { ...(cur ?? {}), ...clean } as ShapeMeta\n // 清理合并后为 undefined 的顶层键(空串清除写入 undefined)。\n for (const k of Object.keys(merged)) {\n if ((merged as Record<string, unknown>)[k] === undefined) delete (merged as Record<string, unknown>)[k]\n }\n return merged\n}\n\n// ── Shape 方法挂载 ──\n\n/**\n * 给 Shape 实例挂载元数据方法(幂等:已有 setMeta 则跳过)。\n *\n * 所有产物构造点(solid/curve → fromBrep/fromMeshSolid/fromBrepCurve)统一\n * 调用本函数,保证 mesh/brep 双支路产物都可用 `box1.setName(...)`。\n * 方法**不序列化**(JSON 丢弃函数);`meta` 字段随产物跨打印,编辑器/\n * 查看器只读字段即可,不依赖方法。\n * @param shape 产物 Shape 实例(solid/curve 产物)\n * @returns 挂载后的 shape(类型提升为 `Shape & ShapeMetaMethods`;同一实例原地挂载)\n */\nexport function attachMetaMethods(shape: Shape): Shape & ShapeMetaMethods {\n const s = shape as Shape & ShapeMetaMethods\n if (typeof s.setMeta === 'function') return s\n s.setMeta = function setMeta(this: Shape & ShapeMetaMethods, spec: ShapeMeta) {\n this.meta = mergeMeta(this.meta, spec)\n return this\n }\n s.setName = function setName(this: Shape & ShapeMetaMethods, name: string) {\n this.meta = mergeMeta(this.meta, { name })\n return this\n }\n s.setDescription = function setDescription(this: Shape & ShapeMetaMethods, description: string) {\n this.meta = mergeMeta(this.meta, { description })\n return this\n }\n s.setPartNumber = function setPartNumber(this: Shape & ShapeMetaMethods, partNumber: string) {\n this.meta = mergeMeta(this.meta, { partNumber })\n return this\n }\n s.setMetaField = function setMetaField(this: Shape & ShapeMetaMethods, key: string, value: string) {\n this.meta = mergeMeta(this.meta, { metadata: { [key]: value } })\n return this\n }\n s.getMeta = function getMeta(this: Shape) {\n return this.meta\n }\n return s\n}"]}
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/api/meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api/meta — faijs 零件名称/描述/料号 与 整体文件元数据 权威类型与 Shape 方法\n *\n * 定位(与 api/appearance.ts 同款方法模式):\n * - 名称/描述设置**不是 op**(不进 defineOp/api-namespace/args-schema),是 Shape\n * 实例方法(`box1.setName('…')`,复用 `asm1.solve()` 的成员调用语句形态)。\n * - `ShapeMeta`(零件级)与 `FileMeta`(整体级)引擎无关、JSON 可序列化;\n * `Shape.meta` 随 Shape 走 mesh/brep 双链路,编辑器/查看器只读字段。\n * - 本文件零依赖(不 import THREE / occt / store);唯一 import 是 mesh/types\n * 的 `Shape` 类型(type-only),mesh/types 亦只 type-import 本文件的类型,\n * 两者为类型环、无运行时环(值依赖单向:shape.ts → api/meta.ts)。\n *\n * 命名约定(camelCase,faijs 全 TS/JS 生态):\n * - 零件级:`name` / `description` / `partNumber` / `metadata`(键值)。\n * - 方法:`setName` / `setDescription` / `setPartNumber` / `setMetaField` /\n * `setMeta` / `getMeta`。字段名与 3MF/STEP 规范一致(不用 note)。\n * 空串 = 清除:`setName('')` 删除 name(与「undefined 不覆盖」互补,用户可\n * 显式去掉继承来的名称)。\n */\n\nimport type { Shape } from '../mesh/types'\n\n// ── 类型 ──\n\n/** 零件级说明性元数据 —— 引擎无关、JSON 可序列化、随 Shape 走双链路。 */\nexport interface ShapeMeta {\n /** 零件名:3MF `<object name>` / STEP `PRODUCT().name`。 */\n name?: string\n /** 描述:STEP `PRODUCT.description`;3MF 写 `faijs:description` metadatagroup。 */\n description?: string\n /** 料号:3MF `<object partnumber>`;STEP `PRODUCT_IDENTIFICATION` 或 UDA。 */\n partNumber?: string\n /**\n * 自定义键值:3MF `<object><metadatagroup>`(vendor 前缀);STEP UDA。\n * 键为规范/厂商原始名(3MF 含命名空间前缀);faijs 不解释值语义,\n * 读入保留、写出回写。\n */\n metadata?: Record<string, string>\n}\n\n/**\n * 整体/文档级说明性元数据 —— 导入结果 / 导出选项,不挂 Shape。\n *\n * 不叫 `ModelMeta`:CAD 直觉里 \"model\" 偏单个零件(那是 `ShapeMeta` 的活);\n * 本类型承载整个交换文件(3MF `<model>` / STEP P21 header)的元数据,故用\n * `FileMeta`。\n */\nexport interface FileMeta {\n title?: string // 3MF Title / STEP FILE_NAME.name\n description?: string // 3MF Description / STEP FILE_DESCRIPTION.description\n designer?: string // 3MF Designer / STEP FILE_NAME.originator\n author?: string // STEP FILE_NAME.author(3MF 无对应;跨格式不互转)\n organization?: string // STEP FILE_NAME.organization(3MF 无对应)\n copyright?: string // 3MF Copyright(STEP 无标准位置)\n licenseTerms?: string // 3MF LicenseTerms(STEP 无标准位置)\n rating?: string // 3MF Rating(STEP 无标准位置)\n creationDate?: string // 3MF CreationDate / STEP FILE_NAME.timestamp\n modificationDate?: string // 3MF ModificationDate(STEP 无标准位置)\n application?: string // 3MF Application / STEP FILE_NAME.preprocessor\n /** 未知/厂商自定义 metadata 兜底(3MF model 级带前缀名;STEP header 其余字段)。 */\n metadata?: Record<string, string>\n}\n\n/** Shape 元数据方法签名(运行时由 attachMetaMethods 挂载;纯数据判定不受影响)。 */\nexport interface ShapeMetaMethods {\n /** 合并 meta:`{...cur, ...spec}`,spec 中 undefined 字段保留旧值。 */\n setMeta(spec: ShapeMeta): this\n /** 便捷:等价 setMeta({ name })(空串视为清除)。 */\n setName(name: string): this\n /** 便捷:等价 setMeta({ description })(空串视为清除)。 */\n setDescription(description: string): this\n /** 便捷:等价 setMeta({ partNumber })。 */\n setPartNumber(partNumber: string): this\n /** 便捷:等价 setMeta({ metadata: {...cur.metadata, ...kv} });值为空串的键删除。 */\n setMetaField(key: string, value: string): this\n /** 读取当前 meta(可能 undefined)。 */\n getMeta(): Readonly<ShapeMeta> | undefined\n}\n\n// ── 合并 ──\n\n/**\n * 合并零件级元数据:spec 中 undefined 字段不覆盖旧值;空串覆盖为清除。\n * @param cur 当前 meta(可为 undefined)\n * @param spec 待合并字段(undefined 字段跳过;'' 显式清除)\n * @returns 合并后的 meta(新对象;cur 为 undefined 时仅含 spec 非空字段)\n */\nexport function mergeMeta(cur: ShapeMeta | undefined, spec: ShapeMeta): ShapeMeta {\n const clean: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(spec)) {\n if (v === undefined) continue\n if (k === 'metadata' && v && typeof v === 'object') {\n // 键值子合并:保留旧 metadata 的未覆盖键。\n const base: Record<string, string> = { ...((cur?.metadata as Record<string, string> | undefined) ?? {}) }\n for (const [kk, vv] of Object.entries(v as Record<string, string>)) {\n if (vv === '') delete base[kk] // 空串清除该键\n else base[kk] = vv\n }\n clean[k] = base\n continue\n }\n if (v === '') clean[k] = undefined as unknown as string // 空串清除顶层字段\n else clean[k] = v\n }\n const merged = { ...(cur ?? {}), ...clean } as ShapeMeta\n // 清理合并后为 undefined 的顶层键(空串清除写入 undefined)。\n for (const k of Object.keys(merged)) {\n if ((merged as Record<string, unknown>)[k] === undefined) delete (merged as Record<string, unknown>)[k]\n }\n return merged\n}\n\n// ── Shape 方法挂载 ──\n\n/**\n * 给 Shape 实例挂载元数据方法(幂等:已有 setMeta 则跳过)。\n *\n * 所有产物构造点(solid/curve → fromBrep/fromMeshSolid/fromBrepCurve)统一\n * 调用本函数,保证 mesh/brep 双支路产物都可用 `box1.setName(...)`。\n * 方法**不序列化**(JSON 丢弃函数);`meta` 字段随产物跨打印,编辑器/\n * 查看器只读字段即可,不依赖方法。\n * @param shape 产物 Shape 实例(solid/curve 产物)\n * @returns 挂载后的 shape(类型提升为 `Shape & ShapeMetaMethods`;同一实例原地挂载)\n */\nexport function attachMetaMethods(shape: Shape): Shape & ShapeMetaMethods {\n const s = shape as Shape & ShapeMetaMethods\n if (typeof s.setMeta === 'function') return s\n s.setMeta = function setMeta(this: Shape & ShapeMetaMethods, spec: ShapeMeta) {\n this.meta = mergeMeta(this.meta, spec)\n return this\n }\n s.setName = function setName(this: Shape & ShapeMetaMethods, name: string) {\n this.meta = mergeMeta(this.meta, { name })\n return this\n }\n s.setDescription = function setDescription(this: Shape & ShapeMetaMethods, description: string) {\n this.meta = mergeMeta(this.meta, { description })\n return this\n }\n s.setPartNumber = function setPartNumber(this: Shape & ShapeMetaMethods, partNumber: string) {\n this.meta = mergeMeta(this.meta, { partNumber })\n return this\n }\n s.setMetaField = function setMetaField(this: Shape & ShapeMetaMethods, key: string, value: string) {\n this.meta = mergeMeta(this.meta, { metadata: { [key]: value } })\n return this\n }\n s.getMeta = function getMeta(this: Shape) {\n return this.meta\n }\n return s\n}"]}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * api offset2d — 2D 轮廓偏置(手写平台 op engines:['occt'])
3
+ *
4
+ * @platform occt — 实现直调 occt 原生 `offsetWire2D`(occt-wasm 有,L1 契约
5
+ * `brep/engine/primitives.ts` 无对应成员——brepkit 侧只有裸 wasm 的
6
+ * `offsetWire2DWithJoin`,未接进 adapter)⇒ 平台 op:defineOp 声明
7
+ * `engines: ['occt']`(D11)。
8
+ *
9
+ * 与 `offset`(3D 全表面偏置)的分工(方案 §4.5 去重表):
10
+ * - `offset` = **3D 实体**的面偏置(`BRepOffsetAPI_MakeThickSolid`),产实体;
11
+ * - `offset2d` = **2D 轮廓**(平面 wire)的法向偏置(`BRepOffsetAPI_MakeOffset`),
12
+ * 产**1D 轮廓**(OpenSCAD `offset()` 链路的几何前置)。
13
+ *
14
+ * 产物形态(同 sectionByPlane / helix):1D 轮廓经 `fromBrepCurve` 登记为
15
+ * `kind:'curve'`(wire/edge 三角载荷为空,显示走 L1 `wireframe`)。
16
+ */
17
+ import type { Shape } from '../mesh/types.js';
18
+ /** 拐角连接方式(映射 occt `JoinType`:Arc=0 / Tangent=1 / Intersection=2)。 */
19
+ export type Offset2DJoinType = 'arc' | 'tangent' | 'intersection';
20
+ /** `cad.offset2d` 参数。 */
21
+ export interface Offset2DOptions {
22
+ /**
23
+ * 拐角连接方式:`'arc'`(默认,圆弧插值)| `'tangent'`(切向延伸)|
24
+ * `'intersection'`(求交延伸)。
25
+ */
26
+ joinType?: Offset2DJoinType;
27
+ }
28
+ /**
29
+ * 2D 轮廓偏置:把平面轮廓(wire 或面)沿其法向等距偏移,产出新的 1D 轮廓。
30
+ * @group 特征
31
+ * @inputs 1
32
+ * @async true
33
+ * @qual ok
34
+ * @name offset2d
35
+ * @note 平台 op:仅 occt 引擎(原生 offsetWire2D,L1 契约无对应成员)。非 occt
36
+ * 引擎执行前报错;brep_mock 不拦截。`delta` 可正可负(正 = 外扩,
37
+ * 负 = 内缩,方向随 contour 走向);轮廓接受 wire 或面(面取其外环)。
38
+ * @returns Shape 1D 偏置轮廓(kind:'curve')。
39
+ * @param profile - 轮廓几何(wire;面取其外环)。type:Shape required:true
40
+ * @param delta - 偏置距离(mm)。type:number required:true
41
+ * @param options - 偏置配置(joinType)。type:Offset2DOptions required:false
42
+ * @example
43
+ * const c = cad.wire([[0,0,0],[10,0,0],[10,10,0],[0,10,0]], { closed: true })
44
+ * const outer = await cad.offset2d(c, 2)
45
+ */
46
+ export declare const offset2d: ((profile: Shape, delta: number, options?: Offset2DOptions | undefined) => Promise<Shape>) & {
47
+ __faijs__dualOp?: import("../define-op.js").DualOpMeta;
48
+ };
49
+ //# sourceMappingURL=offset2d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offset2d.d.ts","sourceRoot":"","sources":["../../src/api/offset2d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAU1C,qEAAqE;AACrE,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,SAAS,GAAG,cAAc,CAAA;AAEjE,yBAAyB;AACzB,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAA;CAC5B;AA0CD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,QAAQ;;CAQnB,CAAA"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * api offset2d — 2D 轮廓偏置(手写平台 op engines:['occt'])
3
+ *
4
+ * @platform occt — 实现直调 occt 原生 `offsetWire2D`(occt-wasm 有,L1 契约
5
+ * `brep/engine/primitives.ts` 无对应成员——brepkit 侧只有裸 wasm 的
6
+ * `offsetWire2DWithJoin`,未接进 adapter)⇒ 平台 op:defineOp 声明
7
+ * `engines: ['occt']`(D11)。
8
+ *
9
+ * 与 `offset`(3D 全表面偏置)的分工(方案 §4.5 去重表):
10
+ * - `offset` = **3D 实体**的面偏置(`BRepOffsetAPI_MakeThickSolid`),产实体;
11
+ * - `offset2d` = **2D 轮廓**(平面 wire)的法向偏置(`BRepOffsetAPI_MakeOffset`),
12
+ * 产**1D 轮廓**(OpenSCAD `offset()` 链路的几何前置)。
13
+ *
14
+ * 产物形态(同 sectionByPlane / helix):1D 轮廓经 `fromBrepCurve` 登记为
15
+ * `kind:'curve'`(wire/edge 三角载荷为空,显示走 L1 `wireframe`)。
16
+ */
17
+ import { solidToShape } from '../brep/brep-ops.js';
18
+ import { getBrepApi } from '../brep/handle-bridge.js';
19
+ import { fromBrepCurve } from '../shape.js';
20
+ import { defineOp } from '../sdk.js';
21
+ import { getOcctKernel } from '../occt-kernel/occtKernel.js';
22
+ import { toProfileWireView } from './internal/profile-wire.js';
23
+ /** JoinType 字符串 → occt 枚举值。 */
24
+ const JOIN_TYPE_CODE = {
25
+ arc: 0,
26
+ tangent: 1,
27
+ intersection: 2,
28
+ };
29
+ /** BREP 路径:occt offsetWire2D → 1D 轮廓经 fromBrepCurve 登记。 */
30
+ function offset2dBrep(profile, delta, options) {
31
+ if (!profile) {
32
+ throw new Error('E_OFFSET2D_NO_PROFILE: offset2d requires a profile (wire or face) shape');
33
+ }
34
+ if (typeof delta !== 'number' || !Number.isFinite(delta)) {
35
+ throw new Error('E_OFFSET2D_BAD_DELTA: delta must be a finite number');
36
+ }
37
+ const joinType = options?.joinType ?? 'arc';
38
+ const joinCode = JOIN_TYPE_CODE[joinType];
39
+ if (joinCode === undefined) {
40
+ throw new Error(`E_OFFSET2D_BAD_JOIN: joinType must be 'arc' | 'tangent' | 'intersection' (got '${String(joinType)}')`);
41
+ }
42
+ const kernel = getBrepApi();
43
+ // 轮廓:wire 直用;面取外环(与 sweep/loft 共用唯一步径)。
44
+ const wire = toProfileWireView(profile);
45
+ try {
46
+ const handle = getOcctKernel().offsetWire2D(wire.wrapped, delta, joinCode);
47
+ return fromBrepCurve(solidToShape(kernel, handle), { solid: handle });
48
+ }
49
+ finally {
50
+ // 面→外环产出的 wire 是 arena 新句柄;曲线借用不 release。
51
+ if (!wire.borrowed) {
52
+ try {
53
+ kernel.release(wire.wrapped);
54
+ }
55
+ catch { /* 已释放 */ }
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * 2D 轮廓偏置:把平面轮廓(wire 或面)沿其法向等距偏移,产出新的 1D 轮廓。
61
+ * @group 特征
62
+ * @inputs 1
63
+ * @async true
64
+ * @qual ok
65
+ * @name offset2d
66
+ * @note 平台 op:仅 occt 引擎(原生 offsetWire2D,L1 契约无对应成员)。非 occt
67
+ * 引擎执行前报错;brep_mock 不拦截。`delta` 可正可负(正 = 外扩,
68
+ * 负 = 内缩,方向随 contour 走向);轮廓接受 wire 或面(面取其外环)。
69
+ * @returns Shape 1D 偏置轮廓(kind:'curve')。
70
+ * @param profile - 轮廓几何(wire;面取其外环)。type:Shape required:true
71
+ * @param delta - 偏置距离(mm)。type:number required:true
72
+ * @param options - 偏置配置(joinType)。type:Offset2DOptions required:false
73
+ * @example
74
+ * const c = cad.wire([[0,0,0],[10,0,0],[10,10,0],[0,10,0]], { closed: true })
75
+ * const outer = await cad.offset2d(c, 2)
76
+ */
77
+ export const offset2d = defineOp({
78
+ name: 'offset2d',
79
+ paramDims: { delta: 'length' },
80
+ brep(profile, delta, options) {
81
+ return offset2dBrep(profile, delta, options);
82
+ },
83
+ engines: ['occt'],
84
+ naming: { kind: 'unmodeled', reason: '1D offset contour has no face role vocabulary' },
85
+ });
86
+ //# sourceMappingURL=offset2d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offset2d.js","sourceRoot":"","sources":["../../src/api/offset2d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAc3D,+BAA+B;AAC/B,MAAM,cAAc,GAAqC;IACvD,GAAG,EAAE,CAAC;IACN,OAAO,EAAE,CAAC;IACV,YAAY,EAAE,CAAC;CAChB,CAAA;AAED,2DAA2D;AAC3D,SAAS,YAAY,CAAC,OAAc,EAAE,KAAa,EAAE,OAAyB;IAC5E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAA;IAC5F,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;IACxE,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAA;IAC3C,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACzC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,kFAAkF,MAAM,CAAC,QAAQ,CAAC,IAAI,CACvG,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,wCAAwC;IACxC,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC,YAAY,CACzC,IAAI,CAAC,OAAgB,EACrB,KAAK,EACL,QAAiB,CACO,CAAA;QAC1B,OAAO,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC;YAAS,CAAC;QACT,0CAA0C;QAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC;gBAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC/B,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC9B,IAAI,CAAC,OAAc,EAAE,KAAa,EAAE,OAAyB;QAC3D,OAAO,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,CAAC;IACjB,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,+CAA+C,EAAgB;CACrG,CAAC,CAAA","sourcesContent":["/**\n * api offset2d — 2D 轮廓偏置(手写平台 op engines:['occt'])\n *\n * @platform occt — 实现直调 occt 原生 `offsetWire2D`(occt-wasm 有,L1 契约\n * `brep/engine/primitives.ts` 无对应成员——brepkit 侧只有裸 wasm 的\n * `offsetWire2DWithJoin`,未接进 adapter)⇒ 平台 op:defineOp 声明\n * `engines: ['occt']`(D11)。\n *\n * 与 `offset`(3D 全表面偏置)的分工(方案 §4.5 去重表):\n * - `offset` = **3D 实体**的面偏置(`BRepOffsetAPI_MakeThickSolid`),产实体;\n * - `offset2d` = **2D 轮廓**(平面 wire)的法向偏置(`BRepOffsetAPI_MakeOffset`),\n * 产**1D 轮廓**(OpenSCAD `offset()` 链路的几何前置)。\n *\n * 产物形态(同 sectionByPlane / helix):1D 轮廓经 `fromBrepCurve` 登记为\n * `kind:'curve'`(wire/edge 三角载荷为空,显示走 L1 `wireframe`)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrepCurve } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { getOcctKernel } from '../occt-kernel/occtKernel'\nimport { toProfileWireView } from './internal/profile-wire'\n\n/** 拐角连接方式(映射 occt `JoinType`:Arc=0 / Tangent=1 / Intersection=2)。 */\nexport type Offset2DJoinType = 'arc' | 'tangent' | 'intersection'\n\n/** `cad.offset2d` 参数。 */\nexport interface Offset2DOptions {\n /**\n * 拐角连接方式:`'arc'`(默认,圆弧插值)| `'tangent'`(切向延伸)|\n * `'intersection'`(求交延伸)。\n */\n joinType?: Offset2DJoinType\n}\n\n/** JoinType 字符串 → occt 枚举值。 */\nconst JOIN_TYPE_CODE: Record<Offset2DJoinType, number> = {\n arc: 0,\n tangent: 1,\n intersection: 2,\n}\n\n/** BREP 路径:occt offsetWire2D → 1D 轮廓经 fromBrepCurve 登记。 */\nfunction offset2dBrep(profile: Shape, delta: number, options?: Offset2DOptions): Shape {\n if (!profile) {\n throw new Error('E_OFFSET2D_NO_PROFILE: offset2d requires a profile (wire or face) shape')\n }\n if (typeof delta !== 'number' || !Number.isFinite(delta)) {\n throw new Error('E_OFFSET2D_BAD_DELTA: delta must be a finite number')\n }\n const joinType = options?.joinType ?? 'arc'\n const joinCode = JOIN_TYPE_CODE[joinType]\n if (joinCode === undefined) {\n throw new Error(\n `E_OFFSET2D_BAD_JOIN: joinType must be 'arc' | 'tangent' | 'intersection' (got '${String(joinType)}')`,\n )\n }\n const kernel = getBrepApi()\n // 轮廓:wire 直用;面取外环(与 sweep/loft 共用唯一步径)。\n const wire = toProfileWireView(profile)\n try {\n const handle = getOcctKernel().offsetWire2D(\n wire.wrapped as never,\n delta,\n joinCode as never,\n ) as unknown as BrepHandle\n return fromBrepCurve(solidToShape(kernel, handle), { solid: handle })\n } finally {\n // 面→外环产出的 wire 是 arena 新句柄;曲线借用不 release。\n if (!wire.borrowed) {\n try { kernel.release(wire.wrapped) } catch { /* 已释放 */ }\n }\n }\n}\n\n/**\n * 2D 轮廓偏置:把平面轮廓(wire 或面)沿其法向等距偏移,产出新的 1D 轮廓。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name offset2d\n * @note 平台 op:仅 occt 引擎(原生 offsetWire2D,L1 契约无对应成员)。非 occt\n * 引擎执行前报错;brep_mock 不拦截。`delta` 可正可负(正 = 外扩,\n * 负 = 内缩,方向随 contour 走向);轮廓接受 wire 或面(面取其外环)。\n * @returns Shape 1D 偏置轮廓(kind:'curve')。\n * @param profile - 轮廓几何(wire;面取其外环)。type:Shape required:true\n * @param delta - 偏置距离(mm)。type:number required:true\n * @param options - 偏置配置(joinType)。type:Offset2DOptions required:false\n * @example\n * const c = cad.wire([[0,0,0],[10,0,0],[10,10,0],[0,10,0]], { closed: true })\n * const outer = await cad.offset2d(c, 2)\n */\nexport const offset2d = defineOp({\n name: 'offset2d',\n paramDims: { delta: 'length' },\n brep(profile: Shape, delta: number, options?: Offset2DOptions) {\n return offset2dBrep(profile, delta, options)\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: '1D offset contour has no face role vocabulary' } as Provenance,\n})\n"]}
@@ -9,7 +9,7 @@
9
9
  * 倍数即得 k;再按「面内坐标」(centroid − t·dir)匹配输入面对应面,回投其 inner role。
10
10
  */
11
11
  import { solidToShape } from '../brep/brep-ops.js';
12
- import { getCurrentStmt, keep } from '../runtime-state.js';
12
+ import { getCurrentStmt, keepHidden } from '../runtime-state.js';
13
13
  import { getBrepApi } from '../brep/handle-bridge.js';
14
14
  import { fromBrep, brepOf } from '../shape.js';
15
15
  import { defineOp } from '../sdk.js';
@@ -94,14 +94,14 @@ function linearPatternMeshSolid(input, direction, count, spacing) {
94
94
  export const linearPattern = defineOp({
95
95
  meshEngines: ['brepkit'],
96
96
  mesh(input, direction, count, spacing) {
97
- keep(input);
97
+ keepHidden(input);
98
98
  // 裸网格输入由 `meshSolidBasicEntry` 如实拒绝(近似链没有 role 层,也没有句柄)——
99
99
  // 这里不复刻一遍判定,失败面只有一处。
100
100
  return linearPatternMeshSolid(input, direction, count, spacing);
101
101
  },
102
102
  brep(input, direction, count, spacing) {
103
103
  // copy-like keep semantics: replicate ops preserve their source shape.
104
- keep(input);
104
+ keepHidden(input);
105
105
  return linearPatternBrep(input, direction, count, spacing);
106
106
  },
107
107
  // Phase 1(Brep 引擎可切换重构):能力前置判定——linearPattern 需要内核的
@@ -1 +1 @@
1
- {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/api/pattern.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api pattern — linearPattern(手写覆盖生成投影,Phase 3: L3 `replica[k]` 角色表)\n *\n * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径\n * 用质心聚类把结果面按份数 k 分组、回投影到输入面角色,产出 `replica[k]/<inner>`。\n *\n * 机制(无内核历史,纯几何推理):pattern 的每份副本都是输入的精确平移,副本面\n * 几何相同但质心不同。结果面沿 pattern 方向投影得到份数坐标 t,四舍五入到 spacing\n * 倍数即得 k;再按「面内坐标」(centroid − t·dir)匹配输入面对应面,回投其 inner role。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getCurrentStmt, keep } from '../runtime-state'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { buildReplicaRoleTable, type ReplicaTransform } from './internal/replica-role-table'\nimport { meshPatternProduct, meshSolidBasicEntry } from './internal/mesh-solid-op'\n\n/** 归一化向量(零向量 → [0,0,1] 兜底)。 */\nfunction norm(v: Vec3): [number, number, number] {\n const len = Math.hypot(v[0], v[1], v[2])\n if (len < 1e-9) return [0, 0, 1]\n return [v[0] / len, v[1] / len, v[2] / len]\n}\n\n/** BREP 路径:沿 direction 复制 count 份,质心聚类回投输入面角色。 */\nfunction linearPatternBrep(input: Shape, direction: Vec3, count: number, spacing: number): Shape {\n const kernel = getBrepApi()\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[api/pattern] input is not BREP')\n\n // Phase 1.6:origin = 本次语句 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n\n // 取 count 份副本。Phase 2:BrepEngineApi.linearPattern 契约统一返回 BrepHandle[]\n // (两内核原生都返回 compound,由适配器拆成数组)——不再有「单句柄 fused」形态。\n const dir = norm(direction)\n const raw = kernel.linearPattern(inputSolid, { x: dir[0], y: dir[1], z: dir[2] }, spacing, count)\n\n let resultSolid: BrepHandle\n try {\n resultSolid = kernel.fuseAll(raw)\n } finally {\n for (const c of raw) kernel.release(c)\n }\n\n // 第 k 份副本是输入沿 dir 平移 k*spacing:质心反投回输入坐标系(T_k⁻¹)。\n const replicas: ReplicaTransform[] = []\n for (let k = 0; k < count; k++) {\n const off = k * spacing\n replicas.push({\n label: `replica[${k}]`,\n inverse: (c) => ({ x: c.x - off * dir[0], y: c.y - off * dir[1], z: c.z - off * dir[2] }),\n })\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n}\n\n/**\n * 网格实体路径:沿 direction 阵列并把副本融成一个网格零件。\n *\n * 与 BREP 路径同一条内核契约(`linearPattern` 返回含原位置在内的 count 个句柄,\n * 再 `fuseAll` 成一体),差别只在**没有 quality 面角色可回投**——近似拓扑没有 role\n * 层,故不产 `replica[k]/<inner>` 命名(如实缺席,不伪造恒等映射)。\n *\n * @param input - the mesh-solid input.\n * @param direction - the pattern direction.\n * @param count - total number of copies (including the original).\n * @param spacing - the spacing between copies.\n * @returns the fused mesh solid as a new mesh part.\n */\nfunction linearPatternMeshSolid(input: Shape, direction: Vec3, count: number, spacing: number): Shape {\n const entry = meshSolidBasicEntry(input, 'linearPattern')\n const d = norm(direction)\n return meshPatternProduct(entry, 'linearPattern', 'E_PATTERN_FAILED', () =>\n entry.kernel.linearPattern(entry.solid, { x: d[0], y: d[1], z: d[2] }, spacing, count),\n )\n}\n\n/**\n * 线性阵列:沿 direction 复制 count 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name linearPattern\n * @note BREP 输入走质心聚类回投,结果面按份数 k 回投影到输入面角色,产出\n * `replica[k]/<inner>`(Phase 3 L3 抗重放词汇);**网格实体**输入走网格后端,\n * 阵列后融合为一个新的网格零件,近似拓扑没有 role 层故不产 replica 命名。\n * 裸网格输入仍抛 `E_MESH_UNSUPPORTED`。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param direction - 阵列方向。type:[x,y,z] required:true\n * @param count - 副本总数(含原位置)。type:number required:true\n * @param spacing - 副本间距。type:number required:true\n * @example\n * const p = await cad.linearPattern(part0, [1, 0, 0], 3, 20)\n */\nexport const linearPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, direction: Vec3, count: number, spacing: number) {\n keep(input)\n // 裸网格输入由 `meshSolidBasicEntry` 如实拒绝(近似链没有 role 层,也没有句柄)——\n // 这里不复刻一遍判定,失败面只有一处。\n return linearPatternMeshSolid(input, direction, count, spacing)\n },\n brep(input: Shape, direction: Vec3, count: number, spacing: number) {\n // copy-like keep semantics: replicate ops preserve their source shape.\n keep(input)\n return linearPatternBrep(input, direction, count, spacing)\n },\n // Phase 1(Brep 引擎可切换重构):能力前置判定——linearPattern 需要内核的\n // 线性阵列方法(BrepMethodKind),brepkit 装配下缺失时执行前静态报错。\n capabilities: ['linearPattern'],\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n"]}
1
+ {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/api/pattern.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api pattern — linearPattern(手写覆盖生成投影,Phase 3: L3 `replica[k]` 角色表)\n *\n * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径\n * 用质心聚类把结果面按份数 k 分组、回投影到输入面角色,产出 `replica[k]/<inner>`。\n *\n * 机制(无内核历史,纯几何推理):pattern 的每份副本都是输入的精确平移,副本面\n * 几何相同但质心不同。结果面沿 pattern 方向投影得到份数坐标 t,四舍五入到 spacing\n * 倍数即得 k;再按「面内坐标」(centroid − t·dir)匹配输入面对应面,回投其 inner role。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getCurrentStmt, keepHidden } from '../runtime-state'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { buildReplicaRoleTable, type ReplicaTransform } from './internal/replica-role-table'\nimport { meshPatternProduct, meshSolidBasicEntry } from './internal/mesh-solid-op'\n\n/** 归一化向量(零向量 → [0,0,1] 兜底)。 */\nfunction norm(v: Vec3): [number, number, number] {\n const len = Math.hypot(v[0], v[1], v[2])\n if (len < 1e-9) return [0, 0, 1]\n return [v[0] / len, v[1] / len, v[2] / len]\n}\n\n/** BREP 路径:沿 direction 复制 count 份,质心聚类回投输入面角色。 */\nfunction linearPatternBrep(input: Shape, direction: Vec3, count: number, spacing: number): Shape {\n const kernel = getBrepApi()\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[api/pattern] input is not BREP')\n\n // Phase 1.6:origin = 本次语句 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n\n // 取 count 份副本。Phase 2:BrepEngineApi.linearPattern 契约统一返回 BrepHandle[]\n // (两内核原生都返回 compound,由适配器拆成数组)——不再有「单句柄 fused」形态。\n const dir = norm(direction)\n const raw = kernel.linearPattern(inputSolid, { x: dir[0], y: dir[1], z: dir[2] }, spacing, count)\n\n let resultSolid: BrepHandle\n try {\n resultSolid = kernel.fuseAll(raw)\n } finally {\n for (const c of raw) kernel.release(c)\n }\n\n // 第 k 份副本是输入沿 dir 平移 k*spacing:质心反投回输入坐标系(T_k⁻¹)。\n const replicas: ReplicaTransform[] = []\n for (let k = 0; k < count; k++) {\n const off = k * spacing\n replicas.push({\n label: `replica[${k}]`,\n inverse: (c) => ({ x: c.x - off * dir[0], y: c.y - off * dir[1], z: c.z - off * dir[2] }),\n })\n }\n const roleTable = buildReplicaRoleTable(kernel, input, resultSolid, replicas, outStmt)\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n}\n\n/**\n * 网格实体路径:沿 direction 阵列并把副本融成一个网格零件。\n *\n * 与 BREP 路径同一条内核契约(`linearPattern` 返回含原位置在内的 count 个句柄,\n * 再 `fuseAll` 成一体),差别只在**没有 quality 面角色可回投**——近似拓扑没有 role\n * 层,故不产 `replica[k]/<inner>` 命名(如实缺席,不伪造恒等映射)。\n *\n * @param input - the mesh-solid input.\n * @param direction - the pattern direction.\n * @param count - total number of copies (including the original).\n * @param spacing - the spacing between copies.\n * @returns the fused mesh solid as a new mesh part.\n */\nfunction linearPatternMeshSolid(input: Shape, direction: Vec3, count: number, spacing: number): Shape {\n const entry = meshSolidBasicEntry(input, 'linearPattern')\n const d = norm(direction)\n return meshPatternProduct(entry, 'linearPattern', 'E_PATTERN_FAILED', () =>\n entry.kernel.linearPattern(entry.solid, { x: d[0], y: d[1], z: d[2] }, spacing, count),\n )\n}\n\n/**\n * 线性阵列:沿 direction 复制 count 份(含原位置)。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name linearPattern\n * @note BREP 输入走质心聚类回投,结果面按份数 k 回投影到输入面角色,产出\n * `replica[k]/<inner>`(Phase 3 L3 抗重放词汇);**网格实体**输入走网格后端,\n * 阵列后融合为一个新的网格零件,近似拓扑没有 role 层故不产 replica 命名。\n * 裸网格输入仍抛 `E_MESH_UNSUPPORTED`。\n * @returns Shape 所有副本 fused 后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param direction - 阵列方向。type:[x,y,z] required:true\n * @param count - 副本总数(含原位置)。type:number required:true\n * @param spacing - 副本间距。type:number required:true\n * @example\n * const p = await cad.linearPattern(part0, [1, 0, 0], 3, 20)\n */\nexport const linearPattern = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, direction: Vec3, count: number, spacing: number) {\n keepHidden(input)\n // 裸网格输入由 `meshSolidBasicEntry` 如实拒绝(近似链没有 role 层,也没有句柄)——\n // 这里不复刻一遍判定,失败面只有一处。\n return linearPatternMeshSolid(input, direction, count, spacing)\n },\n brep(input: Shape, direction: Vec3, count: number, spacing: number) {\n // copy-like keep semantics: replicate ops preserve their source shape.\n keepHidden(input)\n return linearPatternBrep(input, direction, count, spacing)\n },\n // Phase 1(Brep 引擎可切换重构):能力前置判定——linearPattern 需要内核的\n // 线性阵列方法(BrepMethodKind),brepkit 装配下缺失时执行前静态报错。\n capabilities: ['linearPattern'],\n naming: { kind: 'replicate', k: 0 } as Provenance,\n})\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/api/primitives.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAmB1C;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAS1E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUtE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKvE;AAyHD;;;;;;;;;;;;;;;;;;;;;;KAsBK;AACL,eAAO,MAAM,GAAG;;CAwBd,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,MAAM;;CAgBjB,CAAA;AAWF;;;;;;;;;;;;;;;;;;;;;;IAsBI;AACJ,eAAO,MAAM,QAAQ;;CAgBnB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;IAsBI;AACJ,eAAO,MAAM,IAAI;;CAuBf,CAAA;AAEF;;;;;;;;;;;;;;;;IAgBI;AACJ,eAAO,MAAM,KAAK;;CAchB,CAAA"}
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/api/primitives.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAoB1C;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAS1E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUtE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKvE;AAyHD;;;;;;;;;;;;;;;;;;;;;;KAsBK;AACL,eAAO,MAAM,GAAG;;CAwBd,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,MAAM;;CAgBjB,CAAA;AAWF;;;;;;;;;;;;;;;;;;;;;;IAsBI;AACJ,eAAO,MAAM,QAAQ;;CAgBnB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;IAsBI;AACJ,eAAO,MAAM,IAAI;;CAuBf,CAAA;AAEF;;;;;;;;;;;;;;;;IAgBI;AACJ,eAAO,MAAM,KAAK;;CAchB,CAAA"}