@faicad/faijs 0.22.2 → 0.29.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/LICENSE +202 -28
  2. package/dist/api/api-namespace.d.ts +5 -5
  3. package/dist/api/api-namespace.d.ts.map +1 -1
  4. package/dist/api/api-namespace.js +4 -4
  5. package/dist/api/api-namespace.js.map +1 -1
  6. package/dist/api/assert.d.ts +2 -2
  7. package/dist/api/assert.js +8 -8
  8. package/dist/api/assert.js.map +1 -1
  9. package/dist/api/asset.d.ts +1 -1
  10. package/dist/api/asset.js +2 -2
  11. package/dist/api/asset.js.map +1 -1
  12. package/dist/api/boolean.d.ts +1 -1
  13. package/dist/api/boolean.d.ts.map +1 -1
  14. package/dist/api/boolean.js +128 -16
  15. package/dist/api/boolean.js.map +1 -1
  16. package/dist/api/cadquery-selectors/borrow-bridge.d.ts +14 -0
  17. package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -0
  18. package/dist/api/cadquery-selectors/borrow-bridge.js +52 -0
  19. package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -0
  20. package/dist/api/cadquery-selectors/edge.d.ts +40 -0
  21. package/dist/api/cadquery-selectors/edge.d.ts.map +1 -0
  22. package/dist/api/cadquery-selectors/edge.js +70 -0
  23. package/dist/api/cadquery-selectors/edge.js.map +1 -0
  24. package/dist/api/cadquery-selectors/entity.d.ts +121 -0
  25. package/dist/api/cadquery-selectors/entity.d.ts.map +1 -0
  26. package/dist/api/cadquery-selectors/entity.js +167 -0
  27. package/dist/api/cadquery-selectors/entity.js.map +1 -0
  28. package/dist/api/cadquery-selectors/face.d.ts +33 -0
  29. package/dist/api/cadquery-selectors/face.d.ts.map +1 -0
  30. package/dist/api/cadquery-selectors/face.js +353 -0
  31. package/dist/api/cadquery-selectors/face.js.map +1 -0
  32. package/dist/api/cadquery-selectors/grammar.d.ts +50 -0
  33. package/dist/api/cadquery-selectors/grammar.d.ts.map +1 -0
  34. package/dist/api/cadquery-selectors/grammar.js +345 -0
  35. package/dist/api/cadquery-selectors/grammar.js.map +1 -0
  36. package/dist/api/cadquery-selectors/index.d.ts +18 -0
  37. package/dist/api/cadquery-selectors/index.d.ts.map +1 -0
  38. package/dist/api/cadquery-selectors/index.js +17 -0
  39. package/dist/api/cadquery-selectors/index.js.map +1 -0
  40. package/dist/api/cadquery-selectors/predicates.d.ts +76 -0
  41. package/dist/api/cadquery-selectors/predicates.d.ts.map +1 -0
  42. package/dist/api/cadquery-selectors/predicates.js +85 -0
  43. package/dist/api/cadquery-selectors/predicates.js.map +1 -0
  44. package/dist/api/cadquery-selectors/resolve.d.ts +41 -0
  45. package/dist/api/cadquery-selectors/resolve.d.ts.map +1 -0
  46. package/dist/api/cadquery-selectors/resolve.js +243 -0
  47. package/dist/api/cadquery-selectors/resolve.js.map +1 -0
  48. package/dist/api/cadquery-selectors/types.d.ts +96 -0
  49. package/dist/api/cadquery-selectors/types.d.ts.map +1 -0
  50. package/dist/api/cadquery-selectors/types.js +11 -0
  51. package/dist/api/cadquery-selectors/types.js.map +1 -0
  52. package/dist/api/chamfer.d.ts +13 -5
  53. package/dist/api/chamfer.d.ts.map +1 -1
  54. package/dist/api/chamfer.js +63 -7
  55. package/dist/api/chamfer.js.map +1 -1
  56. package/dist/api/compound-geom.d.ts +1 -1
  57. package/dist/api/compound-geom.js +1 -1
  58. package/dist/api/compound-geom.js.map +1 -1
  59. package/dist/api/draft.d.ts +1 -1
  60. package/dist/api/draft.js +1 -1
  61. package/dist/api/draft.js.map +1 -1
  62. package/dist/api/edge-ref.d.ts +1 -1
  63. package/dist/api/edge-ref.d.ts.map +1 -1
  64. package/dist/api/edge-ref.js +11 -3
  65. package/dist/api/edge-ref.js.map +1 -1
  66. package/dist/api/engrave.d.ts +1 -1
  67. package/dist/api/engrave.js +7 -7
  68. package/dist/api/engrave.js.map +1 -1
  69. package/dist/api/extrude.d.ts +6 -1
  70. package/dist/api/extrude.d.ts.map +1 -1
  71. package/dist/api/extrude.js +59 -5
  72. package/dist/api/extrude.js.map +1 -1
  73. package/dist/api/face-ref.d.ts +1 -1
  74. package/dist/api/face-ref.js +1 -1
  75. package/dist/api/face-ref.js.map +1 -1
  76. package/dist/api/feature-repair.d.ts +1 -1
  77. package/dist/api/feature-repair.js +1 -1
  78. package/dist/api/feature-repair.js.map +1 -1
  79. package/dist/api/fillet-variable.d.ts +1 -1
  80. package/dist/api/fillet-variable.js +1 -1
  81. package/dist/api/fillet-variable.js.map +1 -1
  82. package/dist/api/fillet.d.ts +28 -8
  83. package/dist/api/fillet.d.ts.map +1 -1
  84. package/dist/api/fillet.js +64 -9
  85. package/dist/api/fillet.js.map +1 -1
  86. package/dist/api/geom.d.ts +1 -1
  87. package/dist/api/geom.js +1 -1
  88. package/dist/api/geom.js.map +1 -1
  89. package/dist/api/helix.d.ts +1 -1
  90. package/dist/api/helix.js +1 -1
  91. package/dist/api/helix.js.map +1 -1
  92. package/dist/api/import-brep.d.ts +20 -2
  93. package/dist/api/import-brep.d.ts.map +1 -1
  94. package/dist/api/import-brep.js +28 -3
  95. package/dist/api/import-brep.js.map +1 -1
  96. package/dist/api/import-step.d.ts +17 -2
  97. package/dist/api/import-step.d.ts.map +1 -1
  98. package/dist/api/import-step.js +23 -3
  99. package/dist/api/import-step.js.map +1 -1
  100. package/dist/api/index.d.ts +2 -1
  101. package/dist/api/index.d.ts.map +1 -1
  102. package/dist/api/index.js +5 -2
  103. package/dist/api/index.js.map +1 -1
  104. package/dist/api/internal/compat-op.js +1 -1
  105. package/dist/api/internal/compat-op.js.map +1 -1
  106. package/dist/api/internal/mesh-solid-op.d.ts +236 -0
  107. package/dist/api/internal/mesh-solid-op.d.ts.map +1 -0
  108. package/dist/api/internal/mesh-solid-op.js +352 -0
  109. package/dist/api/internal/mesh-solid-op.js.map +1 -0
  110. package/dist/api/internal/svg-asset-resolver.d.ts +1 -1
  111. package/dist/api/internal/svg-asset-resolver.js +1 -1
  112. package/dist/api/internal/svg-asset-resolver.js.map +1 -1
  113. package/dist/api/knurl.d.ts +1 -1
  114. package/dist/api/knurl.js +2 -2
  115. package/dist/api/knurl.js.map +1 -1
  116. package/dist/api/loft.d.ts +1 -1
  117. package/dist/api/loft.js +1 -1
  118. package/dist/api/loft.js.map +1 -1
  119. package/dist/api/measurement/index.d.ts +9 -5
  120. package/dist/api/measurement/index.d.ts.map +1 -1
  121. package/dist/api/measurement/index.js +47 -20
  122. package/dist/api/measurement/index.js.map +1 -1
  123. package/dist/api/pattern.d.ts +5 -3
  124. package/dist/api/pattern.d.ts.map +1 -1
  125. package/dist/api/pattern.js +32 -4
  126. package/dist/api/pattern.js.map +1 -1
  127. package/dist/api/place.d.ts +1 -1
  128. package/dist/api/place.js +1 -1
  129. package/dist/api/place.js.map +1 -1
  130. package/dist/api/primitives.d.ts +1 -1
  131. package/dist/api/primitives.js +2 -2
  132. package/dist/api/primitives.js.map +1 -1
  133. package/dist/api/profile.d.ts +39 -12
  134. package/dist/api/profile.d.ts.map +1 -1
  135. package/dist/api/profile.js +4 -4
  136. package/dist/api/profile.js.map +1 -1
  137. package/dist/api/reconcile.d.ts +1 -1
  138. package/dist/api/reconcile.js +1 -1
  139. package/dist/api/reconcile.js.map +1 -1
  140. package/dist/api/replicate.d.ts.map +1 -1
  141. package/dist/api/replicate.js +122 -1
  142. package/dist/api/replicate.js.map +1 -1
  143. package/dist/api/screw.d.ts +1 -1
  144. package/dist/api/screw.js +3 -3
  145. package/dist/api/screw.js.map +1 -1
  146. package/dist/api/sdf.d.ts +1 -1
  147. package/dist/api/sdf.js +2 -2
  148. package/dist/api/sdf.js.map +1 -1
  149. package/dist/api/section-by-plane.d.ts +1 -1
  150. package/dist/api/section-by-plane.d.ts.map +1 -1
  151. package/dist/api/section-by-plane.js +2 -1
  152. package/dist/api/section-by-plane.js.map +1 -1
  153. package/dist/api/shell.d.ts +11 -4
  154. package/dist/api/shell.d.ts.map +1 -1
  155. package/dist/api/shell.js +53 -7
  156. package/dist/api/shell.js.map +1 -1
  157. package/dist/api/sketch-on-face.d.ts +41 -0
  158. package/dist/api/sketch-on-face.d.ts.map +1 -1
  159. package/dist/api/sketch-on-face.js +100 -1
  160. package/dist/api/sketch-on-face.js.map +1 -1
  161. package/dist/api/sketch-on-plane.d.ts +7 -5
  162. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  163. package/dist/api/sketch-on-plane.js +6 -7
  164. package/dist/api/sketch-on-plane.js.map +1 -1
  165. package/dist/api/split-by-plane.d.ts +1 -1
  166. package/dist/api/split-by-plane.d.ts.map +1 -1
  167. package/dist/api/split-by-plane.js +2 -1
  168. package/dist/api/split-by-plane.js.map +1 -1
  169. package/dist/api/split.d.ts +1 -1
  170. package/dist/api/split.js +2 -2
  171. package/dist/api/split.js.map +1 -1
  172. package/dist/api/sweep.d.ts +1 -1
  173. package/dist/api/sweep.js +1 -1
  174. package/dist/api/sweep.js.map +1 -1
  175. package/dist/api/thicken.d.ts +1 -1
  176. package/dist/api/thicken.js +1 -1
  177. package/dist/api/thicken.js.map +1 -1
  178. package/dist/api/topo-resolve.d.ts +74 -1
  179. package/dist/api/topo-resolve.d.ts.map +1 -1
  180. package/dist/api/topo-resolve.js +180 -2
  181. package/dist/api/topo-resolve.js.map +1 -1
  182. package/dist/api/transform.d.ts +5 -1
  183. package/dist/api/transform.d.ts.map +1 -1
  184. package/dist/api/transform.js +62 -11
  185. package/dist/api/transform.js.map +1 -1
  186. package/dist/api/wire.d.ts +1 -1
  187. package/dist/api/wire.js +1 -1
  188. package/dist/api/wire.js.map +1 -1
  189. package/dist/brep/brep-ops.d.ts +9 -7
  190. package/dist/brep/brep-ops.d.ts.map +1 -1
  191. package/dist/brep/brep-ops.js +23 -24
  192. package/dist/brep/brep-ops.js.map +1 -1
  193. package/dist/brep/brep-topology.d.ts +5 -4
  194. package/dist/brep/brep-topology.d.ts.map +1 -1
  195. package/dist/brep/brep-topology.js +6 -5
  196. package/dist/brep/brep-topology.js.map +1 -1
  197. package/dist/brep/effective-deflection.d.ts +35 -0
  198. package/dist/brep/effective-deflection.d.ts.map +1 -0
  199. package/dist/brep/effective-deflection.js +49 -0
  200. package/dist/brep/effective-deflection.js.map +1 -0
  201. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  202. package/dist/brep/engine/adapters/brep-mock.js +27 -0
  203. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  204. package/dist/brep/engine/adapters/brepkit.d.ts +18 -0
  205. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  206. package/dist/brep/engine/adapters/brepkit.js +46 -1
  207. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  208. package/dist/brep/engine/adapters/occt.d.ts +1 -1
  209. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  210. package/dist/brep/engine/adapters/occt.js +3 -1
  211. package/dist/brep/engine/adapters/occt.js.map +1 -1
  212. package/dist/brep/engine/primitives.d.ts +29 -7
  213. package/dist/brep/engine/primitives.d.ts.map +1 -1
  214. package/dist/brep/engine/primitives.js.map +1 -1
  215. package/dist/brep/engine/registry.d.ts +24 -1
  216. package/dist/brep/engine/registry.d.ts.map +1 -1
  217. package/dist/brep/engine/registry.js +24 -0
  218. package/dist/brep/engine/registry.js.map +1 -1
  219. package/dist/brep/engine/types.d.ts +54 -3
  220. package/dist/brep/engine/types.d.ts.map +1 -1
  221. package/dist/brep/engine/types.js +10 -0
  222. package/dist/brep/engine/types.js.map +1 -1
  223. package/dist/brep/export/export-model.d.ts.map +1 -1
  224. package/dist/brep/export/export-model.js +6 -5
  225. package/dist/brep/export/export-model.js.map +1 -1
  226. package/dist/brep/face-evolution.d.ts +1 -1
  227. package/dist/brep/face-evolution.d.ts.map +1 -1
  228. package/dist/brep/face-evolution.js +20 -1
  229. package/dist/brep/face-evolution.js.map +1 -1
  230. package/dist/brep/handle-bridge.d.ts +1 -1
  231. package/dist/brep/handle-bridge.js +1 -1
  232. package/dist/brep/handle-bridge.js.map +1 -1
  233. package/dist/brep/mesh-solid.d.ts +218 -0
  234. package/dist/brep/mesh-solid.d.ts.map +1 -0
  235. package/dist/brep/mesh-solid.js +229 -0
  236. package/dist/brep/mesh-solid.js.map +1 -0
  237. package/dist/brep/text/fontRegistry.d.ts +32 -1
  238. package/dist/brep/text/fontRegistry.d.ts.map +1 -1
  239. package/dist/brep/text/fontRegistry.js +51 -1
  240. package/dist/brep/text/fontRegistry.js.map +1 -1
  241. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  242. package/dist/brep/text/text-to-solid.js +8 -3
  243. package/dist/brep/text/text-to-solid.js.map +1 -1
  244. package/dist/brepkit-kernel/brepkitKernel.d.ts +18 -2
  245. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  246. package/dist/brepkit-kernel/brepkitKernel.js +449 -123
  247. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  248. package/dist/brepkit-kernel/brepkitWasm.d.ts +8 -0
  249. package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
  250. package/dist/brepkit-kernel/brepkitWasm.js +10 -0
  251. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  252. package/dist/browser-host/browser-font-provider.d.ts +12 -0
  253. package/dist/browser-host/browser-font-provider.d.ts.map +1 -1
  254. package/dist/browser-host/browser-font-provider.js +25 -0
  255. package/dist/browser-host/browser-font-provider.js.map +1 -1
  256. package/dist/browser.d.ts +6 -3
  257. package/dist/browser.d.ts.map +1 -1
  258. package/dist/browser.js +10 -3
  259. package/dist/browser.js.map +1 -1
  260. package/dist/cad-runtime/backend-dispatch.d.ts +28 -3
  261. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  262. package/dist/cad-runtime/backend-dispatch.js +119 -4
  263. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  264. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  265. package/dist/cad-runtime/direct-executor.d.ts +15 -3
  266. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  267. package/dist/cad-runtime/direct-executor.js +33 -1
  268. package/dist/cad-runtime/direct-executor.js.map +1 -1
  269. package/dist/cad-runtime/ports.d.ts +3 -3
  270. package/dist/cad-runtime/ports.d.ts.map +1 -1
  271. package/dist/cad-runtime/ports.js.map +1 -1
  272. package/dist/cad-runtime/preview-exec.d.ts +4 -4
  273. package/dist/cad-runtime/preview-exec.js +2 -2
  274. package/dist/cad-runtime/preview-exec.js.map +1 -1
  275. package/dist/cad-runtime/runtime.d.ts +42 -7
  276. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  277. package/dist/cad-runtime/runtime.js +68 -5
  278. package/dist/cad-runtime/runtime.js.map +1 -1
  279. package/dist/define-op.d.ts +15 -1
  280. package/dist/define-op.d.ts.map +1 -1
  281. package/dist/define-op.js +10 -1
  282. package/dist/define-op.js.map +1 -1
  283. package/dist/env-agnostic.d.ts +2 -2
  284. package/dist/env-agnostic.d.ts.map +1 -1
  285. package/dist/env-agnostic.js +1 -1
  286. package/dist/env-agnostic.js.map +1 -1
  287. package/dist/geometry2d/adapt.d.ts +39 -4
  288. package/dist/geometry2d/adapt.d.ts.map +1 -1
  289. package/dist/geometry2d/adapt.js +14 -3
  290. package/dist/geometry2d/adapt.js.map +1 -1
  291. package/dist/geometry2d/blueprint.d.ts +2 -2
  292. package/dist/geometry2d/blueprint.js +2 -2
  293. package/dist/geometry2d/blueprint.js.map +1 -1
  294. package/dist/geometry2d/bridge/lift-on-plane.d.ts +18 -8
  295. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  296. package/dist/geometry2d/bridge/lift-on-plane.js +65 -12
  297. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  298. package/dist/geometry2d/bridge/plane.d.ts +17 -0
  299. package/dist/geometry2d/bridge/plane.d.ts.map +1 -1
  300. package/dist/geometry2d/bridge/plane.js +22 -0
  301. package/dist/geometry2d/bridge/plane.js.map +1 -1
  302. package/dist/geometry2d/curve2d.d.ts +25 -0
  303. package/dist/geometry2d/curve2d.d.ts.map +1 -1
  304. package/dist/geometry2d/curve2d.js +41 -5
  305. package/dist/geometry2d/curve2d.js.map +1 -1
  306. package/dist/index.d.ts +6 -2
  307. package/dist/index.d.ts.map +1 -1
  308. package/dist/index.js +10 -3
  309. package/dist/index.js.map +1 -1
  310. package/dist/io/bytes-node.d.ts +11 -0
  311. package/dist/io/bytes-node.d.ts.map +1 -0
  312. package/dist/io/bytes-node.js +28 -0
  313. package/dist/io/bytes-node.js.map +1 -0
  314. package/dist/io/bytes.d.ts +33 -0
  315. package/dist/io/bytes.d.ts.map +1 -0
  316. package/dist/io/bytes.js +41 -0
  317. package/dist/io/bytes.js.map +1 -0
  318. package/dist/io/fai-zip/container-read.d.ts +102 -0
  319. package/dist/io/fai-zip/container-read.d.ts.map +1 -0
  320. package/dist/io/fai-zip/container-read.js +305 -0
  321. package/dist/io/fai-zip/container-read.js.map +1 -0
  322. package/dist/io/fai-zip/container-write.d.ts +70 -0
  323. package/dist/io/fai-zip/container-write.d.ts.map +1 -0
  324. package/dist/io/fai-zip/container-write.js +186 -0
  325. package/dist/io/fai-zip/container-write.js.map +1 -0
  326. package/dist/io/fai-zip/container.d.ts +107 -0
  327. package/dist/io/fai-zip/container.d.ts.map +1 -0
  328. package/dist/io/fai-zip/container.js +89 -0
  329. package/dist/io/fai-zip/container.js.map +1 -0
  330. package/dist/io/fai-zip/index.d.ts +18 -0
  331. package/dist/io/fai-zip/index.d.ts.map +1 -0
  332. package/dist/io/fai-zip/index.js +4 -0
  333. package/dist/io/fai-zip/index.js.map +1 -0
  334. package/dist/io/index.d.ts +10 -0
  335. package/dist/io/index.d.ts.map +1 -0
  336. package/dist/io/index.js +13 -0
  337. package/dist/io/index.js.map +1 -0
  338. package/dist/io/zip.d.ts +68 -0
  339. package/dist/io/zip.d.ts.map +1 -0
  340. package/dist/io/zip.js +147 -0
  341. package/dist/io/zip.js.map +1 -0
  342. package/dist/lang/code-to-args.d.ts +1 -1
  343. package/dist/lang/code-to-args.js +1 -1
  344. package/dist/lang/code-to-args.js.map +1 -1
  345. package/dist/lang/statement-summary.d.ts +1 -1
  346. package/dist/lang/statement-summary.js +1 -1
  347. package/dist/lang/statement-summary.js.map +1 -1
  348. package/dist/lang/types.d.ts +1 -1
  349. package/dist/lang/types.js +1 -1
  350. package/dist/lang/types.js.map +1 -1
  351. package/dist/mesh/index.d.ts +2 -1
  352. package/dist/mesh/index.d.ts.map +1 -1
  353. package/dist/mesh/index.js +2 -1
  354. package/dist/mesh/index.js.map +1 -1
  355. package/dist/mesh/io.d.ts +7 -0
  356. package/dist/mesh/io.d.ts.map +1 -1
  357. package/dist/mesh/io.js +14 -17
  358. package/dist/mesh/io.js.map +1 -1
  359. package/dist/mesh/reconcile.d.ts +1 -1
  360. package/dist/mesh/reconcile.js +1 -1
  361. package/dist/mesh/reconcile.js.map +1 -1
  362. package/dist/mesh/rigid-transform.d.ts +3 -3
  363. package/dist/mesh/rigid-transform.js +3 -3
  364. package/dist/mesh/rigid-transform.js.map +1 -1
  365. package/dist/mesh/stl-unit.d.ts +24 -0
  366. package/dist/mesh/stl-unit.d.ts.map +1 -0
  367. package/dist/mesh/stl-unit.js +17 -0
  368. package/dist/mesh/stl-unit.js.map +1 -0
  369. package/dist/mesh/threemf-bambu.d.ts +142 -0
  370. package/dist/mesh/threemf-bambu.d.ts.map +1 -0
  371. package/dist/mesh/threemf-bambu.js +334 -0
  372. package/dist/mesh/threemf-bambu.js.map +1 -0
  373. package/dist/mesh/threemf-loader.d.ts +42 -7
  374. package/dist/mesh/threemf-loader.d.ts.map +1 -1
  375. package/dist/mesh/threemf-loader.js +565 -100
  376. package/dist/mesh/threemf-loader.js.map +1 -1
  377. package/dist/mesh/threemf-view.d.ts +71 -0
  378. package/dist/mesh/threemf-view.d.ts.map +1 -0
  379. package/dist/mesh/threemf-view.js +100 -0
  380. package/dist/mesh/threemf-view.js.map +1 -0
  381. package/dist/node-host/cli.d.ts +44 -6
  382. package/dist/node-host/cli.d.ts.map +1 -1
  383. package/dist/node-host/cli.js +76 -26
  384. package/dist/node-host/cli.js.map +1 -1
  385. package/dist/node-host/font-family-index.d.ts +93 -0
  386. package/dist/node-host/font-family-index.d.ts.map +1 -0
  387. package/dist/node-host/font-family-index.js +273 -0
  388. package/dist/node-host/font-family-index.js.map +1 -0
  389. package/dist/node-host/fs-asset-resolver.d.ts +8 -3
  390. package/dist/node-host/fs-asset-resolver.d.ts.map +1 -1
  391. package/dist/node-host/fs-asset-resolver.js +13 -5
  392. package/dist/node-host/fs-asset-resolver.js.map +1 -1
  393. package/dist/node-host/index.d.ts +8 -0
  394. package/dist/node-host/index.d.ts.map +1 -1
  395. package/dist/node-host/index.js +1 -0
  396. package/dist/node-host/index.js.map +1 -1
  397. package/dist/node-host/node-font-provider.d.ts +28 -0
  398. package/dist/node-host/node-font-provider.d.ts.map +1 -1
  399. package/dist/node-host/node-font-provider.js +49 -0
  400. package/dist/node-host/node-font-provider.js.map +1 -1
  401. package/dist/node.d.ts +1 -0
  402. package/dist/node.d.ts.map +1 -1
  403. package/dist/node.js +1 -0
  404. package/dist/node.js.map +1 -1
  405. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  406. package/dist/occt-kernel/occt-primitives.js +35 -2
  407. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  408. package/dist/occt-kernel/occtKernel.d.ts +18 -13
  409. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  410. package/dist/occt-kernel/occtKernel.js +18 -31
  411. package/dist/occt-kernel/occtKernel.js.map +1 -1
  412. package/dist/occt-kernel/stepColorParser.d.ts +18 -0
  413. package/dist/occt-kernel/stepColorParser.d.ts.map +1 -1
  414. package/dist/occt-kernel/stepColorParser.js +38 -0
  415. package/dist/occt-kernel/stepColorParser.js.map +1 -1
  416. package/dist/occt-kernel/topologyExt.d.ts +1 -1
  417. package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
  418. package/dist/occt-kernel/topologyExt.js +4 -5
  419. package/dist/occt-kernel/topologyExt.js.map +1 -1
  420. package/dist/primitives/text/cjk-font.d.ts +2 -15
  421. package/dist/primitives/text/cjk-font.d.ts.map +1 -1
  422. package/dist/primitives/text/cjk-font.js +13 -1
  423. package/dist/primitives/text/cjk-font.js.map +1 -1
  424. package/dist/runtime-state.d.ts +85 -9
  425. package/dist/runtime-state.d.ts.map +1 -1
  426. package/dist/runtime-state.js +72 -2
  427. package/dist/runtime-state.js.map +1 -1
  428. package/dist/sdk.d.ts +3 -3
  429. package/dist/sdk.d.ts.map +1 -1
  430. package/dist/sdk.js +5 -5
  431. package/dist/sdk.js.map +1 -1
  432. package/dist/shape.d.ts +97 -2
  433. package/dist/shape.d.ts.map +1 -1
  434. package/dist/shape.js +126 -1
  435. package/dist/shape.js.map +1 -1
  436. package/dist/topology/naming/lineage.d.ts +6 -0
  437. package/dist/topology/naming/lineage.d.ts.map +1 -1
  438. package/dist/topology/naming/lineage.js +8 -0
  439. package/dist/topology/naming/lineage.js.map +1 -1
  440. package/dist/topology/naming/resolve-edge.d.ts +20 -1
  441. package/dist/topology/naming/resolve-edge.d.ts.map +1 -1
  442. package/dist/topology/naming/resolve-edge.js +54 -20
  443. package/dist/topology/naming/resolve-edge.js.map +1 -1
  444. package/dist/weapp.d.ts +6 -2
  445. package/dist/weapp.d.ts.map +1 -1
  446. package/dist/weapp.js +7 -1
  447. package/dist/weapp.js.map +1 -1
  448. package/package.json +18 -2
@@ -0,0 +1,218 @@
1
+ /**
2
+ * mesh-solid — 网格实体(mesh solid)与其网格后端端口
3
+ *
4
+ *
5
+ * 名词边界(方案 §3.1):
6
+ * - **网格实体** = 由网格文件导入、经「规范化」得到的引擎实体。它是**近似拓扑**
7
+ * 的载体,不是精度链的一环;永不进 `brepChain.solidCache`。
8
+ * - **规范化** = `importIndexedMesh` → `weldShellsAndFaces(tol)` → `unifyFaces()`。
9
+ * **顺序不可交换**:先 `unifyFaces` 会把实体做坏(体积归零),防回归用例见
10
+ * `brepkit-kernel/mesh-solid-topology.test.ts`。
11
+ * - **网格后端** = 提供网格实体能力的引擎侧组件(本期即 brepkit 的网格用法)。
12
+ * 与 BREP 引擎**同名不同用**:可能同一个 wasm 实例,但走 mesh 语义路径。
13
+ *
14
+ * 本模块只依赖 L1(`engine/types`、`engine/primitives`)与拓扑构建器;后端实现
15
+ * 放在适配器侧(`brep/engine/adapters/brepkit`),因此本模块自身不含任何内核私有
16
+ * 调用——`MeshSolidKernelOps` 是内核私有原语的端口(L1 契约不含 weld/unify)。
17
+ */
18
+ import type { BrepHandle, BrepMeshResult } from './engine/types.js';
19
+ import type { BrepEngineApi } from './engine/primitives.js';
20
+ import type { PartName } from '../identity.js';
21
+ import type { SelectorRuntimeData } from '../topology/build-selector-runtime.js';
22
+ /** 网格实体构建的输入网格(已按基准单位折算的坐标,与 `Shape` 同构)。 */
23
+ export interface MeshSolidInput {
24
+ positions: Float32Array;
25
+ indices: Uint32Array;
26
+ }
27
+ /** 规范化选项。 */
28
+ export interface MeshSolidNormalizeOptions {
29
+ /**
30
+ * 焊接容差(顶点/重复边缝合半径)。缺省由包围盒对角线定标
31
+ * (`max(1e-6, 对角线 × 1e-6)`)——**不得写死绝对值**:STL 无单位元数据,
32
+ * 同一文件既可能是 mm 也可能是 inch,绝对容差在两种尺度下必有一边失准。
33
+ */
34
+ weldTolerance?: number;
35
+ /** 三角化参数(缺省与显示 mesh 一致:0.1 / 2π/32)。 */
36
+ linearDeflection?: number;
37
+ angularDeflection?: number;
38
+ }
39
+ /** 规范化结果:实体句柄 + 其三角化(显示 mesh 与拓扑 mesh 的唯一真源)。 */
40
+ export interface MeshSolidResult {
41
+ /** 规范化后的网格实体句柄。 */
42
+ readonly solid: BrepHandle;
43
+ /**
44
+ * 同一实体的三角化(含 faceGroups)。**显示 mesh 必须用这一份**——规则 1:
45
+ * 拓扑 faceRuns 所索引的三角形,必须就是用户看到的三角形。若显示仍用原始
46
+ * STL 顶点数组、拓扑用实体的重新三角化,两者三角形数/序不一致 → faceRuns 错位。
47
+ */
48
+ readonly mesh: BrepMeshResult;
49
+ readonly faceCount: number;
50
+ readonly edgeCount: number;
51
+ readonly vertexCount: number;
52
+ /** 实际使用的焊接容差(诊断/复现用)。 */
53
+ readonly weldTolerance: number;
54
+ /** `unifyFaces` 合并掉的重复面数(0 = 共面面片未被合并,顶点未焊上)。 */
55
+ readonly mergedFaceCount: number;
56
+ }
57
+ /**
58
+ * 网格后端的**内核私有原语**(L1 `BrepEngineApi` 不含 weld/unify)。
59
+ *
60
+ * 由适配器(拥用内核闭包的一侧)实现;句柄一律是 faijs `BrepHandle`
61
+ * (适配器内部负责 `asNum()` 剥离标签),本模块不感知内核方言。
62
+ */
63
+ export interface MeshSolidKernelOps {
64
+ /** 原始三角网格 → 逐三角形面的实体(内核自带顶点焊接)。 */
65
+ importMesh(positions: Float32Array, indices: Uint32Array): BrepHandle;
66
+ /** 面列表 → 缝合后的实体(重复边缝成共享边 → 真流形)。 */
67
+ weld(faces: BrepHandle[], tolerance: number): BrepHandle;
68
+ /** 共面区域合并(**原地修改**,返回合并掉的面数)。 */
69
+ unify(solid: BrepHandle): number;
70
+ }
71
+ /**
72
+ * 网格后端端口:`load` 的 mesh 路径经它产出网格实体与近似拓扑。
73
+ *
74
+ * 生命周期:由宿主装配期注册进 mesh 引擎槽(`registerMeshEngine`),运行期只读。
75
+ */
76
+ export interface MeshSolidBackend {
77
+ /** 后端 id(与 `defineOp.meshEngines` 的门禁名同源,如 `'brepkit'`)。 */
78
+ readonly id: string;
79
+ /** L1 契约面(拓扑查询 + 几何操作;brepkit 适配器已全实现)。 */
80
+ readonly kernel: BrepEngineApi;
81
+ /** 内核私有原语(weld/unify)。 */
82
+ readonly ops: MeshSolidKernelOps;
83
+ /**
84
+ * 规范化 + 三角化。**失败必须抛错**(带 part 名由调用方补),不静默降级。
85
+ * @param mesh - the source triangle mesh (base-unit coordinates).
86
+ * @param opts - optional weld tolerance / tessellation overrides.
87
+ * @returns the mesh solid with its tessellation.
88
+ */
89
+ normalize(mesh: MeshSolidInput, opts?: MeshSolidNormalizeOptions): MeshSolidResult;
90
+ /**
91
+ * 已存在的网格实体 → 结果描述(三角化 + 计数)。Phase 2 的 mesh op 用它把
92
+ * 「内核操作产出的新实体」包成下一份网格零件(显示 mesh 与拓扑 mesh 同源)。
93
+ * @param solid - an existing mesh solid handle.
94
+ * @param opts - optional tessellation overrides.
95
+ * @returns the mesh solid result carrying the shared tessellation.
96
+ */
97
+ describe(solid: BrepHandle, opts?: MeshSolidNormalizeOptions): MeshSolidResult;
98
+ /**
99
+ * 从网格实体结果构建近似拓扑数据(`SelectorRuntimeData`,可直接交 `setTopology`)。
100
+ * @param result - the mesh solid result (its tessellation indexes the topology).
101
+ * @returns the serializable selector runtime data.
102
+ */
103
+ buildTopologyData(result: MeshSolidResult): SelectorRuntimeData;
104
+ /** 释放网格实体句柄。 */
105
+ release(solid: BrepHandle): void;
106
+ }
107
+ /**
108
+ * 由包围盒对角线导出焊接容差(方案 §3.3)。
109
+ *
110
+ * 下限 1e-6 兜住退化 bbox(单点/零厚网格);上不封顶——超大模型需要更粗的
111
+ * 缝合半径才缝得上(float32 坐标的相对误差随尺度线性增长)。
112
+ *
113
+ * @param kernel - the L1 kernel API (bbox query only).
114
+ * @param shape - the raw imported shape.
115
+ * @returns the weld tolerance derived from the bounding-box diagonal.
116
+ */
117
+ export declare function weldToleranceFor(kernel: BrepEngineApi, shape: BrepHandle): number;
118
+ /**
119
+ * 规范化:`importMesh` → `weld` → `unify`,再校验并三角化。
120
+ *
121
+ * 三条硬约束,都是 Phase 0 实测结论:
122
+ * 1. **顺序不可交换**——先 unify 再 weld 会得到体积归零的坏实体;
123
+ * 2. `unify` **原地修改**,返回值是合并面数,不是句柄;
124
+ * 3. 校验用 `isValid`(weld 后必须合法),不合法即抛错——开放/非流形网格必须
125
+ * 在导入处失败,不能静默退化成"无拓扑的裸网格"(那会让所有下游 mesh op
126
+ * 失去选择能力)。
127
+ *
128
+ * @param backend - the mesh backend providing ops + kernel.
129
+ * @param mesh - the source triangle mesh.
130
+ * @param opts - optional weld tolerance / tessellation overrides.
131
+ * @returns the normalized mesh solid, its tessellation, and element counts.
132
+ * @throws {Error} `E_MESH_SOLID_UNWELDABLE` when welding leaves an invalid solid.
133
+ */
134
+ export declare function normalizeMeshSolid(backend: MeshSolidBackend, mesh: MeshSolidInput, opts?: MeshSolidNormalizeOptions): MeshSolidResult;
135
+ /**
136
+ * 已存在的网格实体 → 结果描述(三角化 + 计数)。
137
+ *
138
+ * Phase 2 的 mesh op 产出的新实体走这里:**一次**三角化同时喂显示与拓扑,
139
+ * 保证 `faceRuns` 与所见三角形一一对应(规则 1)。重复调 `describe` 会得到
140
+ * 另一份三角化结果——同一实体在同一参数下确定性一致,但仍应复用同一份结果。
141
+ *
142
+ * @param backend - the mesh backend.
143
+ * @param solid - an existing mesh solid handle.
144
+ * @param opts - optional tessellation overrides.
145
+ * @returns the mesh solid result carrying the shared tessellation.
146
+ */
147
+ export declare function describeMeshSolid(backend: MeshSolidBackend, solid: BrepHandle, opts?: MeshSolidNormalizeOptions): MeshSolidResult;
148
+ /**
149
+ * 网格实体 → 近似拓扑数据(`SelectorRuntimeData`)。
150
+ *
151
+ * 复用 BREP 路径同源的 `buildTopologyFromMesh`(方案 §1.3 实测:产物与 BREP
152
+ * 路径同构——同样的 FaceRow/EdgeRow 字段、同样的 `faceStart/faceCount` 邻接)。
153
+ * **不引入第二套拓扑表示。**
154
+ *
155
+ * @param backend - the mesh backend (kernel + release).
156
+ * @param result - the normalized mesh solid result (carries the shared tessellation).
157
+ * @returns the serializable selector runtime data.
158
+ */
159
+ export declare function buildMeshSolidTopology(backend: MeshSolidBackend, result: MeshSolidResult): SelectorRuntimeData;
160
+ /**
161
+ * 网格实体句柄注册表(`PartName → BrepHandle`)。
162
+ *
163
+ * 与 `brepChain.solidCache` 的差别:本表**永不**参与 BREP 精度链判定——
164
+ * 它存在只表示"该 part 是网格零件,携带近似拓扑"。释放语义与 solidCache 对齐:
165
+ * `set` 覆盖不释放(旧句柄可能仍被旧输出 Shape 引用),`delete`/`clear` 释放。
166
+ */
167
+ export declare class MeshSolidRegistry {
168
+ private readonly handles;
169
+ private backendRef;
170
+ /**
171
+ * 装配/换装网格后端(宿主装配期;运行期只读语义)。
172
+ * @param backend - the mesh backend, or null to detach.
173
+ */
174
+ setBackend(backend: MeshSolidBackend | null): void;
175
+ /**
176
+ * 当前网格后端(未装配则 null)。
177
+ * @returns the assembled mesh backend, or null.
178
+ */
179
+ get backend(): MeshSolidBackend | null;
180
+ /**
181
+ * 登记某 part 的网格实体句柄(覆盖旧值,**不释放**旧句柄——与 solidCache 同语义)。
182
+ * @param part - the part name.
183
+ * @param solid - the mesh solid handle.
184
+ */
185
+ set(part: PartName, solid: BrepHandle): void;
186
+ /**
187
+ * 读取某 part 的网格实体句柄。
188
+ * @param part - the part name.
189
+ * @returns the handle, or undefined.
190
+ */
191
+ get(part: PartName): BrepHandle | undefined;
192
+ /**
193
+ * 该 part 是否携带网格实体。
194
+ * @param part - the part name.
195
+ * @returns true when a handle is registered.
196
+ */
197
+ has(part: PartName): boolean;
198
+ /**
199
+ * 删除某 part 并释放其句柄(重放/失效路径)。
200
+ * @param part - the part name.
201
+ */
202
+ delete(part: PartName): void;
203
+ /**
204
+ * 按 part 名列表批量删除(重放失效用)。
205
+ * @param parts - the part names to delete; unknown names are ignored.
206
+ */
207
+ deleteMany(parts: Iterable<PartName>): void;
208
+ /** 释放全部句柄并清空(dispose)。 */
209
+ clear(): void;
210
+ /**
211
+ * 当前登记的全部 part 名(诊断/测试)。
212
+ * @returns the registered part names.
213
+ */
214
+ keys(): PartName[];
215
+ /** 登记数量(诊断/测试)。 */
216
+ get size(): number;
217
+ }
218
+ //# sourceMappingURL=mesh-solid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-solid.d.ts","sourceRoot":"","sources":["../../src/brep/mesh-solid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * mesh-solid — 网格实体(mesh solid)与其网格后端端口
3
+ *
4
+ *
5
+ * 名词边界(方案 §3.1):
6
+ * - **网格实体** = 由网格文件导入、经「规范化」得到的引擎实体。它是**近似拓扑**
7
+ * 的载体,不是精度链的一环;永不进 `brepChain.solidCache`。
8
+ * - **规范化** = `importIndexedMesh` → `weldShellsAndFaces(tol)` → `unifyFaces()`。
9
+ * **顺序不可交换**:先 `unifyFaces` 会把实体做坏(体积归零),防回归用例见
10
+ * `brepkit-kernel/mesh-solid-topology.test.ts`。
11
+ * - **网格后端** = 提供网格实体能力的引擎侧组件(本期即 brepkit 的网格用法)。
12
+ * 与 BREP 引擎**同名不同用**:可能同一个 wasm 实例,但走 mesh 语义路径。
13
+ *
14
+ * 本模块只依赖 L1(`engine/types`、`engine/primitives`)与拓扑构建器;后端实现
15
+ * 放在适配器侧(`brep/engine/adapters/brepkit`),因此本模块自身不含任何内核私有
16
+ * 调用——`MeshSolidKernelOps` 是内核私有原语的端口(L1 契约不含 weld/unify)。
17
+ */
18
+ import { buildTopologyFromMesh } from './brep-topology.js';
19
+ // ── 规范化驱动(引擎中立,供适配器的 MeshSolidBackend 实现复用) ──
20
+ /** 与显示 mesh 一致的默认三角化参数(`buildSolidTopologyRuntime` 同源)。 */
21
+ const DISPLAY_LINEAR_DEFLECTION = 0.1;
22
+ const DISPLAY_ANGULAR_DEFLECTION = (2 * Math.PI) / 32;
23
+ /**
24
+ * 由包围盒对角线导出焊接容差(方案 §3.3)。
25
+ *
26
+ * 下限 1e-6 兜住退化 bbox(单点/零厚网格);上不封顶——超大模型需要更粗的
27
+ * 缝合半径才缝得上(float32 坐标的相对误差随尺度线性增长)。
28
+ *
29
+ * @param kernel - the L1 kernel API (bbox query only).
30
+ * @param shape - the raw imported shape.
31
+ * @returns the weld tolerance derived from the bounding-box diagonal.
32
+ */
33
+ export function weldToleranceFor(kernel, shape) {
34
+ const bb = kernel.getBoundingBox(shape, false);
35
+ const dx = bb.xmax - bb.xmin;
36
+ const dy = bb.ymax - bb.ymin;
37
+ const dz = bb.zmax - bb.zmin;
38
+ const diag = Math.sqrt(dx * dx + dy * dy + dz * dz);
39
+ return Math.max(1e-6, diag * 1e-6);
40
+ }
41
+ /**
42
+ * 规范化:`importMesh` → `weld` → `unify`,再校验并三角化。
43
+ *
44
+ * 三条硬约束,都是 Phase 0 实测结论:
45
+ * 1. **顺序不可交换**——先 unify 再 weld 会得到体积归零的坏实体;
46
+ * 2. `unify` **原地修改**,返回值是合并面数,不是句柄;
47
+ * 3. 校验用 `isValid`(weld 后必须合法),不合法即抛错——开放/非流形网格必须
48
+ * 在导入处失败,不能静默退化成"无拓扑的裸网格"(那会让所有下游 mesh op
49
+ * 失去选择能力)。
50
+ *
51
+ * @param backend - the mesh backend providing ops + kernel.
52
+ * @param mesh - the source triangle mesh.
53
+ * @param opts - optional weld tolerance / tessellation overrides.
54
+ * @returns the normalized mesh solid, its tessellation, and element counts.
55
+ * @throws {Error} `E_MESH_SOLID_UNWELDABLE` when welding leaves an invalid solid.
56
+ */
57
+ export function normalizeMeshSolid(backend, mesh, opts) {
58
+ const { kernel, ops } = backend;
59
+ const raw = ops.importMesh(mesh.positions, mesh.indices);
60
+ const tolerance = opts?.weldTolerance ?? weldToleranceFor(kernel, raw);
61
+ const faces = kernel.getSubShapes(raw, 'face');
62
+ const welded = ops.weld(faces, tolerance);
63
+ // 原地修改:返回值是合并掉的面数。绝不能把它当句柄。
64
+ const mergedFaceCount = ops.unify(welded);
65
+ if (!kernel.isValid(welded)) {
66
+ // 原始实体(逐三角形、边不共享)在 weld 前就不合法是正常的;weld 后仍不合法
67
+ // 说明网格本身开放/非流形/自交——这是**必须暴露的导入失败**,不是可降级状态。
68
+ try {
69
+ backend.release(raw);
70
+ }
71
+ catch { /* already released */ }
72
+ throw new Error(`E_MESH_SOLID_UNWELDABLE: welded mesh is still an invalid solid (tolerance=${tolerance}) — ` +
73
+ 'the source mesh is open, non-manifold or self-intersecting');
74
+ }
75
+ // 焊接后原始逐三角形实体已无用;及时释放,避免句柄堆积(新路径不得添泄漏)。
76
+ try {
77
+ backend.release(raw);
78
+ }
79
+ catch { /* already released */ }
80
+ const tess = kernel.meshShape(welded, {
81
+ linearDeflection: opts?.linearDeflection ?? DISPLAY_LINEAR_DEFLECTION,
82
+ angularDeflection: opts?.angularDeflection ?? DISPLAY_ANGULAR_DEFLECTION,
83
+ });
84
+ return {
85
+ solid: welded,
86
+ mesh: tess,
87
+ faceCount: kernel.getSubShapes(welded, 'face').length,
88
+ edgeCount: kernel.getSubShapes(welded, 'edge').length,
89
+ vertexCount: kernel.getSubShapes(welded, 'vertex').length,
90
+ weldTolerance: tolerance,
91
+ mergedFaceCount,
92
+ };
93
+ }
94
+ /**
95
+ * 已存在的网格实体 → 结果描述(三角化 + 计数)。
96
+ *
97
+ * Phase 2 的 mesh op 产出的新实体走这里:**一次**三角化同时喂显示与拓扑,
98
+ * 保证 `faceRuns` 与所见三角形一一对应(规则 1)。重复调 `describe` 会得到
99
+ * 另一份三角化结果——同一实体在同一参数下确定性一致,但仍应复用同一份结果。
100
+ *
101
+ * @param backend - the mesh backend.
102
+ * @param solid - an existing mesh solid handle.
103
+ * @param opts - optional tessellation overrides.
104
+ * @returns the mesh solid result carrying the shared tessellation.
105
+ */
106
+ export function describeMeshSolid(backend, solid, opts) {
107
+ const { kernel } = backend;
108
+ const tess = kernel.meshShape(solid, {
109
+ linearDeflection: opts?.linearDeflection ?? DISPLAY_LINEAR_DEFLECTION,
110
+ angularDeflection: opts?.angularDeflection ?? DISPLAY_ANGULAR_DEFLECTION,
111
+ });
112
+ return {
113
+ solid,
114
+ mesh: tess,
115
+ faceCount: kernel.getSubShapes(solid, 'face').length,
116
+ edgeCount: kernel.getSubShapes(solid, 'edge').length,
117
+ vertexCount: kernel.getSubShapes(solid, 'vertex').length,
118
+ weldTolerance: 0,
119
+ mergedFaceCount: 0,
120
+ };
121
+ }
122
+ /**
123
+ * 网格实体 → 近似拓扑数据(`SelectorRuntimeData`)。
124
+ *
125
+ * 复用 BREP 路径同源的 `buildTopologyFromMesh`(方案 §1.3 实测:产物与 BREP
126
+ * 路径同构——同样的 FaceRow/EdgeRow 字段、同样的 `faceStart/faceCount` 邻接)。
127
+ * **不引入第二套拓扑表示。**
128
+ *
129
+ * @param backend - the mesh backend (kernel + release).
130
+ * @param result - the normalized mesh solid result (carries the shared tessellation).
131
+ * @returns the serializable selector runtime data.
132
+ */
133
+ export function buildMeshSolidTopology(backend, result) {
134
+ return buildTopologyFromMesh(backend.kernel, result.solid, result.mesh);
135
+ }
136
+ // ── 注册表(生命周期,与 brepChain.solidCache 并列且互不干扰) ──
137
+ /**
138
+ * 网格实体句柄注册表(`PartName → BrepHandle`)。
139
+ *
140
+ * 与 `brepChain.solidCache` 的差别:本表**永不**参与 BREP 精度链判定——
141
+ * 它存在只表示"该 part 是网格零件,携带近似拓扑"。释放语义与 solidCache 对齐:
142
+ * `set` 覆盖不释放(旧句柄可能仍被旧输出 Shape 引用),`delete`/`clear` 释放。
143
+ */
144
+ export class MeshSolidRegistry {
145
+ handles = new Map();
146
+ backendRef = null;
147
+ /**
148
+ * 装配/换装网格后端(宿主装配期;运行期只读语义)。
149
+ * @param backend - the mesh backend, or null to detach.
150
+ */
151
+ setBackend(backend) {
152
+ this.backendRef = backend;
153
+ }
154
+ /**
155
+ * 当前网格后端(未装配则 null)。
156
+ * @returns the assembled mesh backend, or null.
157
+ */
158
+ get backend() {
159
+ return this.backendRef;
160
+ }
161
+ /**
162
+ * 登记某 part 的网格实体句柄(覆盖旧值,**不释放**旧句柄——与 solidCache 同语义)。
163
+ * @param part - the part name.
164
+ * @param solid - the mesh solid handle.
165
+ */
166
+ set(part, solid) {
167
+ this.handles.set(part, solid);
168
+ }
169
+ /**
170
+ * 读取某 part 的网格实体句柄。
171
+ * @param part - the part name.
172
+ * @returns the handle, or undefined.
173
+ */
174
+ get(part) {
175
+ return this.handles.get(part);
176
+ }
177
+ /**
178
+ * 该 part 是否携带网格实体。
179
+ * @param part - the part name.
180
+ * @returns true when a handle is registered.
181
+ */
182
+ has(part) {
183
+ return this.handles.has(part);
184
+ }
185
+ /**
186
+ * 删除某 part 并释放其句柄(重放/失效路径)。
187
+ * @param part - the part name.
188
+ */
189
+ delete(part) {
190
+ const h = this.handles.get(part);
191
+ if (h === undefined)
192
+ return;
193
+ this.handles.delete(part);
194
+ try {
195
+ this.backendRef?.release(h);
196
+ }
197
+ catch { /* already released */ }
198
+ }
199
+ /**
200
+ * 按 part 名列表批量删除(重放失效用)。
201
+ * @param parts - the part names to delete; unknown names are ignored.
202
+ */
203
+ deleteMany(parts) {
204
+ for (const p of parts)
205
+ this.delete(p);
206
+ }
207
+ /** 释放全部句柄并清空(dispose)。 */
208
+ clear() {
209
+ for (const h of this.handles.values()) {
210
+ try {
211
+ this.backendRef?.release(h);
212
+ }
213
+ catch { /* already released */ }
214
+ }
215
+ this.handles.clear();
216
+ }
217
+ /**
218
+ * 当前登记的全部 part 名(诊断/测试)。
219
+ * @returns the registered part names.
220
+ */
221
+ keys() {
222
+ return [...this.handles.keys()];
223
+ }
224
+ /** 登记数量(诊断/测试)。 */
225
+ get size() {
226
+ return this.handles.size;
227
+ }
228
+ }
229
+ //# sourceMappingURL=mesh-solid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-solid.js","sourceRoot":"","sources":["../../src/brep/mesh-solid.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh-solid — 网格实体(mesh solid)与其网格后端端口\n *\n *\n * 名词边界(方案 §3.1):\n * - **网格实体** = 由网格文件导入、经「规范化」得到的引擎实体。它是**近似拓扑**\n * 的载体,不是精度链的一环;永不进 `brepChain.solidCache`。\n * - **规范化** = `importIndexedMesh` → `weldShellsAndFaces(tol)` → `unifyFaces()`。\n * **顺序不可交换**:先 `unifyFaces` 会把实体做坏(体积归零),防回归用例见\n * `brepkit-kernel/mesh-solid-topology.test.ts`。\n * - **网格后端** = 提供网格实体能力的引擎侧组件(本期即 brepkit 的网格用法)。\n * 与 BREP 引擎**同名不同用**:可能同一个 wasm 实例,但走 mesh 语义路径。\n *\n * 本模块只依赖 L1(`engine/types`、`engine/primitives`)与拓扑构建器;后端实现\n * 放在适配器侧(`brep/engine/adapters/brepkit`),因此本模块自身不含任何内核私有\n * 调用——`MeshSolidKernelOps` 是内核私有原语的端口(L1 契约不含 weld/unify)。\n */\n\nimport type { BrepHandle, BrepMeshResult } from './engine/types'\nimport type { BrepEngineApi } from './engine/primitives'\nimport type { PartName } from '../identity'\nimport type { SelectorRuntimeData } from '../topology/build-selector-runtime'\nimport { buildTopologyFromMesh } from './brep-topology'\n\n/** 网格实体构建的输入网格(已按基准单位折算的坐标,与 `Shape` 同构)。 */\nexport interface MeshSolidInput {\n positions: Float32Array\n indices: Uint32Array\n}\n\n/** 规范化选项。 */\nexport interface MeshSolidNormalizeOptions {\n /**\n * 焊接容差(顶点/重复边缝合半径)。缺省由包围盒对角线定标\n * (`max(1e-6, 对角线 × 1e-6)`)——**不得写死绝对值**:STL 无单位元数据,\n * 同一文件既可能是 mm 也可能是 inch,绝对容差在两种尺度下必有一边失准。\n */\n weldTolerance?: number\n /** 三角化参数(缺省与显示 mesh 一致:0.1 / 2π/32)。 */\n linearDeflection?: number\n angularDeflection?: number\n}\n\n/** 规范化结果:实体句柄 + 其三角化(显示 mesh 与拓扑 mesh 的唯一真源)。 */\nexport interface MeshSolidResult {\n /** 规范化后的网格实体句柄。 */\n readonly solid: BrepHandle\n /**\n * 同一实体的三角化(含 faceGroups)。**显示 mesh 必须用这一份**——规则 1:\n * 拓扑 faceRuns 所索引的三角形,必须就是用户看到的三角形。若显示仍用原始\n * STL 顶点数组、拓扑用实体的重新三角化,两者三角形数/序不一致 → faceRuns 错位。\n */\n readonly mesh: BrepMeshResult\n readonly faceCount: number\n readonly edgeCount: number\n readonly vertexCount: number\n /** 实际使用的焊接容差(诊断/复现用)。 */\n readonly weldTolerance: number\n /** `unifyFaces` 合并掉的重复面数(0 = 共面面片未被合并,顶点未焊上)。 */\n readonly mergedFaceCount: number\n}\n\n/**\n * 网格后端的**内核私有原语**(L1 `BrepEngineApi` 不含 weld/unify)。\n *\n * 由适配器(拥用内核闭包的一侧)实现;句柄一律是 faijs `BrepHandle`\n * (适配器内部负责 `asNum()` 剥离标签),本模块不感知内核方言。\n */\nexport interface MeshSolidKernelOps {\n /** 原始三角网格 → 逐三角形面的实体(内核自带顶点焊接)。 */\n importMesh(positions: Float32Array, indices: Uint32Array): BrepHandle\n /** 面列表 → 缝合后的实体(重复边缝成共享边 → 真流形)。 */\n weld(faces: BrepHandle[], tolerance: number): BrepHandle\n /** 共面区域合并(**原地修改**,返回合并掉的面数)。 */\n unify(solid: BrepHandle): number\n}\n\n/**\n * 网格后端端口:`load` 的 mesh 路径经它产出网格实体与近似拓扑。\n *\n * 生命周期:由宿主装配期注册进 mesh 引擎槽(`registerMeshEngine`),运行期只读。\n */\nexport interface MeshSolidBackend {\n /** 后端 id(与 `defineOp.meshEngines` 的门禁名同源,如 `'brepkit'`)。 */\n readonly id: string\n /** L1 契约面(拓扑查询 + 几何操作;brepkit 适配器已全实现)。 */\n readonly kernel: BrepEngineApi\n /** 内核私有原语(weld/unify)。 */\n readonly ops: MeshSolidKernelOps\n /**\n * 规范化 + 三角化。**失败必须抛错**(带 part 名由调用方补),不静默降级。\n * @param mesh - the source triangle mesh (base-unit coordinates).\n * @param opts - optional weld tolerance / tessellation overrides.\n * @returns the mesh solid with its tessellation.\n */\n normalize(mesh: MeshSolidInput, opts?: MeshSolidNormalizeOptions): MeshSolidResult\n /**\n * 已存在的网格实体 → 结果描述(三角化 + 计数)。Phase 2 的 mesh op 用它把\n * 「内核操作产出的新实体」包成下一份网格零件(显示 mesh 与拓扑 mesh 同源)。\n * @param solid - an existing mesh solid handle.\n * @param opts - optional tessellation overrides.\n * @returns the mesh solid result carrying the shared tessellation.\n */\n describe(solid: BrepHandle, opts?: MeshSolidNormalizeOptions): MeshSolidResult\n /**\n * 从网格实体结果构建近似拓扑数据(`SelectorRuntimeData`,可直接交 `setTopology`)。\n * @param result - the mesh solid result (its tessellation indexes the topology).\n * @returns the serializable selector runtime data.\n */\n buildTopologyData(result: MeshSolidResult): SelectorRuntimeData\n /** 释放网格实体句柄。 */\n release(solid: BrepHandle): void\n}\n\n// ── 规范化驱动(引擎中立,供适配器的 MeshSolidBackend 实现复用) ──\n\n/** 与显示 mesh 一致的默认三角化参数(`buildSolidTopologyRuntime` 同源)。 */\nconst DISPLAY_LINEAR_DEFLECTION = 0.1\nconst DISPLAY_ANGULAR_DEFLECTION = (2 * Math.PI) / 32\n\n/**\n * 由包围盒对角线导出焊接容差(方案 §3.3)。\n *\n * 下限 1e-6 兜住退化 bbox(单点/零厚网格);上不封顶——超大模型需要更粗的\n * 缝合半径才缝得上(float32 坐标的相对误差随尺度线性增长)。\n *\n * @param kernel - the L1 kernel API (bbox query only).\n * @param shape - the raw imported shape.\n * @returns the weld tolerance derived from the bounding-box diagonal.\n */\nexport function weldToleranceFor(kernel: BrepEngineApi, shape: BrepHandle): number {\n const bb = kernel.getBoundingBox(shape, false)\n const dx = bb.xmax - bb.xmin\n const dy = bb.ymax - bb.ymin\n const dz = bb.zmax - bb.zmin\n const diag = Math.sqrt(dx * dx + dy * dy + dz * dz)\n return Math.max(1e-6, diag * 1e-6)\n}\n\n/**\n * 规范化:`importMesh` → `weld` → `unify`,再校验并三角化。\n *\n * 三条硬约束,都是 Phase 0 实测结论:\n * 1. **顺序不可交换**——先 unify 再 weld 会得到体积归零的坏实体;\n * 2. `unify` **原地修改**,返回值是合并面数,不是句柄;\n * 3. 校验用 `isValid`(weld 后必须合法),不合法即抛错——开放/非流形网格必须\n * 在导入处失败,不能静默退化成\"无拓扑的裸网格\"(那会让所有下游 mesh op\n * 失去选择能力)。\n *\n * @param backend - the mesh backend providing ops + kernel.\n * @param mesh - the source triangle mesh.\n * @param opts - optional weld tolerance / tessellation overrides.\n * @returns the normalized mesh solid, its tessellation, and element counts.\n * @throws {Error} `E_MESH_SOLID_UNWELDABLE` when welding leaves an invalid solid.\n */\nexport function normalizeMeshSolid(\n backend: MeshSolidBackend,\n mesh: MeshSolidInput,\n opts?: MeshSolidNormalizeOptions,\n): MeshSolidResult {\n const { kernel, ops } = backend\n const raw = ops.importMesh(mesh.positions, mesh.indices)\n const tolerance = opts?.weldTolerance ?? weldToleranceFor(kernel, raw)\n\n const faces = kernel.getSubShapes(raw, 'face')\n const welded = ops.weld(faces, tolerance)\n // 原地修改:返回值是合并掉的面数。绝不能把它当句柄。\n const mergedFaceCount = ops.unify(welded)\n\n if (!kernel.isValid(welded)) {\n // 原始实体(逐三角形、边不共享)在 weld 前就不合法是正常的;weld 后仍不合法\n // 说明网格本身开放/非流形/自交——这是**必须暴露的导入失败**,不是可降级状态。\n try { backend.release(raw) } catch { /* already released */ }\n throw new Error(\n `E_MESH_SOLID_UNWELDABLE: welded mesh is still an invalid solid (tolerance=${tolerance}) — ` +\n 'the source mesh is open, non-manifold or self-intersecting',\n )\n }\n // 焊接后原始逐三角形实体已无用;及时释放,避免句柄堆积(新路径不得添泄漏)。\n try { backend.release(raw) } catch { /* already released */ }\n\n const tess = kernel.meshShape(welded, {\n linearDeflection: opts?.linearDeflection ?? DISPLAY_LINEAR_DEFLECTION,\n angularDeflection: opts?.angularDeflection ?? DISPLAY_ANGULAR_DEFLECTION,\n })\n\n return {\n solid: welded,\n mesh: tess,\n faceCount: kernel.getSubShapes(welded, 'face').length,\n edgeCount: kernel.getSubShapes(welded, 'edge').length,\n vertexCount: kernel.getSubShapes(welded, 'vertex').length,\n weldTolerance: tolerance,\n mergedFaceCount,\n }\n}\n\n/**\n * 已存在的网格实体 → 结果描述(三角化 + 计数)。\n *\n * Phase 2 的 mesh op 产出的新实体走这里:**一次**三角化同时喂显示与拓扑,\n * 保证 `faceRuns` 与所见三角形一一对应(规则 1)。重复调 `describe` 会得到\n * 另一份三角化结果——同一实体在同一参数下确定性一致,但仍应复用同一份结果。\n *\n * @param backend - the mesh backend.\n * @param solid - an existing mesh solid handle.\n * @param opts - optional tessellation overrides.\n * @returns the mesh solid result carrying the shared tessellation.\n */\nexport function describeMeshSolid(\n backend: MeshSolidBackend,\n solid: BrepHandle,\n opts?: MeshSolidNormalizeOptions,\n): MeshSolidResult {\n const { kernel } = backend\n const tess = kernel.meshShape(solid, {\n linearDeflection: opts?.linearDeflection ?? DISPLAY_LINEAR_DEFLECTION,\n angularDeflection: opts?.angularDeflection ?? DISPLAY_ANGULAR_DEFLECTION,\n })\n return {\n solid,\n mesh: tess,\n faceCount: kernel.getSubShapes(solid, 'face').length,\n edgeCount: kernel.getSubShapes(solid, 'edge').length,\n vertexCount: kernel.getSubShapes(solid, 'vertex').length,\n weldTolerance: 0,\n mergedFaceCount: 0,\n }\n}\n\n/**\n * 网格实体 → 近似拓扑数据(`SelectorRuntimeData`)。\n *\n * 复用 BREP 路径同源的 `buildTopologyFromMesh`(方案 §1.3 实测:产物与 BREP\n * 路径同构——同样的 FaceRow/EdgeRow 字段、同样的 `faceStart/faceCount` 邻接)。\n * **不引入第二套拓扑表示。**\n *\n * @param backend - the mesh backend (kernel + release).\n * @param result - the normalized mesh solid result (carries the shared tessellation).\n * @returns the serializable selector runtime data.\n */\nexport function buildMeshSolidTopology(\n backend: MeshSolidBackend,\n result: MeshSolidResult,\n): SelectorRuntimeData {\n return buildTopologyFromMesh(backend.kernel, result.solid, result.mesh)\n}\n\n// ── 注册表(生命周期,与 brepChain.solidCache 并列且互不干扰) ──\n\n/**\n * 网格实体句柄注册表(`PartName → BrepHandle`)。\n *\n * 与 `brepChain.solidCache` 的差别:本表**永不**参与 BREP 精度链判定——\n * 它存在只表示\"该 part 是网格零件,携带近似拓扑\"。释放语义与 solidCache 对齐:\n * `set` 覆盖不释放(旧句柄可能仍被旧输出 Shape 引用),`delete`/`clear` 释放。\n */\nexport class MeshSolidRegistry {\n private readonly handles = new Map<PartName, BrepHandle>()\n private backendRef: MeshSolidBackend | null = null\n\n /**\n * 装配/换装网格后端(宿主装配期;运行期只读语义)。\n * @param backend - the mesh backend, or null to detach.\n */\n setBackend(backend: MeshSolidBackend | null): void {\n this.backendRef = backend\n }\n\n /**\n * 当前网格后端(未装配则 null)。\n * @returns the assembled mesh backend, or null.\n */\n get backend(): MeshSolidBackend | null {\n return this.backendRef\n }\n\n /**\n * 登记某 part 的网格实体句柄(覆盖旧值,**不释放**旧句柄——与 solidCache 同语义)。\n * @param part - the part name.\n * @param solid - the mesh solid handle.\n */\n set(part: PartName, solid: BrepHandle): void {\n this.handles.set(part, solid)\n }\n\n /**\n * 读取某 part 的网格实体句柄。\n * @param part - the part name.\n * @returns the handle, or undefined.\n */\n get(part: PartName): BrepHandle | undefined {\n return this.handles.get(part)\n }\n\n /**\n * 该 part 是否携带网格实体。\n * @param part - the part name.\n * @returns true when a handle is registered.\n */\n has(part: PartName): boolean {\n return this.handles.has(part)\n }\n\n /**\n * 删除某 part 并释放其句柄(重放/失效路径)。\n * @param part - the part name.\n */\n delete(part: PartName): void {\n const h = this.handles.get(part)\n if (h === undefined) return\n this.handles.delete(part)\n try { this.backendRef?.release(h) } catch { /* already released */ }\n }\n\n /**\n * 按 part 名列表批量删除(重放失效用)。\n * @param parts - the part names to delete; unknown names are ignored.\n */\n deleteMany(parts: Iterable<PartName>): void {\n for (const p of parts) this.delete(p)\n }\n\n /** 释放全部句柄并清空(dispose)。 */\n clear(): void {\n for (const h of this.handles.values()) {\n try { this.backendRef?.release(h) } catch { /* already released */ }\n }\n this.handles.clear()\n }\n\n /**\n * 当前登记的全部 part 名(诊断/测试)。\n * @returns the registered part names.\n */\n keys(): PartName[] {\n return [...this.handles.keys()]\n }\n\n /** 登记数量(诊断/测试)。 */\n get size(): number {\n return this.handles.size\n }\n}\n"]}
@@ -13,11 +13,24 @@ import type { Font } from 'opentype.js';
13
13
  * 字体二进制加载器接口。
14
14
  *
15
15
  * 生产代码(text.ts / engrave.ts)不自己决定字体来源,
16
- * 而是通过 ensureDefaultFont() 使用注入的 FontLoader。
16
+ * 而是通过 ensureDefaultFont() / ensureFont() 使用注入的 FontLoader。
17
17
  */
18
18
  export interface FontLoader {
19
19
  /** 返回默认字体的二进制数据 */
20
20
  loadDefaultFont(): Promise<ArrayBuffer>;
21
+ /**
22
+ * 可选:按**字体族名**或**文件路径**取字体二进制。
23
+ *
24
+ * 宿主实现(Node 读磁盘/系统字体目录、浏览器按 URL 映射)决定来源;引擎核心
25
+ * 不碰 fs/fetch。返回 `null` 表示宿主无法解析该名字——调用方回退到默认字体
26
+ * (与 CadQuery/OCC `Font_FontMgr::FindFont` 找不到名字时回退默认字体的语义一致)。
27
+ *
28
+ * 未实现该方法的宿主(如浏览器)会让 `ensureFont(name)` 直接回退默认字体。
29
+ *
30
+ * @param nameOrPath - 字体族名(如 `"Arial"`)或字体文件路径
31
+ * @returns 字体字节,或 null(无法解析)
32
+ */
33
+ resolveFont?(nameOrPath: string): Promise<ArrayBuffer | null>;
21
34
  }
22
35
  /**
23
36
  * 设置当前环境的字体加载器。
@@ -61,6 +74,24 @@ export declare function ensureDefaultFont(): Promise<void>;
61
74
  * @returns opentype.js Font 对象,如果未加载则返回 undefined
62
75
  */
63
76
  export declare function getFont(fontFamily?: string): Font | undefined;
77
+ /**
78
+ * 确保某个**具名字体**可用,并返回它。
79
+ *
80
+ * 语义对齐 CadQuery 的 `font=`/`fontPath=`:
81
+ *
82
+ * - 名字已注册过(含 `loadFont(data, name)` 直接注册)⇒ 直接返回;
83
+ * - `fontPath`(已存在的文件路径)或字体族名 ⇒ 交给 `FontLoader.resolveFont` 解析,
84
+ * 解析成功后**以该名字注册**,后续同名调用命中缓存;
85
+ * - 宿主没有 `resolveFont`、或解析失败(名字不是本机已安装字体)⇒ **回退到默认字体**
86
+ * (OCC `Font_FontMgr::FindFont` 找不到字体时同样回退默认字体,不会抛错)。
87
+ *
88
+ * `null`/`undefined`/空串等价于「不指定」⇒ 默认字体。
89
+ *
90
+ * @param nameOrPath - 字体族名、字体文件路径,或 null/undefined 表示默认字体
91
+ * @returns 解析到的字体(解析不到时是默认字体)
92
+ * @throws 没有安装 FontLoader 且默认字体也未加载时
93
+ */
94
+ export declare function ensureFont(nameOrPath?: string | null): Promise<Font>;
64
95
  /**
65
96
  * 清除所有已注册的字体。
66
97
  *
@@ -1 +1 @@
1
- {"version":3,"file":"fontRegistry.d.ts","sourceRoot":"","sources":["../../../src/brep/text/fontRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAMvC;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,mBAAmB;IACnB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;CACxC;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAEjD;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,WAAW,EACrB,UAAU,SAAY,EACtB,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAavD;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,UAAU,SAAY,GAAG,IAAI,GAAG,SAAS,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAIjC"}
1
+ {"version":3,"file":"fontRegistry.d.ts","sourceRoot":"","sources":["../../../src/brep/text/fontRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAoBvC;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,mBAAmB;IACnB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;IACvC;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;CAC9D;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAEjD;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,WAAW,EACrB,UAAU,SAAY,EACtB,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAavD;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,UAAU,SAAY,GAAG,IAAI,GAAG,SAAS,CAEhE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB1E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAIjC"}
@@ -8,7 +8,19 @@
8
8
  * - Node 测试:fontTestHelper.ts 通过 fs.readFileSync 加载
9
9
  * - 字体文件唯一真源:src/assets/fonts/OpenSans-Regular.ttf
10
10
  */
11
- import * as opentype from 'opentype.js';
11
+ import * as opentypeModule from 'opentype.js';
12
+ /**
13
+ * `opentype.js` publishes no `exports` map: it ships a UMD bundle (`main`) plus
14
+ * an ESM build (`module`). Node ESM resolves the UMD `main`, whose CommonJS
15
+ * interop exposes a namespace import as `{ default }` only — so
16
+ * `opentypeModule.parse` is undefined there — whereas bundlers (vite/vitest)
17
+ * resolve the ESM build and expose the named exports directly. Resolve once,
18
+ * here, so glyph parsing works in every host (CLI/tsx = Node ESM,
19
+ * vitest/browser = bundler).
20
+ */
21
+ const opentype = typeof opentypeModule.parse === 'function'
22
+ ? opentypeModule
23
+ : opentypeModule.default;
12
24
  const FONT_REGISTER = {};
13
25
  let activeFontLoader = null;
14
26
  /**
@@ -86,6 +98,44 @@ export async function ensureDefaultFont() {
86
98
  export function getFont(fontFamily = 'default') {
87
99
  return FONT_REGISTER[fontFamily];
88
100
  }
101
+ /**
102
+ * 确保某个**具名字体**可用,并返回它。
103
+ *
104
+ * 语义对齐 CadQuery 的 `font=`/`fontPath=`:
105
+ *
106
+ * - 名字已注册过(含 `loadFont(data, name)` 直接注册)⇒ 直接返回;
107
+ * - `fontPath`(已存在的文件路径)或字体族名 ⇒ 交给 `FontLoader.resolveFont` 解析,
108
+ * 解析成功后**以该名字注册**,后续同名调用命中缓存;
109
+ * - 宿主没有 `resolveFont`、或解析失败(名字不是本机已安装字体)⇒ **回退到默认字体**
110
+ * (OCC `Font_FontMgr::FindFont` 找不到字体时同样回退默认字体,不会抛错)。
111
+ *
112
+ * `null`/`undefined`/空串等价于「不指定」⇒ 默认字体。
113
+ *
114
+ * @param nameOrPath - 字体族名、字体文件路径,或 null/undefined 表示默认字体
115
+ * @returns 解析到的字体(解析不到时是默认字体)
116
+ * @throws 没有安装 FontLoader 且默认字体也未加载时
117
+ */
118
+ export async function ensureFont(nameOrPath) {
119
+ if (!nameOrPath) {
120
+ await ensureDefaultFont();
121
+ return getFont();
122
+ }
123
+ const already = getFont(nameOrPath);
124
+ if (already)
125
+ return already;
126
+ if (nameOrPath === 'default') {
127
+ await ensureDefaultFont();
128
+ return getFont();
129
+ }
130
+ const resolver = activeFontLoader?.resolveFont;
131
+ if (resolver) {
132
+ const data = await activeFontLoader.resolveFont(nameOrPath);
133
+ if (data)
134
+ return loadFont(data, nameOrPath, true);
135
+ }
136
+ await ensureDefaultFont();
137
+ return getFont();
138
+ }
89
139
  /**
90
140
  * 清除所有已注册的字体。
91
141
  *