@faicad/faijs 0.33.2 → 0.35.8
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/dist/api/api-namespace.d.ts +14 -14
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +40 -14
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/appearance.d.ts +47 -6
- package/dist/api/appearance.d.ts.map +1 -1
- package/dist/api/appearance.js.map +1 -1
- package/dist/api/assembly/entities.js +14 -4
- package/dist/api/assembly/entities.js.map +1 -1
- package/dist/api/assembly/solve-tree.d.ts +1 -0
- package/dist/api/assembly/solve-tree.d.ts.map +1 -1
- package/dist/api/assembly/solve-tree.js +42 -17
- package/dist/api/assembly/solve-tree.js.map +1 -1
- package/dist/api/assembly/solve.d.ts +1 -0
- package/dist/api/assembly/solve.d.ts.map +1 -1
- package/dist/api/assembly/solve.js.map +1 -1
- package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
- package/dist/api/assembly/solvers/global-solver.js +130 -23
- package/dist/api/assembly/solvers/global-solver.js.map +1 -1
- package/dist/api/assembly/solvers/pose-from-delta.d.ts +9 -0
- package/dist/api/assembly/solvers/pose-from-delta.d.ts.map +1 -1
- package/dist/api/assembly/solvers/pose-from-delta.js +23 -0
- package/dist/api/assembly/solvers/pose-from-delta.js.map +1 -1
- package/dist/api/assembly/solvers/types.d.ts +20 -2
- package/dist/api/assembly/solvers/types.d.ts.map +1 -1
- package/dist/api/assembly/solvers/types.js.map +1 -1
- package/dist/api/chamfer.d.ts +7 -4
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +57 -13
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/draft.d.ts +7 -4
- package/dist/api/draft.d.ts.map +1 -1
- package/dist/api/draft.js +11 -6
- package/dist/api/draft.js.map +1 -1
- package/dist/api/edge-ref.d.ts +4 -4
- package/dist/api/edge-ref.js +4 -4
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/extrude.d.ts +10 -6
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +54 -26
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts +4 -4
- package/dist/api/face-ref.js +4 -4
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/feature-repair.d.ts +6 -3
- package/dist/api/feature-repair.d.ts.map +1 -1
- package/dist/api/feature-repair.js +12 -7
- package/dist/api/feature-repair.js.map +1 -1
- package/dist/api/fillet-variable.d.ts +6 -2
- package/dist/api/fillet-variable.d.ts.map +1 -1
- package/dist/api/fillet-variable.js +24 -6
- package/dist/api/fillet-variable.js.map +1 -1
- package/dist/api/fillet.d.ts +7 -4
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +92 -12
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/generated/script-face-manifest.js +1 -1
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/generated/topology.js +1 -1
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/helix.d.ts +13 -13
- package/dist/api/helix.d.ts.map +1 -1
- package/dist/api/helix.js +19 -24
- package/dist/api/helix.js.map +1 -1
- package/dist/api/import-brep.d.ts +10 -18
- package/dist/api/import-brep.d.ts.map +1 -1
- package/dist/api/import-brep.js +17 -25
- package/dist/api/import-brep.js.map +1 -1
- package/dist/api/import-step.d.ts +10 -15
- package/dist/api/import-step.d.ts.map +1 -1
- package/dist/api/import-step.js +24 -29
- package/dist/api/import-step.js.map +1 -1
- package/dist/api/index.js +2 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/export-members.js.map +1 -1
- package/dist/api/loft-advanced.d.ts +4 -0
- package/dist/api/loft-advanced.d.ts.map +1 -1
- package/dist/api/loft-advanced.js +4 -0
- package/dist/api/loft-advanced.js.map +1 -1
- package/dist/api/loft.d.ts +5 -3
- package/dist/api/loft.d.ts.map +1 -1
- package/dist/api/loft.js +5 -3
- package/dist/api/loft.js.map +1 -1
- package/dist/api/meta.d.ts +42 -6
- package/dist/api/meta.d.ts.map +1 -1
- package/dist/api/meta.js.map +1 -1
- package/dist/api/primitives.d.ts +3 -2
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +3 -2
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/punch-hole.d.ts +5 -2
- package/dist/api/punch-hole.d.ts.map +1 -1
- package/dist/api/punch-hole.js +4 -1
- package/dist/api/punch-hole.js.map +1 -1
- package/dist/api/replicate.d.ts +4 -5
- package/dist/api/replicate.d.ts.map +1 -1
- package/dist/api/replicate.js +4 -5
- package/dist/api/replicate.js.map +1 -1
- package/dist/api/selectors-to-refs.d.ts +83 -0
- package/dist/api/selectors-to-refs.d.ts.map +1 -0
- package/dist/api/selectors-to-refs.js +211 -0
- package/dist/api/selectors-to-refs.js.map +1 -0
- package/dist/api/shell.d.ts +17 -8
- package/dist/api/shell.d.ts.map +1 -1
- package/dist/api/shell.js +45 -15
- package/dist/api/shell.js.map +1 -1
- package/dist/api/sketch-on-face.d.ts +12 -6
- package/dist/api/sketch-on-face.d.ts.map +1 -1
- package/dist/api/sketch-on-face.js +31 -4
- package/dist/api/sketch-on-face.js.map +1 -1
- package/dist/api/sketch-on-plane.d.ts +3 -0
- package/dist/api/sketch-on-plane.d.ts.map +1 -1
- package/dist/api/sketch-on-plane.js +3 -0
- package/dist/api/sketch-on-plane.js.map +1 -1
- package/dist/api/sketch-on-surface.d.ts +4 -1
- package/dist/api/sketch-on-surface.d.ts.map +1 -1
- package/dist/api/sketch-on-surface.js +4 -1
- package/dist/api/sketch-on-surface.js.map +1 -1
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +5 -6
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/topo-resolve.d.ts.map +1 -1
- package/dist/api/topo-resolve.js +24 -5
- package/dist/api/topo-resolve.js.map +1 -1
- package/dist/api/view/view-projection.d.ts.map +1 -1
- package/dist/api/view/view-projection.js +9 -2
- package/dist/api/view/view-projection.js.map +1 -1
- package/dist/brep/brep-chain.js +2 -2
- package/dist/brep/brep-chain.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +1 -1
- package/dist/brep/brep-ops.js +1 -1
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +45 -0
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +87 -3
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js +1 -1
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/registry.d.ts +33 -7
- package/dist/brep/engine/registry.d.ts.map +1 -1
- package/dist/brep/engine/registry.js +47 -16
- package/dist/brep/engine/registry.js.map +1 -1
- package/dist/brep/handle-bridge.d.ts +14 -15
- package/dist/brep/handle-bridge.d.ts.map +1 -1
- package/dist/brep/handle-bridge.js +35 -15
- package/dist/brep/handle-bridge.js.map +1 -1
- package/dist/brep/primitives-brep.js +2 -2
- package/dist/brep/primitives-brep.js.map +1 -1
- package/dist/brep/text/text-to-solid.d.ts +40 -3
- package/dist/brep/text/text-to-solid.d.ts.map +1 -1
- package/dist/brep/text/text-to-solid.js +104 -24
- package/dist/brep/text/text-to-solid.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +2 -2
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +328 -38
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/brepkit-kernel/brepkitWasm.d.ts +3 -1
- package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitWasm.js +13 -9
- package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
- package/dist/brepkit-kernel/multi-version-test.d.ts +2 -2
- package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
- package/dist/brepkit-kernel/multi-version-test.js +6 -6
- package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
- package/dist/browser.d.ts +2 -3
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -2
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +9 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +11 -1
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.d.ts +16 -11
- package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js +16 -8
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts +62 -5
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +617 -42
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/interp/closure.d.ts +3 -2
- package/dist/cad-runtime/interp/closure.d.ts.map +1 -1
- package/dist/cad-runtime/interp/closure.js.map +1 -1
- package/dist/cad-runtime/interp/env.d.ts +9 -6
- package/dist/cad-runtime/interp/env.d.ts.map +1 -1
- package/dist/cad-runtime/interp/env.js +4 -2
- package/dist/cad-runtime/interp/env.js.map +1 -1
- package/dist/cad-runtime/lib-decl.d.ts +121 -0
- package/dist/cad-runtime/lib-decl.d.ts.map +1 -0
- package/dist/cad-runtime/lib-decl.js +100 -0
- package/dist/cad-runtime/lib-decl.js.map +1 -0
- package/dist/cad-runtime/ports.d.ts +12 -0
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +59 -5
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +252 -20
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/extra/browser.d.ts +9 -0
- package/dist/extra/browser.d.ts.map +1 -0
- package/dist/extra/browser.js +9 -0
- package/dist/extra/browser.js.map +1 -0
- package/dist/extra/editor-ops.d.ts +22 -0
- package/dist/extra/editor-ops.d.ts.map +1 -0
- package/dist/extra/editor-ops.js +21 -0
- package/dist/extra/editor-ops.js.map +1 -0
- package/dist/extra/extras/svg-extrude.d.ts +45 -0
- package/dist/extra/extras/svg-extrude.d.ts.map +1 -0
- package/dist/extra/extras/svg-extrude.js +110 -0
- package/dist/extra/extras/svg-extrude.js.map +1 -0
- package/dist/extra/extras/text-cjk.d.ts +36 -0
- package/dist/extra/extras/text-cjk.d.ts.map +1 -0
- package/dist/extra/extras/text-cjk.js +86 -0
- package/dist/extra/extras/text-cjk.js.map +1 -0
- package/dist/extra/extras/text-geometry.d.ts +69 -0
- package/dist/extra/extras/text-geometry.d.ts.map +1 -0
- package/dist/extra/extras/text-geometry.js +188 -0
- package/dist/extra/extras/text-geometry.js.map +1 -0
- package/dist/extra/index.d.ts +40 -0
- package/dist/extra/index.d.ts.map +1 -0
- package/dist/extra/index.js +40 -0
- package/dist/extra/index.js.map +1 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts +94 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts.map +1 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.js +282 -0
- package/dist/extra/mesh/drill-hole/DrillHoleCore.js.map +1 -0
- package/dist/extra/mesh/drill-hole/drill-types.d.ts +34 -0
- package/dist/extra/mesh/drill-hole/drill-types.d.ts.map +1 -0
- package/dist/extra/mesh/drill-hole/drill-types.js +7 -0
- package/dist/extra/mesh/drill-hole/drill-types.js.map +1 -0
- package/dist/extra/mesh/engrave-decoration.d.ts +42 -0
- package/dist/extra/mesh/engrave-decoration.d.ts.map +1 -0
- package/dist/extra/mesh/engrave-decoration.js +39 -0
- package/dist/extra/mesh/engrave-decoration.js.map +1 -0
- package/dist/extra/mesh/fai_drill.d.ts +21 -0
- package/dist/extra/mesh/fai_drill.d.ts.map +1 -0
- package/dist/extra/mesh/fai_drill.js +89 -0
- package/dist/extra/mesh/fai_drill.js.map +1 -0
- package/dist/extra/mesh/fai_extrude.d.ts +24 -0
- package/dist/extra/mesh/fai_extrude.d.ts.map +1 -0
- package/dist/extra/mesh/fai_extrude.js +42 -0
- package/dist/extra/mesh/fai_extrude.js.map +1 -0
- package/dist/extra/mesh/fai_split.d.ts +164 -0
- package/dist/extra/mesh/fai_split.d.ts.map +1 -0
- package/dist/extra/mesh/fai_split.js +269 -0
- package/dist/extra/mesh/fai_split.js.map +1 -0
- package/dist/extra/mesh/primitives.d.ts +29 -0
- package/dist/extra/mesh/primitives.d.ts.map +1 -0
- package/dist/extra/mesh/primitives.js +41 -0
- package/dist/extra/mesh/primitives.js.map +1 -0
- package/dist/extra/op-names.d.ts +37 -0
- package/dist/extra/op-names.d.ts.map +1 -0
- package/dist/extra/op-names.js +46 -0
- package/dist/extra/op-names.js.map +1 -0
- package/dist/extra/ops/compound.d.ts +140 -0
- package/dist/extra/ops/compound.d.ts.map +1 -0
- package/dist/extra/ops/compound.js +167 -0
- package/dist/extra/ops/compound.js.map +1 -0
- package/dist/extra/ops/copy.d.ts +40 -0
- package/dist/extra/ops/copy.d.ts.map +1 -0
- package/dist/extra/ops/copy.js +83 -0
- package/dist/extra/ops/copy.js.map +1 -0
- package/dist/extra/ops/fai_drill.d.ts +51 -0
- package/dist/extra/ops/fai_drill.d.ts.map +1 -0
- package/dist/extra/ops/fai_drill.js +233 -0
- package/dist/extra/ops/fai_drill.js.map +1 -0
- package/dist/extra/ops/fai_extrude.d.ts +36 -0
- package/dist/extra/ops/fai_extrude.d.ts.map +1 -0
- package/dist/extra/ops/fai_extrude.js +84 -0
- package/dist/extra/ops/fai_extrude.js.map +1 -0
- package/dist/extra/ops/fai_split.d.ts +46 -0
- package/dist/extra/ops/fai_split.d.ts.map +1 -0
- package/dist/extra/ops/fai_split.js +235 -0
- package/dist/extra/ops/fai_split.js.map +1 -0
- package/dist/extra/ops/load.d.ts +49 -0
- package/dist/extra/ops/load.d.ts.map +1 -0
- package/dist/extra/ops/load.js +423 -0
- package/dist/extra/ops/load.js.map +1 -0
- package/dist/extra/ops/svg-extrude.d.ts +32 -0
- package/dist/extra/ops/svg-extrude.d.ts.map +1 -0
- package/dist/extra/ops/svg-extrude.js +74 -0
- package/dist/extra/ops/svg-extrude.js.map +1 -0
- package/dist/extra/ops/text.d.ts +34 -0
- package/dist/extra/ops/text.d.ts.map +1 -0
- package/dist/extra/ops/text.js +100 -0
- package/dist/extra/ops/text.js.map +1 -0
- package/dist/geometry2d/bridge/lift-on-plane.d.ts +8 -5
- package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.js +8 -5
- package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/lang/symbol-table.d.ts +3 -3
- package/dist/lang/symbol-table.generated.d.ts +10 -0
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +10 -0
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/lang/symbol-table.js +3 -3
- package/dist/lang/symbol-table.js.map +1 -1
- package/dist/math3d/index.d.ts +1 -1
- package/dist/math3d/index.js +1 -1
- package/dist/math3d/index.js.map +1 -1
- package/dist/mesh/engrave.d.ts +2 -3
- package/dist/mesh/engrave.d.ts.map +1 -1
- package/dist/mesh/engrave.js +4 -11
- package/dist/mesh/engrave.js.map +1 -1
- package/dist/mesh/index.d.ts +0 -2
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +0 -2
- package/dist/mesh/index.js.map +1 -1
- package/dist/mesh/primitives.d.ts +7 -5
- package/dist/mesh/primitives.d.ts.map +1 -1
- package/dist/mesh/primitives.js +16 -9
- package/dist/mesh/primitives.js.map +1 -1
- package/dist/mesh/types.d.ts +4 -3
- package/dist/mesh/types.d.ts.map +1 -1
- package/dist/mesh/types.js.map +1 -1
- package/dist/node-host/cli.d.ts +11 -4
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +53 -28
- package/dist/node-host/cli.js.map +1 -1
- package/dist/node-host/execute-script.d.ts.map +1 -1
- package/dist/node-host/execute-script.js +3 -4
- package/dist/node-host/execute-script.js.map +1 -1
- package/dist/node-host/lib-package-json.d.ts +36 -0
- package/dist/node-host/lib-package-json.d.ts.map +1 -0
- package/dist/node-host/lib-package-json.js +73 -0
- package/dist/node-host/lib-package-json.js.map +1 -0
- package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
- package/dist/occt-kernel/occt-primitives.js +41 -0
- package/dist/occt-kernel/occt-primitives.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts +1 -1
- package/dist/occt-kernel/occtKernel.js +1 -1
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/primitives/brep-primitives.d.ts.map +1 -1
- package/dist/primitives/brep-primitives.js +39 -12
- package/dist/primitives/brep-primitives.js.map +1 -1
- package/dist/runtime-state.d.ts +28 -1
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +14 -1
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +2 -2
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +11 -2
- package/dist/sdk.js.map +1 -1
- package/dist/sketch/bspline.d.ts +58 -0
- package/dist/sketch/bspline.d.ts.map +1 -0
- package/dist/sketch/bspline.js +104 -0
- package/dist/sketch/bspline.js.map +1 -0
- package/dist/sketch/canonical.d.ts +239 -0
- package/dist/sketch/canonical.d.ts.map +1 -0
- package/dist/sketch/canonical.js +17 -0
- package/dist/sketch/canonical.js.map +1 -0
- package/dist/sketch/contour.d.ts +43 -0
- package/dist/sketch/contour.d.ts.map +1 -0
- package/dist/sketch/contour.js +202 -0
- package/dist/sketch/contour.js.map +1 -0
- package/dist/sketch/dim-spec.d.ts +32 -0
- package/dist/sketch/dim-spec.d.ts.map +1 -0
- package/dist/sketch/dim-spec.js +112 -0
- package/dist/sketch/dim-spec.js.map +1 -0
- package/dist/sketch/faces.d.ts +45 -0
- package/dist/sketch/faces.d.ts.map +1 -0
- package/dist/sketch/faces.js +108 -0
- package/dist/sketch/faces.js.map +1 -0
- package/dist/sketch/fcstd-types.d.ts +194 -0
- package/dist/sketch/fcstd-types.d.ts.map +1 -0
- package/dist/sketch/fcstd-types.js +67 -0
- package/dist/sketch/fcstd-types.js.map +1 -0
- package/dist/sketch/index.d.ts +46 -0
- package/dist/sketch/index.d.ts.map +1 -0
- package/dist/sketch/index.js +39 -0
- package/dist/sketch/index.js.map +1 -0
- package/dist/sketch/node.d.ts +14 -0
- package/dist/sketch/node.d.ts.map +1 -0
- package/dist/sketch/node.js +43 -0
- package/dist/sketch/node.js.map +1 -0
- package/dist/sketch/op.d.ts +111 -0
- package/dist/sketch/op.d.ts.map +1 -0
- package/dist/sketch/op.js +185 -0
- package/dist/sketch/op.js.map +1 -0
- package/dist/sketch/planegcs-backend.d.ts +69 -0
- package/dist/sketch/planegcs-backend.d.ts.map +1 -0
- package/dist/sketch/planegcs-backend.js +812 -0
- package/dist/sketch/planegcs-backend.js.map +1 -0
- package/dist/sketch/project.d.ts +176 -0
- package/dist/sketch/project.d.ts.map +1 -0
- package/dist/sketch/project.js +656 -0
- package/dist/sketch/project.js.map +1 -0
- package/dist/sketch/shapes.d.ts +370 -0
- package/dist/sketch/shapes.d.ts.map +1 -0
- package/dist/sketch/shapes.js +959 -0
- package/dist/sketch/shapes.js.map +1 -0
- package/dist/sketch/solve.d.ts +21 -0
- package/dist/sketch/solve.d.ts.map +1 -0
- package/dist/sketch/solve.js +144 -0
- package/dist/sketch/solve.js.map +1 -0
- package/dist/sketch/solver-loader.d.ts +47 -0
- package/dist/sketch/solver-loader.d.ts.map +1 -0
- package/dist/sketch/solver-loader.js +77 -0
- package/dist/sketch/solver-loader.js.map +1 -0
- package/dist/sketch/solver.d.ts +63 -0
- package/dist/sketch/solver.d.ts.map +1 -0
- package/dist/sketch/solver.js +28 -0
- package/dist/sketch/solver.js.map +1 -0
- package/dist/sketch/verify.d.ts +53 -0
- package/dist/sketch/verify.d.ts.map +1 -0
- package/dist/sketch/verify.js +71 -0
- package/dist/sketch/verify.js.map +1 -0
- package/dist/topology/naming/geom-hint.d.ts +12 -0
- package/dist/topology/naming/geom-hint.d.ts.map +1 -1
- package/dist/topology/naming/geom-hint.js +1 -1
- package/dist/topology/naming/geom-hint.js.map +1 -1
- package/dist/topology/naming/lineage.d.ts +1 -0
- package/dist/topology/naming/lineage.d.ts.map +1 -1
- package/dist/topology/naming/lineage.js +37 -1
- package/dist/topology/naming/lineage.js.map +1 -1
- package/dist/topology/naming/resolve-face.d.ts +13 -2
- package/dist/topology/naming/resolve-face.d.ts.map +1 -1
- package/dist/topology/naming/resolve-face.js +18 -2
- package/dist/topology/naming/resolve-face.js.map +1 -1
- package/dist/weapp.d.ts +1 -1
- package/dist/weapp.d.ts.map +1 -1
- package/dist/weapp.js +1 -1
- package/dist/weapp.js.map +1 -1
- package/package.json +43 -11
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api selectors-to-refs — CadQuery 选择器 → TopoRef 桥(方案 2026-10-12 §3.2)
|
|
3
|
+
*
|
|
4
|
+
* 把 CadQuery 字符串选择器(`">Z"`、`"|Z"`、`"%PLANE"`、命名视图 `"top"`、
|
|
5
|
+
* 集合表达式 `"|Z and %PLANE"` …)求值成内核句柄,再经命名层(RoleTable + 血缘)
|
|
6
|
+
* 反查合成 `FaceTopoRef` / `EdgeTopoRef`,或直接投影成顶点坐标(`P3`)——让
|
|
7
|
+
* `cad.*` op 的拓扑参数能吃下字符串选择器(AI 生成 faijs 代码的目标形态),
|
|
8
|
+
* 而不破坏「选择器子系统与命名/TopoRef 系统物理隔离」的红线。
|
|
9
|
+
*
|
|
10
|
+
* 职责边界(方案 §3.2 R4):本文件是选择器与命名系统之间**唯一的显式通道**。
|
|
11
|
+
* 句柄 → TopoRef 反查复用 `edge-ref.ts` / `face-ref.ts` 已示范的路径
|
|
12
|
+
* (`captureEdgeHint` / `captureFaceHint` / `findOriginRole` /
|
|
13
|
+
* `recoverEdgeFaceRole`),不重写命名逻辑。
|
|
14
|
+
*
|
|
15
|
+
* 错误红线(方案 §3.2 R1,与 faijs 红线一致):选择器选中的**无名实体**
|
|
16
|
+
* (role 缺失,如 3MF 网格链)→ 抛 `TopoRefError`,不静默降级;网格零件没有
|
|
17
|
+
* role 层,选择器/命名体系只服务精度链(网格链用序号是设计定论)。
|
|
18
|
+
*/
|
|
19
|
+
import type { Shape } from '../mesh/types.js';
|
|
20
|
+
import { type EdgeTopoRef, type FaceTopoRef } from '../topology/naming/index.js';
|
|
21
|
+
import type { P3 } from './cadquery-selectors/entity.js';
|
|
22
|
+
/**
|
|
23
|
+
* 把面选择器字符串解析成 `FaceTopoRef[]`(选择器 → 句柄 → TopoRef 全链)。
|
|
24
|
+
*
|
|
25
|
+
* 示例:`">Z"`(Z 极值面)、`"|Z"`(法向平行 Z 的平面面)、`"%PLANE"`、
|
|
26
|
+
* `"top"`(命名视图)、`"|Z and %PLANE"`(集合表达式)。
|
|
27
|
+
*
|
|
28
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape;选择器服务精度链)。
|
|
29
|
+
* @param sel - CadQuery 面选择器字符串。
|
|
30
|
+
* @returns 选中面的 `FaceTopoRef[]`(保持选择器返回顺序)。
|
|
31
|
+
* @throws {TopoRefError} 无 BREP / 选中面无 role 血统(不静默降级)。
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveSelectorToFaceRefs(shape: Shape, sel: string): FaceTopoRef[];
|
|
34
|
+
/**
|
|
35
|
+
* 把边选择器字符串解析成 `EdgeTopoRef[]`(选择器 → 句柄 → TopoRef 全链)。
|
|
36
|
+
*
|
|
37
|
+
* 示例:`"|Z"`(切线平行 Z 的边)、`">Z"`(Z 极值边)、`"%LINE"`、
|
|
38
|
+
* `"#Z"`(切线垂直 Z)。
|
|
39
|
+
*
|
|
40
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
41
|
+
* @param sel - CadQuery 边选择器字符串。
|
|
42
|
+
* @returns 选中边的 `EdgeTopoRef[]`(保持选择器返回顺序)。
|
|
43
|
+
* @throws {TopoRefError} 无 BREP / 选中边邻面不足两面或无 role 血统。
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveSelectorToEdgeRefs(shape: Shape, sel: string): EdgeTopoRef[];
|
|
46
|
+
/**
|
|
47
|
+
* 把顶点选择器字符串解析成顶点坐标 `P3[]`。
|
|
48
|
+
*
|
|
49
|
+
* 顶点没有角色身份(命名层只给面/边命名),故直接投影成世界坐标点——
|
|
50
|
+
* 供未来需要「点」的 op(如打点/对齐)使用。
|
|
51
|
+
*
|
|
52
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
53
|
+
* @param sel - CadQuery 顶点选择器字符串(如 `">Z"`、`"(0,0,0)"`,空串 = 全部)。
|
|
54
|
+
* @returns 选中顶点的世界坐标(保持选择器返回顺序)。
|
|
55
|
+
* @throws {TopoRefError} 无 BREP(顶点选择器只服务精度链)。
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveSelectorToVertexPts(shape: Shape, sel: string): P3[];
|
|
58
|
+
/** 边选择器参数的一个条目:选择器字符串或 `EdgeTopoRef`。 */
|
|
59
|
+
export type EdgeSelectorEntry = EdgeTopoRef | string;
|
|
60
|
+
/** 面选择器参数的一个条目:选择器字符串或 `FaceTopoRef`。 */
|
|
61
|
+
export type FaceSelectorEntry = FaceTopoRef | string;
|
|
62
|
+
/**
|
|
63
|
+
* 展开 op 的边选择器参数(顶层字符串或数组元素字符串)到 `EdgeTopoRef[]`。
|
|
64
|
+
*
|
|
65
|
+
* 形态(方案 D2-A):`edges: "|Z"`、`edges: ["|Z"]`、`edges: ["|Z", refA]` 均可。
|
|
66
|
+
* 数组里的 `EdgeTopoRef` 原样保留;字符串逐个经桥解析(保持出现顺序)。
|
|
67
|
+
*
|
|
68
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
69
|
+
* @param edges - 边选择器参数(字符串 = 单一选择器;数组元素可为选择器字符串或 EdgeTopoRef)。
|
|
70
|
+
* @returns 展开后的 `EdgeTopoRef[]`。
|
|
71
|
+
*/
|
|
72
|
+
export declare function expandEdgeSelectorRefs(shape: Shape, edges: EdgeSelectorEntry[] | string): EdgeTopoRef[];
|
|
73
|
+
/**
|
|
74
|
+
* 展开 op 的面选择器参数(顶层字符串或数组元素字符串)到 `FaceTopoRef[]`。
|
|
75
|
+
*
|
|
76
|
+
* 形态(方案 D2-A):`openFaces: ">Z"`、`faces: ["|Z"]`、`faces: ["|Z", refA]` 均可。
|
|
77
|
+
*
|
|
78
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
79
|
+
* @param faces - 面选择器参数(字符串 = 单一选择器;数组元素可为选择器字符串或 FaceTopoRef)。
|
|
80
|
+
* @returns 展开后的 `FaceTopoRef[]`。
|
|
81
|
+
*/
|
|
82
|
+
export declare function expandFaceSelectorRefs(shape: Shape, faces: FaceSelectorEntry[] | string): FaceTopoRef[];
|
|
83
|
+
//# sourceMappingURL=selectors-to-refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectors-to-refs.d.ts","sourceRoot":"","sources":["../../src/api/selectors-to-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAM1C,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,WAAW,EAGjB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAA;AAgJrD;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAalF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAalF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,CAQ1E;AAID,yCAAyC;AACzC,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,MAAM,CAAA;AAEpD,yCAAyC;AACzC,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,MAAM,CAAA;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,GAClC,WAAW,EAAE,CAGf;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,GAClC,WAAW,EAAE,CAGf"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api selectors-to-refs — CadQuery 选择器 → TopoRef 桥(方案 2026-10-12 §3.2)
|
|
3
|
+
*
|
|
4
|
+
* 把 CadQuery 字符串选择器(`">Z"`、`"|Z"`、`"%PLANE"`、命名视图 `"top"`、
|
|
5
|
+
* 集合表达式 `"|Z and %PLANE"` …)求值成内核句柄,再经命名层(RoleTable + 血缘)
|
|
6
|
+
* 反查合成 `FaceTopoRef` / `EdgeTopoRef`,或直接投影成顶点坐标(`P3`)——让
|
|
7
|
+
* `cad.*` op 的拓扑参数能吃下字符串选择器(AI 生成 faijs 代码的目标形态),
|
|
8
|
+
* 而不破坏「选择器子系统与命名/TopoRef 系统物理隔离」的红线。
|
|
9
|
+
*
|
|
10
|
+
* 职责边界(方案 §3.2 R4):本文件是选择器与命名系统之间**唯一的显式通道**。
|
|
11
|
+
* 句柄 → TopoRef 反查复用 `edge-ref.ts` / `face-ref.ts` 已示范的路径
|
|
12
|
+
* (`captureEdgeHint` / `captureFaceHint` / `findOriginRole` /
|
|
13
|
+
* `recoverEdgeFaceRole`),不重写命名逻辑。
|
|
14
|
+
*
|
|
15
|
+
* 错误红线(方案 §3.2 R1,与 faijs 红线一致):选择器选中的**无名实体**
|
|
16
|
+
* (role 缺失,如 3MF 网格链)→ 抛 `TopoRefError`,不静默降级;网格零件没有
|
|
17
|
+
* role 层,选择器/命名体系只服务精度链(网格链用序号是设计定论)。
|
|
18
|
+
*/
|
|
19
|
+
import { getBrepApi } from '../brep/handle-bridge.js';
|
|
20
|
+
import { brepOf, hasBrep } from '../shape.js';
|
|
21
|
+
import { nameOf } from '../runtime-state.js';
|
|
22
|
+
import { captureEdgeHint, captureFaceHint, findOriginRole, TopoRefError, } from '../topology/naming/index.js';
|
|
23
|
+
import { buildEdgeResolutionContext, recoverEdgeFaceRole } from './topo-resolve.js';
|
|
24
|
+
import { resolveStepHandles } from './cadquery-selectors/resolve.js';
|
|
25
|
+
/** 桥的静态前置:shape 必须是带 BREP 的活实体(选择器服务精度链)。 */
|
|
26
|
+
function requireBrep(shape, what) {
|
|
27
|
+
const kernel = getBrepApi();
|
|
28
|
+
if (!kernel) {
|
|
29
|
+
throw new TopoRefError('E_TOPO_MESH_UNSUPPORTED', 'face', `${what}: selector resolution is BREP-only (mesh path unsupported)`);
|
|
30
|
+
}
|
|
31
|
+
if (!hasBrep(shape)) {
|
|
32
|
+
throw new TopoRefError('E_TOPO_MESH_UNSUPPORTED', 'face', `${what}: input shape has no BREP solid (mesh shapes do not carry topology identity)`);
|
|
33
|
+
}
|
|
34
|
+
return kernel;
|
|
35
|
+
}
|
|
36
|
+
/** 取形状的 BREP solid 句柄(调用方已过 requireBrep,solid 必在)。 */
|
|
37
|
+
function solidOf(shape, what) {
|
|
38
|
+
const solid = brepOf(shape);
|
|
39
|
+
if (solid === undefined) {
|
|
40
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `${what}: input has no BREP solid`);
|
|
41
|
+
}
|
|
42
|
+
return solid;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 面句柄 → `FaceTopoRef`:在命名现场(ctx.faces)定位 ordinal → roleTable 反查
|
|
46
|
+
* `{origin, role}`(miss 沿血缘回走恢复)→ 几何 hint。
|
|
47
|
+
*
|
|
48
|
+
* @param kernel - the active BREP engine.
|
|
49
|
+
* @param shape - the live input shape (for nameOf lineage recovery).
|
|
50
|
+
* @param ctx - the naming resolution context built from the shape.
|
|
51
|
+
* @param handle - the selected face handle.
|
|
52
|
+
* @returns the FaceTopoRef, or throws when the face has no role lineage.
|
|
53
|
+
*/
|
|
54
|
+
function faceHandleToRef(kernel, shape, ctx, handle) {
|
|
55
|
+
const idx = ctx.faces.findIndex((f) => f.handle !== undefined && kernel.isSame(f.handle, handle));
|
|
56
|
+
if (idx < 0) {
|
|
57
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'selector: resolved face is not in the naming context');
|
|
58
|
+
}
|
|
59
|
+
const ordinal = ctx.faces[idx].ordinal;
|
|
60
|
+
const table = ctx.roleTable;
|
|
61
|
+
if (!table) {
|
|
62
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'selector: input shape has no role table (nameless shape)');
|
|
63
|
+
}
|
|
64
|
+
const ordinalToHash = ctx.faces.map((f) => f.hash ?? 0);
|
|
65
|
+
let found = findOriginRole(table, ordinalToHash, ordinal);
|
|
66
|
+
if (!found) {
|
|
67
|
+
// 与 face-ref.ts 同构:目标 part 的 roleTable 缓存残缺但血缘可回走 → 恢复。
|
|
68
|
+
const part = nameOf(shape);
|
|
69
|
+
if (part)
|
|
70
|
+
found = recoverEdgeFaceRole(kernel, part, ordinal, ordinalToHash);
|
|
71
|
+
}
|
|
72
|
+
if (!found) {
|
|
73
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `selector: resolved face ordinal ${ordinal} has no role lineage`);
|
|
74
|
+
}
|
|
75
|
+
return { kind: 'face', origin: found.origin, role: found.role, hint: captureFaceHint(kernel, handle) };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 边句柄 → `EdgeTopoRef`:与 `edge-ref.ts` 同构——逐面枚举其边找邻面(不依赖
|
|
79
|
+
* 邻接表下标对齐),两邻面的 role 对合成限定符 + 几何 hint。
|
|
80
|
+
*
|
|
81
|
+
* @param kernel - the active BREP engine.
|
|
82
|
+
* @param shape - the live input shape (for nameOf lineage recovery).
|
|
83
|
+
* @param ctx - the naming resolution context built from the shape.
|
|
84
|
+
* @param handle - the selected edge handle.
|
|
85
|
+
* @returns the EdgeTopoRef, or throws when the edge lacks a two-face role pair.
|
|
86
|
+
*/
|
|
87
|
+
function edgeHandleToRef(kernel, shape, ctx, handle) {
|
|
88
|
+
const faceOrdinals = [];
|
|
89
|
+
for (const f of ctx.faces) {
|
|
90
|
+
if (f.handle === undefined)
|
|
91
|
+
continue;
|
|
92
|
+
if (kernel.getSubShapes(f.handle, 'edge').some((eh) => kernel.isSame(eh, handle))) {
|
|
93
|
+
faceOrdinals.push(f.ordinal);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (faceOrdinals.length < 2) {
|
|
97
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'edge', `selector: edge has ${faceOrdinals.length} adjacent face(s); an EdgeTopoRef needs a two-face pair`);
|
|
98
|
+
}
|
|
99
|
+
const table = ctx.roleTable;
|
|
100
|
+
if (!table) {
|
|
101
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'edge', 'selector: input shape has no role table (nameless shape)');
|
|
102
|
+
}
|
|
103
|
+
const ordinalToHash = ctx.faces.map((f) => f.hash ?? 0);
|
|
104
|
+
const quals = [];
|
|
105
|
+
for (const fo of faceOrdinals.slice(0, 2)) {
|
|
106
|
+
let found = findOriginRole(table, ordinalToHash, fo);
|
|
107
|
+
if (!found) {
|
|
108
|
+
const part = nameOf(shape);
|
|
109
|
+
if (part)
|
|
110
|
+
found = recoverEdgeFaceRole(kernel, part, fo, ordinalToHash);
|
|
111
|
+
}
|
|
112
|
+
if (!found) {
|
|
113
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'edge', `selector: adjacent face ordinal ${fo} has no role lineage`);
|
|
114
|
+
}
|
|
115
|
+
quals.push({ origin: found.origin, role: found.role });
|
|
116
|
+
}
|
|
117
|
+
const [qa, qb] = quals;
|
|
118
|
+
return { kind: 'edge', faces: [qa, qb], hint: captureEdgeHint(kernel, handle) };
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 把面选择器字符串解析成 `FaceTopoRef[]`(选择器 → 句柄 → TopoRef 全链)。
|
|
122
|
+
*
|
|
123
|
+
* 示例:`">Z"`(Z 极值面)、`"|Z"`(法向平行 Z 的平面面)、`"%PLANE"`、
|
|
124
|
+
* `"top"`(命名视图)、`"|Z and %PLANE"`(集合表达式)。
|
|
125
|
+
*
|
|
126
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape;选择器服务精度链)。
|
|
127
|
+
* @param sel - CadQuery 面选择器字符串。
|
|
128
|
+
* @returns 选中面的 `FaceTopoRef[]`(保持选择器返回顺序)。
|
|
129
|
+
* @throws {TopoRefError} 无 BREP / 选中面无 role 血统(不静默降级)。
|
|
130
|
+
*/
|
|
131
|
+
export function resolveSelectorToFaceRefs(shape, sel) {
|
|
132
|
+
const kernel = requireBrep(shape, 'resolveSelectorToFaceRefs');
|
|
133
|
+
const solid = solidOf(shape, 'resolveSelectorToFaceRefs');
|
|
134
|
+
const ctx = buildEdgeResolutionContext(kernel, shape);
|
|
135
|
+
if (!ctx) {
|
|
136
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'resolveSelectorToFaceRefs: input has no BREP naming context');
|
|
137
|
+
}
|
|
138
|
+
const handles = resolveStepHandles(solid, 'face', sel);
|
|
139
|
+
return handles.map((h) => faceHandleToRef(kernel, shape, ctx, h));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 把边选择器字符串解析成 `EdgeTopoRef[]`(选择器 → 句柄 → TopoRef 全链)。
|
|
143
|
+
*
|
|
144
|
+
* 示例:`"|Z"`(切线平行 Z 的边)、`">Z"`(Z 极值边)、`"%LINE"`、
|
|
145
|
+
* `"#Z"`(切线垂直 Z)。
|
|
146
|
+
*
|
|
147
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
148
|
+
* @param sel - CadQuery 边选择器字符串。
|
|
149
|
+
* @returns 选中边的 `EdgeTopoRef[]`(保持选择器返回顺序)。
|
|
150
|
+
* @throws {TopoRefError} 无 BREP / 选中边邻面不足两面或无 role 血统。
|
|
151
|
+
*/
|
|
152
|
+
export function resolveSelectorToEdgeRefs(shape, sel) {
|
|
153
|
+
const kernel = requireBrep(shape, 'resolveSelectorToEdgeRefs');
|
|
154
|
+
const solid = solidOf(shape, 'resolveSelectorToEdgeRefs');
|
|
155
|
+
const ctx = buildEdgeResolutionContext(kernel, shape);
|
|
156
|
+
if (!ctx) {
|
|
157
|
+
throw new TopoRefError('E_TOPO_NOT_FOUND', 'edge', 'resolveSelectorToEdgeRefs: input has no BREP naming context');
|
|
158
|
+
}
|
|
159
|
+
const handles = resolveStepHandles(solid, 'edge', sel);
|
|
160
|
+
return handles.map((h) => edgeHandleToRef(kernel, shape, ctx, h));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 把顶点选择器字符串解析成顶点坐标 `P3[]`。
|
|
164
|
+
*
|
|
165
|
+
* 顶点没有角色身份(命名层只给面/边命名),故直接投影成世界坐标点——
|
|
166
|
+
* 供未来需要「点」的 op(如打点/对齐)使用。
|
|
167
|
+
*
|
|
168
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
169
|
+
* @param sel - CadQuery 顶点选择器字符串(如 `">Z"`、`"(0,0,0)"`,空串 = 全部)。
|
|
170
|
+
* @returns 选中顶点的世界坐标(保持选择器返回顺序)。
|
|
171
|
+
* @throws {TopoRefError} 无 BREP(顶点选择器只服务精度链)。
|
|
172
|
+
*/
|
|
173
|
+
export function resolveSelectorToVertexPts(shape, sel) {
|
|
174
|
+
const kernel = requireBrep(shape, 'resolveSelectorToVertexPts');
|
|
175
|
+
const solid = solidOf(shape, 'resolveSelectorToVertexPts');
|
|
176
|
+
const handles = resolveStepHandles(solid, 'vertex', sel);
|
|
177
|
+
return handles.map((h) => {
|
|
178
|
+
const p = kernel.vertexPosition(h);
|
|
179
|
+
return { x: p.x, y: p.y, z: p.z };
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 展开 op 的边选择器参数(顶层字符串或数组元素字符串)到 `EdgeTopoRef[]`。
|
|
184
|
+
*
|
|
185
|
+
* 形态(方案 D2-A):`edges: "|Z"`、`edges: ["|Z"]`、`edges: ["|Z", refA]` 均可。
|
|
186
|
+
* 数组里的 `EdgeTopoRef` 原样保留;字符串逐个经桥解析(保持出现顺序)。
|
|
187
|
+
*
|
|
188
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
189
|
+
* @param edges - 边选择器参数(字符串 = 单一选择器;数组元素可为选择器字符串或 EdgeTopoRef)。
|
|
190
|
+
* @returns 展开后的 `EdgeTopoRef[]`。
|
|
191
|
+
*/
|
|
192
|
+
export function expandEdgeSelectorRefs(shape, edges) {
|
|
193
|
+
if (typeof edges === 'string')
|
|
194
|
+
return resolveSelectorToEdgeRefs(shape, edges);
|
|
195
|
+
return edges.flatMap((e) => (typeof e === 'string' ? resolveSelectorToEdgeRefs(shape, e) : [e]));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* 展开 op 的面选择器参数(顶层字符串或数组元素字符串)到 `FaceTopoRef[]`。
|
|
199
|
+
*
|
|
200
|
+
* 形态(方案 D2-A):`openFaces: ">Z"`、`faces: ["|Z"]`、`faces: ["|Z", refA]` 均可。
|
|
201
|
+
*
|
|
202
|
+
* @param shape - 目标几何(BREP 实体所在的 Shape)。
|
|
203
|
+
* @param faces - 面选择器参数(字符串 = 单一选择器;数组元素可为选择器字符串或 FaceTopoRef)。
|
|
204
|
+
* @returns 展开后的 `FaceTopoRef[]`。
|
|
205
|
+
*/
|
|
206
|
+
export function expandFaceSelectorRefs(shape, faces) {
|
|
207
|
+
if (typeof faces === 'string')
|
|
208
|
+
return resolveSelectorToFaceRefs(shape, faces);
|
|
209
|
+
return faces.flatMap((f) => (typeof f === 'string' ? resolveSelectorToFaceRefs(shape, f) : [f]));
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=selectors-to-refs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectors-to-refs.js","sourceRoot":"","sources":["../../src/api/selectors-to-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAGzC,OAAO,EACL,eAAe,EACf,eAAe,EACf,cAAc,EACd,YAAY,GAKb,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAGjE,6CAA6C;AAC7C,SAAS,WAAW,CAAC,KAAY,EAAE,IAAY;IAC7C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,YAAY,CACpB,yBAAyB,EACzB,MAAM,EACN,GAAG,IAAI,4DAA4D,CACpE,CAAA;IACH,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,YAAY,CACpB,yBAAyB,EACzB,MAAM,EACN,GAAG,IAAI,8EAA8E,CACtF,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,sDAAsD;AACtD,SAAS,OAAO,CAAC,KAAY,EAAE,IAAY;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IACrD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,YAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,2BAA2B,CAAC,CAAA;IACxF,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,eAAe,CACtB,MAAqB,EACrB,KAAY,EACZ,GAAsB,EACtB,MAAkB;IAElB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAC7B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CACjE,CAAA;IACD,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,sDAAsD,CACvD,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAA;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAA;IAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,0DAA0D,CAC3D,CAAA;IACH,CAAC;IACD,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;IACvD,IAAI,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,CAAA;IACzD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,wDAAwD;QACxD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAe,CAAC,CAAA;QACpC,IAAI,IAAI;YAAE,KAAK,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;IAC7E,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,mCAAmC,OAAO,sBAAsB,CACjE,CAAA;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;AACxG,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,eAAe,CACtB,MAAqB,EACrB,KAAY,EACZ,GAAsB,EACtB,MAAkB;IAElB,MAAM,YAAY,GAAa,EAAE,CAAA;IACjC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,SAAQ;QACpC,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YAClF,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,sBAAsB,YAAY,CAAC,MAAM,yDAAyD,CACnG,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAA;IAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,0DAA0D,CAC3D,CAAA;IACH,CAAC;IACD,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;IACvD,MAAM,KAAK,GAAoB,EAAE,CAAA;IACjC,KAAK,MAAM,EAAE,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC1C,IAAI,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,CAAA;QACpD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,MAAM,CAAC,KAAe,CAAC,CAAA;YACpC,IAAI,IAAI;gBAAE,KAAK,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,aAAa,CAAC,CAAA;QACxE,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,mCAAmC,EAAE,sBAAsB,CAC5D,CAAA;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,KAAuC,CAAA;IACxD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;AACjF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAY,EAAE,GAAW;IACjE,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAA;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAA;IACzD,MAAM,GAAG,GAAG,0BAA0B,CAAC,MAAM,EAAE,KAAe,CAAC,CAAA;IAC/D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,6DAA6D,CAC9D,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IACtD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;AACnE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAY,EAAE,GAAW;IACjE,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAA;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAA;IACzD,MAAM,GAAG,GAAG,0BAA0B,CAAC,MAAM,EAAE,KAAe,CAAC,CAAA;IAC/D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,6DAA6D,CAC9D,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IACtD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;AACnE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAY,EAAE,GAAW;IAClE,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,4BAA4B,CAAC,CAAA;IAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,4BAA4B,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAA;IACxD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACvB,MAAM,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;QAClC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACnC,CAAC,CAAC,CAAA;AACJ,CAAC;AAUD;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAY,EACZ,KAAmC;IAEnC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC7E,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAClG,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAY,EACZ,KAAmC;IAEnC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC7E,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAClG,CAAC","sourcesContent":["/**\n * api selectors-to-refs — CadQuery 选择器 → TopoRef 桥(方案 2026-10-12 §3.2)\n *\n * 把 CadQuery 字符串选择器(`\">Z\"`、`\"|Z\"`、`\"%PLANE\"`、命名视图 `\"top\"`、\n * 集合表达式 `\"|Z and %PLANE\"` …)求值成内核句柄,再经命名层(RoleTable + 血缘)\n * 反查合成 `FaceTopoRef` / `EdgeTopoRef`,或直接投影成顶点坐标(`P3`)——让\n * `cad.*` op 的拓扑参数能吃下字符串选择器(AI 生成 faijs 代码的目标形态),\n * 而不破坏「选择器子系统与命名/TopoRef 系统物理隔离」的红线。\n *\n * 职责边界(方案 §3.2 R4):本文件是选择器与命名系统之间**唯一的显式通道**。\n * 句柄 → TopoRef 反查复用 `edge-ref.ts` / `face-ref.ts` 已示范的路径\n * (`captureEdgeHint` / `captureFaceHint` / `findOriginRole` /\n * `recoverEdgeFaceRole`),不重写命名逻辑。\n *\n * 错误红线(方案 §3.2 R1,与 faijs 红线一致):选择器选中的**无名实体**\n * (role 缺失,如 3MF 网格链)→ 抛 `TopoRefError`,不静默降级;网格零件没有\n * role 层,选择器/命名体系只服务精度链(网格链用序号是设计定论)。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { brepOf, hasBrep } from '../shape'\nimport { nameOf } from '../runtime-state'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport type { BrepHandle } from '../brep/engine/types'\nimport {\n captureEdgeHint,\n captureFaceHint,\n findOriginRole,\n TopoRefError,\n type EdgeTopoRef,\n type FaceTopoRef,\n type ResolutionContext,\n type RoleQualifier,\n} from '../topology/naming'\nimport { buildEdgeResolutionContext, recoverEdgeFaceRole } from './topo-resolve'\nimport { resolveStepHandles } from './cadquery-selectors/resolve'\nimport type { P3 } from './cadquery-selectors/entity'\n\n/** 桥的静态前置:shape 必须是带 BREP 的活实体(选择器服务精度链)。 */\nfunction requireBrep(shape: Shape, what: string): BrepEngineApi {\n const kernel = getBrepApi()\n if (!kernel) {\n throw new TopoRefError(\n 'E_TOPO_MESH_UNSUPPORTED',\n 'face',\n `${what}: selector resolution is BREP-only (mesh path unsupported)`,\n )\n }\n if (!hasBrep(shape)) {\n throw new TopoRefError(\n 'E_TOPO_MESH_UNSUPPORTED',\n 'face',\n `${what}: input shape has no BREP solid (mesh shapes do not carry topology identity)`,\n )\n }\n return kernel\n}\n\n/** 取形状的 BREP solid 句柄(调用方已过 requireBrep,solid 必在)。 */\nfunction solidOf(shape: Shape, what: string): BrepHandle {\n const solid = brepOf(shape) as BrepHandle | undefined\n if (solid === undefined) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `${what}: input has no BREP solid`)\n }\n return solid\n}\n\n/**\n * 面句柄 → `FaceTopoRef`:在命名现场(ctx.faces)定位 ordinal → roleTable 反查\n * `{origin, role}`(miss 沿血缘回走恢复)→ 几何 hint。\n *\n * @param kernel - the active BREP engine.\n * @param shape - the live input shape (for nameOf lineage recovery).\n * @param ctx - the naming resolution context built from the shape.\n * @param handle - the selected face handle.\n * @returns the FaceTopoRef, or throws when the face has no role lineage.\n */\nfunction faceHandleToRef(\n kernel: BrepEngineApi,\n shape: Shape,\n ctx: ResolutionContext,\n handle: BrepHandle,\n): FaceTopoRef {\n const idx = ctx.faces.findIndex(\n (f) => f.handle !== undefined && kernel.isSame(f.handle, handle),\n )\n if (idx < 0) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n 'selector: resolved face is not in the naming context',\n )\n }\n const ordinal = ctx.faces[idx].ordinal\n const table = ctx.roleTable\n if (!table) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n 'selector: input shape has no role table (nameless shape)',\n )\n }\n const ordinalToHash = ctx.faces.map((f) => f.hash ?? 0)\n let found = findOriginRole(table, ordinalToHash, ordinal)\n if (!found) {\n // 与 face-ref.ts 同构:目标 part 的 roleTable 缓存残缺但血缘可回走 → 恢复。\n const part = nameOf(shape as object)\n if (part) found = recoverEdgeFaceRole(kernel, part, ordinal, ordinalToHash)\n }\n if (!found) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n `selector: resolved face ordinal ${ordinal} has no role lineage`,\n )\n }\n return { kind: 'face', origin: found.origin, role: found.role, hint: captureFaceHint(kernel, handle) }\n}\n\n/**\n * 边句柄 → `EdgeTopoRef`:与 `edge-ref.ts` 同构——逐面枚举其边找邻面(不依赖\n * 邻接表下标对齐),两邻面的 role 对合成限定符 + 几何 hint。\n *\n * @param kernel - the active BREP engine.\n * @param shape - the live input shape (for nameOf lineage recovery).\n * @param ctx - the naming resolution context built from the shape.\n * @param handle - the selected edge handle.\n * @returns the EdgeTopoRef, or throws when the edge lacks a two-face role pair.\n */\nfunction edgeHandleToRef(\n kernel: BrepEngineApi,\n shape: Shape,\n ctx: ResolutionContext,\n handle: BrepHandle,\n): EdgeTopoRef {\n const faceOrdinals: number[] = []\n for (const f of ctx.faces) {\n if (f.handle === undefined) continue\n if (kernel.getSubShapes(f.handle, 'edge').some((eh) => kernel.isSame(eh, handle))) {\n faceOrdinals.push(f.ordinal)\n }\n }\n if (faceOrdinals.length < 2) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'edge',\n `selector: edge has ${faceOrdinals.length} adjacent face(s); an EdgeTopoRef needs a two-face pair`,\n )\n }\n\n const table = ctx.roleTable\n if (!table) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'edge',\n 'selector: input shape has no role table (nameless shape)',\n )\n }\n const ordinalToHash = ctx.faces.map((f) => f.hash ?? 0)\n const quals: RoleQualifier[] = []\n for (const fo of faceOrdinals.slice(0, 2)) {\n let found = findOriginRole(table, ordinalToHash, fo)\n if (!found) {\n const part = nameOf(shape as object)\n if (part) found = recoverEdgeFaceRole(kernel, part, fo, ordinalToHash)\n }\n if (!found) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'edge',\n `selector: adjacent face ordinal ${fo} has no role lineage`,\n )\n }\n quals.push({ origin: found.origin, role: found.role })\n }\n\n const [qa, qb] = quals as [RoleQualifier, RoleQualifier]\n return { kind: 'edge', faces: [qa, qb], hint: captureEdgeHint(kernel, handle) }\n}\n\n/**\n * 把面选择器字符串解析成 `FaceTopoRef[]`(选择器 → 句柄 → TopoRef 全链)。\n *\n * 示例:`\">Z\"`(Z 极值面)、`\"|Z\"`(法向平行 Z 的平面面)、`\"%PLANE\"`、\n * `\"top\"`(命名视图)、`\"|Z and %PLANE\"`(集合表达式)。\n *\n * @param shape - 目标几何(BREP 实体所在的 Shape;选择器服务精度链)。\n * @param sel - CadQuery 面选择器字符串。\n * @returns 选中面的 `FaceTopoRef[]`(保持选择器返回顺序)。\n * @throws {TopoRefError} 无 BREP / 选中面无 role 血统(不静默降级)。\n */\nexport function resolveSelectorToFaceRefs(shape: Shape, sel: string): FaceTopoRef[] {\n const kernel = requireBrep(shape, 'resolveSelectorToFaceRefs')\n const solid = solidOf(shape, 'resolveSelectorToFaceRefs')\n const ctx = buildEdgeResolutionContext(kernel, shape as object)\n if (!ctx) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n 'resolveSelectorToFaceRefs: input has no BREP naming context',\n )\n }\n const handles = resolveStepHandles(solid, 'face', sel)\n return handles.map((h) => faceHandleToRef(kernel, shape, ctx, h))\n}\n\n/**\n * 把边选择器字符串解析成 `EdgeTopoRef[]`(选择器 → 句柄 → TopoRef 全链)。\n *\n * 示例:`\"|Z\"`(切线平行 Z 的边)、`\">Z\"`(Z 极值边)、`\"%LINE\"`、\n * `\"#Z\"`(切线垂直 Z)。\n *\n * @param shape - 目标几何(BREP 实体所在的 Shape)。\n * @param sel - CadQuery 边选择器字符串。\n * @returns 选中边的 `EdgeTopoRef[]`(保持选择器返回顺序)。\n * @throws {TopoRefError} 无 BREP / 选中边邻面不足两面或无 role 血统。\n */\nexport function resolveSelectorToEdgeRefs(shape: Shape, sel: string): EdgeTopoRef[] {\n const kernel = requireBrep(shape, 'resolveSelectorToEdgeRefs')\n const solid = solidOf(shape, 'resolveSelectorToEdgeRefs')\n const ctx = buildEdgeResolutionContext(kernel, shape as object)\n if (!ctx) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'edge',\n 'resolveSelectorToEdgeRefs: input has no BREP naming context',\n )\n }\n const handles = resolveStepHandles(solid, 'edge', sel)\n return handles.map((h) => edgeHandleToRef(kernel, shape, ctx, h))\n}\n\n/**\n * 把顶点选择器字符串解析成顶点坐标 `P3[]`。\n *\n * 顶点没有角色身份(命名层只给面/边命名),故直接投影成世界坐标点——\n * 供未来需要「点」的 op(如打点/对齐)使用。\n *\n * @param shape - 目标几何(BREP 实体所在的 Shape)。\n * @param sel - CadQuery 顶点选择器字符串(如 `\">Z\"`、`\"(0,0,0)\"`,空串 = 全部)。\n * @returns 选中顶点的世界坐标(保持选择器返回顺序)。\n * @throws {TopoRefError} 无 BREP(顶点选择器只服务精度链)。\n */\nexport function resolveSelectorToVertexPts(shape: Shape, sel: string): P3[] {\n const kernel = requireBrep(shape, 'resolveSelectorToVertexPts')\n const solid = solidOf(shape, 'resolveSelectorToVertexPts')\n const handles = resolveStepHandles(solid, 'vertex', sel)\n return handles.map((h) => {\n const p = kernel.vertexPosition(h)\n return { x: p.x, y: p.y, z: p.z }\n })\n}\n\n// ── op 参数输入归一(string 顶层或数组元素 → refs 展开)──────────────────\n\n/** 边选择器参数的一个条目:选择器字符串或 `EdgeTopoRef`。 */\nexport type EdgeSelectorEntry = EdgeTopoRef | string\n\n/** 面选择器参数的一个条目:选择器字符串或 `FaceTopoRef`。 */\nexport type FaceSelectorEntry = FaceTopoRef | string\n\n/**\n * 展开 op 的边选择器参数(顶层字符串或数组元素字符串)到 `EdgeTopoRef[]`。\n *\n * 形态(方案 D2-A):`edges: \"|Z\"`、`edges: [\"|Z\"]`、`edges: [\"|Z\", refA]` 均可。\n * 数组里的 `EdgeTopoRef` 原样保留;字符串逐个经桥解析(保持出现顺序)。\n *\n * @param shape - 目标几何(BREP 实体所在的 Shape)。\n * @param edges - 边选择器参数(字符串 = 单一选择器;数组元素可为选择器字符串或 EdgeTopoRef)。\n * @returns 展开后的 `EdgeTopoRef[]`。\n */\nexport function expandEdgeSelectorRefs(\n shape: Shape,\n edges: EdgeSelectorEntry[] | string,\n): EdgeTopoRef[] {\n if (typeof edges === 'string') return resolveSelectorToEdgeRefs(shape, edges)\n return edges.flatMap((e) => (typeof e === 'string' ? resolveSelectorToEdgeRefs(shape, e) : [e]))\n}\n\n/**\n * 展开 op 的面选择器参数(顶层字符串或数组元素字符串)到 `FaceTopoRef[]`。\n *\n * 形态(方案 D2-A):`openFaces: \">Z\"`、`faces: [\"|Z\"]`、`faces: [\"|Z\", refA]` 均可。\n *\n * @param shape - 目标几何(BREP 实体所在的 Shape)。\n * @param faces - 面选择器参数(字符串 = 单一选择器;数组元素可为选择器字符串或 FaceTopoRef)。\n * @returns 展开后的 `FaceTopoRef[]`。\n */\nexport function expandFaceSelectorRefs(\n shape: Shape,\n faces: FaceSelectorEntry[] | string,\n): FaceTopoRef[] {\n if (typeof faces === 'string') return resolveSelectorToFaceRefs(shape, faces)\n return faces.flatMap((f) => (typeof f === 'string' ? resolveSelectorToFaceRefs(shape, f) : [f]))\n}\n"]}
|
package/dist/api/shell.d.ts
CHANGED
|
@@ -16,12 +16,15 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import type { Shape } from '../mesh/types.js';
|
|
18
18
|
import type { FaceTopoRef } from '../topology/naming/index.js';
|
|
19
|
-
/**
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* 抽壳时移除的面选择器:精度链用 `FaceTopoRef`(UI 拾取产物)或 CadQuery 面选择器
|
|
21
|
+
* 字符串(AI 生成,如 `">Z"` / `"|Z"` / `"%PLANE"`);网格链也可用 1 起序号。
|
|
22
|
+
*/
|
|
23
|
+
export type ShellFaceSelector = number | FaceTopoRef | string;
|
|
21
24
|
/** `cad.shell` 参数。 */
|
|
22
25
|
export interface ShellParams {
|
|
23
|
-
/**
|
|
24
|
-
openFaces: ShellFaceSelector[];
|
|
26
|
+
/** 抽壳时移除的面:面选择器字符串(`">Z"` 等)、或 FaceTopoRef/序号/选择器字符串数组(空数组 = 全封闭薄壁)。 */
|
|
27
|
+
openFaces: ShellFaceSelector[] | string;
|
|
25
28
|
/** 壁厚(mm,>0,向内偏置)。 */
|
|
26
29
|
thickness: number;
|
|
27
30
|
/** 容差(mm,可选;默认走内核约定值)。 */
|
|
@@ -35,15 +38,21 @@ export interface ShellParams {
|
|
|
35
38
|
* @qual ok
|
|
36
39
|
* @name shell
|
|
37
40
|
* @note 中立 op:L1 shell 两引擎同实现。`openFaces` 为空数组时生成全封闭薄壁。
|
|
38
|
-
* 精度链按 role
|
|
39
|
-
*
|
|
41
|
+
* 精度链按 role 线路选面(TopoRef 字面量或 CadQuery 面选择器字符串);
|
|
42
|
+
* **禁止 `cad.faceRef` 序号**——序号跨内核不可移植。网格链没有 role 层,
|
|
43
|
+
* 序号是唯一无歧义的指认方式(仅当前内核快照),选择器字符串只服务精度链。
|
|
40
44
|
* @returns Shape 抽壳后的薄壁体。
|
|
41
45
|
* @param input - 目标几何。type:Shape required:true
|
|
42
|
-
* @param params.openFaces -
|
|
46
|
+
* @param params.openFaces - 要移除的面:面选择器字符串(如 ">Z",AI 生成)或 FaceTopoRef[](UI 拾取产物字面量;禁止 cad.faceRef 序号;网格链可用 1 起序号)。type:ShellFaceSelector[]|string required:true
|
|
43
47
|
* @param params.thickness - 壁厚(mm,>0)。type:number required:true
|
|
44
48
|
* @param params.tolerance - 容差(mm)。type:number required:false
|
|
45
49
|
* @example
|
|
46
|
-
*
|
|
50
|
+
* // openFaces 取 UI 拾取产物的 FaceTopoRef 字面量(origin/role 由命名层分配,不手写);
|
|
51
|
+
* // ❌ 不要用 cad.faceRef 序号——跨内核不可移植
|
|
52
|
+
* const sh = await cad.shell(part0, { openFaces: pickedFaces, thickness: 2 })
|
|
53
|
+
* // AI 生成可写 CadQuery 面选择器字符串("|Z" 法向平行 Z 的面、"top" 命名视图)
|
|
54
|
+
* const sh2 = await cad.shell(part0, { openFaces: "|Z", thickness: 2 })
|
|
55
|
+
* // 网格链(3MF mesh-solid):无 role 层,序号是唯一无歧义指认(仅当前内核快照)
|
|
47
56
|
* const sm = await cad.shell(meshPart, { openFaces: [4], thickness: 2 })
|
|
48
57
|
*/
|
|
49
58
|
export declare const shell: ((input: Shape, params: ShellParams) => Promise<Shape>) & {
|
package/dist/api/shell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAQ1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAQ1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAOrD;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAA;AAE7D,sBAAsB;AACtB,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAAA;IACvC,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqHD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,KAAK;;CAWhB,CAAA"}
|
package/dist/api/shell.js
CHANGED
|
@@ -23,16 +23,43 @@ import { hasNativeHistory } from '../brep/engine/native-history.js';
|
|
|
23
23
|
import { resolveTopoRef, TopoRefError } from '../topology/naming/index.js';
|
|
24
24
|
import { buildEdgeResolutionContext } from './topo-resolve.js';
|
|
25
25
|
import { meshKernelFailure, meshSolidBasicEntry, meshSolidProduct, resolveMeshFaces } from './internal/mesh-solid-op.js';
|
|
26
|
+
import { resolveSelectorToFaceRefs } from './selectors-to-refs.js';
|
|
26
27
|
/** 参数共校验(两条路径共用;`openFaces` 为空数组合法 = 全封闭薄壁)。 */
|
|
27
28
|
function assertShellParams(params) {
|
|
28
29
|
const { openFaces, thickness } = params ?? {};
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const openFacesOk = typeof openFaces === 'string' ||
|
|
31
|
+
(Array.isArray(openFaces) &&
|
|
32
|
+
openFaces.every((s) => typeof s === 'string' ||
|
|
33
|
+
typeof s === 'number' ||
|
|
34
|
+
(!!s && typeof s === 'object' && s.kind === 'face')));
|
|
35
|
+
if (!openFacesOk) {
|
|
36
|
+
throw new Error('E_SHELL_BAD_OPEN_FACES: shell.openFaces must be a face selector string, or an array of FaceTopoRef / ordinal / selector string');
|
|
31
37
|
}
|
|
32
38
|
if (typeof thickness !== 'number' || !Number.isFinite(thickness) || thickness <= 0) {
|
|
33
39
|
throw new Error('E_SHELL_BAD_THICKNESS: shell.thickness must be a positive number');
|
|
34
40
|
}
|
|
35
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* 展开 `openFaces` 到 `FaceTopoRef` 列表(BREP 路径):选择器字符串 → 桥解析;
|
|
44
|
+
* `FaceTopoRef` 原样保留;**序号在精度链抛错**(BREP 面身份是 `(origin, role)`,
|
|
45
|
+
* 序号只是本次枚举序,见 shellBrep 原注释)。
|
|
46
|
+
*/
|
|
47
|
+
function expandShellFaceRefs(input, openFaces) {
|
|
48
|
+
if (typeof openFaces === 'string')
|
|
49
|
+
return resolveSelectorToFaceRefs(input, openFaces);
|
|
50
|
+
return openFaces.flatMap((sel) => {
|
|
51
|
+
if (typeof sel === 'string')
|
|
52
|
+
return resolveSelectorToFaceRefs(input, sel);
|
|
53
|
+
if (typeof sel === 'number') {
|
|
54
|
+
throw new Error('E_SHELL_BAD_OPEN_FACES: an ordinal face selector is only available on the mesh chain — ' +
|
|
55
|
+
'a precision-chain face is identified by its role line (cad.faceRef) or a selector string');
|
|
56
|
+
}
|
|
57
|
+
if (!sel || sel.kind !== 'face') {
|
|
58
|
+
throw new Error('E_SHELL_BAD_OPEN_FACES: every openFaces entry must be a FaceTopoRef (cad.faceRef) or a selector string');
|
|
59
|
+
}
|
|
60
|
+
return [sel];
|
|
61
|
+
});
|
|
62
|
+
}
|
|
36
63
|
/** BREP 路径:解析面引用 → L1 shell → 收养。 */
|
|
37
64
|
function shellBrep(input, params) {
|
|
38
65
|
const { openFaces, thickness, tolerance } = params;
|
|
@@ -44,15 +71,7 @@ function shellBrep(input, params) {
|
|
|
44
71
|
const ctx = buildEdgeResolutionContext(kernel, input);
|
|
45
72
|
if (!ctx)
|
|
46
73
|
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'shell: input has no BREP naming context');
|
|
47
|
-
const faceHandles = openFaces.map((ref) => {
|
|
48
|
-
// 精度链不开序号口子:BREP 的面身份是 `(origin, role)`,序号只是本次枚举序。
|
|
49
|
-
if (typeof ref === 'number') {
|
|
50
|
-
throw new Error('E_SHELL_BAD_OPEN_FACES: an ordinal face selector is only available on the mesh chain — ' +
|
|
51
|
-
'a precision-chain face is identified by its role line (cad.faceRef)');
|
|
52
|
-
}
|
|
53
|
-
if (!ref || ref.kind !== 'face') {
|
|
54
|
-
throw new Error('E_SHELL_BAD_OPEN_FACES: every openFaces entry must be a FaceTopoRef (cad.faceRef)');
|
|
55
|
-
}
|
|
74
|
+
const faceHandles = expandShellFaceRefs(input, openFaces).map((ref) => {
|
|
56
75
|
const r = resolveTopoRef(ref, ctx);
|
|
57
76
|
if (r.handle === undefined) {
|
|
58
77
|
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `shell: face resolved without handle (${ref.origin}/${ref.role})`);
|
|
@@ -86,6 +105,11 @@ function shellMeshSolid(input, params) {
|
|
|
86
105
|
const { openFaces, thickness, tolerance } = params;
|
|
87
106
|
assertShellParams(params);
|
|
88
107
|
const entry = meshSolidBasicEntry(input, 'shell');
|
|
108
|
+
// 选择器字符串只服务精度链:网格零件没有 role 层,选择器命中无名实体转
|
|
109
|
+
// TopoRef 必然失败(方案 R1),显式抛错而非静默降级;网格链用 1 起序号。
|
|
110
|
+
if (typeof openFaces === 'string' || openFaces.some((s) => typeof s === 'string')) {
|
|
111
|
+
throw new TopoRefError('E_TOPO_MESH_UNSUPPORTED', 'face', 'shell: selector strings are precision-chain only — mesh solids have no role layer (use 1-based face ordinals)');
|
|
112
|
+
}
|
|
89
113
|
const faceHandles = resolveMeshFaces(entry.kernel, input, openFaces, 'shell');
|
|
90
114
|
let result;
|
|
91
115
|
try {
|
|
@@ -104,15 +128,21 @@ function shellMeshSolid(input, params) {
|
|
|
104
128
|
* @qual ok
|
|
105
129
|
* @name shell
|
|
106
130
|
* @note 中立 op:L1 shell 两引擎同实现。`openFaces` 为空数组时生成全封闭薄壁。
|
|
107
|
-
* 精度链按 role
|
|
108
|
-
*
|
|
131
|
+
* 精度链按 role 线路选面(TopoRef 字面量或 CadQuery 面选择器字符串);
|
|
132
|
+
* **禁止 `cad.faceRef` 序号**——序号跨内核不可移植。网格链没有 role 层,
|
|
133
|
+
* 序号是唯一无歧义的指认方式(仅当前内核快照),选择器字符串只服务精度链。
|
|
109
134
|
* @returns Shape 抽壳后的薄壁体。
|
|
110
135
|
* @param input - 目标几何。type:Shape required:true
|
|
111
|
-
* @param params.openFaces -
|
|
136
|
+
* @param params.openFaces - 要移除的面:面选择器字符串(如 ">Z",AI 生成)或 FaceTopoRef[](UI 拾取产物字面量;禁止 cad.faceRef 序号;网格链可用 1 起序号)。type:ShellFaceSelector[]|string required:true
|
|
112
137
|
* @param params.thickness - 壁厚(mm,>0)。type:number required:true
|
|
113
138
|
* @param params.tolerance - 容差(mm)。type:number required:false
|
|
114
139
|
* @example
|
|
115
|
-
*
|
|
140
|
+
* // openFaces 取 UI 拾取产物的 FaceTopoRef 字面量(origin/role 由命名层分配,不手写);
|
|
141
|
+
* // ❌ 不要用 cad.faceRef 序号——跨内核不可移植
|
|
142
|
+
* const sh = await cad.shell(part0, { openFaces: pickedFaces, thickness: 2 })
|
|
143
|
+
* // AI 生成可写 CadQuery 面选择器字符串("|Z" 法向平行 Z 的面、"top" 命名视图)
|
|
144
|
+
* const sh2 = await cad.shell(part0, { openFaces: "|Z", thickness: 2 })
|
|
145
|
+
* // 网格链(3MF mesh-solid):无 role 层,序号是唯一无歧义指认(仅当前内核快照)
|
|
116
146
|
* const sm = await cad.shell(meshPart, { openFaces: [4], thickness: 2 })
|
|
117
147
|
*/
|
|
118
148
|
export const shell = defineOp({
|
package/dist/api/shell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api shell — 抽壳:按面移除生成等厚薄壁(手写中立 op,Phase 5)\n *\n * 中立 op:L1 `shell(solid, facesToRemove, thickness, tolerance)` 在 occt 与\n * brepkit 两侧均有真实现(engine-method-map 实测 `dialect`)⇒ 走 `getBrepApi()`\n * (D12),不声明 engines(中立 op:实现只经 L1 契约面)。相对现状是\n * 覆盖面扩大——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。\n *\n * 选面口径(设计原则 4):`openFaces: FaceTopoRef[]`(`cad.faceRef` 产物),\n * 与 `fillet` 的 `EdgeTopoRef[]` / `extrude` 的 `upTo` 同族;不复刻旧\n * `Face[]` 句柄入参。解析在 op 内一处完成(`buildEdgeResolutionContext` 现场枚举\n * + `resolveTopoRef`)。\n *\n * 网格链(方案 2026-10-01 §4 Phase 4 / B3 批):`mesh:` 实现走网格后端,面按\n * **序号或 FaceTopoRef** 解析(近似拓扑没有 role 层),产物是新的网格零件。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { shellWithHashEvolution } from '../brep/face-evolution'\nimport { brepOf, fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\nimport { hasNativeHistory } from '../brep/engine/native-history'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { resolveTopoRef, TopoRefError } from '../topology/naming'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { buildEdgeResolutionContext } from './topo-resolve'\nimport { meshKernelFailure, meshSolidBasicEntry, meshSolidProduct, resolveMeshFaces } from './internal/mesh-solid-op'\n\n/** 抽壳时移除的面选择器:精度链用 `FaceTopoRef`;网格链也可用 1 起序号。 */\nexport type ShellFaceSelector = number | FaceTopoRef\n\n/** `cad.shell` 参数。 */\nexport interface ShellParams {\n /** 抽壳时移除的面(FaceTopoRef[],`cad.faceRef` 产物;空数组 = 全封闭薄壁)。 */\n openFaces: ShellFaceSelector[]\n /** 壁厚(mm,>0,向内偏置)。 */\n thickness: number\n /** 容差(mm,可选;默认走内核约定值)。 */\n tolerance?: number\n}\n\n/** 参数共校验(两条路径共用;`openFaces` 为空数组合法 = 全封闭薄壁)。 */\nfunction assertShellParams(params: ShellParams): void {\n const { openFaces, thickness } = params ?? ({} as ShellParams)\n if (!Array.isArray(openFaces)) {\n throw new Error('E_SHELL_BAD_OPEN_FACES: shell.openFaces must be an array of FaceTopoRef or ordinals')\n }\n if (typeof thickness !== 'number' || !Number.isFinite(thickness) || thickness <= 0) {\n throw new Error('E_SHELL_BAD_THICKNESS: shell.thickness must be a positive number')\n }\n}\n\n/** BREP 路径:解析面引用 → L1 shell → 收养。 */\nfunction shellBrep(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (solid === undefined) throw new Error('E_SHELL_NO_BREP: shell input is not BREP')\n\n const ctx = buildEdgeResolutionContext(kernel, input as object)\n if (!ctx) throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'shell: input has no BREP naming context')\n const faceHandles = openFaces.map((ref) => {\n // 精度链不开序号口子:BREP 的面身份是 `(origin, role)`,序号只是本次枚举序。\n if (typeof ref === 'number') {\n throw new Error(\n 'E_SHELL_BAD_OPEN_FACES: an ordinal face selector is only available on the mesh chain — ' +\n 'a precision-chain face is identified by its role line (cad.faceRef)',\n )\n }\n if (!ref || (ref as { kind?: unknown }).kind !== 'face') {\n throw new Error('E_SHELL_BAD_OPEN_FACES: every openFaces entry must be a FaceTopoRef (cad.faceRef)')\n }\n const r = resolveTopoRef(ref, ctx)\n if (r.handle === undefined) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `shell: face resolved without handle (${ref.origin}/${ref.role})`)\n }\n return r.handle as BrepHandle\n })\n\n // C5 实现面接入(静态双轨,无运行时 try-catch):\n // - occt 原生有 `shellWithHistory` → 走权威面演化(血缘更准);\n // - brepkit 没有 → 显式回退裸 L1 `shell`(**不报错**),不伪造面演化\n // (抽壳是毁面重造,恒等映射不真实)。\n if (hasNativeHistory('shellWithHistory')) {\n const r = shellWithHashEvolution(kernel, solid, faceHandles, thickness, tolerance ?? 1e-6)\n return fromBrep(solidToShape(kernel, r.result), { solid: r.result, faceEvolution: r.faceEvolution })\n }\n const result = kernel.shell(solid, faceHandles, thickness, tolerance ?? 1e-6)\n return fromBrep(solidToShape(kernel, result), { solid: result })\n}\n\n/**\n * 网格实体路径:按序号或几何选出要开口的面,交网格后端抽壳。\n *\n * 与 BREP 路径同一条 L1 契约面(`shell(solid, faces, thickness, tolerance)`),\n * 差别只在选面方式:近似拓扑没有 role 层,面靠**序号**(拓扑 `faces` 数组下标 + 1)\n * 或 `FaceTopoRef` 的几何匹配(法向/中心/面积)指认。产物是新网格零件,\n * 近似拓扑由 `meshSolidProduct` 重建。\n *\n * @param input - the mesh-solid input.\n * @param params - the shell parameters.\n * @returns the shelled mesh solid as a new mesh part.\n */\nfunction shellMeshSolid(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const entry = meshSolidBasicEntry(input, 'shell')\n const faceHandles = resolveMeshFaces(entry.kernel, input, openFaces, 'shell')\n\n let result: BrepHandle\n try {\n result = entry.kernel.shell(entry.solid, faceHandles, thickness, tolerance ?? 1e-6)\n } catch (cause) {\n throw meshKernelFailure(\n 'shell',\n 'E_SHELL_FAILED',\n `shell(thickness=${thickness}) removing ${faceHandles.length} face(s)`,\n cause,\n )\n }\n return meshSolidProduct(entry, result)\n}\n\n/**\n * 抽壳:移除指定面并把余下面偏置成等厚薄壁。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name shell\n * @note 中立 op:L1 shell 两引擎同实现。`openFaces` 为空数组时生成全封闭薄壁。\n * 精度链按 role 线路选面(`cad.faceRef`);网格链按序号或几何选面——网格零件\n * 没有 role 层,序号是唯一无歧义的指认方式。\n * @returns Shape 抽壳后的薄壁体。\n * @param input - 目标几何。type:Shape required:true\n * @param params.openFaces - 要移除的面(FaceTopoRef[],cad.faceRef 产物;网格链可用 1 起序号)。type:FaceTopoRef[] required:true\n * @param params.thickness - 壁厚(mm,>0)。type:number required:true\n * @param params.tolerance - 容差(mm)。type:number required:false\n * @example\n * const sh = await cad.shell(part0, { openFaces: [cad.faceRef(part0, 1)], thickness: 2 })\n * const sm = await cad.shell(meshPart, { openFaces: [4], thickness: 2 })\n */\nexport const shell = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, params: ShellParams) {\n return shellMeshSolid(input, params)\n },\n brep(input: Shape, params: ShellParams) {\n return shellBrep(input, params)\n },\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n\n paramDims: {},\n})\n"]}
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/api/shell.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api shell — 抽壳:按面移除生成等厚薄壁(手写中立 op,Phase 5)\n *\n * 中立 op:L1 `shell(solid, facesToRemove, thickness, tolerance)` 在 occt 与\n * brepkit 两侧均有真实现(engine-method-map 实测 `dialect`)⇒ 走 `getBrepApi()`\n * (D12),不声明 engines(中立 op:实现只经 L1 契约面)。相对现状是\n * 覆盖面扩大——旧版是 occt 平台 op(arg-spec `engines:['occt']`,skip)。\n *\n * 选面口径(设计原则 4):`openFaces: FaceTopoRef[]`(`cad.faceRef` 产物),\n * 与 `fillet` 的 `EdgeTopoRef[]` / `extrude` 的 `upTo` 同族;不复刻旧\n * `Face[]` 句柄入参。解析在 op 内一处完成(`buildEdgeResolutionContext` 现场枚举\n * + `resolveTopoRef`)。\n *\n * 网格链(方案 2026-10-01 §4 Phase 4 / B3 批):`mesh:` 实现走网格后端,面按\n * **序号或 FaceTopoRef** 解析(近似拓扑没有 role 层),产物是新的网格零件。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { shellWithHashEvolution } from '../brep/face-evolution'\nimport { brepOf, fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\nimport { hasNativeHistory } from '../brep/engine/native-history'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { resolveTopoRef, TopoRefError } from '../topology/naming'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { buildEdgeResolutionContext } from './topo-resolve'\nimport { meshKernelFailure, meshSolidBasicEntry, meshSolidProduct, resolveMeshFaces } from './internal/mesh-solid-op'\nimport { resolveSelectorToFaceRefs } from './selectors-to-refs'\n\n/**\n * 抽壳时移除的面选择器:精度链用 `FaceTopoRef`(UI 拾取产物)或 CadQuery 面选择器\n * 字符串(AI 生成,如 `\">Z\"` / `\"|Z\"` / `\"%PLANE\"`);网格链也可用 1 起序号。\n */\nexport type ShellFaceSelector = number | FaceTopoRef | string\n\n/** `cad.shell` 参数。 */\nexport interface ShellParams {\n /** 抽壳时移除的面:面选择器字符串(`\">Z\"` 等)、或 FaceTopoRef/序号/选择器字符串数组(空数组 = 全封闭薄壁)。 */\n openFaces: ShellFaceSelector[] | string\n /** 壁厚(mm,>0,向内偏置)。 */\n thickness: number\n /** 容差(mm,可选;默认走内核约定值)。 */\n tolerance?: number\n}\n\n/** 参数共校验(两条路径共用;`openFaces` 为空数组合法 = 全封闭薄壁)。 */\nfunction assertShellParams(params: ShellParams): void {\n const { openFaces, thickness } = params ?? ({} as ShellParams)\n const openFacesOk =\n typeof openFaces === 'string' ||\n (Array.isArray(openFaces) &&\n openFaces.every(\n (s) =>\n typeof s === 'string' ||\n typeof s === 'number' ||\n (!!s && typeof s === 'object' && (s as { kind?: unknown }).kind === 'face'),\n ))\n if (!openFacesOk) {\n throw new Error(\n 'E_SHELL_BAD_OPEN_FACES: shell.openFaces must be a face selector string, or an array of FaceTopoRef / ordinal / selector string',\n )\n }\n if (typeof thickness !== 'number' || !Number.isFinite(thickness) || thickness <= 0) {\n throw new Error('E_SHELL_BAD_THICKNESS: shell.thickness must be a positive number')\n }\n}\n\n/**\n * 展开 `openFaces` 到 `FaceTopoRef` 列表(BREP 路径):选择器字符串 → 桥解析;\n * `FaceTopoRef` 原样保留;**序号在精度链抛错**(BREP 面身份是 `(origin, role)`,\n * 序号只是本次枚举序,见 shellBrep 原注释)。\n */\nfunction expandShellFaceRefs(input: Shape, openFaces: ShellFaceSelector[] | string): FaceTopoRef[] {\n if (typeof openFaces === 'string') return resolveSelectorToFaceRefs(input, openFaces)\n return openFaces.flatMap((sel) => {\n if (typeof sel === 'string') return resolveSelectorToFaceRefs(input, sel)\n if (typeof sel === 'number') {\n throw new Error(\n 'E_SHELL_BAD_OPEN_FACES: an ordinal face selector is only available on the mesh chain — ' +\n 'a precision-chain face is identified by its role line (cad.faceRef) or a selector string',\n )\n }\n if (!sel || (sel as { kind?: unknown }).kind !== 'face') {\n throw new Error('E_SHELL_BAD_OPEN_FACES: every openFaces entry must be a FaceTopoRef (cad.faceRef) or a selector string')\n }\n return [sel]\n })\n}\n\n/** BREP 路径:解析面引用 → L1 shell → 收养。 */\nfunction shellBrep(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const kernel = getBrepApi()\n const solid = brepOf(input) as BrepHandle | undefined\n if (solid === undefined) throw new Error('E_SHELL_NO_BREP: shell input is not BREP')\n\n const ctx = buildEdgeResolutionContext(kernel, input as object)\n if (!ctx) throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'shell: input has no BREP naming context')\n const faceHandles = expandShellFaceRefs(input, openFaces).map((ref) => {\n const r = resolveTopoRef(ref, ctx)\n if (r.handle === undefined) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `shell: face resolved without handle (${ref.origin}/${ref.role})`)\n }\n return r.handle as BrepHandle\n })\n\n // C5 实现面接入(静态双轨,无运行时 try-catch):\n // - occt 原生有 `shellWithHistory` → 走权威面演化(血缘更准);\n // - brepkit 没有 → 显式回退裸 L1 `shell`(**不报错**),不伪造面演化\n // (抽壳是毁面重造,恒等映射不真实)。\n if (hasNativeHistory('shellWithHistory')) {\n const r = shellWithHashEvolution(kernel, solid, faceHandles, thickness, tolerance ?? 1e-6)\n return fromBrep(solidToShape(kernel, r.result), { solid: r.result, faceEvolution: r.faceEvolution })\n }\n const result = kernel.shell(solid, faceHandles, thickness, tolerance ?? 1e-6)\n return fromBrep(solidToShape(kernel, result), { solid: result })\n}\n\n/**\n * 网格实体路径:按序号或几何选出要开口的面,交网格后端抽壳。\n *\n * 与 BREP 路径同一条 L1 契约面(`shell(solid, faces, thickness, tolerance)`),\n * 差别只在选面方式:近似拓扑没有 role 层,面靠**序号**(拓扑 `faces` 数组下标 + 1)\n * 或 `FaceTopoRef` 的几何匹配(法向/中心/面积)指认。产物是新网格零件,\n * 近似拓扑由 `meshSolidProduct` 重建。\n *\n * @param input - the mesh-solid input.\n * @param params - the shell parameters.\n * @returns the shelled mesh solid as a new mesh part.\n */\nfunction shellMeshSolid(input: Shape, params: ShellParams): Shape {\n const { openFaces, thickness, tolerance } = params\n assertShellParams(params)\n const entry = meshSolidBasicEntry(input, 'shell')\n // 选择器字符串只服务精度链:网格零件没有 role 层,选择器命中无名实体转\n // TopoRef 必然失败(方案 R1),显式抛错而非静默降级;网格链用 1 起序号。\n if (typeof openFaces === 'string' || openFaces.some((s) => typeof s === 'string')) {\n throw new TopoRefError(\n 'E_TOPO_MESH_UNSUPPORTED',\n 'face',\n 'shell: selector strings are precision-chain only — mesh solids have no role layer (use 1-based face ordinals)',\n )\n }\n const faceHandles = resolveMeshFaces(entry.kernel, input, openFaces as (number | FaceTopoRef)[], 'shell')\n\n let result: BrepHandle\n try {\n result = entry.kernel.shell(entry.solid, faceHandles, thickness, tolerance ?? 1e-6)\n } catch (cause) {\n throw meshKernelFailure(\n 'shell',\n 'E_SHELL_FAILED',\n `shell(thickness=${thickness}) removing ${faceHandles.length} face(s)`,\n cause,\n )\n }\n return meshSolidProduct(entry, result)\n}\n\n/**\n * 抽壳:移除指定面并把余下面偏置成等厚薄壁。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name shell\n * @note 中立 op:L1 shell 两引擎同实现。`openFaces` 为空数组时生成全封闭薄壁。\n * 精度链按 role 线路选面(TopoRef 字面量或 CadQuery 面选择器字符串);\n * **禁止 `cad.faceRef` 序号**——序号跨内核不可移植。网格链没有 role 层,\n * 序号是唯一无歧义的指认方式(仅当前内核快照),选择器字符串只服务精度链。\n * @returns Shape 抽壳后的薄壁体。\n * @param input - 目标几何。type:Shape required:true\n * @param params.openFaces - 要移除的面:面选择器字符串(如 \">Z\",AI 生成)或 FaceTopoRef[](UI 拾取产物字面量;禁止 cad.faceRef 序号;网格链可用 1 起序号)。type:ShellFaceSelector[]|string required:true\n * @param params.thickness - 壁厚(mm,>0)。type:number required:true\n * @param params.tolerance - 容差(mm)。type:number required:false\n * @example\n * // openFaces 取 UI 拾取产物的 FaceTopoRef 字面量(origin/role 由命名层分配,不手写);\n * // ❌ 不要用 cad.faceRef 序号——跨内核不可移植\n * const sh = await cad.shell(part0, { openFaces: pickedFaces, thickness: 2 })\n * // AI 生成可写 CadQuery 面选择器字符串(\"|Z\" 法向平行 Z 的面、\"top\" 命名视图)\n * const sh2 = await cad.shell(part0, { openFaces: \"|Z\", thickness: 2 })\n * // 网格链(3MF mesh-solid):无 role 层,序号是唯一无歧义指认(仅当前内核快照)\n * const sm = await cad.shell(meshPart, { openFaces: [4], thickness: 2 })\n */\nexport const shell = defineOp({\n meshEngines: ['brepkit'],\n mesh(input: Shape, params: ShellParams) {\n return shellMeshSolid(input, params)\n },\n brep(input: Shape, params: ShellParams) {\n return shellBrep(input, params)\n },\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n\n paramDims: {},\n})\n"]}
|
|
@@ -36,15 +36,17 @@ import type { BrepHandle } from '../brep/engine/types.js';
|
|
|
36
36
|
import { type FaceTopoRef } from '../topology/naming/index.js';
|
|
37
37
|
import { type FaceScaleMode } from '../geometry2d/bridge/on-surface.js';
|
|
38
38
|
import { type ProfileLoop } from './profile.js';
|
|
39
|
-
/** A face selector on a target solid: a 1-based ordinal (FreeCAD `FaceN
|
|
40
|
-
|
|
39
|
+
/** A face selector on a target solid: a 1-based ordinal (FreeCAD `FaceN`, mesh chain /
|
|
40
|
+
* current kernel snapshot only), a `cad.faceRef` result, or a CadQuery face selector
|
|
41
|
+
* string (e.g. `">Z"` — precision chain, resolved on `on`). */
|
|
42
|
+
export type FaceSelector = number | FaceTopoRef | string;
|
|
41
43
|
/** Contour loops + the target face for `cad.sketchOnFace`. */
|
|
42
44
|
export interface SketchOnFaceParams {
|
|
43
45
|
/** Ordered 2D closed contours (same shape as `cad.profile` / `cad.sketchOnPlane`). */
|
|
44
46
|
contours: ProfileLoop[];
|
|
45
47
|
/** The target solid on which the host face lives. */
|
|
46
48
|
on: Shape;
|
|
47
|
-
/** The host face: a
|
|
49
|
+
/** The host face: a FaceTopoRef (UI-picked literal), a CadQuery face selector string (e.g. ">Z", resolved on `on`), or a 1-based face ordinal (mesh chain / current kernel snapshot only). */
|
|
48
50
|
face: FaceSelector;
|
|
49
51
|
/** How 2D coords map onto the face UV space: `'original'` (identity) | `'bounds'`/`'native'` (affine-fit). */
|
|
50
52
|
scaleMode?: FaceScaleMode;
|
|
@@ -52,10 +54,11 @@ export interface SketchOnFaceParams {
|
|
|
52
54
|
as?: 'face' | 'wire';
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
|
-
* Resolve a face on `on` to its live BREP handle (1-based ordinal
|
|
57
|
+
* Resolve a face on `on` to its live BREP handle (1-based ordinal, `cad.faceRef`,
|
|
58
|
+
* or CadQuery face selector string resolved on `on`).
|
|
56
59
|
* @param kernel - the BREP engine surface.
|
|
57
60
|
* @param on - the target solid shape.
|
|
58
|
-
* @param selector - the face ordinal
|
|
61
|
+
* @param selector - the face ordinal, `cad.faceRef` result, or selector string.
|
|
59
62
|
* @returns the live face handle.
|
|
60
63
|
*/
|
|
61
64
|
export declare function resolveFaceHandle(kernel: BrepEngineApi, on: Shape, selector: FaceSelector): BrepHandle;
|
|
@@ -120,9 +123,12 @@ export declare function buildSketchOnFaceMesh(params: SketchOnFaceParams): Shape
|
|
|
120
123
|
* @returns Shape on the target face (face, or a wire curve when `as:'wire'`).
|
|
121
124
|
* @param params.contours - ordered 2D closed contours (same shape as `cad.profile`).type:any[] required:true
|
|
122
125
|
* @param params.on - the target solid on which the face lives.type:Shape required:true
|
|
123
|
-
* @param params.face - the host face:
|
|
126
|
+
* @param params.face - the host face: FaceTopoRef(UI 拾取产物字面量)| 面选择器字符串(如 ">Z",在 on 上解析,多面命中抛错)| 1 起序号(仅网格链/当前内核快照,禁止用于生成脚本)。type:any required:true
|
|
124
127
|
* @param params.scaleMode - UV mapping: 'original' (identity) | 'bounds'/'native' (affine-fit; OCCT planar only).type:string required:false
|
|
125
128
|
* @param params.as - `'face'` (default) or `'wire'` (outer loop only).type:string required:false
|
|
129
|
+
* @example
|
|
130
|
+
* // loop = 一个闭合 2D 轮廓:{ segments: [{ kind: 'line', x1, y1, x2, y2 }, ...] }
|
|
131
|
+
* const face = cad.sketchOnFace({ contours: [loop], on: cad.box(20, 20, 10), face: '>Z' })
|
|
126
132
|
*/
|
|
127
133
|
export declare const sketchOnFace: ((params: Record<string, unknown>) => Promise<Shape>) & {
|
|
128
134
|
__faijs__dualOp?: import("../define-op.js").DualOpMeta;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sketch-on-face.d.ts","sourceRoot":"","sources":["../../src/api/sketch-on-face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAMtD,OAAO,EAAgC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"sketch-on-face.d.ts","sourceRoot":"","sources":["../../src/api/sketch-on-face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAMtD,OAAO,EAAgC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAMnF,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAGxF,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAStF;;+DAE+D;AAC/D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAA;AAExD,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,sFAAsF;IACtF,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,qDAAqD;IACrD,EAAE,EAAE,KAAK,CAAA;IACT,8LAA8L;IAC9L,IAAI,EAAE,YAAY,CAAA;IAClB,8GAA8G;IAC9G,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,gHAAgH;IAChH,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,GAAG,UAAU,CA+CtG;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAKpG;AA6BD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,kBAAkB,GAAG,KAAK,CA+C9F;AAoCD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,KAAK,CAwDvE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,YAAY;;CAavB,CAAA"}
|