@faicad/faijs 0.33.1 → 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 +20 -4
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +84 -35
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fai_extrude.d.ts","sourceRoot":"","sources":["../../../src/extra/mesh/fai_extrude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAE5D;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,CA2BjF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh 拉伸 API
|
|
3
|
+
*
|
|
4
|
+
* 提取来源:engine/boolean/extrude-helpers.ts (buildExtrudeParts)
|
|
5
|
+
* 已是纯数据函数(ManifoldMeshData 输入输出),直接包装。
|
|
6
|
+
*
|
|
7
|
+
* 拉伸语义(三段模型):
|
|
8
|
+
* - back(下半):沿法线 N 平移 offsetBack
|
|
9
|
+
* - middle(中段):平面处的截面沿 N 挤出 L
|
|
10
|
+
* - front(上半):沿法线 N 平移 offsetFront
|
|
11
|
+
* 其中 offsetFront - offsetBack === length 恒成立。
|
|
12
|
+
*/
|
|
13
|
+
import { computeBoolean } from '../../boolean/csg-backend.js';
|
|
14
|
+
import { buildExtrudeParts } from '../../boolean/extrude-helpers.js';
|
|
15
|
+
/**
|
|
16
|
+
* Execute a face extrude: cut the model at the cutting plane and extrude the
|
|
17
|
+
* middle section by `length` along the plane normal, then union the three
|
|
18
|
+
* segments back into a single solid.
|
|
19
|
+
*
|
|
20
|
+
* @param shape - the world-space shape to extrude.
|
|
21
|
+
* @param params - extrude parameters (normal, planeDistance, length, mode).
|
|
22
|
+
* @returns the extruded shape in world space.
|
|
23
|
+
*/
|
|
24
|
+
export async function extrude(shape, params) {
|
|
25
|
+
const mode = params.mode ?? 'centered';
|
|
26
|
+
const { front, back, extruded } = await buildExtrudeParts(shape, params.normal, params.planeDistance, params.length, mode);
|
|
27
|
+
// Union 三段为单体
|
|
28
|
+
const meshesToUnion = [];
|
|
29
|
+
for (const part of [front, extruded, back]) {
|
|
30
|
+
if (!part || part.indices.length === 0)
|
|
31
|
+
continue;
|
|
32
|
+
meshesToUnion.push(part);
|
|
33
|
+
}
|
|
34
|
+
if (meshesToUnion.length === 0) {
|
|
35
|
+
throw new Error('No valid geometry to extrude');
|
|
36
|
+
}
|
|
37
|
+
if (meshesToUnion.length === 1) {
|
|
38
|
+
return meshesToUnion[0];
|
|
39
|
+
}
|
|
40
|
+
return computeBoolean(meshesToUnion, 'union');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=fai_extrude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fai_extrude.js","sourceRoot":"","sources":["../../../src/extra/mesh/fai_extrude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAIjE;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAY,EAAE,MAAqB;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,UAAU,CAAA;IAEtC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,iBAAiB,CACvD,KAAyB,EACzB,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,aAAa,EACpB,MAAM,CAAC,MAAM,EACb,IAAI,CACL,CAAA;IAED,cAAc;IACd,MAAM,aAAa,GAAuB,EAAE,CAAA;IAC5C,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAQ;QAChD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,aAAa,CAAC,CAAC,CAAC,CAAA;IACzB,CAAC;IAED,OAAO,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;AAC/C,CAAC","sourcesContent":["/**\n * mesh 拉伸 API\n *\n * 提取来源:engine/boolean/extrude-helpers.ts (buildExtrudeParts)\n * 已是纯数据函数(ManifoldMeshData 输入输出),直接包装。\n *\n * 拉伸语义(三段模型):\n * - back(下半):沿法线 N 平移 offsetBack\n * - middle(中段):平面处的截面沿 N 挤出 L\n * - front(上半):沿法线 N 平移 offsetFront\n * 其中 offsetFront - offsetBack === length 恒成立。\n */\n\nimport { computeBoolean } from '../../boolean/csg-backend'\nimport { buildExtrudeParts } from '../../boolean/extrude-helpers'\nimport type { ManifoldMeshData } from '../../boolean/csg-backend'\nimport type { Shape, ExtrudeParams } from '../../mesh/types'\n\n/**\n * Execute a face extrude: cut the model at the cutting plane and extrude the\n * middle section by `length` along the plane normal, then union the three\n * segments back into a single solid.\n *\n * @param shape - the world-space shape to extrude.\n * @param params - extrude parameters (normal, planeDistance, length, mode).\n * @returns the extruded shape in world space.\n */\nexport async function extrude(shape: Shape, params: ExtrudeParams): Promise<Shape> {\n const mode = params.mode ?? 'centered'\n\n const { front, back, extruded } = await buildExtrudeParts(\n shape as ManifoldMeshData,\n params.normal,\n params.planeDistance,\n params.length,\n mode,\n )\n\n // Union 三段为单体\n const meshesToUnion: ManifoldMeshData[] = []\n for (const part of [front, extruded, back]) {\n if (!part || part.indices.length === 0) continue\n meshesToUnion.push(part)\n }\n\n if (meshesToUnion.length === 0) {\n throw new Error('No valid geometry to extrude')\n }\n\n if (meshesToUnion.length === 1) {\n return meshesToUnion[0]\n }\n\n return computeBoolean(meshesToUnion, 'union')\n}\n"]}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh 分割 API
|
|
3
|
+
*
|
|
4
|
+
* 提取来源:engine/boolean/csg.ts (computeSplit/computeDovetailSplit/...)
|
|
5
|
+
* 已是纯数据函数,直接包装。
|
|
6
|
+
*
|
|
7
|
+
* splitWithParams 是 UI 与重放共用的唯一分割入口:
|
|
8
|
+
* 参数编排(planeParams / planeBasis / 爆炸位移 / 世界坐标变换)
|
|
9
|
+
* 全部在此函数内部完成,调用方只需传入 cutMode + normal/offset/inPlaneAngle + bbCenter
|
|
10
|
+
* 以及各 cutMode 专属参数。
|
|
11
|
+
*/
|
|
12
|
+
import type { Shape, SplitResult, SplitPlane, DovetailSplitParams, DowelSplitParams, TenonSplitParams, Vec3 } from '../../mesh/types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Derive the cutting-plane parameters from Euler angles (in degrees), the
|
|
15
|
+
* plane position and the bounding-box center. Behavior is identical to the
|
|
16
|
+
* former split-store.computePlaneParams.
|
|
17
|
+
* @param rotationX - rotation about X in degrees.
|
|
18
|
+
* @param rotationY - rotation about Y in degrees.
|
|
19
|
+
* @param rotationZ - rotation about Z in degrees.
|
|
20
|
+
* @param planePosition - offset of the cutting plane along the plane normal.
|
|
21
|
+
* @param bbCenter - world-space bounding-box center of the source mesh.
|
|
22
|
+
* @returns the plane normal, the plane's signed distance from the origin, and its center.
|
|
23
|
+
*/
|
|
24
|
+
export declare function computePlaneParams(rotationX: number, rotationY: number, rotationZ: number, planePosition: number, bbCenter: Vec3): {
|
|
25
|
+
normal: Vec3;
|
|
26
|
+
planeDistance: number;
|
|
27
|
+
planeCenter: Vec3;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Derive the plane basis vectors from Euler angles (in degrees). Behavior is
|
|
31
|
+
* identical to the former split-store.computePlaneBasis.
|
|
32
|
+
* @param rotationX - rotation about X in degrees.
|
|
33
|
+
* @param rotationY - rotation about Y in degrees.
|
|
34
|
+
* @param rotationZ - rotation about Z in degrees.
|
|
35
|
+
* @returns the plane normal plus the in-plane width and depth directions.
|
|
36
|
+
*/
|
|
37
|
+
export declare function computePlaneBasis(rotationX: number, rotationY: number, rotationZ: number): {
|
|
38
|
+
normal: Vec3;
|
|
39
|
+
widthDir: Vec3;
|
|
40
|
+
depthDir: Vec3;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Derive widthDir/depthDir from the cutting-plane normal and the in-plane
|
|
44
|
+
* rotation angle. Matches computePlaneBasis(rx, ry, rz) with
|
|
45
|
+
* normal = eulerXYZToNormal(rx, ry, 0) and inPlaneAngle = rz: the rx/ry
|
|
46
|
+
* Euler XYZ decomposition is recovered from the normal, then the rz rotation
|
|
47
|
+
* is applied.
|
|
48
|
+
*
|
|
49
|
+
* normal = [sin(ry), -sin(rx)*cos(ry), cos(rx)*cos(ry)]
|
|
50
|
+
* ry = asin(normal[0])
|
|
51
|
+
* rx = atan2(-normal[1], normal[2]) (when cos(ry) !== 0)
|
|
52
|
+
* @param normal - cutting-plane unit normal.
|
|
53
|
+
* @param inPlaneAngle - in-plane rotation about the normal, in degrees.
|
|
54
|
+
* @returns the in-plane width and depth directions.
|
|
55
|
+
*/
|
|
56
|
+
export declare function computeBasisFromNormal(normal: Vec3, inPlaneAngle: number): {
|
|
57
|
+
widthDir: Vec3;
|
|
58
|
+
depthDir: Vec3;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Input parameters for splitWithParams.
|
|
62
|
+
*/
|
|
63
|
+
export interface SplitWithParamsInput {
|
|
64
|
+
/** 源几何(已在世界空间) */
|
|
65
|
+
shape: Shape;
|
|
66
|
+
/** 分割模式 */
|
|
67
|
+
cutMode: 'plane' | 'dovetail' | 'dowel' | 'straight-tenon' | 'tenon' | 'straight';
|
|
68
|
+
/** 切割面法线 */
|
|
69
|
+
normal: Vec3;
|
|
70
|
+
/** 切割面沿法线方向相对 bbCenter 的偏移(标量) */
|
|
71
|
+
offset: number;
|
|
72
|
+
/** 切割面绕法线的面内旋转(角度制,承载原 planeRotation 的 rz 分量) */
|
|
73
|
+
inPlaneAngle: number;
|
|
74
|
+
/** 源 mesh 的世界空间包围盒中心 */
|
|
75
|
+
bbCenter: Vec3;
|
|
76
|
+
/** 源 mesh 的世界空间包围盒尺寸(用于计算 bboxWidthOnWidthDir 和爆炸位移) */
|
|
77
|
+
bboxSize: Vec3;
|
|
78
|
+
/** 燕尾参数(cutMode='dovetail' 时需要) */
|
|
79
|
+
groove?: {
|
|
80
|
+
depth: number;
|
|
81
|
+
depthTolerance: number;
|
|
82
|
+
width: number;
|
|
83
|
+
widthTolerance: number;
|
|
84
|
+
flapsAngle: number;
|
|
85
|
+
};
|
|
86
|
+
/** 定位销参数(cutMode='dowel' 时需要) */
|
|
87
|
+
dowel?: {
|
|
88
|
+
diameter: number;
|
|
89
|
+
diameterTolerance: number;
|
|
90
|
+
height: number;
|
|
91
|
+
heightTolerance: number;
|
|
92
|
+
};
|
|
93
|
+
/** 直榫参数(cutMode='straight-tenon' 时需要) */
|
|
94
|
+
tenon?: {
|
|
95
|
+
sideLength: number;
|
|
96
|
+
sideLengthTolerance: number;
|
|
97
|
+
height: number;
|
|
98
|
+
heightTolerance: number;
|
|
99
|
+
};
|
|
100
|
+
/** 选择的截面(dowel/straight-tenon 用) */
|
|
101
|
+
selectedSections?: number[] | null;
|
|
102
|
+
/** 是否应用爆炸位移(默认 true;导出/重放纯几何时可设 false) */
|
|
103
|
+
applyExplode?: boolean;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Output of splitWithParams: the two halves plus the derived splitting data.
|
|
107
|
+
*/
|
|
108
|
+
export interface SplitWithParamsResult {
|
|
109
|
+
front: Shape;
|
|
110
|
+
back: Shape;
|
|
111
|
+
/** 实际使用的法线(派生量,供调用方记录/调试) */
|
|
112
|
+
normal: Vec3;
|
|
113
|
+
/** 实际使用的 planeDistance(派生量) */
|
|
114
|
+
planeDistance: number;
|
|
115
|
+
/** 实际使用的 planeCenter(派生量) */
|
|
116
|
+
planeCenter: Vec3;
|
|
117
|
+
/** 实际使用的 widthDir(派生量) */
|
|
118
|
+
widthDir: Vec3;
|
|
119
|
+
/** 爆炸位移(front 正、back 负) */
|
|
120
|
+
frontExplodeOffset: number;
|
|
121
|
+
backExplodeOffset: number;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Unified split entry point: the single split function shared by the UI
|
|
125
|
+
* executor and script replay. All parameter orchestration (planeParams,
|
|
126
|
+
* planeBasis, bboxWidthOnWidthDir, explode offset) happens inside this
|
|
127
|
+
* function; callers pass only semantic parameters. Both interaction paths
|
|
128
|
+
* (mouse / code) converge here, so the geometry result is identical.
|
|
129
|
+
* @param input - the split mode-specific input (shape, plane, mode params).
|
|
130
|
+
* @returns the split result with front/back halves and derived plane data.
|
|
131
|
+
*/
|
|
132
|
+
export declare function splitWithParams(input: SplitWithParamsInput): Promise<SplitWithParamsResult>;
|
|
133
|
+
/**
|
|
134
|
+
* Plane split of a mesh shape.
|
|
135
|
+
* @param shape - the mesh shape to split.
|
|
136
|
+
* @param plane - the cutting plane (normal + offset).
|
|
137
|
+
* @returns the front and back halves of the shape.
|
|
138
|
+
*/
|
|
139
|
+
export declare function split(shape: Shape, plane: SplitPlane): Promise<{
|
|
140
|
+
front: Shape;
|
|
141
|
+
back: Shape;
|
|
142
|
+
}>;
|
|
143
|
+
/**
|
|
144
|
+
* Dovetail split of a mesh shape.
|
|
145
|
+
* @param shape - the mesh shape to split.
|
|
146
|
+
* @param params - dovetail groove parameters plus the cutting plane setup.
|
|
147
|
+
* @returns the front/back halves and the dovetail wedge.
|
|
148
|
+
*/
|
|
149
|
+
export declare function dovetailSplit(shape: Shape, params: DovetailSplitParams): Promise<SplitResult>;
|
|
150
|
+
/**
|
|
151
|
+
* Dowel-pin split of a mesh shape.
|
|
152
|
+
* @param shape - the mesh shape to split.
|
|
153
|
+
* @param params - dowel parameters plus the cutting plane setup.
|
|
154
|
+
* @returns the front/back halves and the dowel wedge.
|
|
155
|
+
*/
|
|
156
|
+
export declare function dowelSplit(shape: Shape, params: DowelSplitParams): Promise<SplitResult>;
|
|
157
|
+
/**
|
|
158
|
+
* Straight-tenon split of a mesh shape.
|
|
159
|
+
* @param shape - the mesh shape to split.
|
|
160
|
+
* @param params - tenon parameters plus the cutting plane setup.
|
|
161
|
+
* @returns the front/back halves and the tenon wedge.
|
|
162
|
+
*/
|
|
163
|
+
export declare function tenonSplit(shape: Shape, params: TenonSplitParams): Promise<SplitResult>;
|
|
164
|
+
//# sourceMappingURL=fai_split.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fai_split.d.ts","sourceRoot":"","sources":["../../../src/extra/mesh/fai_split.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh 分割 API
|
|
3
|
+
*
|
|
4
|
+
* 提取来源:engine/boolean/csg.ts (computeSplit/computeDovetailSplit/...)
|
|
5
|
+
* 已是纯数据函数,直接包装。
|
|
6
|
+
*
|
|
7
|
+
* splitWithParams 是 UI 与重放共用的唯一分割入口:
|
|
8
|
+
* 参数编排(planeParams / planeBasis / 爆炸位移 / 世界坐标变换)
|
|
9
|
+
* 全部在此函数内部完成,调用方只需传入 cutMode + normal/offset/inPlaneAngle + bbCenter
|
|
10
|
+
* 以及各 cutMode 专属参数。
|
|
11
|
+
*/
|
|
12
|
+
import { computeSplit, computeDovetailSplit, computeDowelSplit, computeStraightTenonSplit, } from '../../boolean/csg-backend.js';
|
|
13
|
+
import { Euler, Quat, Vec3 as Vec3C } from '../../math3d/index.js';
|
|
14
|
+
// ── 派生量计算(从 split-store 下沉,UI 与重放共用同一份公式) ──
|
|
15
|
+
/**
|
|
16
|
+
* Derive the cutting-plane parameters from Euler angles (in degrees), the
|
|
17
|
+
* plane position and the bounding-box center. Behavior is identical to the
|
|
18
|
+
* former split-store.computePlaneParams.
|
|
19
|
+
* @param rotationX - rotation about X in degrees.
|
|
20
|
+
* @param rotationY - rotation about Y in degrees.
|
|
21
|
+
* @param rotationZ - rotation about Z in degrees.
|
|
22
|
+
* @param planePosition - offset of the cutting plane along the plane normal.
|
|
23
|
+
* @param bbCenter - world-space bounding-box center of the source mesh.
|
|
24
|
+
* @returns the plane normal, the plane's signed distance from the origin, and its center.
|
|
25
|
+
*/
|
|
26
|
+
export function computePlaneParams(rotationX, rotationY, rotationZ, planePosition, bbCenter) {
|
|
27
|
+
const rx = (rotationX * Math.PI) / 180;
|
|
28
|
+
const ry = (rotationY * Math.PI) / 180;
|
|
29
|
+
const rz = (rotationZ * Math.PI) / 180;
|
|
30
|
+
const euler = new Euler(rx, ry, rz, 'XYZ');
|
|
31
|
+
const quat = new Quat().setFromEuler(euler);
|
|
32
|
+
const normalVec = new Vec3C(0, 0, 1).applyQuaternion(quat);
|
|
33
|
+
const normal = [normalVec.x, normalVec.y, normalVec.z];
|
|
34
|
+
const planeCenter = [
|
|
35
|
+
bbCenter[0] + planePosition * normal[0],
|
|
36
|
+
bbCenter[1] + planePosition * normal[1],
|
|
37
|
+
bbCenter[2] + planePosition * normal[2],
|
|
38
|
+
];
|
|
39
|
+
const planeDistance = normal[0] * planeCenter[0] + normal[1] * planeCenter[1] + normal[2] * planeCenter[2];
|
|
40
|
+
return { normal, planeDistance, planeCenter };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Derive the plane basis vectors from Euler angles (in degrees). Behavior is
|
|
44
|
+
* identical to the former split-store.computePlaneBasis.
|
|
45
|
+
* @param rotationX - rotation about X in degrees.
|
|
46
|
+
* @param rotationY - rotation about Y in degrees.
|
|
47
|
+
* @param rotationZ - rotation about Z in degrees.
|
|
48
|
+
* @returns the plane normal plus the in-plane width and depth directions.
|
|
49
|
+
*/
|
|
50
|
+
export function computePlaneBasis(rotationX, rotationY, rotationZ) {
|
|
51
|
+
const rx = (rotationX * Math.PI) / 180;
|
|
52
|
+
const ry = (rotationY * Math.PI) / 180;
|
|
53
|
+
const rz = (rotationZ * Math.PI) / 180;
|
|
54
|
+
const euler = new Euler(rx, ry, rz, 'XYZ');
|
|
55
|
+
const quat = new Quat().setFromEuler(euler);
|
|
56
|
+
const normalVec = new Vec3C(0, 0, 1).applyQuaternion(quat);
|
|
57
|
+
const widthVec = new Vec3C(1, 0, 0).applyQuaternion(quat);
|
|
58
|
+
const depthVec = new Vec3C(0, 1, 0).applyQuaternion(quat);
|
|
59
|
+
return {
|
|
60
|
+
normal: [normalVec.x, normalVec.y, normalVec.z],
|
|
61
|
+
widthDir: [widthVec.x, widthVec.y, widthVec.z],
|
|
62
|
+
depthDir: [depthVec.x, depthVec.y, depthVec.z],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// ── 从法线 + 面内旋转推导基向量(纯数学,无 THREE 依赖) ──
|
|
66
|
+
/**
|
|
67
|
+
* Derive widthDir/depthDir from the cutting-plane normal and the in-plane
|
|
68
|
+
* rotation angle. Matches computePlaneBasis(rx, ry, rz) with
|
|
69
|
+
* normal = eulerXYZToNormal(rx, ry, 0) and inPlaneAngle = rz: the rx/ry
|
|
70
|
+
* Euler XYZ decomposition is recovered from the normal, then the rz rotation
|
|
71
|
+
* is applied.
|
|
72
|
+
*
|
|
73
|
+
* normal = [sin(ry), -sin(rx)*cos(ry), cos(rx)*cos(ry)]
|
|
74
|
+
* ry = asin(normal[0])
|
|
75
|
+
* rx = atan2(-normal[1], normal[2]) (when cos(ry) !== 0)
|
|
76
|
+
* @param normal - cutting-plane unit normal.
|
|
77
|
+
* @param inPlaneAngle - in-plane rotation about the normal, in degrees.
|
|
78
|
+
* @returns the in-plane width and depth directions.
|
|
79
|
+
*/
|
|
80
|
+
export function computeBasisFromNormal(normal, inPlaneAngle) {
|
|
81
|
+
const sinRy = Math.max(-1, Math.min(1, normal[0]));
|
|
82
|
+
const ry = Math.asin(sinRy);
|
|
83
|
+
const cosRy = Math.cos(ry);
|
|
84
|
+
let rx;
|
|
85
|
+
if (Math.abs(cosRy) < 1e-10) {
|
|
86
|
+
// 万向锁:ry = ±90°,rx 与 rz 耦合,设 rx = 0
|
|
87
|
+
rx = 0;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
rx = Math.atan2(-normal[1], normal[2]);
|
|
91
|
+
}
|
|
92
|
+
const rz = (inPlaneAngle * Math.PI) / 180;
|
|
93
|
+
// R = RX(rx) · RY(ry)(不含 rz 的部分)
|
|
94
|
+
// widthDir = R · (cos(rz), sin(rz), 0)
|
|
95
|
+
// depthDir = R · (-sin(rz), cos(rz), 0)
|
|
96
|
+
const cr = Math.cos(ry), sr = Math.sin(ry);
|
|
97
|
+
const cx = Math.cos(rx), sx = Math.sin(rx);
|
|
98
|
+
const cosRz = Math.cos(rz), sinRz = Math.sin(rz);
|
|
99
|
+
const widthDir = [
|
|
100
|
+
cr * cosRz,
|
|
101
|
+
sx * sr * cosRz + cx * sinRz,
|
|
102
|
+
-cx * sr * cosRz + sx * sinRz,
|
|
103
|
+
];
|
|
104
|
+
const depthDir = [
|
|
105
|
+
-cr * sinRz,
|
|
106
|
+
-sx * sr * sinRz + cx * cosRz,
|
|
107
|
+
cx * sr * sinRz + sx * cosRz,
|
|
108
|
+
];
|
|
109
|
+
return { widthDir, depthDir };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Unified split entry point: the single split function shared by the UI
|
|
113
|
+
* executor and script replay. All parameter orchestration (planeParams,
|
|
114
|
+
* planeBasis, bboxWidthOnWidthDir, explode offset) happens inside this
|
|
115
|
+
* function; callers pass only semantic parameters. Both interaction paths
|
|
116
|
+
* (mouse / code) converge here, so the geometry result is identical.
|
|
117
|
+
* @param input - the split mode-specific input (shape, plane, mode params).
|
|
118
|
+
* @returns the split result with front/back halves and derived plane data.
|
|
119
|
+
*/
|
|
120
|
+
export async function splitWithParams(input) {
|
|
121
|
+
const { shape, cutMode, normal, offset, inPlaneAngle, bbCenter, bboxSize } = input;
|
|
122
|
+
// 1. 从 normal + offset + bbCenter 派生切割平面参数
|
|
123
|
+
const planeCenter = [
|
|
124
|
+
bbCenter[0] + offset * normal[0],
|
|
125
|
+
bbCenter[1] + offset * normal[1],
|
|
126
|
+
bbCenter[2] + offset * normal[2],
|
|
127
|
+
];
|
|
128
|
+
const planeDistance = normal[0] * planeCenter[0] + normal[1] * planeCenter[1] + normal[2] * planeCenter[2];
|
|
129
|
+
// 2. 从 normal + inPlaneAngle 派生基向量
|
|
130
|
+
const { widthDir } = computeBasisFromNormal(normal, inPlaneAngle);
|
|
131
|
+
// 3. 按 cutMode 分发
|
|
132
|
+
let front;
|
|
133
|
+
let back;
|
|
134
|
+
if (cutMode === 'dovetail') {
|
|
135
|
+
const bboxWidthOnWidthDir = Math.abs(bboxSize[0] * widthDir[0]) +
|
|
136
|
+
Math.abs(bboxSize[1] * widthDir[1]) +
|
|
137
|
+
Math.abs(bboxSize[2] * widthDir[2]);
|
|
138
|
+
const groove = input.groove ?? {
|
|
139
|
+
depth: 0, depthTolerance: 0, width: 0, widthTolerance: 0, flapsAngle: 0,
|
|
140
|
+
};
|
|
141
|
+
const result = await computeDovetailSplit(shape, normal, planeDistance, planeCenter, widthDir, bboxWidthOnWidthDir, groove);
|
|
142
|
+
front = result.front;
|
|
143
|
+
back = result.back;
|
|
144
|
+
const result2 = await finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input);
|
|
145
|
+
return result2;
|
|
146
|
+
}
|
|
147
|
+
else if (cutMode === 'dowel') {
|
|
148
|
+
const dowel = input.dowel ?? {
|
|
149
|
+
diameter: 0, diameterTolerance: 0, height: 0, heightTolerance: 0,
|
|
150
|
+
};
|
|
151
|
+
const result = await computeDowelSplit(shape, normal, planeDistance, planeCenter, widthDir, dowel, input.selectedSections ?? null);
|
|
152
|
+
front = result.front;
|
|
153
|
+
back = result.back;
|
|
154
|
+
return finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input);
|
|
155
|
+
}
|
|
156
|
+
else if (cutMode === 'straight-tenon' || cutMode === 'tenon') {
|
|
157
|
+
const tenon = input.tenon ?? {
|
|
158
|
+
sideLength: 0, sideLengthTolerance: 0, height: 0, heightTolerance: 0,
|
|
159
|
+
};
|
|
160
|
+
const result = await computeStraightTenonSplit(shape, normal, planeDistance, planeCenter, widthDir, tenon, input.selectedSections ?? null);
|
|
161
|
+
front = result.front;
|
|
162
|
+
back = result.back;
|
|
163
|
+
return finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// plane / straight / default
|
|
167
|
+
const result = await computeSplit(shape, normal, planeDistance);
|
|
168
|
+
front = result.front;
|
|
169
|
+
back = result.back;
|
|
170
|
+
return finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/** 计算爆炸位移并应用到 front/back */
|
|
174
|
+
async function finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input) {
|
|
175
|
+
const applyExplode = input.applyExplode ?? true;
|
|
176
|
+
// 爆炸位移:包围盒对角线的 2% + joinery 深度的一半
|
|
177
|
+
const bboxDiagonal = Math.sqrt(bboxSize[0] * bboxSize[0] + bboxSize[1] * bboxSize[1] + bboxSize[2] * bboxSize[2]);
|
|
178
|
+
const baseOffset = bboxDiagonal * 0.02;
|
|
179
|
+
let joineryOffset = 0;
|
|
180
|
+
if (cutMode === 'dovetail') {
|
|
181
|
+
joineryOffset = (input.groove?.depth ?? 0) / 2;
|
|
182
|
+
}
|
|
183
|
+
else if (cutMode === 'dowel') {
|
|
184
|
+
joineryOffset = (input.dowel?.height ?? 0) / 2;
|
|
185
|
+
}
|
|
186
|
+
else if (cutMode === 'straight-tenon' || cutMode === 'tenon') {
|
|
187
|
+
joineryOffset = (input.tenon?.height ?? 0) / 2;
|
|
188
|
+
}
|
|
189
|
+
const frontOffset = baseOffset + joineryOffset;
|
|
190
|
+
const backOffset = -(baseOffset + joineryOffset);
|
|
191
|
+
if (applyExplode) {
|
|
192
|
+
front = { positions: offsetPositions(front.positions, normal, frontOffset), indices: front.indices };
|
|
193
|
+
back = { positions: offsetPositions(back.positions, normal, backOffset), indices: back.indices };
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
front,
|
|
197
|
+
back,
|
|
198
|
+
normal,
|
|
199
|
+
planeDistance,
|
|
200
|
+
planeCenter,
|
|
201
|
+
widthDir,
|
|
202
|
+
frontExplodeOffset: applyExplode ? frontOffset : 0,
|
|
203
|
+
backExplodeOffset: applyExplode ? backOffset : 0,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/** 沿法线方向偏移所有顶点 */
|
|
207
|
+
function offsetPositions(positions, normal, offset) {
|
|
208
|
+
const out = new Float32Array(positions);
|
|
209
|
+
for (let i = 0; i < out.length; i += 3) {
|
|
210
|
+
out[i] += normal[0] * offset;
|
|
211
|
+
out[i + 1] += normal[1] * offset;
|
|
212
|
+
out[i + 2] += normal[2] * offset;
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
// ── 低级 API(保留向后兼容) ──
|
|
217
|
+
/**
|
|
218
|
+
* Plane split of a mesh shape.
|
|
219
|
+
* @param shape - the mesh shape to split.
|
|
220
|
+
* @param plane - the cutting plane (normal + offset).
|
|
221
|
+
* @returns the front and back halves of the shape.
|
|
222
|
+
*/
|
|
223
|
+
export async function split(shape, plane) {
|
|
224
|
+
const result = await computeSplit(shape, plane.normal, plane.offset);
|
|
225
|
+
return { front: result.front, back: result.back };
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Dovetail split of a mesh shape.
|
|
229
|
+
* @param shape - the mesh shape to split.
|
|
230
|
+
* @param params - dovetail groove parameters plus the cutting plane setup.
|
|
231
|
+
* @returns the front/back halves and the dovetail wedge.
|
|
232
|
+
*/
|
|
233
|
+
export async function dovetailSplit(shape, params) {
|
|
234
|
+
const result = await computeDovetailSplit(shape, params.plane.normal, params.plane.offset, params.planeCenter, params.widthDir, params.bboxWidthOnWidthDir, params.groove);
|
|
235
|
+
return {
|
|
236
|
+
front: result.front,
|
|
237
|
+
back: result.back,
|
|
238
|
+
wedge: result.wedge,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Dowel-pin split of a mesh shape.
|
|
243
|
+
* @param shape - the mesh shape to split.
|
|
244
|
+
* @param params - dowel parameters plus the cutting plane setup.
|
|
245
|
+
* @returns the front/back halves and the dowel wedge.
|
|
246
|
+
*/
|
|
247
|
+
export async function dowelSplit(shape, params) {
|
|
248
|
+
const result = await computeDowelSplit(shape, params.plane.normal, params.plane.offset, params.planeCenter, params.widthDir, params.dowel, params.selectedSections);
|
|
249
|
+
return {
|
|
250
|
+
front: result.front,
|
|
251
|
+
back: result.back,
|
|
252
|
+
wedge: result.wedge,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Straight-tenon split of a mesh shape.
|
|
257
|
+
* @param shape - the mesh shape to split.
|
|
258
|
+
* @param params - tenon parameters plus the cutting plane setup.
|
|
259
|
+
* @returns the front/back halves and the tenon wedge.
|
|
260
|
+
*/
|
|
261
|
+
export async function tenonSplit(shape, params) {
|
|
262
|
+
const result = await computeStraightTenonSplit(shape, params.plane.normal, params.plane.offset, params.planeCenter, params.widthDir, params.tenon, params.selectedSections);
|
|
263
|
+
return {
|
|
264
|
+
front: result.front,
|
|
265
|
+
back: result.back,
|
|
266
|
+
wedge: result.wedge,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=fai_split.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fai_split.js","sourceRoot":"","sources":["../../../src/extra/mesh/fai_split.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,KAAK,EAAE,MAAM,cAAc,CAAA;AAGzD,8CAA8C;AAE9C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,SAAiB,EACjB,SAAiB,EACjB,SAAiB,EACjB,aAAqB,EACrB,QAAc;IAEd,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IACtC,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IACtC,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IAEtC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAE1D,MAAM,MAAM,GAAS,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IAE5D,MAAM,WAAW,GAAS;QACxB,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC;QACvC,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC;QACvC,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC;KACxC,CAAA;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAE1G,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAiB,EACjB,SAAiB,EACjB,SAAiB;IAEjB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IACtC,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IACtC,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IAEtC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IAE3C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAC1D,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IACzD,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAEzD,OAAO;QACL,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAC/C,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC9C,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;KAC/C,CAAA;AACH,CAAC;AAED,wCAAwC;AAExC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAY,EACZ,YAAoB;IAEpB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAClD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAE1B,IAAI,EAAU,CAAA;IACd,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC;QAC5B,oCAAoC;QACpC,EAAE,GAAG,CAAC,CAAA;IACR,CAAC;SAAM,CAAC;QACN,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,EAAE,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IAEzC,iCAAiC;IACjC,uCAAuC;IACvC,wCAAwC;IACxC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC1C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAEhD,MAAM,QAAQ,GAAS;QACrB,EAAE,GAAG,KAAK;QACV,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,KAAK;QAC5B,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,KAAK;KAC9B,CAAA;IAED,MAAM,QAAQ,GAAS;QACrB,CAAC,EAAE,GAAG,KAAK;QACX,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,KAAK;QAC7B,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,KAAK;KAC7B,CAAA;IAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;AAC/B,CAAC;AAqED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAA2B;IAC/D,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAElF,2CAA2C;IAC3C,MAAM,WAAW,GAAS;QACxB,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;QAChC,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;QAChC,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;KACjC,CAAA;IACD,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAE1G,mCAAmC;IACnC,MAAM,EAAE,QAAQ,EAAE,GAAG,sBAAsB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAEjE,kBAAkB;IAClB,IAAI,KAAY,CAAA;IAChB,IAAI,IAAW,CAAA;IAEf,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,MAAM,mBAAmB,GACvB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI;YAC7B,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC;SACxE,CAAA;QACD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,CAAC,CAAA;QAC3H,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QAExC,MAAM,OAAO,GAA0B,MAAM,eAAe,CAC1D,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CACpF,CAAA;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;SAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI;YAC3B,QAAQ,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC;SACjE,CAAA;QACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,gBAAgB,IAAI,IAAI,CAAC,CAAA;QAClI,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QACxC,OAAO,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IAC7G,CAAC;SAAM,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI;YAC3B,UAAU,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC;SACrE,CAAA;QACD,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,gBAAgB,IAAI,IAAI,CAAC,CAAA;QAC1I,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QACxC,OAAO,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IAC7G,CAAC;SAAM,CAAC;QACN,6BAA6B;QAC7B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;QAC/D,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QACxC,OAAO,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IAC7G,CAAC;AACH,CAAC;AAED,4BAA4B;AAC5B,KAAK,UAAU,eAAe,CAC5B,KAAY,EACZ,IAAW,EACX,MAAY,EACZ,aAAqB,EACrB,WAAiB,EACjB,QAAc,EACd,QAAc,EACd,OAAe,EACf,KAA2B;IAE3B,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,IAAI,CAAA;IAE/C,kCAAkC;IAClC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAC5B,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAClF,CAAA;IACD,MAAM,UAAU,GAAG,YAAY,GAAG,IAAI,CAAA;IACtC,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,aAAa,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IAChD,CAAC;SAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/B,aAAa,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IAChD,CAAC;SAAM,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/D,aAAa,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IAChD,CAAC;IACD,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,CAAA;IAC9C,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,GAAG,aAAa,CAAC,CAAA;IAEhD,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,GAAG,EAAE,SAAS,EAAE,eAAe,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;QACpG,IAAI,GAAG,EAAE,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IAClG,CAAC;IAED,OAAO;QACL,KAAK;QACL,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW;QACX,QAAQ;QACR,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAClD,iBAAiB,EAAE,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;KACjD,CAAA;AACH,CAAC;AAED,kBAAkB;AAClB,SAAS,eAAe,CACtB,SAAuB,EACvB,MAAY,EACZ,MAAc;IAEd,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAA;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,CAAC,CAAC,IAAQ,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAA;QAChC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAA;QAChC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAA;IAClC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,uBAAuB;AAEvB;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,KAAY,EAAE,KAAiB;IACzD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACpE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAY,EAAE,MAA2B;IAC3E,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,KAAK,EACL,MAAM,CAAC,KAAK,CAAC,MAAM,EACnB,MAAM,CAAC,KAAK,CAAC,MAAM,EACnB,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,mBAAmB,EAC1B,MAAM,CAAC,MAAM,CACd,CAAA;IACD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAY,EAAE,MAAwB;IACrE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,KAAK,EACL,MAAM,CAAC,KAAK,CAAC,MAAM,EACnB,MAAM,CAAC,KAAK,CAAC,MAAM,EACnB,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,gBAAgB,CACxB,CAAA;IACD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAY,EAAE,MAAwB;IACrE,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAC5C,KAAK,EACL,MAAM,CAAC,KAAK,CAAC,MAAM,EACnB,MAAM,CAAC,KAAK,CAAC,MAAM,EACnB,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,gBAAgB,CACxB,CAAA;IACD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAA;AACH,CAAC","sourcesContent":["/**\n * mesh 分割 API\n *\n * 提取来源:engine/boolean/csg.ts (computeSplit/computeDovetailSplit/...)\n * 已是纯数据函数,直接包装。\n *\n * splitWithParams 是 UI 与重放共用的唯一分割入口:\n * 参数编排(planeParams / planeBasis / 爆炸位移 / 世界坐标变换)\n * 全部在此函数内部完成,调用方只需传入 cutMode + normal/offset/inPlaneAngle + bbCenter\n * 以及各 cutMode 专属参数。\n */\n\nimport {\n computeSplit,\n computeDovetailSplit,\n computeDowelSplit,\n computeStraightTenonSplit,\n} from '../../boolean/csg-backend'\nimport { Euler, Quat, Vec3 as Vec3C } from '../../math3d'\nimport type { Shape, SplitResult, SplitPlane, DovetailSplitParams, DowelSplitParams, TenonSplitParams, Vec3 } from '../../mesh/types'\n\n// ── 派生量计算(从 split-store 下沉,UI 与重放共用同一份公式) ──\n\n/**\n * Derive the cutting-plane parameters from Euler angles (in degrees), the\n * plane position and the bounding-box center. Behavior is identical to the\n * former split-store.computePlaneParams.\n * @param rotationX - rotation about X in degrees.\n * @param rotationY - rotation about Y in degrees.\n * @param rotationZ - rotation about Z in degrees.\n * @param planePosition - offset of the cutting plane along the plane normal.\n * @param bbCenter - world-space bounding-box center of the source mesh.\n * @returns the plane normal, the plane's signed distance from the origin, and its center.\n */\nexport function computePlaneParams(\n rotationX: number,\n rotationY: number,\n rotationZ: number,\n planePosition: number,\n bbCenter: Vec3,\n): { normal: Vec3; planeDistance: number; planeCenter: Vec3 } {\n const rx = (rotationX * Math.PI) / 180\n const ry = (rotationY * Math.PI) / 180\n const rz = (rotationZ * Math.PI) / 180\n\n const euler = new Euler(rx, ry, rz, 'XYZ')\n const quat = new Quat().setFromEuler(euler)\n const normalVec = new Vec3C(0, 0, 1).applyQuaternion(quat)\n\n const normal: Vec3 = [normalVec.x, normalVec.y, normalVec.z]\n\n const planeCenter: Vec3 = [\n bbCenter[0] + planePosition * normal[0],\n bbCenter[1] + planePosition * normal[1],\n bbCenter[2] + planePosition * normal[2],\n ]\n\n const planeDistance = normal[0] * planeCenter[0] + normal[1] * planeCenter[1] + normal[2] * planeCenter[2]\n\n return { normal, planeDistance, planeCenter }\n}\n\n/**\n * Derive the plane basis vectors from Euler angles (in degrees). Behavior is\n * identical to the former split-store.computePlaneBasis.\n * @param rotationX - rotation about X in degrees.\n * @param rotationY - rotation about Y in degrees.\n * @param rotationZ - rotation about Z in degrees.\n * @returns the plane normal plus the in-plane width and depth directions.\n */\nexport function computePlaneBasis(\n rotationX: number,\n rotationY: number,\n rotationZ: number,\n): { normal: Vec3; widthDir: Vec3; depthDir: Vec3 } {\n const rx = (rotationX * Math.PI) / 180\n const ry = (rotationY * Math.PI) / 180\n const rz = (rotationZ * Math.PI) / 180\n\n const euler = new Euler(rx, ry, rz, 'XYZ')\n const quat = new Quat().setFromEuler(euler)\n\n const normalVec = new Vec3C(0, 0, 1).applyQuaternion(quat)\n const widthVec = new Vec3C(1, 0, 0).applyQuaternion(quat)\n const depthVec = new Vec3C(0, 1, 0).applyQuaternion(quat)\n\n return {\n normal: [normalVec.x, normalVec.y, normalVec.z],\n widthDir: [widthVec.x, widthVec.y, widthVec.z],\n depthDir: [depthVec.x, depthVec.y, depthVec.z],\n }\n}\n\n// ── 从法线 + 面内旋转推导基向量(纯数学,无 THREE 依赖) ──\n\n/**\n * Derive widthDir/depthDir from the cutting-plane normal and the in-plane\n * rotation angle. Matches computePlaneBasis(rx, ry, rz) with\n * normal = eulerXYZToNormal(rx, ry, 0) and inPlaneAngle = rz: the rx/ry\n * Euler XYZ decomposition is recovered from the normal, then the rz rotation\n * is applied.\n *\n * normal = [sin(ry), -sin(rx)*cos(ry), cos(rx)*cos(ry)]\n * ry = asin(normal[0])\n * rx = atan2(-normal[1], normal[2]) (when cos(ry) !== 0)\n * @param normal - cutting-plane unit normal.\n * @param inPlaneAngle - in-plane rotation about the normal, in degrees.\n * @returns the in-plane width and depth directions.\n */\nexport function computeBasisFromNormal(\n normal: Vec3,\n inPlaneAngle: number,\n): { widthDir: Vec3; depthDir: Vec3 } {\n const sinRy = Math.max(-1, Math.min(1, normal[0]))\n const ry = Math.asin(sinRy)\n const cosRy = Math.cos(ry)\n\n let rx: number\n if (Math.abs(cosRy) < 1e-10) {\n // 万向锁:ry = ±90°,rx 与 rz 耦合,设 rx = 0\n rx = 0\n } else {\n rx = Math.atan2(-normal[1], normal[2])\n }\n\n const rz = (inPlaneAngle * Math.PI) / 180\n\n // R = RX(rx) · RY(ry)(不含 rz 的部分)\n // widthDir = R · (cos(rz), sin(rz), 0)\n // depthDir = R · (-sin(rz), cos(rz), 0)\n const cr = Math.cos(ry), sr = Math.sin(ry)\n const cx = Math.cos(rx), sx = Math.sin(rx)\n const cosRz = Math.cos(rz), sinRz = Math.sin(rz)\n\n const widthDir: Vec3 = [\n cr * cosRz,\n sx * sr * cosRz + cx * sinRz,\n -cx * sr * cosRz + sx * sinRz,\n ]\n\n const depthDir: Vec3 = [\n -cr * sinRz,\n -sx * sr * sinRz + cx * cosRz,\n cx * sr * sinRz + sx * cosRz,\n ]\n\n return { widthDir, depthDir }\n}\n\n// ── 统一分割入口 ──\n\n/**\n * Input parameters for splitWithParams.\n */\nexport interface SplitWithParamsInput {\n /** 源几何(已在世界空间) */\n shape: Shape\n /** 分割模式 */\n cutMode: 'plane' | 'dovetail' | 'dowel' | 'straight-tenon' | 'tenon' | 'straight'\n /** 切割面法线 */\n normal: Vec3\n /** 切割面沿法线方向相对 bbCenter 的偏移(标量) */\n offset: number\n /** 切割面绕法线的面内旋转(角度制,承载原 planeRotation 的 rz 分量) */\n inPlaneAngle: number\n /** 源 mesh 的世界空间包围盒中心 */\n bbCenter: Vec3\n /** 源 mesh 的世界空间包围盒尺寸(用于计算 bboxWidthOnWidthDir 和爆炸位移) */\n bboxSize: Vec3\n /** 燕尾参数(cutMode='dovetail' 时需要) */\n groove?: {\n depth: number\n depthTolerance: number\n width: number\n widthTolerance: number\n flapsAngle: number\n }\n /** 定位销参数(cutMode='dowel' 时需要) */\n dowel?: {\n diameter: number\n diameterTolerance: number\n height: number\n heightTolerance: number\n }\n /** 直榫参数(cutMode='straight-tenon' 时需要) */\n tenon?: {\n sideLength: number\n sideLengthTolerance: number\n height: number\n heightTolerance: number\n }\n /** 选择的截面(dowel/straight-tenon 用) */\n selectedSections?: number[] | null\n /** 是否应用爆炸位移(默认 true;导出/重放纯几何时可设 false) */\n applyExplode?: boolean\n}\n\n/**\n * Output of splitWithParams: the two halves plus the derived splitting data.\n */\nexport interface SplitWithParamsResult {\n front: Shape\n back: Shape\n /** 实际使用的法线(派生量,供调用方记录/调试) */\n normal: Vec3\n /** 实际使用的 planeDistance(派生量) */\n planeDistance: number\n /** 实际使用的 planeCenter(派生量) */\n planeCenter: Vec3\n /** 实际使用的 widthDir(派生量) */\n widthDir: Vec3\n /** 爆炸位移(front 正、back 负) */\n frontExplodeOffset: number\n backExplodeOffset: number\n}\n\n/**\n * Unified split entry point: the single split function shared by the UI\n * executor and script replay. All parameter orchestration (planeParams,\n * planeBasis, bboxWidthOnWidthDir, explode offset) happens inside this\n * function; callers pass only semantic parameters. Both interaction paths\n * (mouse / code) converge here, so the geometry result is identical.\n * @param input - the split mode-specific input (shape, plane, mode params).\n * @returns the split result with front/back halves and derived plane data.\n */\nexport async function splitWithParams(input: SplitWithParamsInput): Promise<SplitWithParamsResult> {\n const { shape, cutMode, normal, offset, inPlaneAngle, bbCenter, bboxSize } = input\n\n // 1. 从 normal + offset + bbCenter 派生切割平面参数\n const planeCenter: Vec3 = [\n bbCenter[0] + offset * normal[0],\n bbCenter[1] + offset * normal[1],\n bbCenter[2] + offset * normal[2],\n ]\n const planeDistance = normal[0] * planeCenter[0] + normal[1] * planeCenter[1] + normal[2] * planeCenter[2]\n\n // 2. 从 normal + inPlaneAngle 派生基向量\n const { widthDir } = computeBasisFromNormal(normal, inPlaneAngle)\n\n // 3. 按 cutMode 分发\n let front: Shape\n let back: Shape\n\n if (cutMode === 'dovetail') {\n const bboxWidthOnWidthDir =\n Math.abs(bboxSize[0] * widthDir[0]) +\n Math.abs(bboxSize[1] * widthDir[1]) +\n Math.abs(bboxSize[2] * widthDir[2])\n const groove = input.groove ?? {\n depth: 0, depthTolerance: 0, width: 0, widthTolerance: 0, flapsAngle: 0,\n }\n const result = await computeDovetailSplit(shape, normal, planeDistance, planeCenter, widthDir, bboxWidthOnWidthDir, groove)\n front = result.front; back = result.back\n\n const result2: SplitWithParamsResult = await finalizeExplode(\n front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input,\n )\n return result2\n } else if (cutMode === 'dowel') {\n const dowel = input.dowel ?? {\n diameter: 0, diameterTolerance: 0, height: 0, heightTolerance: 0,\n }\n const result = await computeDowelSplit(shape, normal, planeDistance, planeCenter, widthDir, dowel, input.selectedSections ?? null)\n front = result.front; back = result.back\n return finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input)\n } else if (cutMode === 'straight-tenon' || cutMode === 'tenon') {\n const tenon = input.tenon ?? {\n sideLength: 0, sideLengthTolerance: 0, height: 0, heightTolerance: 0,\n }\n const result = await computeStraightTenonSplit(shape, normal, planeDistance, planeCenter, widthDir, tenon, input.selectedSections ?? null)\n front = result.front; back = result.back\n return finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input)\n } else {\n // plane / straight / default\n const result = await computeSplit(shape, normal, planeDistance)\n front = result.front; back = result.back\n return finalizeExplode(front, back, normal, planeDistance, planeCenter, widthDir, bboxSize, cutMode, input)\n }\n}\n\n/** 计算爆炸位移并应用到 front/back */\nasync function finalizeExplode(\n front: Shape,\n back: Shape,\n normal: Vec3,\n planeDistance: number,\n planeCenter: Vec3,\n widthDir: Vec3,\n bboxSize: Vec3,\n cutMode: string,\n input: SplitWithParamsInput,\n): Promise<SplitWithParamsResult> {\n const applyExplode = input.applyExplode ?? true\n\n // 爆炸位移:包围盒对角线的 2% + joinery 深度的一半\n const bboxDiagonal = Math.sqrt(\n bboxSize[0] * bboxSize[0] + bboxSize[1] * bboxSize[1] + bboxSize[2] * bboxSize[2],\n )\n const baseOffset = bboxDiagonal * 0.02\n let joineryOffset = 0\n if (cutMode === 'dovetail') {\n joineryOffset = (input.groove?.depth ?? 0) / 2\n } else if (cutMode === 'dowel') {\n joineryOffset = (input.dowel?.height ?? 0) / 2\n } else if (cutMode === 'straight-tenon' || cutMode === 'tenon') {\n joineryOffset = (input.tenon?.height ?? 0) / 2\n }\n const frontOffset = baseOffset + joineryOffset\n const backOffset = -(baseOffset + joineryOffset)\n\n if (applyExplode) {\n front = { positions: offsetPositions(front.positions, normal, frontOffset), indices: front.indices }\n back = { positions: offsetPositions(back.positions, normal, backOffset), indices: back.indices }\n }\n\n return {\n front,\n back,\n normal,\n planeDistance,\n planeCenter,\n widthDir,\n frontExplodeOffset: applyExplode ? frontOffset : 0,\n backExplodeOffset: applyExplode ? backOffset : 0,\n }\n}\n\n/** 沿法线方向偏移所有顶点 */\nfunction offsetPositions(\n positions: Float32Array,\n normal: Vec3,\n offset: number,\n): Float32Array {\n const out = new Float32Array(positions)\n for (let i = 0; i < out.length; i += 3) {\n out[i] += normal[0] * offset\n out[i + 1] += normal[1] * offset\n out[i + 2] += normal[2] * offset\n }\n return out\n}\n\n// ── 低级 API(保留向后兼容) ──\n\n/**\n * Plane split of a mesh shape.\n * @param shape - the mesh shape to split.\n * @param plane - the cutting plane (normal + offset).\n * @returns the front and back halves of the shape.\n */\nexport async function split(shape: Shape, plane: SplitPlane): Promise<{ front: Shape; back: Shape }> {\n const result = await computeSplit(shape, plane.normal, plane.offset)\n return { front: result.front, back: result.back }\n}\n\n/**\n * Dovetail split of a mesh shape.\n * @param shape - the mesh shape to split.\n * @param params - dovetail groove parameters plus the cutting plane setup.\n * @returns the front/back halves and the dovetail wedge.\n */\nexport async function dovetailSplit(shape: Shape, params: DovetailSplitParams): Promise<SplitResult> {\n const result = await computeDovetailSplit(\n shape,\n params.plane.normal,\n params.plane.offset,\n params.planeCenter,\n params.widthDir,\n params.bboxWidthOnWidthDir,\n params.groove,\n )\n return {\n front: result.front,\n back: result.back,\n wedge: result.wedge,\n }\n}\n\n/**\n * Dowel-pin split of a mesh shape.\n * @param shape - the mesh shape to split.\n * @param params - dowel parameters plus the cutting plane setup.\n * @returns the front/back halves and the dowel wedge.\n */\nexport async function dowelSplit(shape: Shape, params: DowelSplitParams): Promise<SplitResult> {\n const result = await computeDowelSplit(\n shape,\n params.plane.normal,\n params.plane.offset,\n params.planeCenter,\n params.widthDir,\n params.dowel,\n params.selectedSections,\n )\n return {\n front: result.front,\n back: result.back,\n wedge: result.wedge,\n }\n}\n\n/**\n * Straight-tenon split of a mesh shape.\n * @param shape - the mesh shape to split.\n * @param params - tenon parameters plus the cutting plane setup.\n * @returns the front/back halves and the tenon wedge.\n */\nexport async function tenonSplit(shape: Shape, params: TenonSplitParams): Promise<SplitResult> {\n const result = await computeStraightTenonSplit(\n shape,\n params.plane.normal,\n params.plane.offset,\n params.planeCenter,\n params.widthDir,\n params.tenon,\n params.selectedSections,\n )\n return {\n front: result.front,\n back: result.back,\n wedge: result.wedge,\n }\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh primitives — editor extension mesh-path creators.
|
|
3
|
+
*
|
|
4
|
+
* `text` and `svgExtrude` are the two creators whose mesh implementations
|
|
5
|
+
* used to carry three's non-basic geometry chain (`Shape` / `ExtrudeGeometry` /
|
|
6
|
+
* `SVGLoader`). They moved here from core's `mesh/primitives.ts` so the
|
|
7
|
+
* platform mesh entry no longer drags that chain (nor `three/examples/**`)
|
|
8
|
+
* into every consumer.
|
|
9
|
+
*
|
|
10
|
+
* Both return core `Shape` directly: text/SVG → Contour[] → `extrudeShape`
|
|
11
|
+
* (three-free). Coordinates: Z-up, millimetres.
|
|
12
|
+
*/
|
|
13
|
+
import type { Shape, TextParams, SvgExtrudeParams } from '../../mesh/types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Create text geometry. Font loading is asynchronous, so this function is
|
|
16
|
+
* async; CJK text is rendered with the system font when one is available.
|
|
17
|
+
*
|
|
18
|
+
* @param params - text parameters (text, size, depth).
|
|
19
|
+
* @returns the text shape.
|
|
20
|
+
*/
|
|
21
|
+
export declare function text(params: TextParams): Promise<Shape>;
|
|
22
|
+
/**
|
|
23
|
+
* Create an extruded geometry from an SVG source.
|
|
24
|
+
*
|
|
25
|
+
* @param params - SVG extrude parameters (svg, depth, target size, optional natural size).
|
|
26
|
+
* @returns the extruded shape.
|
|
27
|
+
*/
|
|
28
|
+
export declare function svgExtrude(params: SvgExtrudeParams): Shape;
|
|
29
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../../src/extra/mesh/primitives.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAM3E;;;;;;GAMG;AACH,wBAAsB,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAc7D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,KAAK,CAO1D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { svgToExtrudedGeometry } from '../extras/svg-extrude.js';
|
|
2
|
+
import { createTextGeometry, getOpentypeFont } from '../extras/text-geometry.js';
|
|
3
|
+
import { createMixedTextGeometry } from '../extras/text-cjk.js';
|
|
4
|
+
import { containsCjk, loadSystemCjkFont } from '../../primitives/text/cjk-font.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create text geometry. Font loading is asynchronous, so this function is
|
|
7
|
+
* async; CJK text is rendered with the system font when one is available.
|
|
8
|
+
*
|
|
9
|
+
* @param params - text parameters (text, size, depth).
|
|
10
|
+
* @returns the text shape.
|
|
11
|
+
*/
|
|
12
|
+
export async function text(params) {
|
|
13
|
+
const font = await getOpentypeFont();
|
|
14
|
+
if (containsCjk(params.text)) {
|
|
15
|
+
const cjkFont = await loadSystemCjkFont();
|
|
16
|
+
if (cjkFont) {
|
|
17
|
+
return createMixedTextGeometry(params.text, params.size, params.depth, cjkFont.font, font);
|
|
18
|
+
}
|
|
19
|
+
// No CJK font available: replace CJK chars with '?' so geometry still
|
|
20
|
+
// can be created (graceful degradation). Without this, createTextGeometry
|
|
21
|
+
// would throw because CJK glyphs are .notdef in OpenSans Regular.
|
|
22
|
+
const fallback = params.text.replace(/[\u4E00-\u9FFF\u3400-\u4DBF\u2F800-\u2FA1F\u3000-\u303F\uFF00-\uFFEF]/g, '?');
|
|
23
|
+
return createTextGeometry(fallback, params.size, params.depth, font);
|
|
24
|
+
}
|
|
25
|
+
return createTextGeometry(params.text, params.size, params.depth, font);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create an extruded geometry from an SVG source.
|
|
29
|
+
*
|
|
30
|
+
* @param params - SVG extrude parameters (svg, depth, target size, optional natural size).
|
|
31
|
+
* @returns the extruded shape.
|
|
32
|
+
*/
|
|
33
|
+
export function svgExtrude(params) {
|
|
34
|
+
return svgToExtrudedGeometry(params.svg, {
|
|
35
|
+
depth: params.depth,
|
|
36
|
+
targetLongSide: params.targetLongSide ?? 20,
|
|
37
|
+
naturalWidth: params.naturalWidth ?? 0,
|
|
38
|
+
naturalHeight: params.naturalHeight ?? 0,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=primitives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../../src/extra/mesh/primitives.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,MAAkB;IAC3C,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAA;IACpC,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAA;QACzC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC5F,CAAC;QACD,sEAAsE;QACtE,0EAA0E;QAC1E,kEAAkE;QAClE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,wEAAwE,EAAE,GAAG,CAAC,CAAA;QACnH,OAAO,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IACtE,CAAC;IACD,OAAO,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACzE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,MAAwB;IACjD,OAAO,qBAAqB,CAAC,MAAM,CAAC,GAAG,EAAE;QACvC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,EAAE;QAC3C,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC;QACtC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,CAAC;KACzC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["/**\n * mesh primitives — editor extension mesh-path creators.\n *\n * `text` and `svgExtrude` are the two creators whose mesh implementations\n * used to carry three's non-basic geometry chain (`Shape` / `ExtrudeGeometry` /\n * `SVGLoader`). They moved here from core's `mesh/primitives.ts` so the\n * platform mesh entry no longer drags that chain (nor `three/examples/**`)\n * into every consumer.\n *\n * Both return core `Shape` directly: text/SVG → Contour[] → `extrudeShape`\n * (three-free). Coordinates: Z-up, millimetres.\n */\nimport type { Shape, TextParams, SvgExtrudeParams } from '../../mesh/types'\nimport { svgToExtrudedGeometry } from '../extras/svg-extrude'\nimport { createTextGeometry, getOpentypeFont } from '../extras/text-geometry'\nimport { createMixedTextGeometry } from '../extras/text-cjk'\nimport { containsCjk, loadSystemCjkFont } from '../../primitives/text/cjk-font'\n\n/**\n * Create text geometry. Font loading is asynchronous, so this function is\n * async; CJK text is rendered with the system font when one is available.\n *\n * @param params - text parameters (text, size, depth).\n * @returns the text shape.\n */\nexport async function text(params: TextParams): Promise<Shape> {\n const font = await getOpentypeFont()\n if (containsCjk(params.text)) {\n const cjkFont = await loadSystemCjkFont()\n if (cjkFont) {\n return createMixedTextGeometry(params.text, params.size, params.depth, cjkFont.font, font)\n }\n // No CJK font available: replace CJK chars with '?' so geometry still\n // can be created (graceful degradation). Without this, createTextGeometry\n // would throw because CJK glyphs are .notdef in OpenSans Regular.\n const fallback = params.text.replace(/[\\u4E00-\\u9FFF\\u3400-\\u4DBF\\u2F800-\\u2FA1F\\u3000-\\u303F\\uFF00-\\uFFEF]/g, '?')\n return createTextGeometry(fallback, params.size, params.depth, font)\n }\n return createTextGeometry(params.text, params.size, params.depth, font)\n}\n\n/**\n * Create an extruded geometry from an SVG source.\n *\n * @param params - SVG extrude parameters (svg, depth, target size, optional natural size).\n * @returns the extruded shape.\n */\nexport function svgExtrude(params: SvgExtrudeParams): Shape {\n return svgToExtrudedGeometry(params.svg, {\n depth: params.depth,\n targetLongSide: params.targetLongSide ?? 20,\n naturalWidth: params.naturalWidth ?? 0,\n naturalHeight: params.naturalHeight ?? 0,\n })\n}\n"]}
|