@faicad/faijs 0.19.0 → 0.29.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -28
- package/dist/api/api-namespace.d.ts +5 -5
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +4 -4
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/assert.d.ts +2 -2
- package/dist/api/assert.js +8 -8
- package/dist/api/assert.js.map +1 -1
- package/dist/api/asset.d.ts +1 -1
- package/dist/api/asset.js +2 -2
- package/dist/api/asset.js.map +1 -1
- package/dist/api/boolean.d.ts +1 -1
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +128 -16
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/brep-mirror/joinery-brep.d.ts.map +1 -1
- package/dist/api/brep-mirror/joinery-brep.js +3 -1
- package/dist/api/brep-mirror/joinery-brep.js.map +1 -1
- package/dist/api/cadquery-selectors/borrow-bridge.d.ts +14 -0
- package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/borrow-bridge.js +52 -0
- package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -0
- package/dist/api/cadquery-selectors/edge.d.ts +40 -0
- package/dist/api/cadquery-selectors/edge.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/edge.js +70 -0
- package/dist/api/cadquery-selectors/edge.js.map +1 -0
- package/dist/api/cadquery-selectors/entity.d.ts +121 -0
- package/dist/api/cadquery-selectors/entity.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/entity.js +167 -0
- package/dist/api/cadquery-selectors/entity.js.map +1 -0
- package/dist/api/cadquery-selectors/face.d.ts +33 -0
- package/dist/api/cadquery-selectors/face.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/face.js +353 -0
- package/dist/api/cadquery-selectors/face.js.map +1 -0
- package/dist/api/cadquery-selectors/grammar.d.ts +50 -0
- package/dist/api/cadquery-selectors/grammar.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/grammar.js +345 -0
- package/dist/api/cadquery-selectors/grammar.js.map +1 -0
- package/dist/api/cadquery-selectors/index.d.ts +18 -0
- package/dist/api/cadquery-selectors/index.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/index.js +17 -0
- package/dist/api/cadquery-selectors/index.js.map +1 -0
- package/dist/api/cadquery-selectors/predicates.d.ts +76 -0
- package/dist/api/cadquery-selectors/predicates.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/predicates.js +85 -0
- package/dist/api/cadquery-selectors/predicates.js.map +1 -0
- package/dist/api/cadquery-selectors/resolve.d.ts +41 -0
- package/dist/api/cadquery-selectors/resolve.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/resolve.js +243 -0
- package/dist/api/cadquery-selectors/resolve.js.map +1 -0
- package/dist/api/cadquery-selectors/types.d.ts +96 -0
- package/dist/api/cadquery-selectors/types.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/types.js +11 -0
- package/dist/api/cadquery-selectors/types.js.map +1 -0
- package/dist/api/chamfer.d.ts +13 -5
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +63 -7
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/compound-geom.d.ts +1 -1
- package/dist/api/compound-geom.js +1 -1
- package/dist/api/compound-geom.js.map +1 -1
- package/dist/api/draft.d.ts +1 -1
- package/dist/api/draft.js +1 -1
- package/dist/api/draft.js.map +1 -1
- package/dist/api/edge-ref.d.ts +1 -1
- package/dist/api/edge-ref.d.ts.map +1 -1
- package/dist/api/edge-ref.js +11 -3
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/engrave.d.ts +1 -1
- package/dist/api/engrave.js +7 -7
- package/dist/api/engrave.js.map +1 -1
- package/dist/api/extrude.d.ts +6 -1
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +59 -5
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts +1 -1
- package/dist/api/face-ref.js +1 -1
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/feature-repair.d.ts +1 -1
- package/dist/api/feature-repair.js +1 -1
- package/dist/api/feature-repair.js.map +1 -1
- package/dist/api/fillet-variable.d.ts +1 -1
- package/dist/api/fillet-variable.js +1 -1
- package/dist/api/fillet-variable.js.map +1 -1
- package/dist/api/fillet.d.ts +28 -8
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +64 -9
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts +4 -0
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/geom.d.ts +1 -1
- package/dist/api/geom.js +1 -1
- package/dist/api/geom.js.map +1 -1
- package/dist/api/helix.d.ts +1 -1
- package/dist/api/helix.js +1 -1
- package/dist/api/helix.js.map +1 -1
- package/dist/api/import-brep.d.ts +20 -2
- package/dist/api/import-brep.d.ts.map +1 -1
- package/dist/api/import-brep.js +28 -3
- package/dist/api/import-brep.js.map +1 -1
- package/dist/api/import-step.d.ts +17 -2
- package/dist/api/import-step.d.ts.map +1 -1
- package/dist/api/import-step.js +23 -3
- package/dist/api/import-step.js.map +1 -1
- package/dist/api/index.d.ts +2 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +5 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-op.js +1 -1
- package/dist/api/internal/compat-op.js.map +1 -1
- package/dist/api/internal/mesh-solid-op.d.ts +236 -0
- package/dist/api/internal/mesh-solid-op.d.ts.map +1 -0
- package/dist/api/internal/mesh-solid-op.js +352 -0
- package/dist/api/internal/mesh-solid-op.js.map +1 -0
- package/dist/api/internal/svg-asset-resolver.d.ts +1 -1
- package/dist/api/internal/svg-asset-resolver.js +1 -1
- package/dist/api/internal/svg-asset-resolver.js.map +1 -1
- package/dist/api/knurl.d.ts +1 -1
- package/dist/api/knurl.d.ts.map +1 -1
- package/dist/api/knurl.js +3 -2
- package/dist/api/knurl.js.map +1 -1
- package/dist/api/loft.d.ts +1 -1
- package/dist/api/loft.js +1 -1
- package/dist/api/loft.js.map +1 -1
- package/dist/api/measurement/index.d.ts +9 -5
- package/dist/api/measurement/index.d.ts.map +1 -1
- package/dist/api/measurement/index.js +47 -20
- package/dist/api/measurement/index.js.map +1 -1
- package/dist/api/pattern.d.ts +5 -3
- package/dist/api/pattern.d.ts.map +1 -1
- package/dist/api/pattern.js +32 -4
- package/dist/api/pattern.js.map +1 -1
- package/dist/api/place.d.ts +1 -1
- package/dist/api/place.js +1 -1
- package/dist/api/place.js.map +1 -1
- package/dist/api/primitives.d.ts +5 -4
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +11 -5
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/profile.d.ts +64 -8
- package/dist/api/profile.d.ts.map +1 -1
- package/dist/api/profile.js +61 -10
- package/dist/api/profile.js.map +1 -1
- package/dist/api/punch-hole.d.ts +3 -0
- package/dist/api/punch-hole.d.ts.map +1 -1
- package/dist/api/punch-hole.js.map +1 -1
- package/dist/api/reconcile.d.ts +1 -1
- package/dist/api/reconcile.js +1 -1
- package/dist/api/reconcile.js.map +1 -1
- package/dist/api/replicate.d.ts.map +1 -1
- package/dist/api/replicate.js +122 -1
- package/dist/api/replicate.js.map +1 -1
- package/dist/api/screw.d.ts +1 -1
- package/dist/api/screw.js +3 -3
- package/dist/api/screw.js.map +1 -1
- package/dist/api/sdf.d.ts +1 -1
- package/dist/api/sdf.js +2 -2
- package/dist/api/sdf.js.map +1 -1
- package/dist/api/section-by-plane.d.ts +1 -1
- package/dist/api/section-by-plane.d.ts.map +1 -1
- package/dist/api/section-by-plane.js +2 -1
- package/dist/api/section-by-plane.js.map +1 -1
- package/dist/api/shell.d.ts +11 -4
- package/dist/api/shell.d.ts.map +1 -1
- package/dist/api/shell.js +53 -7
- package/dist/api/shell.js.map +1 -1
- package/dist/api/sketch-on-face.d.ts +41 -0
- package/dist/api/sketch-on-face.d.ts.map +1 -1
- package/dist/api/sketch-on-face.js +100 -1
- package/dist/api/sketch-on-face.js.map +1 -1
- package/dist/api/sketch-on-plane.d.ts +17 -9
- package/dist/api/sketch-on-plane.d.ts.map +1 -1
- package/dist/api/sketch-on-plane.js +12 -10
- package/dist/api/sketch-on-plane.js.map +1 -1
- package/dist/api/split-by-plane.d.ts +1 -1
- package/dist/api/split-by-plane.d.ts.map +1 -1
- package/dist/api/split-by-plane.js +2 -1
- package/dist/api/split-by-plane.js.map +1 -1
- package/dist/api/split.d.ts +1 -1
- package/dist/api/split.js +2 -2
- package/dist/api/split.js.map +1 -1
- package/dist/api/surface/arg-spec.d.ts +8 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/sweep.d.ts +1 -1
- package/dist/api/sweep.js +1 -1
- package/dist/api/sweep.js.map +1 -1
- package/dist/api/thicken.d.ts +1 -1
- package/dist/api/thicken.js +1 -1
- package/dist/api/thicken.js.map +1 -1
- package/dist/api/topo-resolve.d.ts +74 -1
- package/dist/api/topo-resolve.d.ts.map +1 -1
- package/dist/api/topo-resolve.js +180 -2
- package/dist/api/topo-resolve.js.map +1 -1
- package/dist/api/transform.d.ts +10 -6
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +74 -21
- package/dist/api/transform.js.map +1 -1
- package/dist/api/wire.d.ts +1 -1
- package/dist/api/wire.js +1 -1
- package/dist/api/wire.js.map +1 -1
- package/dist/api/xml-dom.d.ts +27 -0
- package/dist/api/xml-dom.d.ts.map +1 -0
- package/dist/api/xml-dom.js +45 -0
- package/dist/api/xml-dom.js.map +1 -0
- package/dist/brep/brep-ops.d.ts +13 -11
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +31 -30
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/brep-topology.d.ts +5 -4
- package/dist/brep/brep-topology.d.ts.map +1 -1
- package/dist/brep/brep-topology.js +9 -6
- package/dist/brep/brep-topology.js.map +1 -1
- package/dist/brep/effective-deflection.d.ts +35 -0
- package/dist/brep/effective-deflection.d.ts.map +1 -0
- package/dist/brep/effective-deflection.js +49 -0
- package/dist/brep/effective-deflection.js.map +1 -0
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +27 -0
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/adapters/brepkit.d.ts +18 -0
- package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brepkit.js +46 -1
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts +1 -1
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +3 -1
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +29 -7
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/registry.d.ts +24 -1
- package/dist/brep/engine/registry.d.ts.map +1 -1
- package/dist/brep/engine/registry.js +24 -0
- package/dist/brep/engine/registry.js.map +1 -1
- package/dist/brep/engine/types.d.ts +54 -3
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js +10 -0
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brep/export/export-model.d.ts +79 -0
- package/dist/brep/export/export-model.d.ts.map +1 -0
- package/dist/brep/export/export-model.js +336 -0
- package/dist/brep/export/export-model.js.map +1 -0
- package/dist/brep/face-evolution.d.ts +1 -1
- package/dist/brep/face-evolution.d.ts.map +1 -1
- package/dist/brep/face-evolution.js +20 -1
- package/dist/brep/face-evolution.js.map +1 -1
- package/dist/brep/handle-bridge.d.ts +1 -1
- package/dist/brep/handle-bridge.js +1 -1
- package/dist/brep/handle-bridge.js.map +1 -1
- package/dist/brep/mesh-solid.d.ts +218 -0
- package/dist/brep/mesh-solid.d.ts.map +1 -0
- package/dist/brep/mesh-solid.js +229 -0
- package/dist/brep/mesh-solid.js.map +1 -0
- package/dist/brep/primitives-brep.d.ts.map +1 -1
- package/dist/brep/primitives-brep.js +3 -1
- package/dist/brep/primitives-brep.js.map +1 -1
- package/dist/brep/text/fontRegistry.d.ts +32 -1
- package/dist/brep/text/fontRegistry.d.ts.map +1 -1
- package/dist/brep/text/fontRegistry.js +51 -1
- package/dist/brep/text/fontRegistry.js.map +1 -1
- package/dist/brep/text/text-to-solid.d.ts.map +1 -1
- package/dist/brep/text/text-to-solid.js +8 -3
- package/dist/brep/text/text-to-solid.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +18 -2
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +453 -125
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/brepkit-kernel/brepkitWasm.d.ts +8 -0
- package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitWasm.js +10 -0
- package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
- package/dist/browser-host/browser-font-provider.d.ts +12 -0
- package/dist/browser-host/browser-font-provider.d.ts.map +1 -1
- package/dist/browser-host/browser-font-provider.js +25 -0
- package/dist/browser-host/browser-font-provider.js.map +1 -1
- package/dist/browser.d.ts +6 -3
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +10 -3
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +28 -3
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +119 -4
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts +19 -3
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +49 -1
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +3 -3
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/preview-exec.d.ts +4 -4
- package/dist/cad-runtime/preview-exec.js +2 -2
- package/dist/cad-runtime/preview-exec.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +66 -8
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +121 -8
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +37 -1
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +25 -1
- package/dist/define-op.js.map +1 -1
- package/dist/env-agnostic.d.ts +7 -7
- package/dist/env-agnostic.d.ts.map +1 -1
- package/dist/env-agnostic.js +3 -3
- package/dist/env-agnostic.js.map +1 -1
- package/dist/geometry2d/adapt.d.ts +39 -4
- package/dist/geometry2d/adapt.d.ts.map +1 -1
- package/dist/geometry2d/adapt.js +14 -3
- package/dist/geometry2d/adapt.js.map +1 -1
- package/dist/geometry2d/blueprint.d.ts +2 -2
- package/dist/geometry2d/blueprint.js +2 -2
- package/dist/geometry2d/blueprint.js.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.d.ts +18 -8
- package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.js +71 -12
- package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
- package/dist/geometry2d/bridge/plane.d.ts +17 -0
- package/dist/geometry2d/bridge/plane.d.ts.map +1 -1
- package/dist/geometry2d/bridge/plane.js +22 -0
- package/dist/geometry2d/bridge/plane.js.map +1 -1
- package/dist/geometry2d/curve2d.d.ts +25 -0
- package/dist/geometry2d/curve2d.d.ts.map +1 -1
- package/dist/geometry2d/curve2d.js +41 -5
- package/dist/geometry2d/curve2d.js.map +1 -1
- package/dist/geometry2d/pen-sketcher.d.ts +25 -0
- package/dist/geometry2d/pen-sketcher.d.ts.map +1 -1
- package/dist/geometry2d/pen-sketcher.js +43 -0
- package/dist/geometry2d/pen-sketcher.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/io/bytes-node.d.ts +11 -0
- package/dist/io/bytes-node.d.ts.map +1 -0
- package/dist/io/bytes-node.js +28 -0
- package/dist/io/bytes-node.js.map +1 -0
- package/dist/io/bytes.d.ts +33 -0
- package/dist/io/bytes.d.ts.map +1 -0
- package/dist/io/bytes.js +41 -0
- package/dist/io/bytes.js.map +1 -0
- package/dist/io/fai-zip/container-read.d.ts +102 -0
- package/dist/io/fai-zip/container-read.d.ts.map +1 -0
- package/dist/io/fai-zip/container-read.js +305 -0
- package/dist/io/fai-zip/container-read.js.map +1 -0
- package/dist/io/fai-zip/container-write.d.ts +70 -0
- package/dist/io/fai-zip/container-write.d.ts.map +1 -0
- package/dist/io/fai-zip/container-write.js +186 -0
- package/dist/io/fai-zip/container-write.js.map +1 -0
- package/dist/io/fai-zip/container.d.ts +107 -0
- package/dist/io/fai-zip/container.d.ts.map +1 -0
- package/dist/io/fai-zip/container.js +89 -0
- package/dist/io/fai-zip/container.js.map +1 -0
- package/dist/io/fai-zip/index.d.ts +18 -0
- package/dist/io/fai-zip/index.d.ts.map +1 -0
- package/dist/io/fai-zip/index.js +4 -0
- package/dist/io/fai-zip/index.js.map +1 -0
- package/dist/io/index.d.ts +10 -0
- package/dist/io/index.d.ts.map +1 -0
- package/dist/io/index.js +13 -0
- package/dist/io/index.js.map +1 -0
- package/dist/io/zip.d.ts +68 -0
- package/dist/io/zip.d.ts.map +1 -0
- package/dist/io/zip.js +147 -0
- package/dist/io/zip.js.map +1 -0
- package/dist/lang/code-to-args.d.ts +30 -4
- package/dist/lang/code-to-args.d.ts.map +1 -1
- package/dist/lang/code-to-args.js +42 -3
- package/dist/lang/code-to-args.js.map +1 -1
- package/dist/lang/codegen.d.ts +45 -1
- package/dist/lang/codegen.d.ts.map +1 -1
- package/dist/lang/codegen.js +135 -6
- package/dist/lang/codegen.js.map +1 -1
- package/dist/lang/host-arg.d.ts +6 -0
- package/dist/lang/host-arg.d.ts.map +1 -1
- package/dist/lang/host-arg.js.map +1 -1
- package/dist/lang/metadata-extractor.d.ts +25 -0
- package/dist/lang/metadata-extractor.d.ts.map +1 -1
- package/dist/lang/metadata-extractor.js +289 -25
- package/dist/lang/metadata-extractor.js.map +1 -1
- package/dist/lang/parse-error.d.ts +7 -1
- package/dist/lang/parse-error.d.ts.map +1 -1
- package/dist/lang/parse-error.js.map +1 -1
- package/dist/lang/security-scanner.d.ts +9 -1
- package/dist/lang/security-scanner.d.ts.map +1 -1
- package/dist/lang/security-scanner.js +38 -1
- package/dist/lang/security-scanner.js.map +1 -1
- package/dist/lang/statement-summary.d.ts +1 -1
- package/dist/lang/statement-summary.js +1 -1
- package/dist/lang/statement-summary.js.map +1 -1
- package/dist/lang/types.d.ts +1 -1
- package/dist/lang/types.js +1 -1
- package/dist/lang/types.js.map +1 -1
- package/dist/mesh/index.d.ts +2 -1
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +2 -1
- package/dist/mesh/index.js.map +1 -1
- package/dist/mesh/io.d.ts +69 -9
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +121 -17
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/reconcile.d.ts +1 -1
- package/dist/mesh/reconcile.js +1 -1
- package/dist/mesh/reconcile.js.map +1 -1
- package/dist/mesh/rigid-transform.d.ts +3 -3
- package/dist/mesh/rigid-transform.js +3 -3
- package/dist/mesh/rigid-transform.js.map +1 -1
- package/dist/mesh/stl-unit.d.ts +24 -0
- package/dist/mesh/stl-unit.d.ts.map +1 -0
- package/dist/mesh/stl-unit.js +17 -0
- package/dist/mesh/stl-unit.js.map +1 -0
- package/dist/mesh/threemf-bambu.d.ts +142 -0
- package/dist/mesh/threemf-bambu.d.ts.map +1 -0
- package/dist/mesh/threemf-bambu.js +334 -0
- package/dist/mesh/threemf-bambu.js.map +1 -0
- package/dist/mesh/threemf-loader.d.ts +50 -0
- package/dist/mesh/threemf-loader.d.ts.map +1 -0
- package/dist/mesh/threemf-loader.js +628 -0
- package/dist/mesh/threemf-loader.js.map +1 -0
- package/dist/mesh/threemf-view.d.ts +71 -0
- package/dist/mesh/threemf-view.d.ts.map +1 -0
- package/dist/mesh/threemf-view.js +100 -0
- package/dist/mesh/threemf-view.js.map +1 -0
- package/dist/mesh/transform.d.ts +2 -2
- package/dist/mesh/transform.d.ts.map +1 -1
- package/dist/mesh/transform.js +3 -3
- package/dist/mesh/transform.js.map +1 -1
- package/dist/mesh/types.d.ts +1 -1
- package/dist/mesh/types.d.ts.map +1 -1
- package/dist/mesh/types.js.map +1 -1
- package/dist/node-host/cli.d.ts +44 -6
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +127 -50
- package/dist/node-host/cli.js.map +1 -1
- package/dist/node-host/font-family-index.d.ts +93 -0
- package/dist/node-host/font-family-index.d.ts.map +1 -0
- package/dist/node-host/font-family-index.js +273 -0
- package/dist/node-host/font-family-index.js.map +1 -0
- package/dist/node-host/fs-asset-resolver.d.ts +8 -3
- package/dist/node-host/fs-asset-resolver.d.ts.map +1 -1
- package/dist/node-host/fs-asset-resolver.js +13 -5
- package/dist/node-host/fs-asset-resolver.js.map +1 -1
- package/dist/node-host/index.d.ts +8 -0
- package/dist/node-host/index.d.ts.map +1 -1
- package/dist/node-host/index.js +1 -0
- package/dist/node-host/index.js.map +1 -1
- package/dist/node-host/node-font-provider.d.ts +28 -0
- package/dist/node-host/node-font-provider.d.ts.map +1 -1
- package/dist/node-host/node-font-provider.js +49 -0
- package/dist/node-host/node-font-provider.js.map +1 -1
- package/dist/node.d.ts +1 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +1 -0
- package/dist/node.js.map +1 -1
- package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
- package/dist/occt-kernel/occt-primitives.js +35 -2
- package/dist/occt-kernel/occt-primitives.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts +18 -13
- package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
- package/dist/occt-kernel/occtKernel.js +20 -31
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-kernel/stepColorParser.d.ts +18 -0
- package/dist/occt-kernel/stepColorParser.d.ts.map +1 -1
- package/dist/occt-kernel/stepColorParser.js +38 -0
- package/dist/occt-kernel/stepColorParser.js.map +1 -1
- package/dist/occt-kernel/topologyExt.d.ts +1 -1
- package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
- package/dist/occt-kernel/topologyExt.js +8 -6
- package/dist/occt-kernel/topologyExt.js.map +1 -1
- package/dist/primitives/text/cjk-font.d.ts +2 -15
- package/dist/primitives/text/cjk-font.d.ts.map +1 -1
- package/dist/primitives/text/cjk-font.js +13 -1
- package/dist/primitives/text/cjk-font.js.map +1 -1
- package/dist/runtime-state.d.ts +103 -9
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +95 -2
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +4 -4
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +6 -6
- package/dist/sdk.js.map +1 -1
- package/dist/shape.d.ts +97 -2
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +126 -1
- package/dist/shape.js.map +1 -1
- package/dist/tolerance.d.ts +38 -0
- package/dist/tolerance.d.ts.map +1 -0
- package/dist/tolerance.js +40 -0
- package/dist/tolerance.js.map +1 -0
- package/dist/topology/naming/lineage.d.ts +6 -0
- package/dist/topology/naming/lineage.d.ts.map +1 -1
- package/dist/topology/naming/lineage.js +8 -0
- package/dist/topology/naming/lineage.js.map +1 -1
- package/dist/topology/naming/resolve-edge.d.ts +20 -1
- package/dist/topology/naming/resolve-edge.d.ts.map +1 -1
- package/dist/topology/naming/resolve-edge.js +54 -20
- package/dist/topology/naming/resolve-edge.js.map +1 -1
- package/dist/topology/naming/score.js +3 -3
- package/dist/topology/naming/score.js.map +1 -1
- package/dist/units.d.ts +248 -0
- package/dist/units.d.ts.map +1 -0
- package/dist/units.js +397 -0
- package/dist/units.js.map +1 -0
- package/dist/weapp.d.ts +6 -2
- package/dist/weapp.d.ts.map +1 -1
- package/dist/weapp.js +7 -1
- package/dist/weapp.js.map +1 -1
- package/package.json +28 -3
package/dist/api/boolean.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* api boolean — 布尔库函数(union/subtract/intersect,多输入)
|
|
3
3
|
*
|
|
4
4
|
*
|
|
5
5
|
* dispatchPath 静态判定 brep/mesh,BREP 路径用 *WithHistory 收集面演化。
|
|
@@ -12,9 +12,10 @@ import { solidToShape } from '../brep/brep-ops.js';
|
|
|
12
12
|
import { booleanWithRoleTable, } from '../brep/face-evolution.js';
|
|
13
13
|
import { getCurrentStmt, getBackends, keepHidden, nameOf } from '../runtime-state.js';
|
|
14
14
|
import { getBrepApi } from '../brep/handle-bridge.js';
|
|
15
|
-
import { fromBrep, brepOf, inputRoleTable } from '../shape.js';
|
|
15
|
+
import { fromBrep, brepOf, hasMeshSolid, inputRoleTable } from '../shape.js';
|
|
16
16
|
import { reconcileBrepInputs } from './reconcile.js';
|
|
17
17
|
import { OpError } from './internal/result-unwrap.js';
|
|
18
|
+
import { meshKernelFailure, meshSolidEntry, meshSolidProduct } from './internal/mesh-solid-op.js';
|
|
18
19
|
import { defineOp } from '../sdk.js';
|
|
19
20
|
import { engineCapabilitySet } from '../cad-runtime/backend-dispatch.js';
|
|
20
21
|
// ── 共享内部实现 ──
|
|
@@ -44,7 +45,7 @@ function booleanBrep(inputs, operation) {
|
|
|
44
45
|
const offenders = inputs
|
|
45
46
|
.map((s, i) => (inputSolids[i] ? undefined : nameOf(s) ?? `input[${i}]`))
|
|
46
47
|
.filter((x) => x !== undefined);
|
|
47
|
-
throw new OpError(`boolean/${operation}`, 'E_BREP_UNSUPPORTED', `[
|
|
48
|
+
throw new OpError(`boolean/${operation}`, 'E_BREP_UNSUPPORTED', `[api/boolean] ${operation}: input is not on the BREP chain (no OCCT handle) — ` +
|
|
48
49
|
`non-solid geometry (wire/face/shell) cannot take part in a boolean. offenders: ${offenders.join(', ')}`);
|
|
49
50
|
}
|
|
50
51
|
let resultSolid;
|
|
@@ -52,17 +53,42 @@ function booleanBrep(inputs, operation) {
|
|
|
52
53
|
let roleTable;
|
|
53
54
|
// 链式布尔:每步 target(累积结果)与下一个 tool 合流
|
|
54
55
|
const op = operation === 'union' ? 'fuse' : operation === 'subtract' ? 'cut' : 'intersect';
|
|
56
|
+
// F 组(2026-10-03,FAULHABER/Beam-coupling 语料):import_brep 资产可能是
|
|
57
|
+
// wire/face(ShapeBinder 冻结几何)——它们带 OCCT handle、能通过上面的
|
|
58
|
+
// 「无 handle」守卫,但 OCCT 的 BOP 只接受 solid:fuse(wire, solid) 直接
|
|
59
|
+
// "operation failed"(内核直测实证,PartShape5/PartShape6/PartShape93 均
|
|
60
|
+
// wire/face、vol=0)。C3c-1 已实证 0 体积线框成员对 compound invariants
|
|
61
|
+
// 零影响 ⇒ union 的语义是 solid 合流,非 solid 输入如实跳过(keepHidden
|
|
62
|
+
// 语义不变);全非 solid 才抛错。cut/intersect 语义不变(工具/交域必须 solid)。
|
|
63
|
+
const NON_SOLID = new Set(['wire', 'face', 'shell', 'vertex', 'edge']);
|
|
64
|
+
const inputTypes = inputSolids.map((h) => {
|
|
65
|
+
try {
|
|
66
|
+
return h ? kernel.shapeType(h) : 'solid';
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return 'solid';
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
// compound/compsolid 可能含 solid,是合法 fuse 输入——只跳过确定的非 solid 类型。
|
|
73
|
+
const boolIdx = operation === 'union'
|
|
74
|
+
? inputTypes.map((t, i) => (NON_SOLID.has(t) ? -1 : i)).filter((i) => i >= 0)
|
|
75
|
+
: inputs.map((_, i) => i);
|
|
76
|
+
if (operation === 'union' && boolIdx.length === 0) {
|
|
77
|
+
throw new OpError(`boolean/${operation}`, 'E_BREP_UNSUPPORTED', `[api/boolean] ${operation}: no solid input — wire/face/shell geometry cannot fuse (types: ${inputTypes.join(', ')})`);
|
|
78
|
+
}
|
|
55
79
|
// 静态定轨:当前引擎是否声明了本 op 的面演化核函数(读的是同一声明源 dispatchPath 用的
|
|
56
80
|
// 能力集,不是运行时探测)。fuse/cut 因 gate 保证此处恒 true;intersect 在 occt true、
|
|
57
81
|
// brepkit/mock false(后者走 L1 裸 `kernel[op]`,该方法是 BrepEngineApi 必需成员,必存在)。
|
|
58
82
|
const historyCap = op === 'fuse' ? 'fuseWithHistory' : op === 'cut' ? 'cutWithHistory' : 'intersectWithHistory';
|
|
59
83
|
const useHistory = engineCapabilitySet(getBackends().config.brepCapabilities).has(historyCap);
|
|
60
|
-
//
|
|
61
|
-
|
|
84
|
+
// 首个 solid 输入作为 target 起点(F 组:可能不是 inputs[0] —— wire/face
|
|
85
|
+
// 资产常排在前面作为 profile/binder)。
|
|
86
|
+
resultSolid = inputSolids[boolIdx[0]];
|
|
62
87
|
roleTable = useHistory
|
|
63
|
-
? inputRoleTable(inputs[0])
|
|
88
|
+
? inputRoleTable(inputs[boolIdx[0]])
|
|
64
89
|
: undefined;
|
|
65
|
-
for (let
|
|
90
|
+
for (let bi = 1; bi < boolIdx.length; bi++) {
|
|
91
|
+
const i = boolIdx[bi];
|
|
66
92
|
const prev = resultSolid;
|
|
67
93
|
const tool = inputSolids[i];
|
|
68
94
|
if (useHistory) {
|
|
@@ -77,9 +103,39 @@ function booleanBrep(inputs, operation) {
|
|
|
77
103
|
r = booleanWithRoleTable(kernel, op, prev, tool, prevTable ?? new Map(), toolTable ?? new Map(), outStmt);
|
|
78
104
|
}
|
|
79
105
|
catch (cause) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
106
|
+
// GOTCHA: OCCT 的 *WithHistory 在两输入共享子结构/历史(如布尔产物的布尔)
|
|
107
|
+
// 时可能 "operation failed",而同一几何的裸布尔可以成功。降级重试一次裸
|
|
108
|
+
// kernel[op]:几何结果正确,代价是丢本次面演化/roleTable(如实降级,同下方
|
|
109
|
+
// 裸路径语义)。裸布尔也失败时,再试 unifySameDomain(两输入) 后重算——
|
|
110
|
+
// 真实语料(disk-drive)中 tool 是布尔产物且与 target 共享子域,裸 cut 仍失败、
|
|
111
|
+
// unify 后成功。全部失败才真正抛错。
|
|
112
|
+
try {
|
|
113
|
+
resultSolid = kernel[op](prev, tool);
|
|
114
|
+
lastEvolution = undefined;
|
|
115
|
+
roleTable = undefined;
|
|
116
|
+
if (i > 1)
|
|
117
|
+
kernel.release(prev);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
try {
|
|
122
|
+
const uPrev = kernel.unifySameDomain(prev);
|
|
123
|
+
const uTool = kernel.unifySameDomain(tool);
|
|
124
|
+
resultSolid = kernel[op](uPrev, uTool);
|
|
125
|
+
kernel.release(uPrev);
|
|
126
|
+
kernel.release(uTool);
|
|
127
|
+
lastEvolution = undefined;
|
|
128
|
+
roleTable = undefined;
|
|
129
|
+
if (i > 1)
|
|
130
|
+
kernel.release(prev);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
135
|
+
throw new OpError(`boolean/${operation}`, 'E_OP_FAILED', `[api/boolean] ${operation}: kernel ${op} failed for inputs ` +
|
|
136
|
+
`${nameOf(inputs[0]) ?? 'input[0]'} × ${nameOf(inputs[i]) ?? `input[${i}]`} — ${msg}`, { cause });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
83
139
|
}
|
|
84
140
|
resultSolid = r.result;
|
|
85
141
|
lastEvolution = r.faceEvolution;
|
|
@@ -92,7 +148,7 @@ function booleanBrep(inputs, operation) {
|
|
|
92
148
|
}
|
|
93
149
|
catch (cause) {
|
|
94
150
|
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
95
|
-
throw new OpError(`boolean/${operation}`, 'E_OP_FAILED', `[
|
|
151
|
+
throw new OpError(`boolean/${operation}`, 'E_OP_FAILED', `[api/boolean] ${operation}: kernel ${op} failed for inputs ` +
|
|
96
152
|
`${nameOf(inputs[0]) ?? 'input[0]'} × ${nameOf(inputs[i]) ?? `input[${i}]`} — ${msg}`, { cause });
|
|
97
153
|
}
|
|
98
154
|
lastEvolution = undefined;
|
|
@@ -103,12 +159,64 @@ function booleanBrep(inputs, operation) {
|
|
|
103
159
|
}
|
|
104
160
|
return fromBrep(solidToShape(kernel, resultSolid), lastEvolution ? { solid: resultSolid, faceEvolution: lastEvolution, roleTable } : { solid: resultSolid, roleTable });
|
|
105
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* 网格实体路径:brepkit 网格内核的布尔(方案 2026-10-01 §3.5 三明治)。
|
|
164
|
+
*
|
|
165
|
+
* 输入**全部**是网格实体——这一点由 `dispatchPath` 的链门禁保证
|
|
166
|
+
* (`E_MESH_SOLID_MIXED`:网格实体不得与链外几何同处一次调用),此处只复核不补救。
|
|
167
|
+
*
|
|
168
|
+
* 无面演化、无 roleTable:近似拓扑没有 hash 演化,造一张恒等映射就是假身份
|
|
169
|
+
* (与 brepkit 裸布尔降级同一条纪律)。
|
|
170
|
+
*
|
|
171
|
+
* 中间结果是本实现自己造的句柄(不是任何输入),故 i>1 步及时释放;**输入句柄一概
|
|
172
|
+
* 不释放**——生命周期归链(与 BREP 路径 booleanBrep 的 `if (i > 1) kernel.release(prev)`
|
|
173
|
+
* 同构)。
|
|
174
|
+
*
|
|
175
|
+
* @param inputs - the mesh-solid inputs (≥1).
|
|
176
|
+
* @param operation - union / subtract / intersect.
|
|
177
|
+
* @returns the boolean result as a new mesh part.
|
|
178
|
+
*/
|
|
179
|
+
function booleanMeshSolid(inputs, operation) {
|
|
180
|
+
const opLabel = `boolean/${operation}`;
|
|
181
|
+
const entries = inputs.map((s) => meshSolidEntry(s, opLabel));
|
|
182
|
+
const first = entries[0];
|
|
183
|
+
const kernel = first.kernel;
|
|
184
|
+
const op = operation === 'union' ? 'fuse' : operation === 'subtract' ? 'cut' : 'intersect';
|
|
185
|
+
let result = first.solid;
|
|
186
|
+
for (let i = 1; i < entries.length; i++) {
|
|
187
|
+
const prev = result;
|
|
188
|
+
try {
|
|
189
|
+
result = kernel[op](prev, entries[i].solid);
|
|
190
|
+
}
|
|
191
|
+
catch (cause) {
|
|
192
|
+
throw meshKernelFailure(opLabel, 'E_OP_FAILED', `${op}(${nameOf(inputs[0]) ?? 'input[0]'} × ${nameOf(inputs[i]) ?? `input[${i}]`})`, cause);
|
|
193
|
+
}
|
|
194
|
+
// i>1:prev 是本实现上一步造出的中间实体,释放它(i=1 时 prev 是**输入**,不碰)。
|
|
195
|
+
if (i > 1)
|
|
196
|
+
first.backend.release(prev);
|
|
197
|
+
}
|
|
198
|
+
return meshSolidProduct(first, result);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 网格路径分流(方案 2026-10-01 §3.4 规则 4):输入含网格实体 → brepkit 网格内核;
|
|
202
|
+
* 否则保持历史上限(内置 `mesh/` 的 manifold CSG)。两条路**互不冒充**——
|
|
203
|
+
* manifold 不认识网格实体(静态门禁),网格内核也不接受裸网格(无句柄)。
|
|
204
|
+
*
|
|
205
|
+
* @param inputs - the geometry inputs.
|
|
206
|
+
* @param operation - union / subtract / intersect.
|
|
207
|
+
* @returns the boolean product (mesh solid or manifold mesh shape).
|
|
208
|
+
*/
|
|
209
|
+
function booleanMeshPath(inputs, operation) {
|
|
210
|
+
if (inputs.some(hasMeshSolid))
|
|
211
|
+
return booleanMeshSolid(inputs, operation);
|
|
212
|
+
return booleanMesh(inputs, operation);
|
|
213
|
+
}
|
|
106
214
|
/** mesh 路径:manifold-3d mesh-CSG。 */
|
|
107
215
|
async function booleanMesh(inputs, operation) {
|
|
108
216
|
if (inputs.length < 2) {
|
|
109
217
|
if (inputs.length === 1)
|
|
110
218
|
return inputs[0];
|
|
111
|
-
throw new Error('[
|
|
219
|
+
throw new Error('[api/boolean] boolean needs at least 1 input');
|
|
112
220
|
}
|
|
113
221
|
if (operation === 'union')
|
|
114
222
|
return cad.union(inputs[0], inputs[1], ...inputs.slice(2));
|
|
@@ -141,10 +249,11 @@ async function booleanMesh(inputs, operation) {
|
|
|
141
249
|
* const a = await cad.union(part0, part1)
|
|
142
250
|
*/
|
|
143
251
|
export const union = defineOp({
|
|
252
|
+
meshEngines: ['brepkit'],
|
|
144
253
|
mesh: (...shapes) => {
|
|
145
254
|
if (shapes.length > 0)
|
|
146
255
|
keepHidden(...shapes);
|
|
147
|
-
return
|
|
256
|
+
return booleanMeshPath(reconcileBrepInputs(shapes), 'union');
|
|
148
257
|
},
|
|
149
258
|
brep: (...shapes) => {
|
|
150
259
|
if (shapes.length > 0)
|
|
@@ -175,9 +284,10 @@ export const union = defineOp({
|
|
|
175
284
|
* const b = await cad.cut(part0, part1)
|
|
176
285
|
*/
|
|
177
286
|
export const cut = defineOp({
|
|
287
|
+
meshEngines: ['brepkit'],
|
|
178
288
|
mesh: (base, tool) => {
|
|
179
289
|
keepHidden(base, tool);
|
|
180
|
-
return
|
|
290
|
+
return booleanMeshPath(reconcileBrepInputs([base, tool]), 'subtract');
|
|
181
291
|
},
|
|
182
292
|
brep: (base, tool) => {
|
|
183
293
|
keepHidden(base, tool);
|
|
@@ -199,10 +309,11 @@ export const cut = defineOp({
|
|
|
199
309
|
* const b = await cad.subtract(part0, part1)
|
|
200
310
|
*/
|
|
201
311
|
export const subtract = defineOp({
|
|
312
|
+
meshEngines: ['brepkit'],
|
|
202
313
|
mesh: (...shapes) => {
|
|
203
314
|
if (shapes.length > 0)
|
|
204
315
|
keepHidden(...shapes);
|
|
205
|
-
return
|
|
316
|
+
return booleanMeshPath(reconcileBrepInputs(shapes), 'subtract');
|
|
206
317
|
},
|
|
207
318
|
brep: (...shapes) => {
|
|
208
319
|
if (shapes.length > 0)
|
|
@@ -226,10 +337,11 @@ export const subtract = defineOp({
|
|
|
226
337
|
* const c = await cad.intersect(part0, part1)
|
|
227
338
|
*/
|
|
228
339
|
export const intersect = defineOp({
|
|
340
|
+
meshEngines: ['brepkit'],
|
|
229
341
|
mesh: (...shapes) => {
|
|
230
342
|
if (shapes.length > 0)
|
|
231
343
|
keepHidden(...shapes);
|
|
232
|
-
return
|
|
344
|
+
return booleanMeshPath(reconcileBrepInputs(shapes), 'intersect');
|
|
233
345
|
},
|
|
234
346
|
brep: (...shapes) => {
|
|
235
347
|
if (shapes.length > 0)
|
package/dist/api/boolean.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boolean.js","sourceRoot":"","sources":["../../src/api/boolean.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib boolean — 布尔库函数(union/subtract/intersect,多输入)\n *\n *\n * dispatchPath 静态判定 brep/mesh,BREP 路径用 *WithHistory 收集面演化。\n *\n * 阶段 1:拆为三个薄函数 union/subtract/intersect + 兼容 boolean 导出(过渡)。\n * 阶段 3 将删除 boolean 兼容导出。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { solidToShape } from '../brep/brep-ops'\nimport {\n booleanWithRoleTable,\n} from '../brep/face-evolution'\nimport { getCurrentStmt, getBackends, keepHidden, nameOf } from '../runtime-state'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep, brepOf, inputRoleTable } from '../shape'\nimport { reconcileBrepInputs } from './reconcile'\nimport { OpError } from './internal/result-unwrap'\nimport { defineOp } from '../sdk'\nimport { engineCapabilitySet } from '../cad-runtime/backend-dispatch'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle } from '../brep/engine/types'\n\ntype BooleanOperation = 'union' | 'subtract' | 'intersect'\n\n// ── 共享内部实现 ──\n\n/**\n * BREP 路径:fuse/cut/intersect。\n *\n * 静态双轨(无运行时 try-catch 回退——按引擎**声明**的能力集在执行前定轨):\n * - 引擎声明了对应 `*WithHistory`(occt 三员全有)→ `booleanWithRoleTable`:\n * 一次内核调用同时产出结果 + 面演化(faceEvolution)+ roleTable 合流(§3.4)。\n * - 引擎只声明了裸布尔方法(brepkit:声明了 `intersect` 但**没有** `intersectWithHistory`)\n * → 走 L1 裸 `kernel[op](a,b)`:几何正确,但**不产生面演化、不传播 roleTable**。\n * 这是如实降级——绝不用「恒等映射」伪造一张把输入面 hash 指到结果面 hash 的演化表\n * (结果实体的面 hash 与输入根本不同,恒等映射是假身份)。\n *\n * `intersect` 因此不再声明 `capabilities: ['intersectWithHistory']`(中立 op):\n * brepkit 上由本函数静态落到裸 `intersect`;occt 上仍走 `intersectWithHistory`。\n * fuse/cut 保留各自 `*WithHistory` 能力声明——dispatchPath 的 gate 保证它们到达本函数时\n * 引擎必已声明对应历史方法,故下方 `useHistory` 对 fuse/cut 恒为 true。\n */\nfunction booleanBrep(inputs: Shape[], operation: BooleanOperation): Shape {\n const kernel = getBrepApi()\n\n const inputSolids = inputs.map((s) => brepOf(s) as BrepHandle | undefined)\n if (inputSolids.some((s) => !s)) {\n // V-C8 (C6): a non-solid import (wire/face/shell via cad.import_brep) has\n // no OCCT handle yet — booleans must fail HERE with an explicit, op-named\n // error, not with OCCT's raw \"boolean operation failed\" (or silently).\n const offenders = inputs\n .map((s, i) => (inputSolids[i] ? undefined : nameOf(s) ?? `input[${i}]`))\n .filter((x): x is string => x !== undefined)\n throw new OpError(\n `boolean/${operation}`,\n 'E_BREP_UNSUPPORTED',\n `[stdlib/boolean] ${operation}: input is not on the BREP chain (no OCCT handle) — ` +\n `non-solid geometry (wire/face/shell) cannot take part in a boolean. offenders: ${offenders.join(', ')}`,\n )\n }\n\n let resultSolid: BrepHandle\n let lastEvolution: Map<number, number[]> | undefined\n let roleTable: ReadonlyMap<unknown, unknown> | undefined\n\n // 链式布尔:每步 target(累积结果)与下一个 tool 合流\n const op: 'fuse' | 'cut' | 'intersect' =\n operation === 'union' ? 'fuse' : operation === 'subtract' ? 'cut' : 'intersect'\n\n // 静态定轨:当前引擎是否声明了本 op 的面演化核函数(读的是同一声明源 dispatchPath 用的\n // 能力集,不是运行时探测)。fuse/cut 因 gate 保证此处恒 true;intersect 在 occt true、\n // brepkit/mock false(后者走 L1 裸 `kernel[op]`,该方法是 BrepEngineApi 必需成员,必存在)。\n const historyCap = op === 'fuse' ? 'fuseWithHistory' : op === 'cut' ? 'cutWithHistory' : 'intersectWithHistory'\n const useHistory = engineCapabilitySet(getBackends().config.brepCapabilities).has(historyCap)\n\n // 首个输入作为 target 起点\n resultSolid = inputSolids[0]!\n roleTable = useHistory\n ? (inputRoleTable(inputs[0]) as ReadonlyMap<unknown, unknown> | undefined)\n : undefined\n\n for (let i = 1; i < inputSolids.length; i++) {\n const prev = resultSolid\n const tool = inputSolids[i]!\n\n if (useHistory) {\n // §3.4:一次内核调用,A/B 拆流各自传播后合表(缝面 origin=本次语句 StmtId)\n // V-C8:内核裸错误在此包一层——带上 op 名、两个输入的变量名与 cause。\n const prevTable = roleTable\n const toolTable = inputRoleTable(inputs[i]) as ReadonlyMap<unknown, unknown> | undefined\n // Phase 1.6:新 origin = 本次语句的 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n let r: ReturnType<typeof booleanWithRoleTable>\n try {\n r = booleanWithRoleTable(\n kernel,\n op,\n prev,\n tool,\n prevTable ?? new Map(),\n toolTable ?? new Map(),\n outStmt,\n )\n } catch (cause) {\n const msg = cause instanceof Error ? cause.message : String(cause)\n throw new OpError(\n `boolean/${operation}`,\n 'E_OP_FAILED',\n `[stdlib/boolean] ${operation}: kernel ${op} failed for inputs ` +\n `${nameOf(inputs[0]!) ?? 'input[0]'} × ${nameOf(inputs[i]!) ?? `input[${i}]`} — ${msg}`,\n { cause },\n )\n }\n resultSolid = r.result\n lastEvolution = r.faceEvolution\n roleTable = r.roleTable\n } else {\n // 裸布尔降级路径:几何正确,但无面演化、无 roleTable 传播(如实降级,不伪造映射)。\n try {\n resultSolid = kernel[op](prev, tool)\n } catch (cause) {\n const msg = cause instanceof Error ? cause.message : String(cause)\n throw new OpError(\n `boolean/${operation}`,\n 'E_OP_FAILED',\n `[stdlib/boolean] ${operation}: kernel ${op} failed for inputs ` +\n `${nameOf(inputs[0]!) ?? 'input[0]'} × ${nameOf(inputs[i]!) ?? `input[${i}]`} — ${msg}`,\n { cause },\n )\n }\n lastEvolution = undefined\n roleTable = undefined\n }\n if (i > 1) kernel.release(prev)\n }\n\n return fromBrep(\n solidToShape(kernel, resultSolid),\n lastEvolution ? { solid: resultSolid, faceEvolution: lastEvolution, roleTable } : { solid: resultSolid, roleTable },\n )\n}\n\n/** mesh 路径:manifold-3d mesh-CSG。 */\nasync function booleanMesh(inputs: Shape[], operation: BooleanOperation): Promise<Shape> {\n if (inputs.length < 2) {\n if (inputs.length === 1) return inputs[0]\n throw new Error('[stdlib/boolean] boolean needs at least 1 input')\n }\n if (operation === 'union') return cad.union(inputs[0], inputs[1], ...inputs.slice(2))\n if (operation === 'subtract') {\n let result = await cad.subtract(inputs[0], inputs[1])\n for (let i = 2; i < inputs.length; i++) result = await cad.subtract(result, inputs[i])\n return result\n }\n let result = await cad.intersect(inputs[0], inputs[1])\n for (let i = 2; i < inputs.length; i++) result = await cad.intersect(result, inputs[i])\n return result\n}\n\n// ── 三个薄导出(多输入 variadic,defineOp 声明双路径 + 逐核函数 face-evolution 能力) ──\n// 函数体 keep 声明(keep-syntax 设计 §2.5):union/subtract/intersect 保留其\n// 输入且隐藏(R5:3d_editor 现状)——keepHidden 使源变量保持终端但 canvas\n// 不渲染,只有布尔结果正常显示。混合/断链时刻:BREP 侧输入先归约为合法\n// 2-manifold 网格(reconcileBrepInputs),mesh 侧原样透传。\n\n/**\n * 布尔并集:合并所有输入几何(≥2 个输入)。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name union\n * @param shapes - 参与运算的几何(变量引用,≥2 个)。type:Shape[] required:true\n * @returns Shape 所有输入的并集。函数名即操作,输入全是变量引用,可用 `cad.union(a, b, c)` 多输入。\n * @example\n * const a = await cad.union(part0, part1)\n */\nexport const union = defineOp({\n mesh: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanMesh(reconcileBrepInputs(shapes), 'union')\n },\n brep: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanBrep(shapes, 'union')\n },\n // 逐核函数声明(Phase 0.2):union 需要内核的 fuseWithHistory。\n // 不再声明族级 'evolution'——族级名会让 brepkit(无 intersectWithHistory)等\n // 部分实现的内核静默通过静态判定,再死在运行时(红线违规)。\n capabilities: ['fuseWithHistory'],\n schema: { shapes: 'Shape*' },\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * Boolean cut (subtract): remove `tool` from `base`. Same semantics as\n * {@link subtract} but with the brepjs-compatible `(base, tool, options?)` signature.\n * Overrides the generated projection (compatOp) to do roleTable propagation\n * (Phase 3: L2 requires wall:<i> to survive cut).\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name cut\n * @param base - the target shape. type:Shape required:true\n * @param tool - the shape to subtract. type:Shape required:true\n * @returns Shape base minus tool.\n * @example\n * const b = await cad.cut(part0, part1)\n */\nexport const cut = defineOp({\n mesh: (base: Shape, tool: Shape) => {\n keepHidden(base, tool)\n return booleanMesh(reconcileBrepInputs([base, tool]), 'subtract')\n },\n brep: (base: Shape, tool: Shape) => {\n keepHidden(base, tool)\n return booleanBrep([base, tool], 'subtract')\n },\n capabilities: ['cutWithHistory'],\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * 布尔差集:第一个为主体,减去其余输入。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name subtract\n * @param shapes - 参与运算的几何(变量引用,第一个为主体)。type:Shape[] required:true\n * @returns Shape part0 减 part1 的差集(第一个为主体)。\n * @example\n * const b = await cad.subtract(part0, part1)\n */\nexport const subtract = defineOp({\n mesh: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanMesh(reconcileBrepInputs(shapes), 'subtract')\n },\n brep: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanBrep(shapes, 'subtract')\n },\n // 逐核函数声明(Phase 0.2):subtract 需要内核的 cutWithHistory。\n capabilities: ['cutWithHistory'],\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * 布尔交集:所有输入的重叠部分。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name intersect\n * @param shapes - 参与运算的几何(变量引用)。type:Shape[] required:true\n * @returns Shape 所有输入的交集。\n * @example\n * const c = await cad.intersect(part0, part1)\n */\nexport const intersect = defineOp({\n mesh: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanMesh(reconcileBrepInputs(shapes), 'intersect')\n },\n brep: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanBrep(shapes, 'intersect')\n },\n // 不声明 `capabilities: ['intersectWithHistory']`(中立 op):\n // brepkit 声明了裸 `intersect` 但没有 `intersectWithHistory`——若硬声明历史能力,\n // brepkit brep 模式会在执行前静态报 `lacks capability 'intersectWithHistory'`。\n // 现由 booleanBrep 按引擎声明的能力集静态分派:occt(声明 intersectWithHistory)\n // 走历史路径保留面演化/naming;brepkit(只声明裸 intersect)走 L1 裸 `kernel.intersect`,\n // 几何正确但无面演化(如实降级,不伪造恒等映射)。\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n"]}
|
|
1
|
+
{"version":3,"file":"boolean.js","sourceRoot":"","sources":["../../src/api/boolean.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api boolean — 布尔库函数(union/subtract/intersect,多输入)\n *\n *\n * dispatchPath 静态判定 brep/mesh,BREP 路径用 *WithHistory 收集面演化。\n *\n * 阶段 1:拆为三个薄函数 union/subtract/intersect + 兼容 boolean 导出(过渡)。\n * 阶段 3 将删除 boolean 兼容导出。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { solidToShape } from '../brep/brep-ops'\nimport {\n booleanWithRoleTable,\n} from '../brep/face-evolution'\nimport { getCurrentStmt, getBackends, keepHidden, nameOf } from '../runtime-state'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep, brepOf, hasMeshSolid, inputRoleTable } from '../shape'\nimport { reconcileBrepInputs } from './reconcile'\nimport { OpError } from './internal/result-unwrap'\nimport { meshKernelFailure, meshSolidEntry, meshSolidProduct } from './internal/mesh-solid-op'\nimport { defineOp } from '../sdk'\nimport { engineCapabilitySet } from '../cad-runtime/backend-dispatch'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle } from '../brep/engine/types'\n\ntype BooleanOperation = 'union' | 'subtract' | 'intersect'\n\n// ── 共享内部实现 ──\n\n/**\n * BREP 路径:fuse/cut/intersect。\n *\n * 静态双轨(无运行时 try-catch 回退——按引擎**声明**的能力集在执行前定轨):\n * - 引擎声明了对应 `*WithHistory`(occt 三员全有)→ `booleanWithRoleTable`:\n * 一次内核调用同时产出结果 + 面演化(faceEvolution)+ roleTable 合流(§3.4)。\n * - 引擎只声明了裸布尔方法(brepkit:声明了 `intersect` 但**没有** `intersectWithHistory`)\n * → 走 L1 裸 `kernel[op](a,b)`:几何正确,但**不产生面演化、不传播 roleTable**。\n * 这是如实降级——绝不用「恒等映射」伪造一张把输入面 hash 指到结果面 hash 的演化表\n * (结果实体的面 hash 与输入根本不同,恒等映射是假身份)。\n *\n * `intersect` 因此不再声明 `capabilities: ['intersectWithHistory']`(中立 op):\n * brepkit 上由本函数静态落到裸 `intersect`;occt 上仍走 `intersectWithHistory`。\n * fuse/cut 保留各自 `*WithHistory` 能力声明——dispatchPath 的 gate 保证它们到达本函数时\n * 引擎必已声明对应历史方法,故下方 `useHistory` 对 fuse/cut 恒为 true。\n */\nfunction booleanBrep(inputs: Shape[], operation: BooleanOperation): Shape {\n const kernel = getBrepApi()\n\n const inputSolids = inputs.map((s) => brepOf(s) as BrepHandle | undefined)\n if (inputSolids.some((s) => !s)) {\n // V-C8 (C6): a non-solid import (wire/face/shell via cad.import_brep) has\n // no OCCT handle yet — booleans must fail HERE with an explicit, op-named\n // error, not with OCCT's raw \"boolean operation failed\" (or silently).\n const offenders = inputs\n .map((s, i) => (inputSolids[i] ? undefined : nameOf(s) ?? `input[${i}]`))\n .filter((x): x is string => x !== undefined)\n throw new OpError(\n `boolean/${operation}`,\n 'E_BREP_UNSUPPORTED',\n `[api/boolean] ${operation}: input is not on the BREP chain (no OCCT handle) — ` +\n `non-solid geometry (wire/face/shell) cannot take part in a boolean. offenders: ${offenders.join(', ')}`,\n )\n }\n\n let resultSolid: BrepHandle\n let lastEvolution: Map<number, number[]> | undefined\n let roleTable: ReadonlyMap<unknown, unknown> | undefined\n\n // 链式布尔:每步 target(累积结果)与下一个 tool 合流\n const op: 'fuse' | 'cut' | 'intersect' =\n operation === 'union' ? 'fuse' : operation === 'subtract' ? 'cut' : 'intersect'\n\n // F 组(2026-10-03,FAULHABER/Beam-coupling 语料):import_brep 资产可能是\n // wire/face(ShapeBinder 冻结几何)——它们带 OCCT handle、能通过上面的\n // 「无 handle」守卫,但 OCCT 的 BOP 只接受 solid:fuse(wire, solid) 直接\n // \"operation failed\"(内核直测实证,PartShape5/PartShape6/PartShape93 均\n // wire/face、vol=0)。C3c-1 已实证 0 体积线框成员对 compound invariants\n // 零影响 ⇒ union 的语义是 solid 合流,非 solid 输入如实跳过(keepHidden\n // 语义不变);全非 solid 才抛错。cut/intersect 语义不变(工具/交域必须 solid)。\n const NON_SOLID = new Set(['wire', 'face', 'shell', 'vertex', 'edge'])\n const inputTypes = inputSolids.map((h) => {\n try { return h ? (kernel.shapeType(h) as string) : 'solid' } catch { return 'solid' }\n })\n // compound/compsolid 可能含 solid,是合法 fuse 输入——只跳过确定的非 solid 类型。\n const boolIdx = operation === 'union'\n ? inputTypes.map((t, i) => (NON_SOLID.has(t) ? -1 : i)).filter((i) => i >= 0)\n : inputs.map((_, i) => i)\n if (operation === 'union' && boolIdx.length === 0) {\n throw new OpError(\n `boolean/${operation}`,\n 'E_BREP_UNSUPPORTED',\n `[api/boolean] ${operation}: no solid input — wire/face/shell geometry cannot fuse (types: ${inputTypes.join(', ')})`,\n )\n }\n\n // 静态定轨:当前引擎是否声明了本 op 的面演化核函数(读的是同一声明源 dispatchPath 用的\n // 能力集,不是运行时探测)。fuse/cut 因 gate 保证此处恒 true;intersect 在 occt true、\n // brepkit/mock false(后者走 L1 裸 `kernel[op]`,该方法是 BrepEngineApi 必需成员,必存在)。\n const historyCap = op === 'fuse' ? 'fuseWithHistory' : op === 'cut' ? 'cutWithHistory' : 'intersectWithHistory'\n const useHistory = engineCapabilitySet(getBackends().config.brepCapabilities).has(historyCap)\n\n // 首个 solid 输入作为 target 起点(F 组:可能不是 inputs[0] —— wire/face\n // 资产常排在前面作为 profile/binder)。\n resultSolid = inputSolids[boolIdx[0]!]!\n roleTable = useHistory\n ? (inputRoleTable(inputs[boolIdx[0]!]) as ReadonlyMap<unknown, unknown> | undefined)\n : undefined\n\n for (let bi = 1; bi < boolIdx.length; bi++) {\n const i = boolIdx[bi]!\n const prev = resultSolid\n const tool = inputSolids[i]!\n\n if (useHistory) {\n // §3.4:一次内核调用,A/B 拆流各自传播后合表(缝面 origin=本次语句 StmtId)\n // V-C8:内核裸错误在此包一层——带上 op 名、两个输入的变量名与 cause。\n const prevTable = roleTable\n const toolTable = inputRoleTable(inputs[i]) as ReadonlyMap<unknown, unknown> | undefined\n // Phase 1.6:新 origin = 本次语句的 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n let r: ReturnType<typeof booleanWithRoleTable>\n try {\n r = booleanWithRoleTable(\n kernel,\n op,\n prev,\n tool,\n prevTable ?? new Map(),\n toolTable ?? new Map(),\n outStmt,\n )\n } catch (cause) {\n // GOTCHA: OCCT 的 *WithHistory 在两输入共享子结构/历史(如布尔产物的布尔)\n // 时可能 \"operation failed\",而同一几何的裸布尔可以成功。降级重试一次裸\n // kernel[op]:几何结果正确,代价是丢本次面演化/roleTable(如实降级,同下方\n // 裸路径语义)。裸布尔也失败时,再试 unifySameDomain(两输入) 后重算——\n // 真实语料(disk-drive)中 tool 是布尔产物且与 target 共享子域,裸 cut 仍失败、\n // unify 后成功。全部失败才真正抛错。\n try {\n resultSolid = kernel[op](prev, tool)\n lastEvolution = undefined\n roleTable = undefined\n if (i > 1) kernel.release(prev)\n continue\n } catch {\n try {\n const uPrev = kernel.unifySameDomain(prev)\n const uTool = kernel.unifySameDomain(tool)\n resultSolid = kernel[op](uPrev, uTool)\n kernel.release(uPrev)\n kernel.release(uTool)\n lastEvolution = undefined\n roleTable = undefined\n if (i > 1) kernel.release(prev)\n continue\n } catch {\n const msg = cause instanceof Error ? cause.message : String(cause)\n throw new OpError(\n `boolean/${operation}`,\n 'E_OP_FAILED',\n `[api/boolean] ${operation}: kernel ${op} failed for inputs ` +\n `${nameOf(inputs[0]!) ?? 'input[0]'} × ${nameOf(inputs[i]!) ?? `input[${i}]`} — ${msg}`,\n { cause },\n )\n }\n }\n }\n resultSolid = r.result\n lastEvolution = r.faceEvolution\n roleTable = r.roleTable\n } else {\n // 裸布尔降级路径:几何正确,但无面演化、无 roleTable 传播(如实降级,不伪造映射)。\n try {\n resultSolid = kernel[op](prev, tool)\n } catch (cause) {\n const msg = cause instanceof Error ? cause.message : String(cause)\n throw new OpError(\n `boolean/${operation}`,\n 'E_OP_FAILED',\n `[api/boolean] ${operation}: kernel ${op} failed for inputs ` +\n `${nameOf(inputs[0]!) ?? 'input[0]'} × ${nameOf(inputs[i]!) ?? `input[${i}]`} — ${msg}`,\n { cause },\n )\n }\n lastEvolution = undefined\n roleTable = undefined\n }\n if (i > 1) kernel.release(prev)\n }\n\n return fromBrep(\n solidToShape(kernel, resultSolid),\n lastEvolution ? { solid: resultSolid, faceEvolution: lastEvolution, roleTable } : { solid: resultSolid, roleTable },\n )\n}\n\n/**\n * 网格实体路径:brepkit 网格内核的布尔(方案 2026-10-01 §3.5 三明治)。\n *\n * 输入**全部**是网格实体——这一点由 `dispatchPath` 的链门禁保证\n * (`E_MESH_SOLID_MIXED`:网格实体不得与链外几何同处一次调用),此处只复核不补救。\n *\n * 无面演化、无 roleTable:近似拓扑没有 hash 演化,造一张恒等映射就是假身份\n * (与 brepkit 裸布尔降级同一条纪律)。\n *\n * 中间结果是本实现自己造的句柄(不是任何输入),故 i>1 步及时释放;**输入句柄一概\n * 不释放**——生命周期归链(与 BREP 路径 booleanBrep 的 `if (i > 1) kernel.release(prev)`\n * 同构)。\n *\n * @param inputs - the mesh-solid inputs (≥1).\n * @param operation - union / subtract / intersect.\n * @returns the boolean result as a new mesh part.\n */\nfunction booleanMeshSolid(inputs: Shape[], operation: BooleanOperation): Shape {\n const opLabel = `boolean/${operation}`\n const entries = inputs.map((s) => meshSolidEntry(s, opLabel))\n const first = entries[0]!\n const kernel = first.kernel\n const op: 'fuse' | 'cut' | 'intersect' =\n operation === 'union' ? 'fuse' : operation === 'subtract' ? 'cut' : 'intersect'\n\n let result = first.solid\n for (let i = 1; i < entries.length; i++) {\n const prev = result\n try {\n result = kernel[op](prev, entries[i]!.solid)\n } catch (cause) {\n throw meshKernelFailure(\n opLabel,\n 'E_OP_FAILED',\n `${op}(${nameOf(inputs[0]!) ?? 'input[0]'} × ${nameOf(inputs[i]!) ?? `input[${i}]`})`,\n cause,\n )\n }\n // i>1:prev 是本实现上一步造出的中间实体,释放它(i=1 时 prev 是**输入**,不碰)。\n if (i > 1) first.backend.release(prev)\n }\n return meshSolidProduct(first, result)\n}\n\n/**\n * 网格路径分流(方案 2026-10-01 §3.4 规则 4):输入含网格实体 → brepkit 网格内核;\n * 否则保持历史上限(内置 `mesh/` 的 manifold CSG)。两条路**互不冒充**——\n * manifold 不认识网格实体(静态门禁),网格内核也不接受裸网格(无句柄)。\n *\n * @param inputs - the geometry inputs.\n * @param operation - union / subtract / intersect.\n * @returns the boolean product (mesh solid or manifold mesh shape).\n */\nfunction booleanMeshPath(inputs: Shape[], operation: BooleanOperation): Shape | Promise<Shape> {\n if (inputs.some(hasMeshSolid)) return booleanMeshSolid(inputs, operation)\n return booleanMesh(inputs, operation)\n}\n\n/** mesh 路径:manifold-3d mesh-CSG。 */\nasync function booleanMesh(inputs: Shape[], operation: BooleanOperation): Promise<Shape> {\n if (inputs.length < 2) {\n if (inputs.length === 1) return inputs[0]\n throw new Error('[api/boolean] boolean needs at least 1 input')\n }\n if (operation === 'union') return cad.union(inputs[0], inputs[1], ...inputs.slice(2))\n if (operation === 'subtract') {\n let result = await cad.subtract(inputs[0], inputs[1])\n for (let i = 2; i < inputs.length; i++) result = await cad.subtract(result, inputs[i])\n return result\n }\n let result = await cad.intersect(inputs[0], inputs[1])\n for (let i = 2; i < inputs.length; i++) result = await cad.intersect(result, inputs[i])\n return result\n}\n\n// ── 三个薄导出(多输入 variadic,defineOp 声明双路径 + 逐核函数 face-evolution 能力) ──\n// 函数体 keep 声明(keep-syntax 设计 §2.5):union/subtract/intersect 保留其\n// 输入且隐藏(R5:3d_editor 现状)——keepHidden 使源变量保持终端但 canvas\n// 不渲染,只有布尔结果正常显示。混合/断链时刻:BREP 侧输入先归约为合法\n// 2-manifold 网格(reconcileBrepInputs),mesh 侧原样透传。\n\n/**\n * 布尔并集:合并所有输入几何(≥2 个输入)。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name union\n * @param shapes - 参与运算的几何(变量引用,≥2 个)。type:Shape[] required:true\n * @returns Shape 所有输入的并集。函数名即操作,输入全是变量引用,可用 `cad.union(a, b, c)` 多输入。\n * @example\n * const a = await cad.union(part0, part1)\n */\nexport const union = defineOp({\n meshEngines: ['brepkit'],\n mesh: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanMeshPath(reconcileBrepInputs(shapes), 'union')\n },\n brep: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanBrep(shapes, 'union')\n },\n // 逐核函数声明(Phase 0.2):union 需要内核的 fuseWithHistory。\n // 不再声明族级 'evolution'——族级名会让 brepkit(无 intersectWithHistory)等\n // 部分实现的内核静默通过静态判定,再死在运行时(红线违规)。\n capabilities: ['fuseWithHistory'],\n schema: { shapes: 'Shape*' },\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * Boolean cut (subtract): remove `tool` from `base`. Same semantics as\n * {@link subtract} but with the brepjs-compatible `(base, tool, options?)` signature.\n * Overrides the generated projection (compatOp) to do roleTable propagation\n * (Phase 3: L2 requires wall:<i> to survive cut).\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name cut\n * @param base - the target shape. type:Shape required:true\n * @param tool - the shape to subtract. type:Shape required:true\n * @returns Shape base minus tool.\n * @example\n * const b = await cad.cut(part0, part1)\n */\nexport const cut = defineOp({\n meshEngines: ['brepkit'],\n mesh: (base: Shape, tool: Shape) => {\n keepHidden(base, tool)\n return booleanMeshPath(reconcileBrepInputs([base, tool]), 'subtract')\n },\n brep: (base: Shape, tool: Shape) => {\n keepHidden(base, tool)\n return booleanBrep([base, tool], 'subtract')\n },\n capabilities: ['cutWithHistory'],\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * 布尔差集:第一个为主体,减去其余输入。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name subtract\n * @param shapes - 参与运算的几何(变量引用,第一个为主体)。type:Shape[] required:true\n * @returns Shape part0 减 part1 的差集(第一个为主体)。\n * @example\n * const b = await cad.subtract(part0, part1)\n */\nexport const subtract = defineOp({\n meshEngines: ['brepkit'],\n mesh: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanMeshPath(reconcileBrepInputs(shapes), 'subtract')\n },\n brep: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanBrep(shapes, 'subtract')\n },\n // 逐核函数声明(Phase 0.2):subtract 需要内核的 cutWithHistory。\n capabilities: ['cutWithHistory'],\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n\n/**\n * 布尔交集:所有输入的重叠部分。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name intersect\n * @param shapes - 参与运算的几何(变量引用)。type:Shape[] required:true\n * @returns Shape 所有输入的交集。\n * @example\n * const c = await cad.intersect(part0, part1)\n */\nexport const intersect = defineOp({\n meshEngines: ['brepkit'],\n mesh: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanMeshPath(reconcileBrepInputs(shapes), 'intersect')\n },\n brep: (...shapes: Shape[]) => {\n if (shapes.length > 0) keepHidden(...shapes)\n return booleanBrep(shapes, 'intersect')\n },\n // 不声明 `capabilities: ['intersectWithHistory']`(中立 op):\n // brepkit 声明了裸 `intersect` 但没有 `intersectWithHistory`——若硬声明历史能力,\n // brepkit brep 模式会在执行前静态报 `lacks capability 'intersectWithHistory'`。\n // 现由 booleanBrep 按引擎声明的能力集静态分派:occt(声明 intersectWithHistory)\n // 走历史路径保留面演化/naming;brepkit(只声明裸 intersect)走 L1 裸 `kernel.intersect`,\n // 几何正确但无面演化(如实降级,不伪造恒等映射)。\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joinery-brep.d.ts","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"joinery-brep.d.ts","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
import * as THREE from 'three';
|
|
19
19
|
import { getSolidBoundingBox } from '../../brep/brep-utils.js';
|
|
20
20
|
import { splitBrep, matrixToArray } from '../../brep/brep-ops.js';
|
|
21
|
+
import { DEFAULT_LINEAR_DEFLECTION } from '../../tolerance.js';
|
|
22
|
+
import { mm } from '../../units.js';
|
|
21
23
|
// ─── Union-Find(与 csg-worker.ts SimpleUnionFind 一致) ───
|
|
22
24
|
class SimpleUnionFind {
|
|
23
25
|
parent;
|
|
@@ -170,7 +172,7 @@ function computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, widthDir,
|
|
|
170
172
|
/** 将 OCCT solid 三角化为 MeshData(用于截面分析) */
|
|
171
173
|
function solidToMeshData(kernel, solid) {
|
|
172
174
|
const mesh = kernel.meshShape(solid, {
|
|
173
|
-
linearDeflection:
|
|
175
|
+
linearDeflection: DEFAULT_LINEAR_DEFLECTION.as(mm),
|
|
174
176
|
angularDeflection: (2 * Math.PI) / 32,
|
|
175
177
|
});
|
|
176
178
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joinery-brep.js","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * BREP 榫卯结构操作 — 用 OCCT 精确实体复刻 mesh 路径的榫卯布尔序列\n *\n * See docs/api-contract.md §8 (dual-path geometry contract) and §10.5 (split).\n *\n * 与 mesh 路径(joinery-shapes.ts + csg-worker.ts)对照:\n * - mesh 路径:buildWedgeGeometry/buildDowelGeometry/buildStraightTenonGeometry → Manifold CSG\n * - BREP 路径:buildWedgeSolid/buildDowelSolid/buildTenonSolid → OCCT fuse/cut/common\n *\n * 坐标框架与 mesh 路径完全一致:\n * - normal: 切割平面法线(单位向量,指向上方)\n * - widthDir: 挤出方向(单位向量)\n * - depthDir = normalize(cross(normal, widthDir))\n * - planeCenter: 切割平面中心\n *\n * 所有函数都是纯函数,输入输出均为 OCCT BrepHandle,调用方负责句柄生命周期。\n */\n\nimport * as THREE from 'three'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { Vec3 } from '../../mesh/types'\nimport { getSolidBoundingBox } from '../../brep/brep-utils'\nimport { splitBrep, matrixToArray } from '../../brep/brep-ops'\n\n// ─── 坐标框架 ───\n\n/** 榫卯操作的坐标框架(与 joinery-shapes.ts 一致) */\nexport interface JoineryBasis {\n /** 切割平面法线(单位向量) */\n normal: Vec3\n /** 宽度/挤出方向(单位向量) */\n widthDir: Vec3\n /** 深度方向 = normalize(cross(normal, widthDir)) */\n depthDir: Vec3\n /** 切割平面中心 */\n planeCenter: Vec3\n /** 平面原点偏移 = dot(normal, planeCenter) */\n planeDistance: number\n}\n\n// ─── Union-Find(与 csg-worker.ts SimpleUnionFind 一致) ───\n\nclass SimpleUnionFind {\n private parent: number[]\n private rank: number[]\n\n constructor(n: number) {\n this.parent = Array.from({ length: n }, (_, i) => i)\n this.rank = new Array(n).fill(0)\n }\n\n find(x: number): number {\n if (this.parent[x] !== x) {\n this.parent[x] = this.find(this.parent[x])\n }\n return this.parent[x]\n }\n\n union(x: number, y: number): void {\n const px = this.find(x)\n const py = this.find(y)\n if (px === py) return\n if (this.rank[px] < this.rank[py]) {\n this.parent[px] = py\n } else if (this.rank[px] > this.rank[py]) {\n this.parent[py] = px\n } else {\n this.parent[py] = px\n this.rank[px]++\n }\n }\n}\n\n// ─── 截面分析(从 mesh 三角化提取截面信息,与 csg-worker.ts 算法一致) ───\n\ninterface MeshData {\n positions: Float32Array\n indices: Uint32Array\n}\n\n/**\n * 检测切割平面上的帽面连通分量。\n *\n * 与 csg-worker.ts detectCapComponents 算法一致:\n * 1. 找到所有顶点在切割平面上的三角形\n * 2. 用 union-find 按共享顶点分组\n * 3. 返回每分量的顶点索引集合\n */\nfunction detectCapComponentsFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n): Set<number>[] {\n const eps = 0.001\n const { positions, indices } = mesh\n const vertCount = positions.length / 3\n if (indices.length === 0) return []\n\n // 找到所有帽面三角形\n const capVertSet = new Set<number>()\n interface CapTri { v0: number; v1: number; v2: number }\n const capTris: CapTri[] = []\n const triCount = indices.length / 3\n for (let t = 0; t < triCount; t++) {\n const i0 = indices[t * 3]\n const i1 = indices[t * 3 + 1]\n const i2 = indices[t * 3 + 2]\n const d0 = Math.abs(\n positions[i0 * 3] * normal[0] +\n positions[i0 * 3 + 1] * normal[1] +\n positions[i0 * 3 + 2] * normal[2] - planeDistance,\n )\n const d1 = Math.abs(\n positions[i1 * 3] * normal[0] +\n positions[i1 * 3 + 1] * normal[1] +\n positions[i1 * 3 + 2] * normal[2] - planeDistance,\n )\n const d2 = Math.abs(\n positions[i2 * 3] * normal[0] +\n positions[i2 * 3 + 1] * normal[1] +\n positions[i2 * 3 + 2] * normal[2] - planeDistance,\n )\n if (d0 < eps && d1 < eps && d2 < eps) {\n capTris.push({ v0: i0, v1: i1, v2: i2 })\n capVertSet.add(i0); capVertSet.add(i1); capVertSet.add(i2)\n }\n }\n if (capTris.length === 0) return []\n\n // Union-find 按共享顶点分组\n const uf = new SimpleUnionFind(vertCount)\n for (const tri of capTris) {\n uf.union(tri.v0, tri.v1)\n uf.union(tri.v1, tri.v2)\n uf.union(tri.v0, tri.v2)\n }\n\n // 按根节点分组\n const compMap = new Map<number, Set<number>>()\n for (const vi of capVertSet) {\n const root = uf.find(vi)\n if (!compMap.has(root)) compMap.set(root, new Set<number>())\n compMap.get(root)!.add(vi)\n }\n\n return Array.from(compMap.values())\n}\n\n/**\n * 计算切割平面上截面顶点的质心。\n *\n * 与 csg-worker.ts computeCrossSectionCentroid 算法一致。\n */\nfunction computeCrossSectionCentroidFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n fallback: Vec3,\n comp?: Set<number>,\n): Vec3 {\n const eps = 0.001\n const { positions } = mesh\n let cx = 0, cy = 0, cz = 0\n let count = 0\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n cx += x\n cy += y\n cz += z\n count++\n }\n }\n\n if (count === 0) return fallback\n return [cx / count, cy / count, cz / count]\n}\n\n/**\n * 计算切割平面上截面沿指定方向的宽度。\n *\n * 与 csg-worker.ts computeCrossSectionWidth 算法一致。\n */\nfunction computeCrossSectionWidthFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n widthDir: Vec3,\n comp?: Set<number>,\n): number {\n const eps = 0.001\n const { positions } = mesh\n let minProj = Infinity\n let maxProj = -Infinity\n let found = false\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n const proj = x * widthDir[0] + y * widthDir[1] + z * widthDir[2]\n if (proj < minProj) minProj = proj\n if (proj > maxProj) maxProj = proj\n found = true\n }\n }\n\n if (!found) return 0\n return maxProj - minProj\n}\n\n/** 将 OCCT solid 三角化为 MeshData(用于截面分析) */\nfunction solidToMeshData(kernel: BrepEngineApi, solid: BrepHandle): MeshData {\n const mesh = kernel.meshShape(solid, {\n linearDeflection: 0.1,\n angularDeflection: (2 * Math.PI) / 32,\n })\n return {\n positions: new Float32Array(mesh.positions),\n indices: new Uint32Array(mesh.indices),\n }\n}\n\n// ─── 基本体构造(BREP 等价物) ───\n\n/**\n * 构造局部的变换矩阵:local X → widthDir, Y → depthDir, Z → normal,再平移到 origin。\n */\nfunction makeBasisTransform(basis: JoineryBasis, origin: Vec3): THREE.Matrix4 {\n const basisMatrix = new THREE.Matrix4().makeBasis(\n new THREE.Vector3(...basis.widthDir),\n new THREE.Vector3(...basis.depthDir),\n new THREE.Vector3(...basis.normal),\n )\n const transMatrix = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2])\n return new THREE.Matrix4().multiplyMatrices(transMatrix, basisMatrix)\n}\n\n/**\n * 梯形棱柱(燕尾楔)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildWedgeGeometry 的 8 顶点拓扑:\n * - 梯形截面在 normal-depthDir 平面\n * - 底边(宽)在 planeCenter - normal*depth\n * - 顶边(窄)在 planeCenter\n * - 沿 widthDir 拉伸 extrudeLength,居中于 planeCenter\n *\n * 用 kernel.makeLineEdge + makeWire + makeFace + extrude 构造实体,\n * 然后用 transform 对齐到世界坐标系。\n * @param kernel - the BREP engine API.\n * @param basis - the joinery coordinate frame (normal/widthDir/depthDir/planeCenter).\n * @param depth - the wedge depth along the normal direction.\n * @param width - the wedge bottom width.\n * @param angleDeg - the dovetail flap angle in degrees.\n * @param extrudeLength - the extrusion length along the width direction.\n * @returns the constructed wedge solid handle.\n */\nexport function buildWedgeSolid(\n kernel: BrepEngineApi,\n basis: JoineryBasis,\n depth: number,\n width: number,\n angleDeg: number,\n extrudeLength: number,\n): BrepHandle {\n const { planeCenter } = basis\n const angleRad = (angleDeg * Math.PI) / 180\n\n const halfWidth = width / 2\n const halfTopWidth = Math.max(0, halfWidth - depth / Math.tan(angleRad))\n const halfExtrude = extrudeLength / 2\n\n // 在局部坐标系中构造梯形面(YZ 平面,X = -halfExtrude)\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const xLocal = -halfExtrude\n const v0 = { x: xLocal, y: -halfWidth, z: -depth } // bottomLeft\n const v1 = { x: xLocal, y: halfWidth, z: -depth } // bottomRight\n const v2 = { x: xLocal, y: halfTopWidth, z: 0 } // topRight\n const v3 = { x: xLocal, y: -halfTopWidth, z: 0 } // topLeft\n\n // 构建梯形 wire\n const edges: BrepHandle[] = []\n edges.push(kernel.makeLineEdge(v0, v1))\n edges.push(kernel.makeLineEdge(v1, v2))\n edges.push(kernel.makeLineEdge(v2, v3))\n edges.push(kernel.makeLineEdge(v3, v0))\n\n const wire = kernel.makeWire(edges)\n const face = kernel.makeFace(wire)\n\n // 沿 X 轴(= widthDir)拉伸 extrudeLength\n const extruded = kernel.extrude(face, extrudeLength, 0, 0)\n\n // 释放中间句柄\n for (const e of edges) kernel.release(e)\n kernel.release(wire)\n kernel.release(face)\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, planeCenter)\n const result = kernel.transform(extruded, matrixToArray(fullMatrix))\n kernel.release(extruded)\n\n return result\n}\n\n/**\n * 圆柱(定位销)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildDowelGeometry:\n * - 圆截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeCylinder + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the dowel is placed.\n * @param basis - the joinery coordinate frame.\n * @param diameter - the dowel diameter.\n * @param height - the dowel height along the normal direction.\n * @returns the constructed dowel solid handle.\n */\nexport function buildDowelSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n diameter: number,\n height: number,\n): BrepHandle {\n const radius = diameter / 2\n const { normal } = basis\n\n // OCCT makeCylinder 创建 Z 轴方向圆柱(Z=0 → Z=height)\n // 需要旋转使 Z 轴对齐 -normal(圆柱向下延伸),且顶部在 centroid\n const cyl = kernel.makeCylinder(radius, height)\n\n // 旋转 Z → -normal\n const zAxis = new THREE.Vector3(0, 0, 1)\n const negNormal = new THREE.Vector3(-normal[0], -normal[1], -normal[2]).normalize()\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, negNormal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 平移到 centroid(旋转后 Z=0 对应 centroid,即切割平面上的顶面)\n const transMatrix = new THREE.Matrix4().makeTranslation(centroid[0], centroid[1], centroid[2])\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const result = kernel.transform(cyl, matrixToArray(fullMatrix))\n kernel.release(cyl)\n\n return result\n}\n\n/**\n * 长方体(直榫)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildStraightTenonGeometry:\n * - 方截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeBoxFromCorners + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the tenon is placed.\n * @param basis - the joinery coordinate frame.\n * @param sideLength - the tenon square side length.\n * @param height - the tenon height along the normal direction.\n * @returns the constructed tenon solid handle.\n */\nexport function buildTenonSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n sideLength: number,\n height: number,\n): BrepHandle {\n const half = sideLength / 2\n\n // 在局部坐标系中创建盒子:X ∈ [-half, half], Y ∈ [-half, half], Z ∈ [-height, 0]\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const localBox = kernel.makeBoxFromCorners(\n { x: -half, y: -half, z: -height },\n { x: half, y: half, z: 0 },\n )\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, centroid)\n const result = kernel.transform(localBox, matrixToArray(fullMatrix))\n kernel.release(localBox)\n\n return result\n}\n\n// ─── 截面质心 / 多截面检测 ───\n\n/** 截面分量信息 */\nexport interface CrossSectionComponent {\n /** 分量质心 */\n centroid: Vec3\n /** 分量面积(近似,用于排序) */\n area: number\n}\n\n/**\n * 检测上部实体在切割平面上的截面连通分量。\n *\n * BREP 等价物:将 upper solid 三角化后,用与 mesh 路径 detectCapComponents\n * 完全相同的算法(找帽面三角形 → union-find)检测连通分量。\n *\n * 与 csg-worker.ts detectCapComponents + computeCrossSectionCentroid 一致。\n * @param kernel - the BREP engine API.\n * @param upper - the upper solid whose cross section is analyzed.\n * @param basis - the joinery coordinate frame.\n * @returns the detected cross-section components (centroid + area).\n */\nexport function detectCrossSectionComponents(\n kernel: BrepEngineApi,\n upper: BrepHandle,\n basis: JoineryBasis,\n): CrossSectionComponent[] {\n const { normal, planeDistance, widthDir, depthDir, planeCenter } = basis\n const mesh = solidToMeshData(kernel, upper)\n const components = detectCapComponentsFromMesh(mesh, normal, planeDistance)\n\n if (components.length === 0) {\n // 无帽面 → 返回单个全局质心(planeCenter)作为回退\n return [{ centroid: planeCenter, area: 0 }]\n }\n\n return components.map(comp => {\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter, comp)\n const compWidth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, widthDir, comp)\n const compDepth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, depthDir, comp)\n return { centroid, area: compWidth * compDepth }\n })\n}\n\n// ─── 布尔序列(1:1 复刻 csg-worker.ts) ───\n\n/** dovetail 布尔分割的结果 */\nexport interface DovetailSplitBrepResult {\n /** 上部 + 楔(法线正方向半部分加燕尾榫) */\n front: BrepHandle\n /** 下部 - 凹腔(法线负方向半部分减燕尾槽) */\n back: BrepHandle\n}\n\n/** dowel/tenon 布尔分割的结果 */\nexport interface DowelOrTenonSplitBrepResult {\n /** 上部 + 销/榫(法线正方向半部分加圆柱/方柱) */\n front: BrepHandle\n /** 下部 - 孔(法线负方向半部分减圆柱/方柱) */\n back: BrepHandle\n}\n\n/** groove 参数 */\nexport interface GrooveParams {\n depth: number\n depthTolerance: number\n width: number\n widthTolerance: number\n flapsAngle: number\n}\n\n/**\n * Dovetail(燕尾)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dovetailBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. 计算 crossSectionWidth(bbox 投影近似)\n * 3. buildWedgeSolid(overhang=20)→ common(wedge, lower) 裁剪贴合\n * 4. fuse(upper, wedgeTrimmed) → upper'\n * 5. buildWedgeSolid(公差)→ cut(lower, wedgeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param groove - the dovetail groove parameters.\n * @returns the split result with front (upper + wedge) and back (lower - cavity) handles.\n */\nexport function dovetailBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n groove: GrooveParams,\n): DovetailSplitBrepResult {\n const { normal, widthDir, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 计算截面宽度(bbox 投影近似,后续 common 会裁回真实边界)\n const upperBbox = getSolidBoundingBox(kernel, upper)\n const upperSize: Vec3 = [\n upperBbox.max[0] - upperBbox.min[0],\n upperBbox.max[1] - upperBbox.min[1],\n upperBbox.max[2] - upperBbox.min[2],\n ]\n let crossSectionWidth =\n Math.abs(upperSize[0] * widthDir[0]) +\n Math.abs(upperSize[1] * widthDir[1]) +\n Math.abs(upperSize[2] * widthDir[2])\n if (crossSectionWidth <= 0) crossSectionWidth = 10 // 安全回退\n const extrudeLength = crossSectionWidth + 0.2\n const overhang = 20\n\n // Step 3: 构造楔(带 overhang)\n const wedgeW = buildWedgeSolid(kernel, basis, groove.depth, groove.width, groove.flapsAngle, extrudeLength + overhang)\n\n // Step 4: common(wedge, lower) → 裁剪楔贴合模型边界\n const wedgeTrimmed = kernel.common(wedgeW, lower)\n kernel.release(wedgeW)\n\n // Step 5: fuse(upper, wedgeTrimmed) → upper'\n const newUpper = kernel.fuse(upper, wedgeTrimmed)\n kernel.release(upper)\n kernel.release(wedgeTrimmed)\n upper = newUpper\n\n // Step 6: 构造公差楔\n const wedgeTol = buildWedgeSolid(\n kernel, basis,\n groove.depth + groove.depthTolerance,\n groove.width + groove.widthTolerance,\n groove.flapsAngle,\n extrudeLength + overhang,\n )\n\n // Step 7: cut(lower, wedgeTol) → lower'\n const newLower = kernel.cut(lower, wedgeTol)\n kernel.release(lower)\n kernel.release(wedgeTol)\n lower = newLower\n\n return { front: upper, back: lower }\n}\n\n/** dowel/tenon 参数 */\nexport interface DowelOrTenonParams {\n /** 直径(dowel)或边长(tenon) */\n size: number\n /** 尺寸公差 */\n sizeTolerance: number\n /** 高度 */\n height: number\n /** 高度公差 */\n heightTolerance: number\n}\n\n/**\n * Dowel(定位销)/ Tenon(直榫)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dowelOrTenonBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. detectCrossSectionComponents → 截面质心列表\n * 3. 对每个质心:buildShapeSolid → fuse(upper, shape) → upper'\n * 4. 对每个质心:buildShapeSolid(公差)→ cut(lower, shapeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param shape - whether to build a dowel or a tenon.\n * @param params - the dowel/tenon size and tolerance parameters.\n * @param selectedSections - optional indices of cross-section components to place shapes on.\n * @returns the split result with front (upper + shape) and back (lower - hole) handles.\n */\nexport function dowelOrTenonBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n shape: 'dowel' | 'tenon',\n params: DowelOrTenonParams,\n selectedSections?: number[] | null,\n): DowelOrTenonSplitBrepResult {\n const { normal, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 检测截面分量\n const components = detectCrossSectionComponents(kernel, upper, basis)\n\n // 构建放置位置列表\n interface Placement { centroid: Vec3 }\n let placements: Placement[]\n\n if (components.length <= 1 || !selectedSections || selectedSections.length === 0) {\n // 单截面或无选择 → 全局质心(向后兼容)\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n } else {\n // 多截面:按面积降序排,取选择的分量\n const sorted = [...components].sort((a, b) => b.area - a.area)\n placements = []\n for (const selId of selectedSections) {\n if (selId < sorted.length) {\n placements.push({ centroid: sorted[selId].centroid })\n }\n }\n if (placements.length === 0) {\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n }\n }\n\n // Step 3: 对每个质心构造基本体并 fuse 到 upper\n for (const { centroid } of placements) {\n let shapeC: BrepHandle\n if (shape === 'dowel') {\n shapeC = buildDowelSolid(kernel, centroid, basis, params.size, params.height)\n } else {\n shapeC = buildTenonSolid(kernel, centroid, basis, params.size, params.height)\n }\n\n const newUpper = kernel.fuse(upper, shapeC)\n kernel.release(upper)\n kernel.release(shapeC)\n upper = newUpper\n }\n\n // Step 4: 对每个质心构造公差体并 cut 从 lower\n const tolSize = params.size + params.sizeTolerance\n const tolHeight = params.height + params.heightTolerance\n\n for (const { centroid } of placements) {\n let shapeCTol: BrepHandle\n if (shape === 'dowel') {\n shapeCTol = buildDowelSolid(kernel, centroid, basis, tolSize, tolHeight)\n } else {\n shapeCTol = buildTenonSolid(kernel, centroid, basis, tolSize, tolHeight)\n }\n\n const newLower = kernel.cut(lower, shapeCTol)\n kernel.release(lower)\n kernel.release(shapeCTol)\n lower = newLower\n }\n\n return { front: upper, back: lower }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"joinery-brep.js","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * BREP 榫卯结构操作 — 用 OCCT 精确实体复刻 mesh 路径的榫卯布尔序列\n *\n * See docs/api-contract.md §8 (dual-path geometry contract) and §10.5 (split).\n *\n * 与 mesh 路径(joinery-shapes.ts + csg-worker.ts)对照:\n * - mesh 路径:buildWedgeGeometry/buildDowelGeometry/buildStraightTenonGeometry → Manifold CSG\n * - BREP 路径:buildWedgeSolid/buildDowelSolid/buildTenonSolid → OCCT fuse/cut/common\n *\n * 坐标框架与 mesh 路径完全一致:\n * - normal: 切割平面法线(单位向量,指向上方)\n * - widthDir: 挤出方向(单位向量)\n * - depthDir = normalize(cross(normal, widthDir))\n * - planeCenter: 切割平面中心\n *\n * 所有函数都是纯函数,输入输出均为 OCCT BrepHandle,调用方负责句柄生命周期。\n */\n\nimport * as THREE from 'three'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { Vec3 } from '../../mesh/types'\nimport { getSolidBoundingBox } from '../../brep/brep-utils'\nimport { splitBrep, matrixToArray } from '../../brep/brep-ops'\nimport { DEFAULT_LINEAR_DEFLECTION } from '../../tolerance'\nimport { mm } from '../../units'\n\n// ─── 坐标框架 ───\n\n/** 榫卯操作的坐标框架(与 joinery-shapes.ts 一致) */\nexport interface JoineryBasis {\n /** 切割平面法线(单位向量) */\n normal: Vec3\n /** 宽度/挤出方向(单位向量) */\n widthDir: Vec3\n /** 深度方向 = normalize(cross(normal, widthDir)) */\n depthDir: Vec3\n /** 切割平面中心 */\n planeCenter: Vec3\n /** 平面原点偏移 = dot(normal, planeCenter) */\n planeDistance: number\n}\n\n// ─── Union-Find(与 csg-worker.ts SimpleUnionFind 一致) ───\n\nclass SimpleUnionFind {\n private parent: number[]\n private rank: number[]\n\n constructor(n: number) {\n this.parent = Array.from({ length: n }, (_, i) => i)\n this.rank = new Array(n).fill(0)\n }\n\n find(x: number): number {\n if (this.parent[x] !== x) {\n this.parent[x] = this.find(this.parent[x])\n }\n return this.parent[x]\n }\n\n union(x: number, y: number): void {\n const px = this.find(x)\n const py = this.find(y)\n if (px === py) return\n if (this.rank[px] < this.rank[py]) {\n this.parent[px] = py\n } else if (this.rank[px] > this.rank[py]) {\n this.parent[py] = px\n } else {\n this.parent[py] = px\n this.rank[px]++\n }\n }\n}\n\n// ─── 截面分析(从 mesh 三角化提取截面信息,与 csg-worker.ts 算法一致) ───\n\ninterface MeshData {\n positions: Float32Array\n indices: Uint32Array\n}\n\n/**\n * 检测切割平面上的帽面连通分量。\n *\n * 与 csg-worker.ts detectCapComponents 算法一致:\n * 1. 找到所有顶点在切割平面上的三角形\n * 2. 用 union-find 按共享顶点分组\n * 3. 返回每分量的顶点索引集合\n */\nfunction detectCapComponentsFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n): Set<number>[] {\n const eps = 0.001\n const { positions, indices } = mesh\n const vertCount = positions.length / 3\n if (indices.length === 0) return []\n\n // 找到所有帽面三角形\n const capVertSet = new Set<number>()\n interface CapTri { v0: number; v1: number; v2: number }\n const capTris: CapTri[] = []\n const triCount = indices.length / 3\n for (let t = 0; t < triCount; t++) {\n const i0 = indices[t * 3]\n const i1 = indices[t * 3 + 1]\n const i2 = indices[t * 3 + 2]\n const d0 = Math.abs(\n positions[i0 * 3] * normal[0] +\n positions[i0 * 3 + 1] * normal[1] +\n positions[i0 * 3 + 2] * normal[2] - planeDistance,\n )\n const d1 = Math.abs(\n positions[i1 * 3] * normal[0] +\n positions[i1 * 3 + 1] * normal[1] +\n positions[i1 * 3 + 2] * normal[2] - planeDistance,\n )\n const d2 = Math.abs(\n positions[i2 * 3] * normal[0] +\n positions[i2 * 3 + 1] * normal[1] +\n positions[i2 * 3 + 2] * normal[2] - planeDistance,\n )\n if (d0 < eps && d1 < eps && d2 < eps) {\n capTris.push({ v0: i0, v1: i1, v2: i2 })\n capVertSet.add(i0); capVertSet.add(i1); capVertSet.add(i2)\n }\n }\n if (capTris.length === 0) return []\n\n // Union-find 按共享顶点分组\n const uf = new SimpleUnionFind(vertCount)\n for (const tri of capTris) {\n uf.union(tri.v0, tri.v1)\n uf.union(tri.v1, tri.v2)\n uf.union(tri.v0, tri.v2)\n }\n\n // 按根节点分组\n const compMap = new Map<number, Set<number>>()\n for (const vi of capVertSet) {\n const root = uf.find(vi)\n if (!compMap.has(root)) compMap.set(root, new Set<number>())\n compMap.get(root)!.add(vi)\n }\n\n return Array.from(compMap.values())\n}\n\n/**\n * 计算切割平面上截面顶点的质心。\n *\n * 与 csg-worker.ts computeCrossSectionCentroid 算法一致。\n */\nfunction computeCrossSectionCentroidFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n fallback: Vec3,\n comp?: Set<number>,\n): Vec3 {\n const eps = 0.001\n const { positions } = mesh\n let cx = 0, cy = 0, cz = 0\n let count = 0\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n cx += x\n cy += y\n cz += z\n count++\n }\n }\n\n if (count === 0) return fallback\n return [cx / count, cy / count, cz / count]\n}\n\n/**\n * 计算切割平面上截面沿指定方向的宽度。\n *\n * 与 csg-worker.ts computeCrossSectionWidth 算法一致。\n */\nfunction computeCrossSectionWidthFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n widthDir: Vec3,\n comp?: Set<number>,\n): number {\n const eps = 0.001\n const { positions } = mesh\n let minProj = Infinity\n let maxProj = -Infinity\n let found = false\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n const proj = x * widthDir[0] + y * widthDir[1] + z * widthDir[2]\n if (proj < minProj) minProj = proj\n if (proj > maxProj) maxProj = proj\n found = true\n }\n }\n\n if (!found) return 0\n return maxProj - minProj\n}\n\n/** 将 OCCT solid 三角化为 MeshData(用于截面分析) */\nfunction solidToMeshData(kernel: BrepEngineApi, solid: BrepHandle): MeshData {\n const mesh = kernel.meshShape(solid, {\n linearDeflection: DEFAULT_LINEAR_DEFLECTION.as(mm),\n angularDeflection: (2 * Math.PI) / 32,\n })\n return {\n positions: new Float32Array(mesh.positions),\n indices: new Uint32Array(mesh.indices),\n }\n}\n\n// ─── 基本体构造(BREP 等价物) ───\n\n/**\n * 构造局部的变换矩阵:local X → widthDir, Y → depthDir, Z → normal,再平移到 origin。\n */\nfunction makeBasisTransform(basis: JoineryBasis, origin: Vec3): THREE.Matrix4 {\n const basisMatrix = new THREE.Matrix4().makeBasis(\n new THREE.Vector3(...basis.widthDir),\n new THREE.Vector3(...basis.depthDir),\n new THREE.Vector3(...basis.normal),\n )\n const transMatrix = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2])\n return new THREE.Matrix4().multiplyMatrices(transMatrix, basisMatrix)\n}\n\n/**\n * 梯形棱柱(燕尾楔)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildWedgeGeometry 的 8 顶点拓扑:\n * - 梯形截面在 normal-depthDir 平面\n * - 底边(宽)在 planeCenter - normal*depth\n * - 顶边(窄)在 planeCenter\n * - 沿 widthDir 拉伸 extrudeLength,居中于 planeCenter\n *\n * 用 kernel.makeLineEdge + makeWire + makeFace + extrude 构造实体,\n * 然后用 transform 对齐到世界坐标系。\n * @param kernel - the BREP engine API.\n * @param basis - the joinery coordinate frame (normal/widthDir/depthDir/planeCenter).\n * @param depth - the wedge depth along the normal direction.\n * @param width - the wedge bottom width.\n * @param angleDeg - the dovetail flap angle in degrees.\n * @param extrudeLength - the extrusion length along the width direction.\n * @returns the constructed wedge solid handle.\n */\nexport function buildWedgeSolid(\n kernel: BrepEngineApi,\n basis: JoineryBasis,\n depth: number,\n width: number,\n angleDeg: number,\n extrudeLength: number,\n): BrepHandle {\n const { planeCenter } = basis\n const angleRad = (angleDeg * Math.PI) / 180\n\n const halfWidth = width / 2\n const halfTopWidth = Math.max(0, halfWidth - depth / Math.tan(angleRad))\n const halfExtrude = extrudeLength / 2\n\n // 在局部坐标系中构造梯形面(YZ 平面,X = -halfExtrude)\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const xLocal = -halfExtrude\n const v0 = { x: xLocal, y: -halfWidth, z: -depth } // bottomLeft\n const v1 = { x: xLocal, y: halfWidth, z: -depth } // bottomRight\n const v2 = { x: xLocal, y: halfTopWidth, z: 0 } // topRight\n const v3 = { x: xLocal, y: -halfTopWidth, z: 0 } // topLeft\n\n // 构建梯形 wire\n const edges: BrepHandle[] = []\n edges.push(kernel.makeLineEdge(v0, v1))\n edges.push(kernel.makeLineEdge(v1, v2))\n edges.push(kernel.makeLineEdge(v2, v3))\n edges.push(kernel.makeLineEdge(v3, v0))\n\n const wire = kernel.makeWire(edges)\n const face = kernel.makeFace(wire)\n\n // 沿 X 轴(= widthDir)拉伸 extrudeLength\n const extruded = kernel.extrude(face, extrudeLength, 0, 0)\n\n // 释放中间句柄\n for (const e of edges) kernel.release(e)\n kernel.release(wire)\n kernel.release(face)\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, planeCenter)\n const result = kernel.transform(extruded, matrixToArray(fullMatrix))\n kernel.release(extruded)\n\n return result\n}\n\n/**\n * 圆柱(定位销)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildDowelGeometry:\n * - 圆截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeCylinder + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the dowel is placed.\n * @param basis - the joinery coordinate frame.\n * @param diameter - the dowel diameter.\n * @param height - the dowel height along the normal direction.\n * @returns the constructed dowel solid handle.\n */\nexport function buildDowelSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n diameter: number,\n height: number,\n): BrepHandle {\n const radius = diameter / 2\n const { normal } = basis\n\n // OCCT makeCylinder 创建 Z 轴方向圆柱(Z=0 → Z=height)\n // 需要旋转使 Z 轴对齐 -normal(圆柱向下延伸),且顶部在 centroid\n const cyl = kernel.makeCylinder(radius, height)\n\n // 旋转 Z → -normal\n const zAxis = new THREE.Vector3(0, 0, 1)\n const negNormal = new THREE.Vector3(-normal[0], -normal[1], -normal[2]).normalize()\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, negNormal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 平移到 centroid(旋转后 Z=0 对应 centroid,即切割平面上的顶面)\n const transMatrix = new THREE.Matrix4().makeTranslation(centroid[0], centroid[1], centroid[2])\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const result = kernel.transform(cyl, matrixToArray(fullMatrix))\n kernel.release(cyl)\n\n return result\n}\n\n/**\n * 长方体(直榫)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildStraightTenonGeometry:\n * - 方截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeBoxFromCorners + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the tenon is placed.\n * @param basis - the joinery coordinate frame.\n * @param sideLength - the tenon square side length.\n * @param height - the tenon height along the normal direction.\n * @returns the constructed tenon solid handle.\n */\nexport function buildTenonSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n sideLength: number,\n height: number,\n): BrepHandle {\n const half = sideLength / 2\n\n // 在局部坐标系中创建盒子:X ∈ [-half, half], Y ∈ [-half, half], Z ∈ [-height, 0]\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const localBox = kernel.makeBoxFromCorners(\n { x: -half, y: -half, z: -height },\n { x: half, y: half, z: 0 },\n )\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, centroid)\n const result = kernel.transform(localBox, matrixToArray(fullMatrix))\n kernel.release(localBox)\n\n return result\n}\n\n// ─── 截面质心 / 多截面检测 ───\n\n/** 截面分量信息 */\nexport interface CrossSectionComponent {\n /** 分量质心 */\n centroid: Vec3\n /** 分量面积(近似,用于排序) */\n area: number\n}\n\n/**\n * 检测上部实体在切割平面上的截面连通分量。\n *\n * BREP 等价物:将 upper solid 三角化后,用与 mesh 路径 detectCapComponents\n * 完全相同的算法(找帽面三角形 → union-find)检测连通分量。\n *\n * 与 csg-worker.ts detectCapComponents + computeCrossSectionCentroid 一致。\n * @param kernel - the BREP engine API.\n * @param upper - the upper solid whose cross section is analyzed.\n * @param basis - the joinery coordinate frame.\n * @returns the detected cross-section components (centroid + area).\n */\nexport function detectCrossSectionComponents(\n kernel: BrepEngineApi,\n upper: BrepHandle,\n basis: JoineryBasis,\n): CrossSectionComponent[] {\n const { normal, planeDistance, widthDir, depthDir, planeCenter } = basis\n const mesh = solidToMeshData(kernel, upper)\n const components = detectCapComponentsFromMesh(mesh, normal, planeDistance)\n\n if (components.length === 0) {\n // 无帽面 → 返回单个全局质心(planeCenter)作为回退\n return [{ centroid: planeCenter, area: 0 }]\n }\n\n return components.map(comp => {\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter, comp)\n const compWidth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, widthDir, comp)\n const compDepth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, depthDir, comp)\n return { centroid, area: compWidth * compDepth }\n })\n}\n\n// ─── 布尔序列(1:1 复刻 csg-worker.ts) ───\n\n/** dovetail 布尔分割的结果 */\nexport interface DovetailSplitBrepResult {\n /** 上部 + 楔(法线正方向半部分加燕尾榫) */\n front: BrepHandle\n /** 下部 - 凹腔(法线负方向半部分减燕尾槽) */\n back: BrepHandle\n}\n\n/** dowel/tenon 布尔分割的结果 */\nexport interface DowelOrTenonSplitBrepResult {\n /** 上部 + 销/榫(法线正方向半部分加圆柱/方柱) */\n front: BrepHandle\n /** 下部 - 孔(法线负方向半部分减圆柱/方柱) */\n back: BrepHandle\n}\n\n/** groove 参数 */\nexport interface GrooveParams {\n depth: number\n depthTolerance: number\n width: number\n widthTolerance: number\n flapsAngle: number\n}\n\n/**\n * Dovetail(燕尾)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dovetailBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. 计算 crossSectionWidth(bbox 投影近似)\n * 3. buildWedgeSolid(overhang=20)→ common(wedge, lower) 裁剪贴合\n * 4. fuse(upper, wedgeTrimmed) → upper'\n * 5. buildWedgeSolid(公差)→ cut(lower, wedgeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param groove - the dovetail groove parameters.\n * @returns the split result with front (upper + wedge) and back (lower - cavity) handles.\n */\nexport function dovetailBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n groove: GrooveParams,\n): DovetailSplitBrepResult {\n const { normal, widthDir, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 计算截面宽度(bbox 投影近似,后续 common 会裁回真实边界)\n const upperBbox = getSolidBoundingBox(kernel, upper)\n const upperSize: Vec3 = [\n upperBbox.max[0] - upperBbox.min[0],\n upperBbox.max[1] - upperBbox.min[1],\n upperBbox.max[2] - upperBbox.min[2],\n ]\n let crossSectionWidth =\n Math.abs(upperSize[0] * widthDir[0]) +\n Math.abs(upperSize[1] * widthDir[1]) +\n Math.abs(upperSize[2] * widthDir[2])\n if (crossSectionWidth <= 0) crossSectionWidth = 10 // 安全回退\n const extrudeLength = crossSectionWidth + 0.2\n const overhang = 20\n\n // Step 3: 构造楔(带 overhang)\n const wedgeW = buildWedgeSolid(kernel, basis, groove.depth, groove.width, groove.flapsAngle, extrudeLength + overhang)\n\n // Step 4: common(wedge, lower) → 裁剪楔贴合模型边界\n const wedgeTrimmed = kernel.common(wedgeW, lower)\n kernel.release(wedgeW)\n\n // Step 5: fuse(upper, wedgeTrimmed) → upper'\n const newUpper = kernel.fuse(upper, wedgeTrimmed)\n kernel.release(upper)\n kernel.release(wedgeTrimmed)\n upper = newUpper\n\n // Step 6: 构造公差楔\n const wedgeTol = buildWedgeSolid(\n kernel, basis,\n groove.depth + groove.depthTolerance,\n groove.width + groove.widthTolerance,\n groove.flapsAngle,\n extrudeLength + overhang,\n )\n\n // Step 7: cut(lower, wedgeTol) → lower'\n const newLower = kernel.cut(lower, wedgeTol)\n kernel.release(lower)\n kernel.release(wedgeTol)\n lower = newLower\n\n return { front: upper, back: lower }\n}\n\n/** dowel/tenon 参数 */\nexport interface DowelOrTenonParams {\n /** 直径(dowel)或边长(tenon) */\n size: number\n /** 尺寸公差 */\n sizeTolerance: number\n /** 高度 */\n height: number\n /** 高度公差 */\n heightTolerance: number\n}\n\n/**\n * Dowel(定位销)/ Tenon(直榫)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dowelOrTenonBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. detectCrossSectionComponents → 截面质心列表\n * 3. 对每个质心:buildShapeSolid → fuse(upper, shape) → upper'\n * 4. 对每个质心:buildShapeSolid(公差)→ cut(lower, shapeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param shape - whether to build a dowel or a tenon.\n * @param params - the dowel/tenon size and tolerance parameters.\n * @param selectedSections - optional indices of cross-section components to place shapes on.\n * @returns the split result with front (upper + shape) and back (lower - hole) handles.\n */\nexport function dowelOrTenonBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n shape: 'dowel' | 'tenon',\n params: DowelOrTenonParams,\n selectedSections?: number[] | null,\n): DowelOrTenonSplitBrepResult {\n const { normal, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 检测截面分量\n const components = detectCrossSectionComponents(kernel, upper, basis)\n\n // 构建放置位置列表\n interface Placement { centroid: Vec3 }\n let placements: Placement[]\n\n if (components.length <= 1 || !selectedSections || selectedSections.length === 0) {\n // 单截面或无选择 → 全局质心(向后兼容)\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n } else {\n // 多截面:按面积降序排,取选择的分量\n const sorted = [...components].sort((a, b) => b.area - a.area)\n placements = []\n for (const selId of selectedSections) {\n if (selId < sorted.length) {\n placements.push({ centroid: sorted[selId].centroid })\n }\n }\n if (placements.length === 0) {\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n }\n }\n\n // Step 3: 对每个质心构造基本体并 fuse 到 upper\n for (const { centroid } of placements) {\n let shapeC: BrepHandle\n if (shape === 'dowel') {\n shapeC = buildDowelSolid(kernel, centroid, basis, params.size, params.height)\n } else {\n shapeC = buildTenonSolid(kernel, centroid, basis, params.size, params.height)\n }\n\n const newUpper = kernel.fuse(upper, shapeC)\n kernel.release(upper)\n kernel.release(shapeC)\n upper = newUpper\n }\n\n // Step 4: 对每个质心构造公差体并 cut 从 lower\n const tolSize = params.size + params.sizeTolerance\n const tolHeight = params.height + params.heightTolerance\n\n for (const { centroid } of placements) {\n let shapeCTol: BrepHandle\n if (shape === 'dowel') {\n shapeCTol = buildDowelSolid(kernel, centroid, basis, tolSize, tolHeight)\n } else {\n shapeCTol = buildTenonSolid(kernel, centroid, basis, tolSize, tolHeight)\n }\n\n const newLower = kernel.cut(lower, shapeCTol)\n kernel.release(lower)\n kernel.release(shapeCTol)\n lower = newLower\n }\n\n return { front: upper, back: lower }\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cadquery-selectors/borrow-bridge — compatOp 提升边界归一(等价搬运自 cq-compat)
|
|
3
|
+
*
|
|
4
|
+
* 原实现位于 `packages/faijs-cadquery/src/workplane.ts` 的 `asBrepShape`,本文件为
|
|
5
|
+
* 原样搬运(仅 import 路径改为 core 内部相对路径),零逻辑改动。
|
|
6
|
+
*/
|
|
7
|
+
import type { Shape } from '../../mesh/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* 把可能是借用视图的几何输入归一为真实 faijs Shape(见上方注释)。
|
|
10
|
+
* @param v 真实 Shape、借用视图(`{ wrapped }`)或其他原样透传的输入。
|
|
11
|
+
* @returns 真实 faijs `Shape`(借用视图经 `fromHandle` 还原并缓存)。
|
|
12
|
+
*/
|
|
13
|
+
export declare function asBrepShape(v: unknown): Shape;
|
|
14
|
+
//# sourceMappingURL=borrow-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"borrow-bridge.d.ts","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/borrow-bridge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAuB7C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAgB7C"}
|