@faicad/faijs 0.33.2 → 0.35.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. package/dist/api/api-namespace.d.ts +14 -14
  2. package/dist/api/api-namespace.d.ts.map +1 -1
  3. package/dist/api/api-namespace.js +40 -14
  4. package/dist/api/api-namespace.js.map +1 -1
  5. package/dist/api/appearance.d.ts +47 -6
  6. package/dist/api/appearance.d.ts.map +1 -1
  7. package/dist/api/appearance.js.map +1 -1
  8. package/dist/api/assembly/entities.js +14 -4
  9. package/dist/api/assembly/entities.js.map +1 -1
  10. package/dist/api/assembly/solve-tree.d.ts +1 -0
  11. package/dist/api/assembly/solve-tree.d.ts.map +1 -1
  12. package/dist/api/assembly/solve-tree.js +42 -17
  13. package/dist/api/assembly/solve-tree.js.map +1 -1
  14. package/dist/api/assembly/solve.d.ts +1 -0
  15. package/dist/api/assembly/solve.d.ts.map +1 -1
  16. package/dist/api/assembly/solve.js.map +1 -1
  17. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  18. package/dist/api/assembly/solvers/global-solver.js +130 -23
  19. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  20. package/dist/api/assembly/solvers/pose-from-delta.d.ts +9 -0
  21. package/dist/api/assembly/solvers/pose-from-delta.d.ts.map +1 -1
  22. package/dist/api/assembly/solvers/pose-from-delta.js +23 -0
  23. package/dist/api/assembly/solvers/pose-from-delta.js.map +1 -1
  24. package/dist/api/assembly/solvers/types.d.ts +20 -2
  25. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  26. package/dist/api/assembly/solvers/types.js.map +1 -1
  27. package/dist/api/chamfer.d.ts +7 -4
  28. package/dist/api/chamfer.d.ts.map +1 -1
  29. package/dist/api/chamfer.js +57 -13
  30. package/dist/api/chamfer.js.map +1 -1
  31. package/dist/api/draft.d.ts +7 -4
  32. package/dist/api/draft.d.ts.map +1 -1
  33. package/dist/api/draft.js +11 -6
  34. package/dist/api/draft.js.map +1 -1
  35. package/dist/api/edge-ref.d.ts +4 -4
  36. package/dist/api/edge-ref.js +4 -4
  37. package/dist/api/edge-ref.js.map +1 -1
  38. package/dist/api/extrude.d.ts +10 -6
  39. package/dist/api/extrude.d.ts.map +1 -1
  40. package/dist/api/extrude.js +54 -26
  41. package/dist/api/extrude.js.map +1 -1
  42. package/dist/api/face-ref.d.ts +4 -4
  43. package/dist/api/face-ref.js +4 -4
  44. package/dist/api/face-ref.js.map +1 -1
  45. package/dist/api/feature-repair.d.ts +6 -3
  46. package/dist/api/feature-repair.d.ts.map +1 -1
  47. package/dist/api/feature-repair.js +12 -7
  48. package/dist/api/feature-repair.js.map +1 -1
  49. package/dist/api/fillet-variable.d.ts +6 -2
  50. package/dist/api/fillet-variable.d.ts.map +1 -1
  51. package/dist/api/fillet-variable.js +24 -6
  52. package/dist/api/fillet-variable.js.map +1 -1
  53. package/dist/api/fillet.d.ts +7 -4
  54. package/dist/api/fillet.d.ts.map +1 -1
  55. package/dist/api/fillet.js +92 -12
  56. package/dist/api/fillet.js.map +1 -1
  57. package/dist/api/generated/script-face-manifest.js +1 -1
  58. package/dist/api/generated/script-face-manifest.js.map +1 -1
  59. package/dist/api/generated/topology.js +1 -1
  60. package/dist/api/generated/topology.js.map +1 -1
  61. package/dist/api/helix.d.ts +13 -13
  62. package/dist/api/helix.d.ts.map +1 -1
  63. package/dist/api/helix.js +19 -24
  64. package/dist/api/helix.js.map +1 -1
  65. package/dist/api/import-brep.d.ts +10 -18
  66. package/dist/api/import-brep.d.ts.map +1 -1
  67. package/dist/api/import-brep.js +17 -25
  68. package/dist/api/import-brep.js.map +1 -1
  69. package/dist/api/import-step.d.ts +10 -15
  70. package/dist/api/import-step.d.ts.map +1 -1
  71. package/dist/api/import-step.js +24 -29
  72. package/dist/api/import-step.js.map +1 -1
  73. package/dist/api/index.js +2 -2
  74. package/dist/api/index.js.map +1 -1
  75. package/dist/api/internal/export-members.js.map +1 -1
  76. package/dist/api/loft-advanced.d.ts +4 -0
  77. package/dist/api/loft-advanced.d.ts.map +1 -1
  78. package/dist/api/loft-advanced.js +4 -0
  79. package/dist/api/loft-advanced.js.map +1 -1
  80. package/dist/api/loft.d.ts +5 -3
  81. package/dist/api/loft.d.ts.map +1 -1
  82. package/dist/api/loft.js +5 -3
  83. package/dist/api/loft.js.map +1 -1
  84. package/dist/api/meta.d.ts +42 -6
  85. package/dist/api/meta.d.ts.map +1 -1
  86. package/dist/api/meta.js.map +1 -1
  87. package/dist/api/primitives.d.ts +3 -2
  88. package/dist/api/primitives.d.ts.map +1 -1
  89. package/dist/api/primitives.js +3 -2
  90. package/dist/api/primitives.js.map +1 -1
  91. package/dist/api/punch-hole.d.ts +5 -2
  92. package/dist/api/punch-hole.d.ts.map +1 -1
  93. package/dist/api/punch-hole.js +4 -1
  94. package/dist/api/punch-hole.js.map +1 -1
  95. package/dist/api/replicate.d.ts +4 -5
  96. package/dist/api/replicate.d.ts.map +1 -1
  97. package/dist/api/replicate.js +4 -5
  98. package/dist/api/replicate.js.map +1 -1
  99. package/dist/api/selectors-to-refs.d.ts +83 -0
  100. package/dist/api/selectors-to-refs.d.ts.map +1 -0
  101. package/dist/api/selectors-to-refs.js +211 -0
  102. package/dist/api/selectors-to-refs.js.map +1 -0
  103. package/dist/api/shell.d.ts +17 -8
  104. package/dist/api/shell.d.ts.map +1 -1
  105. package/dist/api/shell.js +45 -15
  106. package/dist/api/shell.js.map +1 -1
  107. package/dist/api/sketch-on-face.d.ts +12 -6
  108. package/dist/api/sketch-on-face.d.ts.map +1 -1
  109. package/dist/api/sketch-on-face.js +31 -4
  110. package/dist/api/sketch-on-face.js.map +1 -1
  111. package/dist/api/sketch-on-plane.d.ts +3 -0
  112. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  113. package/dist/api/sketch-on-plane.js +3 -0
  114. package/dist/api/sketch-on-plane.js.map +1 -1
  115. package/dist/api/sketch-on-surface.d.ts +4 -1
  116. package/dist/api/sketch-on-surface.d.ts.map +1 -1
  117. package/dist/api/sketch-on-surface.js +4 -1
  118. package/dist/api/sketch-on-surface.js.map +1 -1
  119. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  120. package/dist/api/surface/arg-spec.js +5 -6
  121. package/dist/api/surface/arg-spec.js.map +1 -1
  122. package/dist/api/topo-resolve.d.ts.map +1 -1
  123. package/dist/api/topo-resolve.js +24 -5
  124. package/dist/api/topo-resolve.js.map +1 -1
  125. package/dist/api/view/view-projection.d.ts.map +1 -1
  126. package/dist/api/view/view-projection.js +9 -2
  127. package/dist/api/view/view-projection.js.map +1 -1
  128. package/dist/brep/brep-chain.js +2 -2
  129. package/dist/brep/brep-chain.js.map +1 -1
  130. package/dist/brep/brep-ops.d.ts +1 -1
  131. package/dist/brep/brep-ops.js +1 -1
  132. package/dist/brep/brep-ops.js.map +1 -1
  133. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  134. package/dist/brep/engine/adapters/brep-mock.js +45 -0
  135. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  136. package/dist/brep/engine/primitives.d.ts +87 -3
  137. package/dist/brep/engine/primitives.d.ts.map +1 -1
  138. package/dist/brep/engine/primitives.js +1 -1
  139. package/dist/brep/engine/primitives.js.map +1 -1
  140. package/dist/brep/engine/registry.d.ts +33 -7
  141. package/dist/brep/engine/registry.d.ts.map +1 -1
  142. package/dist/brep/engine/registry.js +47 -16
  143. package/dist/brep/engine/registry.js.map +1 -1
  144. package/dist/brep/handle-bridge.d.ts +14 -15
  145. package/dist/brep/handle-bridge.d.ts.map +1 -1
  146. package/dist/brep/handle-bridge.js +35 -15
  147. package/dist/brep/handle-bridge.js.map +1 -1
  148. package/dist/brep/primitives-brep.js +2 -2
  149. package/dist/brep/primitives-brep.js.map +1 -1
  150. package/dist/brep/text/text-to-solid.d.ts +40 -3
  151. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  152. package/dist/brep/text/text-to-solid.js +104 -24
  153. package/dist/brep/text/text-to-solid.js.map +1 -1
  154. package/dist/brepkit-kernel/brepkitKernel.d.ts +2 -2
  155. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  156. package/dist/brepkit-kernel/brepkitKernel.js +328 -38
  157. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  158. package/dist/brepkit-kernel/brepkitWasm.d.ts +3 -1
  159. package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
  160. package/dist/brepkit-kernel/brepkitWasm.js +13 -9
  161. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  162. package/dist/brepkit-kernel/multi-version-test.d.ts +2 -2
  163. package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
  164. package/dist/brepkit-kernel/multi-version-test.js +6 -6
  165. package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
  166. package/dist/browser.d.ts +2 -3
  167. package/dist/browser.d.ts.map +1 -1
  168. package/dist/browser.js +1 -2
  169. package/dist/browser.js.map +1 -1
  170. package/dist/cad-runtime/admit-compat-lib.d.ts +9 -1
  171. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  172. package/dist/cad-runtime/admit-compat-lib.js +11 -1
  173. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  174. package/dist/cad-runtime/browser-lib-loader.d.ts +16 -11
  175. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  176. package/dist/cad-runtime/browser-lib-loader.js +16 -8
  177. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  178. package/dist/cad-runtime/direct-executor.d.ts +62 -5
  179. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  180. package/dist/cad-runtime/direct-executor.js +617 -42
  181. package/dist/cad-runtime/direct-executor.js.map +1 -1
  182. package/dist/cad-runtime/interp/closure.d.ts +3 -2
  183. package/dist/cad-runtime/interp/closure.d.ts.map +1 -1
  184. package/dist/cad-runtime/interp/closure.js.map +1 -1
  185. package/dist/cad-runtime/interp/env.d.ts +9 -6
  186. package/dist/cad-runtime/interp/env.d.ts.map +1 -1
  187. package/dist/cad-runtime/interp/env.js +4 -2
  188. package/dist/cad-runtime/interp/env.js.map +1 -1
  189. package/dist/cad-runtime/lib-decl.d.ts +121 -0
  190. package/dist/cad-runtime/lib-decl.d.ts.map +1 -0
  191. package/dist/cad-runtime/lib-decl.js +100 -0
  192. package/dist/cad-runtime/lib-decl.js.map +1 -0
  193. package/dist/cad-runtime/ports.d.ts +12 -0
  194. package/dist/cad-runtime/ports.d.ts.map +1 -1
  195. package/dist/cad-runtime/ports.js.map +1 -1
  196. package/dist/cad-runtime/runtime.d.ts +59 -5
  197. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  198. package/dist/cad-runtime/runtime.js +252 -20
  199. package/dist/cad-runtime/runtime.js.map +1 -1
  200. package/dist/extra/browser.d.ts +9 -0
  201. package/dist/extra/browser.d.ts.map +1 -0
  202. package/dist/extra/browser.js +9 -0
  203. package/dist/extra/browser.js.map +1 -0
  204. package/dist/extra/editor-ops.d.ts +22 -0
  205. package/dist/extra/editor-ops.d.ts.map +1 -0
  206. package/dist/extra/editor-ops.js +21 -0
  207. package/dist/extra/editor-ops.js.map +1 -0
  208. package/dist/extra/extras/svg-extrude.d.ts +45 -0
  209. package/dist/extra/extras/svg-extrude.d.ts.map +1 -0
  210. package/dist/extra/extras/svg-extrude.js +110 -0
  211. package/dist/extra/extras/svg-extrude.js.map +1 -0
  212. package/dist/extra/extras/text-cjk.d.ts +36 -0
  213. package/dist/extra/extras/text-cjk.d.ts.map +1 -0
  214. package/dist/extra/extras/text-cjk.js +86 -0
  215. package/dist/extra/extras/text-cjk.js.map +1 -0
  216. package/dist/extra/extras/text-geometry.d.ts +69 -0
  217. package/dist/extra/extras/text-geometry.d.ts.map +1 -0
  218. package/dist/extra/extras/text-geometry.js +188 -0
  219. package/dist/extra/extras/text-geometry.js.map +1 -0
  220. package/dist/extra/index.d.ts +40 -0
  221. package/dist/extra/index.d.ts.map +1 -0
  222. package/dist/extra/index.js +40 -0
  223. package/dist/extra/index.js.map +1 -0
  224. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts +94 -0
  225. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts.map +1 -0
  226. package/dist/extra/mesh/drill-hole/DrillHoleCore.js +282 -0
  227. package/dist/extra/mesh/drill-hole/DrillHoleCore.js.map +1 -0
  228. package/dist/extra/mesh/drill-hole/drill-types.d.ts +34 -0
  229. package/dist/extra/mesh/drill-hole/drill-types.d.ts.map +1 -0
  230. package/dist/extra/mesh/drill-hole/drill-types.js +7 -0
  231. package/dist/extra/mesh/drill-hole/drill-types.js.map +1 -0
  232. package/dist/extra/mesh/engrave-decoration.d.ts +42 -0
  233. package/dist/extra/mesh/engrave-decoration.d.ts.map +1 -0
  234. package/dist/extra/mesh/engrave-decoration.js +39 -0
  235. package/dist/extra/mesh/engrave-decoration.js.map +1 -0
  236. package/dist/extra/mesh/fai_drill.d.ts +21 -0
  237. package/dist/extra/mesh/fai_drill.d.ts.map +1 -0
  238. package/dist/extra/mesh/fai_drill.js +89 -0
  239. package/dist/extra/mesh/fai_drill.js.map +1 -0
  240. package/dist/extra/mesh/fai_extrude.d.ts +24 -0
  241. package/dist/extra/mesh/fai_extrude.d.ts.map +1 -0
  242. package/dist/extra/mesh/fai_extrude.js +42 -0
  243. package/dist/extra/mesh/fai_extrude.js.map +1 -0
  244. package/dist/extra/mesh/fai_split.d.ts +164 -0
  245. package/dist/extra/mesh/fai_split.d.ts.map +1 -0
  246. package/dist/extra/mesh/fai_split.js +269 -0
  247. package/dist/extra/mesh/fai_split.js.map +1 -0
  248. package/dist/extra/mesh/primitives.d.ts +29 -0
  249. package/dist/extra/mesh/primitives.d.ts.map +1 -0
  250. package/dist/extra/mesh/primitives.js +41 -0
  251. package/dist/extra/mesh/primitives.js.map +1 -0
  252. package/dist/extra/op-names.d.ts +37 -0
  253. package/dist/extra/op-names.d.ts.map +1 -0
  254. package/dist/extra/op-names.js +46 -0
  255. package/dist/extra/op-names.js.map +1 -0
  256. package/dist/extra/ops/compound.d.ts +140 -0
  257. package/dist/extra/ops/compound.d.ts.map +1 -0
  258. package/dist/extra/ops/compound.js +167 -0
  259. package/dist/extra/ops/compound.js.map +1 -0
  260. package/dist/extra/ops/copy.d.ts +40 -0
  261. package/dist/extra/ops/copy.d.ts.map +1 -0
  262. package/dist/extra/ops/copy.js +83 -0
  263. package/dist/extra/ops/copy.js.map +1 -0
  264. package/dist/extra/ops/fai_drill.d.ts +51 -0
  265. package/dist/extra/ops/fai_drill.d.ts.map +1 -0
  266. package/dist/extra/ops/fai_drill.js +233 -0
  267. package/dist/extra/ops/fai_drill.js.map +1 -0
  268. package/dist/extra/ops/fai_extrude.d.ts +36 -0
  269. package/dist/extra/ops/fai_extrude.d.ts.map +1 -0
  270. package/dist/extra/ops/fai_extrude.js +84 -0
  271. package/dist/extra/ops/fai_extrude.js.map +1 -0
  272. package/dist/extra/ops/fai_split.d.ts +46 -0
  273. package/dist/extra/ops/fai_split.d.ts.map +1 -0
  274. package/dist/extra/ops/fai_split.js +235 -0
  275. package/dist/extra/ops/fai_split.js.map +1 -0
  276. package/dist/extra/ops/load.d.ts +49 -0
  277. package/dist/extra/ops/load.d.ts.map +1 -0
  278. package/dist/extra/ops/load.js +423 -0
  279. package/dist/extra/ops/load.js.map +1 -0
  280. package/dist/extra/ops/svg-extrude.d.ts +32 -0
  281. package/dist/extra/ops/svg-extrude.d.ts.map +1 -0
  282. package/dist/extra/ops/svg-extrude.js +74 -0
  283. package/dist/extra/ops/svg-extrude.js.map +1 -0
  284. package/dist/extra/ops/text.d.ts +34 -0
  285. package/dist/extra/ops/text.d.ts.map +1 -0
  286. package/dist/extra/ops/text.js +100 -0
  287. package/dist/extra/ops/text.js.map +1 -0
  288. package/dist/geometry2d/bridge/lift-on-plane.d.ts +8 -5
  289. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  290. package/dist/geometry2d/bridge/lift-on-plane.js +8 -5
  291. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  292. package/dist/index.d.ts +6 -2
  293. package/dist/index.d.ts.map +1 -1
  294. package/dist/index.js +8 -2
  295. package/dist/index.js.map +1 -1
  296. package/dist/lang/symbol-table.d.ts +3 -3
  297. package/dist/lang/symbol-table.generated.d.ts +10 -0
  298. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  299. package/dist/lang/symbol-table.generated.js +10 -0
  300. package/dist/lang/symbol-table.generated.js.map +1 -1
  301. package/dist/lang/symbol-table.js +3 -3
  302. package/dist/lang/symbol-table.js.map +1 -1
  303. package/dist/math3d/index.d.ts +1 -1
  304. package/dist/math3d/index.js +1 -1
  305. package/dist/math3d/index.js.map +1 -1
  306. package/dist/mesh/engrave.d.ts +2 -3
  307. package/dist/mesh/engrave.d.ts.map +1 -1
  308. package/dist/mesh/engrave.js +4 -11
  309. package/dist/mesh/engrave.js.map +1 -1
  310. package/dist/mesh/index.d.ts +0 -2
  311. package/dist/mesh/index.d.ts.map +1 -1
  312. package/dist/mesh/index.js +0 -2
  313. package/dist/mesh/index.js.map +1 -1
  314. package/dist/mesh/primitives.d.ts +7 -5
  315. package/dist/mesh/primitives.d.ts.map +1 -1
  316. package/dist/mesh/primitives.js +16 -9
  317. package/dist/mesh/primitives.js.map +1 -1
  318. package/dist/mesh/types.d.ts +4 -3
  319. package/dist/mesh/types.d.ts.map +1 -1
  320. package/dist/mesh/types.js.map +1 -1
  321. package/dist/node-host/cli.d.ts +11 -4
  322. package/dist/node-host/cli.d.ts.map +1 -1
  323. package/dist/node-host/cli.js +53 -28
  324. package/dist/node-host/cli.js.map +1 -1
  325. package/dist/node-host/execute-script.d.ts.map +1 -1
  326. package/dist/node-host/execute-script.js +3 -4
  327. package/dist/node-host/execute-script.js.map +1 -1
  328. package/dist/node-host/lib-package-json.d.ts +36 -0
  329. package/dist/node-host/lib-package-json.d.ts.map +1 -0
  330. package/dist/node-host/lib-package-json.js +73 -0
  331. package/dist/node-host/lib-package-json.js.map +1 -0
  332. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  333. package/dist/occt-kernel/occt-primitives.js +41 -0
  334. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  335. package/dist/occt-kernel/occtKernel.d.ts +1 -1
  336. package/dist/occt-kernel/occtKernel.js +1 -1
  337. package/dist/occt-kernel/occtKernel.js.map +1 -1
  338. package/dist/primitives/brep-primitives.d.ts.map +1 -1
  339. package/dist/primitives/brep-primitives.js +39 -12
  340. package/dist/primitives/brep-primitives.js.map +1 -1
  341. package/dist/runtime-state.d.ts +28 -1
  342. package/dist/runtime-state.d.ts.map +1 -1
  343. package/dist/runtime-state.js +14 -1
  344. package/dist/runtime-state.js.map +1 -1
  345. package/dist/sdk.d.ts +2 -2
  346. package/dist/sdk.d.ts.map +1 -1
  347. package/dist/sdk.js +11 -2
  348. package/dist/sdk.js.map +1 -1
  349. package/dist/sketch/bspline.d.ts +58 -0
  350. package/dist/sketch/bspline.d.ts.map +1 -0
  351. package/dist/sketch/bspline.js +104 -0
  352. package/dist/sketch/bspline.js.map +1 -0
  353. package/dist/sketch/canonical.d.ts +239 -0
  354. package/dist/sketch/canonical.d.ts.map +1 -0
  355. package/dist/sketch/canonical.js +17 -0
  356. package/dist/sketch/canonical.js.map +1 -0
  357. package/dist/sketch/contour.d.ts +43 -0
  358. package/dist/sketch/contour.d.ts.map +1 -0
  359. package/dist/sketch/contour.js +202 -0
  360. package/dist/sketch/contour.js.map +1 -0
  361. package/dist/sketch/dim-spec.d.ts +32 -0
  362. package/dist/sketch/dim-spec.d.ts.map +1 -0
  363. package/dist/sketch/dim-spec.js +112 -0
  364. package/dist/sketch/dim-spec.js.map +1 -0
  365. package/dist/sketch/faces.d.ts +45 -0
  366. package/dist/sketch/faces.d.ts.map +1 -0
  367. package/dist/sketch/faces.js +108 -0
  368. package/dist/sketch/faces.js.map +1 -0
  369. package/dist/sketch/fcstd-types.d.ts +194 -0
  370. package/dist/sketch/fcstd-types.d.ts.map +1 -0
  371. package/dist/sketch/fcstd-types.js +67 -0
  372. package/dist/sketch/fcstd-types.js.map +1 -0
  373. package/dist/sketch/index.d.ts +46 -0
  374. package/dist/sketch/index.d.ts.map +1 -0
  375. package/dist/sketch/index.js +39 -0
  376. package/dist/sketch/index.js.map +1 -0
  377. package/dist/sketch/node.d.ts +14 -0
  378. package/dist/sketch/node.d.ts.map +1 -0
  379. package/dist/sketch/node.js +43 -0
  380. package/dist/sketch/node.js.map +1 -0
  381. package/dist/sketch/op.d.ts +111 -0
  382. package/dist/sketch/op.d.ts.map +1 -0
  383. package/dist/sketch/op.js +185 -0
  384. package/dist/sketch/op.js.map +1 -0
  385. package/dist/sketch/planegcs-backend.d.ts +69 -0
  386. package/dist/sketch/planegcs-backend.d.ts.map +1 -0
  387. package/dist/sketch/planegcs-backend.js +812 -0
  388. package/dist/sketch/planegcs-backend.js.map +1 -0
  389. package/dist/sketch/project.d.ts +176 -0
  390. package/dist/sketch/project.d.ts.map +1 -0
  391. package/dist/sketch/project.js +656 -0
  392. package/dist/sketch/project.js.map +1 -0
  393. package/dist/sketch/shapes.d.ts +370 -0
  394. package/dist/sketch/shapes.d.ts.map +1 -0
  395. package/dist/sketch/shapes.js +959 -0
  396. package/dist/sketch/shapes.js.map +1 -0
  397. package/dist/sketch/solve.d.ts +21 -0
  398. package/dist/sketch/solve.d.ts.map +1 -0
  399. package/dist/sketch/solve.js +144 -0
  400. package/dist/sketch/solve.js.map +1 -0
  401. package/dist/sketch/solver-loader.d.ts +47 -0
  402. package/dist/sketch/solver-loader.d.ts.map +1 -0
  403. package/dist/sketch/solver-loader.js +77 -0
  404. package/dist/sketch/solver-loader.js.map +1 -0
  405. package/dist/sketch/solver.d.ts +63 -0
  406. package/dist/sketch/solver.d.ts.map +1 -0
  407. package/dist/sketch/solver.js +28 -0
  408. package/dist/sketch/solver.js.map +1 -0
  409. package/dist/sketch/verify.d.ts +53 -0
  410. package/dist/sketch/verify.d.ts.map +1 -0
  411. package/dist/sketch/verify.js +71 -0
  412. package/dist/sketch/verify.js.map +1 -0
  413. package/dist/topology/naming/geom-hint.d.ts +12 -0
  414. package/dist/topology/naming/geom-hint.d.ts.map +1 -1
  415. package/dist/topology/naming/geom-hint.js +1 -1
  416. package/dist/topology/naming/geom-hint.js.map +1 -1
  417. package/dist/topology/naming/lineage.d.ts +1 -0
  418. package/dist/topology/naming/lineage.d.ts.map +1 -1
  419. package/dist/topology/naming/lineage.js +37 -1
  420. package/dist/topology/naming/lineage.js.map +1 -1
  421. package/dist/topology/naming/resolve-face.d.ts +13 -2
  422. package/dist/topology/naming/resolve-face.d.ts.map +1 -1
  423. package/dist/topology/naming/resolve-face.js +18 -2
  424. package/dist/topology/naming/resolve-face.js.map +1 -1
  425. package/dist/weapp.d.ts +1 -1
  426. package/dist/weapp.d.ts.map +1 -1
  427. package/dist/weapp.js +1 -1
  428. package/dist/weapp.js.map +1 -1
  429. package/package.json +43 -11
@@ -6,7 +6,8 @@
6
6
  *
7
7
  * 与 brepjs 的差异:
8
8
  * - brepjs 用 BlueprintSketcher 构造 wire → 本项目直接用 kernel.makeLineEdge / makeBezierEdge
9
- * - brepjs 用 organiseBlueprints 处理孔洞 → 本项目用 makeFace 直接构建(OCCT 自动处理内孔)
9
+ * - brepjs 用 organiseBlueprints 处理孔洞 → 本项目用 makeFace + addHolesInFace 构建
10
+ * (分类复用 `primitives/svg/svg-path.ts` 的共享 classifyNested,与 svg-to-solid 同源)
10
11
  * - brepjs 用 sketchOnPlane → 本项目直接在 XY 平面构造然后按需变换
11
12
  *
12
13
  * opentype.js 路径命令 → OCCT edge 映射:
@@ -15,8 +16,20 @@
15
16
  * - C (cubicBezier) → kernel.makeBezierEdge([p0, cp1, cp2, p1])
16
17
  * - Q (quadraticBezier) → 转换为三次贝塞尔后用 makeBezierEdge
17
18
  * - Z (closePath) → 闭合 wire
19
+ *
20
+ * 孔洞与组合(2026-10-13 修复,见 .agents/notes/ 对应 Agent Note):
21
+ * - 旧实现把每个闭合轮廓独立 makeFace+extrude 后**逐个 fuse**:带孔字符(如 'o')
22
+ * 的外轮廓体与内孔体被布尔并成一个实心体,孔被填实(与 mesh 路径的 evenodd
23
+ * 分类不一致);且 fuse 次数 = 轮廓数,'Hello' ≈ 8-12 次 OCCT 布尔是文字建模
24
+ * 10 秒级耗时的主因。
25
+ * - 新实现:轮廓按包含关系分组(外轮廓 + 其孔,复用 classifyNested)→ 每组
26
+ * makeFace(outer) + addHolesInFace(holes) 挖孔 → extrude;字符间互不重叠,
27
+ * **用 makeCompound 组合(零布尔成本)**,不再逐轮廓 fuse。
18
28
  */
19
29
  import { getFont } from './fontRegistry.js';
30
+ import { classifyNested, computeBBox, computeSignedArea, } from '../../primitives/svg/svg-path.js';
31
+ /** 每条曲线离散化的采样段数(分类用的点集精度:bbox/质心/射线足够)。 */
32
+ const CURVE_SAMPLES = 8;
20
33
  /**
21
34
  * 将 opentype.js 坐标转为 OCCT 点(XY 平面,Z=0)。
22
35
  *
@@ -57,15 +70,31 @@ function quadToCubic(p0, cp, p2) {
57
70
  function makeBezierFromPoints(kernel, p0, c1, c2, p1) {
58
71
  return kernel.makeBezierEdge([p0, c1, c2, p1]);
59
72
  }
73
+ /** 三次贝塞尔在 t 处的采样点(用于轮廓分类点集)。 */
74
+ function sampleCubic(p0, c1, c2, p1, t) {
75
+ const mt = 1 - t;
76
+ const a = mt * mt * mt;
77
+ const b = 3 * mt * mt * t;
78
+ const c = 3 * mt * t * t;
79
+ const d = t * t * t;
80
+ return {
81
+ x: a * p0.x + b * c1.x + c * c2.x + d * p1.x,
82
+ y: a * p0.y + b * c1.y + c * c2.y + d * p1.y,
83
+ };
84
+ }
60
85
  /**
61
- * 将文字转换为 OCCT wire 数组(每个闭合轮廓一个 wire)。
86
+ * 将文字转换为 OCCT wire 数组(每个闭合轮廓一个 wire),并带各轮廓的
87
+ * 采样点集(供 classifyNested 做外轮廓/孔洞分类)。
88
+ *
89
+ * 采样点:L 端点、Q/C 按 CURVE_SAMPLES 段离散化 —— 与 mesh 路径
90
+ * `opentypePathToContours` 的曲线折线化同一用途(bbox/质心/射线判定精度足够)。
62
91
  *
63
92
  * @param kernel OCCT 内核
64
93
  * @param text 文字字符串
65
94
  * @param options 配置选项
66
- * @returns BrepHandle 数组(每个是一个闭合 wire)
95
+ * @returns 每个闭合轮廓的 { wire, points }(points 为 Y-up 采样点)
67
96
  */
68
- export function textBlueprints(kernel, text, options = {}) {
97
+ export function textBlueprintsDetailed(kernel, text, options = {}) {
69
98
  const { startX = 0, startY = 0, fontSize = 16, fontFamily = 'default' } = options;
70
99
  let font = getFont(fontFamily);
71
100
  if (!font)
@@ -89,6 +118,7 @@ export function textBlueprints(kernel, text, options = {}) {
89
118
  const wires = [];
90
119
  const allEdges = [];
91
120
  let currentEdges = [];
121
+ let currentPoints = [];
92
122
  let lastPt = null;
93
123
  let subpathStart = null;
94
124
  for (const cmd of commands) {
@@ -97,18 +127,21 @@ export function textBlueprints(kernel, text, options = {}) {
97
127
  // 开始新子路径 — 如果当前有 edges,先构建 wire
98
128
  if (currentEdges.length > 0) {
99
129
  const wire = kernel.makeWire(currentEdges);
100
- wires.push(wire);
130
+ wires.push({ wire, points: currentPoints });
101
131
  allEdges.push(...currentEdges);
102
132
  currentEdges = [];
133
+ currentPoints = [];
103
134
  }
104
135
  lastPt = toPt(cmd.x, cmd.y);
105
136
  subpathStart = lastPt;
137
+ currentPoints.push({ x: lastPt.x, y: lastPt.y });
106
138
  break;
107
139
  }
108
140
  case 'L': {
109
141
  if (!lastPt) {
110
142
  lastPt = toPt(cmd.x, cmd.y);
111
143
  subpathStart = lastPt;
144
+ currentPoints.push({ x: lastPt.x, y: lastPt.y });
112
145
  break;
113
146
  }
114
147
  const curr = toPt(cmd.x, cmd.y);
@@ -117,6 +150,7 @@ export function textBlueprints(kernel, text, options = {}) {
117
150
  const edge = kernel.makeLineEdge(lastPt, curr);
118
151
  currentEdges.push(edge);
119
152
  allEdges.push(edge);
153
+ currentPoints.push({ x: curr.x, y: curr.y });
120
154
  }
121
155
  lastPt = curr;
122
156
  break;
@@ -131,6 +165,10 @@ export function textBlueprints(kernel, text, options = {}) {
131
165
  const edge = makeBezierFromPoints(kernel, lastPt, c1, c2, endPt);
132
166
  currentEdges.push(edge);
133
167
  allEdges.push(edge);
168
+ // 采样曲线点(端点已含)——与 makeBezierEdge 同一组控制点
169
+ for (let s = 1; s <= CURVE_SAMPLES; s++) {
170
+ currentPoints.push(sampleCubic(lastPt, c1, c2, endPt, s / CURVE_SAMPLES));
171
+ }
134
172
  lastPt = endPt;
135
173
  break;
136
174
  }
@@ -143,6 +181,9 @@ export function textBlueprints(kernel, text, options = {}) {
143
181
  const edge = makeBezierFromPoints(kernel, lastPt, c1, c2, endPt);
144
182
  currentEdges.push(edge);
145
183
  allEdges.push(edge);
184
+ for (let s = 1; s <= CURVE_SAMPLES; s++) {
185
+ currentPoints.push(sampleCubic(lastPt, c1, c2, endPt, s / CURVE_SAMPLES));
186
+ }
146
187
  lastPt = endPt;
147
188
  break;
148
189
  }
@@ -154,12 +195,21 @@ export function textBlueprints(kernel, text, options = {}) {
154
195
  currentEdges.push(edge);
155
196
  allEdges.push(edge);
156
197
  }
198
+ // 闭合点回归起点(pointInPolygon 的射线判定要求多边形闭合)
199
+ if (subpathStart && currentPoints.length > 0) {
200
+ const s = currentPoints[0];
201
+ const l = currentPoints[currentPoints.length - 1];
202
+ if (Math.abs(s.x - l.x) > 1e-9 || Math.abs(s.y - l.y) > 1e-9) {
203
+ currentPoints.push(s);
204
+ }
205
+ }
157
206
  // 构建 wire
158
207
  if (currentEdges.length > 0) {
159
208
  const wire = kernel.makeWire(currentEdges);
160
- wires.push(wire);
209
+ wires.push({ wire, points: currentPoints });
161
210
  allEdges.push(...currentEdges);
162
211
  currentEdges = [];
212
+ currentPoints = [];
163
213
  }
164
214
  lastPt = null;
165
215
  subpathStart = null;
@@ -170,7 +220,7 @@ export function textBlueprints(kernel, text, options = {}) {
170
220
  // 处理最后一个未闭合的子路径
171
221
  if (currentEdges.length > 0) {
172
222
  const wire = kernel.makeWire(currentEdges);
173
- wires.push(wire);
223
+ wires.push({ wire, points: currentPoints });
174
224
  allEdges.push(...currentEdges);
175
225
  }
176
226
  // 释放所有边(wire 已共享 TShape)
@@ -180,24 +230,53 @@ export function textBlueprints(kernel, text, options = {}) {
180
230
  return wires;
181
231
  }
182
232
  /**
183
- * 将文字转换为 OCCT 3D solid(face → extrude → fuse)。
233
+ * 将文字转换为 OCCT wire 数组(每个闭合轮廓一个 wire)。
234
+ *
235
+ * @param kernel OCCT 内核
236
+ * @param text 文字字符串
237
+ * @param options 配置选项
238
+ * @returns BrepHandle 数组(每个是一个闭合 wire)
239
+ */
240
+ export function textBlueprints(kernel, text, options = {}) {
241
+ return textBlueprintsDetailed(kernel, text, options).map((d) => d.wire);
242
+ }
243
+ /**
244
+ * 将文字转换为 OCCT 3D solid(face → 挖孔 → extrude → compound)。
245
+ *
246
+ * 每个「外轮廓 + 其孔」分组生成一个空心 solid(makeFace + addHolesInFace);
247
+ * 分组之间(字符 / 互不重叠的独立轮廓,如 'i' 的点)**用 makeCompound 组合**,
248
+ * 不做布尔融合 —— 字符水平排列互不重叠,compound 语义正确且零布尔成本
249
+ * (旧实现逐个 fuse 是文字建模慢的根因,也是 'o' 孔被填实的成因)。
184
250
  *
185
251
  * @param kernel OCCT 内核
186
252
  * @param text 文字字符串
187
253
  * @param options 配置选项
188
- * @returns BrepHandle(合并后的 solid)
254
+ * @returns BrepHandle(单组时为 solid,多组时为 compound)
189
255
  */
190
256
  export function textToSolid(kernel, text, options) {
191
257
  const { fontSize = 16, fontFamily = 'default', depth } = options;
192
- const wires = textBlueprints(kernel, text, { fontSize, fontFamily });
193
- if (wires.length === 0) {
258
+ const detailed = textBlueprintsDetailed(kernel, text, { fontSize, fontFamily });
259
+ if (detailed.length === 0) {
194
260
  throw new Error('[textToSolid] no wires generated from text');
195
261
  }
196
- // 为每个 wire 创建 face → extrude
262
+ // 轮廓分类:外轮廓 + 孔(复用 svg 共享 classifyNested;text 字符水平排布、字形
263
+ // 直立,bbox 预筛 + 质心射线足够,与 mesh 路径的 evenodd 分类同源)。
264
+ const subpaths = detailed.map((d) => ({
265
+ points: d.points,
266
+ bbox: computeBBox(d.points),
267
+ signedArea: computeSignedArea(d.points),
268
+ }));
269
+ const groups = classifyNested(subpaths);
270
+ // 为每个分组创建 face(挖孔)→ extrude
197
271
  const solids = [];
198
- for (const wire of wires) {
272
+ for (const g of groups) {
199
273
  try {
200
- const face = kernel.makeFace(wire);
274
+ let face = kernel.makeFace(detailed[g.outerIdx].wire);
275
+ if (g.holes.length > 0) {
276
+ const holed = kernel.addHolesInFace(face, g.holes.map((h) => detailed[h].wire));
277
+ kernel.release(face);
278
+ face = holed;
279
+ }
201
280
  const solid = kernel.extrude(face, 0, 0, depth);
202
281
  kernel.release(face);
203
282
  solids.push(solid);
@@ -205,19 +284,20 @@ export function textToSolid(kernel, text, options) {
205
284
  catch {
206
285
  // 某些 wire 可能无法构建 face(如开放线框)— 跳过
207
286
  }
208
- kernel.release(wire);
287
+ }
288
+ // 释放所有 wire(face/solid 已共享 TShape)
289
+ for (const d of detailed) {
290
+ kernel.release(d.wire);
209
291
  }
210
292
  if (solids.length === 0) {
211
293
  throw new Error('[textToSolid] no solids generated from wires');
212
294
  }
213
- // Fuse 所有 solid
214
- let result = solids[0];
215
- for (let i = 1; i < solids.length; i++) {
216
- const prev = result;
217
- result = kernel.fuse(prev, solids[i]);
218
- kernel.release(prev);
219
- kernel.release(solids[i]);
220
- }
221
- return result;
295
+ if (solids.length === 1)
296
+ return solids[0];
297
+ // 多组:compound 组合(不 fuse —— 组间互不重叠,布尔是多余且昂贵的操作)。
298
+ const compound = kernel.makeCompound(solids);
299
+ for (const s of solids)
300
+ kernel.release(s);
301
+ return compound;
222
302
  }
223
303
  //# sourceMappingURL=text-to-solid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"text-to-solid.js","sourceRoot":"","sources":["../../../src/brep/text/text-to-solid.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 文字 → OCCT wire/face 转换\n *\n * 适配自 brepjs `src/text/text-to-solid.ts`。\n * 保留文件名和核心算法,适配本项目的 occt-wasm API。\n *\n * 与 brepjs 的差异:\n * - brepjs 用 BlueprintSketcher 构造 wire → 本项目直接用 kernel.makeLineEdge / makeBezierEdge\n * - brepjs 用 organiseBlueprints 处理孔洞 → 本项目用 makeFace 直接构建(OCCT 自动处理内孔)\n * - brepjs 用 sketchOnPlane → 本项目直接在 XY 平面构造然后按需变换\n *\n * opentype.js 路径命令 → OCCT edge 映射:\n * - M (moveTo) → 开始新子路径\n * - L (lineTo) → kernel.makeLineEdge(prev, curr)\n * - C (cubicBezier) → kernel.makeBezierEdge([p0, cp1, cp2, p1])\n * - Q (quadraticBezier) → 转换为三次贝塞尔后用 makeBezierEdge\n * - Z (closePath) → 闭合 wire\n */\n\nimport type { BrepHandle } from '../engine/types'\nimport type { BrepEngineApi } from '../engine/primitives'\nimport type { Font } from 'opentype.js'\nimport type { PathCommand } from 'opentype.js'\nimport { getFont } from './fontRegistry'\n\n/** 点坐标(OCCT 格式) */\ninterface Pt { x: number; y: number; z: number }\n\n/**\n * 将 opentype.js 坐标转为 OCCT 点(XY 平面,Z=0)。\n *\n * opentype.js 的 path 是 **y 向下**(canvas 约定:字形主体在负 y),OCCT 是\n * **y 向上**,故这里翻转 y —— 与 `../svg/svg-to-solid.ts` 的 `flipY`\n * (SVG Y-down → OCCT Y-up)同一约定。X 不翻转,文字从左到右。\n */\nfunction toPt(x: number, y: number): Pt {\n return { x, y: -y, z: 0 }\n}\n\n/**\n * 将 opentype.js 二次贝塞尔转换为三次贝塞尔的控制点。\n *\n * Q: P0 → P1 (cp) → P2\n * C: P0 → C1 → C2 → P2\n * C1 = P0 + 2/3 * (P1 - P0) = (2*P1 + P0) / 3\n * C2 = P2 + 2/3 * (P1 - P2) = (2*P1 + P2) / 3\n */\nfunction quadToCubic(\n p0: Pt, cp: Pt, p2: Pt,\n): [Pt, Pt] {\n const c1 = {\n x: (2 * cp.x + p0.x) / 3,\n y: (2 * cp.y + p0.y) / 3,\n z: 0,\n }\n const c2 = {\n x: (2 * cp.x + p2.x) / 3,\n y: (2 * cp.y + p2.y) / 3,\n z: 0,\n }\n return [c1, c2]\n}\n\n/**\n * 用 OCCT 贝塞尔边构造一段三次贝塞尔曲线。\n *\n * 三次贝塞尔曲线有 4 个控制点:P0, C1, C2, P1。\n * occt-wasm 的 makeBezierEdge 接受 Vec3[] 控制点数组。\n */\nfunction makeBezierFromPoints(\n kernel: BrepEngineApi,\n p0: Pt, c1: Pt, c2: Pt, p1: Pt,\n): BrepHandle {\n return kernel.makeBezierEdge([p0, c1, c2, p1])\n}\n\n/**\n * 将文字转换为 OCCT wire 数组(每个闭合轮廓一个 wire)。\n *\n * @param kernel OCCT 内核\n * @param text 文字字符串\n * @param options 配置选项\n * @returns BrepHandle 数组(每个是一个闭合 wire)\n */\nexport function textBlueprints(\n kernel: BrepEngineApi,\n text: string,\n options: {\n startX?: number\n startY?: number\n fontSize?: number\n fontFamily?: string\n } = {},\n): BrepHandle[] {\n const { startX = 0, startY = 0, fontSize = 16, fontFamily = 'default' } = options\n\n let font: Font | undefined = getFont(fontFamily)\n if (!font) font = getFont()\n if (!font) {\n throw new Error('[textBlueprints] No fonts loaded. Call loadFont() before using text functions.')\n }\n\n // 检查缺字形(CJK 字符在 OpenSans Regular 中没有对应字形)\n for (const ch of text) {\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') continue\n const glyph = font.charToGlyph(ch)\n if (glyph.index === 0) {\n throw new Error(\n `[textBlueprints] Character \"${ch}\" (U+${ch.codePointAt(0)!.toString(16).toUpperCase()}) ` +\n `not found in font. If it is a CJK character, a CJK font must be loaded.`,\n )\n }\n }\n\n // 获取文字路径\n const path = font.getPath(text, startX, startY, fontSize)\n const commands = path.commands as PathCommand[]\n\n const wires: BrepHandle[] = []\n const allEdges: BrepHandle[] = []\n\n let currentEdges: BrepHandle[] = []\n let lastPt: Pt | null = null\n let subpathStart: Pt | null = null\n\n for (const cmd of commands) {\n switch (cmd.type) {\n case 'M': {\n // 开始新子路径 — 如果当前有 edges,先构建 wire\n if (currentEdges.length > 0) {\n const wire = kernel.makeWire(currentEdges)\n wires.push(wire)\n allEdges.push(...currentEdges)\n currentEdges = []\n }\n lastPt = toPt(cmd.x!, cmd.y!)\n subpathStart = lastPt\n break\n }\n case 'L': {\n if (!lastPt) {\n lastPt = toPt(cmd.x!, cmd.y!)\n subpathStart = lastPt\n break\n }\n const curr = toPt(cmd.x!, cmd.y!)\n // 跳过零长度边\n if (Math.abs(curr.x - lastPt.x) > 1e-9 || Math.abs(curr.y - lastPt.y) > 1e-9) {\n const edge = kernel.makeLineEdge(lastPt, curr)\n currentEdges.push(edge)\n allEdges.push(edge)\n }\n lastPt = curr\n break\n }\n case 'Q': {\n if (!lastPt) break\n const cp = toPt(cmd.x1!, cmd.y1!)\n const endPt = toPt(cmd.x!, cmd.y!)\n // 转换为三次贝塞尔\n const [c1, c2] = quadToCubic(lastPt, cp, endPt)\n const edge = makeBezierFromPoints(kernel, lastPt, c1, c2, endPt)\n currentEdges.push(edge)\n allEdges.push(edge)\n lastPt = endPt\n break\n }\n case 'C': {\n if (!lastPt) break\n const c1 = toPt(cmd.x1!, cmd.y1!)\n const c2 = toPt(cmd.x2!, cmd.y2!)\n const endPt = toPt(cmd.x!, cmd.y!)\n const edge = makeBezierFromPoints(kernel, lastPt, c1, c2, endPt)\n currentEdges.push(edge)\n allEdges.push(edge)\n lastPt = endPt\n break\n }\n case 'Z': {\n // 闭合 — 如果有起点,添加闭合边\n if (subpathStart && lastPt &&\n (Math.abs(subpathStart.x - lastPt.x) > 1e-9 || Math.abs(subpathStart.y - lastPt.y) > 1e-9)) {\n const edge = kernel.makeLineEdge(lastPt, subpathStart)\n currentEdges.push(edge)\n allEdges.push(edge)\n }\n // 构建 wire\n if (currentEdges.length > 0) {\n const wire = kernel.makeWire(currentEdges)\n wires.push(wire)\n allEdges.push(...currentEdges)\n currentEdges = []\n }\n lastPt = null\n subpathStart = null\n break\n }\n }\n }\n\n // 处理最后一个未闭合的子路径\n if (currentEdges.length > 0) {\n const wire = kernel.makeWire(currentEdges)\n wires.push(wire)\n allEdges.push(...currentEdges)\n }\n\n // 释放所有边(wire 已共享 TShape)\n for (const e of allEdges) {\n kernel.release(e)\n }\n\n return wires\n}\n\n/**\n * 将文字转换为 OCCT 3D solid(face → extrude → fuse)。\n *\n * @param kernel OCCT 内核\n * @param text 文字字符串\n * @param options 配置选项\n * @returns BrepHandle(合并后的 solid)\n */\nexport function textToSolid(\n kernel: BrepEngineApi,\n text: string,\n options: {\n fontSize?: number\n fontFamily?: string\n depth: number\n },\n): BrepHandle {\n const { fontSize = 16, fontFamily = 'default', depth } = options\n\n const wires = textBlueprints(kernel, text, { fontSize, fontFamily })\n\n if (wires.length === 0) {\n throw new Error('[textToSolid] no wires generated from text')\n }\n\n // 为每个 wire 创建 face → extrude\n const solids: BrepHandle[] = []\n for (const wire of wires) {\n try {\n const face = kernel.makeFace(wire)\n const solid = kernel.extrude(face, 0, 0, depth)\n kernel.release(face)\n solids.push(solid)\n } catch {\n // 某些 wire 可能无法构建 face(如开放线框)— 跳过\n }\n kernel.release(wire)\n }\n\n if (solids.length === 0) {\n throw new Error('[textToSolid] no solids generated from wires')\n }\n\n // Fuse 所有 solid\n let result = solids[0]\n for (let i = 1; i < solids.length; i++) {\n const prev = result\n result = kernel.fuse(prev, solids[i])\n kernel.release(prev)\n kernel.release(solids[i])\n }\n\n return result\n}\n"]}
1
+ {"version":3,"file":"text-to-solid.js","sourceRoot":"","sources":["../../../src/brep/text/text-to-solid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACxC,OAAO,EACL,cAAc,EACd,WAAW,EACX,iBAAiB,GAGlB,MAAM,+BAA+B,CAAA;AAKtC,2CAA2C;AAC3C,MAAM,aAAa,GAAG,CAAC,CAAA;AAEvB;;;;;;GAMG;AACH,SAAS,IAAI,CAAC,CAAS,EAAE,CAAS;IAChC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,WAAW,CAClB,EAAM,EAAE,EAAM,EAAE,EAAM;IAEtB,MAAM,EAAE,GAAG;QACT,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACxB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACxB,CAAC,EAAE,CAAC;KACL,CAAA;IACD,MAAM,EAAE,GAAG;QACT,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACxB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACxB,CAAC,EAAE,CAAC;KACL,CAAA;IACD,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AACjB,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAC3B,MAAqB,EACrB,EAAM,EAAE,EAAM,EAAE,EAAM,EAAE,EAAM;IAE9B,OAAO,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AAChD,CAAC;AAED,gCAAgC;AAChC,SAAS,WAAW,CAClB,EAAM,EAAE,EAAM,EAAE,EAAM,EAAE,EAAM,EAAE,CAAS;IAEzC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IAChB,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;IACtB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACzB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IACxB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACnB,OAAO;QACL,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;KAC7C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAqB,EACrB,IAAY,EACZ,UAKI,EAAE;IAEN,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE,UAAU,GAAG,SAAS,EAAE,GAAG,OAAO,CAAA;IAEjF,IAAI,IAAI,GAAqB,OAAO,CAAC,UAAU,CAAC,CAAA;IAChD,IAAI,CAAC,IAAI;QAAE,IAAI,GAAG,OAAO,EAAE,CAAA;IAC3B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAA;IACnG,CAAC;IAED,0CAA0C;IAC1C,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI;YAAE,SAAQ;QACrE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAClC,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,+BAA+B,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI;gBAC1F,yEAAyE,CAC1E,CAAA;QACH,CAAC;IACH,CAAC;IAED,SAAS;IACT,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAyB,CAAA;IAE/C,MAAM,KAAK,GAAgD,EAAE,CAAA;IAC7D,MAAM,QAAQ,GAAiB,EAAE,CAAA;IAEjC,IAAI,YAAY,GAAiB,EAAE,CAAA;IACnC,IAAI,aAAa,GAAgB,EAAE,CAAA;IACnC,IAAI,MAAM,GAAc,IAAI,CAAA;IAC5B,IAAI,YAAY,GAAc,IAAI,CAAA;IAElC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,gCAAgC;gBAChC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;oBAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAA;oBAC3C,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAA;oBAC9B,YAAY,GAAG,EAAE,CAAA;oBACjB,aAAa,GAAG,EAAE,CAAA;gBACpB,CAAC;gBACD,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,GAAG,CAAC,CAAE,CAAC,CAAA;gBAC7B,YAAY,GAAG,MAAM,CAAA;gBACrB,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;gBAChD,MAAK;YACP,CAAC;YACD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,GAAG,CAAC,CAAE,CAAC,CAAA;oBAC7B,YAAY,GAAG,MAAM,CAAA;oBACrB,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;oBAChD,MAAK;gBACP,CAAC;gBACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,GAAG,CAAC,CAAE,CAAC,CAAA;gBACjC,SAAS;gBACT,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;oBAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;oBAC9C,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACvB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACnB,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;gBAC9C,CAAC;gBACD,MAAM,GAAG,IAAI,CAAA;gBACb,MAAK;YACP,CAAC;YACD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,IAAI,CAAC,MAAM;oBAAE,MAAK;gBAClB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAG,EAAE,GAAG,CAAC,EAAG,CAAC,CAAA;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,GAAG,CAAC,CAAE,CAAC,CAAA;gBAClC,WAAW;gBACX,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;gBAC/C,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;gBAChE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACvB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACnB,uCAAuC;gBACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;oBACxC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAA;gBAC3E,CAAC;gBACD,MAAM,GAAG,KAAK,CAAA;gBACd,MAAK;YACP,CAAC;YACD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,IAAI,CAAC,MAAM;oBAAE,MAAK;gBAClB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAG,EAAE,GAAG,CAAC,EAAG,CAAC,CAAA;gBACjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAG,EAAE,GAAG,CAAC,EAAG,CAAC,CAAA;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,GAAG,CAAC,CAAE,CAAC,CAAA;gBAClC,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;gBAChE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACvB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;oBACxC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAA;gBAC3E,CAAC;gBACD,MAAM,GAAG,KAAK,CAAA;gBACd,MAAK;YACP,CAAC;YACD,KAAK,GAAG,CAAC,CAAC,CAAC;gBACT,mBAAmB;gBACnB,IAAI,YAAY,IAAI,MAAM;oBACtB,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;oBAC/F,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;oBACtD,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACvB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACrB,CAAC;gBACD,uCAAuC;gBACvC,IAAI,YAAY,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7C,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;oBAC1B,MAAM,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;oBACjD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;wBAC7D,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;oBACvB,CAAC;gBACH,CAAC;gBACD,UAAU;gBACV,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;oBAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAA;oBAC3C,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAA;oBAC9B,YAAY,GAAG,EAAE,CAAA;oBACjB,aAAa,GAAG,EAAE,CAAA;gBACpB,CAAC;gBACD,MAAM,GAAG,IAAI,CAAA;gBACb,YAAY,GAAG,IAAI,CAAA;gBACnB,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAA;QAC3C,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAA;IAChC,CAAC;IAED,yBAAyB;IACzB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAqB,EACrB,IAAY,EACZ,UAKI,EAAE;IAEN,OAAO,sBAAsB,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AACzE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CACzB,MAAqB,EACrB,IAAY,EACZ,OAIC;IAED,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IAEhE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAA;IAE/E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;IAC/D,CAAC;IAED,uDAAuD;IACvD,gDAAgD;IAChD,MAAM,QAAQ,GAA0B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3D,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3B,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC;KACxC,CAAC,CAAC,CAAA;IACH,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAEvC,4BAA4B;IAC5B,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,IAAI,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAA;YACrD,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;gBAC/E,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBACpB,IAAI,GAAG,KAAK,CAAA;YACd,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;YAC/C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YACpB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IAEzC,gDAAgD;IAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;IAC5C,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACzC,OAAO,QAAQ,CAAA;AACjB,CAAC","sourcesContent":["/**\n * 文字 → OCCT wire/face 转换\n *\n * 适配自 brepjs `src/text/text-to-solid.ts`。\n * 保留文件名和核心算法,适配本项目的 occt-wasm API。\n *\n * 与 brepjs 的差异:\n * - brepjs 用 BlueprintSketcher 构造 wire → 本项目直接用 kernel.makeLineEdge / makeBezierEdge\n * - brepjs 用 organiseBlueprints 处理孔洞 → 本项目用 makeFace + addHolesInFace 构建\n * (分类复用 `primitives/svg/svg-path.ts` 的共享 classifyNested,与 svg-to-solid 同源)\n * - brepjs 用 sketchOnPlane → 本项目直接在 XY 平面构造然后按需变换\n *\n * opentype.js 路径命令 → OCCT edge 映射:\n * - M (moveTo) → 开始新子路径\n * - L (lineTo) → kernel.makeLineEdge(prev, curr)\n * - C (cubicBezier) → kernel.makeBezierEdge([p0, cp1, cp2, p1])\n * - Q (quadraticBezier) → 转换为三次贝塞尔后用 makeBezierEdge\n * - Z (closePath) → 闭合 wire\n *\n * 孔洞与组合(2026-10-13 修复,见 .agents/notes/ 对应 Agent Note):\n * - 旧实现把每个闭合轮廓独立 makeFace+extrude 后**逐个 fuse**:带孔字符(如 'o')\n * 的外轮廓体与内孔体被布尔并成一个实心体,孔被填实(与 mesh 路径的 evenodd\n * 分类不一致);且 fuse 次数 = 轮廓数,'Hello' ≈ 8-12 次 OCCT 布尔是文字建模\n * 10 秒级耗时的主因。\n * - 新实现:轮廓按包含关系分组(外轮廓 + 其孔,复用 classifyNested)→ 每组\n * makeFace(outer) + addHolesInFace(holes) 挖孔 → extrude;字符间互不重叠,\n * **用 makeCompound 组合(零布尔成本)**,不再逐轮廓 fuse。\n */\n\nimport type { BrepHandle } from '../engine/types'\nimport type { BrepEngineApi } from '../engine/primitives'\nimport type { Font } from 'opentype.js'\nimport type { PathCommand } from 'opentype.js'\nimport { getFont } from './fontRegistry'\nimport {\n classifyNested,\n computeBBox,\n computeSignedArea,\n type ClassifiableSubpath,\n type SvgPoint2,\n} from '../../primitives/svg/svg-path'\n\n/** 点坐标(OCCT 格式) */\ninterface Pt { x: number; y: number; z: number }\n\n/** 每条曲线离散化的采样段数(分类用的点集精度:bbox/质心/射线足够)。 */\nconst CURVE_SAMPLES = 8\n\n/**\n * 将 opentype.js 坐标转为 OCCT 点(XY 平面,Z=0)。\n *\n * opentype.js 的 path 是 **y 向下**(canvas 约定:字形主体在负 y),OCCT 是\n * **y 向上**,故这里翻转 y —— 与 `../svg/svg-to-solid.ts` 的 `flipY`\n * (SVG Y-down → OCCT Y-up)同一约定。X 不翻转,文字从左到右。\n */\nfunction toPt(x: number, y: number): Pt {\n return { x, y: -y, z: 0 }\n}\n\n/**\n * 将 opentype.js 二次贝塞尔转换为三次贝塞尔的控制点。\n *\n * Q: P0 → P1 (cp) → P2\n * C: P0 → C1 → C2 → P2\n * C1 = P0 + 2/3 * (P1 - P0) = (2*P1 + P0) / 3\n * C2 = P2 + 2/3 * (P1 - P2) = (2*P1 + P2) / 3\n */\nfunction quadToCubic(\n p0: Pt, cp: Pt, p2: Pt,\n): [Pt, Pt] {\n const c1 = {\n x: (2 * cp.x + p0.x) / 3,\n y: (2 * cp.y + p0.y) / 3,\n z: 0,\n }\n const c2 = {\n x: (2 * cp.x + p2.x) / 3,\n y: (2 * cp.y + p2.y) / 3,\n z: 0,\n }\n return [c1, c2]\n}\n\n/**\n * 用 OCCT 贝塞尔边构造一段三次贝塞尔曲线。\n *\n * 三次贝塞尔曲线有 4 个控制点:P0, C1, C2, P1。\n * occt-wasm 的 makeBezierEdge 接受 Vec3[] 控制点数组。\n */\nfunction makeBezierFromPoints(\n kernel: BrepEngineApi,\n p0: Pt, c1: Pt, c2: Pt, p1: Pt,\n): BrepHandle {\n return kernel.makeBezierEdge([p0, c1, c2, p1])\n}\n\n/** 三次贝塞尔在 t 处的采样点(用于轮廓分类点集)。 */\nfunction sampleCubic(\n p0: Pt, c1: Pt, c2: Pt, p1: Pt, t: number,\n): SvgPoint2 {\n const mt = 1 - t\n const a = mt * mt * mt\n const b = 3 * mt * mt * t\n const c = 3 * mt * t * t\n const d = t * t * t\n return {\n x: a * p0.x + b * c1.x + c * c2.x + d * p1.x,\n y: a * p0.y + b * c1.y + c * c2.y + d * p1.y,\n }\n}\n\n/**\n * 将文字转换为 OCCT wire 数组(每个闭合轮廓一个 wire),并带各轮廓的\n * 采样点集(供 classifyNested 做外轮廓/孔洞分类)。\n *\n * 采样点:L 端点、Q/C 按 CURVE_SAMPLES 段离散化 —— 与 mesh 路径\n * `opentypePathToContours` 的曲线折线化同一用途(bbox/质心/射线判定精度足够)。\n *\n * @param kernel OCCT 内核\n * @param text 文字字符串\n * @param options 配置选项\n * @returns 每个闭合轮廓的 { wire, points }(points 为 Y-up 采样点)\n */\nexport function textBlueprintsDetailed(\n kernel: BrepEngineApi,\n text: string,\n options: {\n startX?: number\n startY?: number\n fontSize?: number\n fontFamily?: string\n } = {},\n): { wire: BrepHandle; points: SvgPoint2[] }[] {\n const { startX = 0, startY = 0, fontSize = 16, fontFamily = 'default' } = options\n\n let font: Font | undefined = getFont(fontFamily)\n if (!font) font = getFont()\n if (!font) {\n throw new Error('[textBlueprints] No fonts loaded. Call loadFont() before using text functions.')\n }\n\n // 检查缺字形(CJK 字符在 OpenSans Regular 中没有对应字形)\n for (const ch of text) {\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') continue\n const glyph = font.charToGlyph(ch)\n if (glyph.index === 0) {\n throw new Error(\n `[textBlueprints] Character \"${ch}\" (U+${ch.codePointAt(0)!.toString(16).toUpperCase()}) ` +\n `not found in font. If it is a CJK character, a CJK font must be loaded.`,\n )\n }\n }\n\n // 获取文字路径\n const path = font.getPath(text, startX, startY, fontSize)\n const commands = path.commands as PathCommand[]\n\n const wires: { wire: BrepHandle; points: SvgPoint2[] }[] = []\n const allEdges: BrepHandle[] = []\n\n let currentEdges: BrepHandle[] = []\n let currentPoints: SvgPoint2[] = []\n let lastPt: Pt | null = null\n let subpathStart: Pt | null = null\n\n for (const cmd of commands) {\n switch (cmd.type) {\n case 'M': {\n // 开始新子路径 — 如果当前有 edges,先构建 wire\n if (currentEdges.length > 0) {\n const wire = kernel.makeWire(currentEdges)\n wires.push({ wire, points: currentPoints })\n allEdges.push(...currentEdges)\n currentEdges = []\n currentPoints = []\n }\n lastPt = toPt(cmd.x!, cmd.y!)\n subpathStart = lastPt\n currentPoints.push({ x: lastPt.x, y: lastPt.y })\n break\n }\n case 'L': {\n if (!lastPt) {\n lastPt = toPt(cmd.x!, cmd.y!)\n subpathStart = lastPt\n currentPoints.push({ x: lastPt.x, y: lastPt.y })\n break\n }\n const curr = toPt(cmd.x!, cmd.y!)\n // 跳过零长度边\n if (Math.abs(curr.x - lastPt.x) > 1e-9 || Math.abs(curr.y - lastPt.y) > 1e-9) {\n const edge = kernel.makeLineEdge(lastPt, curr)\n currentEdges.push(edge)\n allEdges.push(edge)\n currentPoints.push({ x: curr.x, y: curr.y })\n }\n lastPt = curr\n break\n }\n case 'Q': {\n if (!lastPt) break\n const cp = toPt(cmd.x1!, cmd.y1!)\n const endPt = toPt(cmd.x!, cmd.y!)\n // 转换为三次贝塞尔\n const [c1, c2] = quadToCubic(lastPt, cp, endPt)\n const edge = makeBezierFromPoints(kernel, lastPt, c1, c2, endPt)\n currentEdges.push(edge)\n allEdges.push(edge)\n // 采样曲线点(端点已含)——与 makeBezierEdge 同一组控制点\n for (let s = 1; s <= CURVE_SAMPLES; s++) {\n currentPoints.push(sampleCubic(lastPt, c1, c2, endPt, s / CURVE_SAMPLES))\n }\n lastPt = endPt\n break\n }\n case 'C': {\n if (!lastPt) break\n const c1 = toPt(cmd.x1!, cmd.y1!)\n const c2 = toPt(cmd.x2!, cmd.y2!)\n const endPt = toPt(cmd.x!, cmd.y!)\n const edge = makeBezierFromPoints(kernel, lastPt, c1, c2, endPt)\n currentEdges.push(edge)\n allEdges.push(edge)\n for (let s = 1; s <= CURVE_SAMPLES; s++) {\n currentPoints.push(sampleCubic(lastPt, c1, c2, endPt, s / CURVE_SAMPLES))\n }\n lastPt = endPt\n break\n }\n case 'Z': {\n // 闭合 — 如果有起点,添加闭合边\n if (subpathStart && lastPt &&\n (Math.abs(subpathStart.x - lastPt.x) > 1e-9 || Math.abs(subpathStart.y - lastPt.y) > 1e-9)) {\n const edge = kernel.makeLineEdge(lastPt, subpathStart)\n currentEdges.push(edge)\n allEdges.push(edge)\n }\n // 闭合点回归起点(pointInPolygon 的射线判定要求多边形闭合)\n if (subpathStart && currentPoints.length > 0) {\n const s = currentPoints[0]\n const l = currentPoints[currentPoints.length - 1]\n if (Math.abs(s.x - l.x) > 1e-9 || Math.abs(s.y - l.y) > 1e-9) {\n currentPoints.push(s)\n }\n }\n // 构建 wire\n if (currentEdges.length > 0) {\n const wire = kernel.makeWire(currentEdges)\n wires.push({ wire, points: currentPoints })\n allEdges.push(...currentEdges)\n currentEdges = []\n currentPoints = []\n }\n lastPt = null\n subpathStart = null\n break\n }\n }\n }\n\n // 处理最后一个未闭合的子路径\n if (currentEdges.length > 0) {\n const wire = kernel.makeWire(currentEdges)\n wires.push({ wire, points: currentPoints })\n allEdges.push(...currentEdges)\n }\n\n // 释放所有边(wire 已共享 TShape)\n for (const e of allEdges) {\n kernel.release(e)\n }\n\n return wires\n}\n\n/**\n * 将文字转换为 OCCT wire 数组(每个闭合轮廓一个 wire)。\n *\n * @param kernel OCCT 内核\n * @param text 文字字符串\n * @param options 配置选项\n * @returns BrepHandle 数组(每个是一个闭合 wire)\n */\nexport function textBlueprints(\n kernel: BrepEngineApi,\n text: string,\n options: {\n startX?: number\n startY?: number\n fontSize?: number\n fontFamily?: string\n } = {},\n): BrepHandle[] {\n return textBlueprintsDetailed(kernel, text, options).map((d) => d.wire)\n}\n\n/**\n * 将文字转换为 OCCT 3D solid(face → 挖孔 → extrude → compound)。\n *\n * 每个「外轮廓 + 其孔」分组生成一个空心 solid(makeFace + addHolesInFace);\n * 分组之间(字符 / 互不重叠的独立轮廓,如 'i' 的点)**用 makeCompound 组合**,\n * 不做布尔融合 —— 字符水平排列互不重叠,compound 语义正确且零布尔成本\n * (旧实现逐个 fuse 是文字建模慢的根因,也是 'o' 孔被填实的成因)。\n *\n * @param kernel OCCT 内核\n * @param text 文字字符串\n * @param options 配置选项\n * @returns BrepHandle(单组时为 solid,多组时为 compound)\n */\nexport function textToSolid(\n kernel: BrepEngineApi,\n text: string,\n options: {\n fontSize?: number\n fontFamily?: string\n depth: number\n },\n): BrepHandle {\n const { fontSize = 16, fontFamily = 'default', depth } = options\n\n const detailed = textBlueprintsDetailed(kernel, text, { fontSize, fontFamily })\n\n if (detailed.length === 0) {\n throw new Error('[textToSolid] no wires generated from text')\n }\n\n // 轮廓分类:外轮廓 + 孔(复用 svg 共享 classifyNested;text 字符水平排布、字形\n // 直立,bbox 预筛 + 质心射线足够,与 mesh 路径的 evenodd 分类同源)。\n const subpaths: ClassifiableSubpath[] = detailed.map((d) => ({\n points: d.points,\n bbox: computeBBox(d.points),\n signedArea: computeSignedArea(d.points),\n }))\n const groups = classifyNested(subpaths)\n\n // 为每个分组创建 face(挖孔)→ extrude\n const solids: BrepHandle[] = []\n for (const g of groups) {\n try {\n let face = kernel.makeFace(detailed[g.outerIdx].wire)\n if (g.holes.length > 0) {\n const holed = kernel.addHolesInFace(face, g.holes.map((h) => detailed[h].wire))\n kernel.release(face)\n face = holed\n }\n const solid = kernel.extrude(face, 0, 0, depth)\n kernel.release(face)\n solids.push(solid)\n } catch {\n // 某些 wire 可能无法构建 face(如开放线框)— 跳过\n }\n }\n\n // 释放所有 wire(face/solid 已共享 TShape)\n for (const d of detailed) {\n kernel.release(d.wire)\n }\n\n if (solids.length === 0) {\n throw new Error('[textToSolid] no solids generated from wires')\n }\n\n if (solids.length === 1) return solids[0]\n\n // 多组:compound 组合(不 fuse —— 组间互不重叠,布尔是多余且昂贵的操作)。\n const compound = kernel.makeCompound(solids)\n for (const s of solids) kernel.release(s)\n return compound\n}\n"]}
@@ -9,7 +9,7 @@
9
9
  * `api/surface/engine-method-map.json` 的 aligned/dialect 条目)。brepkit 独有
10
10
  * 能力(chamfer2d/chamferV2/filletV2/sketch* 族、serializeSolid、meshBoolean、
11
11
  * minkowskiSum …)与单方语义(loft、平面 section/split 之外的 splitter 语义…)
12
- * 都不在本对象里——平台代码经原生面 `getBrepkitKernel()`(D3)访问。
12
+ * 都不在本对象里——平台代码经原生面 `getBrepKitKernel()`(D3)访问。
13
13
  *
14
14
  * 设计要点(对应 3d_editor 项目的 weapp-voice-ai-modeling 设计计划 §5):
15
15
  * - 句柄:brepkit u32 句柄与 faijs BrepHandle(number) 同构,直通零转换;
@@ -49,7 +49,7 @@ export declare function createBrepkitPrimitives(): Promise<BrepkitEngineExtras>;
49
49
  *
50
50
  * @returns the live brepkit wasm kernel singleton.
51
51
  */
52
- export declare function getBrepkitKernel(): BrepKitKernel;
52
+ export declare function getBrepKitKernel(): BrepKitKernel;
53
53
  /**
54
54
  * 释放内核单例(测试收尾用;宿主常驻不需调用)。
55
55
  *
@@ -1 +1 @@
1
- {"version":3,"file":"brepkitKernel.d.ts","sourceRoot":"","sources":["../../src/brepkit-kernel/brepkitKernel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAGrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAoO9D,6DAA6D;AAC7D,KAAK,mBAAmB,GAAG,aAAa,GAAG;IACzC,oBAAoB,IAAI,MAAM,CAAA;IAC9B;;;;;;;OAOG;IACH,SAAS,EAAE,OAAO,oBAAoB,EAAE,kBAAkB,CAAA;CAC3D,CAAA;AAkDD;;;;;GAKG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CA0wC5E;AAwDD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAQrC;AAED,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"brepkitKernel.d.ts","sourceRoot":"","sources":["../../src/brepkit-kernel/brepkitKernel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAGrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAiP9D,6DAA6D;AAC7D,KAAK,mBAAmB,GAAG,aAAa,GAAG;IACzC,oBAAoB,IAAI,MAAM,CAAA;IAC9B;;;;;;;OAOG;IACH,SAAS,EAAE,OAAO,oBAAoB,EAAE,kBAAkB,CAAA;CAC3D,CAAA;AAkDD;;;;;GAKG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAm+C5E;AA6ID;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAQrC;AAED,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAA"}