@faicad/faijs 0.16.1 → 0.18.0
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/LICENSE +4 -5
- package/NOTICE +5 -6
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +20 -2
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/assembly/entities.d.ts +1 -1
- package/dist/api/assembly/entities.d.ts.map +1 -1
- package/dist/api/assembly/entities.js.map +1 -1
- package/dist/api/assembly/joints.d.ts +2 -2
- package/dist/api/assembly/joints.d.ts.map +1 -1
- package/dist/api/assembly/joints.js +2 -2
- package/dist/api/assembly/joints.js.map +1 -1
- package/dist/api/assembly/lower.d.ts +1 -1
- package/dist/api/assembly/lower.d.ts.map +1 -1
- package/dist/api/assembly/lower.js.map +1 -1
- package/dist/api/assembly/pose.d.ts +3 -3
- package/dist/api/assembly/pose.d.ts.map +1 -1
- package/dist/api/assembly/pose.js +1 -1
- package/dist/api/assembly/pose.js.map +1 -1
- package/dist/api/assembly/preview.d.ts +1 -1
- package/dist/api/assembly/preview.d.ts.map +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.map +1 -1
- package/dist/api/assembly/solve.js +3 -3
- package/dist/api/assembly/solve.js.map +1 -1
- package/dist/api/assembly/solvers/assembly-tree.d.ts +98 -0
- package/dist/api/assembly/solvers/assembly-tree.d.ts.map +1 -0
- package/dist/api/assembly/solvers/assembly-tree.js +130 -0
- package/dist/api/assembly/solvers/assembly-tree.js.map +1 -0
- package/dist/api/assembly/solvers/chain-solver.d.ts +27 -0
- package/dist/api/assembly/solvers/chain-solver.d.ts.map +1 -0
- package/dist/api/assembly/solvers/chain-solver.js +330 -0
- package/dist/api/assembly/solvers/chain-solver.js.map +1 -0
- package/dist/api/assembly/solvers/global-solver.js +2 -2
- package/dist/api/assembly/solvers/global-solver.js.map +1 -1
- package/dist/api/assembly/solvers/joints-kinematics.d.ts +308 -0
- package/dist/api/assembly/solvers/joints-kinematics.d.ts.map +1 -0
- package/dist/api/assembly/solvers/joints-kinematics.js +643 -0
- package/dist/api/assembly/solvers/joints-kinematics.js.map +1 -0
- package/dist/api/assembly/solvers/quat.d.ts +35 -0
- package/dist/api/assembly/solvers/quat.d.ts.map +1 -0
- package/dist/api/assembly/solvers/quat.js +84 -0
- package/dist/api/assembly/solvers/quat.js.map +1 -0
- package/dist/api/assembly/solvers/types.d.ts +33 -0
- package/dist/api/assembly/solvers/types.d.ts.map +1 -1
- package/dist/api/assembly/solvers/types.js.map +1 -1
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +66 -29
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/brep-mirror/booleanFns.d.ts +40 -0
- package/dist/api/brep-mirror/booleanFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/booleanFns.js +104 -0
- package/dist/api/brep-mirror/booleanFns.js.map +1 -0
- package/dist/api/brep-mirror/brepHelpers.d.ts +55 -0
- package/dist/api/brep-mirror/brepHelpers.d.ts.map +1 -0
- package/dist/api/brep-mirror/brepHelpers.js +131 -0
- package/dist/api/brep-mirror/brepHelpers.js.map +1 -0
- package/dist/api/brep-mirror/compoundFns.d.ts +47 -0
- package/dist/api/brep-mirror/compoundFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/compoundFns.js +300 -0
- package/dist/api/brep-mirror/compoundFns.js.map +1 -0
- package/dist/api/brep-mirror/healingFns.d.ts +78 -0
- package/dist/api/brep-mirror/healingFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/healingFns.js +294 -0
- package/dist/api/brep-mirror/healingFns.js.map +1 -0
- package/dist/api/brep-mirror/hullFns.d.ts +20 -0
- package/dist/api/brep-mirror/hullFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/hullFns.js +46 -0
- package/dist/api/brep-mirror/hullFns.js.map +1 -0
- package/dist/api/brep-mirror/patternFns.d.ts +43 -0
- package/dist/api/brep-mirror/patternFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/patternFns.js +178 -0
- package/dist/api/brep-mirror/patternFns.js.map +1 -0
- package/dist/api/brep-mirror/primitiveFns.d.ts +42 -0
- package/dist/api/brep-mirror/primitiveFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/primitiveFns.js +104 -0
- package/dist/api/brep-mirror/primitiveFns.js.map +1 -0
- package/dist/api/brep-mirror/roofFns.d.ts +24 -0
- package/dist/api/brep-mirror/roofFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/roofFns.js +229 -0
- package/dist/api/brep-mirror/roofFns.js.map +1 -0
- package/dist/api/brep-mirror/straightSkeleton.d.ts +36 -0
- package/dist/api/brep-mirror/straightSkeleton.d.ts.map +1 -0
- package/dist/api/brep-mirror/straightSkeleton.js +443 -0
- package/dist/api/brep-mirror/straightSkeleton.js.map +1 -0
- package/dist/api/brep-mirror/sweepFns.d.ts +55 -0
- package/dist/api/brep-mirror/sweepFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/sweepFns.js +200 -0
- package/dist/api/brep-mirror/sweepFns.js.map +1 -0
- package/dist/api/brep-mirror/threadFns.d.ts +15 -0
- package/dist/api/brep-mirror/threadFns.d.ts.map +1 -1
- package/dist/api/brep-mirror/threadFns.js +37 -2
- package/dist/api/brep-mirror/threadFns.js.map +1 -1
- package/dist/api/brep-mirror/topologyFns.d.ts +74 -0
- package/dist/api/brep-mirror/topologyFns.d.ts.map +1 -0
- package/dist/api/brep-mirror/topologyFns.js +276 -0
- package/dist/api/brep-mirror/topologyFns.js.map +1 -0
- package/dist/api/brep-topology.d.ts +190 -0
- package/dist/api/brep-topology.d.ts.map +1 -0
- package/dist/api/brep-topology.js +337 -0
- package/dist/api/brep-topology.js.map +1 -0
- package/dist/api/brepjs-compat/constants.d.ts +11 -0
- package/dist/api/brepjs-compat/constants.d.ts.map +1 -0
- package/dist/api/brepjs-compat/constants.js +11 -0
- package/dist/api/brepjs-compat/constants.js.map +1 -0
- package/dist/api/brepjs-compat/index.d.ts +19 -232
- package/dist/api/brepjs-compat/index.d.ts.map +1 -1
- package/dist/api/brepjs-compat/index.js +19 -286
- package/dist/api/brepjs-compat/index.js.map +1 -1
- package/dist/api/brepjs-compat/planeOps.d.ts +98 -0
- package/dist/api/brepjs-compat/planeOps.d.ts.map +1 -0
- package/dist/api/brepjs-compat/planeOps.js +170 -0
- package/dist/api/brepjs-compat/planeOps.js.map +1 -0
- package/dist/api/brepjs-compat/planeTypes.d.ts +24 -0
- package/dist/api/brepjs-compat/planeTypes.d.ts.map +1 -0
- package/dist/api/brepjs-compat/planeTypes.js +8 -0
- package/dist/api/brepjs-compat/planeTypes.js.map +1 -0
- package/dist/api/brepjs-compat/types.d.ts +64 -0
- package/dist/api/brepjs-compat/types.d.ts.map +1 -0
- package/dist/api/brepjs-compat/types.js +48 -0
- package/dist/api/brepjs-compat/types.js.map +1 -0
- package/dist/api/brepjs-compat/vecOps.d.ts +124 -0
- package/dist/api/brepjs-compat/vecOps.d.ts.map +1 -0
- package/dist/api/brepjs-compat/vecOps.js +202 -0
- package/dist/api/brepjs-compat/vecOps.js.map +1 -0
- package/dist/api/chamfer.d.ts +12 -3
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +54 -20
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/compound-geom.d.ts.map +1 -1
- package/dist/api/compound-geom.js +8 -2
- package/dist/api/compound-geom.js.map +1 -1
- package/dist/api/draft.d.ts +69 -0
- package/dist/api/draft.d.ts.map +1 -0
- package/dist/api/draft.js +109 -0
- package/dist/api/draft.js.map +1 -0
- package/dist/api/edge-ref.d.ts.map +1 -1
- package/dist/api/edge-ref.js +2 -2
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/engrave.d.ts.map +1 -1
- package/dist/api/engrave.js +2 -3
- package/dist/api/engrave.js.map +1 -1
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +44 -14
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts.map +1 -1
- package/dist/api/face-ref.js +2 -2
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/feature-repair.d.ts +137 -0
- package/dist/api/feature-repair.d.ts.map +1 -0
- package/dist/api/feature-repair.js +221 -0
- package/dist/api/feature-repair.js.map +1 -0
- package/dist/api/fillet-variable.d.ts +35 -0
- package/dist/api/fillet-variable.d.ts.map +1 -0
- package/dist/api/fillet-variable.js +71 -0
- package/dist/api/fillet-variable.js.map +1 -0
- package/dist/api/fillet.d.ts +3 -0
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +7 -4
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/generated/2d.d.ts +1 -13
- package/dist/api/generated/2d.d.ts.map +1 -1
- package/dist/api/generated/2d.js +6 -1
- package/dist/api/generated/2d.js.map +1 -1
- package/dist/api/generated/brepjs/index.d.ts +298 -298
- package/dist/api/generated/brepjs/index.d.ts.map +1 -1
- package/dist/api/generated/brepjs/index.js +183 -183
- package/dist/api/generated/brepjs/index.js.map +1 -1
- package/dist/api/generated/core.d.ts +3 -123
- package/dist/api/generated/core.d.ts.map +1 -1
- package/dist/api/generated/core.js +2 -81
- package/dist/api/generated/core.js.map +1 -1
- package/dist/api/generated/gear.d.ts +1 -15
- package/dist/api/generated/gear.d.ts.map +1 -1
- package/dist/api/generated/gear.js +6 -3
- package/dist/api/generated/gear.js.map +1 -1
- package/dist/api/generated/io.d.ts +1 -13
- package/dist/api/generated/io.d.ts.map +1 -1
- package/dist/api/generated/io.js +6 -1
- package/dist/api/generated/io.js.map +1 -1
- package/dist/api/generated/kernel.d.ts +1 -39
- package/dist/api/generated/kernel.d.ts.map +1 -1
- package/dist/api/generated/kernel.js +6 -4
- package/dist/api/generated/kernel.js.map +1 -1
- package/dist/api/generated/measurement.d.ts +53 -97
- package/dist/api/generated/measurement.d.ts.map +1 -1
- package/dist/api/generated/measurement.js +48 -143
- package/dist/api/generated/measurement.js.map +1 -1
- package/dist/api/generated/ns.d.ts +1 -10
- package/dist/api/generated/ns.d.ts.map +1 -1
- package/dist/api/generated/ns.js +2 -10
- package/dist/api/generated/ns.js.map +1 -1
- package/dist/api/generated/operations.d.ts +65 -110
- package/dist/api/generated/operations.d.ts.map +1 -1
- package/dist/api/generated/operations.js +132 -80
- package/dist/api/generated/operations.js.map +1 -1
- package/dist/api/generated/projection.d.ts +1 -8
- package/dist/api/generated/projection.d.ts.map +1 -1
- package/dist/api/generated/projection.js +6 -4
- package/dist/api/generated/projection.js.map +1 -1
- package/dist/api/generated/query.d.ts +1 -9
- package/dist/api/generated/query.d.ts.map +1 -1
- package/dist/api/generated/query.js +6 -1
- package/dist/api/generated/query.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts +2 -0
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.js +22 -10
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/generated/script-face.d.ts +52 -27
- package/dist/api/generated/script-face.d.ts.map +1 -1
- package/dist/api/generated/script-face.js +18 -4
- package/dist/api/generated/script-face.js.map +1 -1
- package/dist/api/generated/sketching.d.ts +4 -7
- package/dist/api/generated/sketching.d.ts.map +1 -1
- package/dist/api/generated/sketching.js +10 -8
- package/dist/api/generated/sketching.js.map +1 -1
- package/dist/api/generated/text.d.ts +1 -6
- package/dist/api/generated/text.d.ts.map +1 -1
- package/dist/api/generated/text.js +6 -3
- package/dist/api/generated/text.js.map +1 -1
- package/dist/api/generated/topology.d.ts +77 -175
- package/dist/api/generated/topology.d.ts.map +1 -1
- package/dist/api/generated/topology.js +172 -131
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/geom.d.ts.map +1 -1
- package/dist/api/geom.js +2 -2
- package/dist/api/geom.js.map +1 -1
- package/dist/api/helix.d.ts +51 -0
- package/dist/api/helix.d.ts.map +1 -0
- package/dist/api/helix.js +63 -0
- package/dist/api/helix.js.map +1 -0
- package/dist/api/import-step.d.ts.map +1 -1
- package/dist/api/import-step.js +6 -2
- package/dist/api/import-step.js.map +1 -1
- package/dist/api/index.d.ts +20 -6
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +30 -13
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-op.d.ts +10 -0
- package/dist/api/internal/compat-op.d.ts.map +1 -1
- package/dist/api/internal/compat-op.js +9 -3
- package/dist/api/internal/compat-op.js.map +1 -1
- package/dist/api/internal/compat-projection.d.ts +4 -4
- package/dist/api/internal/compat-projection.js +7 -7
- package/dist/api/internal/compat-projection.js.map +1 -1
- package/dist/api/internal/l3-bridge.d.ts +75 -42
- package/dist/api/internal/l3-bridge.d.ts.map +1 -1
- package/dist/api/internal/l3-bridge.js +105 -50
- package/dist/api/internal/l3-bridge.js.map +1 -1
- package/dist/api/internal/profile-wire.d.ts +31 -0
- package/dist/api/internal/profile-wire.d.ts.map +1 -0
- package/dist/api/internal/profile-wire.js +37 -0
- package/dist/api/internal/profile-wire.js.map +1 -0
- package/dist/api/internal/replica-role-table.js +2 -2
- package/dist/api/internal/replica-role-table.js.map +1 -1
- package/dist/api/loft.d.ts +66 -0
- package/dist/api/loft.d.ts.map +1 -0
- package/dist/api/loft.js +111 -0
- package/dist/api/loft.js.map +1 -0
- package/dist/api/measurement/index.d.ts +51 -0
- package/dist/api/measurement/index.d.ts.map +1 -0
- package/dist/api/measurement/index.js +71 -0
- package/dist/api/measurement/index.js.map +1 -0
- package/dist/api/occt-kernel-bridge.d.ts +5 -8
- package/dist/api/occt-kernel-bridge.d.ts.map +1 -1
- package/dist/api/occt-kernel-bridge.js +18 -14
- package/dist/api/occt-kernel-bridge.js.map +1 -1
- package/dist/api/pattern.d.ts.map +1 -1
- package/dist/api/pattern.js +3 -4
- package/dist/api/pattern.js.map +1 -1
- package/dist/api/place.d.ts.map +1 -1
- package/dist/api/place.js +2 -4
- package/dist/api/place.js.map +1 -1
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +3 -4
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/profile.d.ts +89 -0
- package/dist/api/profile.d.ts.map +1 -0
- package/dist/api/profile.js +194 -0
- package/dist/api/profile.js.map +1 -0
- package/dist/api/replicate.d.ts +28 -1
- package/dist/api/replicate.d.ts.map +1 -1
- package/dist/api/replicate.js +34 -23
- package/dist/api/replicate.js.map +1 -1
- package/dist/api/result.d.ts +6 -11
- package/dist/api/result.d.ts.map +1 -1
- package/dist/api/result.js +6 -11
- package/dist/api/result.js.map +1 -1
- package/dist/api/revolve.d.ts.map +1 -1
- package/dist/api/revolve.js +15 -14
- package/dist/api/revolve.js.map +1 -1
- package/dist/api/screw.d.ts +3 -0
- package/dist/api/screw.d.ts.map +1 -1
- package/dist/api/screw.js +9 -4
- package/dist/api/screw.js.map +1 -1
- package/dist/api/sdf.d.ts +1 -1
- package/dist/api/section-by-plane.d.ts +42 -0
- package/dist/api/section-by-plane.d.ts.map +1 -0
- package/dist/api/section-by-plane.js +61 -0
- package/dist/api/section-by-plane.js.map +1 -0
- package/dist/api/shell.d.ts +45 -0
- package/dist/api/shell.d.ts.map +1 -0
- package/dist/api/shell.js +73 -0
- package/dist/api/shell.js.map +1 -0
- package/dist/api/sketch.d.ts +8 -1
- package/dist/api/sketch.d.ts.map +1 -1
- package/dist/api/sketch.js +12 -7
- package/dist/api/sketch.js.map +1 -1
- package/dist/api/split-by-plane.d.ts +41 -0
- package/dist/api/split-by-plane.d.ts.map +1 -0
- package/dist/api/split-by-plane.js +60 -0
- package/dist/api/split-by-plane.js.map +1 -0
- package/dist/api/split.d.ts +6 -1
- package/dist/api/split.d.ts.map +1 -1
- package/dist/api/split.js +23 -9
- package/dist/api/split.js.map +1 -1
- package/dist/api/surface/arg-spec.d.ts +22 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +729 -477
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/sweep.d.ts +55 -0
- package/dist/api/sweep.d.ts.map +1 -0
- package/dist/api/sweep.js +86 -0
- package/dist/api/sweep.js.map +1 -0
- package/dist/api/thicken.d.ts +36 -0
- package/dist/api/thicken.d.ts.map +1 -0
- package/dist/api/thicken.js +55 -0
- package/dist/api/thicken.js.map +1 -0
- package/dist/api/transform.d.ts +8 -0
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +15 -4
- package/dist/api/transform.js.map +1 -1
- package/dist/api/view/cameraFns.d.ts +48 -0
- package/dist/api/view/cameraFns.d.ts.map +1 -0
- package/dist/api/view/cameraFns.js +75 -0
- package/dist/api/view/cameraFns.js.map +1 -0
- package/dist/api/view/projectionPlanes.d.ts +25 -0
- package/dist/api/view/projectionPlanes.d.ts.map +1 -0
- package/dist/api/view/projectionPlanes.js +30 -0
- package/dist/api/view/projectionPlanes.js.map +1 -0
- package/dist/api/view/view-camera.d.ts +2 -2
- package/dist/api/view/view-camera.d.ts.map +1 -1
- package/dist/api/view/view-camera.js +3 -3
- package/dist/api/view/view-camera.js.map +1 -1
- package/dist/api/view/view-projection.d.ts +9 -6
- package/dist/api/view/view-projection.d.ts.map +1 -1
- package/dist/api/view/view-projection.js +132 -65
- package/dist/api/view/view-projection.js.map +1 -1
- package/dist/api/wire.d.ts +45 -0
- package/dist/api/wire.d.ts.map +1 -0
- package/dist/api/wire.js +96 -0
- package/dist/api/wire.js.map +1 -0
- package/dist/boolean/creased-normals.d.ts +50 -0
- package/dist/boolean/creased-normals.d.ts.map +1 -0
- package/dist/boolean/creased-normals.js +114 -0
- package/dist/boolean/creased-normals.js.map +1 -0
- package/dist/boolean/deriveNormals.d.ts +4 -1
- package/dist/boolean/deriveNormals.d.ts.map +1 -1
- package/dist/boolean/deriveNormals.js +5 -2
- package/dist/boolean/deriveNormals.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +6 -0
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +11 -2
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/brep-topology.d.ts +4 -0
- package/dist/brep/brep-topology.d.ts.map +1 -1
- package/dist/brep/brep-topology.js +4 -0
- package/dist/brep/brep-topology.js.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +79 -59
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brepkit.js +35 -2
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts +15 -7
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +64 -167
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +93 -130
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js +9 -7
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/types.d.ts +14 -1
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js +11 -1
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brep/export/step.d.ts +3 -0
- package/dist/brep/export/step.d.ts.map +1 -1
- package/dist/brep/export/step.js +7 -1
- package/dist/brep/export/step.js.map +1 -1
- package/dist/brep/face-evolution.d.ts +8 -0
- package/dist/brep/face-evolution.d.ts.map +1 -1
- package/dist/brep/face-evolution.js +15 -3
- package/dist/brep/face-evolution.js.map +1 -1
- package/dist/brep/handle-bridge.d.ts +20 -2
- package/dist/brep/handle-bridge.d.ts.map +1 -1
- package/dist/brep/handle-bridge.js +25 -2
- package/dist/brep/handle-bridge.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +25 -5
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +782 -218
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/brepkit-kernel/multi-version-test.d.ts +40 -0
- package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -0
- package/dist/brepkit-kernel/multi-version-test.js +89 -0
- package/dist/brepkit-kernel/multi-version-test.js.map +1 -0
- package/dist/cad-runtime/admit-compat-lib.d.ts +6 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +5 -1
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +9 -3
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +32 -2
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +8 -2
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +3 -0
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +3 -1
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +18 -2
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +29 -1
- package/dist/define-op.js.map +1 -1
- package/dist/env-agnostic.d.ts +3 -0
- package/dist/env-agnostic.d.ts.map +1 -1
- package/dist/env-agnostic.js +7 -0
- package/dist/env-agnostic.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/lang/symbol-table.generated.d.ts +29 -1
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +30 -2
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
- package/dist/occt-kernel/highLevelApi.js +6 -3
- package/dist/occt-kernel/highLevelApi.js.map +1 -1
- package/dist/occt-kernel/hullGeometry.d.ts +31 -0
- package/dist/occt-kernel/hullGeometry.d.ts.map +1 -0
- package/dist/occt-kernel/hullGeometry.js +319 -0
- package/dist/occt-kernel/hullGeometry.js.map +1 -0
- package/dist/occt-kernel/hullOps.d.ts +24 -0
- package/dist/occt-kernel/hullOps.d.ts.map +1 -0
- package/dist/occt-kernel/hullOps.js +52 -0
- package/dist/occt-kernel/hullOps.js.map +1 -0
- package/dist/occt-kernel/occt-primitives.d.ts +14 -0
- package/dist/occt-kernel/occt-primitives.d.ts.map +1 -0
- package/dist/occt-kernel/occt-primitives.js +351 -0
- package/dist/occt-kernel/occt-primitives.js.map +1 -0
- package/dist/occt-kernel/occtKernel.d.ts +14 -6
- package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
- package/dist/occt-kernel/occtKernel.js +11 -3
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-kernel/topologyExt.js +2 -2
- package/dist/occt-kernel/topologyExt.js.map +1 -1
- package/dist/primitives/brep-primitives.d.ts +4 -0
- package/dist/primitives/brep-primitives.d.ts.map +1 -1
- package/dist/primitives/brep-primitives.js +4 -0
- package/dist/primitives/brep-primitives.js.map +1 -1
- package/dist/result/bug.d.ts +22 -0
- package/dist/result/bug.d.ts.map +1 -0
- package/dist/result/bug.js +28 -0
- package/dist/result/bug.js.map +1 -0
- package/dist/result/errors.d.ts +270 -0
- package/dist/result/errors.d.ts.map +1 -0
- package/dist/result/errors.js +317 -0
- package/dist/result/errors.js.map +1 -0
- package/dist/result/kernelErrorTranslation.d.ts +21 -0
- package/dist/result/kernelErrorTranslation.d.ts.map +1 -0
- package/dist/result/kernelErrorTranslation.js +102 -0
- package/dist/result/kernelErrorTranslation.js.map +1 -0
- package/dist/result/result.d.ts +213 -0
- package/dist/result/result.d.ts.map +1 -0
- package/dist/result/result.js +336 -0
- package/dist/result/result.js.map +1 -0
- package/dist/result/vec3.d.ts +12 -0
- package/dist/result/vec3.d.ts.map +1 -0
- package/dist/result/vec3.js +14 -0
- package/dist/result/vec3.js.map +1 -0
- package/dist/runtime-state.d.ts +9 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +3 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +2 -1
- package/dist/sdk.js.map +1 -1
- package/dist/shape.d.ts +43 -1
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +57 -1
- package/dist/shape.js.map +1 -1
- package/dist/topology/naming/geom-hint.js +1 -1
- package/dist/topology/naming/geom-hint.js.map +1 -1
- package/dist/topology/naming/score.js +1 -1
- package/dist/topology/naming/score.js.map +1 -1
- package/package.json +6 -16
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire.js","sourceRoot":"","sources":["../../src/api/wire.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib wire — 从点列构造 1D 曲线(折线 / 闭合轮廓 / 平滑样条)\n *\n * 用途:脚本面造线能力(G-D 门控层,Phase 3)。下游 sweep / loft / twistExtrude /\n * complexExtrude / roof 等 11 个动作都需要 wire 输入;此前脚本面造不出 wire,这些动作\n * 即使登记也喂不进输入。\n *\n * 设计:\n * - 中立 op(dual-path):mesh 路径用折线 mesh 包成 `curve(mesh)`;brep 路径用 L1 构造\n * (makeLineEdge / interpolatePoints + makeWire),经 `fromBrepCurve` 登记 1D 句柄。\n * 两种 mode 下 kind 都取 'curve',避免随 mode 漂移(§7.1 建议 1 / 附带子项②推荐 (i))。\n * - 无输入(creator),故 dispatch 走 mesh(mode=mesh)或 brep(mode=brep/auto 有 brep 实现)。\n * - 1D 产物命名取 unmodeled(无面 → 无 roleTable,先例 torus/convexHull)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport type { BrepHandle, BrepVec3 } from '../brep/engine/types'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { solidToShape } from '../brep/brep-ops'\nimport { curve, fromBrepCurve } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\n\n/** 一个 3D 点(点列成员)。 */\nexport type WirePoint = [number, number, number]\n\n/** `cad.wire` 选项:折线 / 闭合轮廓 / 平滑曲线。 */\nexport interface WireOptions {\n /** 闭合轮廓:首尾相连。 */\n closed?: boolean\n /** 平滑曲线:经 interpolatePoints 走 B-样条穿过全部点(默认折线)。 */\n smooth?: boolean\n /** smooth 时的样条次数(默认 3)。 */\n degree?: number\n}\n\n/** 校验并归一化点列(至少 2 点,每点 [x,y,z])。 */\nfunction normalizePoints(raw: unknown): BrepVec3[] {\n if (!Array.isArray(raw) || raw.length < 2) {\n throw new Error('E_WIRE_TOO_FEW_POINTS: wire requires at least 2 points')\n }\n const pts: BrepVec3[] = []\n for (const p of raw as unknown[]) {\n if (!Array.isArray(p) || p.length < 3) {\n throw new Error('E_WIRE_BAD_POINT: each wire point must be [x, y, z]')\n }\n pts.push({ x: Number(p[0]), y: Number(p[1]), z: Number(p[2]) })\n }\n return pts\n}\n\n/** mesh 路径:折线 mesh 载荷(位置 + 线段索引),包成 curve(kind 维持 'curve')。 */\nfunction wireMesh(points: WirePoint[], opts?: WireOptions): Shape {\n const pts = normalizePoints(points)\n const closed = !!(opts && opts.closed)\n const positions: number[] = []\n for (const p of pts) positions.push(p.x, p.y, p.z)\n if (closed) positions.push(pts[0]!.x, pts[0]!.y, pts[0]!.z)\n const n = pts.length + (closed ? 1 : 0)\n const indices: number[] = []\n for (let i = 0; i < n - 1; i++) indices.push(i, i + 1)\n return curve({ positions: new Float32Array(positions), indices: new Uint32Array(indices) })\n}\n\n/** BREP 路径:点列 → wire(折线或平滑样条),经 fromBrepCurve 登记 1D 句柄。 */\nfunction wireBrep(points: WirePoint[], opts?: WireOptions): Shape {\n const pts = normalizePoints(points)\n const closed = !!(opts && opts.closed)\n const smooth = !!(opts && opts.smooth)\n const kernel: BrepEngineApi = getBrepApi()\n let handle: unknown\n if (smooth && pts.length >= 2) {\n // 平滑曲线:interpolatePoints 返回穿过全部点的 B-样条(曲线/线柄),直接作为 wire 载荷。\n const degree = typeof opts?.degree === 'number' ? opts.degree : 3\n handle = kernel.interpolatePoints(pts, degree)\n } else {\n const edges: BrepHandle[] = []\n const segCount = closed ? pts.length : pts.length - 1\n for (let i = 0; i < segCount; i++) {\n const a = pts[i]!\n const b = pts[(i + 1) % pts.length]!\n edges.push(kernel.makeLineEdge(a, b))\n }\n handle = kernel.makeWire(edges)\n }\n return fromBrepCurve(solidToShape(kernel, handle as BrepHandle), { solid: handle as BrepHandle })\n}\n\n/**\n * 从点列构造 1D 曲线(折线 / 闭合轮廓 / 平滑样条)。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name wire\n * @returns Shape 1D 曲线(kind:'curve',无三角载荷;显示经 wireframe)。\n * @param points - 有序点列 [[x,y,z], ...],至少 2 点。type:Vec3[] required:true\n * @param options.closed - 闭合轮廓(首尾相连)。type:boolean required:false\n * @param options.smooth - 平滑曲线(B-样条穿过全部点,默认折线)。type:boolean required:false\n * @param options.degree - smooth 时的样条次数(默认 3)。type:number required:false\n * @example\n * const w = cad.wire([[0,0,0],[10,0,0],[10,10,0]], { closed: true })\n */\nexport const wire = defineOp({\n mesh(points: WirePoint[], opts?: WireOptions) {\n return wireMesh(points, opts)\n },\n brep(points: WirePoint[], opts?: WireOptions) {\n return wireBrep(points, opts)\n },\n naming: { kind: 'unmodeled', reason: 'construct vocabulary pending Phase 3' } as Provenance,\n})\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* creased-normals.ts — dependency-free creased (folded) normal computation.
|
|
3
|
+
*
|
|
4
|
+
* The engine's own port of three's `toCreasedNormals`
|
|
5
|
+
* (three/examples/jsm/utils/BufferGeometryUtils.js). Why a port instead of an
|
|
6
|
+
* import: the three helper drags the whole `three` package into any consumer
|
|
7
|
+
* (weapp main thread cannot hold two three copies — see 3d_editor weapp plan
|
|
8
|
+
* §1.1.1 "no three via dependency packages"), while the algorithm itself is
|
|
9
|
+
* pure array math.
|
|
10
|
+
*
|
|
11
|
+
* Semantics are aligned with three r162..r184 `toCreasedNormals` line by line:
|
|
12
|
+
* - input is expanded to non-indexed triangles (indexed geometry is unwound);
|
|
13
|
+
* output is always non-indexed (positions count = triangleCount * 3, indices = null);
|
|
14
|
+
* - a face normal is computed per triangle and pushed onto hash buckets of its
|
|
15
|
+
* 3 vertices (hash = trunc(x * 100 * (1 + 1e-10)) per component, same
|
|
16
|
+
* quantization as three's `hashVertex`);
|
|
17
|
+
* - each vertex normal = normalize(sum of bucket normals whose dot with the
|
|
18
|
+
* face normal exceeds cos(creaseAngleDeg)) — sharp edges split, smooth
|
|
19
|
+
* surfaces (drill walls) stay averaged;
|
|
20
|
+
* - degenerate (zero-area) faces yield NaN normals exactly like three's
|
|
21
|
+
* divide-by-zero; callers treat that as invalid geometry upstream.
|
|
22
|
+
*/
|
|
23
|
+
export interface CreasedNormalsInput {
|
|
24
|
+
/** Triangle positions, xyz interleaved, length = n * 3. */
|
|
25
|
+
positions: Float32Array;
|
|
26
|
+
/** Triangle vertex indices, length = n * 3 (n = triangle count). `null` = sequential. */
|
|
27
|
+
indices: Uint32Array | null;
|
|
28
|
+
/** Dihedral-angle threshold in degrees above which normals split (default 60). */
|
|
29
|
+
creaseAngleDeg?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creased-normals computation input/output (dependency-free surface).
|
|
33
|
+
*/
|
|
34
|
+
export interface CreasedNormalsResult {
|
|
35
|
+
/** Non-indexed positions (indexed input is expanded). */
|
|
36
|
+
positions: Float32Array;
|
|
37
|
+
/** Per-vertex creased normals, xyz interleaved. */
|
|
38
|
+
normals: Float32Array;
|
|
39
|
+
/** Always null — creased normals cannot be expressed on shared vertices. */
|
|
40
|
+
indices: null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Derive creased (folded) normals from raw triangle data — the dependency-free
|
|
44
|
+
* equivalent of three's `toCreasedNormals`. See the module header for the
|
|
45
|
+
* aligned semantics.
|
|
46
|
+
* @param input - positions (+ optional indices) and the crease angle threshold.
|
|
47
|
+
* @returns non-indexed positions plus per-vertex creased normals.
|
|
48
|
+
*/
|
|
49
|
+
export declare function deriveCreasedNormalsData(input: CreasedNormalsInput): CreasedNormalsResult;
|
|
50
|
+
//# sourceMappingURL=creased-normals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"creased-normals.d.ts","sourceRoot":"","sources":["../../src/boolean/creased-normals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,SAAS,EAAE,YAAY,CAAA;IACvB,yFAAyF;IACzF,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;IAC3B,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,SAAS,EAAE,YAAY,CAAA;IACvB,mDAAmD;IACnD,OAAO,EAAE,YAAY,CAAA;IACrB,4EAA4E;IAC5E,OAAO,EAAE,IAAI,CAAA;CACd;AAYD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CA8EzF"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* creased-normals.ts — dependency-free creased (folded) normal computation.
|
|
3
|
+
*
|
|
4
|
+
* The engine's own port of three's `toCreasedNormals`
|
|
5
|
+
* (three/examples/jsm/utils/BufferGeometryUtils.js). Why a port instead of an
|
|
6
|
+
* import: the three helper drags the whole `three` package into any consumer
|
|
7
|
+
* (weapp main thread cannot hold two three copies — see 3d_editor weapp plan
|
|
8
|
+
* §1.1.1 "no three via dependency packages"), while the algorithm itself is
|
|
9
|
+
* pure array math.
|
|
10
|
+
*
|
|
11
|
+
* Semantics are aligned with three r162..r184 `toCreasedNormals` line by line:
|
|
12
|
+
* - input is expanded to non-indexed triangles (indexed geometry is unwound);
|
|
13
|
+
* output is always non-indexed (positions count = triangleCount * 3, indices = null);
|
|
14
|
+
* - a face normal is computed per triangle and pushed onto hash buckets of its
|
|
15
|
+
* 3 vertices (hash = trunc(x * 100 * (1 + 1e-10)) per component, same
|
|
16
|
+
* quantization as three's `hashVertex`);
|
|
17
|
+
* - each vertex normal = normalize(sum of bucket normals whose dot with the
|
|
18
|
+
* face normal exceeds cos(creaseAngleDeg)) — sharp edges split, smooth
|
|
19
|
+
* surfaces (drill walls) stay averaged;
|
|
20
|
+
* - degenerate (zero-area) faces yield NaN normals exactly like three's
|
|
21
|
+
* divide-by-zero; callers treat that as invalid geometry upstream.
|
|
22
|
+
*/
|
|
23
|
+
const HASH_MULTIPLIER = (1 + 1e-10) * 1e2;
|
|
24
|
+
function hashVertex(x, y, z) {
|
|
25
|
+
// Same truncation semantics as three: `~~` (32-bit trunc) on scaled coords.
|
|
26
|
+
const hx = ~~(x * HASH_MULTIPLIER);
|
|
27
|
+
const hy = ~~(y * HASH_MULTIPLIER);
|
|
28
|
+
const hz = ~~(z * HASH_MULTIPLIER);
|
|
29
|
+
return `${hx},${hy},${hz}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Derive creased (folded) normals from raw triangle data — the dependency-free
|
|
33
|
+
* equivalent of three's `toCreasedNormals`. See the module header for the
|
|
34
|
+
* aligned semantics.
|
|
35
|
+
* @param input - positions (+ optional indices) and the crease angle threshold.
|
|
36
|
+
* @returns non-indexed positions plus per-vertex creased normals.
|
|
37
|
+
*/
|
|
38
|
+
export function deriveCreasedNormalsData(input) {
|
|
39
|
+
const { indices, creaseAngleDeg = 60 } = input;
|
|
40
|
+
const srcPos = input.positions;
|
|
41
|
+
const triCount = indices ? indices.length / 3 : srcPos.length / 9;
|
|
42
|
+
// Expand to non-indexed triangles (three: geometry.toNonIndexed()).
|
|
43
|
+
const pos = new Float32Array(triCount * 9);
|
|
44
|
+
for (let t = 0; t < triCount; t++) {
|
|
45
|
+
for (let v = 0; v < 3; v++) {
|
|
46
|
+
const srcIdx = indices ? indices[t * 3 + v] : t * 3 + v;
|
|
47
|
+
pos[t * 9 + v * 3 + 0] = srcPos[srcIdx * 3 + 0];
|
|
48
|
+
pos[t * 9 + v * 3 + 1] = srcPos[srcIdx * 3 + 1];
|
|
49
|
+
pos[t * 9 + v * 3 + 2] = srcPos[srcIdx * 3 + 2];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const creaseDot = Math.cos((creaseAngleDeg * Math.PI) / 180);
|
|
53
|
+
// Pass 1: face normals into per-vertex hash buckets.
|
|
54
|
+
const vertexMap = new Map();
|
|
55
|
+
const fnx = new Float32Array(triCount);
|
|
56
|
+
const fny = new Float32Array(triCount);
|
|
57
|
+
const fnz = new Float32Array(triCount);
|
|
58
|
+
for (let t = 0; t < triCount; t++) {
|
|
59
|
+
const ax = pos[t * 9 + 0], ay = pos[t * 9 + 1], az = pos[t * 9 + 2];
|
|
60
|
+
const bx = pos[t * 9 + 3], by = pos[t * 9 + 4], bz = pos[t * 9 + 5];
|
|
61
|
+
const cx = pos[t * 9 + 6], cy = pos[t * 9 + 7], cz = pos[t * 9 + 8];
|
|
62
|
+
// cb = c - b, ab = a - b; normal = cb × ab (same edge order as three).
|
|
63
|
+
const e1x = cx - bx, e1y = cy - by, e1z = cz - bz;
|
|
64
|
+
const e2x = ax - bx, e2y = ay - by, e2z = az - bz;
|
|
65
|
+
let nx = e1y * e2z - e1z * e2y;
|
|
66
|
+
let ny = e1z * e2x - e1x * e2z;
|
|
67
|
+
let nz = e1x * e2y - e1y * e2x;
|
|
68
|
+
const len = Math.sqrt(nx * nx + ny * ny + nz * nz);
|
|
69
|
+
if (len > 0) {
|
|
70
|
+
nx /= len;
|
|
71
|
+
ny /= len;
|
|
72
|
+
nz /= len;
|
|
73
|
+
}
|
|
74
|
+
fnx[t] = nx;
|
|
75
|
+
fny[t] = ny;
|
|
76
|
+
fnz[t] = nz;
|
|
77
|
+
for (let v = 0; v < 3; v++) {
|
|
78
|
+
const h = hashVertex(pos[t * 9 + v * 3], pos[t * 9 + v * 3 + 1], pos[t * 9 + v * 3 + 2]);
|
|
79
|
+
let bucket = vertexMap.get(h);
|
|
80
|
+
if (!bucket) {
|
|
81
|
+
bucket = [];
|
|
82
|
+
vertexMap.set(h, bucket);
|
|
83
|
+
}
|
|
84
|
+
bucket.push([nx, ny, nz]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Pass 2: average bucket normals within the crease threshold.
|
|
88
|
+
const normals = new Float32Array(triCount * 9);
|
|
89
|
+
for (let t = 0; t < triCount; t++) {
|
|
90
|
+
for (let v = 0; v < 3; v++) {
|
|
91
|
+
const h = hashVertex(pos[t * 9 + v * 3], pos[t * 9 + v * 3 + 1], pos[t * 9 + v * 3 + 2]);
|
|
92
|
+
const bucket = vertexMap.get(h);
|
|
93
|
+
let sx = 0, sy = 0, sz = 0;
|
|
94
|
+
for (let k = 0; k < bucket.length; k++) {
|
|
95
|
+
const on = bucket[k];
|
|
96
|
+
// Three uses `>` (strictly greater) — coplanar neighbours merge,
|
|
97
|
+
// faces at exactly the crease angle do not.
|
|
98
|
+
if (fnx[t] * on[0] + fny[t] * on[1] + fnz[t] * on[2] > creaseDot) {
|
|
99
|
+
sx += on[0];
|
|
100
|
+
sy += on[1];
|
|
101
|
+
sz += on[2];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const sl = Math.sqrt(sx * sx + sy * sy + sz * sz);
|
|
105
|
+
// Divide unconditionally: a zero-length sum yields NaN, matching three's
|
|
106
|
+
// divide-by-zero behavior on degenerate geometry.
|
|
107
|
+
normals[t * 9 + v * 3 + 0] = sx / sl;
|
|
108
|
+
normals[t * 9 + v * 3 + 1] = sy / sl;
|
|
109
|
+
normals[t * 9 + v * 3 + 2] = sz / sl;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { positions: pos, normals, indices: null };
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=creased-normals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"creased-normals.js","sourceRoot":"","sources":["../../src/boolean/creased-normals.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * creased-normals.ts — dependency-free creased (folded) normal computation.\n *\n * The engine's own port of three's `toCreasedNormals`\n * (three/examples/jsm/utils/BufferGeometryUtils.js). Why a port instead of an\n * import: the three helper drags the whole `three` package into any consumer\n * (weapp main thread cannot hold two three copies — see 3d_editor weapp plan\n * §1.1.1 \"no three via dependency packages\"), while the algorithm itself is\n * pure array math.\n *\n * Semantics are aligned with three r162..r184 `toCreasedNormals` line by line:\n * - input is expanded to non-indexed triangles (indexed geometry is unwound);\n * output is always non-indexed (positions count = triangleCount * 3, indices = null);\n * - a face normal is computed per triangle and pushed onto hash buckets of its\n * 3 vertices (hash = trunc(x * 100 * (1 + 1e-10)) per component, same\n * quantization as three's `hashVertex`);\n * - each vertex normal = normalize(sum of bucket normals whose dot with the\n * face normal exceeds cos(creaseAngleDeg)) — sharp edges split, smooth\n * surfaces (drill walls) stay averaged;\n * - degenerate (zero-area) faces yield NaN normals exactly like three's\n * divide-by-zero; callers treat that as invalid geometry upstream.\n */\n\nexport interface CreasedNormalsInput {\n /** Triangle positions, xyz interleaved, length = n * 3. */\n positions: Float32Array\n /** Triangle vertex indices, length = n * 3 (n = triangle count). `null` = sequential. */\n indices: Uint32Array | null\n /** Dihedral-angle threshold in degrees above which normals split (default 60). */\n creaseAngleDeg?: number\n}\n\n/**\n * Creased-normals computation input/output (dependency-free surface).\n */\nexport interface CreasedNormalsResult {\n /** Non-indexed positions (indexed input is expanded). */\n positions: Float32Array\n /** Per-vertex creased normals, xyz interleaved. */\n normals: Float32Array\n /** Always null — creased normals cannot be expressed on shared vertices. */\n indices: null\n}\n\nconst HASH_MULTIPLIER = (1 + 1e-10) * 1e2\n\nfunction hashVertex(x: number, y: number, z: number): string {\n // Same truncation semantics as three: `~~` (32-bit trunc) on scaled coords.\n const hx = ~~(x * HASH_MULTIPLIER)\n const hy = ~~(y * HASH_MULTIPLIER)\n const hz = ~~(z * HASH_MULTIPLIER)\n return `${hx},${hy},${hz}`\n}\n\n/**\n * Derive creased (folded) normals from raw triangle data — the dependency-free\n * equivalent of three's `toCreasedNormals`. See the module header for the\n * aligned semantics.\n * @param input - positions (+ optional indices) and the crease angle threshold.\n * @returns non-indexed positions plus per-vertex creased normals.\n */\nexport function deriveCreasedNormalsData(input: CreasedNormalsInput): CreasedNormalsResult {\n const { indices, creaseAngleDeg = 60 } = input\n const srcPos = input.positions\n\n const triCount = indices ? indices.length / 3 : srcPos.length / 9\n\n // Expand to non-indexed triangles (three: geometry.toNonIndexed()).\n const pos = new Float32Array(triCount * 9)\n for (let t = 0; t < triCount; t++) {\n for (let v = 0; v < 3; v++) {\n const srcIdx = indices ? indices[t * 3 + v] : t * 3 + v\n pos[t * 9 + v * 3 + 0] = srcPos[srcIdx * 3 + 0]\n pos[t * 9 + v * 3 + 1] = srcPos[srcIdx * 3 + 1]\n pos[t * 9 + v * 3 + 2] = srcPos[srcIdx * 3 + 2]\n }\n }\n\n const creaseDot = Math.cos((creaseAngleDeg * Math.PI) / 180)\n\n // Pass 1: face normals into per-vertex hash buckets.\n const vertexMap = new Map<string, number[][]>()\n const fnx = new Float32Array(triCount)\n const fny = new Float32Array(triCount)\n const fnz = new Float32Array(triCount)\n\n for (let t = 0; t < triCount; t++) {\n const ax = pos[t * 9 + 0], ay = pos[t * 9 + 1], az = pos[t * 9 + 2]\n const bx = pos[t * 9 + 3], by = pos[t * 9 + 4], bz = pos[t * 9 + 5]\n const cx = pos[t * 9 + 6], cy = pos[t * 9 + 7], cz = pos[t * 9 + 8]\n\n // cb = c - b, ab = a - b; normal = cb × ab (same edge order as three).\n const e1x = cx - bx, e1y = cy - by, e1z = cz - bz\n const e2x = ax - bx, e2y = ay - by, e2z = az - bz\n let nx = e1y * e2z - e1z * e2y\n let ny = e1z * e2x - e1x * e2z\n let nz = e1x * e2y - e1y * e2x\n const len = Math.sqrt(nx * nx + ny * ny + nz * nz)\n if (len > 0) {\n nx /= len; ny /= len; nz /= len\n }\n fnx[t] = nx; fny[t] = ny; fnz[t] = nz\n\n for (let v = 0; v < 3; v++) {\n const h = hashVertex(pos[t * 9 + v * 3], pos[t * 9 + v * 3 + 1], pos[t * 9 + v * 3 + 2])\n let bucket = vertexMap.get(h)\n if (!bucket) {\n bucket = []\n vertexMap.set(h, bucket)\n }\n bucket.push([nx, ny, nz])\n }\n }\n\n // Pass 2: average bucket normals within the crease threshold.\n const normals = new Float32Array(triCount * 9)\n for (let t = 0; t < triCount; t++) {\n for (let v = 0; v < 3; v++) {\n const h = hashVertex(pos[t * 9 + v * 3], pos[t * 9 + v * 3 + 1], pos[t * 9 + v * 3 + 2])\n const bucket = vertexMap.get(h)!\n let sx = 0, sy = 0, sz = 0\n for (let k = 0; k < bucket.length; k++) {\n const on = bucket[k]\n // Three uses `>` (strictly greater) — coplanar neighbours merge,\n // faces at exactly the crease angle do not.\n if (fnx[t] * on[0] + fny[t] * on[1] + fnz[t] * on[2] > creaseDot) {\n sx += on[0]; sy += on[1]; sz += on[2]\n }\n }\n const sl = Math.sqrt(sx * sx + sy * sy + sz * sz)\n // Divide unconditionally: a zero-length sum yields NaN, matching three's\n // divide-by-zero behavior on degenerate geometry.\n normals[t * 9 + v * 3 + 0] = sx / sl\n normals[t * 9 + v * 3 + 1] = sy / sl\n normals[t * 9 + v * 3 + 2] = sz / sl\n }\n }\n\n return { positions: pos, normals, indices: null }\n}\n"]}
|
|
@@ -6,7 +6,10 @@ import { BufferGeometry } from 'three';
|
|
|
6
6
|
* 几何**上会把相邻三角面的法线取平均 → 棱边被"磨圆"。这正是钻孔/布尔/分割操作后
|
|
7
7
|
* model visual anomalies after drilling/boolean/split operations.
|
|
8
8
|
*
|
|
9
|
-
* 算法本体在
|
|
9
|
+
* 算法本体在 `./creased-normals`(零依赖移植 three 的 toCreasedNormals;本文件只是
|
|
10
|
+
* BufferGeometry ↔ 数据的薄适配)。场景内核(scene-kernel)消费同算法的数据版
|
|
11
|
+
* `deriveCreasedNormalsData`——经 `@faicad/faijs/env-agnostic` 导出、不 import three,
|
|
12
|
+
* 避免经依赖包间接引入第二份 three(weapp 方案 §1.1.1):
|
|
10
13
|
* 锐边处"裂开"法线 → 锐边保持锐利,仅对近共面 / 真实曲面(如钻孔内壁)平滑。
|
|
11
14
|
* 输入若是索引几何会被展开为非索引(单条法线属性无法在共享顶点上表达锐边),
|
|
12
15
|
* 因此返回的几何**可能是非索引的**——这是预期且正确的表示,且与 STL 源零件
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveNormals.d.ts","sourceRoot":"","sources":["../../src/boolean/deriveNormals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,OAAO,CAAA;AAGvD
|
|
1
|
+
{"version":3,"file":"deriveNormals.d.ts","sourceRoot":"","sources":["../../src/boolean/deriveNormals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,OAAO,CAAA;AAGvD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,cAAc,SAAK,GAAG,cAAc,CAoB3F"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BufferGeometry, BufferAttribute } from 'three';
|
|
2
|
-
import { deriveCreasedNormalsData } from '
|
|
2
|
+
import { deriveCreasedNormalsData } from './creased-normals.js';
|
|
3
3
|
/**
|
|
4
4
|
* 统一的法线派生函数(折边法线)。
|
|
5
5
|
*
|
|
@@ -7,7 +7,10 @@ import { deriveCreasedNormalsData } from '../mesh/creased-normals.js';
|
|
|
7
7
|
* 几何**上会把相邻三角面的法线取平均 → 棱边被"磨圆"。这正是钻孔/布尔/分割操作后
|
|
8
8
|
* model visual anomalies after drilling/boolean/split operations.
|
|
9
9
|
*
|
|
10
|
-
* 算法本体在
|
|
10
|
+
* 算法本体在 `./creased-normals`(零依赖移植 three 的 toCreasedNormals;本文件只是
|
|
11
|
+
* BufferGeometry ↔ 数据的薄适配)。场景内核(scene-kernel)消费同算法的数据版
|
|
12
|
+
* `deriveCreasedNormalsData`——经 `@faicad/faijs/env-agnostic` 导出、不 import three,
|
|
13
|
+
* 避免经依赖包间接引入第二份 three(weapp 方案 §1.1.1):
|
|
11
14
|
* 锐边处"裂开"法线 → 锐边保持锐利,仅对近共面 / 真实曲面(如钻孔内壁)平滑。
|
|
12
15
|
* 输入若是索引几何会被展开为非索引(单条法线属性无法在共享顶点上表达锐边),
|
|
13
16
|
* 因此返回的几何**可能是非索引的**——这是预期且正确的表示,且与 STL 源零件
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveNormals.js","sourceRoot":"","sources":["../../src/boolean/deriveNormals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"deriveNormals.js","sourceRoot":"","sources":["../../src/boolean/deriveNormals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAE5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,aAAa,CAAC,QAAwB,EAAE,cAAc,GAAG,EAAE;IACzE,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAgC,CAAA;IAChF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;IACvE,CAAC;IACD,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAA;IACrC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAqB,CAAA;IAC/C,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAE,SAAS,CAAC,KAA2B,CAAC,CAAC,CAAC,IAAI,CAAA;IAEzE,MAAM,MAAM,GAAG,wBAAwB,CAAC;QACtC,SAAS;QACT,wEAAwE;QACxE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI;QAClD,cAAc;KACf,CAAC,CAAA;IAEF,MAAM,GAAG,GAAG,IAAI,cAAc,EAAE,CAAA;IAChC,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;IACtE,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;IACzE,OAAO,GAAG,CAAA;AACZ,CAAC","sourcesContent":["import { BufferGeometry, BufferAttribute } from 'three'\nimport { deriveCreasedNormalsData } from './creased-normals'\n\n/**\n * 统一的法线派生函数(折边法线)。\n *\n * 取代散落在各处的 `geometry.computeVertexNormals()`。后者在**索引(共享顶点)\n * 几何**上会把相邻三角面的法线取平均 → 棱边被\"磨圆\"。这正是钻孔/布尔/分割操作后\n * model visual anomalies after drilling/boolean/split operations.\n *\n * 算法本体在 `./creased-normals`(零依赖移植 three 的 toCreasedNormals;本文件只是\n * BufferGeometry ↔ 数据的薄适配)。场景内核(scene-kernel)消费同算法的数据版\n * `deriveCreasedNormalsData`——经 `@faicad/faijs/env-agnostic` 导出、不 import three,\n * 避免经依赖包间接引入第二份 three(weapp 方案 §1.1.1):\n * 锐边处\"裂开\"法线 → 锐边保持锐利,仅对近共面 / 真实曲面(如钻孔内壁)平滑。\n * 输入若是索引几何会被展开为非索引(单条法线属性无法在共享顶点上表达锐边),\n * 因此返回的几何**可能是非索引的**——这是预期且正确的表示,且与 STL 源零件\n * 本就是非索引一致,使各格式往返统一。\n *\n * 约定:项目中所有\"需要派生法线\"之处(操作结果、STL/3MF 导入)都经此函数,\n * 不得再直接调用 `computeVertexNormals()`。\n * @param geometry - the indexed geometry to derive creased (folded) normals for.\n * @param creaseAngleDeg - the dihedral-angle threshold in degrees above which normals are split (default 60).\n * @returns a BufferGeometry with creased normals applied; it may be non-indexed.\n */\nexport function deriveNormals(geometry: BufferGeometry, creaseAngleDeg = 60): BufferGeometry {\n const posAttr = geometry.getAttribute('position') as BufferAttribute | undefined\n if (!posAttr) {\n throw new Error('[deriveNormals] geometry has no position attribute')\n }\n const indexAttr = geometry.getIndex()\n const positions = posAttr.array as Float32Array\n const indices = indexAttr ? (indexAttr.array as ArrayLike<number>) : null\n\n const result = deriveCreasedNormalsData({\n positions,\n // creased-normals expects Uint32Array | null; widen typed index arrays.\n indices: indices ? new Uint32Array(indices) : null,\n creaseAngleDeg,\n })\n\n const out = new BufferGeometry()\n out.setAttribute('position', new BufferAttribute(result.positions, 3))\n out.setAttribute('normal', new BufferAttribute(result.normals, 3, false))\n return out\n}\n"]}
|
package/dist/brep/brep-ops.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 核心 BREP 操作 — 使用 OCCT 精确实体运算
|
|
3
3
|
*
|
|
4
|
+
* @platform occt — 本文件 import occt-kernel:`extrudeBrep` 用原生 `section`
|
|
5
|
+
* (BRepAlgoAPI_Section,occt-only,L1 只有 sectionByPlane)构造截面 → 守卫①
|
|
6
|
+
* 要求平台 import 自证身份。本文件是内部工具面(非 op 文件),文件级标注即满足
|
|
7
|
+
* 守卫;调用方 op 若经本文件触达 occt-only 能力,须在 defineOp 声明 engines
|
|
8
|
+
* (extrudeBrep 的 section 仅 occt 路径可达,brepkit 下由调用方引擎声明拦截)。
|
|
9
|
+
*
|
|
4
10
|
* See docs/api-contract.md §8 (dual-path geometry contract: BREP / Mesh).
|
|
5
11
|
*
|
|
6
12
|
* 与 mesh 路径(transform.ts / boolean/ / drill.ts / split.ts / extrude.ts)对照:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brep-ops.d.ts","sourceRoot":"","sources":["../../src/brep/brep-ops.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"brep-ops.d.ts","sourceRoot":"","sources":["../../src/brep/brep-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,gBAAgB,CAAA;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAK3C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,cAAc,EAC1B,QAAQ,CAAC,EAAE,QAAQ,GAClB,KAAK,CAkBP;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,IAAI,GACX,UAAU,CAEZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,IAAI,EACf,KAAK,CAAC,EAAE,IAAI,GACX,UAAU,CAYZ;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,CAAC,EAAE,IAAI,GACZ,UAAU,CAiBZ;AAID;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC5C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC/B,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GACpC,UAAU,CAWZ;AAID;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,aAAa,EACrB,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,UAAU,GACZ,UAAU,CAEZ;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,aAAa,EACrB,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,UAAU,GACZ,UAAU,CAEZ;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,UAAU,GACZ,UAAU,CAEZ;AAID,oBAAoB;AACpB,MAAM,WAAW,eAAe;IAC9B,UAAU;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB;IAChB,QAAQ,EAAE,IAAI,CAAA;IACd,wBAAwB;IACxB,SAAS,EAAE,IAAI,CAAA;IACf,gBAAgB;IAChB,UAAU,EAAE,IAAI,CAAA;IAChB,UAAU;IACV,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;CAC9B;AAED;;;;;;;;;;;;;GAaG;AACH,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAA;IAClC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAA;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,eAAe,GACtB,aAAa,CAkEf;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,GAAG,UAAU,CAuB1F;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,eAAe,GACtB,UAAU,CAWZ;AAID,oBAAoB;AACpB,MAAM,WAAW,eAAe;IAC9B,aAAa;IACb,MAAM,EAAE,IAAI,CAAA;IACZ,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc;IACd,WAAW,EAAE,IAAI,CAAA;CAClB;AAED,oBAAoB;AACpB,MAAM,WAAW,eAAe;IAC9B,gBAAgB;IAChB,KAAK,EAAE,UAAU,CAAA;IACjB,gBAAgB;IAChB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,eAAe,GACtB,eAAe,CAsDjB;AAID,sBAAsB;AACtB,MAAM,WAAW,iBAAiB;IAChC,aAAa;IACb,MAAM,EAAE,IAAI,CAAA;IACZ,aAAa;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW;IACX,MAAM,EAAE,MAAM,CAAA;IACd,WAAW;IACX,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;CAC3C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,iBAAiB,GACxB,UAAU,CA+IZ;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,WAAW,EACnB,SAAS,CAAC,EAAE,cAAc,EAC1B,MAAM,CAAC,EAAE,QAAQ,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CA4DrC;AAsBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,GAAG,MAAM,EAAE,CAQ7D"}
|
package/dist/brep/brep-ops.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 核心 BREP 操作 — 使用 OCCT 精确实体运算
|
|
3
3
|
*
|
|
4
|
+
* @platform occt — 本文件 import occt-kernel:`extrudeBrep` 用原生 `section`
|
|
5
|
+
* (BRepAlgoAPI_Section,occt-only,L1 只有 sectionByPlane)构造截面 → 守卫①
|
|
6
|
+
* 要求平台 import 自证身份。本文件是内部工具面(非 op 文件),文件级标注即满足
|
|
7
|
+
* 守卫;调用方 op 若经本文件触达 occt-only 能力,须在 defineOp 声明 engines
|
|
8
|
+
* (extrudeBrep 的 section 仅 occt 路径可达,brepkit 下由调用方引擎声明拦截)。
|
|
9
|
+
*
|
|
4
10
|
* See docs/api-contract.md §8 (dual-path geometry contract: BREP / Mesh).
|
|
5
11
|
*
|
|
6
12
|
* 与 mesh 路径(transform.ts / boolean/ / drill.ts / split.ts / extrude.ts)对照:
|
|
@@ -13,6 +19,7 @@
|
|
|
13
19
|
* 坐标系:Z-up、毫米,与 mesh 路径一致。
|
|
14
20
|
*/
|
|
15
21
|
import * as THREE from 'three';
|
|
22
|
+
import { getOcctKernel } from '../occt-kernel/occtKernel.js';
|
|
16
23
|
import { getSolidBoundingBox } from './brep-utils.js';
|
|
17
24
|
// ─── 通用工具 ───
|
|
18
25
|
/**
|
|
@@ -378,8 +385,10 @@ export function extrudeBrep(kernel, solid, params) {
|
|
|
378
385
|
kernel.release(planeRect);
|
|
379
386
|
const planeFace = kernel.transform(centeredRect, matrixToArray(planeMatrix));
|
|
380
387
|
kernel.release(centeredRect);
|
|
381
|
-
//
|
|
382
|
-
|
|
388
|
+
// 获取截面边(occt-only 平台面,D3)。BrepHandle(branded number)与
|
|
389
|
+
// occt-wasm ShapeHandle 运行时同构,品牌转换只发生在平台边界;转回 BrepHandle
|
|
390
|
+
// 后继续用 L1 面(getSubShapes/makeWire/extrude)。
|
|
391
|
+
const sectionEdges = getOcctKernel().section(solid, planeFace);
|
|
383
392
|
kernel.release(planeFace);
|
|
384
393
|
// 4. 构建截面 wire → face → 拉伸
|
|
385
394
|
let extrudedSolid;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brep-ops.js","sourceRoot":"","sources":["../../src/brep/brep-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD,eAAe;AAEf;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAqB,EACrB,KAAiB,EACjB,QAAiB,EACjB,SAA0B,EAC1B,QAAmB;IAEnB,MAAM,iBAAiB,GAAG,QAAQ;QAChC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC;QACvC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAA,CAAC,wCAAwC;IAC/D,MAAM,IAAI,GAAmB,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE;QACnD,gBAAgB,EAAE,GAAG;QACrB,iBAAiB;KAClB,CAAC,CAAA;IAEF,gEAAgE;IAChE,IAAI,SAAS,EAAE,cAAc,IAAI,QAAQ,EAAE,CAAC;QAC1C,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO;QACL,SAAS,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3C,OAAO,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;KACvC,CAAA;AACH,CAAC;AAED,eAAe;AAEf;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAqB,EACrB,KAAiB,EACjB,MAAY;IAEZ,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AACjE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CACxB,MAAqB,EACrB,KAAiB,EACjB,SAAe,EACf,KAAY;IAEZ,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,CAC3B,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,EAC9B,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,EAC9B,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAC/B,CAAA;IACD,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAC/D,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACrF,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvF,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;AACvD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS,CACvB,MAAqB,EACrB,KAAiB,EACjB,MAAqB,EACrB,MAAa;IAEb,MAAM,CAAC,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IACxE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7D,6CAA6C;IAC7C,MAAM,MAAM,GAAG,MAAM;QACnB,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE;aAChB,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;aAChD,QAAQ,CAAC,KAAK,CAAC;aACf,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,CAAC,CAAC,KAAK,CAAA;IACT,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAChD,iEAAiE;IACjE,mEAAmE;IACnE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;IACvD,CAAC;IACD,OAAO,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,eAAe;AAEf;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAqB,EACrB,KAAiB,EACjB,UAA4C,EAC5C,KAA+B,EAC/B,WAAqC;IAErC,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,0BAA0B,CAC7D,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CACjF,CAAA;IACD,mFAAmF;IACnF,2DAA2D;IAC3D,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE;SAC/B,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;SAChG,QAAQ,CAAC,QAAQ,CAAC;SAClB,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACjF,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;AACvD,CAAC;AAED,eAAe;AAEf;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACtB,MAAqB,EACrB,CAAa,EACb,CAAa;IAEb,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CACrB,MAAqB,EACrB,CAAa,EACb,CAAa;IAEb,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACzB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,MAAqB,EACrB,CAAa,EACb,CAAa;IAEb,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC;AA0CD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAqB,EACrB,KAAiB,EACjB,MAAuB;IAEvB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAA;IAClC,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,CAAA;IACpE,aAAa;IACb,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IAC1D,IAAI,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,SAAS,CAAC,MAAM,EAAE,CAAA;IACpB,CAAC;IAED,YAAY;IACZ,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC/C,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,OAAO,CAChC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAC1B,CAAA;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAE5D,IAAI,UAAkB,CAAA;IACtB,IAAI,UAAyB,CAAA;IAC7B,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IAEjD,8EAA8E;IAC9E,4EAA4E;IAC5E,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,CAAA;QACvC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACtE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAEtE,IAAI,KAAK,GAAG,CAAC,QAAQ,CAAA;QACrB,IAAI,IAAI,GAAG,QAAQ,CAAA;QACnB,MAAM,IAAI,GAA4C;YACpD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YAC1B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YAC1B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;SAC3B,CAAA;QACD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;QAClC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;YACtC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;YACrB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC;gBACzB,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAA;gBACzB,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAA;gBACzB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;gBACzC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YACzC,CAAC;iBAAM,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;gBAC9B,yCAAyC;gBACzC,KAAK,GAAG,CAAC,CAAA;gBACT,IAAI,GAAG,CAAC,CAAA;YACV,CAAC;QACH,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;YACxD,kCAAkC;YAClC,UAAU,GAAG,GAAG,CAAA;YAChB,UAAU,GAAG,GAAG,CAAC,KAAK,EAAE,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,CAAA;YAC/B,UAAU,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC,cAAc,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAChG,CAAC;IACH,CAAC;SAAM,CAAC;QACN,gDAAgD;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;QAC9D,UAAU,GAAG,SAAS,CAAA;QACtB,UAAU,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC,cAAc,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAA;IAC3F,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAqB,EAAE,IAAmB;IAC5E,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IAElE,yBAAyB;IACzB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IAC7E,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAA;IAEtE,uCAAuC;IACvC,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CACrD,IAAI,CAAC,UAAU,CAAC,CAAC,EACjB,IAAI,CAAC,UAAU,CAAC,CAAC,EACjB,IAAI,CAAC,UAAU,CAAC,CAAC,CAClB,CAAA;IACD,aAAa;IACb,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAChF,0CAA0C;IAC1C,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;IACpF,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IAElF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,CAAA;IACvE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxB,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,MAAqB,EACrB,KAAiB,EACjB,MAAuB;IAEvB,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IACxD,MAAM,SAAS,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAC3C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACzB,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACzB,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACrH,CAAC;AACH,CAAC;AAsBD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,SAAS,CACvB,MAAqB,EACrB,KAAiB,EACjB,MAAuB;IAEvB,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC/C,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,OAAO,CAChC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAC1B,CAAA;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC5D,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,OAAO,CAClC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAC/B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAC/B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAChC,CAAA;IAED,sBAAsB;IACtB,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAA;IAC9D,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,CAAA,CAAC,MAAM;IAEnC,0BAA0B;IAC1B,aAAa;IACb,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACrE,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAA;IAEtE,sCAAsC;IACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,kBAAkB,CACxC,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,EACpC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAC1C,CAAA;IAED,gBAAgB;IAChB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW;QACpC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;QAC1C,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAA;IAE9E,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CACrD,WAAW,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,CACd,CAAA;IACD,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAEhF,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC,CAAA;IAC3E,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAExB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;QAC5C,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QAC5B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QAC5B,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACvH,CAAC;AACH,CAAC;AAgBD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW,CACzB,MAAqB,EACrB,KAAiB,EACjB,MAAyB;IAEzB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,UAAU,CAAA;IACtC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAA;IAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAE5B,cAAc;IACd,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC/C,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,OAAO,CAClC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAC/B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAC/B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAChC,CAAA;IACD,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAA;IAE9F,UAAU;IACV,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE;QAC3C,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACtC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,WAAW,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;KAC3D,CAAC,CAAA;IAEF,UAAU;IACV,0BAA0B;IAC1B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACrE,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAA;IACtE,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CACrD,WAAW,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,CACd,CAAA;IACD,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAEhF,kBAAkB;IAClB,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,OAAO,CAChC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAC1B,CAAA;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAClE,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAC5D,wFAAwF;IACxF,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3F,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC,CAAA;IAC7E,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACzB,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC,CAAA;IAC5E,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAE5B,QAAQ;IACR,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IACrD,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAEzB,2BAA2B;IAC3B,IAAI,aAAyB,CAAA;IAC7B,IAAI,CAAC;QACH,gBAAgB;QAChB,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;QAC3D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;YAC5B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YACjC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YAChC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;QAC7D,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAEpB,SAAS;QACT,IAAI,UAAyB,CAAA;QAC7B,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QACpD,CAAC;aAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QACpD,CAAC;aAAM,CAAC;YACN,WAAW;YACX,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;QACrD,CAAC;QAED,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;QAC9E,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACpB,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,mBAAmB;QACnB,IAAI,YAAY;YAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QAC9C,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QAChC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAA;IACzE,CAAC;IAED,YAAY;IACZ,IAAI,WAAmB,CAAA;IACvB,IAAI,UAAkB,CAAA;IACtB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,WAAW,GAAG,MAAM,GAAG,CAAC,CAAA;QACxB,UAAU,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;IAC1B,CAAC;SAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,WAAW,GAAG,MAAM,CAAA;QACpB,UAAU,GAAG,CAAC,CAAA;IAChB,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,CAAC,CAAA;QACf,UAAU,GAAG,CAAC,MAAM,CAAA;IACtB,CAAC;IAED,kBAAkB;IAClB,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,CACtC,WAAW,CAAC,KAAK,EACjB,MAAM,CAAC,CAAC,GAAG,WAAW,EACtB,MAAM,CAAC,CAAC,GAAG,WAAW,EACtB,MAAM,CAAC,CAAC,GAAG,WAAW,CACvB,CAAA;IACD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAEjC,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CACrC,WAAW,CAAC,IAAI,EAChB,MAAM,CAAC,CAAC,GAAG,UAAU,EACrB,MAAM,CAAC,CAAC,GAAG,UAAU,EACrB,MAAM,CAAC,CAAC,GAAG,UAAU,CACtB,CAAA;IACD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IAEhC,aAAa;IACb,IAAI,MAAkB,CAAA;IACtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;QAC1D,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QAC/B,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QAC7B,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;QAC5C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACtB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QAC/B,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QAC7B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;QAC9B,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACnH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,yBAAyB;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,QAAQ,CACtB,MAAqB,EACrB,MAAmB,EACnB,SAA0B,EAC1B,MAAiB,EACjB,SAAkB,EAClB,IAAkC;IAElC,wDAAwD;IACxD,+DAA+D;IAC/D,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC3C,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAE7B,4CAA4C;IAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAChD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,4DAA4D;QAC5D,6CAA6C;QAC7C,gBAAgB;QAChB,yDAAyD;QACzD,+BAA+B;QAC/B,IAAI,IAAI,EAAE,aAAa,IAAI,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;YACrE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;QAC9B,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACnB,MAAM,IAAI,KAAK,CACb,yDAAyD;YACzD,sEAAsE;YACtE,6BAA6B,CAC9B,CAAA;IACH,CAAC;IAED,sCAAsC;IACtC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QAC3B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA,CAAC,gCAAgC;QACpD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;QAC3E,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;IACpC,CAAC;IAED,gEAAgE;IAChE,kDAAkD;IAClD,4CAA4C;IAC5C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACnB,MAAM,IAAI,KAAK,CACb,wBAAwB,SAAS,kBAAkB,MAAM,CAAC,MAAM,UAAU,CAC3E,CAAA;QACH,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA,CAAC,0CAA0C;QAC9D,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;QACxE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;IACjC,CAAC;IAED,yDAAyD;IACzD,qCAAqC;IACrC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC;YAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;IACrE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;AAC9B,CAAC;AAED,iFAAiF;AACjF,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAA;AAE5E;;;;;;;;;;GAUG;AACH,SAAS,cAAc,CAAC,MAAqB,EAAE,GAAe;IAC5D,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAClF,CAAC;AAED,eAAe;AAEf;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAA;IACzB,qDAAqD;IACrD,OAAO;QACL,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;KACzB,CAAA;AACH,CAAC","sourcesContent":["/**\n * 核心 BREP 操作 — 使用 OCCT 精确实体运算\n *\n * See docs/api-contract.md §8 (dual-path geometry contract: BREP / Mesh).\n *\n * 与 mesh 路径(transform.ts / boolean/ / drill.ts / split.ts / extrude.ts)对照:\n * - mesh 路径:消费 Shape(三角网格),走 manifold-3d(mesh-CSG)\n * - BREP 路径:消费 BrepHandle(OCCT 实体句柄),走 OCCT 精确布尔/变换\n *\n * 所有函数都是纯函数(可 import occtWasmKernel,不读 store)。\n * 输入输出均为 OCCT BrepHandle,调用方负责句柄生命周期。\n *\n * 坐标系:Z-up、毫米,与 mesh 路径一致。\n */\n\nimport * as THREE from 'three'\nimport type { BrepHandle, BrepMeshResult } from './engine/types'\nimport type { BrepEngineApi } from './engine/primitives'\nimport type { Shape, Vec3 } from '../mesh/types'\nimport type { BrepChainState } from './brep-chain'\nimport type { PartName } from '../identity'\nimport { getSolidBoundingBox } from './brep-utils'\n\n// ─── 通用工具 ───\n\n/**\n * 将 OCCT solid 三角化为 Shape(供显示用)。\n *\n * 如果传入 brepChain + stmtId,同时把完整 BrepMeshResult(含 faceGroups)缓存到\n * brepChain.meshShapeCache,供 buildBrepTopology 复用——确保拓扑 mesh 与显示 mesh\n * 完全一致(规则 1:拓扑数据生成所使用的 mesh,必须是当前用户看到的 mesh)。\n *\n * @param kernel the initialized OCCT kernel.\n * @param solid the CAD solid handle.\n * @param segments optional tessellation segment count (affects precision).\n * @param brepChain optional - caches the BrepMeshResult when provided.\n * @param partName optional - the part this solid belongs to, paired with brepChain as the cache key.\n * @returns the tessellated Shape.\n */\nexport function solidToShape(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n segments?: number,\n brepChain?: BrepChainState,\n partName?: PartName,\n): Shape {\n const angularDeflection = segments\n ? (2 * Math.PI) / Math.max(3, segments)\n : (2 * Math.PI) / 64 // 缺省 64 = brepjs standard 等效(§5.0/§5.1)\n const mesh: BrepMeshResult = kernel.meshShape(solid, {\n linearDeflection: 0.1,\n angularDeflection,\n })\n\n // 规则 1:缓存完整 BrepMeshResult(含 faceGroups),供 buildBrepTopology 复用\n if (brepChain?.meshShapeCache && partName) {\n brepChain.meshShapeCache.set(partName, mesh)\n }\n\n return {\n positions: new Float32Array(mesh.positions),\n indices: new Uint32Array(mesh.indices),\n }\n}\n\n// ─── 变换操作 ───\n\n/**\n * BREP 平移:使用 OCCT translate(精确,不损失几何精度)。\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param offset 平移量 [dx, dy, dz]\n * @returns 新实体(调用方负责释放输入实体)\n */\nexport function translateBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n offset: Vec3,\n): BrepHandle {\n return kernel.translate(solid, offset[0], offset[1], offset[2])\n}\n\n/**\n * BREP 旋转:使用 OCCT transform(3x4 仿射矩阵)。\n *\n * 与 mesh 路径 rotate_euler(shape, anglesDeg, pivot?) 一致:\n * - anglesDeg 为 XYZ 欧拉角(角度制)\n * - pivot 为旋转中心(可选,默认原点)\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param anglesDeg XYZ 欧拉角(角度制)\n * @param pivot 旋转中心(可选)\n * @returns 新实体\n */\nexport function rotateBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n anglesDeg: Vec3,\n pivot?: Vec3,\n): BrepHandle {\n const euler = new THREE.Euler(\n (anglesDeg[0] * Math.PI) / 180,\n (anglesDeg[1] * Math.PI) / 180,\n (anglesDeg[2] * Math.PI) / 180,\n )\n const matrix = new THREE.Matrix4().makeRotationFromEuler(euler)\n if (pivot) {\n matrix.premultiply(new THREE.Matrix4().makeTranslation(pivot[0], pivot[1], pivot[2]))\n matrix.multiply(new THREE.Matrix4().makeTranslation(-pivot[0], -pivot[1], -pivot[2]))\n }\n return kernel.transform(solid, matrixToArray(matrix))\n}\n\n/**\n * BREP 缩放:使用 OCCT transform(3x4 仿射矩阵)。\n *\n * 与 mesh 路径 scale(P6 §4.6)一致:\n * - factor 为 number(均匀缩放)或 Vec3 [sx, sy, sz](非均匀)\n * - center 为缩放不动点(p' = center + S·(p − center));缺省 [0,0,0](原点),\n * 与 vendored brepjs `scale(shape, factor, { center? })` 的默认一致。\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param factor 缩放因子\n * @param center 缩放不动点(可选,默认原点)\n * @returns 新实体\n */\nexport function scaleBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n factor: number | Vec3,\n center?: Vec3,\n): BrepHandle {\n const f = typeof factor === 'number' ? [factor, factor, factor] : factor\n const scale = new THREE.Matrix4().makeScale(f[0], f[1], f[2])\n // T(c)·S·T(−c):不动点为 center;缺省时退化为原点缩放(现状行为)。\n const matrix = center\n ? new THREE.Matrix4()\n .makeTranslation(center[0], center[1], center[2])\n .multiply(scale)\n .multiply(new THREE.Matrix4().makeTranslation(-center[0], -center[1], -center[2]))\n : scale\n const isUniform = f[0] === f[1] && f[1] === f[2]\n // OCCT gp_Trsf (kernel.transform) only supports uniform scaling.\n // Non-uniform scaling requires gp_GTrsf (kernel.generalTransform).\n if (isUniform) {\n return kernel.transform(solid, matrixToArray(matrix))\n }\n return kernel.generalTransform(solid, matrixToArray(matrix))\n}\n\n// ─── 装配变换 ───\n\n/**\n * BREP 版 applyTransform:与 mesh ops/assemble.ts 的 applyTransform 同语义(绕 pivot 旋转 + 平移)。\n *\n * 数学公式:p' = R·(p − pivot) + pivot + translation\n * 等价 Matrix4 = T(pivot) · R · T(−pivot) · T(translation)\n *\n * 用四元数而非欧拉角,是因为装配变换源是 api/assembly 的四元数;\n * 转欧拉会引入顺序/万向锁歧义。与 mesh applyTransform 顶点公式完全等价。\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param quaternion 旋转四元数 [x, y, z, w]\n * @param pivot 旋转中心\n * @param translation 平移量\n * @returns 新实体(调用方负责释放输入实体)\n */\nexport function applyTransformBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n quaternion: [number, number, number, number],\n pivot: [number, number, number],\n translation: [number, number, number],\n): BrepHandle {\n const rotation = new THREE.Matrix4().makeRotationFromQuaternion(\n new THREE.Quaternion(quaternion[0], quaternion[1], quaternion[2], quaternion[3]),\n )\n // T(translation) · T(pivot) · R · T(-pivot) = T(pivot+translation) · R · T(-pivot)\n // 先绕 pivot 旋转,再平移 translation(与 mesh 路径 applyTransform 一致)\n const matrix = new THREE.Matrix4()\n .makeTranslation(pivot[0] + translation[0], pivot[1] + translation[1], pivot[2] + translation[2])\n .multiply(rotation)\n .multiply(new THREE.Matrix4().makeTranslation(-pivot[0], -pivot[1], -pivot[2]))\n return kernel.transform(solid, matrixToArray(matrix))\n}\n\n// ─── 布尔操作 ───\n\n/**\n * BREP 布尔并集:使用 OCCT fuse(BRepAlgoAPI_Fuse)。\n *\n * @param kernel OCCT 内核\n * @param a 实体 A\n * @param b 实体 B\n * @returns 融合后的实体\n */\nexport function fuseBrep(\n kernel: BrepEngineApi,\n a: BrepHandle,\n b: BrepHandle,\n): BrepHandle {\n return kernel.fuse(a, b)\n}\n\n/**\n * BREP 布尔差集:使用 OCCT cut(BRepAlgoAPI_Cut)。\n *\n * @param kernel OCCT 内核\n * @param a 基体\n * @param b 工具(从基体中减去)\n * @returns 切割后的实体\n */\nexport function cutBrep(\n kernel: BrepEngineApi,\n a: BrepHandle,\n b: BrepHandle,\n): BrepHandle {\n return kernel.cut(a, b)\n}\n\n/**\n * BREP 布尔交集:使用 OCCT common(BRepAlgoAPI_Common)。\n *\n * @param kernel OCCT 内核\n * @param a 实体 A\n * @param b 实体 B\n * @returns 交集实体\n */\nexport function commonBrep(\n kernel: BrepEngineApi,\n a: BrepHandle,\n b: BrepHandle,\n): BrepHandle {\n return kernel.common(a, b)\n}\n\n// ─── 钻孔操作 ───\n\n/** drillBrep 的参数 */\nexport interface DrillBrepParams {\n /** 孔直径 */\n diameter: number\n /** 孔深度(0 = 通孔) */\n depth: number\n /** 孔位置(世界空间) */\n position: Vec3\n /** 钻孔方向(世界空间,指向材料内部) */\n direction: Vec3\n /** 面法向(世界空间) */\n faceNormal: Vec3\n /** 孔类型 */\n holeType?: 'simple' | 'screw'\n}\n\n/**\n * BREP 钻孔:创建圆柱工具实体并用 OCCT cut 减去。\n *\n * 仅支持圆柱孔(holeType='simple')。\n * 螺丝孔(holeType='screw')由调用方判断为 mesh-only,触发 BREP 链断裂。\n *\n * 通孔(depth=0):创建一个足够长的圆柱体穿透整个零件。\n * 盲孔(depth>0):创建指定深度的圆柱体。\n *\n * @param kernel OCCT 内核\n * @param solid 目标实体\n * @param params 钻孔参数\n * @returns 钻孔后的实体\n */\n/** 钻孔几何参数(由 `DrillBrepParams` 推导;roleTable 路径与 `drillBrep` 共用同一份几何,避免重复计算)。 */\nexport interface DrillGeometry {\n readonly radius: number\n readonly holeHeight: number\n readonly holeCenter: THREE.Vector3\n readonly direction: THREE.Vector3\n}\n\n/** 从 `DrillBrepParams` 推导钻孔几何(孔中心/高度/轴向)。供 `drillBrep` 与 role-table 路径共用。\n * @param kernel - BREP 引擎接口\n * @param solid - 待钻孔实体(用于 bbox 推导通孔高度)\n * @param params - 钻孔参数(直径/深度/位置/方向/面法向)\n * @returns 钻孔几何(半径/高度/中心/轴向)\n */\nexport function computeDrillGeometry(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: DrillBrepParams,\n): DrillGeometry {\n const radius = params.diameter / 2\n const direction = new THREE.Vector3(...params.direction).normalize()\n // 确保方向指向材料内部\n const faceNormal = new THREE.Vector3(...params.faceNormal)\n if (direction.dot(faceNormal) > 0) {\n direction.negate()\n }\n\n // 计算孔的高度和中心\n const bbox = getSolidBoundingBox(kernel, solid)\n const bboxSize = new THREE.Vector3(\n bbox.max[0] - bbox.min[0],\n bbox.max[1] - bbox.min[1],\n bbox.max[2] - bbox.min[2],\n )\n const bboxMax = Math.max(bboxSize.x, bboxSize.y, bboxSize.z)\n\n let holeHeight: number\n let holeCenter: THREE.Vector3\n const pos = new THREE.Vector3(...params.position)\n\n // 通孔:depth <= 0(契约:depth<=0 表示通孔,与 mesh 路径 `depth>0 ? 'blind':'through'` 一致)。\n // ⚠️ 只判 `=== 0` 会让 depth<0 落入盲孔分支 → safeDepth=0 → 零高圆柱 → OCCT transform 崩溃。\n if (params.depth <= 0) {\n const d = direction.clone().normalize()\n const bbMin = new THREE.Vector3(bbox.min[0], bbox.min[1], bbox.min[2])\n const bbMax = new THREE.Vector3(bbox.max[0], bbox.max[1], bbox.max[2])\n\n let tNear = -Infinity\n let tFar = Infinity\n const axes: Array<[number, number, number, number]> = [\n [0, d.x, bbMin.x, bbMax.x],\n [1, d.y, bbMin.y, bbMax.y],\n [2, d.z, bbMin.z, bbMax.z],\n ]\n const pArr = [pos.x, pos.y, pos.z]\n for (const [axis, di, lo, hi] of axes) {\n const pi = pArr[axis]\n if (Math.abs(di) > 1e-12) {\n const t1 = (lo - pi) / di\n const t2 = (hi - pi) / di\n tNear = Math.max(tNear, Math.min(t1, t2))\n tFar = Math.min(tFar, Math.max(t1, t2))\n } else if (pi < lo || pi > hi) {\n // 与 slab 平行且在外部 — 无交点(与 mesh 行为一致:几乎不钻孔)\n tNear = 0\n tFar = 0\n }\n }\n if (!isFinite(tNear) || !isFinite(tFar) || tFar < tNear) {\n // 不穿过 bbox:与 mesh 一致,只留 0.2mm 微小孔\n holeHeight = 0.2\n holeCenter = pos.clone()\n } else {\n holeHeight = tFar - tNear + 0.2\n holeCenter = pos.clone().add(direction.clone().normalize().multiplyScalar((tNear + tFar) / 2))\n }\n } else {\n // 盲孔:深度钳制到 bboxMax(与 mesh cad-core/drill.ts 一致)\n const safeDepth = Math.max(0, Math.min(params.depth, bboxMax))\n holeHeight = safeDepth\n holeCenter = pos.clone().add(direction.clone().normalize().multiplyScalar(safeDepth / 2))\n }\n\n return { radius, holeHeight, holeCenter, direction }\n}\n\n/** 由钻孔几何构造刀具实体(圆柱,旋转 + 平移到孔位)。调用方负责 release。\n * @param kernel - BREP 引擎接口\n * @param geom - 钻孔几何(半径/高度/中心/轴向)\n * @returns 刀具实体(BrepHandle,调用方负责 release)\n */\nexport function buildDrillToolSolid(kernel: BrepEngineApi, geom: DrillGeometry): BrepHandle {\n const cylinder = kernel.makeCylinder(geom.radius, geom.holeHeight)\n\n // 计算从 Z 轴到 direction 的旋转\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, geom.direction)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 平移矩阵:到孔中心,并减去 height/2(因为圆柱从 Z=0 开始)\n const transMatrix = new THREE.Matrix4().makeTranslation(\n geom.holeCenter.x,\n geom.holeCenter.y,\n geom.holeCenter.z,\n )\n // 组合:先旋转,再平移\n const finalMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n // 还需要补偿圆柱的起始位置(从 Z=0 开始 → 需要先下移 height/2)\n const offsetMatrix = new THREE.Matrix4().makeTranslation(0, 0, -geom.holeHeight / 2)\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(finalMatrix, offsetMatrix)\n\n const toolSolid = kernel.transform(cylinder, matrixToArray(fullMatrix))\n kernel.release(cylinder)\n return toolSolid\n}\n\n/** 在实体上钻一个孔:由参数推导几何、构造刀具实体并做布尔差。\n * @param kernel - BREP 引擎接口\n * @param solid - 待钻孔实体\n * @param params - 钻孔参数(直径/深度/位置/方向/面法向)\n * @returns 钻孔后的实体(BrepHandle)\n */\nexport function drillBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: DrillBrepParams,\n): BrepHandle {\n const geom = computeDrillGeometry(kernel, solid, params)\n const toolSolid = buildDrillToolSolid(kernel, geom)\n try {\n const result = kernel.cut(solid, toolSolid)\n kernel.release(toolSolid)\n return result\n } catch (err) {\n kernel.release(toolSolid)\n throw new Error(`[drillBrep] OCCT cut failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err })\n }\n}\n\n// ─── 分割操作 ───\n\n/** splitBrep 的参数 */\nexport interface SplitBrepParams {\n /** 切割平面法线 */\n normal: Vec3\n /** 切割平面原点偏移(法线方向上的距离) */\n originOffset: number\n /** 切割平面中心点 */\n planeCenter: Vec3\n}\n\n/** splitBrep 的结果 */\nexport interface SplitBrepResult {\n /** 法线正方向的半部分 */\n front: BrepHandle\n /** 法线负方向的半部分 */\n back: BrepHandle\n}\n\n/**\n * BREP 平面分割:使用 OCCT cut + common 实现平面分割。\n *\n * 仅支持平面分割(cutMode='plane')。\n * 燕尾/定位销/直榫等复杂分割由 joinery-brep.ts 处理。\n *\n * 实现方式:\n * 1. 创建一个大的半空间盒子(法线正方向一侧)\n * 2. common(solid, box) → 法线正方向的半部分\n * 3. cut(solid, box) → 法线负方向的半部分\n *\n * @param kernel OCCT 内核\n * @param solid 目标实体\n * @param params 分割参数\n * @returns 两个半部分\n */\nexport function splitBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: SplitBrepParams,\n): SplitBrepResult {\n const bbox = getSolidBoundingBox(kernel, solid)\n const bboxSize = new THREE.Vector3(\n bbox.max[0] - bbox.min[0],\n bbox.max[1] - bbox.min[1],\n bbox.max[2] - bbox.min[2],\n )\n const bboxMax = Math.max(bboxSize.x, bboxSize.y, bboxSize.z)\n const bboxCenter = new THREE.Vector3(\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n )\n\n // 创建一个大的盒子代表法线正方向的半空间\n const normal = new THREE.Vector3(...params.normal).normalize()\n const halfSize = bboxMax * 3 // 足够大\n\n // 先在局部坐标系(Z 轴 = 法线方向)创建盒子\n // 然后旋转到世界坐标系\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, normal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 在局部坐标系中,盒子从 Z=0(切割平面)延伸到 Z=halfSize\n const localBox = kernel.makeBoxFromCorners(\n { x: -halfSize, y: -halfSize, z: 0 },\n { x: halfSize, y: halfSize, z: halfSize },\n )\n\n // 计算切割平面的世界坐标原点\n const planeOrigin = params.planeCenter\n ? new THREE.Vector3(...params.planeCenter)\n : bboxCenter.clone().add(normal.clone().multiplyScalar(params.originOffset))\n\n const transMatrix = new THREE.Matrix4().makeTranslation(\n planeOrigin.x,\n planeOrigin.y,\n planeOrigin.z,\n )\n const finalMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const halfSpaceBox = kernel.transform(localBox, matrixToArray(finalMatrix))\n kernel.release(localBox)\n\n try {\n const front = kernel.common(solid, halfSpaceBox)\n const back = kernel.cut(solid, halfSpaceBox)\n kernel.release(halfSpaceBox)\n return { front, back }\n } catch (err) {\n kernel.release(halfSpaceBox)\n throw new Error(`[splitBrep] OCCT split failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err })\n }\n}\n\n// ─── 拉伸操作 ───\n\n/** extrudeBrep 的参数 */\nexport interface ExtrudeBrepParams {\n /** 拉伸法线方向 */\n normal: Vec3\n /** 平面原点偏移 */\n originOffset: number\n /** 拉伸长度 */\n length: number\n /** 拉伸模式 */\n mode?: 'centered' | 'forward' | 'backward'\n}\n\n/**\n * BREP 拉伸:在切割平面处将实体切开,中段沿法线拉伸 length,三段 fuse。\n *\n * 实现方式:\n * 1. 用平面分割得到 front + back\n * 2. 获取截面线(section edges → wire → face)\n * 3. 沿法线拉伸截面 face → 中段实体\n * 4. fuse(front, extruded, back)\n *\n * 如果截面无法构建 face(开放线框等),抛出错误由调用方处理为链断裂。\n *\n * @param kernel OCCT 内核\n * @param solid 目标实体\n * @param params 拉伸参数\n * @returns 拉伸后的实体\n */\nexport function extrudeBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: ExtrudeBrepParams,\n): BrepHandle {\n const mode = params.mode ?? 'centered'\n const normal = new THREE.Vector3(...params.normal).normalize()\n const length = params.length\n\n // 1. 创建切割平面盒子\n const bbox = getSolidBoundingBox(kernel, solid)\n const bboxCenter = new THREE.Vector3(\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n )\n const planeOrigin = bboxCenter.clone().add(normal.clone().multiplyScalar(params.originOffset))\n\n // 2. 分割实体\n const splitResult = splitBrep(kernel, solid, {\n normal: [normal.x, normal.y, normal.z],\n originOffset: params.originOffset,\n planeCenter: [planeOrigin.x, planeOrigin.y, planeOrigin.z],\n })\n\n // 3. 获取截面\n // 使用 section 获取切割平面与实体的交线\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, normal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n const transMatrix = new THREE.Matrix4().makeTranslation(\n planeOrigin.x,\n planeOrigin.y,\n planeOrigin.z,\n )\n const planeMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n // 创建一个大的矩形面作为切割平面\n const bboxSize = new THREE.Vector3(\n bbox.max[0] - bbox.min[0],\n bbox.max[1] - bbox.min[1],\n bbox.max[2] - bbox.min[2],\n )\n const planeSize = Math.max(bboxSize.x, bboxSize.y, bboxSize.z) * 3\n const planeRect = kernel.makeRectangle(planeSize, planeSize)\n // makeRectangle creates a face from [0,0] to [width,height] — center it at origin first\n const centerMatrix = new THREE.Matrix4().makeTranslation(-planeSize / 2, -planeSize / 2, 0)\n const centeredRect = kernel.transform(planeRect, matrixToArray(centerMatrix))\n kernel.release(planeRect)\n const planeFace = kernel.transform(centeredRect, matrixToArray(planeMatrix))\n kernel.release(centeredRect)\n\n // 获取截面边\n const sectionEdges = kernel.section(solid, planeFace)\n kernel.release(planeFace)\n\n // 4. 构建截面 wire → face → 拉伸\n let extrudedSolid: BrepHandle\n try {\n // 尝试从截面边构建 wire\n const subShapes = kernel.getSubShapes(sectionEdges, 'edge')\n if (subShapes.length === 0) {\n kernel.release(sectionEdges)\n kernel.release(splitResult.front)\n kernel.release(splitResult.back)\n throw new Error('no section edges from plane intersection')\n }\n\n const wire = kernel.makeWire(subShapes)\n const face = kernel.makeFace(wire)\n kernel.release(wire)\n\n // 计算拉伸向量\n let extrudeVec: THREE.Vector3\n if (mode === 'centered') {\n extrudeVec = normal.clone().multiplyScalar(length)\n } else if (mode === 'forward') {\n extrudeVec = normal.clone().multiplyScalar(length)\n } else {\n // backward\n extrudeVec = normal.clone().multiplyScalar(-length)\n }\n\n extrudedSolid = kernel.extrude(face, extrudeVec.x, extrudeVec.y, extrudeVec.z)\n kernel.release(face)\n kernel.release(sectionEdges)\n } catch {\n // 截面构建失败 — 释放资源并抛出\n if (sectionEdges) kernel.release(sectionEdges)\n kernel.release(splitResult.front)\n kernel.release(splitResult.back)\n throw new Error('[extrudeBrep] failed to build extrusion from section')\n }\n\n // 5. 计算各段位置\n let frontOffset: number\n let backOffset: number\n if (mode === 'centered') {\n frontOffset = length / 2\n backOffset = -length / 2\n } else if (mode === 'forward') {\n frontOffset = length\n backOffset = 0\n } else {\n frontOffset = 0\n backOffset = -length\n }\n\n // 平移 front 和 back\n const frontTranslated = kernel.translate(\n splitResult.front,\n normal.x * frontOffset,\n normal.y * frontOffset,\n normal.z * frontOffset,\n )\n kernel.release(splitResult.front)\n\n const backTranslated = kernel.translate(\n splitResult.back,\n normal.x * backOffset,\n normal.y * backOffset,\n normal.z * backOffset,\n )\n kernel.release(splitResult.back)\n\n // 6. Fuse 三段\n let result: BrepHandle\n try {\n const fused1 = kernel.fuse(frontTranslated, extrudedSolid)\n kernel.release(frontTranslated)\n kernel.release(extrudedSolid)\n result = kernel.fuse(fused1, backTranslated)\n kernel.release(fused1)\n kernel.release(backTranslated)\n } catch (err) {\n kernel.release(frontTranslated)\n kernel.release(extrudedSolid)\n kernel.release(backTranslated)\n throw new Error(`[extrudeBrep] fuse failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err })\n }\n\n return result\n}\n\n// ─── STEP/BREP 导入操作 ───\n\n/**\n * BREP-native STEP 导入:使用 OCCT kernel.importStep 导入 STEP 文件为精确实体。\n *\n * 与 mesh 路径(cad-core/io.ts importFile → loadFormat → meshes)对照:\n * - mesh 路径:STEP → 三角网格,丢弃 OCCT BrepHandle\n * - BREP 路径:STEP → kernel.importStep → 保留 BrepHandle,同时三角化为显示 mesh\n *\n * 导入的 solid 存入 brepChain.solidCache,后续操作(drillBrep/splitBrep 等)\n * 将其作为\"基座特征\"进行精确运算。\n *\n * **设计决策(I5 不准合并)**:\n * - 单 solid STEP:`importStep` 返回 Compound 包裹(顶层是 `TopoDS_Compound`,\n * 内含 1 个 `TopoDS_Solid`)。此处**解包**返回真实 Solid(`solids[0]`),\n * 下游 `isValid`/编辑/导出都针对真实实体。\n * - 多 solid STEP:返回顶层 Compound **不 fuse**。`meshShape(compound)` 整体显示,\n * 导出时 Compound 仍含全部 solid(非三角化)。逐 part 编辑由 Phase 1 XCAF 负责。\n * - **不调用 `kernel.isValid`**:`importStep` 对单 solid STEP 也返回 Compound 包裹,\n * `isValid(compound)` 返回 false(Compound 不是 Solid),这会误杀合法 STEP。\n * 合法性判据改为 `getSubShapes(top, 'solid').length >= 1`(含 ≥1 个 solid 即合法),\n * 与装配路径 `walkLabel` 一致。\n *\n * @param kernel the initialized OCCT kernel.\n * @param buffer the raw STEP file bytes (a text-encoded ArrayBuffer).\n * @param brepChain optional - caches the tessellated BrepMeshResult when provided.\n * @param stmtId optional - the part this solid belongs to, paired with brepChain as the cache key.\n * @param partIndex optional - for multi-solid files, return the N-th sub-solid\n * (host emits one load statement per part with its index).\n * @param opts optional - `allowNonSolid` relaxes the solid requirement so\n * a frozen wireframe/surface asset (a Draft wire, a face, a\n * shell) can be imported as addressable geometry. Callers\n * must decide this STATICALLY from the asset itself (see\n * `brepTextHasSolid`), never by retrying after a failure.\n * @returns { solid: the OCCT solid handle, shape: the display tessellated mesh }\n */\nexport function loadBrep(\n kernel: BrepEngineApi,\n buffer: ArrayBuffer,\n brepChain?: BrepChainState,\n stmtId?: PartName,\n partIndex?: number,\n opts?: { allowNonSolid?: boolean },\n): { solid: BrepHandle; shape: Shape } {\n // BREP 文件(CASCADE Topology 文本格式)必须用 kernel.fromBREP 解析;\n // 误用 STEP 解析器(importStep)读 BREP 会抛 \"failed to read STEP data\"。\n const decoder = new TextDecoder('utf-8')\n const head = decoder.decode(buffer.slice(0, 64))\n const top = head.includes('CASCADE Topology')\n ? kernel.fromBREP(decoder.decode(buffer))\n : kernel.importStep(buffer)\n\n // 校验:含至少一个 solid 子形即合法(不调用 isValid,见上文设计决策)\n const solids = kernel.getSubShapes(top, 'solid')\n if (solids.length < 1) {\n // 非实体导入(allowNonSolid):冻结资产是 wireframe/surface(Draft 线/面/壳)\n // 时仍可作为可寻址几何导入——顶点/边/线/面/壳都算有内容。此时返回 top 本身,\n // 它独立持有几何,不能释放。\n // 注意:这类 Shape 进不了布尔运算(OCCT fuse/cut 抛 \"boolean operation\n // failed\"),调用方必须自己保证它只流向变换/聚合。\n if (opts?.allowNonSolid && hasAnyTopology(kernel, top)) {\n const shape = solidToShape(kernel, top, undefined, brepChain, stmtId)\n return { solid: top, shape }\n }\n kernel.release(top)\n throw new Error(\n `[loadBrep] imported shape contains no solid sub-shapes ` +\n `(solidCount=0) — wireframe/surface/invalid shapes are not supported ` +\n `unless allowNonSolid is set`\n )\n }\n\n // 单 solid:解包返回真实 Solid(非 Compound 包裹)\n if (solids.length === 1) {\n const realSolid = solids[0]\n kernel.release(top) // 释放 Compound 包裹,realSolid 独立持有\n const shape = solidToShape(kernel, realSolid, undefined, brepChain, stmtId)\n return { solid: realSolid, shape }\n }\n\n // 多 solid + partIndex:提取第 partIndex 个子 solid(逐 part load 语句使用)。\n // 宿主为多 part 文件的每个 part 生成独立 load 语句并携带 partIndex,\n // 使每条 load 输出对应 part 的几何,而不是整个文件的 Compound。\n if (partIndex !== undefined) {\n const target = solids[partIndex]\n if (!target) {\n kernel.release(top)\n throw new Error(\n `[loadBrep] partIndex ${partIndex} out of range (${solids.length} solids)`,\n )\n }\n kernel.release(top) // 释放 Compound 包裹,target 独立持有(同单 solid 模式)\n const shape = solidToShape(kernel, target, undefined, brepChain, stmtId)\n return { solid: target, shape }\n }\n\n // 多 solid:保留 Compound 不合并(I5),逐 part 编辑由 Phase 1 XCAF 负责\n // 释放提取的子形句柄(它们是 top 的子引用,top 本身持有几何)\n for (const s of solids) {\n try { kernel.release(s) } catch { /* already released */ }\n }\n const shape = solidToShape(kernel, top, undefined, brepChain, stmtId)\n return { solid: top, shape }\n}\n\n/** Sub-shape kinds that make an imported shape \"addressable but not a solid\". */\nconst NON_SOLID_KINDS = ['vertex', 'edge', 'wire', 'face', 'shell'] as const\n\n/**\n * Does a freshly imported shape hold any sub-shape at all?\n *\n * Guards the `allowNonSolid` path: a file whose TShapes table is empty (or that\n * holds only a bare compound with nothing inside) is a broken asset, not a\n * wireframe one, and must still fail loudly.\n *\n * @param kernel - the initialized OCCT kernel.\n * @param top - the imported top-level shape handle.\n * @returns true when at least one non-solid sub-shape exists.\n */\nfunction hasAnyTopology(kernel: BrepEngineApi, top: BrepHandle): boolean {\n return NON_SOLID_KINDS.some((kind) => kernel.getSubShapes(top, kind).length > 0)\n}\n\n// ─── 辅助函数 ───\n\n/**\n * Convert a THREE.Matrix4 into the 3x4 row-major array (12 doubles) the OCCT\n * transform expects.\n *\n * OCCT transform accepts [r00,r01,r02,tx, r10,r11,r12,ty, r20,r21,r22,tz].\n * @param matrix - the source matrix to convert.\n * @returns the 3x4 row-major array of 12 doubles.\n */\nexport function matrixToArray(matrix: THREE.Matrix4): number[] {\n const e = matrix.elements\n // THREE.Matrix4 是 column-major,OCCT 需要 row-major 3x4\n return [\n e[0], e[4], e[8], e[12],\n e[1], e[5], e[9], e[13],\n e[2], e[6], e[10], e[14],\n ]\n}\n"]}
|
|
1
|
+
{"version":3,"file":"brep-ops.js","sourceRoot":"","sources":["../../src/brep/brep-ops.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 核心 BREP 操作 — 使用 OCCT 精确实体运算\n *\n * @platform occt — 本文件 import occt-kernel:`extrudeBrep` 用原生 `section`\n * (BRepAlgoAPI_Section,occt-only,L1 只有 sectionByPlane)构造截面 → 守卫①\n * 要求平台 import 自证身份。本文件是内部工具面(非 op 文件),文件级标注即满足\n * 守卫;调用方 op 若经本文件触达 occt-only 能力,须在 defineOp 声明 engines\n * (extrudeBrep 的 section 仅 occt 路径可达,brepkit 下由调用方引擎声明拦截)。\n *\n * See docs/api-contract.md §8 (dual-path geometry contract: BREP / Mesh).\n *\n * 与 mesh 路径(transform.ts / boolean/ / drill.ts / split.ts / extrude.ts)对照:\n * - mesh 路径:消费 Shape(三角网格),走 manifold-3d(mesh-CSG)\n * - BREP 路径:消费 BrepHandle(OCCT 实体句柄),走 OCCT 精确布尔/变换\n *\n * 所有函数都是纯函数(可 import occtWasmKernel,不读 store)。\n * 输入输出均为 OCCT BrepHandle,调用方负责句柄生命周期。\n *\n * 坐标系:Z-up、毫米,与 mesh 路径一致。\n */\n\nimport * as THREE from 'three'\nimport type { BrepHandle, BrepMeshResult } from './engine/types'\nimport type { BrepEngineApi } from './engine/primitives'\nimport { getOcctKernel, type ShapeHandle } from '../occt-kernel/occtKernel'\nimport type { Shape, Vec3 } from '../mesh/types'\nimport type { BrepChainState } from './brep-chain'\nimport type { PartName } from '../identity'\nimport { getSolidBoundingBox } from './brep-utils'\n\n// ─── 通用工具 ───\n\n/**\n * 将 OCCT solid 三角化为 Shape(供显示用)。\n *\n * 如果传入 brepChain + stmtId,同时把完整 BrepMeshResult(含 faceGroups)缓存到\n * brepChain.meshShapeCache,供 buildBrepTopology 复用——确保拓扑 mesh 与显示 mesh\n * 完全一致(规则 1:拓扑数据生成所使用的 mesh,必须是当前用户看到的 mesh)。\n *\n * @param kernel the initialized OCCT kernel.\n * @param solid the CAD solid handle.\n * @param segments optional tessellation segment count (affects precision).\n * @param brepChain optional - caches the BrepMeshResult when provided.\n * @param partName optional - the part this solid belongs to, paired with brepChain as the cache key.\n * @returns the tessellated Shape.\n */\nexport function solidToShape(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n segments?: number,\n brepChain?: BrepChainState,\n partName?: PartName,\n): Shape {\n const angularDeflection = segments\n ? (2 * Math.PI) / Math.max(3, segments)\n : (2 * Math.PI) / 64 // 缺省 64 = brepjs standard 等效(§5.0/§5.1)\n const mesh: BrepMeshResult = kernel.meshShape(solid, {\n linearDeflection: 0.1,\n angularDeflection,\n })\n\n // 规则 1:缓存完整 BrepMeshResult(含 faceGroups),供 buildBrepTopology 复用\n if (brepChain?.meshShapeCache && partName) {\n brepChain.meshShapeCache.set(partName, mesh)\n }\n\n return {\n positions: new Float32Array(mesh.positions),\n indices: new Uint32Array(mesh.indices),\n }\n}\n\n// ─── 变换操作 ───\n\n/**\n * BREP 平移:使用 OCCT translate(精确,不损失几何精度)。\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param offset 平移量 [dx, dy, dz]\n * @returns 新实体(调用方负责释放输入实体)\n */\nexport function translateBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n offset: Vec3,\n): BrepHandle {\n return kernel.translate(solid, offset[0], offset[1], offset[2])\n}\n\n/**\n * BREP 旋转:使用 OCCT transform(3x4 仿射矩阵)。\n *\n * 与 mesh 路径 rotate_euler(shape, anglesDeg, pivot?) 一致:\n * - anglesDeg 为 XYZ 欧拉角(角度制)\n * - pivot 为旋转中心(可选,默认原点)\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param anglesDeg XYZ 欧拉角(角度制)\n * @param pivot 旋转中心(可选)\n * @returns 新实体\n */\nexport function rotateBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n anglesDeg: Vec3,\n pivot?: Vec3,\n): BrepHandle {\n const euler = new THREE.Euler(\n (anglesDeg[0] * Math.PI) / 180,\n (anglesDeg[1] * Math.PI) / 180,\n (anglesDeg[2] * Math.PI) / 180,\n )\n const matrix = new THREE.Matrix4().makeRotationFromEuler(euler)\n if (pivot) {\n matrix.premultiply(new THREE.Matrix4().makeTranslation(pivot[0], pivot[1], pivot[2]))\n matrix.multiply(new THREE.Matrix4().makeTranslation(-pivot[0], -pivot[1], -pivot[2]))\n }\n return kernel.transform(solid, matrixToArray(matrix))\n}\n\n/**\n * BREP 缩放:使用 OCCT transform(3x4 仿射矩阵)。\n *\n * 与 mesh 路径 scale(P6 §4.6)一致:\n * - factor 为 number(均匀缩放)或 Vec3 [sx, sy, sz](非均匀)\n * - center 为缩放不动点(p' = center + S·(p − center));缺省 [0,0,0](原点),\n * 与 vendored brepjs `scale(shape, factor, { center? })` 的默认一致。\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param factor 缩放因子\n * @param center 缩放不动点(可选,默认原点)\n * @returns 新实体\n */\nexport function scaleBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n factor: number | Vec3,\n center?: Vec3,\n): BrepHandle {\n const f = typeof factor === 'number' ? [factor, factor, factor] : factor\n const scale = new THREE.Matrix4().makeScale(f[0], f[1], f[2])\n // T(c)·S·T(−c):不动点为 center;缺省时退化为原点缩放(现状行为)。\n const matrix = center\n ? new THREE.Matrix4()\n .makeTranslation(center[0], center[1], center[2])\n .multiply(scale)\n .multiply(new THREE.Matrix4().makeTranslation(-center[0], -center[1], -center[2]))\n : scale\n const isUniform = f[0] === f[1] && f[1] === f[2]\n // OCCT gp_Trsf (kernel.transform) only supports uniform scaling.\n // Non-uniform scaling requires gp_GTrsf (kernel.generalTransform).\n if (isUniform) {\n return kernel.transform(solid, matrixToArray(matrix))\n }\n return kernel.generalTransform(solid, matrixToArray(matrix))\n}\n\n// ─── 装配变换 ───\n\n/**\n * BREP 版 applyTransform:与 mesh ops/assemble.ts 的 applyTransform 同语义(绕 pivot 旋转 + 平移)。\n *\n * 数学公式:p' = R·(p − pivot) + pivot + translation\n * 等价 Matrix4 = T(pivot) · R · T(−pivot) · T(translation)\n *\n * 用四元数而非欧拉角,是因为装配变换源是 api/assembly 的四元数;\n * 转欧拉会引入顺序/万向锁歧义。与 mesh applyTransform 顶点公式完全等价。\n *\n * @param kernel OCCT 内核\n * @param solid 输入实体\n * @param quaternion 旋转四元数 [x, y, z, w]\n * @param pivot 旋转中心\n * @param translation 平移量\n * @returns 新实体(调用方负责释放输入实体)\n */\nexport function applyTransformBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n quaternion: [number, number, number, number],\n pivot: [number, number, number],\n translation: [number, number, number],\n): BrepHandle {\n const rotation = new THREE.Matrix4().makeRotationFromQuaternion(\n new THREE.Quaternion(quaternion[0], quaternion[1], quaternion[2], quaternion[3]),\n )\n // T(translation) · T(pivot) · R · T(-pivot) = T(pivot+translation) · R · T(-pivot)\n // 先绕 pivot 旋转,再平移 translation(与 mesh 路径 applyTransform 一致)\n const matrix = new THREE.Matrix4()\n .makeTranslation(pivot[0] + translation[0], pivot[1] + translation[1], pivot[2] + translation[2])\n .multiply(rotation)\n .multiply(new THREE.Matrix4().makeTranslation(-pivot[0], -pivot[1], -pivot[2]))\n return kernel.transform(solid, matrixToArray(matrix))\n}\n\n// ─── 布尔操作 ───\n\n/**\n * BREP 布尔并集:使用 OCCT fuse(BRepAlgoAPI_Fuse)。\n *\n * @param kernel OCCT 内核\n * @param a 实体 A\n * @param b 实体 B\n * @returns 融合后的实体\n */\nexport function fuseBrep(\n kernel: BrepEngineApi,\n a: BrepHandle,\n b: BrepHandle,\n): BrepHandle {\n return kernel.fuse(a, b)\n}\n\n/**\n * BREP 布尔差集:使用 OCCT cut(BRepAlgoAPI_Cut)。\n *\n * @param kernel OCCT 内核\n * @param a 基体\n * @param b 工具(从基体中减去)\n * @returns 切割后的实体\n */\nexport function cutBrep(\n kernel: BrepEngineApi,\n a: BrepHandle,\n b: BrepHandle,\n): BrepHandle {\n return kernel.cut(a, b)\n}\n\n/**\n * BREP 布尔交集:使用 OCCT common(BRepAlgoAPI_Common)。\n *\n * @param kernel OCCT 内核\n * @param a 实体 A\n * @param b 实体 B\n * @returns 交集实体\n */\nexport function commonBrep(\n kernel: BrepEngineApi,\n a: BrepHandle,\n b: BrepHandle,\n): BrepHandle {\n return kernel.common(a, b)\n}\n\n// ─── 钻孔操作 ───\n\n/** drillBrep 的参数 */\nexport interface DrillBrepParams {\n /** 孔直径 */\n diameter: number\n /** 孔深度(0 = 通孔) */\n depth: number\n /** 孔位置(世界空间) */\n position: Vec3\n /** 钻孔方向(世界空间,指向材料内部) */\n direction: Vec3\n /** 面法向(世界空间) */\n faceNormal: Vec3\n /** 孔类型 */\n holeType?: 'simple' | 'screw'\n}\n\n/**\n * BREP 钻孔:创建圆柱工具实体并用 OCCT cut 减去。\n *\n * 仅支持圆柱孔(holeType='simple')。\n * 螺丝孔(holeType='screw')由调用方判断为 mesh-only,触发 BREP 链断裂。\n *\n * 通孔(depth=0):创建一个足够长的圆柱体穿透整个零件。\n * 盲孔(depth>0):创建指定深度的圆柱体。\n *\n * @param kernel OCCT 内核\n * @param solid 目标实体\n * @param params 钻孔参数\n * @returns 钻孔后的实体\n */\n/** 钻孔几何参数(由 `DrillBrepParams` 推导;roleTable 路径与 `drillBrep` 共用同一份几何,避免重复计算)。 */\nexport interface DrillGeometry {\n readonly radius: number\n readonly holeHeight: number\n readonly holeCenter: THREE.Vector3\n readonly direction: THREE.Vector3\n}\n\n/** 从 `DrillBrepParams` 推导钻孔几何(孔中心/高度/轴向)。供 `drillBrep` 与 role-table 路径共用。\n * @param kernel - BREP 引擎接口\n * @param solid - 待钻孔实体(用于 bbox 推导通孔高度)\n * @param params - 钻孔参数(直径/深度/位置/方向/面法向)\n * @returns 钻孔几何(半径/高度/中心/轴向)\n */\nexport function computeDrillGeometry(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: DrillBrepParams,\n): DrillGeometry {\n const radius = params.diameter / 2\n const direction = new THREE.Vector3(...params.direction).normalize()\n // 确保方向指向材料内部\n const faceNormal = new THREE.Vector3(...params.faceNormal)\n if (direction.dot(faceNormal) > 0) {\n direction.negate()\n }\n\n // 计算孔的高度和中心\n const bbox = getSolidBoundingBox(kernel, solid)\n const bboxSize = new THREE.Vector3(\n bbox.max[0] - bbox.min[0],\n bbox.max[1] - bbox.min[1],\n bbox.max[2] - bbox.min[2],\n )\n const bboxMax = Math.max(bboxSize.x, bboxSize.y, bboxSize.z)\n\n let holeHeight: number\n let holeCenter: THREE.Vector3\n const pos = new THREE.Vector3(...params.position)\n\n // 通孔:depth <= 0(契约:depth<=0 表示通孔,与 mesh 路径 `depth>0 ? 'blind':'through'` 一致)。\n // ⚠️ 只判 `=== 0` 会让 depth<0 落入盲孔分支 → safeDepth=0 → 零高圆柱 → OCCT transform 崩溃。\n if (params.depth <= 0) {\n const d = direction.clone().normalize()\n const bbMin = new THREE.Vector3(bbox.min[0], bbox.min[1], bbox.min[2])\n const bbMax = new THREE.Vector3(bbox.max[0], bbox.max[1], bbox.max[2])\n\n let tNear = -Infinity\n let tFar = Infinity\n const axes: Array<[number, number, number, number]> = [\n [0, d.x, bbMin.x, bbMax.x],\n [1, d.y, bbMin.y, bbMax.y],\n [2, d.z, bbMin.z, bbMax.z],\n ]\n const pArr = [pos.x, pos.y, pos.z]\n for (const [axis, di, lo, hi] of axes) {\n const pi = pArr[axis]\n if (Math.abs(di) > 1e-12) {\n const t1 = (lo - pi) / di\n const t2 = (hi - pi) / di\n tNear = Math.max(tNear, Math.min(t1, t2))\n tFar = Math.min(tFar, Math.max(t1, t2))\n } else if (pi < lo || pi > hi) {\n // 与 slab 平行且在外部 — 无交点(与 mesh 行为一致:几乎不钻孔)\n tNear = 0\n tFar = 0\n }\n }\n if (!isFinite(tNear) || !isFinite(tFar) || tFar < tNear) {\n // 不穿过 bbox:与 mesh 一致,只留 0.2mm 微小孔\n holeHeight = 0.2\n holeCenter = pos.clone()\n } else {\n holeHeight = tFar - tNear + 0.2\n holeCenter = pos.clone().add(direction.clone().normalize().multiplyScalar((tNear + tFar) / 2))\n }\n } else {\n // 盲孔:深度钳制到 bboxMax(与 mesh cad-core/drill.ts 一致)\n const safeDepth = Math.max(0, Math.min(params.depth, bboxMax))\n holeHeight = safeDepth\n holeCenter = pos.clone().add(direction.clone().normalize().multiplyScalar(safeDepth / 2))\n }\n\n return { radius, holeHeight, holeCenter, direction }\n}\n\n/** 由钻孔几何构造刀具实体(圆柱,旋转 + 平移到孔位)。调用方负责 release。\n * @param kernel - BREP 引擎接口\n * @param geom - 钻孔几何(半径/高度/中心/轴向)\n * @returns 刀具实体(BrepHandle,调用方负责 release)\n */\nexport function buildDrillToolSolid(kernel: BrepEngineApi, geom: DrillGeometry): BrepHandle {\n const cylinder = kernel.makeCylinder(geom.radius, geom.holeHeight)\n\n // 计算从 Z 轴到 direction 的旋转\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, geom.direction)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 平移矩阵:到孔中心,并减去 height/2(因为圆柱从 Z=0 开始)\n const transMatrix = new THREE.Matrix4().makeTranslation(\n geom.holeCenter.x,\n geom.holeCenter.y,\n geom.holeCenter.z,\n )\n // 组合:先旋转,再平移\n const finalMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n // 还需要补偿圆柱的起始位置(从 Z=0 开始 → 需要先下移 height/2)\n const offsetMatrix = new THREE.Matrix4().makeTranslation(0, 0, -geom.holeHeight / 2)\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(finalMatrix, offsetMatrix)\n\n const toolSolid = kernel.transform(cylinder, matrixToArray(fullMatrix))\n kernel.release(cylinder)\n return toolSolid\n}\n\n/** 在实体上钻一个孔:由参数推导几何、构造刀具实体并做布尔差。\n * @param kernel - BREP 引擎接口\n * @param solid - 待钻孔实体\n * @param params - 钻孔参数(直径/深度/位置/方向/面法向)\n * @returns 钻孔后的实体(BrepHandle)\n */\nexport function drillBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: DrillBrepParams,\n): BrepHandle {\n const geom = computeDrillGeometry(kernel, solid, params)\n const toolSolid = buildDrillToolSolid(kernel, geom)\n try {\n const result = kernel.cut(solid, toolSolid)\n kernel.release(toolSolid)\n return result\n } catch (err) {\n kernel.release(toolSolid)\n throw new Error(`[drillBrep] OCCT cut failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err })\n }\n}\n\n// ─── 分割操作 ───\n\n/** splitBrep 的参数 */\nexport interface SplitBrepParams {\n /** 切割平面法线 */\n normal: Vec3\n /** 切割平面原点偏移(法线方向上的距离) */\n originOffset: number\n /** 切割平面中心点 */\n planeCenter: Vec3\n}\n\n/** splitBrep 的结果 */\nexport interface SplitBrepResult {\n /** 法线正方向的半部分 */\n front: BrepHandle\n /** 法线负方向的半部分 */\n back: BrepHandle\n}\n\n/**\n * BREP 平面分割:使用 OCCT cut + common 实现平面分割。\n *\n * 仅支持平面分割(cutMode='plane')。\n * 燕尾/定位销/直榫等复杂分割由 joinery-brep.ts 处理。\n *\n * 实现方式:\n * 1. 创建一个大的半空间盒子(法线正方向一侧)\n * 2. common(solid, box) → 法线正方向的半部分\n * 3. cut(solid, box) → 法线负方向的半部分\n *\n * @param kernel OCCT 内核\n * @param solid 目标实体\n * @param params 分割参数\n * @returns 两个半部分\n */\nexport function splitBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: SplitBrepParams,\n): SplitBrepResult {\n const bbox = getSolidBoundingBox(kernel, solid)\n const bboxSize = new THREE.Vector3(\n bbox.max[0] - bbox.min[0],\n bbox.max[1] - bbox.min[1],\n bbox.max[2] - bbox.min[2],\n )\n const bboxMax = Math.max(bboxSize.x, bboxSize.y, bboxSize.z)\n const bboxCenter = new THREE.Vector3(\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n )\n\n // 创建一个大的盒子代表法线正方向的半空间\n const normal = new THREE.Vector3(...params.normal).normalize()\n const halfSize = bboxMax * 3 // 足够大\n\n // 先在局部坐标系(Z 轴 = 法线方向)创建盒子\n // 然后旋转到世界坐标系\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, normal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 在局部坐标系中,盒子从 Z=0(切割平面)延伸到 Z=halfSize\n const localBox = kernel.makeBoxFromCorners(\n { x: -halfSize, y: -halfSize, z: 0 },\n { x: halfSize, y: halfSize, z: halfSize },\n )\n\n // 计算切割平面的世界坐标原点\n const planeOrigin = params.planeCenter\n ? new THREE.Vector3(...params.planeCenter)\n : bboxCenter.clone().add(normal.clone().multiplyScalar(params.originOffset))\n\n const transMatrix = new THREE.Matrix4().makeTranslation(\n planeOrigin.x,\n planeOrigin.y,\n planeOrigin.z,\n )\n const finalMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const halfSpaceBox = kernel.transform(localBox, matrixToArray(finalMatrix))\n kernel.release(localBox)\n\n try {\n const front = kernel.common(solid, halfSpaceBox)\n const back = kernel.cut(solid, halfSpaceBox)\n kernel.release(halfSpaceBox)\n return { front, back }\n } catch (err) {\n kernel.release(halfSpaceBox)\n throw new Error(`[splitBrep] OCCT split failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err })\n }\n}\n\n// ─── 拉伸操作 ───\n\n/** extrudeBrep 的参数 */\nexport interface ExtrudeBrepParams {\n /** 拉伸法线方向 */\n normal: Vec3\n /** 平面原点偏移 */\n originOffset: number\n /** 拉伸长度 */\n length: number\n /** 拉伸模式 */\n mode?: 'centered' | 'forward' | 'backward'\n}\n\n/**\n * BREP 拉伸:在切割平面处将实体切开,中段沿法线拉伸 length,三段 fuse。\n *\n * 实现方式:\n * 1. 用平面分割得到 front + back\n * 2. 获取截面线(section edges → wire → face)\n * 3. 沿法线拉伸截面 face → 中段实体\n * 4. fuse(front, extruded, back)\n *\n * 如果截面无法构建 face(开放线框等),抛出错误由调用方处理为链断裂。\n *\n * @param kernel OCCT 内核\n * @param solid 目标实体\n * @param params 拉伸参数\n * @returns 拉伸后的实体\n */\nexport function extrudeBrep(\n kernel: BrepEngineApi,\n solid: BrepHandle,\n params: ExtrudeBrepParams,\n): BrepHandle {\n const mode = params.mode ?? 'centered'\n const normal = new THREE.Vector3(...params.normal).normalize()\n const length = params.length\n\n // 1. 创建切割平面盒子\n const bbox = getSolidBoundingBox(kernel, solid)\n const bboxCenter = new THREE.Vector3(\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n )\n const planeOrigin = bboxCenter.clone().add(normal.clone().multiplyScalar(params.originOffset))\n\n // 2. 分割实体\n const splitResult = splitBrep(kernel, solid, {\n normal: [normal.x, normal.y, normal.z],\n originOffset: params.originOffset,\n planeCenter: [planeOrigin.x, planeOrigin.y, planeOrigin.z],\n })\n\n // 3. 获取截面\n // 使用 section 获取切割平面与实体的交线\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, normal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n const transMatrix = new THREE.Matrix4().makeTranslation(\n planeOrigin.x,\n planeOrigin.y,\n planeOrigin.z,\n )\n const planeMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n // 创建一个大的矩形面作为切割平面\n const bboxSize = new THREE.Vector3(\n bbox.max[0] - bbox.min[0],\n bbox.max[1] - bbox.min[1],\n bbox.max[2] - bbox.min[2],\n )\n const planeSize = Math.max(bboxSize.x, bboxSize.y, bboxSize.z) * 3\n const planeRect = kernel.makeRectangle(planeSize, planeSize)\n // makeRectangle creates a face from [0,0] to [width,height] — center it at origin first\n const centerMatrix = new THREE.Matrix4().makeTranslation(-planeSize / 2, -planeSize / 2, 0)\n const centeredRect = kernel.transform(planeRect, matrixToArray(centerMatrix))\n kernel.release(planeRect)\n const planeFace = kernel.transform(centeredRect, matrixToArray(planeMatrix))\n kernel.release(centeredRect)\n\n // 获取截面边(occt-only 平台面,D3)。BrepHandle(branded number)与\n // occt-wasm ShapeHandle 运行时同构,品牌转换只发生在平台边界;转回 BrepHandle\n // 后继续用 L1 面(getSubShapes/makeWire/extrude)。\n const sectionEdges = getOcctKernel().section(\n solid as unknown as ShapeHandle,\n planeFace as unknown as ShapeHandle,\n ) as unknown as BrepHandle\n kernel.release(planeFace)\n\n // 4. 构建截面 wire → face → 拉伸\n let extrudedSolid: BrepHandle\n try {\n // 尝试从截面边构建 wire\n const subShapes = kernel.getSubShapes(sectionEdges, 'edge')\n if (subShapes.length === 0) {\n kernel.release(sectionEdges)\n kernel.release(splitResult.front)\n kernel.release(splitResult.back)\n throw new Error('no section edges from plane intersection')\n }\n\n const wire = kernel.makeWire(subShapes)\n const face = kernel.makeFace(wire)\n kernel.release(wire)\n\n // 计算拉伸向量\n let extrudeVec: THREE.Vector3\n if (mode === 'centered') {\n extrudeVec = normal.clone().multiplyScalar(length)\n } else if (mode === 'forward') {\n extrudeVec = normal.clone().multiplyScalar(length)\n } else {\n // backward\n extrudeVec = normal.clone().multiplyScalar(-length)\n }\n\n extrudedSolid = kernel.extrude(face, extrudeVec.x, extrudeVec.y, extrudeVec.z)\n kernel.release(face)\n kernel.release(sectionEdges)\n } catch {\n // 截面构建失败 — 释放资源并抛出\n if (sectionEdges) kernel.release(sectionEdges)\n kernel.release(splitResult.front)\n kernel.release(splitResult.back)\n throw new Error('[extrudeBrep] failed to build extrusion from section')\n }\n\n // 5. 计算各段位置\n let frontOffset: number\n let backOffset: number\n if (mode === 'centered') {\n frontOffset = length / 2\n backOffset = -length / 2\n } else if (mode === 'forward') {\n frontOffset = length\n backOffset = 0\n } else {\n frontOffset = 0\n backOffset = -length\n }\n\n // 平移 front 和 back\n const frontTranslated = kernel.translate(\n splitResult.front,\n normal.x * frontOffset,\n normal.y * frontOffset,\n normal.z * frontOffset,\n )\n kernel.release(splitResult.front)\n\n const backTranslated = kernel.translate(\n splitResult.back,\n normal.x * backOffset,\n normal.y * backOffset,\n normal.z * backOffset,\n )\n kernel.release(splitResult.back)\n\n // 6. Fuse 三段\n let result: BrepHandle\n try {\n const fused1 = kernel.fuse(frontTranslated, extrudedSolid)\n kernel.release(frontTranslated)\n kernel.release(extrudedSolid)\n result = kernel.fuse(fused1, backTranslated)\n kernel.release(fused1)\n kernel.release(backTranslated)\n } catch (err) {\n kernel.release(frontTranslated)\n kernel.release(extrudedSolid)\n kernel.release(backTranslated)\n throw new Error(`[extrudeBrep] fuse failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err })\n }\n\n return result\n}\n\n// ─── STEP/BREP 导入操作 ───\n\n/**\n * BREP-native STEP 导入:使用 OCCT kernel.importStep 导入 STEP 文件为精确实体。\n *\n * 与 mesh 路径(cad-core/io.ts importFile → loadFormat → meshes)对照:\n * - mesh 路径:STEP → 三角网格,丢弃 OCCT BrepHandle\n * - BREP 路径:STEP → kernel.importStep → 保留 BrepHandle,同时三角化为显示 mesh\n *\n * 导入的 solid 存入 brepChain.solidCache,后续操作(drillBrep/splitBrep 等)\n * 将其作为\"基座特征\"进行精确运算。\n *\n * **设计决策(I5 不准合并)**:\n * - 单 solid STEP:`importStep` 返回 Compound 包裹(顶层是 `TopoDS_Compound`,\n * 内含 1 个 `TopoDS_Solid`)。此处**解包**返回真实 Solid(`solids[0]`),\n * 下游 `isValid`/编辑/导出都针对真实实体。\n * - 多 solid STEP:返回顶层 Compound **不 fuse**。`meshShape(compound)` 整体显示,\n * 导出时 Compound 仍含全部 solid(非三角化)。逐 part 编辑由 Phase 1 XCAF 负责。\n * - **不调用 `kernel.isValid`**:`importStep` 对单 solid STEP 也返回 Compound 包裹,\n * `isValid(compound)` 返回 false(Compound 不是 Solid),这会误杀合法 STEP。\n * 合法性判据改为 `getSubShapes(top, 'solid').length >= 1`(含 ≥1 个 solid 即合法),\n * 与装配路径 `walkLabel` 一致。\n *\n * @param kernel the initialized OCCT kernel.\n * @param buffer the raw STEP file bytes (a text-encoded ArrayBuffer).\n * @param brepChain optional - caches the tessellated BrepMeshResult when provided.\n * @param stmtId optional - the part this solid belongs to, paired with brepChain as the cache key.\n * @param partIndex optional - for multi-solid files, return the N-th sub-solid\n * (host emits one load statement per part with its index).\n * @param opts optional - `allowNonSolid` relaxes the solid requirement so\n * a frozen wireframe/surface asset (a Draft wire, a face, a\n * shell) can be imported as addressable geometry. Callers\n * must decide this STATICALLY from the asset itself (see\n * `brepTextHasSolid`), never by retrying after a failure.\n * @returns { solid: the OCCT solid handle, shape: the display tessellated mesh }\n */\nexport function loadBrep(\n kernel: BrepEngineApi,\n buffer: ArrayBuffer,\n brepChain?: BrepChainState,\n stmtId?: PartName,\n partIndex?: number,\n opts?: { allowNonSolid?: boolean },\n): { solid: BrepHandle; shape: Shape } {\n // BREP 文件(CASCADE Topology 文本格式)必须用 kernel.fromBREP 解析;\n // 误用 STEP 解析器(importStep)读 BREP 会抛 \"failed to read STEP data\"。\n const decoder = new TextDecoder('utf-8')\n const head = decoder.decode(buffer.slice(0, 64))\n const top = head.includes('CASCADE Topology')\n ? kernel.fromBREP(decoder.decode(buffer))\n : kernel.importStep(buffer)\n\n // 校验:含至少一个 solid 子形即合法(不调用 isValid,见上文设计决策)\n const solids = kernel.getSubShapes(top, 'solid')\n if (solids.length < 1) {\n // 非实体导入(allowNonSolid):冻结资产是 wireframe/surface(Draft 线/面/壳)\n // 时仍可作为可寻址几何导入——顶点/边/线/面/壳都算有内容。此时返回 top 本身,\n // 它独立持有几何,不能释放。\n // 注意:这类 Shape 进不了布尔运算(OCCT fuse/cut 抛 \"boolean operation\n // failed\"),调用方必须自己保证它只流向变换/聚合。\n if (opts?.allowNonSolid && hasAnyTopology(kernel, top)) {\n const shape = solidToShape(kernel, top, undefined, brepChain, stmtId)\n return { solid: top, shape }\n }\n kernel.release(top)\n throw new Error(\n `[loadBrep] imported shape contains no solid sub-shapes ` +\n `(solidCount=0) — wireframe/surface/invalid shapes are not supported ` +\n `unless allowNonSolid is set`\n )\n }\n\n // 单 solid:解包返回真实 Solid(非 Compound 包裹)\n if (solids.length === 1) {\n const realSolid = solids[0]\n kernel.release(top) // 释放 Compound 包裹,realSolid 独立持有\n const shape = solidToShape(kernel, realSolid, undefined, brepChain, stmtId)\n return { solid: realSolid, shape }\n }\n\n // 多 solid + partIndex:提取第 partIndex 个子 solid(逐 part load 语句使用)。\n // 宿主为多 part 文件的每个 part 生成独立 load 语句并携带 partIndex,\n // 使每条 load 输出对应 part 的几何,而不是整个文件的 Compound。\n if (partIndex !== undefined) {\n const target = solids[partIndex]\n if (!target) {\n kernel.release(top)\n throw new Error(\n `[loadBrep] partIndex ${partIndex} out of range (${solids.length} solids)`,\n )\n }\n kernel.release(top) // 释放 Compound 包裹,target 独立持有(同单 solid 模式)\n const shape = solidToShape(kernel, target, undefined, brepChain, stmtId)\n return { solid: target, shape }\n }\n\n // 多 solid:保留 Compound 不合并(I5),逐 part 编辑由 Phase 1 XCAF 负责\n // 释放提取的子形句柄(它们是 top 的子引用,top 本身持有几何)\n for (const s of solids) {\n try { kernel.release(s) } catch { /* already released */ }\n }\n const shape = solidToShape(kernel, top, undefined, brepChain, stmtId)\n return { solid: top, shape }\n}\n\n/** Sub-shape kinds that make an imported shape \"addressable but not a solid\". */\nconst NON_SOLID_KINDS = ['vertex', 'edge', 'wire', 'face', 'shell'] as const\n\n/**\n * Does a freshly imported shape hold any sub-shape at all?\n *\n * Guards the `allowNonSolid` path: a file whose TShapes table is empty (or that\n * holds only a bare compound with nothing inside) is a broken asset, not a\n * wireframe one, and must still fail loudly.\n *\n * @param kernel - the initialized OCCT kernel.\n * @param top - the imported top-level shape handle.\n * @returns true when at least one non-solid sub-shape exists.\n */\nfunction hasAnyTopology(kernel: BrepEngineApi, top: BrepHandle): boolean {\n return NON_SOLID_KINDS.some((kind) => kernel.getSubShapes(top, kind).length > 0)\n}\n\n// ─── 辅助函数 ───\n\n/**\n * Convert a THREE.Matrix4 into the 3x4 row-major array (12 doubles) the OCCT\n * transform expects.\n *\n * OCCT transform accepts [r00,r01,r02,tx, r10,r11,r12,ty, r20,r21,r22,tz].\n * @param matrix - the source matrix to convert.\n * @returns the 3x4 row-major array of 12 doubles.\n */\nexport function matrixToArray(matrix: THREE.Matrix4): number[] {\n const e = matrix.elements\n // THREE.Matrix4 是 column-major,OCCT 需要 row-major 3x4\n return [\n e[0], e[4], e[8], e[12],\n e[1], e[5], e[9], e[13],\n e[2], e[6], e[10], e[14],\n ]\n}\n"]}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BREP 拓扑运行时构建 — 从 OCCT solid 句柄生成 SelectorRuntime + mesh 数据
|
|
3
3
|
*
|
|
4
|
+
* @platform occt — 本文件 import occt-kernel(occtKernel / topologyExt):拓扑
|
|
5
|
+
* 提取直接消费平台原生句柄与扩展方法,由调用方(宿主导出缓存 / 平台装配点)
|
|
6
|
+
* 在 occt 引擎下使用;守卫 R1 豁免、R2 无 defineOp 不适用。
|
|
7
|
+
*
|
|
4
8
|
* 与 STEP 文件导入的拓扑提取使用**同源算法**:
|
|
5
9
|
* meshShape + buildAssemblySelectorManifest + buildSelectorRuntime
|
|
6
10
|
*
|