@faicad/faijs 0.16.1 → 0.18.0

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 (498) hide show
  1. package/LICENSE +4 -5
  2. package/NOTICE +5 -6
  3. package/dist/api/api-namespace.d.ts.map +1 -1
  4. package/dist/api/api-namespace.js +20 -2
  5. package/dist/api/api-namespace.js.map +1 -1
  6. package/dist/api/assembly/entities.d.ts +1 -1
  7. package/dist/api/assembly/entities.d.ts.map +1 -1
  8. package/dist/api/assembly/entities.js.map +1 -1
  9. package/dist/api/assembly/joints.d.ts +2 -2
  10. package/dist/api/assembly/joints.d.ts.map +1 -1
  11. package/dist/api/assembly/joints.js +2 -2
  12. package/dist/api/assembly/joints.js.map +1 -1
  13. package/dist/api/assembly/lower.d.ts +1 -1
  14. package/dist/api/assembly/lower.d.ts.map +1 -1
  15. package/dist/api/assembly/lower.js.map +1 -1
  16. package/dist/api/assembly/pose.d.ts +3 -3
  17. package/dist/api/assembly/pose.d.ts.map +1 -1
  18. package/dist/api/assembly/pose.js +1 -1
  19. package/dist/api/assembly/pose.js.map +1 -1
  20. package/dist/api/assembly/preview.d.ts +1 -1
  21. package/dist/api/assembly/preview.d.ts.map +1 -1
  22. package/dist/api/assembly/preview.js +1 -1
  23. package/dist/api/assembly/preview.js.map +1 -1
  24. package/dist/api/assembly/solve.d.ts.map +1 -1
  25. package/dist/api/assembly/solve.js +3 -3
  26. package/dist/api/assembly/solve.js.map +1 -1
  27. package/dist/api/assembly/solvers/assembly-tree.d.ts +98 -0
  28. package/dist/api/assembly/solvers/assembly-tree.d.ts.map +1 -0
  29. package/dist/api/assembly/solvers/assembly-tree.js +130 -0
  30. package/dist/api/assembly/solvers/assembly-tree.js.map +1 -0
  31. package/dist/api/assembly/solvers/chain-solver.d.ts +27 -0
  32. package/dist/api/assembly/solvers/chain-solver.d.ts.map +1 -0
  33. package/dist/api/assembly/solvers/chain-solver.js +330 -0
  34. package/dist/api/assembly/solvers/chain-solver.js.map +1 -0
  35. package/dist/api/assembly/solvers/global-solver.js +2 -2
  36. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  37. package/dist/api/assembly/solvers/joints-kinematics.d.ts +308 -0
  38. package/dist/api/assembly/solvers/joints-kinematics.d.ts.map +1 -0
  39. package/dist/api/assembly/solvers/joints-kinematics.js +643 -0
  40. package/dist/api/assembly/solvers/joints-kinematics.js.map +1 -0
  41. package/dist/api/assembly/solvers/quat.d.ts +35 -0
  42. package/dist/api/assembly/solvers/quat.d.ts.map +1 -0
  43. package/dist/api/assembly/solvers/quat.js +84 -0
  44. package/dist/api/assembly/solvers/quat.js.map +1 -0
  45. package/dist/api/assembly/solvers/types.d.ts +33 -0
  46. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  47. package/dist/api/assembly/solvers/types.js.map +1 -1
  48. package/dist/api/boolean.d.ts.map +1 -1
  49. package/dist/api/boolean.js +66 -29
  50. package/dist/api/boolean.js.map +1 -1
  51. package/dist/api/brep-mirror/booleanFns.d.ts +40 -0
  52. package/dist/api/brep-mirror/booleanFns.d.ts.map +1 -0
  53. package/dist/api/brep-mirror/booleanFns.js +104 -0
  54. package/dist/api/brep-mirror/booleanFns.js.map +1 -0
  55. package/dist/api/brep-mirror/brepHelpers.d.ts +55 -0
  56. package/dist/api/brep-mirror/brepHelpers.d.ts.map +1 -0
  57. package/dist/api/brep-mirror/brepHelpers.js +131 -0
  58. package/dist/api/brep-mirror/brepHelpers.js.map +1 -0
  59. package/dist/api/brep-mirror/compoundFns.d.ts +47 -0
  60. package/dist/api/brep-mirror/compoundFns.d.ts.map +1 -0
  61. package/dist/api/brep-mirror/compoundFns.js +300 -0
  62. package/dist/api/brep-mirror/compoundFns.js.map +1 -0
  63. package/dist/api/brep-mirror/healingFns.d.ts +78 -0
  64. package/dist/api/brep-mirror/healingFns.d.ts.map +1 -0
  65. package/dist/api/brep-mirror/healingFns.js +294 -0
  66. package/dist/api/brep-mirror/healingFns.js.map +1 -0
  67. package/dist/api/brep-mirror/hullFns.d.ts +20 -0
  68. package/dist/api/brep-mirror/hullFns.d.ts.map +1 -0
  69. package/dist/api/brep-mirror/hullFns.js +46 -0
  70. package/dist/api/brep-mirror/hullFns.js.map +1 -0
  71. package/dist/api/brep-mirror/patternFns.d.ts +43 -0
  72. package/dist/api/brep-mirror/patternFns.d.ts.map +1 -0
  73. package/dist/api/brep-mirror/patternFns.js +178 -0
  74. package/dist/api/brep-mirror/patternFns.js.map +1 -0
  75. package/dist/api/brep-mirror/primitiveFns.d.ts +42 -0
  76. package/dist/api/brep-mirror/primitiveFns.d.ts.map +1 -0
  77. package/dist/api/brep-mirror/primitiveFns.js +104 -0
  78. package/dist/api/brep-mirror/primitiveFns.js.map +1 -0
  79. package/dist/api/brep-mirror/roofFns.d.ts +24 -0
  80. package/dist/api/brep-mirror/roofFns.d.ts.map +1 -0
  81. package/dist/api/brep-mirror/roofFns.js +229 -0
  82. package/dist/api/brep-mirror/roofFns.js.map +1 -0
  83. package/dist/api/brep-mirror/straightSkeleton.d.ts +36 -0
  84. package/dist/api/brep-mirror/straightSkeleton.d.ts.map +1 -0
  85. package/dist/api/brep-mirror/straightSkeleton.js +443 -0
  86. package/dist/api/brep-mirror/straightSkeleton.js.map +1 -0
  87. package/dist/api/brep-mirror/sweepFns.d.ts +55 -0
  88. package/dist/api/brep-mirror/sweepFns.d.ts.map +1 -0
  89. package/dist/api/brep-mirror/sweepFns.js +200 -0
  90. package/dist/api/brep-mirror/sweepFns.js.map +1 -0
  91. package/dist/api/brep-mirror/threadFns.d.ts +15 -0
  92. package/dist/api/brep-mirror/threadFns.d.ts.map +1 -1
  93. package/dist/api/brep-mirror/threadFns.js +37 -2
  94. package/dist/api/brep-mirror/threadFns.js.map +1 -1
  95. package/dist/api/brep-mirror/topologyFns.d.ts +74 -0
  96. package/dist/api/brep-mirror/topologyFns.d.ts.map +1 -0
  97. package/dist/api/brep-mirror/topologyFns.js +276 -0
  98. package/dist/api/brep-mirror/topologyFns.js.map +1 -0
  99. package/dist/api/brep-topology.d.ts +190 -0
  100. package/dist/api/brep-topology.d.ts.map +1 -0
  101. package/dist/api/brep-topology.js +337 -0
  102. package/dist/api/brep-topology.js.map +1 -0
  103. package/dist/api/brepjs-compat/constants.d.ts +11 -0
  104. package/dist/api/brepjs-compat/constants.d.ts.map +1 -0
  105. package/dist/api/brepjs-compat/constants.js +11 -0
  106. package/dist/api/brepjs-compat/constants.js.map +1 -0
  107. package/dist/api/brepjs-compat/index.d.ts +19 -232
  108. package/dist/api/brepjs-compat/index.d.ts.map +1 -1
  109. package/dist/api/brepjs-compat/index.js +19 -286
  110. package/dist/api/brepjs-compat/index.js.map +1 -1
  111. package/dist/api/brepjs-compat/planeOps.d.ts +98 -0
  112. package/dist/api/brepjs-compat/planeOps.d.ts.map +1 -0
  113. package/dist/api/brepjs-compat/planeOps.js +170 -0
  114. package/dist/api/brepjs-compat/planeOps.js.map +1 -0
  115. package/dist/api/brepjs-compat/planeTypes.d.ts +24 -0
  116. package/dist/api/brepjs-compat/planeTypes.d.ts.map +1 -0
  117. package/dist/api/brepjs-compat/planeTypes.js +8 -0
  118. package/dist/api/brepjs-compat/planeTypes.js.map +1 -0
  119. package/dist/api/brepjs-compat/types.d.ts +64 -0
  120. package/dist/api/brepjs-compat/types.d.ts.map +1 -0
  121. package/dist/api/brepjs-compat/types.js +48 -0
  122. package/dist/api/brepjs-compat/types.js.map +1 -0
  123. package/dist/api/brepjs-compat/vecOps.d.ts +124 -0
  124. package/dist/api/brepjs-compat/vecOps.d.ts.map +1 -0
  125. package/dist/api/brepjs-compat/vecOps.js +202 -0
  126. package/dist/api/brepjs-compat/vecOps.js.map +1 -0
  127. package/dist/api/chamfer.d.ts +12 -3
  128. package/dist/api/chamfer.d.ts.map +1 -1
  129. package/dist/api/chamfer.js +54 -20
  130. package/dist/api/chamfer.js.map +1 -1
  131. package/dist/api/compound-geom.d.ts.map +1 -1
  132. package/dist/api/compound-geom.js +8 -2
  133. package/dist/api/compound-geom.js.map +1 -1
  134. package/dist/api/draft.d.ts +69 -0
  135. package/dist/api/draft.d.ts.map +1 -0
  136. package/dist/api/draft.js +109 -0
  137. package/dist/api/draft.js.map +1 -0
  138. package/dist/api/edge-ref.d.ts.map +1 -1
  139. package/dist/api/edge-ref.js +2 -2
  140. package/dist/api/edge-ref.js.map +1 -1
  141. package/dist/api/engrave.d.ts.map +1 -1
  142. package/dist/api/engrave.js +2 -3
  143. package/dist/api/engrave.js.map +1 -1
  144. package/dist/api/extrude.d.ts.map +1 -1
  145. package/dist/api/extrude.js +44 -14
  146. package/dist/api/extrude.js.map +1 -1
  147. package/dist/api/face-ref.d.ts.map +1 -1
  148. package/dist/api/face-ref.js +2 -2
  149. package/dist/api/face-ref.js.map +1 -1
  150. package/dist/api/feature-repair.d.ts +137 -0
  151. package/dist/api/feature-repair.d.ts.map +1 -0
  152. package/dist/api/feature-repair.js +221 -0
  153. package/dist/api/feature-repair.js.map +1 -0
  154. package/dist/api/fillet-variable.d.ts +35 -0
  155. package/dist/api/fillet-variable.d.ts.map +1 -0
  156. package/dist/api/fillet-variable.js +71 -0
  157. package/dist/api/fillet-variable.js.map +1 -0
  158. package/dist/api/fillet.d.ts +3 -0
  159. package/dist/api/fillet.d.ts.map +1 -1
  160. package/dist/api/fillet.js +7 -4
  161. package/dist/api/fillet.js.map +1 -1
  162. package/dist/api/generated/2d.d.ts +1 -13
  163. package/dist/api/generated/2d.d.ts.map +1 -1
  164. package/dist/api/generated/2d.js +6 -1
  165. package/dist/api/generated/2d.js.map +1 -1
  166. package/dist/api/generated/brepjs/index.d.ts +298 -298
  167. package/dist/api/generated/brepjs/index.d.ts.map +1 -1
  168. package/dist/api/generated/brepjs/index.js +183 -183
  169. package/dist/api/generated/brepjs/index.js.map +1 -1
  170. package/dist/api/generated/core.d.ts +3 -123
  171. package/dist/api/generated/core.d.ts.map +1 -1
  172. package/dist/api/generated/core.js +2 -81
  173. package/dist/api/generated/core.js.map +1 -1
  174. package/dist/api/generated/gear.d.ts +1 -15
  175. package/dist/api/generated/gear.d.ts.map +1 -1
  176. package/dist/api/generated/gear.js +6 -3
  177. package/dist/api/generated/gear.js.map +1 -1
  178. package/dist/api/generated/io.d.ts +1 -13
  179. package/dist/api/generated/io.d.ts.map +1 -1
  180. package/dist/api/generated/io.js +6 -1
  181. package/dist/api/generated/io.js.map +1 -1
  182. package/dist/api/generated/kernel.d.ts +1 -39
  183. package/dist/api/generated/kernel.d.ts.map +1 -1
  184. package/dist/api/generated/kernel.js +6 -4
  185. package/dist/api/generated/kernel.js.map +1 -1
  186. package/dist/api/generated/measurement.d.ts +53 -97
  187. package/dist/api/generated/measurement.d.ts.map +1 -1
  188. package/dist/api/generated/measurement.js +48 -143
  189. package/dist/api/generated/measurement.js.map +1 -1
  190. package/dist/api/generated/ns.d.ts +1 -10
  191. package/dist/api/generated/ns.d.ts.map +1 -1
  192. package/dist/api/generated/ns.js +2 -10
  193. package/dist/api/generated/ns.js.map +1 -1
  194. package/dist/api/generated/operations.d.ts +65 -110
  195. package/dist/api/generated/operations.d.ts.map +1 -1
  196. package/dist/api/generated/operations.js +132 -80
  197. package/dist/api/generated/operations.js.map +1 -1
  198. package/dist/api/generated/projection.d.ts +1 -8
  199. package/dist/api/generated/projection.d.ts.map +1 -1
  200. package/dist/api/generated/projection.js +6 -4
  201. package/dist/api/generated/projection.js.map +1 -1
  202. package/dist/api/generated/query.d.ts +1 -9
  203. package/dist/api/generated/query.d.ts.map +1 -1
  204. package/dist/api/generated/query.js +6 -1
  205. package/dist/api/generated/query.js.map +1 -1
  206. package/dist/api/generated/script-face-manifest.d.ts +2 -0
  207. package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
  208. package/dist/api/generated/script-face-manifest.js +22 -10
  209. package/dist/api/generated/script-face-manifest.js.map +1 -1
  210. package/dist/api/generated/script-face.d.ts +52 -27
  211. package/dist/api/generated/script-face.d.ts.map +1 -1
  212. package/dist/api/generated/script-face.js +18 -4
  213. package/dist/api/generated/script-face.js.map +1 -1
  214. package/dist/api/generated/sketching.d.ts +4 -7
  215. package/dist/api/generated/sketching.d.ts.map +1 -1
  216. package/dist/api/generated/sketching.js +10 -8
  217. package/dist/api/generated/sketching.js.map +1 -1
  218. package/dist/api/generated/text.d.ts +1 -6
  219. package/dist/api/generated/text.d.ts.map +1 -1
  220. package/dist/api/generated/text.js +6 -3
  221. package/dist/api/generated/text.js.map +1 -1
  222. package/dist/api/generated/topology.d.ts +77 -175
  223. package/dist/api/generated/topology.d.ts.map +1 -1
  224. package/dist/api/generated/topology.js +172 -131
  225. package/dist/api/generated/topology.js.map +1 -1
  226. package/dist/api/geom.d.ts.map +1 -1
  227. package/dist/api/geom.js +2 -2
  228. package/dist/api/geom.js.map +1 -1
  229. package/dist/api/helix.d.ts +51 -0
  230. package/dist/api/helix.d.ts.map +1 -0
  231. package/dist/api/helix.js +63 -0
  232. package/dist/api/helix.js.map +1 -0
  233. package/dist/api/import-step.d.ts.map +1 -1
  234. package/dist/api/import-step.js +6 -2
  235. package/dist/api/import-step.js.map +1 -1
  236. package/dist/api/index.d.ts +20 -6
  237. package/dist/api/index.d.ts.map +1 -1
  238. package/dist/api/index.js +30 -13
  239. package/dist/api/index.js.map +1 -1
  240. package/dist/api/internal/compat-op.d.ts +10 -0
  241. package/dist/api/internal/compat-op.d.ts.map +1 -1
  242. package/dist/api/internal/compat-op.js +9 -3
  243. package/dist/api/internal/compat-op.js.map +1 -1
  244. package/dist/api/internal/compat-projection.d.ts +4 -4
  245. package/dist/api/internal/compat-projection.js +7 -7
  246. package/dist/api/internal/compat-projection.js.map +1 -1
  247. package/dist/api/internal/l3-bridge.d.ts +75 -42
  248. package/dist/api/internal/l3-bridge.d.ts.map +1 -1
  249. package/dist/api/internal/l3-bridge.js +105 -50
  250. package/dist/api/internal/l3-bridge.js.map +1 -1
  251. package/dist/api/internal/profile-wire.d.ts +31 -0
  252. package/dist/api/internal/profile-wire.d.ts.map +1 -0
  253. package/dist/api/internal/profile-wire.js +37 -0
  254. package/dist/api/internal/profile-wire.js.map +1 -0
  255. package/dist/api/internal/replica-role-table.js +2 -2
  256. package/dist/api/internal/replica-role-table.js.map +1 -1
  257. package/dist/api/loft.d.ts +66 -0
  258. package/dist/api/loft.d.ts.map +1 -0
  259. package/dist/api/loft.js +111 -0
  260. package/dist/api/loft.js.map +1 -0
  261. package/dist/api/measurement/index.d.ts +51 -0
  262. package/dist/api/measurement/index.d.ts.map +1 -0
  263. package/dist/api/measurement/index.js +71 -0
  264. package/dist/api/measurement/index.js.map +1 -0
  265. package/dist/api/occt-kernel-bridge.d.ts +5 -8
  266. package/dist/api/occt-kernel-bridge.d.ts.map +1 -1
  267. package/dist/api/occt-kernel-bridge.js +18 -14
  268. package/dist/api/occt-kernel-bridge.js.map +1 -1
  269. package/dist/api/pattern.d.ts.map +1 -1
  270. package/dist/api/pattern.js +3 -4
  271. package/dist/api/pattern.js.map +1 -1
  272. package/dist/api/place.d.ts.map +1 -1
  273. package/dist/api/place.js +2 -4
  274. package/dist/api/place.js.map +1 -1
  275. package/dist/api/primitives.d.ts.map +1 -1
  276. package/dist/api/primitives.js +3 -4
  277. package/dist/api/primitives.js.map +1 -1
  278. package/dist/api/profile.d.ts +89 -0
  279. package/dist/api/profile.d.ts.map +1 -0
  280. package/dist/api/profile.js +194 -0
  281. package/dist/api/profile.js.map +1 -0
  282. package/dist/api/replicate.d.ts +28 -1
  283. package/dist/api/replicate.d.ts.map +1 -1
  284. package/dist/api/replicate.js +34 -23
  285. package/dist/api/replicate.js.map +1 -1
  286. package/dist/api/result.d.ts +6 -11
  287. package/dist/api/result.d.ts.map +1 -1
  288. package/dist/api/result.js +6 -11
  289. package/dist/api/result.js.map +1 -1
  290. package/dist/api/revolve.d.ts.map +1 -1
  291. package/dist/api/revolve.js +15 -14
  292. package/dist/api/revolve.js.map +1 -1
  293. package/dist/api/screw.d.ts +3 -0
  294. package/dist/api/screw.d.ts.map +1 -1
  295. package/dist/api/screw.js +9 -4
  296. package/dist/api/screw.js.map +1 -1
  297. package/dist/api/sdf.d.ts +1 -1
  298. package/dist/api/section-by-plane.d.ts +42 -0
  299. package/dist/api/section-by-plane.d.ts.map +1 -0
  300. package/dist/api/section-by-plane.js +61 -0
  301. package/dist/api/section-by-plane.js.map +1 -0
  302. package/dist/api/shell.d.ts +45 -0
  303. package/dist/api/shell.d.ts.map +1 -0
  304. package/dist/api/shell.js +73 -0
  305. package/dist/api/shell.js.map +1 -0
  306. package/dist/api/sketch.d.ts +8 -1
  307. package/dist/api/sketch.d.ts.map +1 -1
  308. package/dist/api/sketch.js +12 -7
  309. package/dist/api/sketch.js.map +1 -1
  310. package/dist/api/split-by-plane.d.ts +41 -0
  311. package/dist/api/split-by-plane.d.ts.map +1 -0
  312. package/dist/api/split-by-plane.js +60 -0
  313. package/dist/api/split-by-plane.js.map +1 -0
  314. package/dist/api/split.d.ts +6 -1
  315. package/dist/api/split.d.ts.map +1 -1
  316. package/dist/api/split.js +23 -9
  317. package/dist/api/split.js.map +1 -1
  318. package/dist/api/surface/arg-spec.d.ts +22 -0
  319. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  320. package/dist/api/surface/arg-spec.js +729 -477
  321. package/dist/api/surface/arg-spec.js.map +1 -1
  322. package/dist/api/sweep.d.ts +55 -0
  323. package/dist/api/sweep.d.ts.map +1 -0
  324. package/dist/api/sweep.js +86 -0
  325. package/dist/api/sweep.js.map +1 -0
  326. package/dist/api/thicken.d.ts +36 -0
  327. package/dist/api/thicken.d.ts.map +1 -0
  328. package/dist/api/thicken.js +55 -0
  329. package/dist/api/thicken.js.map +1 -0
  330. package/dist/api/transform.d.ts +8 -0
  331. package/dist/api/transform.d.ts.map +1 -1
  332. package/dist/api/transform.js +15 -4
  333. package/dist/api/transform.js.map +1 -1
  334. package/dist/api/view/cameraFns.d.ts +48 -0
  335. package/dist/api/view/cameraFns.d.ts.map +1 -0
  336. package/dist/api/view/cameraFns.js +75 -0
  337. package/dist/api/view/cameraFns.js.map +1 -0
  338. package/dist/api/view/projectionPlanes.d.ts +25 -0
  339. package/dist/api/view/projectionPlanes.d.ts.map +1 -0
  340. package/dist/api/view/projectionPlanes.js +30 -0
  341. package/dist/api/view/projectionPlanes.js.map +1 -0
  342. package/dist/api/view/view-camera.d.ts +2 -2
  343. package/dist/api/view/view-camera.d.ts.map +1 -1
  344. package/dist/api/view/view-camera.js +3 -3
  345. package/dist/api/view/view-camera.js.map +1 -1
  346. package/dist/api/view/view-projection.d.ts +9 -6
  347. package/dist/api/view/view-projection.d.ts.map +1 -1
  348. package/dist/api/view/view-projection.js +132 -65
  349. package/dist/api/view/view-projection.js.map +1 -1
  350. package/dist/api/wire.d.ts +45 -0
  351. package/dist/api/wire.d.ts.map +1 -0
  352. package/dist/api/wire.js +96 -0
  353. package/dist/api/wire.js.map +1 -0
  354. package/dist/boolean/creased-normals.d.ts +50 -0
  355. package/dist/boolean/creased-normals.d.ts.map +1 -0
  356. package/dist/boolean/creased-normals.js +114 -0
  357. package/dist/boolean/creased-normals.js.map +1 -0
  358. package/dist/boolean/deriveNormals.d.ts +4 -1
  359. package/dist/boolean/deriveNormals.d.ts.map +1 -1
  360. package/dist/boolean/deriveNormals.js +5 -2
  361. package/dist/boolean/deriveNormals.js.map +1 -1
  362. package/dist/brep/brep-ops.d.ts +6 -0
  363. package/dist/brep/brep-ops.d.ts.map +1 -1
  364. package/dist/brep/brep-ops.js +11 -2
  365. package/dist/brep/brep-ops.js.map +1 -1
  366. package/dist/brep/brep-topology.d.ts +4 -0
  367. package/dist/brep/brep-topology.d.ts.map +1 -1
  368. package/dist/brep/brep-topology.js +4 -0
  369. package/dist/brep/brep-topology.js.map +1 -1
  370. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  371. package/dist/brep/engine/adapters/brep-mock.js +79 -59
  372. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  373. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  374. package/dist/brep/engine/adapters/brepkit.js +35 -2
  375. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  376. package/dist/brep/engine/adapters/occt.d.ts +15 -7
  377. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  378. package/dist/brep/engine/adapters/occt.js +64 -167
  379. package/dist/brep/engine/adapters/occt.js.map +1 -1
  380. package/dist/brep/engine/primitives.d.ts +93 -130
  381. package/dist/brep/engine/primitives.d.ts.map +1 -1
  382. package/dist/brep/engine/primitives.js +9 -7
  383. package/dist/brep/engine/primitives.js.map +1 -1
  384. package/dist/brep/engine/types.d.ts +14 -1
  385. package/dist/brep/engine/types.d.ts.map +1 -1
  386. package/dist/brep/engine/types.js +11 -1
  387. package/dist/brep/engine/types.js.map +1 -1
  388. package/dist/brep/export/step.d.ts +3 -0
  389. package/dist/brep/export/step.d.ts.map +1 -1
  390. package/dist/brep/export/step.js +7 -1
  391. package/dist/brep/export/step.js.map +1 -1
  392. package/dist/brep/face-evolution.d.ts +8 -0
  393. package/dist/brep/face-evolution.d.ts.map +1 -1
  394. package/dist/brep/face-evolution.js +15 -3
  395. package/dist/brep/face-evolution.js.map +1 -1
  396. package/dist/brep/handle-bridge.d.ts +20 -2
  397. package/dist/brep/handle-bridge.d.ts.map +1 -1
  398. package/dist/brep/handle-bridge.js +25 -2
  399. package/dist/brep/handle-bridge.js.map +1 -1
  400. package/dist/brepkit-kernel/brepkitKernel.d.ts +25 -5
  401. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  402. package/dist/brepkit-kernel/brepkitKernel.js +782 -218
  403. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  404. package/dist/brepkit-kernel/multi-version-test.d.ts +40 -0
  405. package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -0
  406. package/dist/brepkit-kernel/multi-version-test.js +89 -0
  407. package/dist/brepkit-kernel/multi-version-test.js.map +1 -0
  408. package/dist/cad-runtime/admit-compat-lib.d.ts +6 -1
  409. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  410. package/dist/cad-runtime/admit-compat-lib.js +5 -1
  411. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  412. package/dist/cad-runtime/backend-dispatch.d.ts +9 -3
  413. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  414. package/dist/cad-runtime/backend-dispatch.js +32 -2
  415. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  416. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  417. package/dist/cad-runtime/direct-executor.js +8 -2
  418. package/dist/cad-runtime/direct-executor.js.map +1 -1
  419. package/dist/cad-runtime/runtime.d.ts +3 -0
  420. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  421. package/dist/cad-runtime/runtime.js +3 -1
  422. package/dist/cad-runtime/runtime.js.map +1 -1
  423. package/dist/define-op.d.ts +18 -2
  424. package/dist/define-op.d.ts.map +1 -1
  425. package/dist/define-op.js +29 -1
  426. package/dist/define-op.js.map +1 -1
  427. package/dist/env-agnostic.d.ts +3 -0
  428. package/dist/env-agnostic.d.ts.map +1 -1
  429. package/dist/env-agnostic.js +7 -0
  430. package/dist/env-agnostic.js.map +1 -1
  431. package/dist/index.d.ts.map +1 -1
  432. package/dist/index.js +3 -4
  433. package/dist/index.js.map +1 -1
  434. package/dist/lang/symbol-table.generated.d.ts +29 -1
  435. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  436. package/dist/lang/symbol-table.generated.js +30 -2
  437. package/dist/lang/symbol-table.generated.js.map +1 -1
  438. package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
  439. package/dist/occt-kernel/highLevelApi.js +6 -3
  440. package/dist/occt-kernel/highLevelApi.js.map +1 -1
  441. package/dist/occt-kernel/hullGeometry.d.ts +31 -0
  442. package/dist/occt-kernel/hullGeometry.d.ts.map +1 -0
  443. package/dist/occt-kernel/hullGeometry.js +319 -0
  444. package/dist/occt-kernel/hullGeometry.js.map +1 -0
  445. package/dist/occt-kernel/hullOps.d.ts +24 -0
  446. package/dist/occt-kernel/hullOps.d.ts.map +1 -0
  447. package/dist/occt-kernel/hullOps.js +52 -0
  448. package/dist/occt-kernel/hullOps.js.map +1 -0
  449. package/dist/occt-kernel/occt-primitives.d.ts +14 -0
  450. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -0
  451. package/dist/occt-kernel/occt-primitives.js +351 -0
  452. package/dist/occt-kernel/occt-primitives.js.map +1 -0
  453. package/dist/occt-kernel/occtKernel.d.ts +14 -6
  454. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  455. package/dist/occt-kernel/occtKernel.js +11 -3
  456. package/dist/occt-kernel/occtKernel.js.map +1 -1
  457. package/dist/occt-kernel/topologyExt.js +2 -2
  458. package/dist/occt-kernel/topologyExt.js.map +1 -1
  459. package/dist/primitives/brep-primitives.d.ts +4 -0
  460. package/dist/primitives/brep-primitives.d.ts.map +1 -1
  461. package/dist/primitives/brep-primitives.js +4 -0
  462. package/dist/primitives/brep-primitives.js.map +1 -1
  463. package/dist/result/bug.d.ts +22 -0
  464. package/dist/result/bug.d.ts.map +1 -0
  465. package/dist/result/bug.js +28 -0
  466. package/dist/result/bug.js.map +1 -0
  467. package/dist/result/errors.d.ts +270 -0
  468. package/dist/result/errors.d.ts.map +1 -0
  469. package/dist/result/errors.js +317 -0
  470. package/dist/result/errors.js.map +1 -0
  471. package/dist/result/kernelErrorTranslation.d.ts +21 -0
  472. package/dist/result/kernelErrorTranslation.d.ts.map +1 -0
  473. package/dist/result/kernelErrorTranslation.js +102 -0
  474. package/dist/result/kernelErrorTranslation.js.map +1 -0
  475. package/dist/result/result.d.ts +213 -0
  476. package/dist/result/result.d.ts.map +1 -0
  477. package/dist/result/result.js +336 -0
  478. package/dist/result/result.js.map +1 -0
  479. package/dist/result/vec3.d.ts +12 -0
  480. package/dist/result/vec3.d.ts.map +1 -0
  481. package/dist/result/vec3.js +14 -0
  482. package/dist/result/vec3.js.map +1 -0
  483. package/dist/runtime-state.d.ts +9 -0
  484. package/dist/runtime-state.d.ts.map +1 -1
  485. package/dist/runtime-state.js.map +1 -1
  486. package/dist/sdk.d.ts +3 -1
  487. package/dist/sdk.d.ts.map +1 -1
  488. package/dist/sdk.js +2 -1
  489. package/dist/sdk.js.map +1 -1
  490. package/dist/shape.d.ts +43 -1
  491. package/dist/shape.d.ts.map +1 -1
  492. package/dist/shape.js +57 -1
  493. package/dist/shape.js.map +1 -1
  494. package/dist/topology/naming/geom-hint.js +1 -1
  495. package/dist/topology/naming/geom-hint.js.map +1 -1
  496. package/dist/topology/naming/score.js +1 -1
  497. package/dist/topology/naming/score.js.map +1 -1
  498. package/package.json +6 -16
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Shared projection plane definitions used by cameraFns(faijs 视图投影,路径 A)。
3
+ *
4
+ * 第一方模块(2026-09-25 core-decouple Phase 1):复制自 brepjs
5
+ * `src/projection/projectionPlanes.ts`(同源复制,签名不变)。
6
+ */
7
+ /** Lookup table mapping each {@link ProjectionPlane} to its camera configuration. */
8
+ export const PROJECTION_PLANES = {
9
+ XY: { dir: [0, 0, 1], xAxis: [1, 0, 0] },
10
+ XZ: { dir: [0, -1, 0], xAxis: [1, 0, 0] },
11
+ YZ: { dir: [1, 0, 0], xAxis: [0, 1, 0] },
12
+ YX: { dir: [0, 0, -1], xAxis: [0, 1, 0] },
13
+ ZX: { dir: [0, 1, 0], xAxis: [0, 0, 1] },
14
+ ZY: { dir: [-1, 0, 0], xAxis: [0, 0, 1] },
15
+ front: { dir: [0, -1, 0], xAxis: [1, 0, 0] },
16
+ back: { dir: [0, 1, 0], xAxis: [-1, 0, 0] },
17
+ right: { dir: [-1, 0, 0], xAxis: [0, -1, 0] },
18
+ left: { dir: [1, 0, 0], xAxis: [0, 1, 0] },
19
+ bottom: { dir: [0, 0, 1], xAxis: [1, 0, 0] },
20
+ top: { dir: [0, 0, -1], xAxis: [1, 0, 0] },
21
+ };
22
+ /** Type guard — check if a value is a valid {@link ProjectionPlane} name.
23
+ *
24
+ * @param plane - Value to test.
25
+ * @returns True if `plane` is a valid projection plane name.
26
+ */
27
+ export function isProjectionPlane(plane) {
28
+ return typeof plane === 'string' && plane in PROJECTION_PLANES;
29
+ }
30
+ //# sourceMappingURL=projectionPlanes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectionPlanes.js","sourceRoot":"","sources":["../../../src/api/view/projectionPlanes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,qFAAqF;AACrF,MAAM,CAAC,MAAM,iBAAiB,GAAyC;IACrE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACxC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACzC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACxC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACzC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACxC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IAEzC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IAC5C,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IAC3C,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;IAC7C,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IAC1C,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IAC5C,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,iBAAiB,CAAC;AACjE,CAAC","sourcesContent":["/**\n * Shared projection plane definitions used by cameraFns(faijs 视图投影,路径 A)。\n *\n * 第一方模块(2026-09-25 core-decouple Phase 1):复制自 brepjs\n * `src/projection/projectionPlanes.ts`(同源复制,签名不变)。\n */\n\nimport type { Vec3 } from '../brepjs-compat/types';\n\n/** Named face of an axis-aligned bounding cube. */\nexport type CubeFace = 'front' | 'back' | 'top' | 'bottom' | 'left' | 'right';\n\n/** Named projection plane — axis pairs or cube face names. */\nexport type ProjectionPlane =\n 'XY' | 'XZ' | 'YZ' | 'YX' | 'ZX' | 'ZY' | 'front' | 'back' | 'top' | 'bottom' | 'left' | 'right';\n\n/** Camera direction and X axis for a projection plane. */\nexport interface PlaneConfig {\n readonly dir: Vec3;\n readonly xAxis: Vec3;\n}\n\n/** Lookup table mapping each {@link ProjectionPlane} to its camera configuration. */\nexport const PROJECTION_PLANES: Record<ProjectionPlane, PlaneConfig> = {\n XY: { dir: [0, 0, 1], xAxis: [1, 0, 0] },\n XZ: { dir: [0, -1, 0], xAxis: [1, 0, 0] },\n YZ: { dir: [1, 0, 0], xAxis: [0, 1, 0] },\n YX: { dir: [0, 0, -1], xAxis: [0, 1, 0] },\n ZX: { dir: [0, 1, 0], xAxis: [0, 0, 1] },\n ZY: { dir: [-1, 0, 0], xAxis: [0, 0, 1] },\n\n front: { dir: [0, -1, 0], xAxis: [1, 0, 0] },\n back: { dir: [0, 1, 0], xAxis: [-1, 0, 0] },\n right: { dir: [-1, 0, 0], xAxis: [0, -1, 0] },\n left: { dir: [1, 0, 0], xAxis: [0, 1, 0] },\n bottom: { dir: [0, 0, 1], xAxis: [1, 0, 0] },\n top: { dir: [0, 0, -1], xAxis: [1, 0, 0] },\n};\n\n/** Type guard — check if a value is a valid {@link ProjectionPlane} name.\n *\n * @param plane - Value to test.\n * @returns True if `plane` is a valid projection plane name.\n */\nexport function isProjectionPlane(plane: unknown): plane is ProjectionPlane {\n return typeof plane === 'string' && plane in PROJECTION_PLANES;\n}\n"]}
@@ -15,8 +15,8 @@
15
15
  * vendored brepjs 的 Camera 纯数据对象,供 projectView/projectSheet 与宿主复用。
16
16
  * 返回类型 re-export 自 vendored(api/generated/projection.ts 已登记 Camera type)。
17
17
  */
18
- import { type Camera } from '../../vendored/brepjs/projection/cameraFns.js';
19
- import type { Vec3 } from '../../vendored/brepjs/core/types.js';
18
+ import { type Camera } from './cameraFns.js';
19
+ import type { Vec3 } from '../brepjs-compat/types.js';
20
20
  /** 六个标准正交视图名(vendored CubeFace 同集)。 */
21
21
  export type StandardView = 'front' | 'back' | 'top' | 'bottom' | 'left' | 'right';
22
22
  /** 等轴测视图名(faijs 新增别名;方向 (1,-1,1))。 */
@@ -1 +1 @@
1
- {"version":3,"file":"view-camera.d.ts","sourceRoot":"","sources":["../../../src/api/view/view-camera.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAiC,KAAK,MAAM,EAAE,MAAM,+CAA+C,CAAA;AAG1G,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qCAAqC,CAAA;AAE/D,uCAAuC;AACvC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjF,sCAAsC;AACtC,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,WAAW,CAAA;AAEzC,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAEnE,gBAAgB;AAChB,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,GAAG,EAAE,IAAI,CAAA;IACT,wBAAwB;IACxB,KAAK,CAAC,EAAE,IAAI,CAAA;CACb;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,aAAa,GAAG,aAAa,CAAA;AAK7E;;;;;;;;;;;;IAYI;AACJ,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAYjD;AAED,4EAA4E;AAC5E,eAAO,MAAM,aAAa,mBAAa,CAAA"}
1
+ {"version":3,"file":"view-camera.d.ts","sourceRoot":"","sources":["../../../src/api/view/view-camera.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAiC,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAGxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAElD,uCAAuC;AACvC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjF,sCAAsC;AACtC,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,WAAW,CAAA;AAEzC,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAEnE,gBAAgB;AAChB,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,GAAG,EAAE,IAAI,CAAA;IACT,wBAAwB;IACxB,KAAK,CAAC,EAAE,IAAI,CAAA;CACb;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,aAAa,GAAG,aAAa,CAAA;AAK7E;;;;;;;;;;;;IAYI;AACJ,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAYjD;AAED,4EAA4E;AAC5E,eAAO,MAAM,aAAa,mBAAa,CAAA"}
@@ -15,9 +15,9 @@
15
15
  * vendored brepjs 的 Camera 纯数据对象,供 projectView/projectSheet 与宿主复用。
16
16
  * 返回类型 re-export 自 vendored(api/generated/projection.ts 已登记 Camera type)。
17
17
  */
18
- import { createCamera, cameraFromPlane } from '../../vendored/brepjs/projection/cameraFns.js';
19
- import { isProjectionPlane } from '../../vendored/brepjs/projection/projectionPlanes.js';
20
- import { unwrap } from '../../vendored/brepjs/core/result.js';
18
+ import { createCamera, cameraFromPlane } from './cameraFns.js';
19
+ import { isProjectionPlane } from './projectionPlanes.js';
20
+ import { unwrap } from '../../result/result.js';
21
21
  /** 等轴测视向(方案 §2.3:Iso=(1,-1,1),与 FreeCAD 惯例一致)。 */
22
22
  const ISO_DIR = [1, -1, 1];
23
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"view-camera.js","sourceRoot":"","sources":["../../../src/api/view/view-camera.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAe,MAAM,+CAA+C,CAAA;AAC1G,OAAO,EAAE,iBAAiB,EAAE,MAAM,sDAAsD,CAAA;AACxF,OAAO,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAA;AAyB7D,kDAAkD;AAClD,MAAM,OAAO,GAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEhC;;;;;;;;;;;;IAYI;AACJ,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAC3C,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;QACjD,CAAC;QACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAA;QACtC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,6EAA6E,CAAC,CAAA;IAClI,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAC3B,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;AACpD,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAA","sourcesContent":["/**\n * view-camera — 视图规格 → 投影相机(faijs 视图投影能力,路径 A 纯数据面)\n *\n * 设计文档:docs/plans/2026-09-10-faijs-view-projection-and-screenshot.md §3.2\n *\n * 视图规格(ViewSpec):\n * - 六个标准正交视图:'front' | 'back' | 'top' | 'bottom' | 'left' | 'right'\n * (方向沿用 vendored brepjs PROJECTION_PLANES:front=(0,-1,0)、top=(0,0,-1)…,\n * 与 FreeCAD TechDraw 的方向向量惯例一致,见方案 §2.2);\n * - 等轴测:'iso' | 'isometric'(方向 (1,-1,1),方案 §2.3 定稿);\n * - 轴对平面:'XY' | 'XZ' | 'YZ' | 'YX' | 'ZX' | 'ZY'(vendored 平面名);\n * - 任意方向:{ dir: Vec3, xAxis?: Vec3 }(xAxis 缺省由方向自动推导)。\n *\n * viewCamera 是纯数据函数(无 Shape 输入,kind 'pure' 语义):把视图规格解析成\n * vendored brepjs 的 Camera 纯数据对象,供 projectView/projectSheet 与宿主复用。\n * 返回类型 re-export 自 vendored(api/generated/projection.ts 已登记 Camera type)。\n */\n\nimport { createCamera, cameraFromPlane, type Camera } from '../../vendored/brepjs/projection/cameraFns.js'\nimport { isProjectionPlane } from '../../vendored/brepjs/projection/projectionPlanes.js'\nimport { unwrap } from '../../vendored/brepjs/core/result.js'\nimport type { Vec3 } from '../../vendored/brepjs/core/types.js'\n\n/** 六个标准正交视图名(vendored CubeFace 同集)。 */\nexport type StandardView = 'front' | 'back' | 'top' | 'bottom' | 'left' | 'right'\n\n/** 等轴测视图名(faijs 新增别名;方向 (1,-1,1))。 */\nexport type IsoView = 'iso' | 'isometric'\n\n/** 轴对平面名(vendored ProjectionPlane 的子集)。 */\nexport type AxisPlaneView = 'XY' | 'XZ' | 'YZ' | 'YX' | 'ZX' | 'ZY'\n\n/** 任意方向视图规格。 */\nexport interface DirectionView {\n /** 视向(相机沿此方向观察;零向量报错)。 */\n dir: Vec3\n /** 可选水平轴(缺省由方向自动推导)。 */\n xAxis?: Vec3\n}\n\n/**\n * faijs 视图投影的视图规格:标准正交 / 等轴测 / 轴对平面 / 任意方向。\n */\nexport type ViewSpec = StandardView | IsoView | AxisPlaneView | DirectionView\n\n/** 等轴测视向(方案 §2.3:Iso=(1,-1,1),与 FreeCAD 惯例一致)。 */\nconst ISO_DIR: Vec3 = [1, -1, 1]\n\n/**\n * 解析视图规格为投影相机(纯数据,无 Shape 输入;不消费任何几何)。\n * @group 查询\n * @inputs 0\n * @async false\n * @qual ok\n * @name viewCamera\n * @returns { direction, xAxis? } 归一化方向向量(iso = (1,-1,1)/√3,与 FreeCAD/OCCT 惯例一致)。未知视图名抛错;零方向向量抛错。用于 3d_editor 侧三轴相机渲染(mesh/SDF 形状的截图通道)。\n * @param view - 视图规格:标准视图名(front/back/top/bottom/left/right/iso(=isometric)/XY/XZ/YZ/YX/ZX/ZY)或方向对象。type:string|{dir,xAxis?} required:true\n * @example\n * const cam = cad.viewCamera('iso')\n * const cam = cad.viewCamera({ dir: [1, -1, 1] })\n */\nexport function viewCamera(view: ViewSpec): Camera {\n if (typeof view === 'string') {\n if (view === 'iso' || view === 'isometric') {\n return unwrap(createCamera([0, 0, 0], ISO_DIR))\n }\n if (isProjectionPlane(view)) {\n return unwrap(cameraFromPlane(view))\n }\n throw new Error(`[faijs/view] unknown view '${view}' (expected front/back/top/bottom/left/right/iso/isometric or an axis pair)`)\n }\n const { dir, xAxis } = view\n return unwrap(createCamera([0, 0, 0], dir, xAxis))\n}\n\n/** resolveCamera = viewCamera 别名(projectView/projectSheet 内部使用;与方案措辞一致)。 */\nexport const resolveCamera = viewCamera\n"]}
1
+ {"version":3,"file":"view-camera.js","sourceRoot":"","sources":["../../../src/api/view/view-camera.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAe,MAAM,aAAa,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAyB5C,kDAAkD;AAClD,MAAM,OAAO,GAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEhC;;;;;;;;;;;;IAYI;AACJ,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAC3C,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;QACjD,CAAC;QACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAA;QACtC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,6EAA6E,CAAC,CAAA;IAClI,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAC3B,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;AACpD,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAA","sourcesContent":["/**\n * view-camera — 视图规格 → 投影相机(faijs 视图投影能力,路径 A 纯数据面)\n *\n * 设计文档:docs/plans/2026-09-10-faijs-view-projection-and-screenshot.md §3.2\n *\n * 视图规格(ViewSpec):\n * - 六个标准正交视图:'front' | 'back' | 'top' | 'bottom' | 'left' | 'right'\n * (方向沿用 vendored brepjs PROJECTION_PLANES:front=(0,-1,0)、top=(0,0,-1)…,\n * 与 FreeCAD TechDraw 的方向向量惯例一致,见方案 §2.2);\n * - 等轴测:'iso' | 'isometric'(方向 (1,-1,1),方案 §2.3 定稿);\n * - 轴对平面:'XY' | 'XZ' | 'YZ' | 'YX' | 'ZX' | 'ZY'(vendored 平面名);\n * - 任意方向:{ dir: Vec3, xAxis?: Vec3 }(xAxis 缺省由方向自动推导)。\n *\n * viewCamera 是纯数据函数(无 Shape 输入,kind 'pure' 语义):把视图规格解析成\n * vendored brepjs 的 Camera 纯数据对象,供 projectView/projectSheet 与宿主复用。\n * 返回类型 re-export 自 vendored(api/generated/projection.ts 已登记 Camera type)。\n */\n\nimport { createCamera, cameraFromPlane, type Camera } from './cameraFns'\nimport { isProjectionPlane } from './projectionPlanes'\nimport { unwrap } from '../../result/result'\nimport type { Vec3 } from '../brepjs-compat/types'\n\n/** 六个标准正交视图名(vendored CubeFace 同集)。 */\nexport type StandardView = 'front' | 'back' | 'top' | 'bottom' | 'left' | 'right'\n\n/** 等轴测视图名(faijs 新增别名;方向 (1,-1,1))。 */\nexport type IsoView = 'iso' | 'isometric'\n\n/** 轴对平面名(vendored ProjectionPlane 的子集)。 */\nexport type AxisPlaneView = 'XY' | 'XZ' | 'YZ' | 'YX' | 'ZX' | 'ZY'\n\n/** 任意方向视图规格。 */\nexport interface DirectionView {\n /** 视向(相机沿此方向观察;零向量报错)。 */\n dir: Vec3\n /** 可选水平轴(缺省由方向自动推导)。 */\n xAxis?: Vec3\n}\n\n/**\n * faijs 视图投影的视图规格:标准正交 / 等轴测 / 轴对平面 / 任意方向。\n */\nexport type ViewSpec = StandardView | IsoView | AxisPlaneView | DirectionView\n\n/** 等轴测视向(方案 §2.3:Iso=(1,-1,1),与 FreeCAD 惯例一致)。 */\nconst ISO_DIR: Vec3 = [1, -1, 1]\n\n/**\n * 解析视图规格为投影相机(纯数据,无 Shape 输入;不消费任何几何)。\n * @group 查询\n * @inputs 0\n * @async false\n * @qual ok\n * @name viewCamera\n * @returns { direction, xAxis? } 归一化方向向量(iso = (1,-1,1)/√3,与 FreeCAD/OCCT 惯例一致)。未知视图名抛错;零方向向量抛错。用于 3d_editor 侧三轴相机渲染(mesh/SDF 形状的截图通道)。\n * @param view - 视图规格:标准视图名(front/back/top/bottom/left/right/iso(=isometric)/XY/XZ/YZ/YX/ZX/ZY)或方向对象。type:string|{dir,xAxis?} required:true\n * @example\n * const cam = cad.viewCamera('iso')\n * const cam = cad.viewCamera({ dir: [1, -1, 1] })\n */\nexport function viewCamera(view: ViewSpec): Camera {\n if (typeof view === 'string') {\n if (view === 'iso' || view === 'isometric') {\n return unwrap(createCamera([0, 0, 0], ISO_DIR))\n }\n if (isProjectionPlane(view)) {\n return unwrap(cameraFromPlane(view))\n }\n throw new Error(`[faijs/view] unknown view '${view}' (expected front/back/top/bottom/left/right/iso/isometric or an axis pair)`)\n }\n const { dir, xAxis } = view\n return unwrap(createCamera([0, 0, 0], dir, xAxis))\n}\n\n/** resolveCamera = viewCamera 别名(projectView/projectSheet 内部使用;与方案措辞一致)。 */\nexport const resolveCamera = viewCamera\n"]}
@@ -4,16 +4,19 @@
4
4
  * 设计文档:docs/plans/2026-09-10-faijs-view-projection-and-screenshot.md §3.2
5
5
  *
6
6
  * projectView(shape, view, opts?) 返回**纯数据 SVG 字符串**(非 Shape):
7
- * - 借入 faijs Shape 的 brep 句柄(borrowBrepjsShape,零拷贝,不转移所有权);
8
- * - 经 vendored brepjs drawProjection(OCCT HLR 隐线消除)得到 visible/hidden
9
- * 两组 2D Drawing;
7
+ * - 直连 core 引擎的 HLR 投影(`BrepEngineApi.projectEdges`,OCCT
8
+ * HLRBRep 隐线消除):可见 / 隐藏两组边(sharp/smooth/outline compound);
9
+ * - 每组边 → 3D 曲线采样折线(`curveParameters` + `curvePointAtParam`)→
10
+ * 投影到相机平面(正交投影,坐标 = 相对 camera.origin 在 xAxis/yAxis 上的分量);
10
11
  * - 序列化为一个完整 SVG:可见轮廓实线 + 隐藏线虚线(stroke-dasharray)。
11
12
  *
12
13
  * 返回字符串绕开 arg-spec 对 projectEdges/makeProjectedEdges 的 skip 障碍
13
14
  * (Edge 句柄数组 + compound 生命周期无法静态收养——本 op 只在内部消费,
14
15
  * 产物是 2D 纯文本,无收养问题)。
15
16
  *
16
- * projectViewSvg 返回结构化数据(viewBox/paths/尺寸),供 projectSheet 网格组合。
17
+ * 2026-09-25 core-decouple wrapup(§3.1 A 案):不再依赖 brepjs 的 HLR+2D
18
+ * drawing 链——HLR 由 core 引擎原生提供(occt-wasm projectEdges),2D SVG
19
+ * 序列化为本地实现(曲线边以采样折线近似)。
17
20
  */
18
21
  import type { Shape } from '../../mesh/types.js';
19
22
  import { type ViewSpec } from './view-camera.js';
@@ -38,7 +41,7 @@ export interface ProjectionSvg {
38
41
  svg: string;
39
42
  /** viewBox 属性值('minX minY w h';可见 ∪ 隐藏线并集 + margin)。 */
40
43
  viewBox: string;
41
- /** 各路径 d 串:可见实线 / 隐藏虚线。 */
44
+ /** 各 path d 串:可见实线 / 隐藏虚线。 */
42
45
  paths: {
43
46
  visible: string[];
44
47
  hidden: string[];
@@ -69,7 +72,7 @@ export declare function projectViewSvg(shape: Shape, view: ViewSpec, opts?: Proj
69
72
  * @param opts.strokeWidth - 可见线宽(stroke-width)。type:number 默认 1
70
73
  * @param opts.dash - 隐藏线虚线样式(stroke-dasharray)。type:string 默认 '4,4'
71
74
  * @param opts.hiddenOpacity - 隐藏线透明度。type:number 默认 0.6
72
- * @param opts.margin - viewBox 外扩边距。type:number 默认 10
75
+ * @param opts.margin - viewBox 外扩边距。type:number 默认 1
73
76
  * @param opts.width - 输出宽度(缺省 = viewBox 宽度)。type:number
74
77
  * @param opts.height - 输出高度(缺省 = viewBox 高度)。type:number
75
78
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"view-projection.d.ts","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAK7C,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE5D,0BAA0B;AAC1B,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,2BAA2B;IAC3B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC9C,eAAe;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AA0CD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAE,kBAAuB,GAAG,aAAa,CAqCzG;AAED;;;;;;;;;;;;;;;;;;;IAmBI;AACJ,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAE3F"}
1
+ {"version":3,"file":"view-projection.d.ts","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAI7C,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AAU5D,0BAA0B;AAC1B,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC9C,eAAe;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAyID;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAE,kBAAuB,GAAG,aAAa,CA2BzG;AAED;;;;;;;;;;;;;;;;;;;IAmBI;AACJ,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAE3F"}
@@ -4,20 +4,108 @@
4
4
  * 设计文档:docs/plans/2026-09-10-faijs-view-projection-and-screenshot.md §3.2
5
5
  *
6
6
  * projectView(shape, view, opts?) 返回**纯数据 SVG 字符串**(非 Shape):
7
- * - 借入 faijs Shape 的 brep 句柄(borrowBrepjsShape,零拷贝,不转移所有权);
8
- * - 经 vendored brepjs drawProjection(OCCT HLR 隐线消除)得到 visible/hidden
9
- * 两组 2D Drawing;
7
+ * - 直连 core 引擎的 HLR 投影(`BrepEngineApi.projectEdges`,OCCT
8
+ * HLRBRep 隐线消除):可见 / 隐藏两组边(sharp/smooth/outline compound);
9
+ * - 每组边 → 3D 曲线采样折线(`curveParameters` + `curvePointAtParam`)→
10
+ * 投影到相机平面(正交投影,坐标 = 相对 camera.origin 在 xAxis/yAxis 上的分量);
10
11
  * - 序列化为一个完整 SVG:可见轮廓实线 + 隐藏线虚线(stroke-dasharray)。
11
12
  *
12
13
  * 返回字符串绕开 arg-spec 对 projectEdges/makeProjectedEdges 的 skip 障碍
13
14
  * (Edge 句柄数组 + compound 生命周期无法静态收养——本 op 只在内部消费,
14
15
  * 产物是 2D 纯文本,无收养问题)。
15
16
  *
16
- * projectViewSvg 返回结构化数据(viewBox/paths/尺寸),供 projectSheet 网格组合。
17
+ * 2026-09-25 core-decouple wrapup(§3.1 A 案):不再依赖 brepjs 的 HLR+2D
18
+ * drawing 链——HLR 由 core 引擎原生提供(occt-wasm projectEdges),2D SVG
19
+ * 序列化为本地实现(曲线边以采样折线近似)。
17
20
  */
18
- import { borrowBrepjsShape } from '../internal/l3-bridge.js';
19
- import { drawProjection } from '../../vendored/brepjs/sketching/draw3d.js';
21
+ import { brepOf } from '../../shape.js';
22
+ import { getBrepApi } from '../../brep/handle-bridge.js';
20
23
  import { resolveCamera } from './view-camera.js';
24
+ /** 每条边的 3D 采样点数(直线 2 点;曲线分段近似)。 */
25
+ const EDGE_SAMPLES = 5;
26
+ /** 3D 点 → 相机平面 2D 坐标。
27
+ *
28
+ * GOTCHA: occt-wasm 的 HLR projectEdges 已把边投影到相机平面,输出坐标 =
29
+ * (沿 xAxis 的水平分量, 沿 cross(direction, xAxis) 的垂直分量, 沿 direction
30
+ * 的深度分量≈0)——不是世界坐标。因此 2D 坐标直接取输出的前两分量,不再做
31
+ * dot 二次投影(否则会把垂直信息读丢——垂直在 p.y 而非 p.z)。
32
+ */
33
+ function projectTo2D(p, _cam) {
34
+ return [p[0], p[1]];
35
+ }
36
+ const COMPOUND_KEYS = [
37
+ ['visibleSharp', 'visible'],
38
+ ['visibleSmooth', 'visible'],
39
+ ['visibleOutline', 'visible'],
40
+ ['hiddenSharp', 'hidden'],
41
+ ['hiddenSmooth', 'hidden'],
42
+ ['hiddenOutline', 'hidden'],
43
+ ];
44
+ /**
45
+ * HLR 投影 shape → 可见/隐藏 2D 折线(SVG d 串)。
46
+ * 全部句柄在本函数内释放(compound + 边;输入 shape 不消费)。
47
+ */
48
+ function projectPolylines(shape, view) {
49
+ const solid = brepOf(shape);
50
+ if (solid === undefined) {
51
+ throw new Error('[faijs/view-projection] E_BREP_ONLY_INPUT: operation requires a BREP-backed shape ' +
52
+ '(mesh-only input cannot be projected)');
53
+ }
54
+ const api = getBrepApi();
55
+ const cam = resolveCamera(view);
56
+ const r = api.projectEdges(solid, { x: cam.position[0], y: cam.position[1], z: cam.position[2] }, { x: cam.direction[0], y: cam.direction[1], z: cam.direction[2] }, { x: cam.xAxis[0], y: cam.xAxis[1], z: cam.xAxis[2] }, true, 0.1);
57
+ const out = { visible: [], hidden: [] };
58
+ const toHandle = (id) => id;
59
+ try {
60
+ for (const [key, group] of COMPOUND_KEYS) {
61
+ const compoundId = r[key];
62
+ if (typeof compoundId !== 'number' || compoundId === 0)
63
+ continue;
64
+ const edges = api.getSubShapes(toHandle(compoundId), 'edge');
65
+ for (const edge of edges) {
66
+ const d = edgeToPath(api, edge, cam);
67
+ if (d !== null)
68
+ out[group].push(d);
69
+ }
70
+ // 释放 compound slot(幂等)
71
+ try {
72
+ api.release(toHandle(compoundId));
73
+ }
74
+ catch {
75
+ // already released
76
+ }
77
+ }
78
+ }
79
+ finally {
80
+ void 0;
81
+ }
82
+ return out;
83
+ }
84
+ /** 单条边 → SVG path d 串(3D 曲线采样折线投影到相机平面)。 */
85
+ function edgeToPath(api, edge, cam) {
86
+ let cp;
87
+ try {
88
+ cp = api.curveParameters(edge);
89
+ }
90
+ catch {
91
+ return null; // 退化边(如孤立顶点线)无曲线参数
92
+ }
93
+ const { first, last } = cp;
94
+ const span = last - first;
95
+ const pts = [];
96
+ for (let i = 0; i < EDGE_SAMPLES; i += 1) {
97
+ const t = first + (span * i) / (EDGE_SAMPLES - 1);
98
+ const p = api.curvePointAtParam(edge, t);
99
+ pts.push(projectTo2D([p.x, p.y, p.z], cam));
100
+ }
101
+ if (pts.length < 2)
102
+ return null;
103
+ let d = `M ${pts[0][0].toFixed(4)} ${pts[0][1].toFixed(4)}`;
104
+ for (let i = 1; i < pts.length; i += 1) {
105
+ d += ` L ${pts[i][0].toFixed(4)} ${pts[i][1].toFixed(4)}`;
106
+ }
107
+ return d;
108
+ }
21
109
  /** 解析 'minX minY w h' 为数值数组。 */
22
110
  function parseViewBox(vb) {
23
111
  const parts = vb.trim().split(/\s+/).map(Number);
@@ -25,39 +113,29 @@ function parseViewBox(vb) {
25
113
  return undefined;
26
114
  return [parts[0], parts[1], parts[2], parts[3]];
27
115
  }
28
- /** 空 Drawing 的 viewBox 是空串(innerShape 为 null);返回 false 表示无内容。 */
29
- function viewBoxOf(d) {
30
- const vb = d.toSVGViewBox(0);
31
- if (vb === '')
32
- return undefined;
33
- return parseViewBox(vb);
34
- }
35
- /**
36
- * 可见 ∪ 隐藏两组 Drawing 的并集 viewBox(统一坐标系;margin 再外扩)。
37
- */
38
- function mergedViewBox(visible, hidden, margin) {
116
+ /** 折线点集 bbox → viewBox(统一坐标系;margin 再外扩)。 */
117
+ function viewBoxOfPaths(paths, margin) {
39
118
  let minX = Infinity;
40
119
  let minY = Infinity;
41
120
  let maxX = -Infinity;
42
121
  let maxY = -Infinity;
43
- for (const d of [visible, hidden]) {
44
- const box = viewBoxOf(d);
45
- if (!box)
46
- continue;
47
- const [x, y, w, h] = box;
48
- minX = Math.min(minX, x);
49
- minY = Math.min(minY, y);
50
- maxX = Math.max(maxX, x + w);
51
- maxY = Math.max(maxY, y + h);
122
+ for (const d of paths) {
123
+ const nums = d.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/g) ?? [];
124
+ for (let i = 0; i + 1 < nums.length; i += 2) {
125
+ const x = Number(nums[i]);
126
+ const y = Number(nums[i + 1]);
127
+ if (!Number.isFinite(x) || !Number.isFinite(y))
128
+ continue;
129
+ minX = Math.min(minX, x);
130
+ minY = Math.min(minY, y);
131
+ maxX = Math.max(maxX, x);
132
+ maxY = Math.max(maxY, y);
133
+ }
52
134
  }
53
135
  if (!Number.isFinite(minX))
54
136
  return '0 0 0 0'; // 空投影(如空 shape)
55
137
  return `${minX - margin} ${minY - margin} ${maxX - minX + 2 * margin} ${maxY - minY + 2 * margin}`;
56
138
  }
57
- function flattenPaths(d) {
58
- const paths = d.toSVGPaths();
59
- return Array.isArray(paths[0]) ? paths.flat() : paths;
60
- }
61
139
  /**
62
140
  * 单视图投影(结构化结果)。
63
141
  *
@@ -67,40 +145,29 @@ function flattenPaths(d) {
67
145
  * @returns 结构化投影结果(svg/viewBox/paths/尺寸)。
68
146
  */
69
147
  export function projectViewSvg(shape, view, opts = {}) {
70
- const borrowed = borrowBrepjsShape(shape);
71
- const camera = resolveCamera(view);
72
- const { visible, hidden } = drawProjection(borrowed, camera);
73
- try {
74
- const visiblePaths = flattenPaths(visible);
75
- const hiddenPaths = flattenPaths(hidden);
76
- const margin = opts.margin ?? 1;
77
- const viewBox = mergedViewBox(visible, hidden, margin);
78
- const parsed = parseViewBox(viewBox) ?? [0, 0, 0, 0];
79
- const width = opts.width ?? parsed[2];
80
- const height = opts.height ?? parsed[3];
81
- const strokeWidth = opts.strokeWidth ?? 1;
82
- const dash = opts.dash ?? '4,4';
83
- const hiddenOpacity = opts.hiddenOpacity ?? 0.6;
84
- const visibleMarkup = visiblePaths
85
- .map((d) => `<path d="${d}" fill="none" stroke="#000" stroke-width="${strokeWidth}" />`)
86
- .join('\n ');
87
- const hiddenMarkup = hiddenPaths
88
- .map((d) => `<path d="${d}" fill="none" stroke="#000" stroke-width="${strokeWidth}" stroke-dasharray="${dash}" opacity="${hiddenOpacity}" />`)
89
- .join('\n ');
90
- const svg = [
91
- `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}" width="${width}" height="${height}" fill="none" stroke="black" stroke-width="0.6%" vector-effect="non-scaling-stroke">`,
92
- ` <g stroke="#000" fill="none">`,
93
- ` ${visibleMarkup}${hiddenMarkup === '' ? '' : `\n ${hiddenMarkup}`}`,
94
- ` </g>`,
95
- `</svg>`,
96
- ].join('\n');
97
- return { svg, viewBox, paths: { visible: visiblePaths, hidden: hiddenPaths }, width, height };
98
- }
99
- finally {
100
- // Drawing 持有 2D kernel 句柄(Bnd_Box2d/2D 曲线),序列化后释放
101
- visible[Symbol.dispose]?.();
102
- hidden[Symbol.dispose]?.();
103
- }
148
+ const { visible: visiblePaths, hidden: hiddenPaths } = projectPolylines(shape, view);
149
+ const margin = opts.margin ?? 1;
150
+ const viewBox = viewBoxOfPaths([...visiblePaths, ...hiddenPaths], margin);
151
+ const parsed = parseViewBox(viewBox) ?? [0, 0, 0, 0];
152
+ const width = opts.width ?? parsed[2];
153
+ const height = opts.height ?? parsed[3];
154
+ const strokeWidth = opts.strokeWidth ?? 1;
155
+ const dash = opts.dash ?? '4,4';
156
+ const hiddenOpacity = opts.hiddenOpacity ?? 0.6;
157
+ const visibleMarkup = visiblePaths
158
+ .map((d) => `<path d="${d}" fill="none" stroke="#000" stroke-width="${strokeWidth}" />`)
159
+ .join('\n ');
160
+ const hiddenMarkup = hiddenPaths
161
+ .map((d) => `<path d="${d}" fill="none" stroke="#000" stroke-width="${strokeWidth}" stroke-dasharray="${dash}" opacity="${hiddenOpacity}" />`)
162
+ .join('\n ');
163
+ const svg = [
164
+ `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}" width="${width}" height="${height}" fill="none" stroke="black" stroke-width="0.6%" vector-effect="non-scaling-stroke">`,
165
+ ` <g stroke="#000" fill="none">`,
166
+ ` ${visibleMarkup}${hiddenMarkup === '' ? '' : `\n ${hiddenMarkup}`}`,
167
+ ` </g>`,
168
+ `</svg>`,
169
+ ].join('\n');
170
+ return { svg, viewBox, paths: { visible: visiblePaths, hidden: hiddenPaths }, width, height };
104
171
  }
105
172
  /**
106
173
  * 单视图投影 → SVG 线稿字符串(纯数据,不消费/修改 shape;规则 1 下裸调用不消费输入)。
@@ -115,7 +182,7 @@ export function projectViewSvg(shape, view, opts = {}) {
115
182
  * @param opts.strokeWidth - 可见线宽(stroke-width)。type:number 默认 1
116
183
  * @param opts.dash - 隐藏线虚线样式(stroke-dasharray)。type:string 默认 '4,4'
117
184
  * @param opts.hiddenOpacity - 隐藏线透明度。type:number 默认 0.6
118
- * @param opts.margin - viewBox 外扩边距。type:number 默认 10
185
+ * @param opts.margin - viewBox 外扩边距。type:number 默认 1
119
186
  * @param opts.width - 输出宽度(缺省 = viewBox 宽度)。type:number
120
187
  * @param opts.height - 输出高度(缺省 = viewBox 高度)。type:number
121
188
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"view-projection.js","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * view-projection — 单视图投影 → SVG 线稿(faijs 视图投影能力,路径 A)\n *\n * 设计文档:docs/plans/2026-09-10-faijs-view-projection-and-screenshot.md §3.2\n *\n * projectView(shape, view, opts?) 返回**纯数据 SVG 字符串**(非 Shape):\n * - 借入 faijs Shape 的 brep 句柄(borrowBrepjsShape,零拷贝,不转移所有权);\n * - 经 vendored brepjs drawProjection(OCCT HLR 隐线消除)得到 visible/hidden\n * 两组 2D Drawing;\n * - 序列化为一个完整 SVG:可见轮廓实线 + 隐藏线虚线(stroke-dasharray)。\n *\n * 返回字符串绕开 arg-spec 对 projectEdges/makeProjectedEdges 的 skip 障碍\n * (Edge 句柄数组 + compound 生命周期无法静态收养——本 op 只在内部消费,\n * 产物是 2D 纯文本,无收养问题)。\n *\n * projectViewSvg 返回结构化数据(viewBox/paths/尺寸),供 projectSheet 网格组合。\n */\n\nimport type { Shape } from '../../mesh/types'\nimport { borrowBrepjsShape } from '../internal/l3-bridge'\nimport { drawProjection } from '../../vendored/brepjs/sketching/draw3d.js'\nimport type { Drawing } from '../../vendored/brepjs/sketching/drawing.js'\nimport type { AnyShape } from '../../vendored/brepjs/core/shapeTypes.js'\nimport { resolveCamera, type ViewSpec } from './view-camera'\n\n/** projectView 的序列化选项。 */\nexport interface ProjectViewOptions {\n /** viewBox 四周留白(单位 = 投影平面坐标单位;缺省 1)。 */\n margin?: number\n /** 可见/隐藏线 stroke-width(像素;缺省 1)。 */\n strokeWidth?: number\n /** 隐藏线虚线样式(SVG stroke-dasharray;缺省 '4,4')。 */\n dash?: string\n /** 隐藏线透明度(缺省 0.6)。 */\n hiddenOpacity?: number\n /** 输出 SVG 宽度(缺省 = viewBox 宽度)。 */\n width?: number\n /** 输出 SVG 高度(缺省 = viewBox 高度)。 */\n height?: number\n}\n\n/** 单视图投影的结构化结果(projectSheet 复用)。 */\nexport interface ProjectionSvg {\n /** 完整 SVG 字符串。 */\n svg: string\n /** viewBox 属性值('minX minY w h';可见 ∪ 隐藏线并集 + margin)。 */\n viewBox: string\n /** 各路径 d 串:可见实线 / 隐藏虚线。 */\n paths: { visible: string[]; hidden: string[] }\n /** 输出宽度/高度。 */\n width: number\n height: number\n}\n\n/** 解析 'minX minY w h' 为数值数组。 */\nfunction parseViewBox(vb: string): [number, number, number, number] | undefined {\n const parts = vb.trim().split(/\\s+/).map(Number)\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n))) return undefined\n return [parts[0], parts[1], parts[2], parts[3]]\n}\n\n/** 空 Drawing 的 viewBox 是空串(innerShape 为 null);返回 false 表示无内容。 */\nfunction viewBoxOf(d: Drawing): [number, number, number, number] | undefined {\n const vb = d.toSVGViewBox(0)\n if (vb === '') return undefined\n return parseViewBox(vb)\n}\n\n/**\n * 可见 ∪ 隐藏两组 Drawing 的并集 viewBox(统一坐标系;margin 再外扩)。\n */\nfunction mergedViewBox(visible: Drawing, hidden: Drawing, margin: number): string {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const d of [visible, hidden]) {\n const box = viewBoxOf(d)\n if (!box) continue\n const [x, y, w, h] = box\n minX = Math.min(minX, x)\n minY = Math.min(minY, y)\n maxX = Math.max(maxX, x + w)\n maxY = Math.max(maxY, y + h)\n }\n if (!Number.isFinite(minX)) return '0 0 0 0' // 空投影(如空 shape)\n return `${minX - margin} ${minY - margin} ${maxX - minX + 2 * margin} ${maxY - minY + 2 * margin}`\n}\n\nfunction flattenPaths(d: Drawing): string[] {\n const paths = d.toSVGPaths()\n return Array.isArray(paths[0]) ? (paths as string[][]).flat() : (paths as string[])\n}\n\n/**\n * 单视图投影(结构化结果)。\n *\n * @param shape - 待投影的 faijs Shape(必须带 BREP 槽;mesh-only 输入抛 E_BREP_ONLY_INPUT)。\n * @param view - 视图规格(标准视图 / iso / 轴对平面 / 方向对象)。\n * @param opts - 序列化选项。\n * @returns 结构化投影结果(svg/viewBox/paths/尺寸)。\n */\nexport function projectViewSvg(shape: Shape, view: ViewSpec, opts: ProjectViewOptions = {}): ProjectionSvg {\n const borrowed = borrowBrepjsShape(shape)\n const camera = resolveCamera(view)\n const { visible, hidden } = drawProjection(borrowed as unknown as AnyShape, camera)\n try {\n const visiblePaths = flattenPaths(visible)\n const hiddenPaths = flattenPaths(hidden)\n const margin = opts.margin ?? 1\n const viewBox = mergedViewBox(visible, hidden, margin)\n const parsed = parseViewBox(viewBox) ?? [0, 0, 0, 0]\n const width = opts.width ?? parsed[2]\n const height = opts.height ?? parsed[3]\n const strokeWidth = opts.strokeWidth ?? 1\n const dash = opts.dash ?? '4,4'\n const hiddenOpacity = opts.hiddenOpacity ?? 0.6\n const visibleMarkup = visiblePaths\n .map((d) => `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" />`)\n .join('\\n ')\n const hiddenMarkup = hiddenPaths\n .map(\n (d) =>\n `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" stroke-dasharray=\"${dash}\" opacity=\"${hiddenOpacity}\" />`,\n )\n .join('\\n ')\n const svg = [\n `<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox}\" width=\"${width}\" height=\"${height}\" fill=\"none\" stroke=\"black\" stroke-width=\"0.6%\" vector-effect=\"non-scaling-stroke\">`,\n ` <g stroke=\"#000\" fill=\"none\">`,\n ` ${visibleMarkup}${hiddenMarkup === '' ? '' : `\\n ${hiddenMarkup}`}`,\n ` </g>`,\n `</svg>`,\n ].join('\\n')\n return { svg, viewBox, paths: { visible: visiblePaths, hidden: hiddenPaths }, width, height }\n } finally {\n // Drawing 持有 2D kernel 句柄(Bnd_Box2d/2D 曲线),序列化后释放\n visible[Symbol.dispose]?.()\n hidden[Symbol.dispose]?.()\n }\n}\n\n/**\n * 单视图投影 → SVG 线稿字符串(纯数据,不消费/修改 shape;规则 1 下裸调用不消费输入)。\n * @group 查询\n * @inputs 1\n * @async false\n * @qual ok\n * @name projectView\n * @returns SVG 字符串(<svg viewBox=\"…\"> + 可见实线 <path> + 隐藏虚线 <path>)。裸调用 cad.projectView(part0, 'front') 不消费 part0(规则 1),part 仍留在 canvas。\n * @param shape - 目标几何(必须有 BREP 槽;mesh-only 抛 E_BREP_ONLY_INPUT)。type:Shape required:true\n * @param view - 视图规格(同 viewCamera:标准视图名 / iso / 轴对平面 / 方向对象)。type:string|{dir,xAxis?} required:true\n * @param opts.strokeWidth - 可见线宽(stroke-width)。type:number 默认 1\n * @param opts.dash - 隐藏线虚线样式(stroke-dasharray)。type:string 默认 '4,4'\n * @param opts.hiddenOpacity - 隐藏线透明度。type:number 默认 0.6\n * @param opts.margin - viewBox 外扩边距。type:number 默认 10\n * @param opts.width - 输出宽度(缺省 = viewBox 宽度)。type:number\n * @param opts.height - 输出高度(缺省 = viewBox 高度)。type:number\n * @example\n * const svg = cad.projectView(part0, 'front')\n * const svg = cad.projectView(part0, 'iso', { strokeWidth: 1, dash: '4,4', hiddenOpacity: 0.6 })\n */\nexport function projectView(shape: Shape, view: ViewSpec, opts?: ProjectViewOptions): string {\n return projectViewSvg(shape, view, opts).svg\n}\n"]}
1
+ {"version":3,"file":"view-projection.js","sourceRoot":"","sources":["../../../src/api/view/view-projection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * view-projection — 单视图投影 → SVG 线稿(faijs 视图投影能力,路径 A)\n *\n * 设计文档:docs/plans/2026-09-10-faijs-view-projection-and-screenshot.md §3.2\n *\n * projectView(shape, view, opts?) 返回**纯数据 SVG 字符串**(非 Shape):\n * - 直连 core 引擎的 HLR 投影(`BrepEngineApi.projectEdges`,OCCT\n * HLRBRep 隐线消除):可见 / 隐藏两组边(sharp/smooth/outline compound);\n * - 每组边 → 3D 曲线采样折线(`curveParameters` + `curvePointAtParam`)→\n * 投影到相机平面(正交投影,坐标 = 相对 camera.origin 在 xAxis/yAxis 上的分量);\n * - 序列化为一个完整 SVG:可见轮廓实线 + 隐藏线虚线(stroke-dasharray)。\n *\n * 返回字符串绕开 arg-spec 对 projectEdges/makeProjectedEdges 的 skip 障碍\n * (Edge 句柄数组 + compound 生命周期无法静态收养——本 op 只在内部消费,\n * 产物是 2D 纯文本,无收养问题)。\n *\n * 2026-09-25 core-decouple wrapup(§3.1 A 案):不再依赖 brepjs 的 HLR+2D\n * drawing 链——HLR 由 core 引擎原生提供(occt-wasm projectEdges),2D SVG\n * 序列化为本地实现(曲线边以采样折线近似)。\n */\n\nimport type { Shape } from '../../mesh/types'\nimport { brepOf } from '../../shape'\nimport { getBrepApi } from '../../brep/handle-bridge'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport { resolveCamera, type ViewSpec } from './view-camera'\n\n/** 投影相机(与 view-camera 输出同构)。 */\ninterface Camera {\n readonly position: [number, number, number]\n readonly direction: [number, number, number]\n readonly xAxis: [number, number, number]\n readonly yAxis: [number, number, number]\n}\n\n/** projectView 的序列化选项。 */\nexport interface ProjectViewOptions {\n /** viewBox 四周留白(单位 = 投影平面坐标单位;缺省 1)。 */\n margin?: number\n /** 可见/隐藏线 stroke-width(像素;缺省 1)。 */\n strokeWidth?: number\n /** 隐藏线虚线样式(SVG stroke-dasharray;缺省 '4,4')。 */\n dash?: string\n /** 隐藏线透明度(缺省 0.6)。 */\n hiddenOpacity?: number\n /** 输出 SVG 宽度(缺省 = viewBox 宽度)。 */\n width?: number\n /** 输出 SVG 高度(缺省 = viewBox 高度)。 */\n height?: number\n}\n\n/** 单视图投影的结构化结果(projectSheet 复用)。 */\nexport interface ProjectionSvg {\n /** 完整 SVG 字符串。 */\n svg: string\n /** viewBox 属性值('minX minY w h';可见 ∪ 隐藏线并集 + margin)。 */\n viewBox: string\n /** 各 path d 串:可见实线 / 隐藏虚线。 */\n paths: { visible: string[]; hidden: string[] }\n /** 输出宽度/高度。 */\n width: number\n height: number\n}\n\n/** 每条边的 3D 采样点数(直线 2 点;曲线分段近似)。 */\nconst EDGE_SAMPLES = 5\n\ntype Vec3 = readonly [number, number, number]\n\n/** 3D 点 → 相机平面 2D 坐标。\n *\n * GOTCHA: occt-wasm 的 HLR projectEdges 已把边投影到相机平面,输出坐标 =\n * (沿 xAxis 的水平分量, 沿 cross(direction, xAxis) 的垂直分量, 沿 direction\n * 的深度分量≈0)——不是世界坐标。因此 2D 坐标直接取输出的前两分量,不再做\n * dot 二次投影(否则会把垂直信息读丢——垂直在 p.y 而非 p.z)。\n */\nfunction projectTo2D(p: Vec3, _cam: Camera): [number, number] {\n return [p[0], p[1]]\n}\n\n/** 引擎 projectEdges 的返回结构(occt-wasm:6 组 compound 的 arena id)。 */\ninterface ProjectEdgesResult {\n visibleSharp: number\n visibleSmooth: number\n visibleOutline: number\n hiddenSharp: number\n hiddenSmooth: number\n hiddenOutline: number\n}\n\nconst COMPOUND_KEYS = [\n ['visibleSharp', 'visible'],\n ['visibleSmooth', 'visible'],\n ['visibleOutline', 'visible'],\n ['hiddenSharp', 'hidden'],\n ['hiddenSmooth', 'hidden'],\n ['hiddenOutline', 'hidden'],\n] as const\n\n/**\n * HLR 投影 shape → 可见/隐藏 2D 折线(SVG d 串)。\n * 全部句柄在本函数内释放(compound + 边;输入 shape 不消费)。\n */\nfunction projectPolylines(shape: Shape, view: ViewSpec): { visible: string[]; hidden: string[] } {\n const solid = brepOf(shape) as BrepHandle | undefined\n if (solid === undefined) {\n throw new Error(\n '[faijs/view-projection] E_BREP_ONLY_INPUT: operation requires a BREP-backed shape ' +\n '(mesh-only input cannot be projected)',\n )\n }\n const api = getBrepApi()\n const cam = resolveCamera(view) as unknown as Camera\n const r = api.projectEdges(\n solid,\n { x: cam.position[0], y: cam.position[1], z: cam.position[2] },\n { x: cam.direction[0], y: cam.direction[1], z: cam.direction[2] },\n { x: cam.xAxis[0], y: cam.xAxis[1], z: cam.xAxis[2] },\n true,\n 0.1,\n ) as ProjectEdgesResult\n\n const out: { visible: string[]; hidden: string[] } = { visible: [], hidden: [] }\n const toHandle = (id: number): BrepHandle => id as BrepHandle\n try {\n for (const [key, group] of COMPOUND_KEYS) {\n const compoundId = r[key]\n if (typeof compoundId !== 'number' || compoundId === 0) continue\n const edges = api.getSubShapes(toHandle(compoundId), 'edge')\n for (const edge of edges) {\n const d = edgeToPath(api, edge, cam)\n if (d !== null) out[group].push(d)\n }\n // 释放 compound slot(幂等)\n try {\n api.release(toHandle(compoundId))\n } catch {\n // already released\n }\n }\n } finally {\n void 0\n }\n return out\n}\n\n/** 单条边 → SVG path d 串(3D 曲线采样折线投影到相机平面)。 */\nfunction edgeToPath(api: ReturnType<typeof getBrepApi>, edge: BrepHandle, cam: Camera): string | null {\n let cp\n try {\n cp = api.curveParameters(edge)\n } catch {\n return null // 退化边(如孤立顶点线)无曲线参数\n }\n const { first, last } = cp\n const span = last - first\n const pts: [number, number][] = []\n for (let i = 0; i < EDGE_SAMPLES; i += 1) {\n const t = first + (span * i) / (EDGE_SAMPLES - 1)\n const p = api.curvePointAtParam(edge, t)\n pts.push(projectTo2D([p.x, p.y, p.z], cam))\n }\n if (pts.length < 2) return null\n let d = `M ${pts[0][0].toFixed(4)} ${pts[0][1].toFixed(4)}`\n for (let i = 1; i < pts.length; i += 1) {\n d += ` L ${pts[i][0].toFixed(4)} ${pts[i][1].toFixed(4)}`\n }\n return d\n}\n\n/** 解析 'minX minY w h' 为数值数组。 */\nfunction parseViewBox(vb: string): [number, number, number, number] | undefined {\n const parts = vb.trim().split(/\\s+/).map(Number)\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n))) return undefined\n return [parts[0], parts[1], parts[2], parts[3]]\n}\n\n/** 折线点集 bbox → viewBox(统一坐标系;margin 再外扩)。 */\nfunction viewBoxOfPaths(paths: string[], margin: number): string {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const d of paths) {\n const nums = d.match(/[-+]?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?/g) ?? []\n for (let i = 0; i + 1 < nums.length; i += 2) {\n const x = Number(nums[i])\n const y = Number(nums[i + 1])\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue\n minX = Math.min(minX, x)\n minY = Math.min(minY, y)\n maxX = Math.max(maxX, x)\n maxY = Math.max(maxY, y)\n }\n }\n if (!Number.isFinite(minX)) return '0 0 0 0' // 空投影(如空 shape)\n return `${minX - margin} ${minY - margin} ${maxX - minX + 2 * margin} ${maxY - minY + 2 * margin}`\n}\n\n/**\n * 单视图投影(结构化结果)。\n *\n * @param shape - 待投影的 faijs Shape(必须带 BREP 槽;mesh-only 输入抛 E_BREP_ONLY_INPUT)。\n * @param view - 视图规格(标准视图 / iso / 轴对平面 / 方向对象)。\n * @param opts - 序列化选项。\n * @returns 结构化投影结果(svg/viewBox/paths/尺寸)。\n */\nexport function projectViewSvg(shape: Shape, view: ViewSpec, opts: ProjectViewOptions = {}): ProjectionSvg {\n const { visible: visiblePaths, hidden: hiddenPaths } = projectPolylines(shape, view)\n const margin = opts.margin ?? 1\n const viewBox = viewBoxOfPaths([...visiblePaths, ...hiddenPaths], margin)\n const parsed = parseViewBox(viewBox) ?? [0, 0, 0, 0]\n const width = opts.width ?? parsed[2]\n const height = opts.height ?? parsed[3]\n const strokeWidth = opts.strokeWidth ?? 1\n const dash = opts.dash ?? '4,4'\n const hiddenOpacity = opts.hiddenOpacity ?? 0.6\n const visibleMarkup = visiblePaths\n .map((d) => `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" />`)\n .join('\\n ')\n const hiddenMarkup = hiddenPaths\n .map(\n (d) =>\n `<path d=\"${d}\" fill=\"none\" stroke=\"#000\" stroke-width=\"${strokeWidth}\" stroke-dasharray=\"${dash}\" opacity=\"${hiddenOpacity}\" />`,\n )\n .join('\\n ')\n const svg = [\n `<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox}\" width=\"${width}\" height=\"${height}\" fill=\"none\" stroke=\"black\" stroke-width=\"0.6%\" vector-effect=\"non-scaling-stroke\">`,\n ` <g stroke=\"#000\" fill=\"none\">`,\n ` ${visibleMarkup}${hiddenMarkup === '' ? '' : `\\n ${hiddenMarkup}`}`,\n ` </g>`,\n `</svg>`,\n ].join('\\n')\n return { svg, viewBox, paths: { visible: visiblePaths, hidden: hiddenPaths }, width, height }\n}\n\n/**\n * 单视图投影 → SVG 线稿字符串(纯数据,不消费/修改 shape;规则 1 下裸调用不消费输入)。\n * @group 查询\n * @inputs 1\n * @async false\n * @qual ok\n * @name projectView\n * @returns SVG 字符串(<svg viewBox=\"…\"> + 可见实线 <path> + 隐藏虚线 <path>)。裸调用 cad.projectView(part0, 'front') 不消费 part0(规则 1),part 仍留在 canvas。\n * @param shape - 目标几何(必须有 BREP 槽;mesh-only 抛 E_BREP_ONLY_INPUT)。type:Shape required:true\n * @param view - 视图规格(同 viewCamera:标准视图名 / iso / 轴对平面 / 方向对象)。type:string|{dir,xAxis?} required:true\n * @param opts.strokeWidth - 可见线宽(stroke-width)。type:number 默认 1\n * @param opts.dash - 隐藏线虚线样式(stroke-dasharray)。type:string 默认 '4,4'\n * @param opts.hiddenOpacity - 隐藏线透明度。type:number 默认 0.6\n * @param opts.margin - viewBox 外扩边距。type:number 默认 1\n * @param opts.width - 输出宽度(缺省 = viewBox 宽度)。type:number\n * @param opts.height - 输出高度(缺省 = viewBox 高度)。type:number\n * @example\n * const svg = cad.projectView(part0, 'front')\n * const svg = cad.projectView(part0, 'iso', { strokeWidth: 1, dash: '4,4', hiddenOpacity: 0.6 })\n */\nexport function projectView(shape: Shape, view: ViewSpec, opts?: ProjectViewOptions): string {\n return projectViewSvg(shape, view, opts).svg\n}\n"]}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * stdlib wire — 从点列构造 1D 曲线(折线 / 闭合轮廓 / 平滑样条)
3
+ *
4
+ * 用途:脚本面造线能力(G-D 门控层,Phase 3)。下游 sweep / loft / twistExtrude /
5
+ * complexExtrude / roof 等 11 个动作都需要 wire 输入;此前脚本面造不出 wire,这些动作
6
+ * 即使登记也喂不进输入。
7
+ *
8
+ * 设计:
9
+ * - 中立 op(dual-path):mesh 路径用折线 mesh 包成 `curve(mesh)`;brep 路径用 L1 构造
10
+ * (makeLineEdge / interpolatePoints + makeWire),经 `fromBrepCurve` 登记 1D 句柄。
11
+ * 两种 mode 下 kind 都取 'curve',避免随 mode 漂移(§7.1 建议 1 / 附带子项②推荐 (i))。
12
+ * - 无输入(creator),故 dispatch 走 mesh(mode=mesh)或 brep(mode=brep/auto 有 brep 实现)。
13
+ * - 1D 产物命名取 unmodeled(无面 → 无 roleTable,先例 torus/convexHull)。
14
+ */
15
+ import type { Shape } from '../mesh/types.js';
16
+ /** 一个 3D 点(点列成员)。 */
17
+ export type WirePoint = [number, number, number];
18
+ /** `cad.wire` 选项:折线 / 闭合轮廓 / 平滑曲线。 */
19
+ export interface WireOptions {
20
+ /** 闭合轮廓:首尾相连。 */
21
+ closed?: boolean;
22
+ /** 平滑曲线:经 interpolatePoints 走 B-样条穿过全部点(默认折线)。 */
23
+ smooth?: boolean;
24
+ /** smooth 时的样条次数(默认 3)。 */
25
+ degree?: number;
26
+ }
27
+ /**
28
+ * 从点列构造 1D 曲线(折线 / 闭合轮廓 / 平滑样条)。
29
+ * @group 创建
30
+ * @inputs 0
31
+ * @async false
32
+ * @qual ok
33
+ * @name wire
34
+ * @returns Shape 1D 曲线(kind:'curve',无三角载荷;显示经 wireframe)。
35
+ * @param points - 有序点列 [[x,y,z], ...],至少 2 点。type:Vec3[] required:true
36
+ * @param options.closed - 闭合轮廓(首尾相连)。type:boolean required:false
37
+ * @param options.smooth - 平滑曲线(B-样条穿过全部点,默认折线)。type:boolean required:false
38
+ * @param options.degree - smooth 时的样条次数(默认 3)。type:number required:false
39
+ * @example
40
+ * const w = cad.wire([[0,0,0],[10,0,0],[10,10,0]], { closed: true })
41
+ */
42
+ export declare const wire: ((points: WirePoint[], opts?: WireOptions | undefined) => Promise<Shape>) & {
43
+ __faijs__dualOp?: import("../define-op.js").DualOpMeta;
44
+ };
45
+ //# sourceMappingURL=wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../src/api/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAS1C,qBAAqB;AACrB,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEhD,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,iBAAiB;IACjB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAsDD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,IAAI;;CAQf,CAAA"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * stdlib wire — 从点列构造 1D 曲线(折线 / 闭合轮廓 / 平滑样条)
3
+ *
4
+ * 用途:脚本面造线能力(G-D 门控层,Phase 3)。下游 sweep / loft / twistExtrude /
5
+ * complexExtrude / roof 等 11 个动作都需要 wire 输入;此前脚本面造不出 wire,这些动作
6
+ * 即使登记也喂不进输入。
7
+ *
8
+ * 设计:
9
+ * - 中立 op(dual-path):mesh 路径用折线 mesh 包成 `curve(mesh)`;brep 路径用 L1 构造
10
+ * (makeLineEdge / interpolatePoints + makeWire),经 `fromBrepCurve` 登记 1D 句柄。
11
+ * 两种 mode 下 kind 都取 'curve',避免随 mode 漂移(§7.1 建议 1 / 附带子项②推荐 (i))。
12
+ * - 无输入(creator),故 dispatch 走 mesh(mode=mesh)或 brep(mode=brep/auto 有 brep 实现)。
13
+ * - 1D 产物命名取 unmodeled(无面 → 无 roleTable,先例 torus/convexHull)。
14
+ */
15
+ import { getBrepApi } from '../brep/handle-bridge.js';
16
+ import { solidToShape } from '../brep/brep-ops.js';
17
+ import { curve, fromBrepCurve } from '../shape.js';
18
+ import { defineOp } from '../sdk.js';
19
+ /** 校验并归一化点列(至少 2 点,每点 [x,y,z])。 */
20
+ function normalizePoints(raw) {
21
+ if (!Array.isArray(raw) || raw.length < 2) {
22
+ throw new Error('E_WIRE_TOO_FEW_POINTS: wire requires at least 2 points');
23
+ }
24
+ const pts = [];
25
+ for (const p of raw) {
26
+ if (!Array.isArray(p) || p.length < 3) {
27
+ throw new Error('E_WIRE_BAD_POINT: each wire point must be [x, y, z]');
28
+ }
29
+ pts.push({ x: Number(p[0]), y: Number(p[1]), z: Number(p[2]) });
30
+ }
31
+ return pts;
32
+ }
33
+ /** mesh 路径:折线 mesh 载荷(位置 + 线段索引),包成 curve(kind 维持 'curve')。 */
34
+ function wireMesh(points, opts) {
35
+ const pts = normalizePoints(points);
36
+ const closed = !!(opts && opts.closed);
37
+ const positions = [];
38
+ for (const p of pts)
39
+ positions.push(p.x, p.y, p.z);
40
+ if (closed)
41
+ positions.push(pts[0].x, pts[0].y, pts[0].z);
42
+ const n = pts.length + (closed ? 1 : 0);
43
+ const indices = [];
44
+ for (let i = 0; i < n - 1; i++)
45
+ indices.push(i, i + 1);
46
+ return curve({ positions: new Float32Array(positions), indices: new Uint32Array(indices) });
47
+ }
48
+ /** BREP 路径:点列 → wire(折线或平滑样条),经 fromBrepCurve 登记 1D 句柄。 */
49
+ function wireBrep(points, opts) {
50
+ const pts = normalizePoints(points);
51
+ const closed = !!(opts && opts.closed);
52
+ const smooth = !!(opts && opts.smooth);
53
+ const kernel = getBrepApi();
54
+ let handle;
55
+ if (smooth && pts.length >= 2) {
56
+ // 平滑曲线:interpolatePoints 返回穿过全部点的 B-样条(曲线/线柄),直接作为 wire 载荷。
57
+ const degree = typeof opts?.degree === 'number' ? opts.degree : 3;
58
+ handle = kernel.interpolatePoints(pts, degree);
59
+ }
60
+ else {
61
+ const edges = [];
62
+ const segCount = closed ? pts.length : pts.length - 1;
63
+ for (let i = 0; i < segCount; i++) {
64
+ const a = pts[i];
65
+ const b = pts[(i + 1) % pts.length];
66
+ edges.push(kernel.makeLineEdge(a, b));
67
+ }
68
+ handle = kernel.makeWire(edges);
69
+ }
70
+ return fromBrepCurve(solidToShape(kernel, handle), { solid: handle });
71
+ }
72
+ /**
73
+ * 从点列构造 1D 曲线(折线 / 闭合轮廓 / 平滑样条)。
74
+ * @group 创建
75
+ * @inputs 0
76
+ * @async false
77
+ * @qual ok
78
+ * @name wire
79
+ * @returns Shape 1D 曲线(kind:'curve',无三角载荷;显示经 wireframe)。
80
+ * @param points - 有序点列 [[x,y,z], ...],至少 2 点。type:Vec3[] required:true
81
+ * @param options.closed - 闭合轮廓(首尾相连)。type:boolean required:false
82
+ * @param options.smooth - 平滑曲线(B-样条穿过全部点,默认折线)。type:boolean required:false
83
+ * @param options.degree - smooth 时的样条次数(默认 3)。type:number required:false
84
+ * @example
85
+ * const w = cad.wire([[0,0,0],[10,0,0],[10,10,0]], { closed: true })
86
+ */
87
+ export const wire = defineOp({
88
+ mesh(points, opts) {
89
+ return wireMesh(points, opts);
90
+ },
91
+ brep(points, opts) {
92
+ return wireBrep(points, opts);
93
+ },
94
+ naming: { kind: 'unmodeled', reason: 'construct vocabulary pending Phase 3' },
95
+ });
96
+ //# sourceMappingURL=wire.js.map