@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,656 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* project — single-point conversion between the canonical sketch model and the
|
|
3
|
+
* two downstream projection dialects (§4.5).
|
|
4
|
+
*
|
|
5
|
+
* canonical ⇄ FCStd (`fcstd-types`, integer ConstraintType + PointPos)
|
|
6
|
+
* canonical ⇄ CadQuery (tag + string constraint names, 0..1 positions)
|
|
7
|
+
*
|
|
8
|
+
* One implementation, two projections: the FCStd side feeds the planegcs solve
|
|
9
|
+
* pipeline; the CadQuery side feeds `cq-compat-sketch`. Constraints with no
|
|
10
|
+
* counterpart in a target dialect raise an explicit `E_SKETCHC_*` — never a
|
|
11
|
+
* silent downgrade.
|
|
12
|
+
*/
|
|
13
|
+
import { PointPos, GeoId, CONSTRAINT_NAMES, ConstraintType } from './fcstd-types.js';
|
|
14
|
+
import { evalBSpline } from './bspline.js';
|
|
15
|
+
/** Projection error with a stable `E_SKETCHC_*` code. */
|
|
16
|
+
export class SketchProjectionError extends Error {
|
|
17
|
+
code;
|
|
18
|
+
constructor(code, message) {
|
|
19
|
+
super(`${code}: ${message}`);
|
|
20
|
+
this.code = code;
|
|
21
|
+
this.name = 'SketchProjectionError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// ── at / Ref resolution ──
|
|
25
|
+
/**
|
|
26
|
+
* Map a canonical `At` to an FCStd `PointPos`. Throws `E_SKETCHC_UNMAPPED` when there is no counterpart.
|
|
27
|
+
*
|
|
28
|
+
* @param at - the canonical position.
|
|
29
|
+
* @returns the FCStd `PointPos` integer.
|
|
30
|
+
*/
|
|
31
|
+
export function atToFreeCad(at) {
|
|
32
|
+
if (at === undefined)
|
|
33
|
+
return PointPos.none;
|
|
34
|
+
if (at === 'start')
|
|
35
|
+
return PointPos.start;
|
|
36
|
+
if (at === 'end')
|
|
37
|
+
return PointPos.end;
|
|
38
|
+
if (at === 'center')
|
|
39
|
+
return PointPos.mid;
|
|
40
|
+
if (at === 'mid') {
|
|
41
|
+
throw new SketchProjectionError('E_SKETCHC_UNMAPPED', 'at "mid" (arc/line midpoint) has no FCStd PointPos');
|
|
42
|
+
}
|
|
43
|
+
if (typeof at === 'number') {
|
|
44
|
+
if (at === 0)
|
|
45
|
+
return PointPos.start;
|
|
46
|
+
if (at === 1)
|
|
47
|
+
return PointPos.end;
|
|
48
|
+
throw new SketchProjectionError('E_SKETCHC_UNMAPPED', `parametric at ${at} has no FCStd PointPos`);
|
|
49
|
+
}
|
|
50
|
+
throw new SketchProjectionError('E_SKETCHC_UNMAPPED', `unsupported at ${String(at)}`);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Map an FCStd `PointPos` to a canonical `At` (`mid` FCStd means the centre).
|
|
54
|
+
*
|
|
55
|
+
* @param pos - the FCStd `PointPos` integer.
|
|
56
|
+
* @returns the canonical position, or `undefined` for `none`.
|
|
57
|
+
*/
|
|
58
|
+
export function atFromFreeCad(pos) {
|
|
59
|
+
switch (pos) {
|
|
60
|
+
case PointPos.none: return undefined;
|
|
61
|
+
case PointPos.start: return 'start';
|
|
62
|
+
case PointPos.end: return 'end';
|
|
63
|
+
case PointPos.mid: return 'center';
|
|
64
|
+
default: return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Map a canonical `At` to a CadQuery 0..1 parameter (`null` = the arc-centre `None` argument).
|
|
69
|
+
*
|
|
70
|
+
* @param at - the canonical position.
|
|
71
|
+
* @returns the CadQuery 0..1 parameter, or `null` for centre.
|
|
72
|
+
*/
|
|
73
|
+
export function atToCadQuery(at) {
|
|
74
|
+
if (at === undefined)
|
|
75
|
+
return null;
|
|
76
|
+
if (at === 'start')
|
|
77
|
+
return 0;
|
|
78
|
+
if (at === 'end')
|
|
79
|
+
return 1;
|
|
80
|
+
if (at === 'mid')
|
|
81
|
+
return 0.5;
|
|
82
|
+
if (at === 'center')
|
|
83
|
+
return null;
|
|
84
|
+
return at;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Map a CadQuery 0..1 parameter to a canonical `At`.
|
|
88
|
+
*
|
|
89
|
+
* @param v - the CadQuery parameter, or `null`/`undefined` for centre.
|
|
90
|
+
* @returns the canonical position, or `undefined` for `null`/`undefined`.
|
|
91
|
+
*/
|
|
92
|
+
export function atFromCadQuery(v) {
|
|
93
|
+
if (v === null || v === undefined)
|
|
94
|
+
return undefined;
|
|
95
|
+
if (v === 0)
|
|
96
|
+
return 'start';
|
|
97
|
+
if (v === 1)
|
|
98
|
+
return 'end';
|
|
99
|
+
if (v === 0.5)
|
|
100
|
+
return 'mid';
|
|
101
|
+
return v;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Build the tag → index lookup for a geometry list in one pass.
|
|
105
|
+
*
|
|
106
|
+
* @param geoms - canonical geometry list.
|
|
107
|
+
* @returns tag → geometry index.
|
|
108
|
+
*/
|
|
109
|
+
export function buildTagIndex(geoms) {
|
|
110
|
+
const index = new Map();
|
|
111
|
+
geoms.forEach((g, i) => {
|
|
112
|
+
if (g.tag !== undefined)
|
|
113
|
+
index.set(g.tag, i);
|
|
114
|
+
});
|
|
115
|
+
return index;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolve a canonical `Ref` to an FCStd `(geoId, pos)` pair.
|
|
119
|
+
*
|
|
120
|
+
* @param ref - the canonical reference (tag or index + at).
|
|
121
|
+
* @param tagIndex - tag → index map (from {@link buildTagIndex}).
|
|
122
|
+
* @param geoms - the geometry array (for bounds checking of index refs).
|
|
123
|
+
* @returns the FCStd `(geoId, pos)` pair.
|
|
124
|
+
* @throws SketchProjectionError `E_SKETCHC_BAD_REF` for unknown tag or out-of-range index.
|
|
125
|
+
*/
|
|
126
|
+
export function refToFreeCad(ref, tagIndex, geoms) {
|
|
127
|
+
let geoId;
|
|
128
|
+
if ('tag' in ref) {
|
|
129
|
+
const found = tagIndex.get(ref.tag);
|
|
130
|
+
if (found === undefined) {
|
|
131
|
+
throw new SketchProjectionError('E_SKETCHC_BAD_REF', `unknown tag "${ref.tag}"`);
|
|
132
|
+
}
|
|
133
|
+
geoId = found;
|
|
134
|
+
}
|
|
135
|
+
else if (ref.index === -1 || ref.index === -2) {
|
|
136
|
+
// AXIS ANCHORS (IRON RULE patch, 2026-10-04): canonical Refs may carry the
|
|
137
|
+
// X axis (-1) / Y axis (-2) verbatim so FCStd axis refs round-trip through
|
|
138
|
+
// canonical. The planegcs backend resolves them (`pt()`: -1 → root point,
|
|
139
|
+
// -2 → VAxis point); anything else negative stays invalid.
|
|
140
|
+
geoId = ref.index;
|
|
141
|
+
}
|
|
142
|
+
else if (ref.index <= -3 && ref.index > -2000) {
|
|
143
|
+
// EXTERNAL ANCHORS (IRON RULE patch, 2026-10-04): canonical Refs may carry
|
|
144
|
+
// the external-geometry geoId verbatim; the emitted `cad.sketch` carries
|
|
145
|
+
// the resolved fixed polylines as its `external` param and the backend
|
|
146
|
+
// (`pt()` + `externalLines`) resolves every ref statically.
|
|
147
|
+
geoId = ref.index;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
if (!Number.isInteger(ref.index) || ref.index < 0 || ref.index >= geoms.length) {
|
|
151
|
+
throw new SketchProjectionError('E_SKETCHC_BAD_REF', `index ${ref.index} out of range [0, ${geoms.length})`);
|
|
152
|
+
}
|
|
153
|
+
geoId = ref.index;
|
|
154
|
+
}
|
|
155
|
+
return { geoId, pos: atToFreeCad(ref.at) };
|
|
156
|
+
}
|
|
157
|
+
// ── geometry projection ──
|
|
158
|
+
/**
|
|
159
|
+
* Spread the `construction` flag when present so reference geometry round-trips
|
|
160
|
+
* through the FCStd projection (canonical ⇄ FCStd). Returns an empty object when
|
|
161
|
+
* the flag is absent, so spreading is a no-op for ordinary geometry.
|
|
162
|
+
*/
|
|
163
|
+
function con(g) {
|
|
164
|
+
return g.construction ? { construction: true } : {};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Project canonical geometry to the FCStd shape consumed by the solver.
|
|
168
|
+
*
|
|
169
|
+
* @param geoms - canonical geometry.
|
|
170
|
+
* @returns FCStd geometry records (same order/index).
|
|
171
|
+
* @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_GEOM` for reserved kinds.
|
|
172
|
+
*/
|
|
173
|
+
export function toFreeCadGeoms(geoms) {
|
|
174
|
+
return geoms.map((g, index) => {
|
|
175
|
+
switch (g.kind) {
|
|
176
|
+
case 'line':
|
|
177
|
+
return { kind: 'line', index, x1: g.x1, y1: g.y1, z1: 0, x2: g.x2, y2: g.y2, z2: 0, ...con(g) };
|
|
178
|
+
case 'circle':
|
|
179
|
+
return { kind: 'circle', index, cx: g.cx, cy: g.cy, cz: 0, radius: g.r, ...con(g) };
|
|
180
|
+
case 'arc': {
|
|
181
|
+
// Pass the canonical signed span (a0, a1) through unchanged. planegcs builds
|
|
182
|
+
// the arc from the pinned start/end endpoints *and* the signed start/end
|
|
183
|
+
// angles, so a CW arc (a1 < a0) is drawn as the short clockwise arc.
|
|
184
|
+
// Normalising a1 into a CCW span would instead produce the long arc through
|
|
185
|
+
// those same endpoints. Arc orientation is carried back to the caller via
|
|
186
|
+
// solveSketch (input ccw preserved), not recovered here.
|
|
187
|
+
const a0 = g.a0;
|
|
188
|
+
const a1 = g.a1;
|
|
189
|
+
return {
|
|
190
|
+
kind: 'arc', index, cx: g.cx, cy: g.cy, cz: 0, radius: g.r,
|
|
191
|
+
startAngle: a0, endAngle: a1,
|
|
192
|
+
x1: g.cx + g.r * Math.cos(a0), y1: g.cy + g.r * Math.sin(a0), z1: 0,
|
|
193
|
+
x2: g.cx + g.r * Math.cos(a1), y2: g.cy + g.r * Math.sin(a1), z2: 0,
|
|
194
|
+
...con(g),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
case 'point':
|
|
198
|
+
// Reopened 2026-09-28: planegcs-backend pushes standalone points and
|
|
199
|
+
// pulls them back; contour extraction skips them (no profile use).
|
|
200
|
+
return { kind: 'point', index, x: g.x, y: g.y, z: 0, ...con(g) };
|
|
201
|
+
case 'bspline': {
|
|
202
|
+
// Reopened 2026-09-29 (fcstd-port A2): the entry used to reject this
|
|
203
|
+
// with E_SKETCHC_UNSUPPORTED_GEOM even though the whole downstream
|
|
204
|
+
// chain already consumed it — planegcs-backend.ts:233 pushes the exact
|
|
205
|
+
// endpoints as a line proxy (so coincident/dimension constraints on the
|
|
206
|
+
// curve ends still solve), planegcs-backend.ts:700 pulls them back,
|
|
207
|
+
// contour.ts:57 de Boor-samples the interior, and verify.ts:30 anchors
|
|
208
|
+
// on the endpoints. Rejecting here was entry-schema narrowness, not a
|
|
209
|
+
// solver capability gap.
|
|
210
|
+
//
|
|
211
|
+
// Endpoints are evaluated at the clamped domain ends rather than read
|
|
212
|
+
// off poles[0]/poles[last]: a periodic or non-clamped knot vector has
|
|
213
|
+
// poles that are NOT on the curve, and evalBSpline already clamps its
|
|
214
|
+
// argument into [knots[degree], knots[n]] (bspline.ts:39-40).
|
|
215
|
+
const d = { poles: g.poles, knots: g.knots, degree: g.degree, periodic: g.periodic ?? false };
|
|
216
|
+
const lo = d.knots[d.degree] ?? 0;
|
|
217
|
+
const hi = d.knots[d.knots.length - d.degree - 1] ?? lo;
|
|
218
|
+
const s = d.poles.length > 0 ? evalBSpline(d, lo) : { x: 0, y: 0 };
|
|
219
|
+
const e = d.poles.length > 0 ? evalBSpline(d, hi) : { x: 0, y: 0 };
|
|
220
|
+
return {
|
|
221
|
+
kind: 'bspline', index,
|
|
222
|
+
poles: g.poles, knots: g.knots, degree: g.degree, periodic: d.periodic,
|
|
223
|
+
x1: s.x, y1: s.y, z1: 0, x2: e.x, y2: e.y, z2: 0,
|
|
224
|
+
...con(g),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
case 'ellipse': {
|
|
228
|
+
// rx/ry ARE the major/minor radii (fromFreeCadGeoms maps them back
|
|
229
|
+
// positionally), `angle` is the major-axis rotation in radians — the
|
|
230
|
+
// same unit contour.ts and planegcs consume for angleXU.
|
|
231
|
+
const major = g.rx;
|
|
232
|
+
const minor = g.ry;
|
|
233
|
+
const angleXU = g.angle ?? 0;
|
|
234
|
+
// first focus pair (computed, mirroring FreeCAD's stored foci)
|
|
235
|
+
const c = Math.sqrt(Math.max(major * major - minor * minor, 0));
|
|
236
|
+
const ca = Math.cos(angleXU);
|
|
237
|
+
const sa = Math.sin(angleXU);
|
|
238
|
+
return {
|
|
239
|
+
kind: 'ellipse', index,
|
|
240
|
+
cx: g.cx, cy: g.cy, cz: 0,
|
|
241
|
+
majorRadius: major, minorRadius: minor, angleXU,
|
|
242
|
+
fx1: g.cx - c * ca, fy1: g.cy - c * sa,
|
|
243
|
+
fx2: g.cx + c * ca, fy2: g.cy + c * sa,
|
|
244
|
+
...con(g),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Project FCStd geometry back to the canonical model (reserved kinds are reported).
|
|
252
|
+
*
|
|
253
|
+
* @param geoms - FCStd geometry records from the solver.
|
|
254
|
+
* @returns canonical geometry (same order/index).
|
|
255
|
+
*/
|
|
256
|
+
export function fromFreeCadGeoms(geoms) {
|
|
257
|
+
return geoms.map((g) => {
|
|
258
|
+
switch (g.kind) {
|
|
259
|
+
case 'line':
|
|
260
|
+
return { kind: 'line', x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2, ...con(g) };
|
|
261
|
+
case 'circle':
|
|
262
|
+
return { kind: 'circle', cx: g.cx, cy: g.cy, r: g.radius, ...con(g) };
|
|
263
|
+
case 'arc': {
|
|
264
|
+
const ccw = normalizeArcCcw(g.startAngle, g.endAngle);
|
|
265
|
+
return { kind: 'arc', cx: g.cx, cy: g.cy, r: g.radius, a0: g.startAngle, a1: g.endAngle, ccw, ...con(g) };
|
|
266
|
+
}
|
|
267
|
+
case 'point':
|
|
268
|
+
return { kind: 'point', x: g.x, y: g.y, ...con(g) };
|
|
269
|
+
case 'ellipse':
|
|
270
|
+
return { kind: 'ellipse', cx: g.cx, cy: g.cy, rx: g.majorRadius, ry: g.minorRadius, angle: g.angleXU, ...con(g) };
|
|
271
|
+
case 'bspline':
|
|
272
|
+
return { kind: 'bspline', poles: g.poles, knots: g.knots, degree: g.degree, periodic: g.periodic, ...con(g) };
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/** True when the arc span is counter-clockwise as stored. */
|
|
277
|
+
function normalizeArcCcw(startAngle, endAngle) {
|
|
278
|
+
let sweep = endAngle - startAngle;
|
|
279
|
+
while (sweep <= 0)
|
|
280
|
+
sweep += 2 * Math.PI;
|
|
281
|
+
while (sweep > 2 * Math.PI)
|
|
282
|
+
sweep -= 2 * Math.PI;
|
|
283
|
+
return sweep > 0;
|
|
284
|
+
}
|
|
285
|
+
function mapConstraint(c, tagIndex, geoms) {
|
|
286
|
+
const ref = (r) => refToFreeCad(r, tagIndex, geoms);
|
|
287
|
+
switch (c.kind) {
|
|
288
|
+
case 'fixed':
|
|
289
|
+
// FCStd has no explicit fixed constraint — the implicit fixed frame
|
|
290
|
+
// (RtPnt + H/V axes) absorbs the rigid-body DoF (§4.5).
|
|
291
|
+
return 'noop';
|
|
292
|
+
case 'coincident':
|
|
293
|
+
return { type: ConstraintType.Coincident, refs: [ref(c.a), ref(c.b)] };
|
|
294
|
+
case 'horizontal':
|
|
295
|
+
return { type: ConstraintType.Horizontal, refs: [ref(c.of)] };
|
|
296
|
+
case 'vertical':
|
|
297
|
+
return { type: ConstraintType.Vertical, refs: [ref(c.of)] };
|
|
298
|
+
case 'parallel':
|
|
299
|
+
return { type: ConstraintType.Parallel, refs: [ref(c.a), ref(c.b)] };
|
|
300
|
+
case 'perpendicular':
|
|
301
|
+
return { type: ConstraintType.Perpendicular, refs: [ref(c.a), ref(c.b)] };
|
|
302
|
+
case 'tangent':
|
|
303
|
+
return { type: ConstraintType.Tangent, refs: [ref(c.a), ref(c.b)] };
|
|
304
|
+
case 'distance':
|
|
305
|
+
return { type: ConstraintType.Distance, refs: [ref(c.a), ref(c.b)], value: c.value };
|
|
306
|
+
case 'distanceX':
|
|
307
|
+
return { type: ConstraintType.DistanceX, refs: [ref(c.a), ref(c.b)], value: c.value };
|
|
308
|
+
case 'distanceY':
|
|
309
|
+
return { type: ConstraintType.DistanceY, refs: [ref(c.a), ref(c.b)], value: c.value };
|
|
310
|
+
case 'length': {
|
|
311
|
+
// Length is expressed as a point-to-point Distance over the element ends.
|
|
312
|
+
const base = ref(c.of);
|
|
313
|
+
const start = { geoId: base.geoId, pos: PointPos.start };
|
|
314
|
+
const end = { geoId: base.geoId, pos: PointPos.end };
|
|
315
|
+
return { type: ConstraintType.Distance, refs: [start, end], value: c.value };
|
|
316
|
+
}
|
|
317
|
+
case 'angle':
|
|
318
|
+
return { type: ConstraintType.Angle, refs: [ref(c.a), ref(c.b)], value: c.value };
|
|
319
|
+
case 'orientation':
|
|
320
|
+
// Reverse of the 1-ref Angle projection: emit a single-reference FCStd
|
|
321
|
+
// Angle (absolute line orientation, radians). The planegcs backend lowers a
|
|
322
|
+
// 1-ref Angle to `p2p_angle` on the line's own endpoints.
|
|
323
|
+
return { type: ConstraintType.Angle, refs: [ref(c.of)], value: Math.atan2(c.dir[1], c.dir[0]) };
|
|
324
|
+
case 'radius':
|
|
325
|
+
return { type: ConstraintType.Radius, refs: [ref(c.of)], value: c.value };
|
|
326
|
+
case 'diameter':
|
|
327
|
+
return { type: ConstraintType.Diameter, refs: [ref(c.of)], value: c.value };
|
|
328
|
+
case 'arcAngle':
|
|
329
|
+
throw new SketchProjectionError('E_SKETCHC_UNMAPPED', 'constraint "arcAngle" has no FCStd counterpart');
|
|
330
|
+
case 'equal':
|
|
331
|
+
return { type: ConstraintType.Equal, refs: [ref(c.a), ref(c.b)] };
|
|
332
|
+
case 'pointOnObject':
|
|
333
|
+
return { type: ConstraintType.PointOnObject, refs: [ref(c.p), ref(c.on)] };
|
|
334
|
+
case 'symmetric':
|
|
335
|
+
return { type: ConstraintType.Symmetric, refs: [ref(c.p1), ref(c.p2), ref(c.about)] };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Project canonical constraints to the FCStd shape the solver consumes.
|
|
340
|
+
*
|
|
341
|
+
* @param constraints - canonical constraints.
|
|
342
|
+
* @param geoms - canonical geometry (for tag/index resolution).
|
|
343
|
+
* @returns FCStd constraints plus the no-op (`fixed`) indices.
|
|
344
|
+
*/
|
|
345
|
+
export function toFreeCadConstraints(constraints, geoms) {
|
|
346
|
+
const tagIndex = buildTagIndex(geoms);
|
|
347
|
+
const out = [];
|
|
348
|
+
const noops = [];
|
|
349
|
+
constraints.forEach((c, index) => {
|
|
350
|
+
const mapped = mapConstraint(c, tagIndex, geoms);
|
|
351
|
+
if (mapped === 'noop') {
|
|
352
|
+
noops.push(index);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
out.push({ index, type: mapped.type, refs: mapped.refs, value: mapped.value ?? 0, isDriving: true, name: '' });
|
|
356
|
+
});
|
|
357
|
+
return { constraints: out, noops };
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Minimum number of refs each FCStd constraint type must carry before
|
|
361
|
+
* {@link fromFreeCadConstraints} can express it.
|
|
362
|
+
*
|
|
363
|
+
* GOTCHA (2026-09-28, `Bathroom_cabinet_sink.FCStd` Sketch259): FreeCAD stores
|
|
364
|
+
* an implicit axis/origin as GeoUndef, so a "vertical distance from the X axis"
|
|
365
|
+
* arrives as a **1-ref** `DistanceY`. `two()`/`ref()` then dereferenced the
|
|
366
|
+
* absent second ref and threw `Cannot read properties of undefined (reading
|
|
367
|
+
* 'pos')`, which the converter reports as `solver-throw` and which failed
|
|
368
|
+
* 436/900 corpus files. Only types the projection switch actually handles are
|
|
369
|
+
* listed here: anything absent (InternalAlignment, Block, Weight …) keeps
|
|
370
|
+
* flowing to the `default:` branch and is still reported as `unsupported-type`.
|
|
371
|
+
*/
|
|
372
|
+
const REFS_REQUIRED = {
|
|
373
|
+
[ConstraintType.Horizontal]: 1,
|
|
374
|
+
[ConstraintType.Vertical]: 1,
|
|
375
|
+
[ConstraintType.Distance]: 1, // 1-ref Distance is a length (see the case below)
|
|
376
|
+
[ConstraintType.Angle]: 1, // the case below flags a 1-ref Angle as ambiguous
|
|
377
|
+
[ConstraintType.Radius]: 1,
|
|
378
|
+
[ConstraintType.Diameter]: 1,
|
|
379
|
+
[ConstraintType.Coincident]: 2,
|
|
380
|
+
[ConstraintType.Parallel]: 2,
|
|
381
|
+
[ConstraintType.Tangent]: 2,
|
|
382
|
+
[ConstraintType.DistanceX]: 1,
|
|
383
|
+
[ConstraintType.DistanceY]: 1,
|
|
384
|
+
[ConstraintType.Perpendicular]: 2,
|
|
385
|
+
[ConstraintType.Equal]: 2,
|
|
386
|
+
[ConstraintType.PointOnObject]: 2,
|
|
387
|
+
[ConstraintType.Symmetric]: 3,
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* Project FCStd sketch constraints back to the canonical model — the reverse of
|
|
391
|
+
* {@link toFreeCadConstraints} / `mapConstraint`. This is the bridge the fcstd
|
|
392
|
+
* converter uses to emit `cad.sketch({ geoms, constraints })` from a parsed
|
|
393
|
+
* `Sketcher::SketchObject` (2026-09-28 plan A1).
|
|
394
|
+
*
|
|
395
|
+
* Mapping notes / GOTCHAs (validated against `mapConstraint` + the planegcs
|
|
396
|
+
* backend):
|
|
397
|
+
* - `length` is stored FCStd-side as a point-to-point Distance over the line's
|
|
398
|
+
* own start/end — a 1-ref Distance projects back to `length` (GOTCHA: a
|
|
399
|
+
* genuine 2-ref Distance between two distinct points is NOT a length).
|
|
400
|
+
* - `fixed` has no FCStd counterpart (the implicit frame absorbs it), so it can
|
|
401
|
+
* never appear in FCStd input — nothing to project back.
|
|
402
|
+
* - Angle values pass through UNCHANGED in both directions: FreeCAD serializes
|
|
403
|
+
* Angle constraint `Value` in radians in the XML, and the planegcs backend
|
|
404
|
+
* forwards it verbatim. Consumers wanting canonical degrees must convert at
|
|
405
|
+
* the boundary that knows the file unit (GOTCHA 2026-09-28: forward
|
|
406
|
+
* projection also passes through, so roundtrips are unit-consistent).
|
|
407
|
+
* - Constraints referencing the axes (geoId -1/-2) or external geometry
|
|
408
|
+
* (geoId <= -3) have no canonical Ref (canonical refs are own-geometry
|
|
409
|
+
* indices only) — reported in `unmapped` with reason
|
|
410
|
+
* `external-or-axis-ref` instead of being silently dropped.
|
|
411
|
+
* - `isDriving === false` (reference/driven) constraints carry no solve
|
|
412
|
+
* information — reported with reason `reference-driven`.
|
|
413
|
+
* - A constraint with fewer refs than its type requires (e.g. a 1-ref
|
|
414
|
+
* `DistanceY`, which FreeCAD writes when the axis is implicit) is reported
|
|
415
|
+
* with reason `ambiguous-refs`; see `REFS_REQUIRED`. This projection never
|
|
416
|
+
* throws on such input.
|
|
417
|
+
*
|
|
418
|
+
* @param cons - FCStd constraints (e.g. from `parseSketchObject`).
|
|
419
|
+
* @param _geoms - unused; kept for signature symmetry with the projection pipeline.
|
|
420
|
+
* @returns canonical constraints plus the unmapped ledger.
|
|
421
|
+
*/
|
|
422
|
+
export function fromFreeCadConstraints(cons, _geoms) {
|
|
423
|
+
const ref = (r) => {
|
|
424
|
+
const at = atFromFreeCad(r.pos);
|
|
425
|
+
return (at === undefined ? { index: r.geoId } : { index: r.geoId, at });
|
|
426
|
+
};
|
|
427
|
+
const constraints = [];
|
|
428
|
+
const unmapped = [];
|
|
429
|
+
const pushUnmapped = (index, type, reason) => {
|
|
430
|
+
unmapped.push({ index, type, typeName: CONSTRAINT_NAMES[type] ?? `type#${type}`, reason });
|
|
431
|
+
};
|
|
432
|
+
cons.forEach((c, index) => {
|
|
433
|
+
if (!c.isDriving) {
|
|
434
|
+
// Reference/driven constraint carries no solve information — canonical has
|
|
435
|
+
// no field for it. Drop it silently instead of reporting a gap.
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
// External geometry refs (geoId <= -3, down to just above GeoUndef) ride
|
|
439
|
+
// into canonical as negative Ref indices verbatim — the converter resolves
|
|
440
|
+
// the referenced external geometry to fixed polylines at convert time and
|
|
441
|
+
// the emitted `cad.sketch` carries them as its `external` param, so the
|
|
442
|
+
// planegcs backend (`pt()` + `externalLines`) resolves every ref
|
|
443
|
+
// statically (IRON RULE patch, 2026-10-04: no run-time attempt — a ref the
|
|
444
|
+
// converter could NOT resolve never enters sketchInputs).
|
|
445
|
+
// GOTCHA (2026-10-04, taperedballnose): old-format constraint triples pad
|
|
446
|
+
// unused slots with GeoUndef = -2000 (sketch-parse.ts skips them when
|
|
447
|
+
// building externalGeoIds for the same reason) — a real axis/external ref
|
|
448
|
+
// never reaches -2000. The old `geoId < 0` blanket check here used to
|
|
449
|
+
// reject ~every constraint in such files (20 of 21 in the sample) as
|
|
450
|
+
// `external-or-axis-ref`, mass-gapping otherwise-clean sketches.
|
|
451
|
+
// Ref-count guard (see REFS_REQUIRED) — runs BEFORE any ref dereference so
|
|
452
|
+
// an under-specified constraint is recorded rather than thrown out of the
|
|
453
|
+
// whole projection. Types the switch does not handle (InternalAlignment,
|
|
454
|
+
// Block, Weight …) are absent from the map and stay on the `default:` path,
|
|
455
|
+
// so they keep reporting `unsupported-type`.
|
|
456
|
+
const required = REFS_REQUIRED[c.type];
|
|
457
|
+
if (required !== undefined && c.refs.length < required) {
|
|
458
|
+
pushUnmapped(index, c.type, 'ambiguous-refs');
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const two = () => [ref(c.refs[0]), ref(c.refs[1])];
|
|
462
|
+
switch (c.type) {
|
|
463
|
+
case ConstraintType.Coincident: {
|
|
464
|
+
const [a, b] = two();
|
|
465
|
+
constraints.push({ kind: 'coincident', a, b });
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
case ConstraintType.Horizontal:
|
|
469
|
+
// GOTCHA (IRON RULE patch, 2026-10-04, Chair Sketch255): FreeCAD's
|
|
470
|
+
// Horizontal has a TWO-POINT form (refs[1] may be an external point):
|
|
471
|
+
// "these two points are level". The canonical `horizontal` kind only
|
|
472
|
+
// takes one line ref — projecting the 2-ref form to it SILENTLY DROPPED
|
|
473
|
+
// the second point and changed the constraint set (solver DoF mismatch
|
|
474
|
+
// → E_SKETCHC_CONFLICTING at run time). Static equivalent instead:
|
|
475
|
+
// two points level ⟺ distanceY(a, b, 0).
|
|
476
|
+
if (c.refs.length >= 2 && c.refs[1].pos !== PointPos.none && c.refs[1].geoId !== c.refs[0].geoId) {
|
|
477
|
+
constraints.push({ kind: 'distanceY', a: ref(c.refs[0]), b: ref(c.refs[1]), value: 0 });
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
constraints.push({ kind: 'horizontal', of: ref(c.refs[0]) });
|
|
481
|
+
}
|
|
482
|
+
break;
|
|
483
|
+
case ConstraintType.Vertical:
|
|
484
|
+
// symmetric case to Horizontal: two points aligned ⟺ distanceX(a, b, 0)
|
|
485
|
+
if (c.refs.length >= 2 && c.refs[1].pos !== PointPos.none && c.refs[1].geoId !== c.refs[0].geoId) {
|
|
486
|
+
constraints.push({ kind: 'distanceX', a: ref(c.refs[0]), b: ref(c.refs[1]), value: 0 });
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
constraints.push({ kind: 'vertical', of: ref(c.refs[0]) });
|
|
490
|
+
}
|
|
491
|
+
break;
|
|
492
|
+
case ConstraintType.Parallel: {
|
|
493
|
+
const [a, b] = two();
|
|
494
|
+
constraints.push({ kind: 'parallel', a, b });
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
case ConstraintType.Perpendicular: {
|
|
498
|
+
const [a, b] = two();
|
|
499
|
+
constraints.push({ kind: 'perpendicular', a, b });
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
case ConstraintType.Tangent: {
|
|
503
|
+
const [a, b] = two();
|
|
504
|
+
constraints.push({ kind: 'tangent', a, b });
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
case ConstraintType.Distance:
|
|
508
|
+
if (c.refs.length >= 2 &&
|
|
509
|
+
// GOTCHA: mapConstraint encodes canonical `length` as a Distance over
|
|
510
|
+
// the SAME geometry's start/end points — a same-geoId start/end pair
|
|
511
|
+
// is a length, not a genuine point-to-point distance.
|
|
512
|
+
!(c.refs[0].geoId === c.refs[1].geoId && c.refs[0].pos === PointPos.start && c.refs[1].pos === PointPos.end)) {
|
|
513
|
+
const [a, b] = two();
|
|
514
|
+
constraints.push({ kind: 'distance', a, b, value: c.value });
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
// point-to-point Distance over one element's own ends = length
|
|
518
|
+
// (canonical `length` refs the whole element, no `at`)
|
|
519
|
+
constraints.push({ kind: 'length', of: { index: c.refs[0].geoId }, value: c.value });
|
|
520
|
+
}
|
|
521
|
+
break;
|
|
522
|
+
case ConstraintType.DistanceX: {
|
|
523
|
+
if (c.refs.length >= 2) {
|
|
524
|
+
const [a, b] = two();
|
|
525
|
+
constraints.push({ kind: 'distanceX', a, b, value: c.value });
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
// 1-ref DistanceX = absolute X coordinate of the point/line w.r.t. the
|
|
529
|
+
// Y-axis (VAxis, geoId -2). The planegcs backend special-cases an
|
|
530
|
+
// axis-edge second ref as `coordinate_x` (absolute, not a difference),
|
|
531
|
+
// matching FreeCAD's single-reference DistanceX semantics.
|
|
532
|
+
constraints.push({ kind: 'distanceX', a: ref(c.refs[0]), b: { index: GeoId.VAxis }, value: c.value });
|
|
533
|
+
}
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
case ConstraintType.DistanceY: {
|
|
537
|
+
if (c.refs.length >= 2) {
|
|
538
|
+
const [a, b] = two();
|
|
539
|
+
constraints.push({ kind: 'distanceY', a, b, value: c.value });
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
// 1-ref DistanceY = absolute Y coordinate w.r.t. the X-axis (HAxis=-1).
|
|
543
|
+
constraints.push({ kind: 'distanceY', a: ref(c.refs[0]), b: { index: GeoId.HAxis }, value: c.value });
|
|
544
|
+
}
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
case ConstraintType.Angle:
|
|
548
|
+
if (c.refs.length >= 2) {
|
|
549
|
+
const [a, b] = two();
|
|
550
|
+
constraints.push({ kind: 'angle', a, b, value: c.value });
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
// 1-ref Angle = absolute orientation of a single line w.r.t. the X-axis.
|
|
554
|
+
// Canonical models this as `orientation` (dir = [cos, sin]); the
|
|
555
|
+
// planegcs backend lowers a 1-ref FCStd Angle to `p2p_angle` on the
|
|
556
|
+
// line's own endpoints, and `mapConstraint` re-emits it as a 1-ref
|
|
557
|
+
// Angle on the reverse path.
|
|
558
|
+
constraints.push({ kind: 'orientation', of: ref(c.refs[0]), dir: [Math.cos(c.value), Math.sin(c.value)] });
|
|
559
|
+
}
|
|
560
|
+
break;
|
|
561
|
+
case ConstraintType.Radius:
|
|
562
|
+
constraints.push({ kind: 'radius', of: ref(c.refs[0]), value: c.value });
|
|
563
|
+
break;
|
|
564
|
+
case ConstraintType.Diameter:
|
|
565
|
+
constraints.push({ kind: 'diameter', of: ref(c.refs[0]), value: c.value });
|
|
566
|
+
break;
|
|
567
|
+
case ConstraintType.Equal: {
|
|
568
|
+
const [a, b] = two();
|
|
569
|
+
constraints.push({ kind: 'equal', a, b });
|
|
570
|
+
break;
|
|
571
|
+
}
|
|
572
|
+
case ConstraintType.PointOnObject:
|
|
573
|
+
constraints.push({ kind: 'pointOnObject', p: ref(c.refs[0]), on: ref(c.refs[1]) });
|
|
574
|
+
break;
|
|
575
|
+
case ConstraintType.Symmetric:
|
|
576
|
+
constraints.push({
|
|
577
|
+
kind: 'symmetric',
|
|
578
|
+
p1: ref(c.refs[0]),
|
|
579
|
+
p2: ref(c.refs[1]),
|
|
580
|
+
about: ref(c.refs[2]),
|
|
581
|
+
});
|
|
582
|
+
break;
|
|
583
|
+
case ConstraintType.Weight:
|
|
584
|
+
// Weight is a solver soft-penalty hint, not a geometric constraint —
|
|
585
|
+
// canonical has no field for it. Drop it (no gap, no constraint).
|
|
586
|
+
break;
|
|
587
|
+
case ConstraintType.Block: {
|
|
588
|
+
// Block freezes its referenced geometry. Canonical `fixed` is the closest
|
|
589
|
+
// existing kind; `mapConstraint` lowers `fixed` to a no-op because the
|
|
590
|
+
// implicit fixed frame already pins the rigid body.
|
|
591
|
+
for (const r of c.refs)
|
|
592
|
+
constraints.push({ kind: 'fixed', of: ref(r) });
|
|
593
|
+
break;
|
|
594
|
+
}
|
|
595
|
+
default:
|
|
596
|
+
// InternalAlignment / SnellsLaw / Group / Text / …
|
|
597
|
+
pushUnmapped(index, c.type, 'unsupported-type');
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
return { constraints, unmapped };
|
|
601
|
+
}
|
|
602
|
+
// ── CadQuery projection (constraint type names) ──
|
|
603
|
+
/** CadQuery constraint names for the canonical kinds it supports (the other 8). */
|
|
604
|
+
export const CONSTRAINT_KIND_TO_CADQUERY = {
|
|
605
|
+
fixed: 'FixedPoint',
|
|
606
|
+
coincident: 'Coincident',
|
|
607
|
+
angle: 'Angle',
|
|
608
|
+
length: 'Length',
|
|
609
|
+
distance: 'Distance',
|
|
610
|
+
radius: 'Radius',
|
|
611
|
+
orientation: 'Orientation',
|
|
612
|
+
arcAngle: 'ArcAngle',
|
|
613
|
+
};
|
|
614
|
+
/**
|
|
615
|
+
* CadQuery constraint name → canonical kind.
|
|
616
|
+
*
|
|
617
|
+
* Beyond the one-name-per-kind reverse of {@link CONSTRAINT_KIND_TO_CADQUERY},
|
|
618
|
+
* CadQuery spells the fixed constraint **two** ways — `Fixed` (whole entity) and
|
|
619
|
+
* `FixedPoint` (a point) — and both mean canonical `fixed` here. The forward
|
|
620
|
+
* direction emits `FixedPoint`; the reverse direction must accept either, or a
|
|
621
|
+
* caller that reads upstream CadQuery scripts (`s.constrain(f, "Fixed")`) gets
|
|
622
|
+
* `E_SKETCHC_UNSUPPORTED_CONSTRAINT` on a name upstream accepts.
|
|
623
|
+
*/
|
|
624
|
+
export const CADQUERY_TO_CONSTRAINT_KIND = {
|
|
625
|
+
...Object.fromEntries(Object.entries(CONSTRAINT_KIND_TO_CADQUERY).map(([kind, name]) => [name, kind])),
|
|
626
|
+
Fixed: 'fixed',
|
|
627
|
+
};
|
|
628
|
+
/**
|
|
629
|
+
* Map a canonical constraint kind to its CadQuery name.
|
|
630
|
+
*
|
|
631
|
+
* @param kind - canonical constraint kind.
|
|
632
|
+
* @returns the CadQuery constraint name.
|
|
633
|
+
* @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_BY_CQ` when CQ has no counterpart.
|
|
634
|
+
*/
|
|
635
|
+
export function constraintKindToCadQuery(kind) {
|
|
636
|
+
const name = CONSTRAINT_KIND_TO_CADQUERY[kind];
|
|
637
|
+
if (!name) {
|
|
638
|
+
throw new SketchProjectionError('E_SKETCHC_UNSUPPORTED_BY_CQ', `constraint "${kind}" is not supported by CadQuery`);
|
|
639
|
+
}
|
|
640
|
+
return name;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Map a CadQuery constraint name to its canonical kind.
|
|
644
|
+
*
|
|
645
|
+
* @param name - CadQuery constraint name.
|
|
646
|
+
* @returns the canonical kind.
|
|
647
|
+
* @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_CONSTRAINT` for unknown names.
|
|
648
|
+
*/
|
|
649
|
+
export function constraintKindFromCadQuery(name) {
|
|
650
|
+
const kind = CADQUERY_TO_CONSTRAINT_KIND[name];
|
|
651
|
+
if (!kind) {
|
|
652
|
+
throw new SketchProjectionError('E_SKETCHC_UNSUPPORTED_CONSTRAINT', `unknown CadQuery constraint "${name}"`);
|
|
653
|
+
}
|
|
654
|
+
return kind;
|
|
655
|
+
}
|
|
656
|
+
//# sourceMappingURL=project.js.map
|