@faicad/faijs 0.22.2 → 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/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/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.js +2 -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 +1 -1
- package/dist/api/primitives.js +2 -2
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/profile.d.ts +39 -12
- package/dist/api/profile.d.ts.map +1 -1
- package/dist/api/profile.js +4 -4
- package/dist/api/profile.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 +7 -5
- package/dist/api/sketch-on-plane.d.ts.map +1 -1
- package/dist/api/sketch-on-plane.js +6 -7
- 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/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 +5 -1
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +62 -11
- 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/brep/brep-ops.d.ts +9 -7
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +23 -24
- 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 +6 -5
- 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.map +1 -1
- package/dist/brep/export/export-model.js +6 -5
- package/dist/brep/export/export-model.js.map +1 -1
- 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/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 +449 -123
- 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 +15 -3
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +33 -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 +42 -7
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +68 -5
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +15 -1
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +10 -1
- package/dist/define-op.js.map +1 -1
- package/dist/env-agnostic.d.ts +2 -2
- package/dist/env-agnostic.d.ts.map +1 -1
- package/dist/env-agnostic.js +1 -1
- 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 +65 -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/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 +1 -1
- package/dist/lang/code-to-args.js +1 -1
- package/dist/lang/code-to-args.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 +7 -0
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +14 -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 +42 -7
- package/dist/mesh/threemf-loader.d.ts.map +1 -1
- package/dist/mesh/threemf-loader.js +565 -100
- package/dist/mesh/threemf-loader.js.map +1 -1
- 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/node-host/cli.d.ts +44 -6
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +76 -26
- 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 +18 -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 +4 -5
- 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 +85 -9
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +72 -2
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +3 -3
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +5 -5
- 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/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/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 +18 -2
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh-solid-op — 网格 op 的「三明治」共享实现(方案 2026-10-01 §3.5)
|
|
3
|
+
*
|
|
4
|
+
* 每个网格 op 的实现体都是同一个形状,本模块只把这三步抽出来,让 op 侧只剩"调哪个
|
|
5
|
+
* 内核方法"这一件事:
|
|
6
|
+
*
|
|
7
|
+
* ```
|
|
8
|
+
* MeshData ──► meshSolid 句柄(从 Shape 槽取,**不重复导入**)
|
|
9
|
+
* │
|
|
10
|
+
* ├─ 内核调用(fillet / chamfer / fuse / cut / intersect / …)
|
|
11
|
+
* │
|
|
12
|
+
* └─ meshShape(新句柄) ──► MeshData(显示 mesh 与近似拓扑**同一份**)
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* 三条不可让步的口径:
|
|
16
|
+
*
|
|
17
|
+
* 1. **显示 mesh = 新实体的三角化**,不是输入的顶点数组。规则 1:拓扑 faceRuns
|
|
18
|
+
* 索引的三角形必须就是用户看到的三角形——照抄输入数组会让两者错位。
|
|
19
|
+
* 2. **新句柄必须写回**(Shape 槽 + 运行时注册表 + 近似拓扑)。不写回 = 下游 op
|
|
20
|
+
* 拿不到句柄、宿主选中不到面;不登记注册表 = 句柄无人释放。
|
|
21
|
+
* 3. **旧句柄不由本模块释放**。BREP 侧同构(`filletBrep` 也不释放输入句柄):
|
|
22
|
+
* 句柄生命周期归链(注册表 / releasePartCaches),op 只管"取一个、交一个"。
|
|
23
|
+
* 这里"顺手 release 输入"会打断 `b = fillet(a)` 之后仍然可用的 `a`。
|
|
24
|
+
*
|
|
25
|
+
* op 拿不到 `CadRuntime` 实例,故句柄与拓扑经 **pending 通道**登记
|
|
26
|
+
* (与 `load` 的 `setPendingMeshSolid` / `setPendingMeshTopology` 同模式),
|
|
27
|
+
* 由引擎在语句执行后收编——收编时会核对存活 ctx 变量仍携带**这个**句柄,防顶替。
|
|
28
|
+
*/
|
|
29
|
+
import { describeMeshSolid, } from '../../brep/mesh-solid.js';
|
|
30
|
+
import { fromMeshFace, fromMeshSolid, meshFaceOf, meshSolidOf } from '../../shape.js';
|
|
31
|
+
import { MeshUnsupportedError, getBackends, getCurrentStmt, setPendingMeshSolid, setPendingMeshTopology, } from '../../runtime-state.js';
|
|
32
|
+
import { TopoRefError, resolveTopoRef } from '../../topology/naming/index.js';
|
|
33
|
+
import { OpError } from './result-unwrap.js';
|
|
34
|
+
import { buildMeshEdgeResolutionContext, buildMeshFaceResolutionContext } from '../topo-resolve.js';
|
|
35
|
+
import { makePlane } from '../../geometry2d/bridge/plane.js';
|
|
36
|
+
/**
|
|
37
|
+
* 取当前装配的网格后端;未装配即抛(宿主装配事实,不是运行时降级点)。
|
|
38
|
+
*
|
|
39
|
+
* @param opLabel - the op name (error messages).
|
|
40
|
+
* @returns the assembled mesh backend.
|
|
41
|
+
* @throws {MeshUnsupportedError} when no mesh backend is assembled in this host.
|
|
42
|
+
*/
|
|
43
|
+
export function meshBackendOrThrow(opLabel) {
|
|
44
|
+
const backend = getBackends().kernel.meshSolid;
|
|
45
|
+
if (!backend) {
|
|
46
|
+
throw new MeshUnsupportedError(`E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs an assembled mesh backend — none is ` +
|
|
47
|
+
'available in this host', getCurrentStmt());
|
|
48
|
+
}
|
|
49
|
+
return backend;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 取网格实体的最小执行入口(只要内核 + 后端 + 句柄)。
|
|
53
|
+
*
|
|
54
|
+
* 两个失败面必须分开说,因为它们的原因完全不同:
|
|
55
|
+
* - 输入**不是**网格实体(裸网格 / BREP 实体)→ 该 op 的 mesh 路径只懂网格实体,
|
|
56
|
+
* 如实拒绝。裸网格意味着"加载它的时候没有装配网格内核",与"规范化失败"是两回事。
|
|
57
|
+
* - 输入是网格实体但**没有装配网格后端** → 装配事实(宿主没提供),不是运行时降级点。
|
|
58
|
+
*
|
|
59
|
+
* @param input - the op's geometry input.
|
|
60
|
+
* @param opLabel - the op name (error messages).
|
|
61
|
+
* @returns the minimal mesh-solid entry for this input.
|
|
62
|
+
* @throws {MeshUnsupportedError} when the input is not a mesh solid or no backend is assembled.
|
|
63
|
+
*/
|
|
64
|
+
export function meshSolidBasicEntry(input, opLabel) {
|
|
65
|
+
const backend = meshBackendOrThrow(opLabel);
|
|
66
|
+
const solid = meshSolidOf(input);
|
|
67
|
+
if (solid === undefined) {
|
|
68
|
+
throw new MeshUnsupportedError(`E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs a mesh solid input — ` +
|
|
69
|
+
'this input is a bare mesh (it was loaded without a mesh backend, so it has no approximate topology)', getCurrentStmt());
|
|
70
|
+
}
|
|
71
|
+
return { kernel: backend.kernel, backend, solid };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 取网格实体的执行入口(含边解析上下文)。
|
|
75
|
+
*
|
|
76
|
+
* 两个失败面必须分开说,因为它们的原因完全不同:
|
|
77
|
+
* - 输入**不是**网格实体(裸网格 / BREP 实体)→ 该 op 的 mesh 路径只懂网格实体,
|
|
78
|
+
* 如实拒绝。裸网格意味着"加载它的时候没有装配网格内核",与"规范化失败"是两回事。
|
|
79
|
+
* - 输入是网格实体但**没有装配网格后端** → 装配事实(宿主没提供),不是运行时降级点。
|
|
80
|
+
*
|
|
81
|
+
* @param input - the op's geometry input.
|
|
82
|
+
* @param opLabel - the op name (error messages).
|
|
83
|
+
* @returns the mesh-solid entry for this input (with the edge resolution context).
|
|
84
|
+
* @throws {MeshUnsupportedError} when the input is not a mesh solid or no backend is assembled.
|
|
85
|
+
*/
|
|
86
|
+
export function meshSolidEntry(input, opLabel) {
|
|
87
|
+
const basic = meshSolidBasicEntry(input, opLabel);
|
|
88
|
+
const edgeContext = buildMeshEdgeResolutionContext(basic.kernel, input);
|
|
89
|
+
if (!edgeContext) {
|
|
90
|
+
throw new MeshUnsupportedError(`E_MESH_SOLID_UNSUPPORTED: ${opLabel} could not build an edge resolution context for the mesh solid ` +
|
|
91
|
+
'(the input carries a mesh solid handle but no readable slot)', getCurrentStmt());
|
|
92
|
+
}
|
|
93
|
+
return { ...basic, edgeContext };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 把一组边**选择器**解析成当前网格实体的边句柄。
|
|
97
|
+
*
|
|
98
|
+
* 两种选择器,两条解析路:
|
|
99
|
+
* - **序号**(1 起,与 `sketchOnFace` 的 `face` 序号同口径):直接取自
|
|
100
|
+
* `getSubShapes(solid,'edge')` 的枚举序,即宿主在近似拓扑 `edges` 数组里看到的
|
|
101
|
+
* 那个下标 + 1。这是**首选**——近似拓扑没有 role 层,几何(长度 / 中点)在等长边
|
|
102
|
+
* 上无法区分,序号是唯一无歧义的指认方式。
|
|
103
|
+
* - **`EdgeTopoRef`**:纯几何匹配(length / midpoint)。解析不到或无法区分时如实
|
|
104
|
+
* 抛错,绝不静默退回"拿序号硬取"。
|
|
105
|
+
*
|
|
106
|
+
* @param entry - the mesh-solid entry (provides the live edge table).
|
|
107
|
+
* @param refs - edge selectors: 1-based ordinals or TopoRefs captured from the topology.
|
|
108
|
+
* @param opLabel - the op name (error messages).
|
|
109
|
+
* @returns the resolved edge handles, in the same order as `refs`.
|
|
110
|
+
* @throws {OpError} `E_TOPO_NOT_FOUND` when a selector cannot be resolved.
|
|
111
|
+
*/
|
|
112
|
+
export function resolveMeshEdges(entry, refs, opLabel) {
|
|
113
|
+
return refs.map((ref, i) => {
|
|
114
|
+
if (typeof ref === 'number')
|
|
115
|
+
return meshEdgeOrdinal(entry, ref, i, opLabel);
|
|
116
|
+
const where = `edge[${i}] of the mesh solid (length=${ref.hint.length ?? '<none>'}, ` +
|
|
117
|
+
`midpoint=${ref.hint.midpoint ? ref.hint.midpoint.join(',') : '<none>'})`;
|
|
118
|
+
let resolved;
|
|
119
|
+
try {
|
|
120
|
+
resolved = resolveTopoRef(ref, entry.edgeContext);
|
|
121
|
+
}
|
|
122
|
+
catch (cause) {
|
|
123
|
+
throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] ${where} could not be resolved — approximate topology has no role layer, ` +
|
|
124
|
+
`so an edge is identified by geometry alone: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
125
|
+
}
|
|
126
|
+
if (resolved.handle === undefined) {
|
|
127
|
+
throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] ${where} resolved without an edge handle`);
|
|
128
|
+
}
|
|
129
|
+
return resolved.handle;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 序号 → 边句柄(1 起,枚举序与近似拓扑 `edges` 数组同序)。
|
|
134
|
+
*
|
|
135
|
+
* 越界不裁剪、不取模、不"就近"——序号是调用方从拓扑读数里抄来的,抄错了就是错的,
|
|
136
|
+
* 静默换一条边会让用户拿到一个不是他要的圆角。
|
|
137
|
+
*
|
|
138
|
+
* @param entry - the mesh-solid entry (provides the live edge table).
|
|
139
|
+
* @param ordinal - the 1-based edge ordinal.
|
|
140
|
+
* @param index - the selector's position in the request (error messages).
|
|
141
|
+
* @param opLabel - the op name (error messages).
|
|
142
|
+
* @returns the live edge handle.
|
|
143
|
+
* @throws {OpError} `E_TOPO_NOT_FOUND` when the ordinal is out of range.
|
|
144
|
+
*/
|
|
145
|
+
function meshEdgeOrdinal(entry, ordinal, index, opLabel) {
|
|
146
|
+
const edges = entry.kernel.getSubShapes(entry.solid, 'edge');
|
|
147
|
+
if (!Number.isInteger(ordinal) || ordinal < 1 || ordinal > edges.length) {
|
|
148
|
+
throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] edge[${index}] ordinal ${ordinal} out of range [1, ${edges.length}] ` +
|
|
149
|
+
'on the mesh solid');
|
|
150
|
+
}
|
|
151
|
+
return edges[ordinal - 1];
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* 面选择器数组 → 面句柄数组(`shell` 的 `openFaces` 用;序号或 `FaceTopoRef` 都收)。
|
|
155
|
+
*
|
|
156
|
+
* @param kernel - the mesh backend's L1 kernel.
|
|
157
|
+
* @param on - the mesh-solid shape hosting the faces.
|
|
158
|
+
* @param selectors - 1-based face ordinals or FaceTopoRefs.
|
|
159
|
+
* @param opLabel - the op name (error messages).
|
|
160
|
+
* @returns the live face handles, in the same order as `selectors`.
|
|
161
|
+
* @throws {OpError} when a selector cannot be resolved.
|
|
162
|
+
*/
|
|
163
|
+
export function resolveMeshFaces(kernel, on, selectors, opLabel) {
|
|
164
|
+
return selectors.map((selector) => resolveMeshFaceHandle(kernel, on, selector, opLabel));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 把内核产出的**新网格实体句柄**封装成 op 产物。
|
|
168
|
+
*
|
|
169
|
+
* 一次三角化同时喂显示与拓扑(规则 1),并把句柄与近似拓扑登记到 pending 通道,
|
|
170
|
+
* 由引擎在语句执行后收编(同 `load`)。
|
|
171
|
+
*
|
|
172
|
+
* @param entry - the mesh-solid entry (backend for tessellation/topology/release).
|
|
173
|
+
* @param solid - the new mesh solid handle produced by the kernel call.
|
|
174
|
+
* @returns the product Shape carrying the new handle and its tessellation.
|
|
175
|
+
*/
|
|
176
|
+
export function meshSolidProduct(entry, solid) {
|
|
177
|
+
return meshSolidProductWithBackend(entry.backend, solid);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 同上,但直接收后端(产物输入不是网格实体时用——如 `extrude` 的输入是一张面)。
|
|
181
|
+
*
|
|
182
|
+
* @param backend - the mesh backend (tessellation / topology / release).
|
|
183
|
+
* @param solid - the new mesh solid handle produced by the kernel call.
|
|
184
|
+
* @returns the product Shape carrying the new handle and its tessellation.
|
|
185
|
+
*/
|
|
186
|
+
export function meshSolidProductWithBackend(backend, solid) {
|
|
187
|
+
const result = describeMeshSolid(backend, solid);
|
|
188
|
+
const part = getCurrentStmt()?.outputs[0];
|
|
189
|
+
if (part) {
|
|
190
|
+
setPendingMeshSolid(part, solid);
|
|
191
|
+
setPendingMeshTopology(part, backend.buildTopologyData(result));
|
|
192
|
+
}
|
|
193
|
+
return fromMeshSolid({ positions: result.mesh.positions, indices: result.mesh.indices }, { meshSolid: solid });
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 阵列 / 镜像族产物:把若干**自造副本**融成一个网格零件,并把副本句柄释放掉。
|
|
197
|
+
*
|
|
198
|
+
* 释放口径与 BREP 侧完全一致(`pattern.ts` 的 `finally { for (const c of raw) kernel.release(c) }`):
|
|
199
|
+
* - 释放的是**本次调用新建的副本**——它们是中间量,融合后无人再引用;
|
|
200
|
+
* - **不释放输入句柄**(`a` 在 `b = linearPattern(a)` 之后仍必须可用)。
|
|
201
|
+
*
|
|
202
|
+
* 副本之间通常是分离的(有间距的阵列),故 fuseAll 得到的是一体多壳的实体——与
|
|
203
|
+
* BREP 路径 fuseAll 分离副本的结局同形,不是"凑成一张皮"。
|
|
204
|
+
*
|
|
205
|
+
* 副本的**生成**也在 try 内:中途失败时已建出的副本同样会被释放(否则每个失败
|
|
206
|
+
* 调用都漏一批句柄)。
|
|
207
|
+
*
|
|
208
|
+
* @param entry - the mesh-solid entry (kernel + backend).
|
|
209
|
+
* @param opLabel - the op name (error messages).
|
|
210
|
+
* @param code - the op-level error code for kernel failures.
|
|
211
|
+
* @param makeCopies - creates the copies to fuse (called once, inside the guard).
|
|
212
|
+
* @returns the fused mesh solid as a new mesh part.
|
|
213
|
+
* @throws {OpError} with `code` when the kernel refuses a copy or the fusion.
|
|
214
|
+
*/
|
|
215
|
+
export function meshPatternProduct(entry, opLabel, code, makeCopies) {
|
|
216
|
+
let copies = [];
|
|
217
|
+
try {
|
|
218
|
+
copies = makeCopies();
|
|
219
|
+
if (copies.length === 0) {
|
|
220
|
+
throw new OpError(opLabel, code, `[api/${opLabel}] the kernel produced no copies`);
|
|
221
|
+
}
|
|
222
|
+
const result = entry.kernel.fuseAll(copies);
|
|
223
|
+
return meshSolidProductWithBackend(entry.backend, result);
|
|
224
|
+
}
|
|
225
|
+
catch (cause) {
|
|
226
|
+
if (cause instanceof OpError)
|
|
227
|
+
throw cause;
|
|
228
|
+
throw meshKernelFailure(opLabel, code, `${opLabel}: fusing ${copies.length} mesh copy(ies)`, cause);
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
for (const c of copies)
|
|
232
|
+
entry.backend.release(c);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* 取网格链面的执行入口(`sketchOnFace` 网格分支的输入门)。
|
|
237
|
+
*
|
|
238
|
+
* 与 `meshSolidEntry` 的两个失败面同构:输入没有网格链面身份 → 如实拒绝(它可能是
|
|
239
|
+
* 网格实体、BREP 面或裸网格,三种都不是这里要的东西);宿主没装配网格后端 → 装配事实。
|
|
240
|
+
*
|
|
241
|
+
* @param input - the op's geometry input (must be a mesh-chain face).
|
|
242
|
+
* @param opLabel - the op name (error messages).
|
|
243
|
+
* @returns the mesh-face entry for this input.
|
|
244
|
+
* @throws {MeshUnsupportedError} when the input is not a mesh-chain face or no backend is assembled.
|
|
245
|
+
*/
|
|
246
|
+
export function meshFaceEntry(input, opLabel) {
|
|
247
|
+
const backend = meshBackendOrThrow(opLabel);
|
|
248
|
+
const face = meshFaceOf(input);
|
|
249
|
+
if (face === undefined) {
|
|
250
|
+
throw new MeshUnsupportedError(`E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs a mesh-chain face input — ` +
|
|
251
|
+
'this input carries no mesh-chain face handle (build one with cad.sketchOnFace on a mesh solid)', getCurrentStmt());
|
|
252
|
+
}
|
|
253
|
+
return { kernel: backend.kernel, backend, face };
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* 把网格链面上的面选择器解析成活句柄(序号直接取;`FaceTopoRef` 走纯几何解析)。
|
|
257
|
+
*
|
|
258
|
+
* 网格零件没有 role 层,故与 `resolveMeshEdges` 同纪律:解析不到或无法区分时如实抛错,
|
|
259
|
+
* 绝不静默按序号硬取一张面。**同尺寸的平行面(立方体顶面/底面)在几何上不可区分**,
|
|
260
|
+
* 这种情形会以 `E_TOPO_AMBIGUOUS` 失败——调用方应改用序号。
|
|
261
|
+
*
|
|
262
|
+
* @param kernel - the mesh backend's L1 kernel.
|
|
263
|
+
* @param on - the mesh-solid shape hosting the face.
|
|
264
|
+
* @param selector - a 1-based face ordinal or a `FaceTopoRef`.
|
|
265
|
+
* @param opLabel - the op name (error messages).
|
|
266
|
+
* @returns the live face handle.
|
|
267
|
+
* @throws {OpError} `E_MESH_SOLID_UNSUPPORTED` / `E_TOPO_NOT_FOUND` / `E_TOPO_AMBIGUOUS`.
|
|
268
|
+
*/
|
|
269
|
+
export function resolveMeshFaceHandle(kernel, on, selector, opLabel) {
|
|
270
|
+
const solid = meshSolidOf(on);
|
|
271
|
+
if (solid === undefined) {
|
|
272
|
+
throw new MeshUnsupportedError(`E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs a mesh solid host — ` +
|
|
273
|
+
'this input is not a mesh solid', getCurrentStmt());
|
|
274
|
+
}
|
|
275
|
+
const faces = kernel.getSubShapes(solid, 'face');
|
|
276
|
+
if (typeof selector === 'number') {
|
|
277
|
+
if (!Number.isInteger(selector) || selector < 1 || selector > faces.length) {
|
|
278
|
+
throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] face ordinal ${selector} out of range [1, ${faces.length}] on the mesh solid`);
|
|
279
|
+
}
|
|
280
|
+
return faces[selector - 1];
|
|
281
|
+
}
|
|
282
|
+
const ctx = buildMeshFaceResolutionContext(kernel, on);
|
|
283
|
+
if (!ctx) {
|
|
284
|
+
throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] input has no mesh naming context`);
|
|
285
|
+
}
|
|
286
|
+
let resolved;
|
|
287
|
+
try {
|
|
288
|
+
resolved = resolveTopoRef(selector, ctx);
|
|
289
|
+
}
|
|
290
|
+
catch (cause) {
|
|
291
|
+
const code = cause instanceof TopoRefError && cause.code === 'E_TOPO_AMBIGUOUS' ? 'E_TOPO_AMBIGUOUS' : 'E_TOPO_NOT_FOUND';
|
|
292
|
+
throw new OpError(opLabel, code, `[api/${opLabel}] mesh face ref could not be resolved — approximate topology has no role layer, ` +
|
|
293
|
+
`so a face is identified by geometry alone (normal/center/area; use an ordinal when two faces are congruent): ` +
|
|
294
|
+
`${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
295
|
+
}
|
|
296
|
+
if (resolved.handle === undefined) {
|
|
297
|
+
throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] mesh face ref resolved to no live handle`);
|
|
298
|
+
}
|
|
299
|
+
return resolved.handle;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* 从一张网格链面取它的支撑平面(草图平面数据,方案 §4 Phase 3-1)。
|
|
303
|
+
*
|
|
304
|
+
* 两个数据源,各有各的理由:
|
|
305
|
+
* - **平面原点**取面的包围盒中心,不取 `surfaceCenterOfMass`:后者在 brepkit 上是
|
|
306
|
+
* "UV 域中点求值"的近似(内核没有 per-face 质心 API),对平面求的域中点是
|
|
307
|
+
* `getSurfaceDomain` 的中点;而平面域是 ±1e6 的**无限域**,其中点只是曲面参数原点,
|
|
308
|
+
* 可能位于面**之外**。包围盒中心是面自己的几何中心,草图从它铺出去必然落在面上。
|
|
309
|
+
* - **法向**取 UV 域中点的 `surfaceNormal`——L1 契约面上的中立方法(brepkit 侧映射
|
|
310
|
+
* `evaluateSurfaceNormal`),不直接调内核方言的 `getAnalyticSurfaceParams`。
|
|
311
|
+
*
|
|
312
|
+
* @param kernel - the mesh backend's L1 kernel.
|
|
313
|
+
* @param face - the live face handle.
|
|
314
|
+
* @returns the face's supporting plane frame (2D origin = the face's bbox centre).
|
|
315
|
+
*/
|
|
316
|
+
export function meshFacePlane(kernel, face) {
|
|
317
|
+
const uv = kernel.uvBounds(face);
|
|
318
|
+
const u = (uv.uMin + uv.uMax) / 2;
|
|
319
|
+
const v = (uv.vMin + uv.vMax) / 2;
|
|
320
|
+
const n = kernel.surfaceNormal(face, u, v);
|
|
321
|
+
const bb = kernel.getBoundingBox(face);
|
|
322
|
+
return makePlane({ x: (bb.xmin + bb.xmax) / 2, y: (bb.ymin + bb.ymax) / 2, z: (bb.zmin + bb.zmax) / 2 }, { x: n.x, y: n.y, z: n.z });
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* 把内核算出的网格链面句柄封装成 op 产物。
|
|
326
|
+
*
|
|
327
|
+
* 与 `meshSolidProductWithBackend` 的区别是**不登记** `MeshSolidRegistry` 与近似拓扑:
|
|
328
|
+
* 面不是零件,没有自己的注册表条目,下游也不需要"面的近似拓扑"(它自己就是拓扑的一部分)。
|
|
329
|
+
* 显示载荷取面自身的三角化(`meshShape` 按句柄类型分发到 face 分支)。
|
|
330
|
+
*
|
|
331
|
+
* @param backend - the mesh backend (tessellation).
|
|
332
|
+
* @param face - the new face handle produced by the kernel call.
|
|
333
|
+
* @returns the product Shape carrying the face handle and its tessellation.
|
|
334
|
+
*/
|
|
335
|
+
export function meshFaceProduct(backend, face) {
|
|
336
|
+
const mesh = backend.kernel.meshShape(face);
|
|
337
|
+
return fromMeshFace({ positions: new Float32Array(mesh.positions), indices: new Uint32Array(mesh.indices) }, { meshFace: face });
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* 内核原生错误 → 带 op 名与输入几何的 OpError(几何失败必须带上下文,不裸抛内核串)。
|
|
341
|
+
*
|
|
342
|
+
* @param opLabel - the op name.
|
|
343
|
+
* @param code - the op-level error code.
|
|
344
|
+
* @param context - a short human description of what was being attempted.
|
|
345
|
+
* @param cause - the kernel's own error.
|
|
346
|
+
* @returns the wrapped op error.
|
|
347
|
+
*/
|
|
348
|
+
export function meshKernelFailure(opLabel, code, context, cause) {
|
|
349
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
350
|
+
return new OpError(opLabel, code, `[api/${opLabel}] ${context} — the mesh kernel refused: ${msg}`, { cause });
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=mesh-solid-op.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesh-solid-op.js","sourceRoot":"","sources":["../../../src/api/internal/mesh-solid-op.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh-solid-op — 网格 op 的「三明治」共享实现(方案 2026-10-01 §3.5)\n *\n * 每个网格 op 的实现体都是同一个形状,本模块只把这三步抽出来,让 op 侧只剩\"调哪个\n * 内核方法\"这一件事:\n *\n * ```\n * MeshData ──► meshSolid 句柄(从 Shape 槽取,**不重复导入**)\n * │\n * ├─ 内核调用(fillet / chamfer / fuse / cut / intersect / …)\n * │\n * └─ meshShape(新句柄) ──► MeshData(显示 mesh 与近似拓扑**同一份**)\n * ```\n *\n * 三条不可让步的口径:\n *\n * 1. **显示 mesh = 新实体的三角化**,不是输入的顶点数组。规则 1:拓扑 faceRuns\n * 索引的三角形必须就是用户看到的三角形——照抄输入数组会让两者错位。\n * 2. **新句柄必须写回**(Shape 槽 + 运行时注册表 + 近似拓扑)。不写回 = 下游 op\n * 拿不到句柄、宿主选中不到面;不登记注册表 = 句柄无人释放。\n * 3. **旧句柄不由本模块释放**。BREP 侧同构(`filletBrep` 也不释放输入句柄):\n * 句柄生命周期归链(注册表 / releasePartCaches),op 只管\"取一个、交一个\"。\n * 这里\"顺手 release 输入\"会打断 `b = fillet(a)` 之后仍然可用的 `a`。\n *\n * op 拿不到 `CadRuntime` 实例,故句柄与拓扑经 **pending 通道**登记\n * (与 `load` 的 `setPendingMeshSolid` / `setPendingMeshTopology` 同模式),\n * 由引擎在语句执行后收编——收编时会核对存活 ctx 变量仍携带**这个**句柄,防顶替。\n */\n\nimport type { Shape } from '../../mesh/types'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport {\n describeMeshSolid,\n type MeshSolidBackend,\n type MeshSolidResult,\n} from '../../brep/mesh-solid'\nimport { fromMeshFace, fromMeshSolid, meshFaceOf, meshSolidOf } from '../../shape'\nimport {\n MeshUnsupportedError,\n getBackends,\n getCurrentStmt,\n setPendingMeshSolid,\n setPendingMeshTopology,\n} from '../../runtime-state'\nimport { TopoRefError, resolveTopoRef, type EdgeTopoRef, type FaceTopoRef, type ResolutionContext } from '../../topology/naming'\nimport { OpError } from './result-unwrap'\nimport { buildMeshEdgeResolutionContext, buildMeshFaceResolutionContext } from '../topo-resolve'\nimport { makePlane, type Plane } from '../../geometry2d/bridge/plane'\n\n/**\n * 网格 op 的最小执行入口:内核 + 后端 + 输入句柄(**不带**解析上下文)。\n *\n * 变换 / 抽壳 / 阵列这类\"整体作用于实体\"的 op 不需要解析上下文(它们按序号或\n * 几何选面/选边,且各自的选面逻辑自带上下文构建)——对它们建一遍全边表 + 逐边\n * 几何 hint,是纯粹的浪费(大网格上是 O(边数) 次内核调用)。\n */\nexport interface MeshSolidBasic {\n /** 网格后端的 L1 契约面(几何操作走它,op 不碰内核私有方言)。 */\n readonly kernel: BrepEngineApi\n /** 网格后端(三角化 / 近似拓扑 / 释放)。 */\n readonly backend: MeshSolidBackend\n /** 输入的网格实体句柄。 */\n readonly solid: BrepHandle\n}\n\n/** 网格 op 的执行入口:最小入口 + 边解析上下文。 */\nexport interface MeshSolidEntry extends MeshSolidBasic {\n /** 边解析上下文(无 role 层 → 纯几何匹配,见 `buildMeshEdgeResolutionContext`)。 */\n readonly edgeContext: ResolutionContext\n}\n\n/**\n * 取当前装配的网格后端;未装配即抛(宿主装配事实,不是运行时降级点)。\n *\n * @param opLabel - the op name (error messages).\n * @returns the assembled mesh backend.\n * @throws {MeshUnsupportedError} when no mesh backend is assembled in this host.\n */\nexport function meshBackendOrThrow(opLabel: string): MeshSolidBackend {\n const backend = getBackends().kernel.meshSolid as MeshSolidBackend | undefined\n if (!backend) {\n throw new MeshUnsupportedError(\n `E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs an assembled mesh backend — none is ` +\n 'available in this host',\n getCurrentStmt(),\n )\n }\n return backend\n}\n\n/**\n * 取网格实体的最小执行入口(只要内核 + 后端 + 句柄)。\n *\n * 两个失败面必须分开说,因为它们的原因完全不同:\n * - 输入**不是**网格实体(裸网格 / BREP 实体)→ 该 op 的 mesh 路径只懂网格实体,\n * 如实拒绝。裸网格意味着\"加载它的时候没有装配网格内核\",与\"规范化失败\"是两回事。\n * - 输入是网格实体但**没有装配网格后端** → 装配事实(宿主没提供),不是运行时降级点。\n *\n * @param input - the op's geometry input.\n * @param opLabel - the op name (error messages).\n * @returns the minimal mesh-solid entry for this input.\n * @throws {MeshUnsupportedError} when the input is not a mesh solid or no backend is assembled.\n */\nexport function meshSolidBasicEntry(input: Shape, opLabel: string): MeshSolidBasic {\n const backend = meshBackendOrThrow(opLabel)\n const solid = meshSolidOf(input) as BrepHandle | undefined\n if (solid === undefined) {\n throw new MeshUnsupportedError(\n `E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs a mesh solid input — ` +\n 'this input is a bare mesh (it was loaded without a mesh backend, so it has no approximate topology)',\n getCurrentStmt(),\n )\n }\n return { kernel: backend.kernel, backend, solid }\n}\n\n/**\n * 取网格实体的执行入口(含边解析上下文)。\n *\n * 两个失败面必须分开说,因为它们的原因完全不同:\n * - 输入**不是**网格实体(裸网格 / BREP 实体)→ 该 op 的 mesh 路径只懂网格实体,\n * 如实拒绝。裸网格意味着\"加载它的时候没有装配网格内核\",与\"规范化失败\"是两回事。\n * - 输入是网格实体但**没有装配网格后端** → 装配事实(宿主没提供),不是运行时降级点。\n *\n * @param input - the op's geometry input.\n * @param opLabel - the op name (error messages).\n * @returns the mesh-solid entry for this input (with the edge resolution context).\n * @throws {MeshUnsupportedError} when the input is not a mesh solid or no backend is assembled.\n */\nexport function meshSolidEntry(input: Shape, opLabel: string): MeshSolidEntry {\n const basic = meshSolidBasicEntry(input, opLabel)\n const edgeContext = buildMeshEdgeResolutionContext(basic.kernel, input)\n if (!edgeContext) {\n throw new MeshUnsupportedError(\n `E_MESH_SOLID_UNSUPPORTED: ${opLabel} could not build an edge resolution context for the mesh solid ` +\n '(the input carries a mesh solid handle but no readable slot)',\n getCurrentStmt(),\n )\n }\n return { ...basic, edgeContext }\n}\n\n/**\n * 把一组边**选择器**解析成当前网格实体的边句柄。\n *\n * 两种选择器,两条解析路:\n * - **序号**(1 起,与 `sketchOnFace` 的 `face` 序号同口径):直接取自\n * `getSubShapes(solid,'edge')` 的枚举序,即宿主在近似拓扑 `edges` 数组里看到的\n * 那个下标 + 1。这是**首选**——近似拓扑没有 role 层,几何(长度 / 中点)在等长边\n * 上无法区分,序号是唯一无歧义的指认方式。\n * - **`EdgeTopoRef`**:纯几何匹配(length / midpoint)。解析不到或无法区分时如实\n * 抛错,绝不静默退回\"拿序号硬取\"。\n *\n * @param entry - the mesh-solid entry (provides the live edge table).\n * @param refs - edge selectors: 1-based ordinals or TopoRefs captured from the topology.\n * @param opLabel - the op name (error messages).\n * @returns the resolved edge handles, in the same order as `refs`.\n * @throws {OpError} `E_TOPO_NOT_FOUND` when a selector cannot be resolved.\n */\nexport function resolveMeshEdges(\n entry: MeshSolidEntry,\n refs: readonly (number | EdgeTopoRef)[],\n opLabel: string,\n): BrepHandle[] {\n return refs.map((ref, i) => {\n if (typeof ref === 'number') return meshEdgeOrdinal(entry, ref, i, opLabel)\n const where =\n `edge[${i}] of the mesh solid (length=${ref.hint.length ?? '<none>'}, ` +\n `midpoint=${ref.hint.midpoint ? ref.hint.midpoint.join(',') : '<none>'})`\n let resolved: { handle?: unknown }\n try {\n resolved = resolveTopoRef(ref, entry.edgeContext)\n } catch (cause) {\n throw new OpError(\n opLabel,\n 'E_TOPO_NOT_FOUND',\n `[api/${opLabel}] ${where} could not be resolved — approximate topology has no role layer, ` +\n `so an edge is identified by geometry alone: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n )\n }\n if (resolved.handle === undefined) {\n throw new OpError(\n opLabel,\n 'E_TOPO_NOT_FOUND',\n `[api/${opLabel}] ${where} resolved without an edge handle`,\n )\n }\n return resolved.handle as BrepHandle\n })\n}\n\n/**\n * 序号 → 边句柄(1 起,枚举序与近似拓扑 `edges` 数组同序)。\n *\n * 越界不裁剪、不取模、不\"就近\"——序号是调用方从拓扑读数里抄来的,抄错了就是错的,\n * 静默换一条边会让用户拿到一个不是他要的圆角。\n *\n * @param entry - the mesh-solid entry (provides the live edge table).\n * @param ordinal - the 1-based edge ordinal.\n * @param index - the selector's position in the request (error messages).\n * @param opLabel - the op name (error messages).\n * @returns the live edge handle.\n * @throws {OpError} `E_TOPO_NOT_FOUND` when the ordinal is out of range.\n */\nfunction meshEdgeOrdinal(\n entry: MeshSolidEntry,\n ordinal: number,\n index: number,\n opLabel: string,\n): BrepHandle {\n const edges = entry.kernel.getSubShapes(entry.solid, 'edge')\n if (!Number.isInteger(ordinal) || ordinal < 1 || ordinal > edges.length) {\n throw new OpError(\n opLabel,\n 'E_TOPO_NOT_FOUND',\n `[api/${opLabel}] edge[${index}] ordinal ${ordinal} out of range [1, ${edges.length}] ` +\n 'on the mesh solid',\n )\n }\n return edges[ordinal - 1] as BrepHandle\n}\n\n/**\n * 面选择器数组 → 面句柄数组(`shell` 的 `openFaces` 用;序号或 `FaceTopoRef` 都收)。\n *\n * @param kernel - the mesh backend's L1 kernel.\n * @param on - the mesh-solid shape hosting the faces.\n * @param selectors - 1-based face ordinals or FaceTopoRefs.\n * @param opLabel - the op name (error messages).\n * @returns the live face handles, in the same order as `selectors`.\n * @throws {OpError} when a selector cannot be resolved.\n */\nexport function resolveMeshFaces(\n kernel: BrepEngineApi,\n on: Shape,\n selectors: readonly (number | FaceTopoRef)[],\n opLabel: string,\n): BrepHandle[] {\n return selectors.map((selector) => resolveMeshFaceHandle(kernel, on, selector, opLabel))\n}\n\n/**\n * 把内核产出的**新网格实体句柄**封装成 op 产物。\n *\n * 一次三角化同时喂显示与拓扑(规则 1),并把句柄与近似拓扑登记到 pending 通道,\n * 由引擎在语句执行后收编(同 `load`)。\n *\n * @param entry - the mesh-solid entry (backend for tessellation/topology/release).\n * @param solid - the new mesh solid handle produced by the kernel call.\n * @returns the product Shape carrying the new handle and its tessellation.\n */\nexport function meshSolidProduct(entry: { backend: MeshSolidBackend }, solid: BrepHandle): Shape {\n return meshSolidProductWithBackend(entry.backend, solid)\n}\n\n/**\n * 同上,但直接收后端(产物输入不是网格实体时用——如 `extrude` 的输入是一张面)。\n *\n * @param backend - the mesh backend (tessellation / topology / release).\n * @param solid - the new mesh solid handle produced by the kernel call.\n * @returns the product Shape carrying the new handle and its tessellation.\n */\nexport function meshSolidProductWithBackend(backend: MeshSolidBackend, solid: BrepHandle): Shape {\n const result: MeshSolidResult = describeMeshSolid(backend, solid)\n const part = getCurrentStmt()?.outputs[0]\n if (part) {\n setPendingMeshSolid(part, solid)\n setPendingMeshTopology(part, backend.buildTopologyData(result))\n }\n return fromMeshSolid(\n { positions: result.mesh.positions, indices: result.mesh.indices },\n { meshSolid: solid },\n )\n}\n\n/**\n * 阵列 / 镜像族产物:把若干**自造副本**融成一个网格零件,并把副本句柄释放掉。\n *\n * 释放口径与 BREP 侧完全一致(`pattern.ts` 的 `finally { for (const c of raw) kernel.release(c) }`):\n * - 释放的是**本次调用新建的副本**——它们是中间量,融合后无人再引用;\n * - **不释放输入句柄**(`a` 在 `b = linearPattern(a)` 之后仍必须可用)。\n *\n * 副本之间通常是分离的(有间距的阵列),故 fuseAll 得到的是一体多壳的实体——与\n * BREP 路径 fuseAll 分离副本的结局同形,不是\"凑成一张皮\"。\n *\n * 副本的**生成**也在 try 内:中途失败时已建出的副本同样会被释放(否则每个失败\n * 调用都漏一批句柄)。\n *\n * @param entry - the mesh-solid entry (kernel + backend).\n * @param opLabel - the op name (error messages).\n * @param code - the op-level error code for kernel failures.\n * @param makeCopies - creates the copies to fuse (called once, inside the guard).\n * @returns the fused mesh solid as a new mesh part.\n * @throws {OpError} with `code` when the kernel refuses a copy or the fusion.\n */\nexport function meshPatternProduct(\n entry: MeshSolidBasic,\n opLabel: string,\n code: string,\n makeCopies: () => BrepHandle[],\n): Shape {\n let copies: BrepHandle[] = []\n try {\n copies = makeCopies()\n if (copies.length === 0) {\n throw new OpError(opLabel, code, `[api/${opLabel}] the kernel produced no copies`)\n }\n const result: BrepHandle = entry.kernel.fuseAll(copies)\n return meshSolidProductWithBackend(entry.backend, result)\n } catch (cause) {\n if (cause instanceof OpError) throw cause\n throw meshKernelFailure(opLabel, code, `${opLabel}: fusing ${copies.length} mesh copy(ies)`, cause)\n } finally {\n for (const c of copies) entry.backend.release(c)\n }\n}\n\n/** 网格链**面**的执行入口:内核 + 后端 + 面句柄(`sketchOnFace` 的网格分支用)。 */export interface MeshFaceEntry {\n /** 网格后端的 L1 契约面。 */\n readonly kernel: BrepEngineApi\n /** 网格后端(三角化 / 释放)。 */\n readonly backend: MeshSolidBackend\n /** 网格链面句柄。 */\n readonly face: BrepHandle\n}\n\n/**\n * 取网格链面的执行入口(`sketchOnFace` 网格分支的输入门)。\n *\n * 与 `meshSolidEntry` 的两个失败面同构:输入没有网格链面身份 → 如实拒绝(它可能是\n * 网格实体、BREP 面或裸网格,三种都不是这里要的东西);宿主没装配网格后端 → 装配事实。\n *\n * @param input - the op's geometry input (must be a mesh-chain face).\n * @param opLabel - the op name (error messages).\n * @returns the mesh-face entry for this input.\n * @throws {MeshUnsupportedError} when the input is not a mesh-chain face or no backend is assembled.\n */\nexport function meshFaceEntry(input: Shape, opLabel: string): MeshFaceEntry {\n const backend = meshBackendOrThrow(opLabel)\n const face = meshFaceOf(input) as BrepHandle | undefined\n if (face === undefined) {\n throw new MeshUnsupportedError(\n `E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs a mesh-chain face input — ` +\n 'this input carries no mesh-chain face handle (build one with cad.sketchOnFace on a mesh solid)',\n getCurrentStmt(),\n )\n }\n return { kernel: backend.kernel, backend, face }\n}\n\n/**\n * 把网格链面上的面选择器解析成活句柄(序号直接取;`FaceTopoRef` 走纯几何解析)。\n *\n * 网格零件没有 role 层,故与 `resolveMeshEdges` 同纪律:解析不到或无法区分时如实抛错,\n * 绝不静默按序号硬取一张面。**同尺寸的平行面(立方体顶面/底面)在几何上不可区分**,\n * 这种情形会以 `E_TOPO_AMBIGUOUS` 失败——调用方应改用序号。\n *\n * @param kernel - the mesh backend's L1 kernel.\n * @param on - the mesh-solid shape hosting the face.\n * @param selector - a 1-based face ordinal or a `FaceTopoRef`.\n * @param opLabel - the op name (error messages).\n * @returns the live face handle.\n * @throws {OpError} `E_MESH_SOLID_UNSUPPORTED` / `E_TOPO_NOT_FOUND` / `E_TOPO_AMBIGUOUS`.\n */\nexport function resolveMeshFaceHandle(\n kernel: BrepEngineApi,\n on: Shape,\n selector: number | FaceTopoRef,\n opLabel: string,\n): BrepHandle {\n const solid = meshSolidOf(on) as BrepHandle | undefined\n if (solid === undefined) {\n throw new MeshUnsupportedError(\n `E_MESH_SOLID_UNSUPPORTED: ${opLabel}'s mesh path needs a mesh solid host — ` +\n 'this input is not a mesh solid',\n getCurrentStmt(),\n )\n }\n const faces = kernel.getSubShapes(solid, 'face')\n if (typeof selector === 'number') {\n if (!Number.isInteger(selector) || selector < 1 || selector > faces.length) {\n throw new OpError(\n opLabel,\n 'E_TOPO_NOT_FOUND',\n `[api/${opLabel}] face ordinal ${selector} out of range [1, ${faces.length}] on the mesh solid`,\n )\n }\n return faces[selector - 1] as BrepHandle\n }\n const ctx = buildMeshFaceResolutionContext(kernel, on as object)\n if (!ctx) {\n throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] input has no mesh naming context`)\n }\n let resolved: { handle?: unknown }\n try {\n resolved = resolveTopoRef(selector, ctx)\n } catch (cause) {\n const code = cause instanceof TopoRefError && cause.code === 'E_TOPO_AMBIGUOUS' ? 'E_TOPO_AMBIGUOUS' : 'E_TOPO_NOT_FOUND'\n throw new OpError(\n opLabel,\n code,\n `[api/${opLabel}] mesh face ref could not be resolved — approximate topology has no role layer, ` +\n `so a face is identified by geometry alone (normal/center/area; use an ordinal when two faces are congruent): ` +\n `${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n )\n }\n if (resolved.handle === undefined) {\n throw new OpError(opLabel, 'E_TOPO_NOT_FOUND', `[api/${opLabel}] mesh face ref resolved to no live handle`)\n }\n return resolved.handle as BrepHandle\n}\n\n/**\n * 从一张网格链面取它的支撑平面(草图平面数据,方案 §4 Phase 3-1)。\n *\n * 两个数据源,各有各的理由:\n * - **平面原点**取面的包围盒中心,不取 `surfaceCenterOfMass`:后者在 brepkit 上是\n * \"UV 域中点求值\"的近似(内核没有 per-face 质心 API),对平面求的域中点是\n * `getSurfaceDomain` 的中点;而平面域是 ±1e6 的**无限域**,其中点只是曲面参数原点,\n * 可能位于面**之外**。包围盒中心是面自己的几何中心,草图从它铺出去必然落在面上。\n * - **法向**取 UV 域中点的 `surfaceNormal`——L1 契约面上的中立方法(brepkit 侧映射\n * `evaluateSurfaceNormal`),不直接调内核方言的 `getAnalyticSurfaceParams`。\n *\n * @param kernel - the mesh backend's L1 kernel.\n * @param face - the live face handle.\n * @returns the face's supporting plane frame (2D origin = the face's bbox centre).\n */\nexport function meshFacePlane(kernel: BrepEngineApi, face: BrepHandle): Plane {\n const uv = kernel.uvBounds(face)\n const u = (uv.uMin + uv.uMax) / 2\n const v = (uv.vMin + uv.vMax) / 2\n const n = kernel.surfaceNormal(face, u, v)\n const bb = kernel.getBoundingBox(face)\n return makePlane(\n { x: (bb.xmin + bb.xmax) / 2, y: (bb.ymin + bb.ymax) / 2, z: (bb.zmin + bb.zmax) / 2 },\n { x: n.x, y: n.y, z: n.z },\n )\n}\n\n/**\n * 把内核算出的网格链面句柄封装成 op 产物。\n *\n * 与 `meshSolidProductWithBackend` 的区别是**不登记** `MeshSolidRegistry` 与近似拓扑:\n * 面不是零件,没有自己的注册表条目,下游也不需要\"面的近似拓扑\"(它自己就是拓扑的一部分)。\n * 显示载荷取面自身的三角化(`meshShape` 按句柄类型分发到 face 分支)。\n *\n * @param backend - the mesh backend (tessellation).\n * @param face - the new face handle produced by the kernel call.\n * @returns the product Shape carrying the face handle and its tessellation.\n */\nexport function meshFaceProduct(backend: MeshSolidBackend, face: BrepHandle): Shape {\n const mesh = backend.kernel.meshShape(face)\n return fromMeshFace(\n { positions: new Float32Array(mesh.positions), indices: new Uint32Array(mesh.indices) },\n { meshFace: face },\n )\n}\n\n/**\n * 内核原生错误 → 带 op 名与输入几何的 OpError(几何失败必须带上下文,不裸抛内核串)。\n *\n * @param opLabel - the op name.\n * @param code - the op-level error code.\n * @param context - a short human description of what was being attempted.\n * @param cause - the kernel's own error.\n * @returns the wrapped op error.\n */\nexport function meshKernelFailure(\n opLabel: string,\n code: string,\n context: string,\n cause: unknown,\n): OpError {\n const msg = cause instanceof Error ? cause.message : String(cause)\n return new OpError(\n opLabel,\n code,\n `[api/${opLabel}] ${context} — the mesh kernel refused: ${msg}`,\n { cause },\n )\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svg-asset-resolver.js","sourceRoot":"","sources":["../../../src/api/internal/svg-asset-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,kCAAkC;AAClC,SAAS,UAAU,CAAC,KAAkB;IACpC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;AAC/D,CAAC;AAED,yDAAyD;AACzD,SAAS,gBAAgB,CAAC,CAAU;IAClC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAA;AAClF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAY,EACZ,KAAiC;IAEjC,gCAAgC;IAChC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IAEvC,yBAAyB;IACzB,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAA;QAEtB,mCAAmC;QACnC,IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;YACnD,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACjC,CAAC;QAED,+CAA+C;QAC/C,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,kDAAkD,CAAC,CAAA;IACtG,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oDAAoD,OAAO,GAAG,EAAE,CAAC,CAAA;AACnF,CAAC","sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"file":"svg-asset-resolver.js","sourceRoot":"","sources":["../../../src/api/internal/svg-asset-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,kCAAkC;AAClC,SAAS,UAAU,CAAC,KAAkB;IACpC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;AAC/D,CAAC;AAED,yDAAyD;AACzD,SAAS,gBAAgB,CAAC,CAAU;IAClC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAA;AAClF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAY,EACZ,KAAiC;IAEjC,gCAAgC;IAChC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IAEvC,yBAAyB;IACzB,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAA;QAEtB,mCAAmC;QACnC,IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;YACnD,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACjC,CAAC;QAED,+CAA+C;QAC/C,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,kDAAkD,CAAC,CAAA;IACtG,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oDAAoD,OAAO,GAAG,EAAE,CAAC,CAAA;AACnF,CAAC","sourcesContent":["/**\n * api internal svg-asset-resolver — SVG 资产解析辅助函数\n *\n * 从 src/ops/svg-asset-resolver.ts 迁入(Phase 2.5 删除 src/ops/)。\n *\n * AssetRef 类型已退役(§4.2:`cad.asset(...)` 走 CallRefIR,运行时解析为字符串);\n * 此处保留对 `{$asset: key}` 结构(旧 IR / 宿主手写语句)的运行时兼容。\n */\n\nimport type { HostPorts } from '../../cad-runtime/ports'\n\n/** 将 ArrayBuffer 解码为 UTF-8 字符串 */\nfunction decodeUtf8(bytes: ArrayBuffer): string {\n return new TextDecoder('utf-8').decode(new Uint8Array(bytes))\n}\n\n/** 结构判断:旧 AssetRef 形态 `{$asset: key}`(运行时兼容,不依赖已退役类型) */\nfunction isLegacyAssetRef(v: unknown): v is { $asset: string } {\n return typeof v === 'object' && v !== null && !Array.isArray(v) && '$asset' in v\n}\n\n/**\n * 解析 args.svg 字段为 SVG 文本字符串。\n *\n * - 普通字符串:直接返回(兼容直接传入 SVG 文本)\n * - 旧 AssetRef 结构({ $asset: key }):按 key 解析(运行时兼容)\n *\n * @throws if the SVG key cannot be resolved.\n * @param svg - the svg argument: a plain SVG string or a legacy `{ $asset: key }` reference.\n * @param ports - the host asset ports used to resolve a legacy asset reference.\n * @returns the resolved SVG text string.\n */\nexport async function resolveSvgArg(\n svg: unknown,\n ports?: Pick<HostPorts, 'assets'>,\n): Promise<string> {\n // 普通字符串:直接返回(兼容旧格式或直接传入 SVG 文本)\n if (typeof svg === 'string') return svg\n\n // 旧 AssetRef 结构:按 key 解析\n if (isLegacyAssetRef(svg)) {\n const key = svg.$asset\n\n // 优先使用 ports.assets(headless 环境支持)\n if (ports?.assets) {\n const result = await ports.assets.resolveByKey(key)\n return decodeUtf8(result.bytes)\n }\n\n // ports.assets is required for headless engine\n throw new Error(`[resolveSvgArg] SVG asset \"${key}\" cannot be resolved: ports.assets not available`)\n }\n\n throw new Error(`[resolveSvgArg] expected string or AssetRef, got ${typeof svg}`)\n}\n"]}
|
package/dist/api/knurl.d.ts
CHANGED
package/dist/api/knurl.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* api knurl — 滚花库函数(mesh-only)
|
|
3
3
|
*
|
|
4
4
|
*
|
|
5
5
|
* knurl 无 BREP 实现(mesh-only)——dispatchPath 在 brep 模式下调用前抛错。
|
|
@@ -40,7 +40,7 @@ export function assertKnurlParams(params) {
|
|
|
40
40
|
export const knurl = defineOp({
|
|
41
41
|
mesh: async (input, params) => {
|
|
42
42
|
if (!input)
|
|
43
|
-
throw new Error('[
|
|
43
|
+
throw new Error('[api/knurl] no input geometry');
|
|
44
44
|
assertKnurlParams(params);
|
|
45
45
|
// 断链时刻(用户点名场景):BREP 建模的模型最后做滚花 → BREP 输入必须先归约为
|
|
46
46
|
// 合法 2-manifold 网格再进 mesh 路径(reconcileBrepInputs 对 mesh 侧输入原样透传)
|
package/dist/api/knurl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knurl.js","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE/C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,oBAAoB,CAAC,MAAM,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,EAAE,KAAY,EAAE,MAA+B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"knurl.js","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE/C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,oBAAoB,CAAC,MAAM,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,EAAE,KAAY,EAAE,MAA+B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;QAC5D,iBAAiB,CAAC,MAAM,CAAC,CAAA;QACzB,+CAA+C;QAC/C,iEAAiE;QACjE,MAAM,CAAC,SAAS,CAAC,GAAG,mBAAmB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAChD,OAAO,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE;YAC1B,IAAI,EAAE;gBACJ,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;gBAC5E,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aAC7D;YACD,kBAAkB,EAAG,MAAM,CAAC,kBAAyC,IAAI,GAAG;YAC5E,uBAAuB,EAAG,MAAM,CAAC,uBAA+C,IAAI,KAAK;YACzF,iBAAiB,EAAG,MAAM,CAAC,iBAAwC,IAAI,GAAG;YAC1E,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,gBAAgB,EAAG,MAAM,CAAC,gBAAuC,IAAI,CAAC;SACvE,CAAC,CAAA;IACJ,CAAC;IACD,SAAS,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE;IACxE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,2CAA2C,EAAgB;CACjG,CAAC,CAAA","sourcesContent":["/**\n * api knurl — 滚花库函数(mesh-only)\n *\n *\n * knurl 无 BREP 实现(mesh-only)——dispatchPath 在 brep 模式下调用前抛错。\n * part-brep-lost 事件由引擎统一发(P4,库不再 emit)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { reconcileBrepInputs } from './reconcile'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { assertPositiveNumber } from './assert'\n\n/**\n * Validate knurl parameters: `knurlTextureHeight` must be a positive number.\n * @param params - the raw knurl operation parameters.\n */\nexport function assertKnurlParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.knurlTextureHeight, 'knurl.knurlTextureHeight')\n}\n\n/**\n * 施加滚花(顶点位移,非布尔)。mesh-only。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual warn\n * @name knurl\n * @note knurl 无 BREP 实现(mesh-only),本质是顶点位移(网格操作),网格参数可接受;brep 模式下调用前抛 BrepUnsupportedError。面锚定建议用几何引用。\n * @returns Shape 滚花后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.knurlTextureHeight - 纹路高度(mm)。type:number 默认 0.5\n * @param params.knurlScaleU - 纹路 U 向频率。type:number 默认 0.15\n * @param params.knurlScaleV - 纹路 V 向频率。type:number 默认 0.15\n * @param params.knurlInvertDisplacement - 反向位移。type:boolean 默认 false\n * @param params.knurlRefineLength - 细分长度(mm)。type:number 默认 1.0\n * @param params.knurlMappingMode - UV 映射模式。type:number 默认 5\n * @param params.faceCenter - 面锚点中心。type:[x,y,z] 默认 bboxCenter\n * @param params.faceNormal - 面法向。type:[x,y,z] 默认 [0,0,1]\n * @example\n * const p = await cad.knurl(part0, { knurlTextureHeight: 0.5, knurlScaleU: 0.15, knurlScaleV: 0.15, knurlInvertDisplacement: false, knurlRefineLength: 1.0, knurlMappingMode: 5 })\n */\nexport const knurl = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[api/knurl] no input geometry')\n assertKnurlParams(params)\n // 断链时刻(用户点名场景):BREP 建模的模型最后做滚花 → BREP 输入必须先归约为\n // 合法 2-manifold 网格再进 mesh 路径(reconcileBrepInputs 对 mesh 侧输入原样透传)\n const [meshInput] = reconcileBrepInputs([input])\n return cad.knurl(meshInput, {\n face: {\n center: (params.faceCenter as Vec3 | undefined) ?? cad.bboxCenter(meshInput),\n normal: (params.faceNormal as Vec3 | undefined) ?? [0, 0, 1],\n },\n knurlTextureHeight: (params.knurlTextureHeight as number | undefined) ?? 0.5,\n knurlInvertDisplacement: (params.knurlInvertDisplacement as boolean | undefined) ?? false,\n knurlRefineLength: (params.knurlRefineLength as number | undefined) ?? 1.0,\n knurlScaleU: (params.knurlScaleU as number | undefined) ?? 0.15,\n knurlScaleV: (params.knurlScaleV as number | undefined) ?? 0.15,\n knurlMappingMode: (params.knurlMappingMode as number | undefined) ?? 5,\n })\n },\n paramDims: { knurlTextureHeight: 'length', knurlRefineLength: 'length' },\n naming: { kind: 'unmodeled', reason: 'knurl is mesh-only, no BREP face identity' } as Provenance,\n})\n"]}
|
package/dist/api/loft.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* api loft — 放样:多个截面之间蒙皮生成体(手写平台 op,Phase 4 → G5 core 直连)
|
|
3
3
|
*
|
|
4
4
|
* @platform occt — 实现走 core 直连 `occt-wasm loft` / `loftWithVertices`
|
|
5
5
|
* (BRepOffsetAPI_ThruSections;engine-method-map 里 `loft` 为 occt-only)⇒ 平台 op:
|
package/dist/api/loft.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* api loft — 放样:多个截面之间蒙皮生成体(手写平台 op,Phase 4 → G5 core 直连)
|
|
3
3
|
*
|
|
4
4
|
* @platform occt — 实现走 core 直连 `occt-wasm loft` / `loftWithVertices`
|
|
5
5
|
* (BRepOffsetAPI_ThruSections;engine-method-map 里 `loft` 为 occt-only)⇒ 平台 op:
|
package/dist/api/loft.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loft.js","sourceRoot":"","sources":["../../src/api/loft.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"file":"loft.js","sourceRoot":"","sources":["../../src/api/loft.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api loft — 放样:多个截面之间蒙皮生成体(手写平台 op,Phase 4 → G5 core 直连)\n *\n * @platform occt — 实现走 core 直连 `occt-wasm loft` / `loftWithVertices`\n * (BRepOffsetAPI_ThruSections;engine-method-map 里 `loft` 为 occt-only)⇒ 平台 op:\n * defineOp 声明 `engines: ['occt']`(D11)。\n *\n * 为什么手写而不走生成投影:与 `api/sweep.ts` 同因——截面最常见来源是\n * `cad.profile(...)`(产出 **face**),内核 `loft(wires, …)` 只吃 wire ⇒\n * 需要「面 → 外环」输入适配(`internal/profile-wire.ts` 的唯一步径)。\n *\n * core-decouple G5:vendored `loft`(brepjs)替换为 occt-wasm 原生直连,\n * 产物经 `fromBrep` 收养(替代 l3-bridge adoptEntity)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep } from '../shape'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getOcctKernel } from '../occt-kernel/occtKernel'\nimport { toProfileWireView } from './internal/profile-wire'\nimport type { BrepHandle } from '../brep/engine/types'\n\n/** 放样配置(与 vendored LoftOptions 同形;本文件自持,去 brepjs 依赖)。 */\nexport interface LoftOptions {\n /** 直线插值(ruled)。默认 true。 */\n ruled?: boolean\n /** 起点(退化到点的蒙皮)。 */\n startPoint?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** 终点(退化到点的蒙皮)。 */\n endPoint?: readonly [number, number, number] | { x: number; y: number; z: number }\n /** ThruSections 缝合公差。默认 1e-6。 */\n tolerance?: number\n}\n\n/** PointInput → [x,y,z](vendored toVec3 同口径)。 */\nfunction toVec3(p: LoftOptions['startPoint']): [number, number, number] {\n if (Array.isArray(p) && p.length >= 3) return [p[0]!, p[1]!, p[2]!]\n const o = p as { x: number; y: number; z: number }\n return [o.x, o.y, o.z]\n}\n\n/** BREP 路径:按序蒙皮各截面(wire 视图 → occt-wasm 直连 → fromBrep 收养)。 */\nfunction loftBrep(sections: Shape[], opts?: LoftOptions): Shape {\n if (!Array.isArray(sections) || sections.length === 0) {\n throw new Error('E_LOFT_NO_SECTIONS: loft requires a non-empty array of section shapes')\n }\n // 每截面:wire 直用;面取外环(孔环不参与放样)。\n const wireViews = sections.map((s) => toProfileWireView(s))\n const { ruled = true, startPoint, endPoint } = opts ?? {}\n const kernel = getBrepApi()\n const k = getOcctKernel()\n const wireHandles = wireViews.map((w) => w.wrapped as never)\n\n try {\n let h: unknown\n if (startPoint !== undefined || endPoint !== undefined) {\n const startVertex = startPoint !== undefined ? k.makeVertex(...toVec3(startPoint)) : undefined\n const endVertex = endPoint !== undefined ? k.makeVertex(...toVec3(endPoint)) : undefined\n try {\n h = k.loftWithVertices(wireHandles, true, ruled, startVertex as never, endVertex as never)\n } finally {\n if (startVertex !== undefined) k.release(startVertex)\n if (endVertex !== undefined) k.release(endVertex)\n }\n } else {\n h = k.loft(wireHandles, true, ruled)\n }\n return fromBrep(solidToShape(kernel, h as BrepHandle), { solid: h as BrepHandle })\n } catch (e) {\n const raw = e instanceof Error ? e.message : String(e)\n throw new Error(`E_LOFT_FAILED: loft failed: ${raw}`, { cause: e })\n } finally {\n // 面→外环产出的 wire 是 arena 新句柄(曲线借用不 release)\n for (const w of wireViews) {\n if (!w.borrowed) {\n try { kernel.release(w.wrapped) } catch { /* 已释放 */ }\n }\n }\n }\n}\n\n/**\n * 放样:按给定顺序在截面之间蒙皮生成体。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name loft\n * @note 平台 op:仅 occt 引擎(BRepOffsetAPI_ThruSections)。截面可为 wire 或面\n * (面取其外环),至少 2 个;`startPoint` / `endPoint` 可做退化到点的蒙皮。\n * 非 occt 引擎执行前报错;brep_mock 不拦截。不做 `loftAll`(数组产物)。\n * @returns Shape 放样体。\n * @param sections - 有序截面集合(wire 或面;面取其外环)。type:Shape[] required:true\n * @param opts - 放样配置(ruled / startPoint / endPoint / tolerance)。type:LoftOptions required:false\n * @example\n * const bottom = cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -5, y1: -5, x2: 5, y2: -5 },\n * { kind: 'line', x1: 5, y1: -5, x2: 5, y2: 5 },\n * { kind: 'line', x1: 5, y1: 5, x2: -5, y2: 5 },\n * { kind: 'line', x1: -5, y1: 5, x2: -5, y2: -5 },\n * ] }] })\n * const top = cad.translate(cad.profile({ contours: [{ segments: [\n * { kind: 'line', x1: -3, y1: -3, x2: 3, y2: -3 },\n * { kind: 'line', x1: 3, y1: -3, x2: 3, y2: 3 },\n * { kind: 'line', x1: 3, y1: 3, x2: -3, y2: 3 },\n * { kind: 'line', x1: -3, y1: 3, x2: -3, y2: -3 },\n * ] }] }), [0, 0, 20])\n * const body = await cad.loft([bottom, top])\n */\nexport const loft = defineOp({\n name: 'loft',\n brep(sections: Shape[], opts?: LoftOptions) {\n return loftBrep(sections, opts)\n },\n engines: ['occt'],\n naming: { kind: 'unmodeled', reason: 'lofted-body face vocabulary not defined' } as Provenance,\n})\n"]}
|
|
@@ -23,14 +23,18 @@ import type { BrepVec3 } from '../../brep/engine/types.js';
|
|
|
23
23
|
/**
|
|
24
24
|
* 测量形状的表面积(L1 getSurfaceArea,两引擎同口径)。
|
|
25
25
|
*
|
|
26
|
-
* @param shape - 被测量的形状(Face / Shape3D / compound
|
|
27
|
-
* @returns 表面积(mm
|
|
26
|
+
* @param shape - 被测量的形状(Face / Shape3D / compound / 网格零件)。
|
|
27
|
+
* @returns 表面积(mm²;网格零件按面片几何计)。
|
|
28
28
|
*/
|
|
29
29
|
export declare function area(shape: Shape): Promise<number>;
|
|
30
30
|
/**
|
|
31
31
|
* 测量形状的边长/线长(L1 getLength,两引擎同口径)。
|
|
32
32
|
*
|
|
33
|
-
*
|
|
33
|
+
* 口径 = **shape 中所有唯一 edge 的弧长之和**:edge 取自身弧长,wire 取其边之和,
|
|
34
|
+
* face 取边界边之和,solid 取全部边之和,compound 取各子实体之和。两个 BREP 引擎
|
|
35
|
+
* 在此口径下逐位一致(2026-10-02 归一化,见 occt / brepkit 适配器的 getLength)。
|
|
36
|
+
*
|
|
37
|
+
* @param shape - 被测量的形状(edge / wire / face / solid / compound)。
|
|
34
38
|
* @returns 长度(mm)。
|
|
35
39
|
*/
|
|
36
40
|
export declare function length(shape: Shape): Promise<number>;
|
|
@@ -38,13 +42,13 @@ export declare function length(shape: Shape): Promise<number>;
|
|
|
38
42
|
* 测量形状的体素体积(L1 getVolume,两引擎同口径)。
|
|
39
43
|
*
|
|
40
44
|
* @param shape - 被测量的形状(solid / compound;对 wire / face 内核按自身口径计,可能返回 0)。
|
|
41
|
-
* @returns 体积(mm
|
|
45
|
+
* @returns 体积(mm³;网格零件按面片几何计)。
|
|
42
46
|
*/
|
|
43
47
|
export declare function volume(shape: Shape): Promise<number>;
|
|
44
48
|
/**
|
|
45
49
|
* 测量形状的质心(L1 getCenterOfMass,两引擎同口径)。
|
|
46
50
|
*
|
|
47
|
-
* @param shape - 被测量的形状(solid / compound / face
|
|
51
|
+
* @param shape - 被测量的形状(solid / compound / face / 网格零件)。
|
|
48
52
|
* @returns 质心坐标(mm,BREP 中立形态 {x,y,z})。
|
|
49
53
|
*/
|
|
50
54
|
export declare function centerOfMass(shape: Shape): Promise<BrepVec3>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/measurement/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/measurement/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAc,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AA+CnE;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxD;AAED;;;;;;;;;GASG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAG1D;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAG1D;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAGlE"}
|