@faicad/faijs 0.29.5 → 0.30.9
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/NOTICE +6 -5
- package/dist/api/api-namespace.d.ts +1 -1
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +53 -1
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/appearance.d.ts +0 -2
- package/dist/api/appearance.d.ts.map +1 -1
- package/dist/api/appearance.js +0 -2
- package/dist/api/appearance.js.map +1 -1
- package/dist/api/assembly/entities.d.ts +1 -1
- package/dist/api/assembly/entities.js +1 -1
- package/dist/api/assembly/entities.js.map +1 -1
- package/dist/api/assembly/index.d.ts +1 -1
- package/dist/api/assembly/index.js +1 -1
- package/dist/api/assembly/index.js.map +1 -1
- package/dist/api/assembly/joints.d.ts +33 -15
- package/dist/api/assembly/joints.d.ts.map +1 -1
- package/dist/api/assembly/joints.js +31 -13
- package/dist/api/assembly/joints.js.map +1 -1
- package/dist/api/assembly/preview.d.ts +1 -1
- package/dist/api/assembly/preview.js +1 -1
- package/dist/api/assembly/preview.js.map +1 -1
- package/dist/api/assembly/solve.d.ts +1 -1
- package/dist/api/assembly/solve.js +1 -1
- package/dist/api/assembly/solve.js.map +1 -1
- package/dist/api/assembly/solvers/assembly-tree.d.ts +1 -1
- package/dist/api/assembly/solvers/assembly-tree.js +1 -1
- package/dist/api/assembly/solvers/assembly-tree.js.map +1 -1
- package/dist/api/assembly/solvers/chain-solver.d.ts +2 -2
- package/dist/api/assembly/solvers/chain-solver.js.map +1 -1
- package/dist/api/assembly/solvers/global-solver.d.ts +1 -2
- package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
- package/dist/api/assembly/solvers/global-solver.js +3 -4
- package/dist/api/assembly/solvers/global-solver.js.map +1 -1
- package/dist/api/assembly/solvers/joints-kinematics.js +1 -1
- package/dist/api/assembly/solvers/joints-kinematics.js.map +1 -1
- package/dist/api/assembly/solvers/linalg.d.ts +2 -2
- package/dist/api/assembly/solvers/linalg.js +2 -2
- package/dist/api/assembly/solvers/linalg.js.map +1 -1
- package/dist/api/assembly/solvers/types.d.ts +2 -5
- package/dist/api/assembly/solvers/types.d.ts.map +1 -1
- package/dist/api/assembly/solvers/types.js +1 -4
- package/dist/api/assembly/solvers/types.js.map +1 -1
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +7 -6
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/brep-mirror/booleanFns.d.ts +3 -3
- package/dist/api/brep-mirror/booleanFns.js +5 -5
- package/dist/api/brep-mirror/booleanFns.js.map +1 -1
- package/dist/api/brep-mirror/compoundFns.d.ts +1 -1
- package/dist/api/brep-mirror/compoundFns.js +4 -4
- package/dist/api/brep-mirror/compoundFns.js.map +1 -1
- package/dist/api/brep-mirror/healingFns.d.ts +4 -4
- package/dist/api/brep-mirror/healingFns.js +4 -4
- package/dist/api/brep-mirror/healingFns.js.map +1 -1
- package/dist/api/brep-mirror/hullFns.d.ts +2 -2
- package/dist/api/brep-mirror/hullFns.js +2 -2
- package/dist/api/brep-mirror/hullFns.js.map +1 -1
- package/dist/api/brep-mirror/patternFns.d.ts +5 -5
- package/dist/api/brep-mirror/patternFns.js +10 -10
- package/dist/api/brep-mirror/patternFns.js.map +1 -1
- package/dist/api/brep-mirror/primitiveFns.d.ts +4 -4
- package/dist/api/brep-mirror/primitiveFns.js +4 -4
- package/dist/api/brep-mirror/primitiveFns.js.map +1 -1
- package/dist/api/brep-mirror/roofFns.d.ts +3 -3
- package/dist/api/brep-mirror/roofFns.js +7 -7
- package/dist/api/brep-mirror/roofFns.js.map +1 -1
- package/dist/api/brep-mirror/sweepFns.d.ts +7 -7
- package/dist/api/brep-mirror/sweepFns.js +14 -14
- package/dist/api/brep-mirror/sweepFns.js.map +1 -1
- package/dist/api/brep-mirror/threadFns.d.ts +1 -1
- package/dist/api/brep-mirror/threadFns.js +1 -1
- package/dist/api/brep-mirror/threadFns.js.map +1 -1
- package/dist/api/brep-mirror/topologyFns.d.ts +5 -5
- package/dist/api/brep-mirror/topologyFns.js +8 -8
- package/dist/api/brep-mirror/topologyFns.js.map +1 -1
- package/dist/api/brep-operations/booleanFns.d.ts +40 -0
- package/dist/api/brep-operations/booleanFns.d.ts.map +1 -0
- package/dist/api/brep-operations/booleanFns.js +104 -0
- package/dist/api/brep-operations/booleanFns.js.map +1 -0
- package/dist/api/brep-operations/brepHelpers.d.ts +55 -0
- package/dist/api/brep-operations/brepHelpers.d.ts.map +1 -0
- package/dist/api/brep-operations/brepHelpers.js +131 -0
- package/dist/api/brep-operations/brepHelpers.js.map +1 -0
- package/dist/api/brep-operations/compoundFns.d.ts +46 -0
- package/dist/api/brep-operations/compoundFns.d.ts.map +1 -0
- package/dist/api/brep-operations/compoundFns.js +299 -0
- package/dist/api/brep-operations/compoundFns.js.map +1 -0
- package/dist/api/brep-operations/healingFns.d.ts +78 -0
- package/dist/api/brep-operations/healingFns.d.ts.map +1 -0
- package/dist/api/brep-operations/healingFns.js +294 -0
- package/dist/api/brep-operations/healingFns.js.map +1 -0
- package/dist/api/brep-operations/hullFns.d.ts +20 -0
- package/dist/api/brep-operations/hullFns.d.ts.map +1 -0
- package/dist/api/brep-operations/hullFns.js +46 -0
- package/dist/api/brep-operations/hullFns.js.map +1 -0
- package/dist/api/brep-operations/joinery-brep.d.ts +172 -0
- package/dist/api/brep-operations/joinery-brep.d.ts.map +1 -0
- package/dist/api/brep-operations/joinery-brep.js +463 -0
- package/dist/api/brep-operations/joinery-brep.js.map +1 -0
- package/dist/api/brep-operations/patternFns.d.ts +43 -0
- package/dist/api/brep-operations/patternFns.d.ts.map +1 -0
- package/dist/api/brep-operations/patternFns.js +178 -0
- package/dist/api/brep-operations/patternFns.js.map +1 -0
- package/dist/api/brep-operations/primitiveFns.d.ts +42 -0
- package/dist/api/brep-operations/primitiveFns.d.ts.map +1 -0
- package/dist/api/brep-operations/primitiveFns.js +104 -0
- package/dist/api/brep-operations/primitiveFns.js.map +1 -0
- package/dist/api/brep-operations/roofFns.d.ts +24 -0
- package/dist/api/brep-operations/roofFns.d.ts.map +1 -0
- package/dist/api/brep-operations/roofFns.js +229 -0
- package/dist/api/brep-operations/roofFns.js.map +1 -0
- package/dist/api/brep-operations/straightSkeleton.d.ts +36 -0
- package/dist/api/brep-operations/straightSkeleton.d.ts.map +1 -0
- package/dist/api/brep-operations/straightSkeleton.js +431 -0
- package/dist/api/brep-operations/straightSkeleton.js.map +1 -0
- package/dist/api/brep-operations/sweepFns.d.ts +60 -0
- package/dist/api/brep-operations/sweepFns.d.ts.map +1 -0
- package/dist/api/brep-operations/sweepFns.js +323 -0
- package/dist/api/brep-operations/sweepFns.js.map +1 -0
- package/dist/api/brep-operations/threadFns.d.ts +83 -0
- package/dist/api/brep-operations/threadFns.d.ts.map +1 -0
- package/dist/api/brep-operations/threadFns.js +138 -0
- package/dist/api/brep-operations/threadFns.js.map +1 -0
- package/dist/api/brep-operations/topologyFns.d.ts +90 -0
- package/dist/api/brep-operations/topologyFns.d.ts.map +1 -0
- package/dist/api/brep-operations/topologyFns.js +276 -0
- package/dist/api/brep-operations/topologyFns.js.map +1 -0
- package/dist/api/brep-topology.d.ts +1 -1
- package/dist/api/brep-topology.d.ts.map +1 -1
- package/dist/api/brep-topology.js +1 -1
- package/dist/api/brep-topology.js.map +1 -1
- package/dist/api/brepjs-compat/index.d.ts +1 -1
- package/dist/api/brepjs-compat/index.js +3 -3
- package/dist/api/brepjs-compat/index.js.map +1 -1
- package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -1
- package/dist/api/cadquery-selectors/borrow-bridge.js +3 -4
- package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -1
- package/dist/api/curve-sketch/index.d.ts +235 -0
- package/dist/api/curve-sketch/index.d.ts.map +1 -0
- package/dist/api/curve-sketch/index.js +487 -0
- package/dist/api/curve-sketch/index.js.map +1 -0
- package/dist/api/engrave.d.ts.map +1 -1
- package/dist/api/engrave.js +3 -2
- package/dist/api/engrave.js.map +1 -1
- package/dist/api/export-brep.d.ts +41 -0
- package/dist/api/export-brep.d.ts.map +1 -0
- package/dist/api/export-brep.js +58 -0
- package/dist/api/export-brep.js.map +1 -0
- package/dist/api/export-stl.d.ts +50 -0
- package/dist/api/export-stl.d.ts.map +1 -0
- package/dist/api/export-stl.js +99 -0
- package/dist/api/export-stl.js.map +1 -0
- package/dist/api/extrude.d.ts +8 -11
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +11 -14
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/fillet-variable.d.ts +2 -2
- package/dist/api/fillet-variable.js +2 -2
- package/dist/api/fillet-variable.js.map +1 -1
- package/dist/api/fillet.d.ts +2 -4
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +2 -4
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/generated/2d.d.ts +4 -0
- package/dist/api/generated/2d.d.ts.map +1 -1
- package/dist/api/generated/2d.js +4 -0
- package/dist/api/generated/2d.js.map +1 -1
- package/dist/api/generated/core.d.ts +4 -0
- package/dist/api/generated/core.d.ts.map +1 -1
- package/dist/api/generated/core.js +4 -0
- package/dist/api/generated/core.js.map +1 -1
- package/dist/api/generated/gear.d.ts +4 -0
- package/dist/api/generated/gear.d.ts.map +1 -1
- package/dist/api/generated/gear.js +4 -0
- package/dist/api/generated/gear.js.map +1 -1
- package/dist/api/generated/io.d.ts +4 -0
- package/dist/api/generated/io.d.ts.map +1 -1
- package/dist/api/generated/io.js +4 -0
- package/dist/api/generated/io.js.map +1 -1
- package/dist/api/generated/kernel.d.ts +4 -0
- package/dist/api/generated/kernel.d.ts.map +1 -1
- package/dist/api/generated/kernel.js +4 -0
- package/dist/api/generated/kernel.js.map +1 -1
- package/dist/api/generated/measurement.d.ts +21 -21
- package/dist/api/generated/measurement.d.ts.map +1 -1
- package/dist/api/generated/measurement.js +25 -21
- package/dist/api/generated/measurement.js.map +1 -1
- package/dist/api/generated/ns.d.ts +4 -0
- package/dist/api/generated/ns.d.ts.map +1 -1
- package/dist/api/generated/ns.js +4 -0
- package/dist/api/generated/ns.js.map +1 -1
- package/dist/api/generated/operations.d.ts +32 -32
- package/dist/api/generated/operations.d.ts.map +1 -1
- package/dist/api/generated/operations.js +52 -48
- package/dist/api/generated/operations.js.map +1 -1
- package/dist/api/generated/projection.d.ts +4 -0
- package/dist/api/generated/projection.d.ts.map +1 -1
- package/dist/api/generated/projection.js +4 -0
- package/dist/api/generated/projection.js.map +1 -1
- package/dist/api/generated/query.d.ts +4 -0
- package/dist/api/generated/query.d.ts.map +1 -1
- package/dist/api/generated/query.js +4 -0
- package/dist/api/generated/query.js.map +1 -1
- package/dist/api/generated/sketching.d.ts +2 -2
- package/dist/api/generated/sketching.d.ts.map +1 -1
- package/dist/api/generated/sketching.js +7 -3
- package/dist/api/generated/sketching.js.map +1 -1
- package/dist/api/generated/text.d.ts +4 -0
- package/dist/api/generated/text.d.ts.map +1 -1
- package/dist/api/generated/text.js +4 -0
- package/dist/api/generated/text.js.map +1 -1
- package/dist/api/generated/topology.d.ts +45 -45
- package/dist/api/generated/topology.d.ts.map +1 -1
- package/dist/api/generated/topology.js +67 -63
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/generated/view.d.ts +4 -0
- package/dist/api/generated/view.d.ts.map +1 -1
- package/dist/api/generated/view.js +4 -0
- package/dist/api/generated/view.js.map +1 -1
- package/dist/api/geom-types/constants.d.ts +11 -0
- package/dist/api/geom-types/constants.d.ts.map +1 -0
- package/dist/api/geom-types/constants.js +11 -0
- package/dist/api/geom-types/constants.js.map +1 -0
- package/dist/api/geom-types/index.d.ts +21 -0
- package/dist/api/geom-types/index.d.ts.map +1 -0
- package/dist/api/geom-types/index.js +22 -0
- package/dist/api/geom-types/index.js.map +1 -0
- package/dist/api/geom-types/planeOps.d.ts +98 -0
- package/dist/api/geom-types/planeOps.d.ts.map +1 -0
- package/dist/api/geom-types/planeOps.js +170 -0
- package/dist/api/geom-types/planeOps.js.map +1 -0
- package/dist/api/geom-types/planeTypes.d.ts +24 -0
- package/dist/api/geom-types/planeTypes.d.ts.map +1 -0
- package/dist/api/geom-types/planeTypes.js +8 -0
- package/dist/api/geom-types/planeTypes.js.map +1 -0
- package/dist/api/geom-types/types.d.ts +64 -0
- package/dist/api/geom-types/types.d.ts.map +1 -0
- package/dist/api/geom-types/types.js +48 -0
- package/dist/api/geom-types/types.js.map +1 -0
- package/dist/api/geom-types/vecOps.d.ts +124 -0
- package/dist/api/geom-types/vecOps.d.ts.map +1 -0
- package/dist/api/geom-types/vecOps.js +202 -0
- package/dist/api/geom-types/vecOps.js.map +1 -0
- package/dist/api/geom.d.ts.map +1 -1
- package/dist/api/geom.js +6 -5
- package/dist/api/geom.js.map +1 -1
- package/dist/api/half-space.d.ts +56 -0
- package/dist/api/half-space.d.ts.map +1 -0
- package/dist/api/half-space.js +82 -0
- package/dist/api/half-space.js.map +1 -0
- package/dist/api/helix.d.ts +10 -1
- package/dist/api/helix.d.ts.map +1 -1
- package/dist/api/helix.js +19 -3
- package/dist/api/helix.js.map +1 -1
- package/dist/api/index.d.ts +15 -6
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +29 -8
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-op.d.ts +4 -30
- package/dist/api/internal/compat-op.d.ts.map +1 -1
- package/dist/api/internal/compat-op.js +10 -42
- package/dist/api/internal/compat-op.js.map +1 -1
- package/dist/api/internal/compat-projection.d.ts +5 -5
- package/dist/api/internal/compat-projection.js +5 -5
- package/dist/api/internal/compat-projection.js.map +1 -1
- package/dist/api/internal/dual-form-args.d.ts +0 -2
- package/dist/api/internal/dual-form-args.d.ts.map +1 -1
- package/dist/api/internal/dual-form-args.js +1 -3
- package/dist/api/internal/dual-form-args.js.map +1 -1
- package/dist/api/internal/l3-bridge.d.ts +5 -37
- package/dist/api/internal/l3-bridge.d.ts.map +1 -1
- package/dist/api/internal/l3-bridge.js +7 -76
- package/dist/api/internal/l3-bridge.js.map +1 -1
- package/dist/api/internal/profile-wire.d.ts +1 -1
- package/dist/api/internal/profile-wire.js +1 -1
- package/dist/api/internal/profile-wire.js.map +1 -1
- package/dist/api/internal/result-unwrap.d.ts +4 -6
- package/dist/api/internal/result-unwrap.d.ts.map +1 -1
- package/dist/api/internal/result-unwrap.js +4 -6
- package/dist/api/internal/result-unwrap.js.map +1 -1
- package/dist/api/knurl.d.ts.map +1 -1
- package/dist/api/knurl.js +5 -3
- package/dist/api/knurl.js.map +1 -1
- package/dist/api/loft.d.ts +2 -2
- package/dist/api/loft.d.ts.map +1 -1
- package/dist/api/loft.js +2 -2
- package/dist/api/loft.js.map +1 -1
- package/dist/api/measurement/index.d.ts +3 -3
- package/dist/api/measurement/index.js +3 -3
- package/dist/api/measurement/index.js.map +1 -1
- package/dist/api/meta.d.ts +0 -2
- package/dist/api/meta.d.ts.map +1 -1
- package/dist/api/meta.js +0 -2
- package/dist/api/meta.js.map +1 -1
- package/dist/api/offset2d.d.ts +49 -0
- package/dist/api/offset2d.d.ts.map +1 -0
- package/dist/api/offset2d.js +86 -0
- package/dist/api/offset2d.js.map +1 -0
- package/dist/api/pattern.js +3 -3
- package/dist/api/pattern.js.map +1 -1
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +7 -6
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/replicate.d.ts +2 -2
- package/dist/api/replicate.d.ts.map +1 -1
- package/dist/api/replicate.js +12 -12
- package/dist/api/replicate.js.map +1 -1
- package/dist/api/result.d.ts +1 -1
- package/dist/api/result.js +1 -1
- package/dist/api/result.js.map +1 -1
- package/dist/api/revolve.d.ts +2 -2
- package/dist/api/revolve.js +3 -3
- package/dist/api/revolve.js.map +1 -1
- package/dist/api/screw.d.ts +1 -1
- package/dist/api/screw.d.ts.map +1 -1
- package/dist/api/screw.js +5 -4
- package/dist/api/screw.js.map +1 -1
- package/dist/api/sdf.d.ts.map +1 -1
- package/dist/api/sdf.js +3 -2
- package/dist/api/sdf.js.map +1 -1
- package/dist/api/shape-type/index.d.ts +141 -0
- package/dist/api/shape-type/index.d.ts.map +1 -0
- package/dist/api/shape-type/index.js +182 -0
- package/dist/api/shape-type/index.js.map +1 -0
- package/dist/api/shell.d.ts +2 -2
- package/dist/api/shell.js +2 -2
- package/dist/api/shell.js.map +1 -1
- package/dist/api/solid-from-faces.d.ts +45 -0
- package/dist/api/solid-from-faces.d.ts.map +1 -0
- package/dist/api/solid-from-faces.js +72 -0
- package/dist/api/solid-from-faces.js.map +1 -0
- package/dist/api/solid-offset/index.d.ts +67 -0
- package/dist/api/solid-offset/index.d.ts.map +1 -0
- package/dist/api/solid-offset/index.js +132 -0
- package/dist/api/solid-offset/index.js.map +1 -0
- package/dist/api/surface/arg-spec.d.ts +35 -33
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +222 -224
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/surface-face/index.d.ts +104 -0
- package/dist/api/surface-face/index.d.ts.map +1 -0
- package/dist/api/surface-face/index.js +217 -0
- package/dist/api/surface-face/index.js.map +1 -0
- package/dist/api/surface.d.ts +44 -0
- package/dist/api/surface.d.ts.map +1 -0
- package/dist/api/surface.js +66 -0
- package/dist/api/surface.js.map +1 -0
- package/dist/api/sweep.d.ts +59 -9
- package/dist/api/sweep.d.ts.map +1 -1
- package/dist/api/sweep.js +11 -6
- package/dist/api/sweep.js.map +1 -1
- package/dist/api/thicken.d.ts +1 -1
- package/dist/api/thicken.js +1 -1
- package/dist/api/thicken.js.map +1 -1
- package/dist/api/transform.d.ts +5 -5
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +11 -10
- package/dist/api/transform.js.map +1 -1
- package/dist/api/view/cameraFns.d.ts +1 -1
- package/dist/api/view/cameraFns.d.ts.map +1 -1
- package/dist/api/view/cameraFns.js +1 -1
- package/dist/api/view/cameraFns.js.map +1 -1
- package/dist/api/view/index.d.ts +0 -2
- package/dist/api/view/index.d.ts.map +1 -1
- package/dist/api/view/index.js +0 -2
- package/dist/api/view/index.js.map +1 -1
- package/dist/api/view/projectionPlanes.d.ts +1 -1
- package/dist/api/view/projectionPlanes.d.ts.map +1 -1
- package/dist/api/view/projectionPlanes.js.map +1 -1
- package/dist/api/view/view-camera.d.ts +7 -9
- package/dist/api/view/view-camera.d.ts.map +1 -1
- package/dist/api/view/view-camera.js +4 -6
- package/dist/api/view/view-camera.js.map +1 -1
- package/dist/api/view/view-projection.d.ts +0 -2
- package/dist/api/view/view-projection.d.ts.map +1 -1
- package/dist/api/view/view-projection.js +0 -2
- package/dist/api/view/view-projection.js.map +1 -1
- package/dist/api/view/view-sheet.d.ts +0 -2
- package/dist/api/view/view-sheet.d.ts.map +1 -1
- package/dist/api/view/view-sheet.js +0 -2
- package/dist/api/view/view-sheet.js.map +1 -1
- package/dist/api/view-export/index.d.ts +97 -0
- package/dist/api/view-export/index.d.ts.map +1 -0
- package/dist/api/view-export/index.js +118 -0
- package/dist/api/view-export/index.js.map +1 -0
- package/dist/brep/brep-ops.d.ts +89 -1
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +176 -10
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/brep-topology.d.ts +20 -0
- package/dist/brep/brep-topology.d.ts.map +1 -1
- package/dist/brep/brep-topology.js +46 -0
- package/dist/brep/brep-topology.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts +1 -1
- package/dist/brep/engine/adapters/occt.js +7 -7
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +2 -3
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js +1 -2
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/registry.d.ts +1 -1
- package/dist/brep/engine/registry.js +1 -1
- package/dist/brep/engine/registry.js.map +1 -1
- package/dist/brep/engine/types.d.ts +2 -2
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brep/handle-bridge.d.ts +2 -2
- package/dist/brep/handle-bridge.js +2 -2
- package/dist/brep/handle-bridge.js.map +1 -1
- package/dist/brep/index.d.ts +6 -3
- package/dist/brep/index.d.ts.map +1 -1
- package/dist/brep/index.js +6 -3
- package/dist/brep/index.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +2 -2
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +5 -4
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +3 -10
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +3 -9
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +12 -3
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts +6 -3
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +31 -9
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/interp/env.d.ts +1 -1
- package/dist/cad-runtime/interp/env.js.map +1 -1
- package/dist/cad-runtime/lib-id.d.ts +0 -2
- package/dist/cad-runtime/lib-id.d.ts.map +1 -1
- package/dist/cad-runtime/lib-id.js +0 -2
- package/dist/cad-runtime/lib-id.js.map +1 -1
- package/dist/cad-runtime/live-shapes.d.ts +3 -5
- package/dist/cad-runtime/live-shapes.d.ts.map +1 -1
- package/dist/cad-runtime/live-shapes.js +8 -10
- package/dist/cad-runtime/live-shapes.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +3 -3
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +21 -7
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +45 -6
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +4 -3
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +2 -2
- package/dist/define-op.js.map +1 -1
- package/dist/geometry2d/bridge/plane.d.ts +1 -1
- package/dist/geometry2d/bridge/plane.js +1 -1
- package/dist/geometry2d/bridge/plane.js.map +1 -1
- package/dist/geometry2d/curve2d.d.ts +1 -1
- package/dist/geometry2d/curve2d.js +1 -1
- package/dist/geometry2d/curve2d.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/io/fai-zip/container-read.d.ts +16 -0
- package/dist/io/fai-zip/container-read.d.ts.map +1 -1
- package/dist/io/fai-zip/container-read.js +22 -0
- package/dist/io/fai-zip/container-read.js.map +1 -1
- package/dist/io/fai-zip/index.d.ts +1 -1
- package/dist/io/fai-zip/index.d.ts.map +1 -1
- package/dist/io/fai-zip/index.js +1 -1
- package/dist/io/fai-zip/index.js.map +1 -1
- package/dist/lang/code-to-args.d.ts.map +1 -1
- package/dist/lang/code-to-args.js +10 -1
- package/dist/lang/code-to-args.js.map +1 -1
- package/dist/lang/determinism-scanner.d.ts.map +1 -1
- package/dist/lang/determinism-scanner.js +22 -9
- package/dist/lang/determinism-scanner.js.map +1 -1
- package/dist/lang/metadata-extractor.d.ts +27 -6
- package/dist/lang/metadata-extractor.d.ts.map +1 -1
- package/dist/lang/metadata-extractor.js +88 -8
- package/dist/lang/metadata-extractor.js.map +1 -1
- package/dist/lang/parse-error.d.ts +4 -0
- package/dist/lang/parse-error.d.ts.map +1 -1
- package/dist/lang/parse-error.js.map +1 -1
- package/dist/lang/security-scanner.d.ts +27 -2
- package/dist/lang/security-scanner.d.ts.map +1 -1
- package/dist/lang/security-scanner.js +29 -2
- package/dist/lang/security-scanner.js.map +1 -1
- package/dist/lang/source-edit.d.ts +2 -2
- package/dist/lang/source-edit.js.map +1 -1
- package/dist/lang/symbol-table.generated.d.ts +36 -0
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +36 -0
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/mesh/import-model.d.ts +94 -0
- package/dist/mesh/import-model.d.ts.map +1 -0
- package/dist/mesh/import-model.js +15 -0
- package/dist/mesh/import-model.js.map +1 -0
- package/dist/mesh/index.d.ts +19 -58
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +19 -70
- package/dist/mesh/index.js.map +1 -1
- package/dist/mesh/io.d.ts +33 -16
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +144 -39
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/primitives.js +1 -1
- package/dist/mesh/primitives.js.map +1 -1
- package/dist/mesh/threemf-bambu.d.ts +12 -1
- package/dist/mesh/threemf-bambu.d.ts.map +1 -1
- package/dist/mesh/threemf-bambu.js +68 -16
- package/dist/mesh/threemf-bambu.js.map +1 -1
- package/dist/mesh/threemf-loader.d.ts +14 -1
- package/dist/mesh/threemf-loader.d.ts.map +1 -1
- package/dist/mesh/threemf-loader.js +24 -7
- package/dist/mesh/threemf-loader.js.map +1 -1
- package/dist/mesh/transform.d.ts +1 -1
- package/dist/mesh/transform.js +1 -1
- package/dist/mesh/transform.js.map +1 -1
- package/dist/mesh/types.d.ts +5 -5
- package/dist/mesh/types.d.ts.map +1 -1
- package/dist/mesh/types.js.map +1 -1
- package/dist/node-host/cli.d.ts +49 -1
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +125 -19
- package/dist/node-host/cli.js.map +1 -1
- package/dist/node-host/execute-script.d.ts +55 -0
- package/dist/node-host/execute-script.d.ts.map +1 -0
- package/dist/node-host/execute-script.js +46 -0
- package/dist/node-host/execute-script.js.map +1 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +3 -0
- package/dist/node.js.map +1 -1
- package/dist/occt-kernel/generated/occtPlatform.generated.d.ts +260 -0
- package/dist/occt-kernel/generated/occtPlatform.generated.d.ts.map +1 -0
- package/dist/occt-kernel/generated/occtPlatform.generated.js +875 -0
- package/dist/occt-kernel/generated/occtPlatform.generated.js.map +1 -0
- package/dist/occt-kernel/hullGeometry.d.ts +2 -2
- package/dist/occt-kernel/hullGeometry.js +2 -3
- package/dist/occt-kernel/hullGeometry.js.map +1 -1
- package/dist/occt-kernel/hullOps.d.ts +3 -3
- package/dist/occt-kernel/hullOps.js +4 -4
- package/dist/occt-kernel/hullOps.js.map +1 -1
- package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
- package/dist/occt-kernel/occt-primitives.js +31 -4
- package/dist/occt-kernel/occt-primitives.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
- package/dist/occt-kernel/occtKernel.js +18 -0
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-scan/recognize.d.ts +58 -0
- package/dist/occt-scan/recognize.d.ts.map +1 -0
- package/dist/occt-scan/recognize.js +216 -0
- package/dist/occt-scan/recognize.js.map +1 -0
- package/dist/primitives/brep-primitives.js +7 -7
- package/dist/primitives/brep-primitives.js.map +1 -1
- package/dist/result/bug.d.ts +1 -1
- package/dist/result/bug.js +1 -1
- package/dist/result/bug.js.map +1 -1
- package/dist/result/errors.d.ts +2 -2
- package/dist/result/errors.d.ts.map +1 -1
- package/dist/result/errors.js +1 -1
- package/dist/result/errors.js.map +1 -1
- package/dist/result/vec3.d.ts +1 -1
- package/dist/result/vec3.js +1 -1
- package/dist/result/vec3.js.map +1 -1
- package/dist/runtime-state.d.ts +16 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +27 -0
- package/dist/runtime-state.js.map +1 -1
- package/dist/script-globals.d.ts +24 -0
- package/dist/script-globals.d.ts.map +1 -0
- package/dist/script-globals.js +24 -0
- package/dist/script-globals.js.map +1 -0
- package/dist/shape.d.ts +24 -0
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +40 -0
- package/dist/shape.js.map +1 -1
- package/dist/topology/naming/lineage.d.ts +3 -2
- package/dist/topology/naming/lineage.d.ts.map +1 -1
- package/dist/topology/naming/lineage.js.map +1 -1
- package/dist/weapp.d.ts +1 -1
- package/dist/weapp.js +1 -1
- package/dist/weapp.js.map +1 -1
- package/package.json +8 -10
package/dist/mesh/io.js
CHANGED
|
@@ -6,19 +6,24 @@
|
|
|
6
6
|
* 坐标永远以 faijs 基准长度单位(mm)存储 — Shape 不贴 unit 标签(D3)。
|
|
7
7
|
*
|
|
8
8
|
* 单位换算边界(unit-system §5.2):
|
|
9
|
-
* - STL 无单位元数据 → 由 `opts.unit`
|
|
9
|
+
* - STL 无单位元数据 → 由 `opts.unit` 显式声明优先;未声明时 faijs 按历史
|
|
10
|
+
* host 行为做启发式猜测(`guessStlUnit`,unified 方案 §6.1/§8 —— 3d_editor
|
|
11
|
+
* 迁移回归的单位断言依赖此行为)。猜测收敛在 faijs 内(红线 R0:宿主不
|
|
12
|
+
* 自实现单位换算),G0 = 折算后坐标,渲染 = 拓扑 = G0。
|
|
10
13
|
* - 3MF `<model unit>` 由解析器读取并换算(micron/mm/cm/inch/foot/meter)。
|
|
11
14
|
*
|
|
12
15
|
* 返回契约(unit-system §10.6):`importFile` 返回 `{ shape, unit }` — `unit`
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* 是文件源单位(必然有值;faijs 是单一真源):3MF/STEP 取文件声明(STEP 无声明
|
|
17
|
+
* → 'mm',与 OCCT 一致),STL 取 opts.unit 或 guessStlUnit 启发式猜测。坐标恒
|
|
18
|
+
* 为基准值 — `unit` 只作元数据(sourceUnit 记录、导出目标判定),绝不参与几何
|
|
19
|
+
* 缩放(读入折算已由内核/解析器完成,二次缩放 = 双重换算)。
|
|
17
20
|
*/
|
|
18
21
|
import { geoToManifoldMesh } from '../boolean/geo-convert.js';
|
|
19
22
|
import { parseStl } from './stl-loader.js';
|
|
20
23
|
import { parseThreemf } from './threemf-loader.js';
|
|
21
|
-
import {
|
|
24
|
+
import { parseBambu3mfFromEntries } from './threemf-bambu.js';
|
|
25
|
+
import { unitScale } from '../units.js';
|
|
26
|
+
import { guessStlUnit } from './stl-unit.js';
|
|
22
27
|
/** SI prefixes that may precede .METRE. in a STEP SI_UNIT, → faijs UnitName. */
|
|
23
28
|
const SI_PREFIX_TO_UNIT = {
|
|
24
29
|
'.MILLI.': 'mm',
|
|
@@ -93,67 +98,167 @@ export function detectStepUnit(stepText) {
|
|
|
93
98
|
* unzipping is the caller's job — faijs never unzips implicitly).
|
|
94
99
|
* @param format - format identifier such as 'stl', '3mf'/'threemf' or 'step'
|
|
95
100
|
* (defaults to 'stl').
|
|
96
|
-
* @param opts - optional settings; `unit`
|
|
97
|
-
* formats without unit metadata (e.g. STL). Defaults to
|
|
98
|
-
*
|
|
99
|
-
*
|
|
101
|
+
* @param opts - optional settings; `unit` (a UnitName string) declares the
|
|
102
|
+
* source unit for formats without unit metadata (e.g. STL). Defaults to
|
|
103
|
+
* the guessStlUnit heuristic when omitted.
|
|
104
|
+
* @returns the shape with base-unit coordinates plus the file's source unit
|
|
105
|
+
* (`unit`, metadata only; always present — faijs is the single source of truth).
|
|
100
106
|
*/
|
|
101
107
|
export async function importFile(buffer, format, opts) {
|
|
102
108
|
const fmt = (format ?? 'stl').toLowerCase();
|
|
103
109
|
if (fmt === '3mf' || fmt === 'threemf') {
|
|
104
110
|
const archive = await parseThreemf(buffer);
|
|
105
|
-
// §5.4
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
if (!first) {
|
|
111
|
+
// P0(方案 §5.4):不再折叠——返回全部 `<build><item>` 对象(declaration order,
|
|
112
|
+
// 坐标已在 parseThreemf 里折算为 faijs 基准单位)。`shape` 保留为 parts[0]
|
|
113
|
+
// (单零件兼容,过渡期)。
|
|
114
|
+
if (archive.objects.length === 0) {
|
|
110
115
|
throw new Error('[mesh/io] 3MF contains no objects');
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
117
|
+
// Bambu 元数据(盘号/挤出机/视图变换):有 Bambu 配置才产生内容,普通 3MF 返回空表。
|
|
118
|
+
// P4:根 model XML 直传(3MF `<build>` 在 resources 前;id 两套编号经父
|
|
119
|
+
// object components 关联——leafParts 表承载)。
|
|
120
|
+
const bambu = parseBambu3mfFromEntries(archive.extraEntries, archive.modelXml);
|
|
121
|
+
const parts = archive.objects.map(threemfObjectToShape);
|
|
122
|
+
const multiPartCount = parts.length > 1 ? parts.length : undefined;
|
|
123
|
+
const importModel = {
|
|
124
|
+
format: '3mf',
|
|
125
|
+
unit: archive.unit,
|
|
126
|
+
parts: archive.objects.map((obj, i) => {
|
|
127
|
+
const part = {
|
|
128
|
+
index: i,
|
|
129
|
+
name: obj.name ?? `imported:${i}`,
|
|
130
|
+
};
|
|
131
|
+
if (obj.baseColor)
|
|
132
|
+
part.color = [obj.baseColor[0], obj.baseColor[1], obj.baseColor[2]];
|
|
133
|
+
if (obj.meta)
|
|
134
|
+
part.meta = obj.meta;
|
|
135
|
+
// Bambu 身份:3MF `<object id>`(叶子实例)与 Bambu objects 表(键为
|
|
136
|
+
// model_settings 父对象 id)是两套编号——经父 object components 关联
|
|
137
|
+
// (ThreemfObject.parentObjectId/componentIndex → bambu.leafParts)。
|
|
138
|
+
const bm = obj.parentObjectId !== undefined
|
|
139
|
+
? bambu.leafParts.get(`${obj.parentObjectId}:${obj.componentIndex ?? 1}`)
|
|
140
|
+
: undefined;
|
|
141
|
+
if (bm) {
|
|
142
|
+
part.objectId = bm.objectId;
|
|
143
|
+
if (bm.plateId > 0)
|
|
144
|
+
part.plateId = bm.plateId;
|
|
145
|
+
// Bambu extruder 1-based(默认 1):显式登记文件声明值
|
|
146
|
+
part.extruder = bm.extruder;
|
|
147
|
+
part.partId = bm.partId;
|
|
130
148
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
...(
|
|
149
|
+
return part;
|
|
150
|
+
}),
|
|
151
|
+
...(archive.fileMeta ? { fileMeta: archive.fileMeta } : {}),
|
|
134
152
|
};
|
|
153
|
+
const bambuViews = buildBambuViews(bambu);
|
|
154
|
+
if (bambuViews)
|
|
155
|
+
importModel.bambuViews = bambuViews;
|
|
135
156
|
return {
|
|
136
|
-
shape,
|
|
157
|
+
shape: parts[0],
|
|
158
|
+
parts,
|
|
137
159
|
unit: archive.unit,
|
|
138
160
|
multiPartCount,
|
|
161
|
+
importModel,
|
|
139
162
|
// 整体级元数据(`<model><metadata>`)随导入结果上抛(方案 §5.1)。
|
|
140
163
|
...(archive.fileMeta ? { fileMeta: archive.fileMeta } : {}),
|
|
141
164
|
};
|
|
142
165
|
}
|
|
143
166
|
if (fmt === 'stl') {
|
|
144
|
-
const scale = (opts?.unit ?? mm).as(mm);
|
|
145
167
|
const geo = parseStl(buffer);
|
|
168
|
+
// STL 无单位声明:opts.unit 显式声明优先;未声明时做启发式猜测
|
|
169
|
+
// (guessStlUnit —— 历史 host 行为,unified §6.1/§8 迁移基线)。猜测与
|
|
170
|
+
// 折算都在 faijs 内完成(红线 R0),G0 即基准值,宿主不再二次换算。
|
|
171
|
+
// unit 字段回传源单位(声明值或猜测值),供宿主记录 sourceUnit 元数据。
|
|
172
|
+
let scale = 1;
|
|
173
|
+
let sourceUnit = 'mm';
|
|
174
|
+
const declared = opts?.unit;
|
|
175
|
+
if (declared) {
|
|
176
|
+
sourceUnit = declared;
|
|
177
|
+
scale = unitScale(declared);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
geo.computeBoundingBox();
|
|
181
|
+
const bb = geo.boundingBox;
|
|
182
|
+
if (bb) {
|
|
183
|
+
sourceUnit = guessStlUnit({
|
|
184
|
+
min: [bb.min.x, bb.min.y, bb.min.z],
|
|
185
|
+
max: [bb.max.x, bb.max.y, bb.max.z],
|
|
186
|
+
});
|
|
187
|
+
scale = unitScale(sourceUnit);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
146
190
|
if (scale !== 1) {
|
|
147
191
|
const attr = geo.getAttribute('position');
|
|
148
192
|
const arr = attr.array;
|
|
149
193
|
for (let i = 0; i < arr.length; i++)
|
|
150
194
|
arr[i] *= scale;
|
|
151
195
|
}
|
|
152
|
-
|
|
196
|
+
const shape = geoToManifoldMesh(geo);
|
|
197
|
+
return { shape, parts: [shape], unit: sourceUnit };
|
|
153
198
|
}
|
|
154
199
|
// STEP goes through the BREP chain (loadBrep → OCCT, which normalizes to the
|
|
155
200
|
// base unit on read). The mesh io path has no kernel-independent STEP parser
|
|
156
201
|
// and must not fake one — a missing path is an error, not a fallback.
|
|
157
202
|
throw new Error(`[mesh/io] unsupported format: ${fmt}`);
|
|
158
203
|
}
|
|
204
|
+
/** 单个 3MF `<build><item>` 对象 → Shape(P0:逐对象构造,替换原"只取第一个"收敛)。 */
|
|
205
|
+
function threemfObjectToShape(obj) {
|
|
206
|
+
return {
|
|
207
|
+
positions: obj.positions,
|
|
208
|
+
indices: obj.indices,
|
|
209
|
+
// P2(方案 §5 3MF 行):对象级 baseColor → appearance.color(sRGB 原值,
|
|
210
|
+
// 宽容兼容:无 baseColor 不带 appearance)。colorgroup(vertexColors)与
|
|
211
|
+
// 逐三角形材质属 Phase 2(materialGroups / vertexColors),P2 不映射。
|
|
212
|
+
...(obj.baseColor ? { appearance: { color: [obj.baseColor[0], obj.baseColor[1], obj.baseColor[2]] } } : {}),
|
|
213
|
+
// P4(方案 §5 3MF 行):逐三角形 basematerials(p1=p2=p3)→ materialGroups
|
|
214
|
+
// (三角形区间 + appearance.color);无则不带。vertexColors(colorgroup)
|
|
215
|
+
// 由上层(编辑器导入路径)消费,io 单零件收敛不展开为材质分组。
|
|
216
|
+
...(obj.materialGroups && obj.materialGroups.length > 0
|
|
217
|
+
? {
|
|
218
|
+
materialGroups: obj.materialGroups.map((g) => ({
|
|
219
|
+
start: g.start,
|
|
220
|
+
count: g.count,
|
|
221
|
+
appearance: { color: [g.color[0], g.color[1], g.color[2]] },
|
|
222
|
+
})),
|
|
223
|
+
}
|
|
224
|
+
: {}),
|
|
225
|
+
// 零件级元数据(方案 §5.1 3MF 行):对象 name/partnumber/metadatagroup → meta。
|
|
226
|
+
...(obj.meta ? { meta: obj.meta } : {}),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/** Bambu 显示视图数据 → ImportModel.bambuViews(无任何 Bambu 结构时省略)。 */
|
|
230
|
+
function buildBambuViews(bambu) {
|
|
231
|
+
const plates = [...bambu.plates.keys()].sort((a, b) => a - b);
|
|
232
|
+
if (plates.length === 0 && !bambu.assembleTransforms && !bambu.importTransforms)
|
|
233
|
+
return undefined;
|
|
234
|
+
const views = { plates };
|
|
235
|
+
if (bambu.assembleTransforms) {
|
|
236
|
+
views.assembleTransforms = Object.fromEntries([...bambu.assembleTransforms].map(([k, v]) => [k, { transform: v.transform, offset: v.offset }]));
|
|
237
|
+
}
|
|
238
|
+
if (bambu.importTransforms) {
|
|
239
|
+
views.importTransforms = Object.fromEntries([...bambu.importTransforms].map(([k, v]) => [k, { matrix: v.matrix, sourceOffset: v.sourceOffset }]));
|
|
240
|
+
}
|
|
241
|
+
// P4:完整消费面随结果回传——宿主重建 Bambu3mfMetadata 不再回读 archive。
|
|
242
|
+
if (bambu.buildItems) {
|
|
243
|
+
views.buildItems = bambu.buildItems.map((b) => ({
|
|
244
|
+
objectId: b.objectId,
|
|
245
|
+
transform: b.transform ?? null,
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
248
|
+
if (bambu.filamentColors.length > 0)
|
|
249
|
+
views.filamentColors = bambu.filamentColors;
|
|
250
|
+
if (bambu.filamentTypes.length > 0)
|
|
251
|
+
views.filamentTypes = bambu.filamentTypes;
|
|
252
|
+
if (bambu.parts.length > 0) {
|
|
253
|
+
views.parts = bambu.parts.map((p) => ({
|
|
254
|
+
partIndex: p.partIndex,
|
|
255
|
+
objectId: p.objectId,
|
|
256
|
+
partId: p.partId,
|
|
257
|
+
name: p.name,
|
|
258
|
+
extruder: p.extruder,
|
|
259
|
+
plateId: p.plateId,
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
262
|
+
return views;
|
|
263
|
+
}
|
|
159
264
|
//# sourceMappingURL=io.js.map
|
package/dist/mesh/io.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh IO API — headless 文件加载\n *\n * STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons);3MF 由\n * `mesh/threemf-loader.ts` 解析(ZIP 解压 + XML,单位换算到 mm 基准)。\n * 坐标永远以 faijs 基准长度单位(mm)存储 — Shape 不贴 unit 标签(D3)。\n *\n * 单位换算边界(unit-system §5.2):\n * - STL 无单位元数据 → 由 `opts.unit` 显式声明,缺省 mm,不做启发式猜测。\n * - 3MF `<model unit>` 由解析器读取并换算(micron/mm/cm/inch/foot/meter)。\n *\n * 返回契约(unit-system §10.6):`importFile` 返回 `{ shape, unit }` — `unit`\n * 是文件**自己声明的单位**(3MF `<model unit>`、STEP 单位实体),无声明格式\n * (STL)为 null(此时 `opts.unit` 决定刻度)。坐标恒为基准值 — `unit` 只作\n * 元数据(sourceUnit 记录、导出目标判定),绝不参与几何缩放(读入折算已由\n * 内核/解析器完成,二次缩放 = 双重换算)。\n */\n\nimport * as THREE from 'three'\nimport { geoToManifoldMesh } from '../boolean/geo-convert'\nimport { parseStl } from './stl-loader'\nimport { parseThreemf } from './threemf-loader'\nimport { mm, type UnitName, type ValueWithUnits } from '../units'\nimport type { Shape } from './types'\nimport type { PbrAppearance } from '../api/appearance'\nimport type { FileMeta } from '../api/meta'\n\n/** Result of a unit-aware file import. */\nexport interface ImportFileResult {\n shape: Shape\n /**\n * The unit the file itself declares (3MF `<model unit>`, STEP unit entities).\n * null for declaration-less formats (STL) — the caller's opts.unit decided.\n */\n unit: UnitName | null\n /**\n * Total parts the single file declared (e.g. 3MF `<build>` object count),\n * present only when > 1. Single-part mesh (STL, single-object 3MF) omits it.\n * When set, `shape` is only the FIRST part's geometry (feijs `load` op is\n * single-part; the file was downgraded to its first part — §5.4).\n */\n multiPartCount?: number\n /**\n * 整体级元数据(文件级;方案 §5.1 3MF `<model><metadata>`)。STL/STEP 视实现\n * 是否解析;无声明则省略。仅随导入结果上抛,不挂 Shape。\n */\n fileMeta?: FileMeta\n}\n\n/** SI prefixes that may precede .METRE. in a STEP SI_UNIT, → faijs UnitName. */\nconst SI_PREFIX_TO_UNIT: Record<string, UnitName> = {\n '.MILLI.': 'mm',\n '.CENTI.': 'cm',\n '$': 'm',\n}\n\n/** CONVERSION_BASED_UNIT names (uppercased) found in real-world STEP files. */\nconst CONVERSION_NAME_TO_UNIT: Record<string, UnitName> = {\n 'METRE': 'm',\n 'METER': 'm',\n 'MILLIMETRE': 'mm',\n 'MILLIMETER': 'mm',\n 'CENTIMETRE': 'cm',\n 'CENTIMETER': 'cm',\n 'MICROMETRE': 'micron',\n 'MICROMETER': 'micron',\n 'INCH': 'inch',\n 'FOOT': 'foot',\n}\n\n/**\n * Bounded scan window for `detectStepUnit`. Unit entities sit at the front of\n * the DATA section (right after the product/context blocks); 256 KiB covers\n * every real-world header+context preamble observed so far. Recomputable\n * constant — raise if a fixture ever misses.\n */\nexport const STEP_UNIT_SCAN_PREFIX = 256 * 1024\n\n/**\n * Parse the declared length unit from STEP text (unit-system §10.4).\n *\n * Unit entities live in the DATA section (not HEADER — ISO 10303-21 reserves\n * HEADER for FILE_DESCRIPTION/FILE_NAME/FILE_SCHEMA), near its start. We scan\n * a bounded prefix; the justification is \"unit entities sit at the front of\n * the DATA section\", not \"top of file\".\n *\n * Recognized forms, both attached to a LENGTH_UNIT():\n * - `SI_UNIT(<prefix>, .METRE.)` — prefix `.MILLI.`/`.CENTI.`/`.MICRO.` or `$`.\n * - `CONVERSION_BASED_UNIT('<NAME>', #n)` — inch/foot/etc.\n *\n * Metadata only — NEVER used to scale geometry (OCCT already normalizes on\n * read; re-scaling = double conversion).\n *\n * @param stepText - the full STEP file text to scan (only a bounded prefix is read).\n * @returns the faijs UnitName, or null when no length-unit declaration is found\n * (STEP permits omitting it; caller falls back to the base unit).\n */\nexport function detectStepUnit(stepText: string): UnitName | null {\n const head = stepText.slice(0, STEP_UNIT_SCAN_PREFIX)\n\n // 1) CONVERSION_BASED_UNIT('<NAME>', #n) — non-SI units (inch/foot/…).\n const conv = head.match(/CONVERSION_BASED_UNIT\\s*\\(\\s*'([^']+)'/i)\n if (conv) {\n const mapped = CONVERSION_NAME_TO_UNIT[conv[1].toUpperCase()]\n if (mapped) return mapped\n }\n\n // 2) SI_UNIT(<prefix>, .METRE.) — the .METRE. guard excludes angle entities\n // (they carry .RADIAN./.STERADIAN., never .METRE.).\n const si = head.match(/SI_UNIT\\s*\\(\\s*([^)]*?)\\s*,\\s*\\.METRE\\.\\s*\\)/i)\n if (si) {\n const prefix = si[1].trim().toUpperCase()\n if (prefix === '.MICRO.') return 'micron'\n const mapped = SI_PREFIX_TO_UNIT[prefix]\n if (mapped) return mapped\n }\n\n return null\n}\n\n/**\n * Load geometry from raw file bytes (headless variant).\n *\n * @param buffer - the raw file bytes to parse (already decompressed; stpz\n * unzipping is the caller's job — faijs never unzips implicitly).\n * @param format - format identifier such as 'stl', '3mf'/'threemf' or 'step'\n * (defaults to 'stl').\n * @param opts - optional settings; `unit` declares the source unit for\n * formats without unit metadata (e.g. STL). Defaults to mm.\n * @returns the shape with base-unit coordinates plus the file's own declared\n * unit (`unit`, metadata only; null when the format has no declaration).\n */\nexport async function importFile(\n buffer: ArrayBuffer,\n format?: string,\n opts?: { unit?: ValueWithUnits },\n): Promise<ImportFileResult> {\n const fmt = (format ?? 'stl').toLowerCase()\n\n if (fmt === '3mf' || fmt === 'threemf') {\n const archive = await parseThreemf(buffer)\n // §5.4 单零件收敛:只取**第一个**对象实例(declaration order — `<build><item>`\n // 序,见 threemf-loader)构造成单一 part;多对象文件记 multiPartCount 供上层\n // 登记\"多零件降级\"警告。坐标已在 parseThreemf 里折算为 faijs 基准单位。\n const first = archive.objects[0]\n if (!first) {\n throw new Error('[mesh/io] 3MF contains no objects')\n }\n const multiPartCount = archive.objects.length > 1 ? archive.objects.length : undefined\n const shape: Shape = {\n positions: first.positions as Float32Array,\n indices: first.indices as Uint32Array,\n // P2(方案 §5 3MF 行):对象级 baseColor → appearance.color(sRGB 原值,\n // 宽容兼容:无 baseColor 不带 appearance)。colorgroup(vertexColors)与\n // 逐三角形材质属 Phase 2(materialGroups / vertexColors),P2 不映射。\n ...(first.baseColor ? { appearance: { color: [first.baseColor[0], first.baseColor[1], first.baseColor[2]] } } : {}),\n // P4(方案 §5 3MF 行):逐三角形 basematerials(p1=p2=p3)→ materialGroups\n // (三角形区间 + appearance.color);无则不带。vertexColors(colorgroup)\n // 由上层(编辑器导入路径)消费,io 单零件收敛不展开为材质分组。\n ...(first.materialGroups && first.materialGroups.length > 0\n ? {\n materialGroups: first.materialGroups.map((g) => ({\n start: g.start,\n count: g.count,\n appearance: { color: [g.color[0], g.color[1], g.color[2]] } as PbrAppearance,\n })),\n }\n : {}),\n // 零件级元数据(方案 §5.1 3MF 行):对象 name/partnumber/metadatagroup → meta。\n ...(first.meta ? { meta: first.meta } : {}),\n }\n return {\n shape,\n unit: archive.unit,\n multiPartCount,\n // 整体级元数据(`<model><metadata>`)随导入结果上抛(方案 §5.1)。\n ...(archive.fileMeta ? { fileMeta: archive.fileMeta } : {}),\n }\n }\n\n if (fmt === 'stl') {\n const scale = (opts?.unit ?? mm).as(mm)\n const geo = parseStl(buffer)\n if (scale !== 1) {\n const attr = geo.getAttribute('position') as THREE.BufferAttribute\n const arr = attr.array as Float32Array\n for (let i = 0; i < arr.length; i++) arr[i] *= scale\n }\n return { shape: geoToManifoldMesh(geo), unit: null }\n }\n\n // STEP goes through the BREP chain (loadBrep → OCCT, which normalizes to the\n // base unit on read). The mesh io path has no kernel-independent STEP parser\n // and must not fake one — a missing path is an error, not a fallback.\n throw new Error(`[mesh/io] unsupported format: ${fmt}`)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh IO API — headless 文件加载\n *\n * STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons);3MF 由\n * `mesh/threemf-loader.ts` 解析(ZIP 解压 + XML,单位换算到 mm 基准)。\n * 坐标永远以 faijs 基准长度单位(mm)存储 — Shape 不贴 unit 标签(D3)。\n *\n * 单位换算边界(unit-system §5.2):\n * - STL 无单位元数据 → 由 `opts.unit` 显式声明优先;未声明时 faijs 按历史\n * host 行为做启发式猜测(`guessStlUnit`,unified 方案 §6.1/§8 —— 3d_editor\n * 迁移回归的单位断言依赖此行为)。猜测收敛在 faijs 内(红线 R0:宿主不\n * 自实现单位换算),G0 = 折算后坐标,渲染 = 拓扑 = G0。\n * - 3MF `<model unit>` 由解析器读取并换算(micron/mm/cm/inch/foot/meter)。\n *\n * 返回契约(unit-system §10.6):`importFile` 返回 `{ shape, unit }` — `unit`\n * 是文件源单位(必然有值;faijs 是单一真源):3MF/STEP 取文件声明(STEP 无声明\n * → 'mm',与 OCCT 一致),STL 取 opts.unit 或 guessStlUnit 启发式猜测。坐标恒\n * 为基准值 — `unit` 只作元数据(sourceUnit 记录、导出目标判定),绝不参与几何\n * 缩放(读入折算已由内核/解析器完成,二次缩放 = 双重换算)。\n */\n\nimport * as THREE from 'three'\nimport { geoToManifoldMesh } from '../boolean/geo-convert'\nimport { parseStl } from './stl-loader'\nimport { parseThreemf, type ThreemfObject } from './threemf-loader'\nimport { parseBambu3mfFromEntries } from './threemf-bambu'\nimport { unitScale, type UnitName } from '../units'\nimport { guessStlUnit } from './stl-unit'\nimport type { Shape } from './types'\nimport type { PbrAppearance } from '../api/appearance'\nimport type { FileMeta } from '../api/meta'\nimport type { ImportModel } from './import-model'\n\n/** Result of a unit-aware file import. */\nexport interface ImportFileResult {\n shape: Shape\n /**\n * All parts the file declared, in declaration order (3MF `<build><item>` 序 /\n * STL 单零件)。`shape` is `parts[0]`(单零件兼容,过渡期)。\n * P0(2026-10-06-step-3mf-multipart-import-plan.md §5.4):多对象 3MF 不再折叠。\n */\n parts: Shape[]\n /**\n * The file's source unit (always present; faijs is the single source of truth).\n * 3MF/STEP: the file's declared unit (STEP 无声明 → 'mm', 与 OCCT 一致).\n * STL: opts.unit if declared, else the guessStlUnit heuristic result.\n * Metadata only — coordinates are already in the faijs base unit (mm).\n */\n unit: UnitName\n /**\n * Total parts the single file declared (e.g. 3MF `<build>` object count),\n * present only when > 1. Single-part mesh (STL, single-object 3MF) omits it.\n * 保留为 `parts.length`(>1 时);多零件不再折叠后该字段仅供旧宿主判断。\n */\n multiPartCount?: number\n /**\n * 整体级元数据(文件级;方案 §5.1 3MF `<model><metadata>`)。STL/STEP 视实现\n * 是否解析;无声明则省略。仅随导入结果上抛,不挂 Shape。\n */\n fileMeta?: FileMeta\n /**\n * 本次导入的结构数据(P0 §5.1):零件身份表 + Bambu 视图(3MF 分支填充)。\n * 单/多零件均登记(单零件 parts 长度 1)。\n */\n importModel?: ImportModel\n}\n\n/** SI prefixes that may precede .METRE. in a STEP SI_UNIT, → faijs UnitName. */\nconst SI_PREFIX_TO_UNIT: Record<string, UnitName> = {\n '.MILLI.': 'mm',\n '.CENTI.': 'cm',\n '$': 'm',\n}\n\n/** CONVERSION_BASED_UNIT names (uppercased) found in real-world STEP files. */\nconst CONVERSION_NAME_TO_UNIT: Record<string, UnitName> = {\n 'METRE': 'm',\n 'METER': 'm',\n 'MILLIMETRE': 'mm',\n 'MILLIMETER': 'mm',\n 'CENTIMETRE': 'cm',\n 'CENTIMETER': 'cm',\n 'MICROMETRE': 'micron',\n 'MICROMETER': 'micron',\n 'INCH': 'inch',\n 'FOOT': 'foot',\n}\n\n/**\n * Bounded scan window for `detectStepUnit`. Unit entities sit at the front of\n * the DATA section (right after the product/context blocks); 256 KiB covers\n * every real-world header+context preamble observed so far. Recomputable\n * constant — raise if a fixture ever misses.\n */\nexport const STEP_UNIT_SCAN_PREFIX = 256 * 1024\n\n/**\n * Parse the declared length unit from STEP text (unit-system §10.4).\n *\n * Unit entities live in the DATA section (not HEADER — ISO 10303-21 reserves\n * HEADER for FILE_DESCRIPTION/FILE_NAME/FILE_SCHEMA), near its start. We scan\n * a bounded prefix; the justification is \"unit entities sit at the front of\n * the DATA section\", not \"top of file\".\n *\n * Recognized forms, both attached to a LENGTH_UNIT():\n * - `SI_UNIT(<prefix>, .METRE.)` — prefix `.MILLI.`/`.CENTI.`/`.MICRO.` or `$`.\n * - `CONVERSION_BASED_UNIT('<NAME>', #n)` — inch/foot/etc.\n *\n * Metadata only — NEVER used to scale geometry (OCCT already normalizes on\n * read; re-scaling = double conversion).\n *\n * @param stepText - the full STEP file text to scan (only a bounded prefix is read).\n * @returns the faijs UnitName, or null when no length-unit declaration is found\n * (STEP permits omitting it; caller falls back to the base unit).\n */\nexport function detectStepUnit(stepText: string): UnitName | null {\n const head = stepText.slice(0, STEP_UNIT_SCAN_PREFIX)\n\n // 1) CONVERSION_BASED_UNIT('<NAME>', #n) — non-SI units (inch/foot/…).\n const conv = head.match(/CONVERSION_BASED_UNIT\\s*\\(\\s*'([^']+)'/i)\n if (conv) {\n const mapped = CONVERSION_NAME_TO_UNIT[conv[1].toUpperCase()]\n if (mapped) return mapped\n }\n\n // 2) SI_UNIT(<prefix>, .METRE.) — the .METRE. guard excludes angle entities\n // (they carry .RADIAN./.STERADIAN., never .METRE.).\n const si = head.match(/SI_UNIT\\s*\\(\\s*([^)]*?)\\s*,\\s*\\.METRE\\.\\s*\\)/i)\n if (si) {\n const prefix = si[1].trim().toUpperCase()\n if (prefix === '.MICRO.') return 'micron'\n const mapped = SI_PREFIX_TO_UNIT[prefix]\n if (mapped) return mapped\n }\n\n return null\n}\n\n/**\n * Load geometry from raw file bytes (headless variant).\n *\n * @param buffer - the raw file bytes to parse (already decompressed; stpz\n * unzipping is the caller's job — faijs never unzips implicitly).\n * @param format - format identifier such as 'stl', '3mf'/'threemf' or 'step'\n * (defaults to 'stl').\n * @param opts - optional settings; `unit` (a UnitName string) declares the\n * source unit for formats without unit metadata (e.g. STL). Defaults to\n * the guessStlUnit heuristic when omitted.\n * @returns the shape with base-unit coordinates plus the file's source unit\n * (`unit`, metadata only; always present — faijs is the single source of truth).\n */\nexport async function importFile(\n buffer: ArrayBuffer,\n format?: string,\n opts?: { unit?: UnitName },\n): Promise<ImportFileResult> {\n const fmt = (format ?? 'stl').toLowerCase()\n\n if (fmt === '3mf' || fmt === 'threemf') {\n const archive = await parseThreemf(buffer)\n // P0(方案 §5.4):不再折叠——返回全部 `<build><item>` 对象(declaration order,\n // 坐标已在 parseThreemf 里折算为 faijs 基准单位)。`shape` 保留为 parts[0]\n // (单零件兼容,过渡期)。\n if (archive.objects.length === 0) {\n throw new Error('[mesh/io] 3MF contains no objects')\n }\n // Bambu 元数据(盘号/挤出机/视图变换):有 Bambu 配置才产生内容,普通 3MF 返回空表。\n // P4:根 model XML 直传(3MF `<build>` 在 resources 前;id 两套编号经父\n // object components 关联——leafParts 表承载)。\n const bambu = parseBambu3mfFromEntries(archive.extraEntries, archive.modelXml)\n const parts = archive.objects.map(threemfObjectToShape)\n const multiPartCount = parts.length > 1 ? parts.length : undefined\n const importModel: ImportModel = {\n format: '3mf',\n unit: archive.unit,\n parts: archive.objects.map((obj, i) => {\n const part: ImportModel['parts'][number] = {\n index: i,\n name: obj.name ?? `imported:${i}`,\n }\n if (obj.baseColor) part.color = [obj.baseColor[0], obj.baseColor[1], obj.baseColor[2]]\n if (obj.meta) part.meta = obj.meta\n // Bambu 身份:3MF `<object id>`(叶子实例)与 Bambu objects 表(键为\n // model_settings 父对象 id)是两套编号——经父 object components 关联\n // (ThreemfObject.parentObjectId/componentIndex → bambu.leafParts)。\n const bm = obj.parentObjectId !== undefined\n ? bambu.leafParts.get(`${obj.parentObjectId}:${obj.componentIndex ?? 1}`)\n : undefined\n if (bm) {\n part.objectId = bm.objectId\n if (bm.plateId > 0) part.plateId = bm.plateId\n // Bambu extruder 1-based(默认 1):显式登记文件声明值\n part.extruder = bm.extruder\n part.partId = bm.partId\n }\n return part\n }),\n ...(archive.fileMeta ? { fileMeta: archive.fileMeta } : {}),\n }\n const bambuViews = buildBambuViews(bambu)\n if (bambuViews) importModel.bambuViews = bambuViews\n return {\n shape: parts[0],\n parts,\n unit: archive.unit,\n multiPartCount,\n importModel,\n // 整体级元数据(`<model><metadata>`)随导入结果上抛(方案 §5.1)。\n ...(archive.fileMeta ? { fileMeta: archive.fileMeta } : {}),\n }\n }\n\n if (fmt === 'stl') {\n const geo = parseStl(buffer)\n // STL 无单位声明:opts.unit 显式声明优先;未声明时做启发式猜测\n // (guessStlUnit —— 历史 host 行为,unified §6.1/§8 迁移基线)。猜测与\n // 折算都在 faijs 内完成(红线 R0),G0 即基准值,宿主不再二次换算。\n // unit 字段回传源单位(声明值或猜测值),供宿主记录 sourceUnit 元数据。\n let scale = 1\n let sourceUnit: UnitName = 'mm'\n const declared = opts?.unit\n if (declared) {\n sourceUnit = declared\n scale = unitScale(declared)\n } else {\n geo.computeBoundingBox()\n const bb = geo.boundingBox\n if (bb) {\n sourceUnit = guessStlUnit({\n min: [bb.min.x, bb.min.y, bb.min.z],\n max: [bb.max.x, bb.max.y, bb.max.z],\n })\n scale = unitScale(sourceUnit)\n }\n }\n if (scale !== 1) {\n const attr = geo.getAttribute('position') as THREE.BufferAttribute\n const arr = attr.array as Float32Array\n for (let i = 0; i < arr.length; i++) arr[i] *= scale\n }\n const shape = geoToManifoldMesh(geo)\n return { shape, parts: [shape], unit: sourceUnit }\n }\n\n // STEP goes through the BREP chain (loadBrep → OCCT, which normalizes to the\n // base unit on read). The mesh io path has no kernel-independent STEP parser\n // and must not fake one — a missing path is an error, not a fallback.\n throw new Error(`[mesh/io] unsupported format: ${fmt}`)\n}\n\n/** 单个 3MF `<build><item>` 对象 → Shape(P0:逐对象构造,替换原\"只取第一个\"收敛)。 */\nfunction threemfObjectToShape(obj: ThreemfObject): Shape {\n return {\n positions: obj.positions as Float32Array,\n indices: obj.indices as Uint32Array,\n // P2(方案 §5 3MF 行):对象级 baseColor → appearance.color(sRGB 原值,\n // 宽容兼容:无 baseColor 不带 appearance)。colorgroup(vertexColors)与\n // 逐三角形材质属 Phase 2(materialGroups / vertexColors),P2 不映射。\n ...(obj.baseColor ? { appearance: { color: [obj.baseColor[0], obj.baseColor[1], obj.baseColor[2]] } } : {}),\n // P4(方案 §5 3MF 行):逐三角形 basematerials(p1=p2=p3)→ materialGroups\n // (三角形区间 + appearance.color);无则不带。vertexColors(colorgroup)\n // 由上层(编辑器导入路径)消费,io 单零件收敛不展开为材质分组。\n ...(obj.materialGroups && obj.materialGroups.length > 0\n ? {\n materialGroups: obj.materialGroups.map((g) => ({\n start: g.start,\n count: g.count,\n appearance: { color: [g.color[0], g.color[1], g.color[2]] } as PbrAppearance,\n })),\n }\n : {}),\n // 零件级元数据(方案 §5.1 3MF 行):对象 name/partnumber/metadatagroup → meta。\n ...(obj.meta ? { meta: obj.meta } : {}),\n }\n}\n\n/** Bambu 显示视图数据 → ImportModel.bambuViews(无任何 Bambu 结构时省略)。 */\nfunction buildBambuViews(\n bambu: import('./threemf-bambu').Bambu3mfMetadata,\n): ImportModel['bambuViews'] | undefined {\n const plates = [...bambu.plates.keys()].sort((a, b) => a - b)\n if (plates.length === 0 && !bambu.assembleTransforms && !bambu.importTransforms) return undefined\n const views: NonNullable<ImportModel['bambuViews']> = { plates }\n if (bambu.assembleTransforms) {\n views.assembleTransforms = Object.fromEntries(\n [...bambu.assembleTransforms].map(([k, v]) => [k, { transform: v.transform, offset: v.offset }]),\n )\n }\n if (bambu.importTransforms) {\n views.importTransforms = Object.fromEntries(\n [...bambu.importTransforms].map(([k, v]) => [k, { matrix: v.matrix, sourceOffset: v.sourceOffset }]),\n )\n }\n // P4:完整消费面随结果回传——宿主重建 Bambu3mfMetadata 不再回读 archive。\n if (bambu.buildItems) {\n views.buildItems = bambu.buildItems.map((b) => ({\n objectId: b.objectId,\n transform: b.transform ?? null,\n }))\n }\n if (bambu.filamentColors.length > 0) views.filamentColors = bambu.filamentColors\n if (bambu.filamentTypes.length > 0) views.filamentTypes = bambu.filamentTypes\n if (bambu.parts.length > 0) {\n views.parts = bambu.parts.map((p) => ({\n partIndex: p.partIndex,\n objectId: p.objectId,\n partId: p.partId,\n name: p.name,\n extruder: p.extruder,\n plateId: p.plateId,\n }))\n }\n return views\n}\n"]}
|
package/dist/mesh/primitives.js
CHANGED
|
@@ -44,7 +44,7 @@ export function box(params) {
|
|
|
44
44
|
// pre-rotation sizes must be (width, height, depth) — 裁决 7 xyz contract.
|
|
45
45
|
const geo = new THREE.BoxGeometry(width, height, depth);
|
|
46
46
|
geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2));
|
|
47
|
-
// brepjs box semantics: corner at origin by default; centered at origin when
|
|
47
|
+
// 原 brepjs box semantics: corner at origin by default; centered at origin when
|
|
48
48
|
// `centered` (no `at`); `at` (CENTER semantics) takes precedence.
|
|
49
49
|
const at = params.at;
|
|
50
50
|
let tx = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/mesh/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh 基本体 API — 从现有纯函数提取的统一接口\n *\n * 提取来源(§5.7):\n * - box/sphere/cylinder/cone/wedge ← engine/primitives/mesh-primitives.ts (makePrimitiveGeo)\n * - screw ← engine/primitives/screw/screw.ts (makeScrew)\n *\n * `text` / `svgExtrude`(three 的 Shape / ExtrudeGeometry / SVGLoader 链)已随\n * B 组迁到 `@faicad/faijs-extra` 的 `mesh/primitives.ts`,core 的 mesh 面不再\n * 承载 three 的非基础几何生成链。\n *\n * 所有函数返回 Shape (ManifoldMeshData):THREE.BufferGeometry → geoToManifoldMesh 转换。\n * 坐标系:Z-up、毫米。\n */\n\nimport * as THREE from 'three'\nimport { makePrimitiveGeo } from '../primitives/mesh-primitives'\nimport { geoToManifoldMesh } from '../boolean/csg-backend'\nimport type { Shape, BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams, SdfParams } from './types'\nimport { clampNRad } from './types'\n\n// ── 内部工具 ──\n\n/** THREE.BufferGeometry → Shape (ManifoldMeshData);可选携带面结构元数据。 */\nfunction geoToShape(geo: THREE.BufferGeometry, faceRanges?: Shape['faceRanges']): Shape {\n const shape = geoToManifoldMesh(geo) as Shape\n if (faceRanges !== undefined) shape.faceRanges = faceRanges\n return shape\n}\n\n// ── 创建 API ──\n\n/**\n * Create a box solid (brepjs contract, §4.1 A 决策).\n *\n * `box(width, depth, height)` — X=width, Y=depth, Z=height — places the\n * min-corner at the origin by default (`centered:false`). `centered: true`\n * centers the box at the origin; `at` is CENTER semantics and takes precedence\n * over `centered`. The `segments` option is consumed by the tessellation\n * caller (this mesh builder keeps it via clampNRad when present).\n *\n * @param params - box parameters (width/depth/height, optional at/centered/segments).\n * @returns the box shape.\n */\nexport function box(params: BoxParams): Shape {\n const { width, depth, height } = params\n // THREE.BoxGeometry(a, b, c) is Y-up (X=a, Y=b, Z=c); after the +90° rotateX\n // the dims map to X=a, Y=c, Z=b. To reach X=width, Y=depth, Z=height the\n // pre-rotation sizes must be (width, height, depth) — 裁决 7 xyz contract.\n const geo = new THREE.BoxGeometry(width, height, depth)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // brepjs box semantics: corner at origin by default; centered at origin when\n // `centered` (no `at`); `at` (CENTER semantics) takes precedence.\n const at = params.at\n let tx = 0\n let ty = 0\n let tz = 0\n if (at !== undefined) {\n ;[tx, ty, tz] = at\n } else if (!params.centered) {\n tx = width / 2\n ty = depth / 2\n tz = height / 2\n }\n if (tx !== 0 || ty !== 0 || tz !== 0) geo.translate(tx, ty, tz)\n // 面结构(P4 面级):BoxGeometry 12 三角形 = 6 面 × 2,顺序固定\n // (+X, −X, +Y, −Y, +Z, −Z);geoToManifoldMesh 焊接顶点保三角形序,故面序契约成立。\n // 面序号契约(setFaceColor 的 faceIds 即此序号):0=+X, 1=−X, 2=+Y, 3=−Y, 4=+Z, 5=−Z。\n const faceRanges: Shape['faceRanges'] = [\n { start: 0, count: 2 },\n { start: 2, count: 2 },\n { start: 4, count: 2 },\n { start: 6, count: 2 },\n { start: 8, count: 2 },\n { start: 10, count: 2 },\n ]\n return geoToShape(geo, faceRanges)\n}\n\n/**\n * Create a sphere centered at the origin (or the optional `center`).\n *\n * @param params - sphere parameters (radius, optional segments, optional center).\n * @returns the sphere shape.\n */\nexport function sphere(params: SphereParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = makePrimitiveGeo('sphere', params.radius * 2, segs)\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a cylinder along +Z (`cylinder(radius, height, { at?, centered?,\n * segments? })` brepjs 契约,§4.3 A 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cylinder parameters (radius, height, optional at/centered/segments).\n * @returns the cylinder shape.\n */\nexport function cylinder(params: CylinderParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.CylinderGeometry(params.radius, params.radius, params.height, segs)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平移到 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n geo.translate(baseX, baseY, baseZ + params.height / 2)\n // 面结构(P4 面级):CylinderGeometry 三角形布局稳定——侧面 2*segs(tri 0..2segs-1)、\n // 顶盖 segs、底盖 segs。面序号契约:0=侧面, 1=顶, 2=底。\n const faceRanges: Shape['faceRanges'] = [\n { start: 0, count: 2 * segs },\n { start: 2 * segs, count: segs },\n { start: 3 * segs, count: segs },\n ]\n return geoToShape(geo, faceRanges)\n}\n\n/**\n * Create a cone, or a frustum when the top and bottom radii differ\n * (`cone(bottomRadius, topRadius, height, { at?, centered?, segments? })` brepjs\n * 契约,§4.1 P 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cone parameters (radiusBottom, radiusTop, height, optional at/centered/segments).\n * @returns the cone shape.\n */\nexport function cone(params: ConeParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.ConeGeometry(\n Math.max(params.radiusBottom, params.radiusTop),\n params.height,\n segs,\n )\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // radiusTop === 0 → 尖锥(ConeGeometry 顶点在顶);其余(含 radiusTop ===\n // radiusBottom 的等径圆柱/圆台)用 CylinderGeometry(radiusTop/bottom 各就各位)。\n let resultGeo: THREE.BufferGeometry\n if (params.radiusTop === 0) {\n resultGeo = geo\n } else {\n const geo2 = new THREE.CylinderGeometry(\n params.radiusTop,\n params.radiusBottom,\n params.height,\n segs,\n )\n geo2.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n resultGeo = geo2\n }\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平坦平移 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n resultGeo.translate(baseX, baseY, baseZ + params.height / 2)\n // 面结构(P4 面级):radiusTop=0 的 ConeGeometry 只有 2 面——侧面(segs 个\n // 三角扇)+ 底盖(segs 个);radiusTop>0 的圆台 CylinderGeometry 3 面\n // (侧面 2*segs、顶、底,同 cylinder 布局)。面序号契约:0=侧面, 1=底\n // (尖锥);0=侧面, 1=顶, 2=底(圆台)。\n const faceRanges: Shape['faceRanges'] =\n params.radiusTop === 0\n ? [\n { start: 0, count: segs },\n { start: segs, count: segs },\n ]\n : [\n { start: 0, count: 2 * segs },\n { start: 2 * segs, count: segs },\n { start: 3 * segs, count: segs },\n ]\n return geoToShape(resultGeo, faceRanges)\n}\n\n/**\n * Create a wedge (ramp) solid, fully parameterized and Z-up.\n *\n * @param params - wedge parameters (width, height, angle, length, optional center).\n * @returns the wedge shape.\n */\nexport function wedge(params: WedgeParams): Shape {\n const width = params.width\n const height = params.height\n const angle = params.angle\n const length = params.length\n\n const angleRad = (angle * Math.PI) / 180\n const halfExtrude = length / 2\n const hw = width / 2\n const halfTopWidth = Math.max(0, hw - height / Math.tan(angleRad))\n // 顶边塌缩(斜坡已在宽度内到顶)→ 三角棱柱(与 brep wedge 的退化处理一致,\n // 保证 mesh/brep 同参数 bbox 一致;零面积三角形会破坏 manifold)。\n const degenerate = halfTopWidth <= 1e-12\n\n const positions = degenerate\n ? new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, 0, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, 0, height,\n ])\n : new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, halfTopWidth, height,\n -halfExtrude, -halfTopWidth, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, halfTopWidth, height,\n halfExtrude, -halfTopWidth, height,\n ])\n\n const indices = degenerate\n ? new Uint32Array([\n 0, 1, 2, 3, 5, 4,\n 0, 3, 4, 0, 4, 1,\n 0, 2, 5, 0, 5, 3,\n 1, 4, 5, 1, 5, 2,\n ])\n : new Uint32Array([\n 0, 1, 2, 0, 2, 3,\n 4, 6, 5, 4, 7, 6,\n 0, 4, 5, 0, 5, 1,\n 3, 2, 6, 3, 6, 7,\n 0, 3, 7, 0, 7, 4,\n 1, 5, 6, 1, 6, 2,\n ])\n\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geo.setIndex(new THREE.BufferAttribute(indices, 1))\n\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a screw (threaded) geometry.\n *\n * @param params - screw parameters (system, specIdx, thread, length, head, optional pitchCustom and nRad).\n * @returns the screw shape.\n */\nexport async function screw(params: {\n system: 'metric' | 'imperial'\n specIdx: number\n thread: 'coarse' | 'fine' | 'custom' | 'none'\n pitchCustom?: number\n length: number\n head: 'hex' | 'chc' | 'none'\n nRad?: number\n}): Promise<Shape> {\n const { makeScrew } = await import('../primitives/screw/screw')\n const geo = makeScrew({\n system: params.system,\n specIdx: params.specIdx,\n thread: params.thread,\n pitchCustom: params.pitchCustom ?? 0,\n length: params.length,\n head: params.head,\n nRad: clampNRad(params.nRad),\n })\n return geoToShape(geo)\n}\n\n/**\n * Create a mesh from SDF (signed distance field) code, sampling the field with\n * marching cubes.\n *\n * @param params - SDF parameters (code, optional bounds, params, resolution).\n * @returns the sampled shape.\n */\nexport async function sdf(params: SdfParams): Promise<Shape> {\n const { runSdf } = await import('../sdf/sdf-runner')\n const box = params.box ?? [[-10, -10, -10], [10, 10, 10]]\n const bounds: [number, number, number, number, number, number] = [\n box[0][0], box[0][1], box[0][2],\n box[1][0], box[1][1], box[1][2],\n ]\n const mesh = await runSdf(\n params.code,\n params.params ?? {},\n bounds,\n params.resolution ?? 1.0,\n )\n return { positions: mesh.positions, indices: mesh.indices }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/mesh/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh 基本体 API — 从现有纯函数提取的统一接口\n *\n * 提取来源(§5.7):\n * - box/sphere/cylinder/cone/wedge ← engine/primitives/mesh-primitives.ts (makePrimitiveGeo)\n * - screw ← engine/primitives/screw/screw.ts (makeScrew)\n *\n * `text` / `svgExtrude`(three 的 Shape / ExtrudeGeometry / SVGLoader 链)已随\n * B 组迁到 `@faicad/faijs-extra` 的 `mesh/primitives.ts`,core 的 mesh 面不再\n * 承载 three 的非基础几何生成链。\n *\n * 所有函数返回 Shape (ManifoldMeshData):THREE.BufferGeometry → geoToManifoldMesh 转换。\n * 坐标系:Z-up、毫米。\n */\n\nimport * as THREE from 'three'\nimport { makePrimitiveGeo } from '../primitives/mesh-primitives'\nimport { geoToManifoldMesh } from '../boolean/csg-backend'\nimport type { Shape, BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams, SdfParams } from './types'\nimport { clampNRad } from './types'\n\n// ── 内部工具 ──\n\n/** THREE.BufferGeometry → Shape (ManifoldMeshData);可选携带面结构元数据。 */\nfunction geoToShape(geo: THREE.BufferGeometry, faceRanges?: Shape['faceRanges']): Shape {\n const shape = geoToManifoldMesh(geo) as Shape\n if (faceRanges !== undefined) shape.faceRanges = faceRanges\n return shape\n}\n\n// ── 创建 API ──\n\n/**\n * Create a box solid (brepjs contract, §4.1 A 决策).\n *\n * `box(width, depth, height)` — X=width, Y=depth, Z=height — places the\n * min-corner at the origin by default (`centered:false`). `centered: true`\n * centers the box at the origin; `at` is CENTER semantics and takes precedence\n * over `centered`. The `segments` option is consumed by the tessellation\n * caller (this mesh builder keeps it via clampNRad when present).\n *\n * @param params - box parameters (width/depth/height, optional at/centered/segments).\n * @returns the box shape.\n */\nexport function box(params: BoxParams): Shape {\n const { width, depth, height } = params\n // THREE.BoxGeometry(a, b, c) is Y-up (X=a, Y=b, Z=c); after the +90° rotateX\n // the dims map to X=a, Y=c, Z=b. To reach X=width, Y=depth, Z=height the\n // pre-rotation sizes must be (width, height, depth) — 裁决 7 xyz contract.\n const geo = new THREE.BoxGeometry(width, height, depth)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // 原 brepjs box semantics: corner at origin by default; centered at origin when\n // `centered` (no `at`); `at` (CENTER semantics) takes precedence.\n const at = params.at\n let tx = 0\n let ty = 0\n let tz = 0\n if (at !== undefined) {\n ;[tx, ty, tz] = at\n } else if (!params.centered) {\n tx = width / 2\n ty = depth / 2\n tz = height / 2\n }\n if (tx !== 0 || ty !== 0 || tz !== 0) geo.translate(tx, ty, tz)\n // 面结构(P4 面级):BoxGeometry 12 三角形 = 6 面 × 2,顺序固定\n // (+X, −X, +Y, −Y, +Z, −Z);geoToManifoldMesh 焊接顶点保三角形序,故面序契约成立。\n // 面序号契约(setFaceColor 的 faceIds 即此序号):0=+X, 1=−X, 2=+Y, 3=−Y, 4=+Z, 5=−Z。\n const faceRanges: Shape['faceRanges'] = [\n { start: 0, count: 2 },\n { start: 2, count: 2 },\n { start: 4, count: 2 },\n { start: 6, count: 2 },\n { start: 8, count: 2 },\n { start: 10, count: 2 },\n ]\n return geoToShape(geo, faceRanges)\n}\n\n/**\n * Create a sphere centered at the origin (or the optional `center`).\n *\n * @param params - sphere parameters (radius, optional segments, optional center).\n * @returns the sphere shape.\n */\nexport function sphere(params: SphereParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = makePrimitiveGeo('sphere', params.radius * 2, segs)\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a cylinder along +Z (`cylinder(radius, height, { at?, centered?,\n * segments? })` brepjs 契约,§4.3 A 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cylinder parameters (radius, height, optional at/centered/segments).\n * @returns the cylinder shape.\n */\nexport function cylinder(params: CylinderParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.CylinderGeometry(params.radius, params.radius, params.height, segs)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平移到 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n geo.translate(baseX, baseY, baseZ + params.height / 2)\n // 面结构(P4 面级):CylinderGeometry 三角形布局稳定——侧面 2*segs(tri 0..2segs-1)、\n // 顶盖 segs、底盖 segs。面序号契约:0=侧面, 1=顶, 2=底。\n const faceRanges: Shape['faceRanges'] = [\n { start: 0, count: 2 * segs },\n { start: 2 * segs, count: segs },\n { start: 3 * segs, count: segs },\n ]\n return geoToShape(geo, faceRanges)\n}\n\n/**\n * Create a cone, or a frustum when the top and bottom radii differ\n * (`cone(bottomRadius, topRadius, height, { at?, centered?, segments? })` brepjs\n * 契约,§4.1 P 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cone parameters (radiusBottom, radiusTop, height, optional at/centered/segments).\n * @returns the cone shape.\n */\nexport function cone(params: ConeParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.ConeGeometry(\n Math.max(params.radiusBottom, params.radiusTop),\n params.height,\n segs,\n )\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // radiusTop === 0 → 尖锥(ConeGeometry 顶点在顶);其余(含 radiusTop ===\n // radiusBottom 的等径圆柱/圆台)用 CylinderGeometry(radiusTop/bottom 各就各位)。\n let resultGeo: THREE.BufferGeometry\n if (params.radiusTop === 0) {\n resultGeo = geo\n } else {\n const geo2 = new THREE.CylinderGeometry(\n params.radiusTop,\n params.radiusBottom,\n params.height,\n segs,\n )\n geo2.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n resultGeo = geo2\n }\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平坦平移 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n resultGeo.translate(baseX, baseY, baseZ + params.height / 2)\n // 面结构(P4 面级):radiusTop=0 的 ConeGeometry 只有 2 面——侧面(segs 个\n // 三角扇)+ 底盖(segs 个);radiusTop>0 的圆台 CylinderGeometry 3 面\n // (侧面 2*segs、顶、底,同 cylinder 布局)。面序号契约:0=侧面, 1=底\n // (尖锥);0=侧面, 1=顶, 2=底(圆台)。\n const faceRanges: Shape['faceRanges'] =\n params.radiusTop === 0\n ? [\n { start: 0, count: segs },\n { start: segs, count: segs },\n ]\n : [\n { start: 0, count: 2 * segs },\n { start: 2 * segs, count: segs },\n { start: 3 * segs, count: segs },\n ]\n return geoToShape(resultGeo, faceRanges)\n}\n\n/**\n * Create a wedge (ramp) solid, fully parameterized and Z-up.\n *\n * @param params - wedge parameters (width, height, angle, length, optional center).\n * @returns the wedge shape.\n */\nexport function wedge(params: WedgeParams): Shape {\n const width = params.width\n const height = params.height\n const angle = params.angle\n const length = params.length\n\n const angleRad = (angle * Math.PI) / 180\n const halfExtrude = length / 2\n const hw = width / 2\n const halfTopWidth = Math.max(0, hw - height / Math.tan(angleRad))\n // 顶边塌缩(斜坡已在宽度内到顶)→ 三角棱柱(与 brep wedge 的退化处理一致,\n // 保证 mesh/brep 同参数 bbox 一致;零面积三角形会破坏 manifold)。\n const degenerate = halfTopWidth <= 1e-12\n\n const positions = degenerate\n ? new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, 0, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, 0, height,\n ])\n : new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, halfTopWidth, height,\n -halfExtrude, -halfTopWidth, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, halfTopWidth, height,\n halfExtrude, -halfTopWidth, height,\n ])\n\n const indices = degenerate\n ? new Uint32Array([\n 0, 1, 2, 3, 5, 4,\n 0, 3, 4, 0, 4, 1,\n 0, 2, 5, 0, 5, 3,\n 1, 4, 5, 1, 5, 2,\n ])\n : new Uint32Array([\n 0, 1, 2, 0, 2, 3,\n 4, 6, 5, 4, 7, 6,\n 0, 4, 5, 0, 5, 1,\n 3, 2, 6, 3, 6, 7,\n 0, 3, 7, 0, 7, 4,\n 1, 5, 6, 1, 6, 2,\n ])\n\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geo.setIndex(new THREE.BufferAttribute(indices, 1))\n\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a screw (threaded) geometry.\n *\n * @param params - screw parameters (system, specIdx, thread, length, head, optional pitchCustom and nRad).\n * @returns the screw shape.\n */\nexport async function screw(params: {\n system: 'metric' | 'imperial'\n specIdx: number\n thread: 'coarse' | 'fine' | 'custom' | 'none'\n pitchCustom?: number\n length: number\n head: 'hex' | 'chc' | 'none'\n nRad?: number\n}): Promise<Shape> {\n const { makeScrew } = await import('../primitives/screw/screw')\n const geo = makeScrew({\n system: params.system,\n specIdx: params.specIdx,\n thread: params.thread,\n pitchCustom: params.pitchCustom ?? 0,\n length: params.length,\n head: params.head,\n nRad: clampNRad(params.nRad),\n })\n return geoToShape(geo)\n}\n\n/**\n * Create a mesh from SDF (signed distance field) code, sampling the field with\n * marching cubes.\n *\n * @param params - SDF parameters (code, optional bounds, params, resolution).\n * @returns the sampled shape.\n */\nexport async function sdf(params: SdfParams): Promise<Shape> {\n const { runSdf } = await import('../sdf/sdf-runner')\n const box = params.box ?? [[-10, -10, -10], [10, 10, 10]]\n const bounds: [number, number, number, number, number, number] = [\n box[0][0], box[0][1], box[0][2],\n box[1][0], box[1][1], box[1][2],\n ]\n const mesh = await runSdf(\n params.code,\n params.params ?? {},\n bounds,\n params.resolution ?? 1.0,\n )\n return { positions: mesh.positions, indices: mesh.indices }\n}\n"]}
|
|
@@ -89,7 +89,15 @@ export interface Bambu3mfMetadata {
|
|
|
89
89
|
filamentColors: string[];
|
|
90
90
|
filamentTypes: string[];
|
|
91
91
|
objects: Map<string, BambuObjectMeta>;
|
|
92
|
+
/** 打印单元表(序 = build items × 父对象 components = 叶子实例序)。 */
|
|
92
93
|
parts: BambuPartMeta[];
|
|
94
|
+
/**
|
|
95
|
+
* P4:叶子实例(3MF `<object id>`,含子文件内局部 id)→ Bambu 身份。
|
|
96
|
+
* 键 = `${父objectId}:${componentIndex}`(ThreemfObject.parentObjectId/
|
|
97
|
+
* componentIndex 同源);3MF object id 与 model_settings id 两套编号,
|
|
98
|
+
* 必须经父对象 components 关联。
|
|
99
|
+
*/
|
|
100
|
+
leafParts: Map<string, BambuPartMeta>;
|
|
93
101
|
plates: Map<number, BambuPlateInfo>;
|
|
94
102
|
modelMeta?: BambuModelMeta;
|
|
95
103
|
metadataEntries: Array<{
|
|
@@ -130,9 +138,12 @@ export declare function extractThumbnailBytes(entries: Map<string, Uint8Array>):
|
|
|
130
138
|
*
|
|
131
139
|
* @param extraEntries - the 3MF entry table excluding the geometry model shared
|
|
132
140
|
* with `parseThreemf` (project_settings / model_settings configs + thumbnails).
|
|
141
|
+
* @param modelXml - P4:根 model 文档(3D/3dmodel.model)XML;3MF 标准把
|
|
142
|
+
* `<build>` 放在 `<resources>` 前,必须全量解析。缺省时回退到
|
|
143
|
+
* extraEntries 里查找(兼容旧调用方)。
|
|
133
144
|
* @returns the resolved `Bambu3mfMetadata`.
|
|
134
145
|
*/
|
|
135
|
-
export declare function parseBambu3mfFromEntries(extraEntries: Map<string, Uint8Array
|
|
146
|
+
export declare function parseBambu3mfFromEntries(extraEntries: Map<string, Uint8Array>, modelXml?: string): Bambu3mfMetadata;
|
|
136
147
|
/** Parse Bambu metadata from a `ThreemfArchive`'s `extraEntries`.
|
|
137
148
|
*
|
|
138
149
|
* @param archive - a `ThreemfArchive` produced by `parseThreemf`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threemf-bambu.d.ts","sourceRoot":"","sources":["../../src/mesh/threemf-bambu.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"threemf-bambu.d.ts","sourceRoot":"","sources":["../../src/mesh/threemf-bambu.ts"],"names":[],"mappings":"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"}
|
|
@@ -87,9 +87,12 @@ export function extractThumbnailBytes(entries) {
|
|
|
87
87
|
*
|
|
88
88
|
* @param extraEntries - the 3MF entry table excluding the geometry model shared
|
|
89
89
|
* with `parseThreemf` (project_settings / model_settings configs + thumbnails).
|
|
90
|
+
* @param modelXml - P4:根 model 文档(3D/3dmodel.model)XML;3MF 标准把
|
|
91
|
+
* `<build>` 放在 `<resources>` 前,必须全量解析。缺省时回退到
|
|
92
|
+
* extraEntries 里查找(兼容旧调用方)。
|
|
90
93
|
* @returns the resolved `Bambu3mfMetadata`.
|
|
91
94
|
*/
|
|
92
|
-
export function parseBambu3mfFromEntries(extraEntries) {
|
|
95
|
+
export function parseBambu3mfFromEntries(extraEntries, modelXml) {
|
|
93
96
|
const decoder = new TextDecoder();
|
|
94
97
|
const filamentColors = [];
|
|
95
98
|
const filamentTypes = [];
|
|
@@ -98,6 +101,8 @@ export function parseBambu3mfFromEntries(extraEntries) {
|
|
|
98
101
|
const objectParts = new Map();
|
|
99
102
|
const assembleTransforms = new Map();
|
|
100
103
|
const importTransforms = new Map();
|
|
104
|
+
// P4:父对象(model_settings id)→ 3MF components 子 id 列表(打印单元关联)。
|
|
105
|
+
const parentComponents = new Map();
|
|
101
106
|
// ---- 1. project_settings.config (JSON) ----
|
|
102
107
|
let bedSize;
|
|
103
108
|
const projKey = [...extraEntries.keys()].find(f => f.endsWith('project_settings.config'));
|
|
@@ -274,39 +279,85 @@ export function parseBambu3mfFromEntries(extraEntries) {
|
|
|
274
279
|
}
|
|
275
280
|
}
|
|
276
281
|
// ---- 3. Model-level metadata + build items from 3D/3dmodel.model ----
|
|
282
|
+
// P4:根 model XML 由 parseThreemf 经 ThreemfArchive.modelXml 直传(根 model
|
|
283
|
+
// 不在 extraEntries);`<build>` 可能位于 `<resources>` 之前(3MF 标准顺序),
|
|
284
|
+
// 故 buildItems 全量解析整个 modelXml,不再只查 resources 之后的 tail。
|
|
277
285
|
const thumbnailBytes = extractThumbnailBytes(extraEntries);
|
|
278
286
|
let modelMeta;
|
|
279
287
|
let metadataEntries = [];
|
|
280
288
|
let buildItems = [];
|
|
281
|
-
const modelFile =
|
|
289
|
+
const modelFile = modelXml ?? (() => {
|
|
290
|
+
const f = [...extraEntries.keys()].find(k => k.endsWith('/3dmodel.model') || k === '3D/3dmodel.model');
|
|
291
|
+
return f ? decoder.decode(extraEntries.get(f)) : undefined;
|
|
292
|
+
})();
|
|
282
293
|
if (modelFile) {
|
|
283
|
-
const
|
|
284
|
-
const
|
|
285
|
-
const resourcesEnd = modelXml.indexOf('</resources>');
|
|
286
|
-
const head = resourcesStart >= 0 ? modelXml.slice(0, resourcesStart) : modelXml;
|
|
287
|
-
const tail = resourcesEnd >= 0 ? modelXml.slice(resourcesEnd) : '';
|
|
288
|
-
const parsedHead = parseModelMeta(head);
|
|
289
|
-
const parsedTail = parseModelMeta(tail);
|
|
294
|
+
const parsedHead = parseModelMeta(modelFile);
|
|
295
|
+
const parsedTail = parseModelMeta(modelFile);
|
|
290
296
|
modelMeta = { ...parsedHead.modelMeta, ...parsedTail.modelMeta };
|
|
291
297
|
metadataEntries = [...parsedHead.metadataEntries, ...parsedTail.metadataEntries];
|
|
292
|
-
buildItems = parse3mfBuild(
|
|
298
|
+
buildItems = parse3mfBuild(modelFile);
|
|
299
|
+
// P4:父对象 components(父 object id → 子 id 列表)——build item 引用父
|
|
300
|
+
// 对象,实际网格在子(叶子)里;打印单元 = 父 × components。
|
|
301
|
+
const parentObjRe = /<object\b[^>]*\bid="(\d+)"[^>]*>([\s\S]*?)<\/object>/gi;
|
|
302
|
+
let pom;
|
|
303
|
+
while ((pom = parentObjRe.exec(modelFile)) !== null) {
|
|
304
|
+
const body = pom[2];
|
|
305
|
+
if (!body.includes('<components>'))
|
|
306
|
+
continue;
|
|
307
|
+
const childIds = [];
|
|
308
|
+
const compRe = /<component\b[^>]*\bobjectid="(\d+)"/g;
|
|
309
|
+
let cm;
|
|
310
|
+
while ((cm = compRe.exec(body)) !== null) {
|
|
311
|
+
const cid = Number(cm[1]);
|
|
312
|
+
if (Number.isFinite(cid))
|
|
313
|
+
childIds.push(cid);
|
|
314
|
+
}
|
|
315
|
+
if (childIds.length > 0)
|
|
316
|
+
parentComponents.set(pom[1], childIds);
|
|
317
|
+
}
|
|
293
318
|
}
|
|
294
|
-
// ---- 4.
|
|
319
|
+
// ---- 4. 打印单元表(build items × 父对象 components 展开) ----
|
|
320
|
+
// P4 修正:3MF `<object id>`(叶子实例,含子文件内局部 id)与
|
|
321
|
+
// model_settings.config 的 `<object id>`(父对象)是两套编号。关联必须走
|
|
322
|
+
// 父对象 `<components>`(component objectid = 叶子 id);每个父对象的每个
|
|
323
|
+
// component = 一个可打印单元(part)。Bambu 导出惯例:component 序 ↔
|
|
324
|
+
// 父对象 part 列表序(partId 同源)。
|
|
325
|
+
// 表序 = build item 序 × components 序 = parseThreemf 叶子实例序(meshIndex
|
|
326
|
+
// 契约:ModelGroup 按 meshIndex 取 parts[i] 做 view delta / 多盘布局)。
|
|
295
327
|
const parts = [];
|
|
328
|
+
const leafParts = new Map();
|
|
296
329
|
let partIndex = 0;
|
|
297
330
|
for (const item of buildItems) {
|
|
298
331
|
const oid = item.objectId;
|
|
299
332
|
const objMeta = objects.get(oid);
|
|
300
333
|
const partList = objectParts.get(oid) ?? [];
|
|
301
|
-
|
|
334
|
+
const compIds = parentComponents.get(oid) ?? [];
|
|
335
|
+
if (compIds.length === 0) {
|
|
336
|
+
// 父对象无 components(单网格对象):1 个打印单元,partId 取第一个 part。
|
|
337
|
+
const p = partList[0];
|
|
302
338
|
parts.push({
|
|
303
339
|
partIndex: partIndex++,
|
|
304
340
|
objectId: oid,
|
|
305
|
-
partId: p
|
|
306
|
-
name: stripExtension(p
|
|
307
|
-
extruder: p
|
|
341
|
+
partId: p?.partId ?? '0',
|
|
342
|
+
name: stripExtension(p?.name ?? objMeta?.name ?? ''),
|
|
343
|
+
extruder: p?.extruder ?? objMeta?.extruder ?? 1,
|
|
308
344
|
plateId: objMeta?.plateId ?? 0,
|
|
309
345
|
});
|
|
346
|
+
leafParts.set(`${oid}:1`, parts[parts.length - 1]);
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
for (let ci = 0; ci < compIds.length; ci++) {
|
|
350
|
+
const p = partList[ci];
|
|
351
|
+
const meta = {
|
|
352
|
+
partIndex: partIndex++,
|
|
353
|
+
objectId: oid,
|
|
354
|
+
partId: p?.partId ?? String(ci + 1),
|
|
355
|
+
name: stripExtension(p?.name ?? objMeta?.name ?? ''),
|
|
356
|
+
extruder: p?.extruder ?? objMeta?.extruder ?? 1,
|
|
357
|
+
plateId: objMeta?.plateId ?? 0,
|
|
358
|
+
};
|
|
359
|
+
parts.push(meta);
|
|
360
|
+
leafParts.set(`${oid}:${ci + 1}`, meta);
|
|
310
361
|
}
|
|
311
362
|
}
|
|
312
363
|
return {
|
|
@@ -321,6 +372,7 @@ export function parseBambu3mfFromEntries(extraEntries) {
|
|
|
321
372
|
assembleTransforms: assembleTransforms.size > 0 ? assembleTransforms : undefined,
|
|
322
373
|
importTransforms: importTransforms.size > 0 ? importTransforms : undefined,
|
|
323
374
|
buildItems: buildItems.length > 0 ? buildItems : undefined,
|
|
375
|
+
leafParts,
|
|
324
376
|
};
|
|
325
377
|
}
|
|
326
378
|
/** Parse Bambu metadata from a `ThreemfArchive`'s `extraEntries`.
|
|
@@ -329,6 +381,6 @@ export function parseBambu3mfFromEntries(extraEntries) {
|
|
|
329
381
|
* @returns the resolved `Bambu3mfMetadata`.
|
|
330
382
|
*/
|
|
331
383
|
export function parseBambu3mfFromArchive(archive) {
|
|
332
|
-
return parseBambu3mfFromEntries(archive.extraEntries);
|
|
384
|
+
return parseBambu3mfFromEntries(archive.extraEntries, archive.modelXml);
|
|
333
385
|
}
|
|
334
386
|
//# sourceMappingURL=threemf-bambu.js.map
|