@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/mesh/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mesh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,UAAU,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,MAAM,CAAA;AAE7B,sBAAsB;AAEtB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,cAAc;IACd,GAAG,EAAE,UAAU,CAAC,GAAG;IACnB,MAAM,EAAE,UAAU,CAAC,MAAM;IACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;IAC7B,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,GAAG,EAAE,UAAU,CAAC,GAAG;IAEnB,6BAA6B;IAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;IAC/B,UAAU,EAAE,cAAc,CAAC,UAAU;IACrC,YAAY,EAAE,cAAc,CAAC,YAAY;IACzC,QAAQ,EAAE,cAAc,CAAC,QAAQ;IACjC,SAAS,EAAE,cAAc,CAAC,SAAS;IAEnC,KAAK;IACL,SAAS,EAAE,YAAY,CAAC,SAAS;IACjC,YAAY,EAAE,YAAY,CAAC,YAAY;IACvC,KAAK,EAAE,YAAY,CAAC,KAAK;IACzB,OAAO,EAAE,YAAY,CAAC,OAAO;IAC7B,eAAe,EAAE,YAAY,CAAC,eAAe;IAE7C,KAAK;IACL,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,QAAQ,EAAE,UAAU,CAAC,QAAQ;IAC7B,SAAS,EAAE,UAAU,CAAC,SAAS;IAE/B,KAAK;IACL,wDAAwD;IACxD,0EAA0E;IAE1E,KAAK;IACL,OAAO,EAAE,UAAU,CAAC,OAAO;IAC3B,KAAK,EAAE,UAAU,CAAC,KAAK;IAEvB,KAAK;IACL,WAAW,EAAE,QAAQ,CAAC,WAAW;IACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;IAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;IAEvB,KAAK;IACL,IAAI,EAAE,KAAK,CAAC,UAAU;IAEtB,mCAAmC;IACnC,aAAa,EAAE,OAAO,CAAC,aAAa;IACpC,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;IAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;CACnC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mesh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,UAAU,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,MAAM,CAAA;AAE7B,sBAAsB;AAEtB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,cAAc;IACd,GAAG,EAAE,UAAU,CAAC,GAAG;IACnB,MAAM,EAAE,UAAU,CAAC,MAAM;IACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;IAC7B,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,GAAG,EAAE,UAAU,CAAC,GAAG;IAEnB,6BAA6B;IAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;IAC/B,UAAU,EAAE,cAAc,CAAC,UAAU;IACrC,YAAY,EAAE,cAAc,CAAC,YAAY;IACzC,QAAQ,EAAE,cAAc,CAAC,QAAQ;IACjC,SAAS,EAAE,cAAc,CAAC,SAAS;IAEnC,KAAK;IACL,SAAS,EAAE,YAAY,CAAC,SAAS;IACjC,YAAY,EAAE,YAAY,CAAC,YAAY;IACvC,KAAK,EAAE,YAAY,CAAC,KAAK;IACzB,OAAO,EAAE,YAAY,CAAC,OAAO;IAC7B,eAAe,EAAE,YAAY,CAAC,eAAe;IAE7C,KAAK;IACL,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,QAAQ,EAAE,UAAU,CAAC,QAAQ;IAC7B,SAAS,EAAE,UAAU,CAAC,SAAS;IAE/B,KAAK;IACL,wDAAwD;IACxD,0EAA0E;IAE1E,KAAK;IACL,OAAO,EAAE,UAAU,CAAC,OAAO;IAC3B,KAAK,EAAE,UAAU,CAAC,KAAK;IAEvB,KAAK;IACL,WAAW,EAAE,QAAQ,CAAC,WAAW;IACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;IAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;IAEvB,KAAK;IACL,IAAI,EAAE,KAAK,CAAC,UAAU;IAEtB,mCAAmC;IACnC,aAAa,EAAE,OAAO,CAAC,aAAa;IACpC,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;IAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;CACnC,CAAA;AAKD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAazC,OAAO,EACL,oBAAoB,EAAE,kBAAkB,EAAE,qBAAqB,EAC/D,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAA","sourcesContent":["/**\n * mesh — 纯数据几何 API 统一入口\n *\n * See docs/api-contract.md §1 (architecture layers) and §10 (api function catalog).\n *\n * 原则(§5.1):\n * 1. 全部纯数据:输入输出是 Shape (ManifoldMeshData),不碰 THREE 场景、不读 store\n * 2. 不可变:每个 API 返回新几何,不修改输入\n * 3. 同步签名、异步执行:API 签名同步(或 async);worker 边界由 ScriptEngine 处理\n * 4. 坐标系:右手系 +Z 向上、毫米、角度用度\n *\n * P1 阶段:mesh 是对现有纯函数的薄包装层,行为完全不变。\n * P3+ 阶段:mesh 将由 ScriptEngine 驱动,在 worker 中执行。\n */\n\nimport * as primitives from './primitives'\nimport * as brepPrimitives from '../brep/primitives-brep'\nimport * as brepOps from '../brep'\nimport * as booleanOps from './boolean'\nimport * as engraveOps from './engrave'\nimport * as transformOps from './transform'\nimport * as queryOps from './query'\nimport * as ioOps from './io'\n\n// ── 统一 cad API 对象 ──\n\n/**\n * Unified `cad` API object aggregating the pure-data mesh operations: mesh and\n * BREP primitives, transforms, booleans, engrave/knurl, geometry queries, file\n * IO, and BREP feature operations.\n *\n * D1(2026-09-23 扩展库拆分):`text` / `svgExtrude` / `fai_*` 键已随\n * `@faicad/faijs-extra` 迁出——它们的实现在扩展库的 mesh 面(`editorCad`)。\n */\nexport const cad = {\n // 创建(mesh 路径)\n box: primitives.box,\n sphere: primitives.sphere,\n cylinder: primitives.cylinder,\n cone: primitives.cone,\n wedge: primitives.wedge,\n screw: primitives.screw,\n sdf: primitives.sdf,\n\n // 创建(BREP 路径 — OCCT 精确实体三角化)\n boxBrep: brepPrimitives.boxBrep,\n sphereBrep: brepPrimitives.sphereBrep,\n cylinderBrep: brepPrimitives.cylinderBrep,\n coneBrep: brepPrimitives.coneBrep,\n wedgeBrep: brepPrimitives.wedgeBrep,\n\n // 变换\n translate: transformOps.translate,\n rotate_euler: transformOps.rotate_euler,\n scale: transformOps.scale,\n scale3d: transformOps.scale3d,\n transformMatrix: transformOps.transformMatrix,\n\n // 布尔\n union: booleanOps.union,\n subtract: booleanOps.subtract,\n intersect: booleanOps.intersect,\n\n // 分割\n // `fai_*` 键(编辑器消费面)已随扩展库迁出:@faicad/faijs-extra 的 mesh 面\n // 经 `mesh/fai_split.ts` / `mesh/fai_drill.ts` / `mesh/fai_extrude.ts` 提供。\n\n // 雕刻\n engrave: engraveOps.engrave,\n knurl: engraveOps.knurl,\n\n // 查询\n boundingBox: queryOps.boundingBox,\n bboxCenter: queryOps.bboxCenter,\n volume: queryOps.volume,\n faceAt: queryOps.faceAt,\n\n // IO\n load: ioOps.importFile,\n\n // BREP 特征操作(Phase 2 — OCCT 精确实体运算)\n translateBrep: brepOps.translateBrep,\n rotateBrep: brepOps.rotateBrep,\n scaleBrep: brepOps.scaleBrep,\n fuseBrep: brepOps.fuseBrep,\n cutBrep: brepOps.cutBrep,\n commonBrep: brepOps.commonBrep,\n drillBrep: brepOps.drillBrep,\n splitBrep: brepOps.splitBrep,\n extrudeBrep: brepOps.extrudeBrep,\n loadBrep: brepOps.loadBrep,\n solidToShape: brepOps.solidToShape,\n}\n\n// ── 类型导出 ──\n\nexport type { Shape, Vec3, BoundingBox, FaceDescriptor } from './types'\nexport { guessStlUnit } from './stl-unit'\nexport type {\n BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams,\n TextParams, SvgExtrudeParams, SdfParams,\n DrillParams, ExtrudeParams, EngraveParams, KnurlParams,\n SplitPlane, SplitResult, DovetailSplitParams, DowelSplitParams, TenonSplitParams,\n} from './types'\n\n// BREP ops 类型导出\nexport type {\n BrepChainState, DrillBrepParams, SplitBrepParams, SplitBrepResult,\n ExtrudeBrepParams,\n} from '../brep'\nexport {\n createBrepChainState, initBrepChainState, releaseBrepChainState,\n solidToShape,\n isCadFormat,\n} from '../brep'\n"]}
|
package/dist/mesh/io.d.ts
CHANGED
|
@@ -1,18 +1,78 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* mesh IO API — headless 文件加载
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons);3MF 由
|
|
5
|
+
* `mesh/threemf-loader.ts` 解析(ZIP 解压 + XML,单位换算到 mm 基准)。
|
|
6
|
+
* 坐标永远以 faijs 基准长度单位(mm)存储 — Shape 不贴 unit 标签(D3)。
|
|
7
|
+
*
|
|
8
|
+
* 单位换算边界(unit-system §5.2):
|
|
9
|
+
* - STL 无单位元数据 → 由 `opts.unit` 显式声明,缺省 mm,不做启发式猜测。
|
|
10
|
+
* - 3MF `<model unit>` 由解析器读取并换算(micron/mm/cm/inch/foot/meter)。
|
|
11
|
+
*
|
|
12
|
+
* 返回契约(unit-system §10.6):`importFile` 返回 `{ shape, unit }` — `unit`
|
|
13
|
+
* 是文件**自己声明的单位**(3MF `<model unit>`、STEP 单位实体),无声明格式
|
|
14
|
+
* (STL)为 null(此时 `opts.unit` 决定刻度)。坐标恒为基准值 — `unit` 只作
|
|
15
|
+
* 元数据(sourceUnit 记录、导出目标判定),绝不参与几何缩放(读入折算已由
|
|
16
|
+
* 内核/解析器完成,二次缩放 = 双重换算)。
|
|
7
17
|
*/
|
|
18
|
+
import { type UnitName, type ValueWithUnits } from '../units.js';
|
|
8
19
|
import type { Shape } from './types.js';
|
|
20
|
+
/** Result of a unit-aware file import. */
|
|
21
|
+
export interface ImportFileResult {
|
|
22
|
+
shape: Shape;
|
|
23
|
+
/**
|
|
24
|
+
* The unit the file itself declares (3MF `<model unit>`, STEP unit entities).
|
|
25
|
+
* null for declaration-less formats (STL) — the caller's opts.unit decided.
|
|
26
|
+
*/
|
|
27
|
+
unit: UnitName | null;
|
|
28
|
+
/**
|
|
29
|
+
* Total parts the single file declared (e.g. 3MF `<build>` object count),
|
|
30
|
+
* present only when > 1. Single-part mesh (STL, single-object 3MF) omits it.
|
|
31
|
+
* When set, `shape` is only the FIRST part's geometry (feijs `load` op is
|
|
32
|
+
* single-part; the file was downgraded to its first part — §5.4).
|
|
33
|
+
*/
|
|
34
|
+
multiPartCount?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Bounded scan window for `detectStepUnit`. Unit entities sit at the front of
|
|
38
|
+
* the DATA section (right after the product/context blocks); 256 KiB covers
|
|
39
|
+
* every real-world header+context preamble observed so far. Recomputable
|
|
40
|
+
* constant — raise if a fixture ever misses.
|
|
41
|
+
*/
|
|
42
|
+
export declare const STEP_UNIT_SCAN_PREFIX: number;
|
|
43
|
+
/**
|
|
44
|
+
* Parse the declared length unit from STEP text (unit-system §10.4).
|
|
45
|
+
*
|
|
46
|
+
* Unit entities live in the DATA section (not HEADER — ISO 10303-21 reserves
|
|
47
|
+
* HEADER for FILE_DESCRIPTION/FILE_NAME/FILE_SCHEMA), near its start. We scan
|
|
48
|
+
* a bounded prefix; the justification is "unit entities sit at the front of
|
|
49
|
+
* the DATA section", not "top of file".
|
|
50
|
+
*
|
|
51
|
+
* Recognized forms, both attached to a LENGTH_UNIT():
|
|
52
|
+
* - `SI_UNIT(<prefix>, .METRE.)` — prefix `.MILLI.`/`.CENTI.`/`.MICRO.` or `$`.
|
|
53
|
+
* - `CONVERSION_BASED_UNIT('<NAME>', #n)` — inch/foot/etc.
|
|
54
|
+
*
|
|
55
|
+
* Metadata only — NEVER used to scale geometry (OCCT already normalizes on
|
|
56
|
+
* read; re-scaling = double conversion).
|
|
57
|
+
*
|
|
58
|
+
* @param stepText - the full STEP file text to scan (only a bounded prefix is read).
|
|
59
|
+
* @returns the faijs UnitName, or null when no length-unit declaration is found
|
|
60
|
+
* (STEP permits omitting it; caller falls back to the base unit).
|
|
61
|
+
*/
|
|
62
|
+
export declare function detectStepUnit(stepText: string): UnitName | null;
|
|
9
63
|
/**
|
|
10
|
-
* Load geometry from raw file bytes (headless variant).
|
|
11
|
-
* directly; unsupported formats fall back to STL parsing.
|
|
64
|
+
* Load geometry from raw file bytes (headless variant).
|
|
12
65
|
*
|
|
13
|
-
* @param buffer - the raw file bytes to parse
|
|
14
|
-
*
|
|
15
|
-
* @
|
|
66
|
+
* @param buffer - the raw file bytes to parse (already decompressed; stpz
|
|
67
|
+
* unzipping is the caller's job — faijs never unzips implicitly).
|
|
68
|
+
* @param format - format identifier such as 'stl', '3mf'/'threemf' or 'step'
|
|
69
|
+
* (defaults to 'stl').
|
|
70
|
+
* @param opts - optional settings; `unit` declares the source unit for
|
|
71
|
+
* formats without unit metadata (e.g. STL). Defaults to mm.
|
|
72
|
+
* @returns the shape with base-unit coordinates plus the file's own declared
|
|
73
|
+
* unit (`unit`, metadata only; null when the format has no declaration).
|
|
16
74
|
*/
|
|
17
|
-
export declare function importFile(buffer: ArrayBuffer, format?: string
|
|
75
|
+
export declare function importFile(buffer: ArrayBuffer, format?: string, opts?: {
|
|
76
|
+
unit?: ValueWithUnits;
|
|
77
|
+
}): Promise<ImportFileResult>;
|
|
18
78
|
//# sourceMappingURL=io.d.ts.map
|
package/dist/mesh/io.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EAAM,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAA;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAA;IACZ;;;OAGG;IACH,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAA;IACrB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAuBD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAa,CAAA;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAqBhE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,WAAW,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,cAAc,CAAA;CAAE,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAmC3B"}
|
package/dist/mesh/io.js
CHANGED
|
@@ -1,31 +1,135 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* mesh IO API — headless 文件加载
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons);3MF 由
|
|
5
|
+
* `mesh/threemf-loader.ts` 解析(ZIP 解压 + XML,单位换算到 mm 基准)。
|
|
6
|
+
* 坐标永远以 faijs 基准长度单位(mm)存储 — Shape 不贴 unit 标签(D3)。
|
|
7
|
+
*
|
|
8
|
+
* 单位换算边界(unit-system §5.2):
|
|
9
|
+
* - STL 无单位元数据 → 由 `opts.unit` 显式声明,缺省 mm,不做启发式猜测。
|
|
10
|
+
* - 3MF `<model unit>` 由解析器读取并换算(micron/mm/cm/inch/foot/meter)。
|
|
11
|
+
*
|
|
12
|
+
* 返回契约(unit-system §10.6):`importFile` 返回 `{ shape, unit }` — `unit`
|
|
13
|
+
* 是文件**自己声明的单位**(3MF `<model unit>`、STEP 单位实体),无声明格式
|
|
14
|
+
* (STL)为 null(此时 `opts.unit` 决定刻度)。坐标恒为基准值 — `unit` 只作
|
|
15
|
+
* 元数据(sourceUnit 记录、导出目标判定),绝不参与几何缩放(读入折算已由
|
|
16
|
+
* 内核/解析器完成,二次缩放 = 双重换算)。
|
|
7
17
|
*/
|
|
8
18
|
import { geoToManifoldMesh } from '../boolean/geo-convert.js';
|
|
9
19
|
import { parseStl } from './stl-loader.js';
|
|
20
|
+
import { parseThreemf } from './threemf-loader.js';
|
|
21
|
+
import { mm } from '../units.js';
|
|
22
|
+
/** SI prefixes that may precede .METRE. in a STEP SI_UNIT, → faijs UnitName. */
|
|
23
|
+
const SI_PREFIX_TO_UNIT = {
|
|
24
|
+
'.MILLI.': 'mm',
|
|
25
|
+
'.CENTI.': 'cm',
|
|
26
|
+
'$': 'm',
|
|
27
|
+
};
|
|
28
|
+
/** CONVERSION_BASED_UNIT names (uppercased) found in real-world STEP files. */
|
|
29
|
+
const CONVERSION_NAME_TO_UNIT = {
|
|
30
|
+
'METRE': 'm',
|
|
31
|
+
'METER': 'm',
|
|
32
|
+
'MILLIMETRE': 'mm',
|
|
33
|
+
'MILLIMETER': 'mm',
|
|
34
|
+
'CENTIMETRE': 'cm',
|
|
35
|
+
'CENTIMETER': 'cm',
|
|
36
|
+
'MICROMETRE': 'micron',
|
|
37
|
+
'MICROMETER': 'micron',
|
|
38
|
+
'INCH': 'inch',
|
|
39
|
+
'FOOT': 'foot',
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Bounded scan window for `detectStepUnit`. Unit entities sit at the front of
|
|
43
|
+
* the DATA section (right after the product/context blocks); 256 KiB covers
|
|
44
|
+
* every real-world header+context preamble observed so far. Recomputable
|
|
45
|
+
* constant — raise if a fixture ever misses.
|
|
46
|
+
*/
|
|
47
|
+
export const STEP_UNIT_SCAN_PREFIX = 256 * 1024;
|
|
10
48
|
/**
|
|
11
|
-
*
|
|
12
|
-
* directly; unsupported formats fall back to STL parsing.
|
|
49
|
+
* Parse the declared length unit from STEP text (unit-system §10.4).
|
|
13
50
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
51
|
+
* Unit entities live in the DATA section (not HEADER — ISO 10303-21 reserves
|
|
52
|
+
* HEADER for FILE_DESCRIPTION/FILE_NAME/FILE_SCHEMA), near its start. We scan
|
|
53
|
+
* a bounded prefix; the justification is "unit entities sit at the front of
|
|
54
|
+
* the DATA section", not "top of file".
|
|
55
|
+
*
|
|
56
|
+
* Recognized forms, both attached to a LENGTH_UNIT():
|
|
57
|
+
* - `SI_UNIT(<prefix>, .METRE.)` — prefix `.MILLI.`/`.CENTI.`/`.MICRO.` or `$`.
|
|
58
|
+
* - `CONVERSION_BASED_UNIT('<NAME>', #n)` — inch/foot/etc.
|
|
59
|
+
*
|
|
60
|
+
* Metadata only — NEVER used to scale geometry (OCCT already normalizes on
|
|
61
|
+
* read; re-scaling = double conversion).
|
|
62
|
+
*
|
|
63
|
+
* @param stepText - the full STEP file text to scan (only a bounded prefix is read).
|
|
64
|
+
* @returns the faijs UnitName, or null when no length-unit declaration is found
|
|
65
|
+
* (STEP permits omitting it; caller falls back to the base unit).
|
|
17
66
|
*/
|
|
18
|
-
export
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
67
|
+
export function detectStepUnit(stepText) {
|
|
68
|
+
const head = stepText.slice(0, STEP_UNIT_SCAN_PREFIX);
|
|
69
|
+
// 1) CONVERSION_BASED_UNIT('<NAME>', #n) — non-SI units (inch/foot/…).
|
|
70
|
+
const conv = head.match(/CONVERSION_BASED_UNIT\s*\(\s*'([^']+)'/i);
|
|
71
|
+
if (conv) {
|
|
72
|
+
const mapped = CONVERSION_NAME_TO_UNIT[conv[1].toUpperCase()];
|
|
73
|
+
if (mapped)
|
|
74
|
+
return mapped;
|
|
75
|
+
}
|
|
76
|
+
// 2) SI_UNIT(<prefix>, .METRE.) — the .METRE. guard excludes angle entities
|
|
77
|
+
// (they carry .RADIAN./.STERADIAN., never .METRE.).
|
|
78
|
+
const si = head.match(/SI_UNIT\s*\(\s*([^)]*?)\s*,\s*\.METRE\.\s*\)/i);
|
|
79
|
+
if (si) {
|
|
80
|
+
const prefix = si[1].trim().toUpperCase();
|
|
81
|
+
if (prefix === '.MICRO.')
|
|
82
|
+
return 'micron';
|
|
83
|
+
const mapped = SI_PREFIX_TO_UNIT[prefix];
|
|
84
|
+
if (mapped)
|
|
85
|
+
return mapped;
|
|
22
86
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Load geometry from raw file bytes (headless variant).
|
|
91
|
+
*
|
|
92
|
+
* @param buffer - the raw file bytes to parse (already decompressed; stpz
|
|
93
|
+
* unzipping is the caller's job — faijs never unzips implicitly).
|
|
94
|
+
* @param format - format identifier such as 'stl', '3mf'/'threemf' or 'step'
|
|
95
|
+
* (defaults to 'stl').
|
|
96
|
+
* @param opts - optional settings; `unit` declares the source unit for
|
|
97
|
+
* formats without unit metadata (e.g. STL). Defaults to mm.
|
|
98
|
+
* @returns the shape with base-unit coordinates plus the file's own declared
|
|
99
|
+
* unit (`unit`, metadata only; null when the format has no declaration).
|
|
100
|
+
*/
|
|
101
|
+
export async function importFile(buffer, format, opts) {
|
|
102
|
+
const fmt = (format ?? 'stl').toLowerCase();
|
|
103
|
+
if (fmt === '3mf' || fmt === 'threemf') {
|
|
104
|
+
const archive = await parseThreemf(buffer);
|
|
105
|
+
// §5.4 单零件收敛:只取**第一个**对象实例(declaration order — `<build><item>`
|
|
106
|
+
// 序,见 threemf-loader)构造成单一 part;多对象文件记 multiPartCount 供上层
|
|
107
|
+
// 登记"多零件降级"警告。坐标已在 parseThreemf 里折算为 faijs 基准单位。
|
|
108
|
+
const first = archive.objects[0];
|
|
109
|
+
if (!first) {
|
|
110
|
+
throw new Error('[mesh/io] 3MF contains no objects');
|
|
111
|
+
}
|
|
112
|
+
const multiPartCount = archive.objects.length > 1 ? archive.objects.length : undefined;
|
|
113
|
+
const shape = {
|
|
114
|
+
positions: first.positions,
|
|
115
|
+
indices: first.indices,
|
|
116
|
+
};
|
|
117
|
+
return { shape, unit: archive.unit, multiPartCount };
|
|
26
118
|
}
|
|
27
|
-
|
|
28
|
-
|
|
119
|
+
if (fmt === 'stl') {
|
|
120
|
+
const scale = (opts?.unit ?? mm).as(mm);
|
|
121
|
+
const geo = parseStl(buffer);
|
|
122
|
+
if (scale !== 1) {
|
|
123
|
+
const attr = geo.getAttribute('position');
|
|
124
|
+
const arr = attr.array;
|
|
125
|
+
for (let i = 0; i < arr.length; i++)
|
|
126
|
+
arr[i] *= scale;
|
|
127
|
+
}
|
|
128
|
+
return { shape: geoToManifoldMesh(geo), unit: null };
|
|
29
129
|
}
|
|
130
|
+
// STEP goes through the BREP chain (loadBrep → OCCT, which normalizes to the
|
|
131
|
+
// base unit on read). The mesh io path has no kernel-independent STEP parser
|
|
132
|
+
// and must not fake one — a missing path is an error, not a fallback.
|
|
133
|
+
throw new Error(`[mesh/io] unsupported format: ${fmt}`);
|
|
30
134
|
}
|
|
31
135
|
//# sourceMappingURL=io.js.map
|
package/dist/mesh/io.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh IO API — headless 文件加载\n *\n * STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons);3MF 由\n * `mesh/threemf-loader.ts` 解析(ZIP 解压 + XML,单位换算到 mm 基准)。\n * 坐标永远以 faijs 基准长度单位(mm)存储 — Shape 不贴 unit 标签(D3)。\n *\n * 单位换算边界(unit-system §5.2):\n * - STL 无单位元数据 → 由 `opts.unit` 显式声明,缺省 mm,不做启发式猜测。\n * - 3MF `<model unit>` 由解析器读取并换算(micron/mm/cm/inch/foot/meter)。\n *\n * 返回契约(unit-system §10.6):`importFile` 返回 `{ shape, unit }` — `unit`\n * 是文件**自己声明的单位**(3MF `<model unit>`、STEP 单位实体),无声明格式\n * (STL)为 null(此时 `opts.unit` 决定刻度)。坐标恒为基准值 — `unit` 只作\n * 元数据(sourceUnit 记录、导出目标判定),绝不参与几何缩放(读入折算已由\n * 内核/解析器完成,二次缩放 = 双重换算)。\n */\n\nimport * as THREE from 'three'\nimport { geoToManifoldMesh } from '../boolean/geo-convert'\nimport { parseStl } from './stl-loader'\nimport { parseThreemf } from './threemf-loader'\nimport { mm, type UnitName, type ValueWithUnits } from '../units'\nimport type { Shape } from './types'\n\n/** Result of a unit-aware file import. */\nexport interface ImportFileResult {\n shape: Shape\n /**\n * The unit the file itself declares (3MF `<model unit>`, STEP unit entities).\n * null for declaration-less formats (STL) — the caller's opts.unit decided.\n */\n unit: UnitName | null\n /**\n * Total parts the single file declared (e.g. 3MF `<build>` object count),\n * present only when > 1. Single-part mesh (STL, single-object 3MF) omits it.\n * When set, `shape` is only the FIRST part's geometry (feijs `load` op is\n * single-part; the file was downgraded to its first part — §5.4).\n */\n multiPartCount?: number\n}\n\n/** SI prefixes that may precede .METRE. in a STEP SI_UNIT, → faijs UnitName. */\nconst SI_PREFIX_TO_UNIT: Record<string, UnitName> = {\n '.MILLI.': 'mm',\n '.CENTI.': 'cm',\n '$': 'm',\n}\n\n/** CONVERSION_BASED_UNIT names (uppercased) found in real-world STEP files. */\nconst CONVERSION_NAME_TO_UNIT: Record<string, UnitName> = {\n 'METRE': 'm',\n 'METER': 'm',\n 'MILLIMETRE': 'mm',\n 'MILLIMETER': 'mm',\n 'CENTIMETRE': 'cm',\n 'CENTIMETER': 'cm',\n 'MICROMETRE': 'micron',\n 'MICROMETER': 'micron',\n 'INCH': 'inch',\n 'FOOT': 'foot',\n}\n\n/**\n * Bounded scan window for `detectStepUnit`. Unit entities sit at the front of\n * the DATA section (right after the product/context blocks); 256 KiB covers\n * every real-world header+context preamble observed so far. Recomputable\n * constant — raise if a fixture ever misses.\n */\nexport const STEP_UNIT_SCAN_PREFIX = 256 * 1024\n\n/**\n * Parse the declared length unit from STEP text (unit-system §10.4).\n *\n * Unit entities live in the DATA section (not HEADER — ISO 10303-21 reserves\n * HEADER for FILE_DESCRIPTION/FILE_NAME/FILE_SCHEMA), near its start. We scan\n * a bounded prefix; the justification is \"unit entities sit at the front of\n * the DATA section\", not \"top of file\".\n *\n * Recognized forms, both attached to a LENGTH_UNIT():\n * - `SI_UNIT(<prefix>, .METRE.)` — prefix `.MILLI.`/`.CENTI.`/`.MICRO.` or `$`.\n * - `CONVERSION_BASED_UNIT('<NAME>', #n)` — inch/foot/etc.\n *\n * Metadata only — NEVER used to scale geometry (OCCT already normalizes on\n * read; re-scaling = double conversion).\n *\n * @param stepText - the full STEP file text to scan (only a bounded prefix is read).\n * @returns the faijs UnitName, or null when no length-unit declaration is found\n * (STEP permits omitting it; caller falls back to the base unit).\n */\nexport function detectStepUnit(stepText: string): UnitName | null {\n const head = stepText.slice(0, STEP_UNIT_SCAN_PREFIX)\n\n // 1) CONVERSION_BASED_UNIT('<NAME>', #n) — non-SI units (inch/foot/…).\n const conv = head.match(/CONVERSION_BASED_UNIT\\s*\\(\\s*'([^']+)'/i)\n if (conv) {\n const mapped = CONVERSION_NAME_TO_UNIT[conv[1].toUpperCase()]\n if (mapped) return mapped\n }\n\n // 2) SI_UNIT(<prefix>, .METRE.) — the .METRE. guard excludes angle entities\n // (they carry .RADIAN./.STERADIAN., never .METRE.).\n const si = head.match(/SI_UNIT\\s*\\(\\s*([^)]*?)\\s*,\\s*\\.METRE\\.\\s*\\)/i)\n if (si) {\n const prefix = si[1].trim().toUpperCase()\n if (prefix === '.MICRO.') return 'micron'\n const mapped = SI_PREFIX_TO_UNIT[prefix]\n if (mapped) return mapped\n }\n\n return null\n}\n\n/**\n * Load geometry from raw file bytes (headless variant).\n *\n * @param buffer - the raw file bytes to parse (already decompressed; stpz\n * unzipping is the caller's job — faijs never unzips implicitly).\n * @param format - format identifier such as 'stl', '3mf'/'threemf' or 'step'\n * (defaults to 'stl').\n * @param opts - optional settings; `unit` declares the source unit for\n * formats without unit metadata (e.g. STL). Defaults to mm.\n * @returns the shape with base-unit coordinates plus the file's own declared\n * unit (`unit`, metadata only; null when the format has no declaration).\n */\nexport async function importFile(\n buffer: ArrayBuffer,\n format?: string,\n opts?: { unit?: ValueWithUnits },\n): Promise<ImportFileResult> {\n const fmt = (format ?? 'stl').toLowerCase()\n\n if (fmt === '3mf' || fmt === 'threemf') {\n const archive = await parseThreemf(buffer)\n // §5.4 单零件收敛:只取**第一个**对象实例(declaration order — `<build><item>`\n // 序,见 threemf-loader)构造成单一 part;多对象文件记 multiPartCount 供上层\n // 登记\"多零件降级\"警告。坐标已在 parseThreemf 里折算为 faijs 基准单位。\n const first = archive.objects[0]\n if (!first) {\n throw new Error('[mesh/io] 3MF contains no objects')\n }\n const multiPartCount = archive.objects.length > 1 ? archive.objects.length : undefined\n const shape: Shape = {\n positions: first.positions as Float32Array,\n indices: first.indices as Uint32Array,\n }\n return { shape, unit: archive.unit, multiPartCount }\n }\n\n if (fmt === 'stl') {\n const scale = (opts?.unit ?? mm).as(mm)\n const geo = parseStl(buffer)\n if (scale !== 1) {\n const attr = geo.getAttribute('position') as THREE.BufferAttribute\n const arr = attr.array as Float32Array\n for (let i = 0; i < arr.length; i++) arr[i] *= scale\n }\n return { shape: geoToManifoldMesh(geo), unit: null }\n }\n\n // STEP goes through the BREP chain (loadBrep → OCCT, which normalizes to the\n // base unit on read). The mesh io path has no kernel-independent STEP parser\n // and must not fake one — a missing path is an error, not a fallback.\n throw new Error(`[mesh/io] unsupported format: ${fmt}`)\n}\n"]}
|
package/dist/mesh/reconcile.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* 3. 朝向统一(连通分量内面法向传播,翻转不一致者)
|
|
13
13
|
* 4. 2-manifold 断言(每条边恰好被 2 个三角形共享;不满足即显式报错,不静默、不 try-catch 回退)
|
|
14
14
|
*
|
|
15
|
-
* 红线(AGENTS.md):这是输入数据规整,不是运行时回退——调用方(
|
|
15
|
+
* 红线(AGENTS.md):这是输入数据规整,不是运行时回退——调用方(api 各 op 的
|
|
16
16
|
* mesh 路径)在 dispatchPath 静态判定为 'mesh' 之后、进入 manifold 之前调用。
|
|
17
17
|
*/
|
|
18
18
|
/**
|
package/dist/mesh/reconcile.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* 3. 朝向统一(连通分量内面法向传播,翻转不一致者)
|
|
13
13
|
* 4. 2-manifold 断言(每条边恰好被 2 个三角形共享;不满足即显式报错,不静默、不 try-catch 回退)
|
|
14
14
|
*
|
|
15
|
-
* 红线(AGENTS.md):这是输入数据规整,不是运行时回退——调用方(
|
|
15
|
+
* 红线(AGENTS.md):这是输入数据规整,不是运行时回退——调用方(api 各 op 的
|
|
16
16
|
* mesh 路径)在 dispatchPath 静态判定为 'mesh' 之后、进入 manifold 之前调用。
|
|
17
17
|
*/
|
|
18
18
|
import { weldPositionsWorker } from '../boolean/csg-core.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/mesh/reconcile.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * reconcile — BREP 三角汤归约为合法 2-manifold 网格(P0-1c)\n *\n *\n * 职责:把 OCCT 逐面三角化(`kernel.meshShape` 产物:共享边顶点重复、\n * 可能带朝向/退化问题)归约为 manifold-3d 可接受的合法 2-manifold 网格。\n * weld(顶点焊接)只是其中一步,故文件名为 reconcile 而非 weld。\n *\n * 纯数据、无 wasm 依赖、可单测。四步按顺序执行,每步可独立断言:\n * 1. 顶点焊接(复用 csg-core 的 weldPositionsWorker,1e-6 mm 量化,推原始坐标无精度损失)\n * 2. 退化剔除(零面积三角形)\n * 3. 朝向统一(连通分量内面法向传播,翻转不一致者)\n * 4. 2-manifold 断言(每条边恰好被 2 个三角形共享;不满足即显式报错,不静默、不 try-catch 回退)\n *\n * 红线(AGENTS.md):这是输入数据规整,不是运行时回退——调用方(stdlib 各 op 的\n * mesh 路径)在 dispatchPath 静态判定为 'mesh' 之后、进入 manifold 之前调用。\n */\n\nimport { weldPositionsWorker } from '../boolean/csg-core'\n\n/**\n * Result of one reconciliation step: the reduced vertex buffer and the index\n * buffer of triangles referencing it.\n */\nexport interface ReconcileResult {\n positions: Float32Array\n indices: Uint32Array\n}\n\n// ── 步骤 1:顶点焊接 ──\n\n/**\n * Weld duplicated vertices shared across triangle edges (reuses the single\n * csg-core weld implementation). Input coordinates are preserved — the 1e-6\n * quantization is only used as a map key and is never written back — so there\n * is no precision loss.\n * @param positions - flat XYZ vertex buffer, length 3 * vertexCount.\n * @param indices - triangle index buffer, length 3 * triangleCount.\n * @returns the welded mesh as a new ReconcileResult.\n */\nexport function weldVertices(\n positions: Float32Array,\n indices: Uint32Array,\n): ReconcileResult {\n const welded = weldPositionsWorker(positions, indices, indices.length)\n return { positions: welded.positions, indices: welded.indices }\n}\n\n// ── 步骤 2:退化剔除 ──\n\n/** 计算包围盒对角线长度(数值尺度参考)。 */\nfunction bboxDiagonal(positions: Float32Array): number {\n let minX = Infinity, minY = Infinity, minZ = Infinity\n let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity\n for (let i = 0; i < positions.length; i += 3) {\n const x = positions[i], y = positions[i + 1], z = positions[i + 2]\n if (x < minX) minX = x\n if (y < minY) minY = y\n if (z < minZ) minZ = z\n if (x > maxX) maxX = x\n if (y > maxY) maxY = y\n if (z > maxZ) maxZ = z\n }\n const dx = maxX - minX, dy = maxY - minY, dz = maxZ - minZ\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n}\n\n/**\n * Drop zero-area triangles and compact the surviving indices, also squeezing\n * out vertices that are no longer referenced. A triangle is degenerate when\n * its area is below the relative threshold (diagonal * 1e-9)².\n * @param positions - flat XYZ vertex buffer, length 3 * vertexCount.\n * @param indices - triangle index buffer, length 3 * triangleCount.\n * @returns the cleaned mesh as a new ReconcileResult.\n */\nexport function removeDegenerate(\n positions: Float32Array,\n indices: Uint32Array,\n): ReconcileResult {\n const triCount = indices.length / 3\n if (triCount === 0) return { positions, indices }\n\n const diag = bboxDiagonal(positions)\n const areaEps = diag * 1e-9\n const areaEpsSq = areaEps * areaEps\n\n const keep = new Uint8Array(triCount)\n let keptCount = 0\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 x0 = positions[i0 * 3], y0 = positions[i0 * 3 + 1], z0 = positions[i0 * 3 + 2]\n const x1 = positions[i1 * 3], y1 = positions[i1 * 3 + 1], z1 = positions[i1 * 3 + 2]\n const x2 = positions[i2 * 3], y2 = positions[i2 * 3 + 1], z2 = positions[i2 * 3 + 2]\n\n // cross(u, v) 长度平方:u = v1 - v0, v = v2 - v0\n const ux = x1 - x0, uy = y1 - y0, uz = z1 - z0\n const vx = x2 - x0, vy = y2 - y0, vz = z2 - z0\n const cx = uy * vz - uz * vy\n const cy = uz * vx - ux * vz\n const cz = ux * vy - uy * vx\n const crossLenSq = cx * cx + cy * cy + cz * cz\n\n if (crossLenSq > areaEpsSq) {\n keep[t] = 1\n keptCount++\n }\n }\n\n if (keptCount === triCount) return { positions, indices }\n\n const newIndices = new Uint32Array(keptCount * 3)\n const remap = new Map<number, number>()\n const newPosArr: number[] = []\n\n let out = 0\n for (let t = 0; t < triCount; t++) {\n if (!keep[t]) continue\n for (let k = 0; k < 3; k++) {\n const vi = indices[t * 3 + k]\n let ni = remap.get(vi)\n if (ni === undefined) {\n ni = newPosArr.length / 3\n remap.set(vi, ni)\n newPosArr.push(positions[vi * 3], positions[vi * 3 + 1], positions[vi * 3 + 2])\n }\n newIndices[out++] = ni\n }\n }\n\n return { positions: new Float32Array(newPosArr), indices: newIndices }\n}\n\n// ── 步骤 3:朝向统一 ──\n\ninterface EdgeRef {\n /** 三角形序号(indices / 3) */\n tri: number\n /** 该三角形沿排序后边的遍历方向:+1 = a→b,-1 = b→a */\n dir: 1 | -1\n}\n\n/**\n * Propagate face winding across each connected component: adjacent triangles\n * sharing an edge must traverse it in opposite directions (manifold winding\n * consistency). Triangles that violate this are flipped (v1/v2 swapped).\n *\n * BFS propagates a flip state f ∈ {+1, -1} per connected component:\n * f(neighbor) = -f(cur) * baseDir(cur, e) * baseDir(neighbor, e)\n * A conflict (one triangle demanded to flip by two different paths) means the\n * mesh is not orientable — the first assignment is kept and step 4's\n * 2-manifold assertion reports the error explicitly.\n * @param positions - flat XYZ vertex buffer.\n * @param indices - triangle index buffer.\n * @returns the orientation-unified mesh as a new ReconcileResult.\n */\nexport function unifyOrientation(\n positions: Float32Array,\n indices: Uint32Array,\n): ReconcileResult {\n const triCount = indices.length / 3\n if (triCount === 0) return { positions, indices }\n\n // 无向边 → 共享它的 (tri, dir) 列表\n const edgeMap = new Map<number, Map<number, EdgeRef[]>>()\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 addEdgeRef(i0, i1, t)\n addEdgeRef(i1, i2, t)\n addEdgeRef(i2, i0, t)\n }\n\n function addEdgeRef(a: number, b: number, tri: number): void {\n const lo = a < b ? a : b\n const hi = a < b ? b : a\n let inner = edgeMap.get(lo)\n if (!inner) {\n inner = new Map()\n edgeMap.set(lo, inner)\n }\n let refs = inner.get(hi)\n if (!refs) {\n refs = []\n inner.set(hi, refs)\n }\n refs.push({ tri, dir: a < b ? 1 : -1 })\n }\n\n // 0 = 未访问,1 = 原朝向,2 = 需翻转\n const flip = new Uint8Array(triCount)\n const queue: number[] = []\n\n for (let seed = 0; seed < triCount; seed++) {\n if (flip[seed] !== 0) continue\n flip[seed] = 1\n queue.length = 0\n queue.push(seed)\n\n while (queue.length > 0) {\n const cur = queue.pop()!\n const curFlip = flip[cur] === 2 ? -1 : 1\n\n for (let k = 0; k < 3; k++) {\n const a = indices[cur * 3 + k]\n const b = indices[cur * 3 + (k + 1) % 3]\n const lo = a < b ? a : b\n const hi = a < b ? b : a\n const refs = edgeMap.get(lo)?.get(hi)\n if (!refs) continue\n\n const baseDirCur: 1 | -1 = a < b ? 1 : -1\n for (const ref of refs) {\n if (ref.tri === cur) continue\n if (flip[ref.tri] !== 0) continue\n // f(n) = -f(c) × dir(c) × dir(n)\n const needFlip = curFlip * baseDirCur * ref.dir === 1 ? 2 : 1\n flip[ref.tri] = needFlip\n queue.push(ref.tri)\n }\n }\n }\n }\n\n // 应用翻转:交换每个三角形 v1/v2\n const out = new Uint32Array(indices)\n for (let t = 0; t < triCount; t++) {\n if (flip[t] === 2) {\n const tmp = out[t * 3 + 1]\n out[t * 3 + 1] = out[t * 3 + 2]\n out[t * 3 + 2] = tmp\n }\n }\n\n return { positions, indices: out }\n}\n\n// ── 步骤 4:2-manifold 断言 ──\n\n/**\n * Assert the mesh is 2-manifold: every undirected edge is shared by exactly\n * two triangles. A violation throws immediately (no silent handling, no\n * try-catch fallback).\n * @param positions - flat XYZ vertex buffer.\n * @param indices - triangle index buffer.\n */\nexport function assertManifold(positions: Float32Array, indices: Uint32Array): void {\n const triCount = indices.length / 3\n const edgeCount = new Map<number, Map<number, number>>()\n\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 bump(i0, i1)\n bump(i1, i2)\n bump(i2, i0)\n }\n\n function bump(a: number, b: number): void {\n const lo = a < b ? a : b\n const hi = a < b ? b : a\n let inner = edgeCount.get(lo)\n if (!inner) {\n inner = new Map()\n edgeCount.set(lo, inner)\n }\n inner.set(hi, (inner.get(hi) ?? 0) + 1)\n }\n\n for (const [lo, inner] of edgeCount) {\n for (const [hi, count] of inner) {\n if (count !== 2) {\n throw new Error(\n `[reconcile] not 2-manifold: edge (${lo},${hi}) shared by ${count} triangles (expected 2)`,\n )\n }\n }\n }\n}\n\n// ── 四步归约(默认入口) ──\n\n/**\n * Tuning knobs for the full reconciliation pass.\n */\nexport interface ReconcileOptions {\n /** Whether to run the 2-manifold assertion (default true). */\n assertManifold?: boolean\n}\n\n/**\n * Full reconciliation: weld → degenerate removal → orientation unification →\n * 2-manifold assertion. An empty mesh is returned untouched.\n * @param positions - flat XYZ vertex buffer.\n * @param indices - triangle index buffer.\n * @param opts - optional tuning knobs, e.g. to skip the manifold assertion.\n * @returns the reconciled mesh as a new ReconcileResult.\n */\nexport function reconcileMesh(\n positions: Float32Array,\n indices: Uint32Array,\n opts?: ReconcileOptions,\n): ReconcileResult {\n if (indices.length === 0 || indices.length % 3 !== 0) {\n if (indices.length === 0) return { positions, indices }\n throw new Error(`[reconcile] indices length must be a multiple of 3, got ${indices.length}`)\n }\n\n let result = weldVertices(positions, indices)\n result = removeDegenerate(result.positions, result.indices)\n result = unifyOrientation(result.positions, result.indices)\n\n if (opts?.assertManifold !== false) {\n assertManifold(result.positions, result.indices)\n }\n return result\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/mesh/reconcile.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * reconcile — BREP 三角汤归约为合法 2-manifold 网格(P0-1c)\n *\n *\n * 职责:把 OCCT 逐面三角化(`kernel.meshShape` 产物:共享边顶点重复、\n * 可能带朝向/退化问题)归约为 manifold-3d 可接受的合法 2-manifold 网格。\n * weld(顶点焊接)只是其中一步,故文件名为 reconcile 而非 weld。\n *\n * 纯数据、无 wasm 依赖、可单测。四步按顺序执行,每步可独立断言:\n * 1. 顶点焊接(复用 csg-core 的 weldPositionsWorker,1e-6 mm 量化,推原始坐标无精度损失)\n * 2. 退化剔除(零面积三角形)\n * 3. 朝向统一(连通分量内面法向传播,翻转不一致者)\n * 4. 2-manifold 断言(每条边恰好被 2 个三角形共享;不满足即显式报错,不静默、不 try-catch 回退)\n *\n * 红线(AGENTS.md):这是输入数据规整,不是运行时回退——调用方(api 各 op 的\n * mesh 路径)在 dispatchPath 静态判定为 'mesh' 之后、进入 manifold 之前调用。\n */\n\nimport { weldPositionsWorker } from '../boolean/csg-core'\n\n/**\n * Result of one reconciliation step: the reduced vertex buffer and the index\n * buffer of triangles referencing it.\n */\nexport interface ReconcileResult {\n positions: Float32Array\n indices: Uint32Array\n}\n\n// ── 步骤 1:顶点焊接 ──\n\n/**\n * Weld duplicated vertices shared across triangle edges (reuses the single\n * csg-core weld implementation). Input coordinates are preserved — the 1e-6\n * quantization is only used as a map key and is never written back — so there\n * is no precision loss.\n * @param positions - flat XYZ vertex buffer, length 3 * vertexCount.\n * @param indices - triangle index buffer, length 3 * triangleCount.\n * @returns the welded mesh as a new ReconcileResult.\n */\nexport function weldVertices(\n positions: Float32Array,\n indices: Uint32Array,\n): ReconcileResult {\n const welded = weldPositionsWorker(positions, indices, indices.length)\n return { positions: welded.positions, indices: welded.indices }\n}\n\n// ── 步骤 2:退化剔除 ──\n\n/** 计算包围盒对角线长度(数值尺度参考)。 */\nfunction bboxDiagonal(positions: Float32Array): number {\n let minX = Infinity, minY = Infinity, minZ = Infinity\n let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity\n for (let i = 0; i < positions.length; i += 3) {\n const x = positions[i], y = positions[i + 1], z = positions[i + 2]\n if (x < minX) minX = x\n if (y < minY) minY = y\n if (z < minZ) minZ = z\n if (x > maxX) maxX = x\n if (y > maxY) maxY = y\n if (z > maxZ) maxZ = z\n }\n const dx = maxX - minX, dy = maxY - minY, dz = maxZ - minZ\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n}\n\n/**\n * Drop zero-area triangles and compact the surviving indices, also squeezing\n * out vertices that are no longer referenced. A triangle is degenerate when\n * its area is below the relative threshold (diagonal * 1e-9)².\n * @param positions - flat XYZ vertex buffer, length 3 * vertexCount.\n * @param indices - triangle index buffer, length 3 * triangleCount.\n * @returns the cleaned mesh as a new ReconcileResult.\n */\nexport function removeDegenerate(\n positions: Float32Array,\n indices: Uint32Array,\n): ReconcileResult {\n const triCount = indices.length / 3\n if (triCount === 0) return { positions, indices }\n\n const diag = bboxDiagonal(positions)\n const areaEps = diag * 1e-9\n const areaEpsSq = areaEps * areaEps\n\n const keep = new Uint8Array(triCount)\n let keptCount = 0\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 x0 = positions[i0 * 3], y0 = positions[i0 * 3 + 1], z0 = positions[i0 * 3 + 2]\n const x1 = positions[i1 * 3], y1 = positions[i1 * 3 + 1], z1 = positions[i1 * 3 + 2]\n const x2 = positions[i2 * 3], y2 = positions[i2 * 3 + 1], z2 = positions[i2 * 3 + 2]\n\n // cross(u, v) 长度平方:u = v1 - v0, v = v2 - v0\n const ux = x1 - x0, uy = y1 - y0, uz = z1 - z0\n const vx = x2 - x0, vy = y2 - y0, vz = z2 - z0\n const cx = uy * vz - uz * vy\n const cy = uz * vx - ux * vz\n const cz = ux * vy - uy * vx\n const crossLenSq = cx * cx + cy * cy + cz * cz\n\n if (crossLenSq > areaEpsSq) {\n keep[t] = 1\n keptCount++\n }\n }\n\n if (keptCount === triCount) return { positions, indices }\n\n const newIndices = new Uint32Array(keptCount * 3)\n const remap = new Map<number, number>()\n const newPosArr: number[] = []\n\n let out = 0\n for (let t = 0; t < triCount; t++) {\n if (!keep[t]) continue\n for (let k = 0; k < 3; k++) {\n const vi = indices[t * 3 + k]\n let ni = remap.get(vi)\n if (ni === undefined) {\n ni = newPosArr.length / 3\n remap.set(vi, ni)\n newPosArr.push(positions[vi * 3], positions[vi * 3 + 1], positions[vi * 3 + 2])\n }\n newIndices[out++] = ni\n }\n }\n\n return { positions: new Float32Array(newPosArr), indices: newIndices }\n}\n\n// ── 步骤 3:朝向统一 ──\n\ninterface EdgeRef {\n /** 三角形序号(indices / 3) */\n tri: number\n /** 该三角形沿排序后边的遍历方向:+1 = a→b,-1 = b→a */\n dir: 1 | -1\n}\n\n/**\n * Propagate face winding across each connected component: adjacent triangles\n * sharing an edge must traverse it in opposite directions (manifold winding\n * consistency). Triangles that violate this are flipped (v1/v2 swapped).\n *\n * BFS propagates a flip state f ∈ {+1, -1} per connected component:\n * f(neighbor) = -f(cur) * baseDir(cur, e) * baseDir(neighbor, e)\n * A conflict (one triangle demanded to flip by two different paths) means the\n * mesh is not orientable — the first assignment is kept and step 4's\n * 2-manifold assertion reports the error explicitly.\n * @param positions - flat XYZ vertex buffer.\n * @param indices - triangle index buffer.\n * @returns the orientation-unified mesh as a new ReconcileResult.\n */\nexport function unifyOrientation(\n positions: Float32Array,\n indices: Uint32Array,\n): ReconcileResult {\n const triCount = indices.length / 3\n if (triCount === 0) return { positions, indices }\n\n // 无向边 → 共享它的 (tri, dir) 列表\n const edgeMap = new Map<number, Map<number, EdgeRef[]>>()\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 addEdgeRef(i0, i1, t)\n addEdgeRef(i1, i2, t)\n addEdgeRef(i2, i0, t)\n }\n\n function addEdgeRef(a: number, b: number, tri: number): void {\n const lo = a < b ? a : b\n const hi = a < b ? b : a\n let inner = edgeMap.get(lo)\n if (!inner) {\n inner = new Map()\n edgeMap.set(lo, inner)\n }\n let refs = inner.get(hi)\n if (!refs) {\n refs = []\n inner.set(hi, refs)\n }\n refs.push({ tri, dir: a < b ? 1 : -1 })\n }\n\n // 0 = 未访问,1 = 原朝向,2 = 需翻转\n const flip = new Uint8Array(triCount)\n const queue: number[] = []\n\n for (let seed = 0; seed < triCount; seed++) {\n if (flip[seed] !== 0) continue\n flip[seed] = 1\n queue.length = 0\n queue.push(seed)\n\n while (queue.length > 0) {\n const cur = queue.pop()!\n const curFlip = flip[cur] === 2 ? -1 : 1\n\n for (let k = 0; k < 3; k++) {\n const a = indices[cur * 3 + k]\n const b = indices[cur * 3 + (k + 1) % 3]\n const lo = a < b ? a : b\n const hi = a < b ? b : a\n const refs = edgeMap.get(lo)?.get(hi)\n if (!refs) continue\n\n const baseDirCur: 1 | -1 = a < b ? 1 : -1\n for (const ref of refs) {\n if (ref.tri === cur) continue\n if (flip[ref.tri] !== 0) continue\n // f(n) = -f(c) × dir(c) × dir(n)\n const needFlip = curFlip * baseDirCur * ref.dir === 1 ? 2 : 1\n flip[ref.tri] = needFlip\n queue.push(ref.tri)\n }\n }\n }\n }\n\n // 应用翻转:交换每个三角形 v1/v2\n const out = new Uint32Array(indices)\n for (let t = 0; t < triCount; t++) {\n if (flip[t] === 2) {\n const tmp = out[t * 3 + 1]\n out[t * 3 + 1] = out[t * 3 + 2]\n out[t * 3 + 2] = tmp\n }\n }\n\n return { positions, indices: out }\n}\n\n// ── 步骤 4:2-manifold 断言 ──\n\n/**\n * Assert the mesh is 2-manifold: every undirected edge is shared by exactly\n * two triangles. A violation throws immediately (no silent handling, no\n * try-catch fallback).\n * @param positions - flat XYZ vertex buffer.\n * @param indices - triangle index buffer.\n */\nexport function assertManifold(positions: Float32Array, indices: Uint32Array): void {\n const triCount = indices.length / 3\n const edgeCount = new Map<number, Map<number, number>>()\n\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 bump(i0, i1)\n bump(i1, i2)\n bump(i2, i0)\n }\n\n function bump(a: number, b: number): void {\n const lo = a < b ? a : b\n const hi = a < b ? b : a\n let inner = edgeCount.get(lo)\n if (!inner) {\n inner = new Map()\n edgeCount.set(lo, inner)\n }\n inner.set(hi, (inner.get(hi) ?? 0) + 1)\n }\n\n for (const [lo, inner] of edgeCount) {\n for (const [hi, count] of inner) {\n if (count !== 2) {\n throw new Error(\n `[reconcile] not 2-manifold: edge (${lo},${hi}) shared by ${count} triangles (expected 2)`,\n )\n }\n }\n }\n}\n\n// ── 四步归约(默认入口) ──\n\n/**\n * Tuning knobs for the full reconciliation pass.\n */\nexport interface ReconcileOptions {\n /** Whether to run the 2-manifold assertion (default true). */\n assertManifold?: boolean\n}\n\n/**\n * Full reconciliation: weld → degenerate removal → orientation unification →\n * 2-manifold assertion. An empty mesh is returned untouched.\n * @param positions - flat XYZ vertex buffer.\n * @param indices - triangle index buffer.\n * @param opts - optional tuning knobs, e.g. to skip the manifold assertion.\n * @returns the reconciled mesh as a new ReconcileResult.\n */\nexport function reconcileMesh(\n positions: Float32Array,\n indices: Uint32Array,\n opts?: ReconcileOptions,\n): ReconcileResult {\n if (indices.length === 0 || indices.length % 3 !== 0) {\n if (indices.length === 0) return { positions, indices }\n throw new Error(`[reconcile] indices length must be a multiple of 3, got ${indices.length}`)\n }\n\n let result = weldVertices(positions, indices)\n result = removeDegenerate(result.positions, result.indices)\n result = unifyOrientation(result.positions, result.indices)\n\n if (opts?.assertManifold !== false) {\n assertManifold(result.positions, result.indices)\n }\n return result\n}\n"]}
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Rigid transform application (engine-side, P6).
|
|
3
3
|
*
|
|
4
4
|
* Applies a face_mate assembly transform to mesh vertices (bake).
|
|
5
|
-
* Math is identical to
|
|
5
|
+
* Math is identical to api/compound.applyTransform and brep/brep-ops
|
|
6
6
|
* applyTransformBrep (p' = R·(p − pivot) + pivot + translation).
|
|
7
7
|
*
|
|
8
8
|
* Ownership (engine-library-contract.md §10.1): constraint solving lives in the
|
|
9
9
|
* library (api/assembly); applying the solved transform to member geometry is
|
|
10
10
|
* done by the engine during replay (F2: libraries must not query/mutate the DAG).
|
|
11
11
|
* This module is the engine-side vertex transform — it must not depend on any
|
|
12
|
-
*
|
|
13
|
-
* Public API is unchanged:
|
|
12
|
+
* api module (E-b: engine must not import api/compound).
|
|
13
|
+
* Public API is unchanged: api/compound still re-exports applyTransform.
|
|
14
14
|
*/
|
|
15
15
|
import type { Shape } from './types.js';
|
|
16
16
|
/**
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Rigid transform application (engine-side, P6).
|
|
3
3
|
*
|
|
4
4
|
* Applies a face_mate assembly transform to mesh vertices (bake).
|
|
5
|
-
* Math is identical to
|
|
5
|
+
* Math is identical to api/compound.applyTransform and brep/brep-ops
|
|
6
6
|
* applyTransformBrep (p' = R·(p − pivot) + pivot + translation).
|
|
7
7
|
*
|
|
8
8
|
* Ownership (engine-library-contract.md §10.1): constraint solving lives in the
|
|
9
9
|
* library (api/assembly); applying the solved transform to member geometry is
|
|
10
10
|
* done by the engine during replay (F2: libraries must not query/mutate the DAG).
|
|
11
11
|
* This module is the engine-side vertex transform — it must not depend on any
|
|
12
|
-
*
|
|
13
|
-
* Public API is unchanged:
|
|
12
|
+
* api module (E-b: engine must not import api/compound).
|
|
13
|
+
* Public API is unchanged: api/compound still re-exports applyTransform.
|
|
14
14
|
*/
|
|
15
15
|
/** Matrix × vector (3x3 * 3). */
|
|
16
16
|
function mat3MulVec(m, v) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rigid-transform.js","sourceRoot":"","sources":["../../src/mesh/rigid-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,iCAAiC;AACjC,SAAS,UAAU,CAAC,CAAW,EAAE,CAA2B;IAC1D,OAAO;QACL,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KACxC,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAY,EACZ,UAA4C,EAC5C,KAA+B,EAC/B,WAAqC,EACrC,cAAwB;IAExB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;IACjC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IAEvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAClC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACtC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAEtC,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAExD,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QACxD,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC5D,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,OAAO;QACL,SAAS,EAAE,YAAY;QACvB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAA;AACH,CAAC","sourcesContent":["/**\n * Rigid transform application (engine-side, P6).\n *\n * Applies a face_mate assembly transform to mesh vertices (bake).\n * Math is identical to
|
|
1
|
+
{"version":3,"file":"rigid-transform.js","sourceRoot":"","sources":["../../src/mesh/rigid-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,iCAAiC;AACjC,SAAS,UAAU,CAAC,CAAW,EAAE,CAA2B;IAC1D,OAAO;QACL,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KACxC,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAY,EACZ,UAA4C,EAC5C,KAA+B,EAC/B,WAAqC,EACrC,cAAwB;IAExB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;IACjC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IAEvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAClC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACtC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAEtC,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAExD,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QACxD,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC5D,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,OAAO;QACL,SAAS,EAAE,YAAY;QACvB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAA;AACH,CAAC","sourcesContent":["/**\n * Rigid transform application (engine-side, P6).\n *\n * Applies a face_mate assembly transform to mesh vertices (bake).\n * Math is identical to api/compound.applyTransform and brep/brep-ops\n * applyTransformBrep (p' = R·(p − pivot) + pivot + translation).\n *\n * Ownership (engine-library-contract.md §10.1): constraint solving lives in the\n * library (api/assembly); applying the solved transform to member geometry is\n * done by the engine during replay (F2: libraries must not query/mutate the DAG).\n * This module is the engine-side vertex transform — it must not depend on any\n * api module (E-b: engine must not import api/compound).\n * Public API is unchanged: api/compound still re-exports applyTransform.\n */\n\nimport type { Shape } from './types'\n\n/** Matrix × vector (3x3 * 3). */\nfunction mat3MulVec(m: number[], v: [number, number, number]): [number, number, number] {\n return [\n m[0] * v[0] + m[1] * v[1] + m[2] * v[2],\n m[3] * v[0] + m[4] * v[1] + m[5] * v[2],\n m[6] * v[0] + m[7] * v[1] + m[8] * v[2],\n ]\n}\n\n/**\n * Apply an assembly transform to a mesh shape: rotate the vertices about the\n * pivot, then translate. The rotation is applied via the precomputed 3x3\n * rotation matrix; the quaternion is carried along for source fidelity.\n * @param shape - the mesh shape to transform.\n * @param quaternion - source rotation as an (x, y, z, w) quaternion (informational).\n * @param pivot - rotation pivot point in mm.\n * @param translation - translation applied after rotation, in mm.\n * @param rotationMatrix - 3x3 rotation matrix as 9 row-major entries.\n * @returns a new shape sharing the same indices with transformed positions.\n */\nexport function applyTransform(\n shape: Shape,\n quaternion: [number, number, number, number],\n pivot: [number, number, number],\n translation: [number, number, number],\n rotationMatrix: number[],\n): Shape {\n const positions = shape.positions\n const newPositions = new Float32Array(positions.length)\n\n for (let i = 0; i < positions.length; i += 3) {\n const px = positions[i] - pivot[0]\n const py = positions[i + 1] - pivot[1]\n const pz = positions[i + 2] - pivot[2]\n\n const rotated = mat3MulVec(rotationMatrix, [px, py, pz])\n\n newPositions[i] = rotated[0] + pivot[0] + translation[0]\n newPositions[i + 1] = rotated[1] + pivot[1] + translation[1]\n newPositions[i + 2] = rotated[2] + pivot[2] + translation[2]\n }\n\n return {\n positions: newPositions,\n indices: shape.indices,\n }\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stl-unit — STL unit guessing (moved up from 3d_editor per plan §8 decision 5).
|
|
3
|
+
*
|
|
4
|
+
* STL carries no unit metadata, so the host seeds `cad.load`'s `unit` from a
|
|
5
|
+
* bounding-box volume heuristic. The heuristic itself now lives here (single
|
|
6
|
+
* source of truth in faijs); the host keeps the "visible + correctable + locked
|
|
7
|
+
* by regression test" constraints, but does not re-implement the guess.
|
|
8
|
+
*
|
|
9
|
+
* The thresholds mirror the historical 3d_editor behaviour:
|
|
10
|
+
* volume < 0.008 m³ → 'm' (cube root ≈ 0.2 → likely meters)
|
|
11
|
+
* volume < 8.0 mm³ → 'inch' (cube root ≈ 2.0 → likely inches)
|
|
12
|
+
* otherwise → 'mm'
|
|
13
|
+
*
|
|
14
|
+
* Input is a world-space axis-aligned bounding box. Returns a faijs `UnitName`.
|
|
15
|
+
*/
|
|
16
|
+
import type { BoundingBox } from './types.js';
|
|
17
|
+
import type { UnitName } from '../units.js';
|
|
18
|
+
/** Guess the STL source unit from a bounding box volume.
|
|
19
|
+
*
|
|
20
|
+
* @param bbox - the world-space axis-aligned bounding box of the mesh.
|
|
21
|
+
* @returns the guessed faijs `UnitName` ('m' | 'inch' | 'mm').
|
|
22
|
+
*/
|
|
23
|
+
export declare function guessStlUnit(bbox: BoundingBox): UnitName;
|
|
24
|
+
//# sourceMappingURL=stl-unit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stl-unit.d.ts","sourceRoot":"","sources":["../../src/mesh/stl-unit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,QAAQ,CASxD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Guess the STL source unit from a bounding box volume.
|
|
2
|
+
*
|
|
3
|
+
* @param bbox - the world-space axis-aligned bounding box of the mesh.
|
|
4
|
+
* @returns the guessed faijs `UnitName` ('m' | 'inch' | 'mm').
|
|
5
|
+
*/
|
|
6
|
+
export function guessStlUnit(bbox) {
|
|
7
|
+
const w = bbox.max[0] - bbox.min[0];
|
|
8
|
+
const h = bbox.max[1] - bbox.min[1];
|
|
9
|
+
const d = bbox.max[2] - bbox.min[2];
|
|
10
|
+
const volume = w * h * d;
|
|
11
|
+
if (volume > 0 && volume < 0.008)
|
|
12
|
+
return 'm'; // cube root ≈ 0.2 → meters
|
|
13
|
+
if (volume > 0 && volume < 8.0)
|
|
14
|
+
return 'inch'; // cube root ≈ 2.0 → inches
|
|
15
|
+
return 'mm';
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=stl-unit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stl-unit.js","sourceRoot":"","sources":["../../src/mesh/stl-unit.ts"],"names":[],"mappings":"AAkBA;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAiB;IAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACnC,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAExB,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,KAAK;QAAE,OAAO,GAAG,CAAA,CAAG,2BAA2B;IAC1E,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG;QAAG,OAAO,MAAM,CAAA,CAAC,2BAA2B;IAC1E,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["/**\n * stl-unit — STL unit guessing (moved up from 3d_editor per plan §8 decision 5).\n *\n * STL carries no unit metadata, so the host seeds `cad.load`'s `unit` from a\n * bounding-box volume heuristic. The heuristic itself now lives here (single\n * source of truth in faijs); the host keeps the \"visible + correctable + locked\n * by regression test\" constraints, but does not re-implement the guess.\n *\n * The thresholds mirror the historical 3d_editor behaviour:\n * volume < 0.008 m³ → 'm' (cube root ≈ 0.2 → likely meters)\n * volume < 8.0 mm³ → 'inch' (cube root ≈ 2.0 → likely inches)\n * otherwise → 'mm'\n *\n * Input is a world-space axis-aligned bounding box. Returns a faijs `UnitName`.\n */\nimport type { BoundingBox } from './types'\nimport type { UnitName } from '../units'\n\n/** Guess the STL source unit from a bounding box volume.\n *\n * @param bbox - the world-space axis-aligned bounding box of the mesh.\n * @returns the guessed faijs `UnitName` ('m' | 'inch' | 'mm').\n */\nexport function guessStlUnit(bbox: BoundingBox): UnitName {\n const w = bbox.max[0] - bbox.min[0]\n const h = bbox.max[1] - bbox.min[1]\n const d = bbox.max[2] - bbox.min[2]\n const volume = w * h * d\n\n if (volume > 0 && volume < 0.008) return 'm' // cube root ≈ 0.2 → meters\n if (volume > 0 && volume < 8.0) return 'inch' // cube root ≈ 2.0 → inches\n return 'mm'\n}"]}
|