@faicad/faijs 0.33.2 → 0.35.2
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.
- package/dist/api/api-namespace.d.ts +14 -14
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +40 -14
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/appearance.d.ts +47 -6
- package/dist/api/appearance.d.ts.map +1 -1
- package/dist/api/appearance.js.map +1 -1
- package/dist/api/assembly/solve-tree.d.ts +1 -0
- package/dist/api/assembly/solve-tree.d.ts.map +1 -1
- package/dist/api/assembly/solve-tree.js +42 -17
- package/dist/api/assembly/solve-tree.js.map +1 -1
- package/dist/api/assembly/solve.d.ts +1 -0
- package/dist/api/assembly/solve.d.ts.map +1 -1
- package/dist/api/assembly/solve.js.map +1 -1
- package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
- package/dist/api/assembly/solvers/global-solver.js +130 -23
- package/dist/api/assembly/solvers/global-solver.js.map +1 -1
- package/dist/api/assembly/solvers/pose-from-delta.d.ts +9 -0
- package/dist/api/assembly/solvers/pose-from-delta.d.ts.map +1 -1
- package/dist/api/assembly/solvers/pose-from-delta.js +23 -0
- package/dist/api/assembly/solvers/pose-from-delta.js.map +1 -1
- package/dist/api/assembly/solvers/types.d.ts +20 -2
- package/dist/api/assembly/solvers/types.d.ts.map +1 -1
- package/dist/api/assembly/solvers/types.js.map +1 -1
- package/dist/api/chamfer.d.ts +7 -4
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +57 -13
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/draft.d.ts +7 -4
- package/dist/api/draft.d.ts.map +1 -1
- package/dist/api/draft.js +11 -6
- package/dist/api/draft.js.map +1 -1
- package/dist/api/edge-ref.d.ts +4 -4
- package/dist/api/edge-ref.js +4 -4
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/extrude.d.ts +10 -6
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +50 -25
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts +4 -4
- package/dist/api/face-ref.js +4 -4
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/feature-repair.d.ts +6 -3
- package/dist/api/feature-repair.d.ts.map +1 -1
- package/dist/api/feature-repair.js +12 -7
- package/dist/api/feature-repair.js.map +1 -1
- package/dist/api/fillet-variable.d.ts +6 -2
- package/dist/api/fillet-variable.d.ts.map +1 -1
- package/dist/api/fillet-variable.js +24 -6
- package/dist/api/fillet-variable.js.map +1 -1
- package/dist/api/fillet.d.ts +7 -4
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +45 -12
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/helix.d.ts +13 -13
- package/dist/api/helix.d.ts.map +1 -1
- package/dist/api/helix.js +19 -24
- package/dist/api/helix.js.map +1 -1
- package/dist/api/import-brep.d.ts +10 -18
- package/dist/api/import-brep.d.ts.map +1 -1
- package/dist/api/import-brep.js +17 -25
- package/dist/api/import-brep.js.map +1 -1
- package/dist/api/import-step.d.ts +10 -15
- package/dist/api/import-step.d.ts.map +1 -1
- package/dist/api/import-step.js +24 -29
- package/dist/api/import-step.js.map +1 -1
- package/dist/api/index.js +2 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/export-members.js.map +1 -1
- package/dist/api/loft-advanced.d.ts +4 -0
- package/dist/api/loft-advanced.d.ts.map +1 -1
- package/dist/api/loft-advanced.js +4 -0
- package/dist/api/loft-advanced.js.map +1 -1
- package/dist/api/loft.d.ts +5 -3
- package/dist/api/loft.d.ts.map +1 -1
- package/dist/api/loft.js +5 -3
- package/dist/api/loft.js.map +1 -1
- package/dist/api/meta.d.ts +42 -6
- package/dist/api/meta.d.ts.map +1 -1
- package/dist/api/meta.js.map +1 -1
- package/dist/api/punch-hole.d.ts +5 -2
- package/dist/api/punch-hole.d.ts.map +1 -1
- package/dist/api/punch-hole.js +4 -1
- package/dist/api/punch-hole.js.map +1 -1
- package/dist/api/replicate.d.ts +4 -5
- package/dist/api/replicate.d.ts.map +1 -1
- package/dist/api/replicate.js +4 -5
- package/dist/api/replicate.js.map +1 -1
- package/dist/api/selectors-to-refs.d.ts +83 -0
- package/dist/api/selectors-to-refs.d.ts.map +1 -0
- package/dist/api/selectors-to-refs.js +211 -0
- package/dist/api/selectors-to-refs.js.map +1 -0
- package/dist/api/shell.d.ts +17 -8
- package/dist/api/shell.d.ts.map +1 -1
- package/dist/api/shell.js +45 -15
- package/dist/api/shell.js.map +1 -1
- package/dist/api/sketch-on-face.d.ts +12 -6
- package/dist/api/sketch-on-face.d.ts.map +1 -1
- package/dist/api/sketch-on-face.js +31 -4
- package/dist/api/sketch-on-face.js.map +1 -1
- package/dist/api/sketch-on-plane.d.ts +3 -0
- package/dist/api/sketch-on-plane.d.ts.map +1 -1
- package/dist/api/sketch-on-plane.js +3 -0
- package/dist/api/sketch-on-plane.js.map +1 -1
- package/dist/api/sketch-on-surface.d.ts +4 -1
- package/dist/api/sketch-on-surface.d.ts.map +1 -1
- package/dist/api/sketch-on-surface.js +4 -1
- package/dist/api/sketch-on-surface.js.map +1 -1
- package/dist/api/view/view-projection.d.ts.map +1 -1
- package/dist/api/view/view-projection.js +9 -2
- package/dist/api/view/view-projection.js.map +1 -1
- package/dist/brep/brep-chain.js +2 -2
- package/dist/brep/brep-chain.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +1 -1
- package/dist/brep/brep-ops.js +1 -1
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +45 -0
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +87 -3
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js +1 -1
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/registry.d.ts +33 -7
- package/dist/brep/engine/registry.d.ts.map +1 -1
- package/dist/brep/engine/registry.js +47 -16
- package/dist/brep/engine/registry.js.map +1 -1
- package/dist/brep/handle-bridge.d.ts +14 -15
- package/dist/brep/handle-bridge.d.ts.map +1 -1
- package/dist/brep/handle-bridge.js +35 -15
- package/dist/brep/handle-bridge.js.map +1 -1
- package/dist/brep/primitives-brep.js +2 -2
- package/dist/brep/primitives-brep.js.map +1 -1
- package/dist/brep/text/text-to-solid.d.ts +40 -3
- package/dist/brep/text/text-to-solid.d.ts.map +1 -1
- package/dist/brep/text/text-to-solid.js +104 -24
- package/dist/brep/text/text-to-solid.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +2 -2
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +315 -36
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/brepkit-kernel/brepkitWasm.js +7 -7
- package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
- package/dist/brepkit-kernel/multi-version-test.d.ts +2 -2
- package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
- package/dist/brepkit-kernel/multi-version-test.js +6 -6
- package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
- package/dist/browser.d.ts +2 -3
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -2
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +9 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +11 -1
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.d.ts +16 -11
- package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js +16 -8
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts +62 -5
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +617 -42
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/interp/closure.d.ts +3 -2
- package/dist/cad-runtime/interp/closure.d.ts.map +1 -1
- package/dist/cad-runtime/interp/closure.js.map +1 -1
- package/dist/cad-runtime/interp/env.d.ts +9 -6
- package/dist/cad-runtime/interp/env.d.ts.map +1 -1
- package/dist/cad-runtime/interp/env.js +4 -2
- package/dist/cad-runtime/interp/env.js.map +1 -1
- package/dist/cad-runtime/lib-decl.d.ts +121 -0
- package/dist/cad-runtime/lib-decl.d.ts.map +1 -0
- package/dist/cad-runtime/lib-decl.js +100 -0
- package/dist/cad-runtime/lib-decl.js.map +1 -0
- package/dist/cad-runtime/ports.d.ts +12 -0
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +59 -5
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +237 -18
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/extra/browser.d.ts +9 -0
- package/dist/extra/browser.d.ts.map +1 -0
- package/dist/extra/browser.js +9 -0
- package/dist/extra/browser.js.map +1 -0
- package/dist/extra/editor-ops.d.ts +22 -0
- package/dist/extra/editor-ops.d.ts.map +1 -0
- package/dist/extra/editor-ops.js +21 -0
- package/dist/extra/editor-ops.js.map +1 -0
- package/dist/extra/extras/svg-extrude.d.ts +45 -0
- package/dist/extra/extras/svg-extrude.d.ts.map +1 -0
- package/dist/extra/extras/svg-extrude.js +110 -0
- package/dist/extra/extras/svg-extrude.js.map +1 -0
- package/dist/extra/extras/text-cjk.d.ts +36 -0
- package/dist/extra/extras/text-cjk.d.ts.map +1 -0
- package/dist/extra/extras/text-cjk.js +86 -0
- package/dist/extra/extras/text-cjk.js.map +1 -0
- package/dist/extra/extras/text-geometry.d.ts +69 -0
- package/dist/extra/extras/text-geometry.d.ts.map +1 -0
- package/dist/extra/extras/text-geometry.js +188 -0
- package/dist/extra/extras/text-geometry.js.map +1 -0
- package/dist/extra/index.d.ts +40 -0
- package/dist/extra/index.d.ts.map +1 -0
- package/dist/extra/index.js +40 -0
- package/dist/extra/index.js.map +1 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts +94 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts.map +1 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.js +282 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.js.map +1 -0
- package/dist/extra/mesh/drill-hole/drill-types.d.ts +34 -0
- package/dist/extra/mesh/drill-hole/drill-types.d.ts.map +1 -0
- package/dist/extra/mesh/drill-hole/drill-types.js +7 -0
- package/dist/extra/mesh/drill-hole/drill-types.js.map +1 -0
- package/dist/extra/mesh/engrave-decoration.d.ts +42 -0
- package/dist/extra/mesh/engrave-decoration.d.ts.map +1 -0
- package/dist/extra/mesh/engrave-decoration.js +39 -0
- package/dist/extra/mesh/engrave-decoration.js.map +1 -0
- package/dist/extra/mesh/fai_drill.d.ts +21 -0
- package/dist/extra/mesh/fai_drill.d.ts.map +1 -0
- package/dist/extra/mesh/fai_drill.js +89 -0
- package/dist/extra/mesh/fai_drill.js.map +1 -0
- package/dist/extra/mesh/fai_extrude.d.ts +24 -0
- package/dist/extra/mesh/fai_extrude.d.ts.map +1 -0
- package/dist/extra/mesh/fai_extrude.js +42 -0
- package/dist/extra/mesh/fai_extrude.js.map +1 -0
- package/dist/extra/mesh/fai_split.d.ts +164 -0
- package/dist/extra/mesh/fai_split.d.ts.map +1 -0
- package/dist/extra/mesh/fai_split.js +269 -0
- package/dist/extra/mesh/fai_split.js.map +1 -0
- package/dist/extra/mesh/primitives.d.ts +29 -0
- package/dist/extra/mesh/primitives.d.ts.map +1 -0
- package/dist/extra/mesh/primitives.js +41 -0
- package/dist/extra/mesh/primitives.js.map +1 -0
- package/dist/extra/op-names.d.ts +37 -0
- package/dist/extra/op-names.d.ts.map +1 -0
- package/dist/extra/op-names.js +46 -0
- package/dist/extra/op-names.js.map +1 -0
- package/dist/extra/ops/compound.d.ts +140 -0
- package/dist/extra/ops/compound.d.ts.map +1 -0
- package/dist/extra/ops/compound.js +167 -0
- package/dist/extra/ops/compound.js.map +1 -0
- package/dist/extra/ops/copy.d.ts +40 -0
- package/dist/extra/ops/copy.d.ts.map +1 -0
- package/dist/extra/ops/copy.js +83 -0
- package/dist/extra/ops/copy.js.map +1 -0
- package/dist/extra/ops/fai_drill.d.ts +51 -0
- package/dist/extra/ops/fai_drill.d.ts.map +1 -0
- package/dist/extra/ops/fai_drill.js +233 -0
- package/dist/extra/ops/fai_drill.js.map +1 -0
- package/dist/extra/ops/fai_extrude.d.ts +36 -0
- package/dist/extra/ops/fai_extrude.d.ts.map +1 -0
- package/dist/extra/ops/fai_extrude.js +84 -0
- package/dist/extra/ops/fai_extrude.js.map +1 -0
- package/dist/extra/ops/fai_split.d.ts +46 -0
- package/dist/extra/ops/fai_split.d.ts.map +1 -0
- package/dist/extra/ops/fai_split.js +235 -0
- package/dist/extra/ops/fai_split.js.map +1 -0
- package/dist/extra/ops/load.d.ts +49 -0
- package/dist/extra/ops/load.d.ts.map +1 -0
- package/dist/extra/ops/load.js +385 -0
- package/dist/extra/ops/load.js.map +1 -0
- package/dist/extra/ops/svg-extrude.d.ts +32 -0
- package/dist/extra/ops/svg-extrude.d.ts.map +1 -0
- package/dist/extra/ops/svg-extrude.js +74 -0
- package/dist/extra/ops/svg-extrude.js.map +1 -0
- package/dist/extra/ops/text.d.ts +34 -0
- package/dist/extra/ops/text.d.ts.map +1 -0
- package/dist/extra/ops/text.js +100 -0
- package/dist/extra/ops/text.js.map +1 -0
- package/dist/geometry2d/bridge/lift-on-plane.d.ts +8 -5
- package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.js +8 -5
- package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/lang/symbol-table.d.ts +3 -3
- package/dist/lang/symbol-table.generated.d.ts +10 -0
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +10 -0
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/lang/symbol-table.js +3 -3
- package/dist/lang/symbol-table.js.map +1 -1
- package/dist/math3d/index.d.ts +1 -1
- package/dist/math3d/index.js +1 -1
- package/dist/math3d/index.js.map +1 -1
- package/dist/mesh/engrave.d.ts +2 -3
- package/dist/mesh/engrave.d.ts.map +1 -1
- package/dist/mesh/engrave.js +4 -11
- package/dist/mesh/engrave.js.map +1 -1
- package/dist/mesh/index.d.ts +0 -2
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +0 -2
- package/dist/mesh/index.js.map +1 -1
- package/dist/mesh/primitives.d.ts +1 -1
- package/dist/mesh/primitives.js +1 -1
- package/dist/mesh/primitives.js.map +1 -1
- package/dist/node-host/cli.d.ts +11 -4
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +53 -28
- package/dist/node-host/cli.js.map +1 -1
- package/dist/node-host/execute-script.d.ts.map +1 -1
- package/dist/node-host/execute-script.js +3 -4
- package/dist/node-host/execute-script.js.map +1 -1
- package/dist/node-host/lib-package-json.d.ts +36 -0
- package/dist/node-host/lib-package-json.d.ts.map +1 -0
- package/dist/node-host/lib-package-json.js +73 -0
- package/dist/node-host/lib-package-json.js.map +1 -0
- package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
- package/dist/occt-kernel/occt-primitives.js +41 -0
- package/dist/occt-kernel/occt-primitives.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts +1 -1
- package/dist/occt-kernel/occtKernel.js +1 -1
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/runtime-state.d.ts +28 -1
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +14 -1
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +2 -2
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +11 -2
- package/dist/sdk.js.map +1 -1
- package/dist/sketch/bspline.d.ts +58 -0
- package/dist/sketch/bspline.d.ts.map +1 -0
- package/dist/sketch/bspline.js +104 -0
- package/dist/sketch/bspline.js.map +1 -0
- package/dist/sketch/canonical.d.ts +239 -0
- package/dist/sketch/canonical.d.ts.map +1 -0
- package/dist/sketch/canonical.js +17 -0
- package/dist/sketch/canonical.js.map +1 -0
- package/dist/sketch/contour.d.ts +43 -0
- package/dist/sketch/contour.d.ts.map +1 -0
- package/dist/sketch/contour.js +202 -0
- package/dist/sketch/contour.js.map +1 -0
- package/dist/sketch/dim-spec.d.ts +32 -0
- package/dist/sketch/dim-spec.d.ts.map +1 -0
- package/dist/sketch/dim-spec.js +112 -0
- package/dist/sketch/dim-spec.js.map +1 -0
- package/dist/sketch/faces.d.ts +45 -0
- package/dist/sketch/faces.d.ts.map +1 -0
- package/dist/sketch/faces.js +108 -0
- package/dist/sketch/faces.js.map +1 -0
- package/dist/sketch/fcstd-types.d.ts +194 -0
- package/dist/sketch/fcstd-types.d.ts.map +1 -0
- package/dist/sketch/fcstd-types.js +67 -0
- package/dist/sketch/fcstd-types.js.map +1 -0
- package/dist/sketch/index.d.ts +46 -0
- package/dist/sketch/index.d.ts.map +1 -0
- package/dist/sketch/index.js +39 -0
- package/dist/sketch/index.js.map +1 -0
- package/dist/sketch/node.d.ts +14 -0
- package/dist/sketch/node.d.ts.map +1 -0
- package/dist/sketch/node.js +43 -0
- package/dist/sketch/node.js.map +1 -0
- package/dist/sketch/op.d.ts +111 -0
- package/dist/sketch/op.d.ts.map +1 -0
- package/dist/sketch/op.js +185 -0
- package/dist/sketch/op.js.map +1 -0
- package/dist/sketch/planegcs-backend.d.ts +69 -0
- package/dist/sketch/planegcs-backend.d.ts.map +1 -0
- package/dist/sketch/planegcs-backend.js +812 -0
- package/dist/sketch/planegcs-backend.js.map +1 -0
- package/dist/sketch/project.d.ts +176 -0
- package/dist/sketch/project.d.ts.map +1 -0
- package/dist/sketch/project.js +656 -0
- package/dist/sketch/project.js.map +1 -0
- package/dist/sketch/shapes.d.ts +370 -0
- package/dist/sketch/shapes.d.ts.map +1 -0
- package/dist/sketch/shapes.js +959 -0
- package/dist/sketch/shapes.js.map +1 -0
- package/dist/sketch/solve.d.ts +21 -0
- package/dist/sketch/solve.d.ts.map +1 -0
- package/dist/sketch/solve.js +144 -0
- package/dist/sketch/solve.js.map +1 -0
- package/dist/sketch/solver-loader.d.ts +47 -0
- package/dist/sketch/solver-loader.d.ts.map +1 -0
- package/dist/sketch/solver-loader.js +77 -0
- package/dist/sketch/solver-loader.js.map +1 -0
- package/dist/sketch/solver.d.ts +63 -0
- package/dist/sketch/solver.d.ts.map +1 -0
- package/dist/sketch/solver.js +28 -0
- package/dist/sketch/solver.js.map +1 -0
- package/dist/sketch/verify.d.ts +53 -0
- package/dist/sketch/verify.d.ts.map +1 -0
- package/dist/sketch/verify.js +71 -0
- package/dist/sketch/verify.js.map +1 -0
- package/dist/weapp.d.ts +1 -1
- package/dist/weapp.d.ts.map +1 -1
- package/dist/weapp.js +1 -1
- package/dist/weapp.js.map +1 -1
- 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
|
|
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
|
|
95
|
+
* @returns 每个闭合轮廓的 { wire, points }(points 为 Y-up 采样点)
|
|
67
96
|
*/
|
|
68
|
-
export function
|
|
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
|
|
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
|
|
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
|
|
193
|
-
if (
|
|
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
|
-
//
|
|
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
|
|
272
|
+
for (const g of groups) {
|
|
199
273
|
try {
|
|
200
|
-
|
|
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
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
kernel.release(
|
|
219
|
-
|
|
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":"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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 + 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
|
-
* 都不在本对象里——平台代码经原生面 `
|
|
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
|
|
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;
|
|
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,CAw9C5E;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"}
|