@faicad/faijs 0.13.1 → 0.14.1
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.map +1 -1
- package/dist/api/api-namespace.js +30 -4
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/boolean.d.ts +19 -0
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +51 -10
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +8 -7
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/compound-geom.d.ts +45 -0
- package/dist/api/compound-geom.d.ts.map +1 -0
- package/dist/api/compound-geom.js +85 -0
- package/dist/api/compound-geom.js.map +1 -0
- package/dist/api/compound.d.ts +2 -0
- package/dist/api/compound.d.ts.map +1 -1
- package/dist/api/compound.js +2 -0
- package/dist/api/compound.js.map +1 -1
- package/dist/api/copy.d.ts +1 -0
- package/dist/api/copy.d.ts.map +1 -1
- package/dist/api/copy.js +4 -2
- package/dist/api/copy.js.map +1 -1
- package/dist/api/edge-ref.d.ts +3 -2
- package/dist/api/edge-ref.d.ts.map +1 -1
- package/dist/api/edge-ref.js +10 -6
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/engrave.d.ts.map +1 -1
- package/dist/api/engrave.js +1 -0
- package/dist/api/engrave.js.map +1 -1
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +131 -3
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts.map +1 -1
- package/dist/api/face-ref.js +7 -4
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/fai_drill.d.ts +1 -1
- package/dist/api/fai_drill.d.ts.map +1 -1
- package/dist/api/fai_drill.js +31 -18
- package/dist/api/fai_drill.js.map +1 -1
- package/dist/api/fai_extrude.d.ts +1 -1
- package/dist/api/fai_extrude.d.ts.map +1 -1
- package/dist/api/fai_extrude.js +2 -1
- package/dist/api/fai_extrude.js.map +1 -1
- package/dist/api/fai_split.d.ts +1 -1
- package/dist/api/fai_split.d.ts.map +1 -1
- package/dist/api/fai_split.js +2 -1
- package/dist/api/fai_split.js.map +1 -1
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +6 -5
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/generated/operations.js +16 -16
- package/dist/api/generated/operations.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.js +0 -1
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/generated/script-face.d.ts +1 -4
- package/dist/api/generated/script-face.d.ts.map +1 -1
- package/dist/api/generated/script-face.js +2 -3
- package/dist/api/generated/script-face.js.map +1 -1
- package/dist/api/generated/sketching.js +1 -1
- package/dist/api/generated/sketching.js.map +1 -1
- package/dist/api/generated/topology.d.ts +0 -48
- package/dist/api/generated/topology.d.ts.map +1 -1
- package/dist/api/generated/topology.js +20 -62
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/import-brep.d.ts +36 -0
- package/dist/api/import-brep.d.ts.map +1 -0
- package/dist/api/import-brep.js +72 -0
- package/dist/api/import-brep.js.map +1 -0
- package/dist/api/import-step.d.ts +28 -0
- package/dist/api/import-step.d.ts.map +1 -0
- package/dist/api/import-step.js +57 -0
- package/dist/api/import-step.js.map +1 -0
- package/dist/api/index.d.ts +7 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +19 -5
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-op.d.ts +2 -0
- package/dist/api/internal/compat-op.d.ts.map +1 -1
- package/dist/api/internal/compat-op.js +10 -2
- package/dist/api/internal/compat-op.js.map +1 -1
- package/dist/api/knurl.d.ts.map +1 -1
- package/dist/api/knurl.js +1 -0
- package/dist/api/knurl.js.map +1 -1
- package/dist/api/load.d.ts +3 -1
- package/dist/api/load.d.ts.map +1 -1
- package/dist/api/load.js +3 -1
- package/dist/api/load.js.map +1 -1
- package/dist/api/pattern.d.ts +32 -0
- package/dist/api/pattern.d.ts.map +1 -0
- package/dist/api/pattern.js +121 -0
- package/dist/api/pattern.js.map +1 -0
- package/dist/api/place.d.ts +35 -0
- package/dist/api/place.d.ts.map +1 -0
- package/dist/api/place.js +113 -0
- package/dist/api/place.js.map +1 -0
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +10 -3
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/screw.d.ts.map +1 -1
- package/dist/api/screw.js +1 -0
- package/dist/api/screw.js.map +1 -1
- package/dist/api/sdf.d.ts.map +1 -1
- package/dist/api/sdf.js +1 -0
- package/dist/api/sdf.js.map +1 -1
- package/dist/api/sketch.d.ts.map +1 -1
- package/dist/api/sketch.js +1 -0
- package/dist/api/sketch.js.map +1 -1
- package/dist/api/split.d.ts +31 -0
- package/dist/api/split.d.ts.map +1 -0
- package/dist/api/split.js +96 -0
- package/dist/api/split.js.map +1 -0
- package/dist/api/surface/arg-spec.d.ts +9 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +49 -30
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/svgExtrude.d.ts.map +1 -1
- package/dist/api/svgExtrude.js +1 -0
- package/dist/api/svgExtrude.js.map +1 -1
- package/dist/api/text.d.ts.map +1 -1
- package/dist/api/text.js +1 -0
- package/dist/api/text.js.map +1 -1
- package/dist/api/topo-resolve.d.ts.map +1 -1
- package/dist/api/topo-resolve.js +65 -3
- package/dist/api/topo-resolve.js.map +1 -1
- package/dist/api/transform.d.ts +4 -0
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +44 -12
- package/dist/api/transform.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +34 -1
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +62 -22
- 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 +8 -0
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brepkit.js +6 -1
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +24 -1
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +17 -0
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/types.d.ts +49 -6
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brep/export/step.d.ts.map +1 -1
- package/dist/brep/export/step.js +6 -1
- package/dist/brep/export/step.js.map +1 -1
- package/dist/brep/face-evolution.d.ts +78 -8
- package/dist/brep/face-evolution.d.ts.map +1 -1
- package/dist/brep/face-evolution.js +130 -17
- package/dist/brep/face-evolution.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +27 -1
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/browser.d.ts +0 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +2 -2
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +19 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +21 -1
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +44 -3
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +46 -3
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.d.ts +2 -0
- package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js +9 -1
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +14 -4
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/module-registry.d.ts +3 -1
- package/dist/cad-runtime/module-registry.d.ts.map +1 -1
- package/dist/cad-runtime/module-registry.js +13 -1
- package/dist/cad-runtime/module-registry.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +7 -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-concurrent-error.d.ts +38 -0
- package/dist/cad-runtime/runtime-concurrent-error.d.ts.map +1 -0
- package/dist/cad-runtime/runtime-concurrent-error.js +43 -0
- package/dist/cad-runtime/runtime-concurrent-error.js.map +1 -0
- package/dist/cad-runtime/runtime.d.ts +54 -2
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +186 -10
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +22 -0
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +82 -12
- package/dist/define-op.js.map +1 -1
- package/dist/fcstd/attachment.d.ts +72 -0
- package/dist/fcstd/attachment.d.ts.map +1 -0
- package/dist/fcstd/attachment.js +93 -0
- package/dist/fcstd/attachment.js.map +1 -0
- package/dist/fcstd/build-fai-zip.d.ts +11 -0
- package/dist/fcstd/build-fai-zip.d.ts.map +1 -1
- package/dist/fcstd/build-fai-zip.js +21 -8
- package/dist/fcstd/build-fai-zip.js.map +1 -1
- package/dist/fcstd/cli.d.ts +3 -0
- package/dist/fcstd/cli.d.ts.map +1 -0
- package/dist/fcstd/cli.js +37 -0
- package/dist/fcstd/cli.js.map +1 -0
- package/dist/fcstd/codegen.d.ts +23 -1
- package/dist/fcstd/codegen.d.ts.map +1 -1
- package/dist/fcstd/codegen.js +159 -48
- package/dist/fcstd/codegen.js.map +1 -1
- package/dist/fcstd/container.d.ts +16 -1
- package/dist/fcstd/container.d.ts.map +1 -1
- package/dist/fcstd/container.js +12 -1
- package/dist/fcstd/container.js.map +1 -1
- package/dist/fcstd/contour.d.ts +9 -1
- package/dist/fcstd/contour.d.ts.map +1 -1
- package/dist/fcstd/contour.js +28 -18
- package/dist/fcstd/contour.js.map +1 -1
- package/dist/fcstd/convert.d.ts +31 -2
- package/dist/fcstd/convert.d.ts.map +1 -1
- package/dist/fcstd/convert.js +73 -22
- package/dist/fcstd/convert.js.map +1 -1
- package/dist/fcstd/document.d.ts +8 -1
- package/dist/fcstd/document.d.ts.map +1 -1
- package/dist/fcstd/document.js +4 -1
- package/dist/fcstd/document.js.map +1 -1
- package/dist/fcstd/expressions.d.ts +14 -1
- package/dist/fcstd/expressions.d.ts.map +1 -1
- package/dist/fcstd/expressions.js +11 -1
- package/dist/fcstd/expressions.js.map +1 -1
- package/dist/fcstd/external-geo.d.ts +27 -2
- package/dist/fcstd/external-geo.d.ts.map +1 -1
- package/dist/fcstd/external-geo.js +23 -2
- package/dist/fcstd/external-geo.js.map +1 -1
- package/dist/fcstd/feature-translate.d.ts +85 -3
- package/dist/fcstd/feature-translate.d.ts.map +1 -1
- package/dist/fcstd/feature-translate.js +189 -9
- package/dist/fcstd/feature-translate.js.map +1 -1
- package/dist/fcstd/index.d.ts +23 -0
- package/dist/fcstd/index.d.ts.map +1 -0
- package/dist/fcstd/index.js +19 -0
- package/dist/fcstd/index.js.map +1 -0
- package/dist/fcstd/placement.d.ts +49 -6
- package/dist/fcstd/placement.d.ts.map +1 -1
- package/dist/fcstd/placement.js +46 -6
- package/dist/fcstd/placement.js.map +1 -1
- package/dist/fcstd/planegcs-backend.d.ts +16 -1
- package/dist/fcstd/planegcs-backend.d.ts.map +1 -1
- package/dist/fcstd/planegcs-backend.js +16 -1
- package/dist/fcstd/planegcs-backend.js.map +1 -1
- package/dist/fcstd/sketch-parse.d.ts +43 -0
- package/dist/fcstd/sketch-parse.d.ts.map +1 -1
- package/dist/fcstd/sketch-parse.js +26 -0
- package/dist/fcstd/sketch-parse.js.map +1 -1
- package/dist/fcstd/sketch-solver.d.ts +20 -2
- package/dist/fcstd/sketch-solver.d.ts.map +1 -1
- package/dist/fcstd/sketch-solver.js +6 -1
- package/dist/fcstd/sketch-solver.js.map +1 -1
- package/dist/fcstd/sketch-verify.d.ts +19 -1
- package/dist/fcstd/sketch-verify.d.ts.map +1 -1
- package/dist/fcstd/sketch-verify.js +14 -1
- package/dist/fcstd/sketch-verify.js.map +1 -1
- package/dist/fcstd/structural-types.d.ts +83 -0
- package/dist/fcstd/structural-types.d.ts.map +1 -0
- package/dist/fcstd/structural-types.js +116 -0
- package/dist/fcstd/structural-types.js.map +1 -0
- package/dist/fcstd/unpack.d.ts +21 -2
- package/dist/fcstd/unpack.d.ts.map +1 -1
- package/dist/fcstd/unpack.js +11 -2
- package/dist/fcstd/unpack.js.map +1 -1
- package/dist/fcstd-convert.d.ts +30 -0
- package/dist/fcstd-convert.d.ts.map +1 -0
- package/dist/fcstd-convert.js +27 -0
- package/dist/fcstd-convert.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lang/determinism-scanner.d.ts +62 -0
- package/dist/lang/determinism-scanner.d.ts.map +1 -0
- package/dist/lang/determinism-scanner.js +619 -0
- package/dist/lang/determinism-scanner.js.map +1 -0
- package/dist/lang/symbol-table.generated.d.ts +7 -3
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +7 -3
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +3 -2
- package/dist/mesh/index.js.map +1 -1
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +56 -2
- package/dist/node-host/cli.js.map +1 -1
- package/dist/runtime-state.d.ts +18 -6
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +9 -1
- package/dist/runtime-state.js.map +1 -1
- package/dist/shape.d.ts +15 -0
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +26 -3
- package/dist/shape.js.map +1 -1
- package/dist/topology/naming/build-naming.d.ts +14 -30
- package/dist/topology/naming/build-naming.d.ts.map +1 -1
- package/dist/topology/naming/build-naming.js +21 -54
- package/dist/topology/naming/build-naming.js.map +1 -1
- package/dist/topology/naming/capture-topo-ref.d.ts.map +1 -1
- package/dist/topology/naming/capture-topo-ref.js +5 -0
- package/dist/topology/naming/capture-topo-ref.js.map +1 -1
- package/dist/topology/naming/index.d.ts +3 -0
- package/dist/topology/naming/index.d.ts.map +1 -1
- package/dist/topology/naming/index.js +3 -0
- package/dist/topology/naming/index.js.map +1 -1
- package/dist/topology/naming/lineage-resolve.d.ts +80 -0
- package/dist/topology/naming/lineage-resolve.d.ts.map +1 -0
- package/dist/topology/naming/lineage-resolve.js +120 -0
- package/dist/topology/naming/lineage-resolve.js.map +1 -0
- package/dist/topology/naming/lineage.d.ts +349 -0
- package/dist/topology/naming/lineage.d.ts.map +1 -0
- package/dist/topology/naming/lineage.js +398 -0
- package/dist/topology/naming/lineage.js.map +1 -0
- package/dist/topology/naming/migrate.d.ts +41 -0
- package/dist/topology/naming/migrate.d.ts.map +1 -0
- package/dist/topology/naming/migrate.js +88 -0
- package/dist/topology/naming/migrate.js.map +1 -0
- package/dist/topology/naming/role-name.d.ts +176 -0
- package/dist/topology/naming/role-name.d.ts.map +1 -0
- package/dist/topology/naming/role-name.js +344 -0
- package/dist/topology/naming/role-name.js.map +1 -0
- package/dist/topology/naming/roles.d.ts +20 -22
- package/dist/topology/naming/roles.d.ts.map +1 -1
- package/dist/topology/naming/roles.js +51 -49
- package/dist/topology/naming/roles.js.map +1 -1
- package/dist/topology/naming/types.d.ts +65 -18
- package/dist/topology/naming/types.d.ts.map +1 -1
- package/dist/topology/naming/types.js.map +1 -1
- package/dist/weapp.d.ts +22 -0
- package/dist/weapp.d.ts.map +1 -0
- package/dist/weapp.js +23 -0
- package/dist/weapp.js.map +1 -0
- package/package.json +18 -5
|
@@ -22,6 +22,10 @@ export const ConstraintType = {
|
|
|
22
22
|
Group: 20,
|
|
23
23
|
Text: 21,
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Human-readable names for the ConstraintType enum integers (debugging/
|
|
27
|
+
* diagnostics only).
|
|
28
|
+
*/
|
|
25
29
|
export const CONSTRAINT_NAMES = {
|
|
26
30
|
1: 'Coincident', 2: 'Horizontal', 3: 'Vertical', 4: 'Parallel', 5: 'Tangent',
|
|
27
31
|
6: 'Distance', 7: 'DistanceX', 8: 'DistanceY', 9: 'Angle', 10: 'Perpendicular',
|
|
@@ -47,6 +51,13 @@ function num(attrs, key) {
|
|
|
47
51
|
const v = attrs[key];
|
|
48
52
|
return v === undefined ? 0 : Number(v);
|
|
49
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Parse a sketch's `<GeometryList>` property into typed geometry elements.
|
|
56
|
+
*
|
|
57
|
+
* @param prop - the sketch's Geometry property.
|
|
58
|
+
* @returns the parsed geometry list; unsupported element kinds degrade to a
|
|
59
|
+
* NaN point so the caller can downgrade the sketch.
|
|
60
|
+
*/
|
|
50
61
|
export function parseGeometryList(prop) {
|
|
51
62
|
// <GeometryList count="N"><Geometry type="...">...</Geometry>...</GeometryList>
|
|
52
63
|
const listEl = prop.children[0];
|
|
@@ -132,6 +143,13 @@ export function parseGeometryList(prop) {
|
|
|
132
143
|
function parseGeoRef(attrs, prefix) {
|
|
133
144
|
return { geoId: Math.trunc(num(attrs, prefix)), pos: Math.trunc(num(attrs, `${prefix}Pos`)) };
|
|
134
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Parse a sketch's `<ConstraintList>` property into constraint records.
|
|
148
|
+
*
|
|
149
|
+
* @param prop - the sketch's Constraints property.
|
|
150
|
+
* @returns the parsed constraints, with element refs resolved from
|
|
151
|
+
* ElementIds/ElementPositions or the old First/Second/Third fallback.
|
|
152
|
+
*/
|
|
135
153
|
export function parseConstraintList(prop) {
|
|
136
154
|
// <ConstraintList count="N"><Constrain .../>...</ConstraintList>
|
|
137
155
|
const listEl = prop.children[0];
|
|
@@ -178,6 +196,14 @@ export function parseConstraintList(prop) {
|
|
|
178
196
|
}
|
|
179
197
|
return cons;
|
|
180
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Parse a sketch object's geometry and constraint properties (M3.1 entry).
|
|
201
|
+
*
|
|
202
|
+
* @param geometryProp - the sketch's Geometry property (may be undefined).
|
|
203
|
+
* @param constraintsProp - the sketch's Constraints property (may be undefined).
|
|
204
|
+
* @param fullyConstrained - the sketch's FullyConstrained flag.
|
|
205
|
+
* @returns the parsed sketch, including external geoIds referenced by constraints.
|
|
206
|
+
*/
|
|
181
207
|
export function parseSketchObject(geometryProp, constraintsProp, fullyConstrained) {
|
|
182
208
|
const geoms = geometryProp ? parseGeometryList(geometryProp) : [];
|
|
183
209
|
const constraints = constraintsProp ? parseConstraintList(constraintsProp) : [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sketch-parse.js","sourceRoot":"","sources":["../../src/fcstd/sketch-parse.ts"],"names":[],"mappings":"AAeA,2EAA2E;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC;IACR,aAAa,EAAE,EAAE;IACjB,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE,EAAE;IACb,iBAAiB,EAAE,EAAE;IACrB,SAAS,EAAE,EAAE;IACb,KAAK,EAAE,EAAE;IACT,QAAQ,EAAE,EAAE;IACZ,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;CACA,CAAC;AAEX,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS;IAC5E,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe;IAC9E,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,WAAW;IAC/D,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU;IACrE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM;CACtC,CAAC;AAEF,qDAAqD;AACrD,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,CAAC,CAAC;IACT,MAAM,EAAE,CAAC,CAAC;CACF,CAAC;AAEX,iCAAiC;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,CAAC,EAAE,cAAc;IACvB,KAAK,EAAE,CAAC;IACR,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC,EAAE,2BAA2B;CAC3B,CAAC;AAsEX,SAAS,GAAG,CAAC,KAA6B,EAAE,GAAW;IACrD,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAmB;IACnD,gFAAgF;IAChF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC7C,mEAAmE;QACnE,oEAAoE;QACpE,kBAAkB;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAC/B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,cAAc,IAAI,CAAC,CAAC,OAAO,KAAK,eAAe,IAAI,CAAC,CAAC,OAAO,KAAK,KAAK,CAC5F,CAAC;QACF,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC;QAC1B,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,GAAG,KAAK,aAAa,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;gBAChE,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,MAAM;oBACZ,KAAK;oBACL,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC;oBAChE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC;iBAC3D,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;YACD,KAAK,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;gBACtD,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,QAAQ;oBACd,KAAK;oBACL,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC;oBACnE,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC;iBACzB,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;YACD,KAAK,GAAG,KAAK,aAAa,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;gBAChE,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC7B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC7B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;gBAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;gBAChC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;gBAC9B,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,KAAK;oBACX,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;oBAC1D,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE;oBAC5D,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE;iBAC7D,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;YACD,KAAK,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gBAC3E,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;gBACrF,MAAM;YACR,CAAC;YACD,KAAK,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBACxD,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC7B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;gBACpC,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;gBACpC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;gBAChE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC;oBACrD,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG;oBACpD,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,GAAG;oBACnC,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,GAAG;iBACpC,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;YACD;gBACE,qEAAqE;gBACrE,qEAAqE;gBACrE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC7D,MAAM;QACV,CAAC;QACD,KAAK,EAAE,CAAC;IACV,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAA6B,EAAE,MAAc;IAChE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAmB;IACrD,iEAAiE;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,IAAI,GAAgB,EAAE,CAAC;IAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,OAAO,KAAK,WAAW;YAAE,SAAS;QAC5C,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAExC,kFAAkF;QAClF,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;gBAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;gBACzC,IAAI,KAAK,KAAK,CAAC,IAAI;oBAAE,SAAS;gBAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC;QAE/E,IAAI,CAAC,IAAI,CAAC;YACR,KAAK;YACL,IAAI;YACJ,IAAI;YACJ,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;YACtB,SAAS;YACT,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;YACrB,qBAAqB,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;SAC7F,CAAC,CAAC;QACH,KAAK,EAAE,CAAC;IACV,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,YAAuC,EACvC,eAA0C,EAC1C,gBAAyB;IAEzB,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,MAAM,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACvB,uEAAuE;YACvE,sEAAsE;YACtE,gDAAgD;YAChD,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI;gBAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,OAAO;QACL,KAAK;QACL,WAAW;QACX,gBAAgB;QAChB,cAAc,EAAE,CAAC,GAAG,cAAc,CAAC;KACpC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * M3.1 — FCStd sketch parsing: <GeometryList> → SketchGeom[],\n * <ConstraintList> → SketchCon[].\n *\n * Field format per plan §5.2/§5.3:\n * - geometry coordinates are 3D (X/Y/Z); sketch-local Z is usually 0\n * - <Constrain> (singular) carries Type as the ConstraintType enum integer\n * (Constraint.h:52-77)\n * - ElementIds/ElementPositions (new) take precedence over First/Second/Third\n * (old); 47.5% of sample constraints lack the new format (§5.3.1)\n * - IsDriving defaults to true when missing (Constraint.h:240)\n * - geoId: >= 0 own geometry; -1 HAxis/RtPnt; -2 VAxis; <= -3 external (D4)\n */\nimport type { FcstdProperty } from './document.js';\n\n/** ConstraintType enum values (src/Mod/Sketcher/App/Constraint.h:52-77) */\nexport const ConstraintType = {\n Coincident: 1,\n Horizontal: 2,\n Vertical: 3,\n Parallel: 4,\n Tangent: 5,\n Distance: 6,\n DistanceX: 7,\n DistanceY: 8,\n Angle: 9,\n Perpendicular: 10,\n Radius: 11,\n Equal: 12,\n PointOnObject: 13,\n Symmetric: 14,\n InternalAlignment: 15,\n SnellsLaw: 16,\n Block: 17,\n Diameter: 18,\n Weight: 19,\n Group: 20,\n Text: 21,\n} as const;\n\nexport const CONSTRAINT_NAMES: Record<number, string> = {\n 1: 'Coincident', 2: 'Horizontal', 3: 'Vertical', 4: 'Parallel', 5: 'Tangent',\n 6: 'Distance', 7: 'DistanceX', 8: 'DistanceY', 9: 'Angle', 10: 'Perpendicular',\n 11: 'Radius', 12: 'Equal', 13: 'PointOnObject', 14: 'Symmetric',\n 15: 'InternalAlignment', 16: 'SnellsLaw', 17: 'Block', 18: 'Diameter',\n 19: 'Weight', 20: 'Group', 21: 'Text',\n};\n\n/** GeoEnum (src/Mod/Sketcher/App/GeoEnum.h:71-78) */\nexport const GeoId = {\n RtPnt: -1,\n HAxis: -1,\n VAxis: -2,\n RefExt: -3,\n} as const;\n\n/** PointPos (GeoEnum.h:88-94) */\nexport const PointPos = {\n none: 0, // edge itself\n start: 1,\n end: 2,\n mid: 3, // center of circle/ellipse\n} as const;\n\nexport type SketchGeom =\n | { kind: 'point'; index: number; x: number; y: number; z: number }\n | { kind: 'line'; index: number; x1: number; y1: number; z1: number; x2: number; y2: number; z2: number }\n | { kind: 'circle'; index: number; cx: number; cy: number; cz: number; radius: number }\n | {\n kind: 'arc';\n index: number;\n cx: number;\n cy: number;\n cz: number;\n radius: number;\n startAngle: number; // radians\n endAngle: number;\n /** arc endpoints derived from angles (kept for solver wiring) */\n x1: number;\n y1: number;\n z1: number;\n x2: number;\n y2: number;\n z2: number;\n }\n | {\n kind: 'ellipse';\n index: number;\n cx: number;\n cy: number;\n cz: number;\n majorRadius: number;\n minorRadius: number;\n /** rotation of major axis, radians */\n angleXU: number;\n /** first focus (computed) */\n fx1: number;\n fy1: number;\n fx2: number;\n fy2: number;\n };\n\nexport interface GeoRef {\n geoId: number;\n pos: number; // PointPos\n}\n\nexport interface SketchCon {\n /** index in the ConstraintList */\n index: number;\n /** ConstraintType integer */\n type: number;\n /** resolved element refs (ElementIds or First/Second/Third fallback) */\n refs: GeoRef[];\n /** driving dimension value (Distance/Angle/Radius/...) */\n value: number;\n /** IsDriving; missing means true (§5.3.1) */\n isDriving: boolean;\n /** raw name attribute */\n name: string;\n /** InternalAlignmentType when type === 15 */\n internalAlignmentType?: number;\n}\n\nexport interface ParsedSketch {\n geoms: SketchGeom[];\n constraints: SketchCon[];\n fullyConstrained: boolean;\n /** geoIds <= -3 referenced by constraints (D4 external geometry) */\n externalGeoIds: number[];\n}\n\nfunction num(attrs: Record<string, string>, key: string): number {\n const v = attrs[key];\n return v === undefined ? 0 : Number(v);\n}\n\nexport function parseGeometryList(prop: FcstdProperty): SketchGeom[] {\n // <GeometryList count=\"N\"><Geometry type=\"...\">...</Geometry>...</GeometryList>\n const listEl = prop.children[0];\n if (!listEl) return [];\n const geoms: SketchGeom[] = [];\n let index = 0;\n for (const child of listEl.children) {\n const gtype = child.attributes['type'] ?? '';\n // <Geometry> may carry <Construction/>, <GeoExtensions/> or <UID/>\n // siblings before the actual geometry element — pick the first real\n // geometry child.\n const inner = child.children.find(\n (c) => c.tagName !== 'Construction' && c.tagName !== 'GeoExtensions' && c.tagName !== 'UID',\n );\n if (!inner) continue;\n const a = inner.attributes;\n const tag = inner.tagName;\n switch (true) {\n case tag === 'LineSegment' || gtype.includes('GeomLineSegment'): {\n geoms.push({\n kind: 'line',\n index,\n x1: num(a, 'StartX'), y1: num(a, 'StartY'), z1: num(a, 'StartZ'),\n x2: num(a, 'EndX'), y2: num(a, 'EndY'), z2: num(a, 'EndZ'),\n });\n break;\n }\n case tag === 'Circle' || gtype.includes('GeomCircle'): {\n geoms.push({\n kind: 'circle',\n index,\n cx: num(a, 'CenterX'), cy: num(a, 'CenterY'), cz: num(a, 'CenterZ'),\n radius: num(a, 'Radius'),\n });\n break;\n }\n case tag === 'ArcOfCircle' || gtype.includes('GeomArcOfCircle'): {\n const cx = num(a, 'CenterX');\n const cy = num(a, 'CenterY');\n const cz = num(a, 'CenterZ');\n const r = num(a, 'Radius');\n const sa = num(a, 'StartAngle');\n const ea = num(a, 'EndAngle');\n geoms.push({\n kind: 'arc',\n index, cx, cy, cz, radius: r, startAngle: sa, endAngle: ea,\n x1: cx + r * Math.cos(sa), y1: cy + r * Math.sin(sa), z1: cz,\n x2: cx + r * Math.cos(ea), y2: cy + r * Math.sin(ea), z2: cz,\n });\n break;\n }\n case tag === 'GeomPoint' || tag === 'Point' || gtype.includes('GeomPoint'): {\n geoms.push({ kind: 'point', index, x: num(a, 'X'), y: num(a, 'Y'), z: num(a, 'Z') });\n break;\n }\n case tag === 'Ellipse' || gtype.includes('GeomEllipse'): {\n const cx = num(a, 'CenterX');\n const cy = num(a, 'CenterY');\n const major = num(a, 'MajorRadius');\n const minor = num(a, 'MinorRadius');\n const ang = num(a, 'AngleXU');\n const f = Math.sqrt(Math.max(0, major * major - minor * minor));\n const ca = Math.cos(ang);\n const sa2 = Math.sin(ang);\n geoms.push({\n kind: 'ellipse', index, cx, cy, cz: num(a, 'CenterZ'),\n majorRadius: major, minorRadius: minor, angleXU: ang,\n fx1: cx + f * ca, fy1: cy + f * sa2,\n fx2: cx - f * ca, fy2: cy - f * sa2,\n });\n break;\n }\n default:\n // ArcOfEllipse / BSpline / hyperbola / parabola: not supported in M3\n // (sample set: 0 occurrences, plan §5.5.3); caller downgrades to L2.\n geoms.push({ kind: 'point', index, x: NaN, y: NaN, z: NaN });\n break;\n }\n index++;\n }\n return geoms;\n}\n\nfunction parseGeoRef(attrs: Record<string, string>, prefix: string): GeoRef {\n return { geoId: Math.trunc(num(attrs, prefix)), pos: Math.trunc(num(attrs, `${prefix}Pos`)) };\n}\n\nexport function parseConstraintList(prop: FcstdProperty): SketchCon[] {\n // <ConstraintList count=\"N\"><Constrain .../>...</ConstraintList>\n const listEl = prop.children[0];\n if (!listEl) return [];\n const cons: SketchCon[] = [];\n let index = 0;\n for (const child of listEl.children) {\n if (child.tagName !== 'Constrain') continue;\n const a = child.attributes;\n const type = Math.trunc(num(a, 'Type'));\n\n // ElementIds (new, space-separated) takes precedence; fallback First/Second/Third\n const refs: GeoRef[] = [];\n const eids = a['ElementIds']?.trim();\n const eposs = a['ElementPositions']?.trim();\n if (eids && eposs) {\n const ids = eids.split(/\\s+/).map(Number);\n const poss = eposs.split(/\\s+/).map(Number);\n for (let i = 0; i < ids.length; i++) {\n refs.push({ geoId: ids[i]!, pos: poss[i] ?? 0 });\n }\n } else {\n // old-style triple; Third=GeoUndef(-2000) means unused\n for (const prefix of ['First', 'Second', 'Third']) {\n const geoId = Math.trunc(num(a, prefix));\n if (geoId === -2000) continue;\n refs.push(parseGeoRef(a, prefix));\n }\n }\n\n const isDriving = a['IsDriving'] === undefined ? true : a['IsDriving'] === '1';\n\n cons.push({\n index,\n type,\n refs,\n value: num(a, 'Value'),\n isDriving,\n name: a['Name'] ?? '',\n internalAlignmentType: type === 15 ? Math.trunc(num(a, 'InternalAlignmentType')) : undefined,\n });\n index++;\n }\n return cons;\n}\n\nexport function parseSketchObject(\n geometryProp: FcstdProperty | undefined,\n constraintsProp: FcstdProperty | undefined,\n fullyConstrained: boolean,\n): ParsedSketch {\n const geoms = geometryProp ? parseGeometryList(geometryProp) : [];\n const constraints = constraintsProp ? parseConstraintList(constraintsProp) : [];\n const externalGeoIds = new Set<number>();\n for (const c of constraints) {\n for (const r of c.refs) {\n // GeoUndef (-2000) is an unused-slot placeholder in old-format triples\n // and ElementIds — it is NOT external geometry. External refs are the\n // small negative range starting at RefExt (-3).\n if (r.geoId <= GeoId.RefExt && r.geoId > -2000) externalGeoIds.add(r.geoId);\n }\n }\n return {\n geoms,\n constraints,\n fullyConstrained,\n externalGeoIds: [...externalGeoIds],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sketch-parse.js","sourceRoot":"","sources":["../../src/fcstd/sketch-parse.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M3.1 — FCStd sketch parsing: <GeometryList> → SketchGeom[],\n * <ConstraintList> → SketchCon[].\n *\n * Field format per plan §5.2/§5.3:\n * - geometry coordinates are 3D (X/Y/Z); sketch-local Z is usually 0\n * - <Constrain> (singular) carries Type as the ConstraintType enum integer\n * (Constraint.h:52-77)\n * - ElementIds/ElementPositions (new) take precedence over First/Second/Third\n * (old); 47.5% of sample constraints lack the new format (§5.3.1)\n * - IsDriving defaults to true when missing (Constraint.h:240)\n * - geoId: >= 0 own geometry; -1 HAxis/RtPnt; -2 VAxis; <= -3 external (D4)\n */\nimport type { FcstdProperty } from './document.js';\n\n/** ConstraintType enum values (src/Mod/Sketcher/App/Constraint.h:52-77) */\nexport const ConstraintType = {\n Coincident: 1,\n Horizontal: 2,\n Vertical: 3,\n Parallel: 4,\n Tangent: 5,\n Distance: 6,\n DistanceX: 7,\n DistanceY: 8,\n Angle: 9,\n Perpendicular: 10,\n Radius: 11,\n Equal: 12,\n PointOnObject: 13,\n Symmetric: 14,\n InternalAlignment: 15,\n SnellsLaw: 16,\n Block: 17,\n Diameter: 18,\n Weight: 19,\n Group: 20,\n Text: 21,\n} as const;\n\n/**\n * Human-readable names for the ConstraintType enum integers (debugging/\n * diagnostics only).\n */\nexport const CONSTRAINT_NAMES: Record<number, string> = {\n 1: 'Coincident', 2: 'Horizontal', 3: 'Vertical', 4: 'Parallel', 5: 'Tangent',\n 6: 'Distance', 7: 'DistanceX', 8: 'DistanceY', 9: 'Angle', 10: 'Perpendicular',\n 11: 'Radius', 12: 'Equal', 13: 'PointOnObject', 14: 'Symmetric',\n 15: 'InternalAlignment', 16: 'SnellsLaw', 17: 'Block', 18: 'Diameter',\n 19: 'Weight', 20: 'Group', 21: 'Text',\n};\n\n/** GeoEnum (src/Mod/Sketcher/App/GeoEnum.h:71-78) */\nexport const GeoId = {\n RtPnt: -1,\n HAxis: -1,\n VAxis: -2,\n RefExt: -3,\n} as const;\n\n/** PointPos (GeoEnum.h:88-94) */\nexport const PointPos = {\n none: 0, // edge itself\n start: 1,\n end: 2,\n mid: 3, // center of circle/ellipse\n} as const;\n\n/**\n * One parsed sketch geometry element (point, line, circle, arc or ellipse),\n * in 3D sketch-local coordinates.\n */\nexport type SketchGeom =\n | { kind: 'point'; index: number; x: number; y: number; z: number }\n | { kind: 'line'; index: number; x1: number; y1: number; z1: number; x2: number; y2: number; z2: number }\n | { kind: 'circle'; index: number; cx: number; cy: number; cz: number; radius: number }\n | {\n kind: 'arc';\n index: number;\n cx: number;\n cy: number;\n cz: number;\n radius: number;\n startAngle: number; // radians\n endAngle: number;\n /** arc endpoints derived from angles (kept for solver wiring) */\n x1: number;\n y1: number;\n z1: number;\n x2: number;\n y2: number;\n z2: number;\n }\n | {\n kind: 'ellipse';\n index: number;\n cx: number;\n cy: number;\n cz: number;\n majorRadius: number;\n minorRadius: number;\n /** rotation of major axis, radians */\n angleXU: number;\n /** first focus (computed) */\n fx1: number;\n fy1: number;\n fx2: number;\n fy2: number;\n };\n\n/**\n * One (geometry, point) reference inside a constraint: a geoId plus a\n * PointPos selector.\n */\nexport interface GeoRef {\n /** geometry id: >= 0 own geometry; -1 HAxis/RtPnt; -2 VAxis; <= -3 external */\n geoId: number;\n /** PointPos selector (0 = edge itself, 1/2 = start/end, 3 = center) */\n pos: number; // PointPos\n}\n\n/**\n * One parsed sketch constraint (`<Constrain>` element).\n */\nexport interface SketchCon {\n /** index in the ConstraintList */\n index: number;\n /** ConstraintType integer */\n type: number;\n /** resolved element refs (ElementIds or First/Second/Third fallback) */\n refs: GeoRef[];\n /** driving dimension value (Distance/Angle/Radius/...) */\n value: number;\n /** IsDriving; missing means true (§5.3.1) */\n isDriving: boolean;\n /** raw name attribute */\n name: string;\n /** InternalAlignmentType when type === 15 */\n internalAlignmentType?: number;\n}\n\n/**\n * The fully parsed sketch: geometry, constraints, constrainedness and the set\n * of referenced external geoIds.\n */\nexport interface ParsedSketch {\n geoms: SketchGeom[];\n constraints: SketchCon[];\n fullyConstrained: boolean;\n /** geoIds <= -3 referenced by constraints (D4 external geometry) */\n externalGeoIds: number[];\n}\n\nfunction num(attrs: Record<string, string>, key: string): number {\n const v = attrs[key];\n return v === undefined ? 0 : Number(v);\n}\n\n/**\n * Parse a sketch's `<GeometryList>` property into typed geometry elements.\n *\n * @param prop - the sketch's Geometry property.\n * @returns the parsed geometry list; unsupported element kinds degrade to a\n * NaN point so the caller can downgrade the sketch.\n */\nexport function parseGeometryList(prop: FcstdProperty): SketchGeom[] {\n // <GeometryList count=\"N\"><Geometry type=\"...\">...</Geometry>...</GeometryList>\n const listEl = prop.children[0];\n if (!listEl) return [];\n const geoms: SketchGeom[] = [];\n let index = 0;\n for (const child of listEl.children) {\n const gtype = child.attributes['type'] ?? '';\n // <Geometry> may carry <Construction/>, <GeoExtensions/> or <UID/>\n // siblings before the actual geometry element — pick the first real\n // geometry child.\n const inner = child.children.find(\n (c) => c.tagName !== 'Construction' && c.tagName !== 'GeoExtensions' && c.tagName !== 'UID',\n );\n if (!inner) continue;\n const a = inner.attributes;\n const tag = inner.tagName;\n switch (true) {\n case tag === 'LineSegment' || gtype.includes('GeomLineSegment'): {\n geoms.push({\n kind: 'line',\n index,\n x1: num(a, 'StartX'), y1: num(a, 'StartY'), z1: num(a, 'StartZ'),\n x2: num(a, 'EndX'), y2: num(a, 'EndY'), z2: num(a, 'EndZ'),\n });\n break;\n }\n case tag === 'Circle' || gtype.includes('GeomCircle'): {\n geoms.push({\n kind: 'circle',\n index,\n cx: num(a, 'CenterX'), cy: num(a, 'CenterY'), cz: num(a, 'CenterZ'),\n radius: num(a, 'Radius'),\n });\n break;\n }\n case tag === 'ArcOfCircle' || gtype.includes('GeomArcOfCircle'): {\n const cx = num(a, 'CenterX');\n const cy = num(a, 'CenterY');\n const cz = num(a, 'CenterZ');\n const r = num(a, 'Radius');\n const sa = num(a, 'StartAngle');\n const ea = num(a, 'EndAngle');\n geoms.push({\n kind: 'arc',\n index, cx, cy, cz, radius: r, startAngle: sa, endAngle: ea,\n x1: cx + r * Math.cos(sa), y1: cy + r * Math.sin(sa), z1: cz,\n x2: cx + r * Math.cos(ea), y2: cy + r * Math.sin(ea), z2: cz,\n });\n break;\n }\n case tag === 'GeomPoint' || tag === 'Point' || gtype.includes('GeomPoint'): {\n geoms.push({ kind: 'point', index, x: num(a, 'X'), y: num(a, 'Y'), z: num(a, 'Z') });\n break;\n }\n case tag === 'Ellipse' || gtype.includes('GeomEllipse'): {\n const cx = num(a, 'CenterX');\n const cy = num(a, 'CenterY');\n const major = num(a, 'MajorRadius');\n const minor = num(a, 'MinorRadius');\n const ang = num(a, 'AngleXU');\n const f = Math.sqrt(Math.max(0, major * major - minor * minor));\n const ca = Math.cos(ang);\n const sa2 = Math.sin(ang);\n geoms.push({\n kind: 'ellipse', index, cx, cy, cz: num(a, 'CenterZ'),\n majorRadius: major, minorRadius: minor, angleXU: ang,\n fx1: cx + f * ca, fy1: cy + f * sa2,\n fx2: cx - f * ca, fy2: cy - f * sa2,\n });\n break;\n }\n default:\n // ArcOfEllipse / BSpline / hyperbola / parabola: not supported in M3\n // (sample set: 0 occurrences, plan §5.5.3); caller downgrades to L2.\n geoms.push({ kind: 'point', index, x: NaN, y: NaN, z: NaN });\n break;\n }\n index++;\n }\n return geoms;\n}\n\nfunction parseGeoRef(attrs: Record<string, string>, prefix: string): GeoRef {\n return { geoId: Math.trunc(num(attrs, prefix)), pos: Math.trunc(num(attrs, `${prefix}Pos`)) };\n}\n\n/**\n * Parse a sketch's `<ConstraintList>` property into constraint records.\n *\n * @param prop - the sketch's Constraints property.\n * @returns the parsed constraints, with element refs resolved from\n * ElementIds/ElementPositions or the old First/Second/Third fallback.\n */\nexport function parseConstraintList(prop: FcstdProperty): SketchCon[] {\n // <ConstraintList count=\"N\"><Constrain .../>...</ConstraintList>\n const listEl = prop.children[0];\n if (!listEl) return [];\n const cons: SketchCon[] = [];\n let index = 0;\n for (const child of listEl.children) {\n if (child.tagName !== 'Constrain') continue;\n const a = child.attributes;\n const type = Math.trunc(num(a, 'Type'));\n\n // ElementIds (new, space-separated) takes precedence; fallback First/Second/Third\n const refs: GeoRef[] = [];\n const eids = a['ElementIds']?.trim();\n const eposs = a['ElementPositions']?.trim();\n if (eids && eposs) {\n const ids = eids.split(/\\s+/).map(Number);\n const poss = eposs.split(/\\s+/).map(Number);\n for (let i = 0; i < ids.length; i++) {\n refs.push({ geoId: ids[i]!, pos: poss[i] ?? 0 });\n }\n } else {\n // old-style triple; Third=GeoUndef(-2000) means unused\n for (const prefix of ['First', 'Second', 'Third']) {\n const geoId = Math.trunc(num(a, prefix));\n if (geoId === -2000) continue;\n refs.push(parseGeoRef(a, prefix));\n }\n }\n\n const isDriving = a['IsDriving'] === undefined ? true : a['IsDriving'] === '1';\n\n cons.push({\n index,\n type,\n refs,\n value: num(a, 'Value'),\n isDriving,\n name: a['Name'] ?? '',\n internalAlignmentType: type === 15 ? Math.trunc(num(a, 'InternalAlignmentType')) : undefined,\n });\n index++;\n }\n return cons;\n}\n\n/**\n * Parse a sketch object's geometry and constraint properties (M3.1 entry).\n *\n * @param geometryProp - the sketch's Geometry property (may be undefined).\n * @param constraintsProp - the sketch's Constraints property (may be undefined).\n * @param fullyConstrained - the sketch's FullyConstrained flag.\n * @returns the parsed sketch, including external geoIds referenced by constraints.\n */\nexport function parseSketchObject(\n geometryProp: FcstdProperty | undefined,\n constraintsProp: FcstdProperty | undefined,\n fullyConstrained: boolean,\n): ParsedSketch {\n const geoms = geometryProp ? parseGeometryList(geometryProp) : [];\n const constraints = constraintsProp ? parseConstraintList(constraintsProp) : [];\n const externalGeoIds = new Set<number>();\n for (const c of constraints) {\n for (const r of c.refs) {\n // GeoUndef (-2000) is an unused-slot placeholder in old-format triples\n // and ElementIds — it is NOT external geometry. External refs are the\n // small negative range starting at RefExt (-3).\n if (r.geoId <= GeoId.RefExt && r.geoId > -2000) externalGeoIds.add(r.geoId);\n }\n }\n return {\n geoms,\n constraints,\n fullyConstrained,\n externalGeoIds: [...externalGeoIds],\n };\n}\n"]}
|
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
* Output: solved geometry or a structured failure — the caller (M3.5) decides
|
|
7
7
|
* between solution and initial-value fallback (D2).
|
|
8
8
|
*/
|
|
9
|
-
import type { Result } from '../
|
|
9
|
+
import type { Result } from '../api/result.js';
|
|
10
10
|
import type { SketchGeom, SketchCon } from './sketch-parse.js';
|
|
11
|
+
/**
|
|
12
|
+
* Result of one solver run: the solved geometry plus convergence status and
|
|
13
|
+
* diagnostics for the caller's L0/L1/L2 decision (D2).
|
|
14
|
+
*/
|
|
11
15
|
export interface SolveOutcome {
|
|
12
16
|
/** geometry after solve, same order/index as input */
|
|
13
17
|
geoms: SketchGeom[];
|
|
@@ -20,11 +24,20 @@ export interface SolveOutcome {
|
|
|
20
24
|
/** constraint indices dropped because their GCS shape could not be pushed */
|
|
21
25
|
droppedConstraints: number[];
|
|
22
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* One pre-projected external geometry segment passed to the solver as fixed
|
|
29
|
+
* (immutable) geometry.
|
|
30
|
+
*/
|
|
23
31
|
export interface ExternalFixedSeg {
|
|
24
32
|
/** negative geoId in link order: -3, -4, ... (GeoEnum.RefExt downward) */
|
|
25
33
|
geoId: number;
|
|
34
|
+
/** the projected sketch-local 2D polyline (immutable to the solver) */
|
|
26
35
|
polyline: [number, number][];
|
|
27
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Solver abstraction (D5): faijs depends only on this interface; the WASM
|
|
39
|
+
* implementation is swappable.
|
|
40
|
+
*/
|
|
28
41
|
export interface SketchSolver {
|
|
29
42
|
/**
|
|
30
43
|
* Solve constraints against the given geometry. The input geometry's stored
|
|
@@ -40,6 +53,11 @@ export interface SketchSolver {
|
|
|
40
53
|
}
|
|
41
54
|
/** Constraint types the planegcs backend can express (P0 set, plan §7 M3.4). */
|
|
42
55
|
export declare const SUPPORTED_CONSTRAINT_TYPES: Set<number>;
|
|
43
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Check whether every constraint in a sketch is expressible by the backend.
|
|
58
|
+
*
|
|
59
|
+
* @param constraints - the parsed sketch constraints.
|
|
60
|
+
* @returns true when every constraint's type is in SUPPORTED_CONSTRAINT_TYPES.
|
|
61
|
+
*/
|
|
44
62
|
export declare function allConstraintsSupported(constraints: SketchCon[]): boolean;
|
|
45
63
|
//# sourceMappingURL=sketch-solver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sketch-solver.d.ts","sourceRoot":"","sources":["../../src/fcstd/sketch-solver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"sketch-solver.d.ts","sourceRoot":"","sources":["../../src/fcstd/sketch-solver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,wBAAwB,CAAC;IAC3E,4CAA4C;IAC5C,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,6EAA6E;IAC7E,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;OASG;IACH,KAAK,CACH,KAAK,EAAE,UAAU,EAAE,EACnB,WAAW,EAAE,SAAS,EAAE,EACxB,QAAQ,CAAC,EAAE,gBAAgB,EAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;CACzC;AAED,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,aAgBrC,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,SAAS,EAAE,GAAG,OAAO,CAEzE"}
|
|
@@ -16,7 +16,12 @@ export const SUPPORTED_CONSTRAINT_TYPES = new Set([
|
|
|
16
16
|
14, // Symmetric
|
|
17
17
|
18, // Diameter
|
|
18
18
|
]);
|
|
19
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Check whether every constraint in a sketch is expressible by the backend.
|
|
21
|
+
*
|
|
22
|
+
* @param constraints - the parsed sketch constraints.
|
|
23
|
+
* @returns true when every constraint's type is in SUPPORTED_CONSTRAINT_TYPES.
|
|
24
|
+
*/
|
|
20
25
|
export function allConstraintsSupported(constraints) {
|
|
21
26
|
return constraints.every((c) => SUPPORTED_CONSTRAINT_TYPES.has(c.type));
|
|
22
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sketch-solver.js","sourceRoot":"","sources":["../../src/fcstd/sketch-solver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sketch-solver.js","sourceRoot":"","sources":["../../src/fcstd/sketch-solver.ts"],"names":[],"mappings":"AA6DA,gFAAgF;AAChF,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAS;IACxD,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,WAAW;IACd,CAAC,EAAE,WAAW;IACd,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,WAAW;IACd,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,QAAQ;IACX,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,YAAY;IAChB,EAAE,EAAE,WAAW;CAChB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAwB;IAC9D,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["/**\n * M3.2 — SketchSolver interface (D5) with the planegcs WASM backend.\n *\n * faijs depends only on this interface; the WASM implementation is swappable\n * (前文 B R2/R3). Input: parsed sketch geometry + constraints (M3.1 types).\n * Output: solved geometry or a structured failure — the caller (M3.5) decides\n * between solution and initial-value fallback (D2).\n */\nimport type { Result } from '../api/result.js';\nimport type { SketchGeom, SketchCon } from './sketch-parse.js';\n\n/**\n * Result of one solver run: the solved geometry plus convergence status and\n * diagnostics for the caller's L0/L1/L2 decision (D2).\n */\nexport interface SolveOutcome {\n /** geometry after solve, same order/index as input */\n geoms: SketchGeom[];\n /** true when the solver reports Success with no conflicts */\n converged: boolean;\n /** diagnostics when not converged */\n reason?: 'conflicting' | 'redundant' | 'failed' | 'unsupported-constraint';\n /** constraint indices the solver flagged */\n problemConstraints: number[];\n /** constraint indices dropped because their GCS shape could not be pushed */\n droppedConstraints: number[];\n}\n\n/**\n * One pre-projected external geometry segment passed to the solver as fixed\n * (immutable) geometry.\n */\nexport interface ExternalFixedSeg {\n /** negative geoId in link order: -3, -4, ... (GeoEnum.RefExt downward) */\n geoId: number;\n /** the projected sketch-local 2D polyline (immutable to the solver) */\n polyline: [number, number][];\n}\n\n/**\n * Solver abstraction (D5): faijs depends only on this interface; the WASM\n * implementation is swappable.\n */\nexport interface SketchSolver {\n /**\n * Solve constraints against the given geometry. The input geometry's stored\n * coordinates are used as the initial guess (D2 — they are FreeCAD's last\n * solution and the ideal starting point).\n *\n * `external` carries pre-projected fixed geometry (M6.3): immutable 2D\n * polylines that constraints may reference by negative geoId. When a\n * constraint references an external geoId not present here, the solver\n * drops that constraint (recorded in droppedConstraints).\n */\n solve(\n geoms: SketchGeom[],\n constraints: SketchCon[],\n external?: ExternalFixedSeg[],\n ): Promise<Result<SolveOutcome, never>>;\n}\n\n/** Constraint types the planegcs backend can express (P0 set, plan §7 M3.4). */\nexport const SUPPORTED_CONSTRAINT_TYPES = new Set<number>([\n 1, // Coincident\n 2, // Horizontal\n 3, // Vertical\n 4, // Parallel\n 5, // Tangent\n 6, // Distance\n 7, // DistanceX\n 8, // DistanceY\n 9, // Angle\n 10, // Perpendicular\n 11, // Radius\n 12, // Equal\n 13, // PointOnObject\n 14, // Symmetric\n 18, // Diameter\n]);\n\n/**\n * Check whether every constraint in a sketch is expressible by the backend.\n *\n * @param constraints - the parsed sketch constraints.\n * @returns true when every constraint's type is in SUPPORTED_CONSTRAINT_TYPES.\n */\nexport function allConstraintsSupported(constraints: SketchCon[]): boolean {\n return constraints.every((c) => SUPPORTED_CONSTRAINT_TYPES.has(c.type));\n}\n"]}
|
|
@@ -8,10 +8,22 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { SketchGeom } from './sketch-parse.js';
|
|
10
10
|
import type { SolveOutcome } from './sketch-solver.js';
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Maximum anchor-point distance between two geometry lists (same indexing).
|
|
13
|
+
*
|
|
14
|
+
* @param a - first geometry list (e.g. the solver result).
|
|
15
|
+
* @param b - second geometry list (e.g. the stored geometry).
|
|
16
|
+
* @returns the maximum Euclidean distance between corresponding anchor points
|
|
17
|
+
* (0 when the lists have no comparable points).
|
|
18
|
+
*/
|
|
12
19
|
export declare function maxPointDistance(a: SketchGeom[], b: SketchGeom[]): number;
|
|
20
|
+
/**
|
|
21
|
+
* Three-level downgrade verdict (D3) for one sketch.
|
|
22
|
+
*/
|
|
13
23
|
export interface SketchVerdict {
|
|
24
|
+
/** solved quality level: L0 = solved & matches, L1 = flagged, L2 = baked */
|
|
14
25
|
level: 'L0' | 'L1' | 'L2';
|
|
26
|
+
/** human-readable reason for a non-L0 verdict */
|
|
15
27
|
reason?: string;
|
|
16
28
|
/** max anchor distance between re-solved and stored geometry */
|
|
17
29
|
maxDelta?: number;
|
|
@@ -20,6 +32,12 @@ export interface SketchVerdict {
|
|
|
20
32
|
* Three-level downgrade (D3). L0 = solved & matches stored (delta <= T1).
|
|
21
33
|
* L1 = solver result kept but flagged, stored coords used instead.
|
|
22
34
|
* L2 = baked (unsupported geometry/constraints, external geometry).
|
|
35
|
+
*
|
|
36
|
+
* @param outcome - the solver result, or undefined when none was produced.
|
|
37
|
+
* @param stored - the on-disk (stored) geometry to compare against.
|
|
38
|
+
* @param t1 - the calibrated distance tolerance for the L0/L1 split.
|
|
39
|
+
* @param preBlocked - pre-solve downgrade reason; when set the sketch is L2.
|
|
40
|
+
* @returns the classification verdict for the sketch.
|
|
23
41
|
*/
|
|
24
42
|
export declare function classifySketch(outcome: SolveOutcome | undefined, stored: SketchGeom[], t1: number, preBlocked?: string): SketchVerdict;
|
|
25
43
|
//# sourceMappingURL=sketch-verify.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sketch-verify.d.ts","sourceRoot":"","sources":["../../src/fcstd/sketch-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAiBvD
|
|
1
|
+
{"version":3,"file":"sketch-verify.d.ts","sourceRoot":"","sources":["../../src/fcstd/sketch-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAiBvD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,MAAM,CAazE;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,MAAM,EAAE,UAAU,EAAE,EACpB,EAAE,EAAE,MAAM,EACV,UAAU,CAAC,EAAE,MAAM,GAClB,aAAa,CASf"}
|
|
@@ -12,7 +12,14 @@ function anchorPoints(g) {
|
|
|
12
12
|
return [{ x: g.cx, y: g.cy }];
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Maximum anchor-point distance between two geometry lists (same indexing).
|
|
17
|
+
*
|
|
18
|
+
* @param a - first geometry list (e.g. the solver result).
|
|
19
|
+
* @param b - second geometry list (e.g. the stored geometry).
|
|
20
|
+
* @returns the maximum Euclidean distance between corresponding anchor points
|
|
21
|
+
* (0 when the lists have no comparable points).
|
|
22
|
+
*/
|
|
16
23
|
export function maxPointDistance(a, b) {
|
|
17
24
|
let max = 0;
|
|
18
25
|
const n = Math.min(a.length, b.length);
|
|
@@ -32,6 +39,12 @@ export function maxPointDistance(a, b) {
|
|
|
32
39
|
* Three-level downgrade (D3). L0 = solved & matches stored (delta <= T1).
|
|
33
40
|
* L1 = solver result kept but flagged, stored coords used instead.
|
|
34
41
|
* L2 = baked (unsupported geometry/constraints, external geometry).
|
|
42
|
+
*
|
|
43
|
+
* @param outcome - the solver result, or undefined when none was produced.
|
|
44
|
+
* @param stored - the on-disk (stored) geometry to compare against.
|
|
45
|
+
* @param t1 - the calibrated distance tolerance for the L0/L1 split.
|
|
46
|
+
* @param preBlocked - pre-solve downgrade reason; when set the sketch is L2.
|
|
47
|
+
* @returns the classification verdict for the sketch.
|
|
35
48
|
*/
|
|
36
49
|
export function classifySketch(outcome, stored, t1, preBlocked) {
|
|
37
50
|
if (preBlocked)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sketch-verify.js","sourceRoot":"","sources":["../../src/fcstd/sketch-verify.ts"],"names":[],"mappings":"AAWA,SAAS,YAAY,CAAC,CAAa;IACjC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,KAAK,MAAM;YACT,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,KAAK,QAAQ;YACX,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChC,KAAK,KAAK;YACR,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5E,KAAK,SAAS;YACZ,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"sketch-verify.js","sourceRoot":"","sources":["../../src/fcstd/sketch-verify.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M3.5 — solved-vs-stored comparison (D2/V2).\n *\n * The on-disk coordinates ARE FreeCAD's last solution, so a correct pipeline\n * re-derives (nearly) the same geometry. maxPointDistance is the V2 metric;\n * its tolerance T1 is calibrated from the sample-set distribution, not\n * pre-set (plan §8).\n */\nimport type { SketchGeom } from './sketch-parse.js';\nimport type { SolveOutcome } from './sketch-solver.js';\n\nfunction anchorPoints(g: SketchGeom): { x: number; y: number }[] {\n switch (g.kind) {\n case 'point':\n return [{ x: g.x, y: g.y }];\n case 'line':\n return [{ x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];\n case 'circle':\n return [{ x: g.cx, y: g.cy }];\n case 'arc':\n return [{ x: g.cx, y: g.cy }, { x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];\n case 'ellipse':\n return [{ x: g.cx, y: g.cy }];\n }\n}\n\n/**\n * Maximum anchor-point distance between two geometry lists (same indexing).\n *\n * @param a - first geometry list (e.g. the solver result).\n * @param b - second geometry list (e.g. the stored geometry).\n * @returns the maximum Euclidean distance between corresponding anchor points\n * (0 when the lists have no comparable points).\n */\nexport function maxPointDistance(a: SketchGeom[], b: SketchGeom[]): number {\n let max = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n const pa = anchorPoints(a[i]!);\n const pb = anchorPoints(b[i]!);\n const m = Math.min(pa.length, pb.length);\n for (let k = 0; k < m; k++) {\n const d = Math.hypot(pa[k]!.x - pb[k]!.x, pa[k]!.y - pb[k]!.y);\n if (Number.isFinite(d) && d > max) max = d;\n }\n }\n return max;\n}\n\n/**\n * Three-level downgrade verdict (D3) for one sketch.\n */\nexport interface SketchVerdict {\n /** solved quality level: L0 = solved & matches, L1 = flagged, L2 = baked */\n level: 'L0' | 'L1' | 'L2';\n /** human-readable reason for a non-L0 verdict */\n reason?: string;\n /** max anchor distance between re-solved and stored geometry */\n maxDelta?: number;\n}\n\n/**\n * Three-level downgrade (D3). L0 = solved & matches stored (delta <= T1).\n * L1 = solver result kept but flagged, stored coords used instead.\n * L2 = baked (unsupported geometry/constraints, external geometry).\n *\n * @param outcome - the solver result, or undefined when none was produced.\n * @param stored - the on-disk (stored) geometry to compare against.\n * @param t1 - the calibrated distance tolerance for the L0/L1 split.\n * @param preBlocked - pre-solve downgrade reason; when set the sketch is L2.\n * @returns the classification verdict for the sketch.\n */\nexport function classifySketch(\n outcome: SolveOutcome | undefined,\n stored: SketchGeom[],\n t1: number,\n preBlocked?: string,\n): SketchVerdict {\n if (preBlocked) return { level: 'L2', reason: preBlocked };\n if (!outcome) return { level: 'L2', reason: 'no-solver-result' };\n if (!outcome.converged) {\n return { level: 'L1', reason: outcome.reason ?? 'solve-failed' };\n }\n const maxDelta = maxPointDistance(outcome.geoms, stored);\n if (maxDelta <= t1) return { level: 'L0', maxDelta };\n return { level: 'L1', reason: 'delta-exceeds-t1', maxDelta };\n}\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-modeling FCStd object types — the single source of truth shared by the
|
|
3
|
+
* C4 disposition audit (`convert.ts`) and the code generator (`codegen.ts`).
|
|
4
|
+
*
|
|
5
|
+
* Why a separate module: `codegen.ts` must skip these objects BEFORE it calls
|
|
6
|
+
* the translator (a datum plane must never enter a Body's feature chain), and
|
|
7
|
+
* `convert.ts` must reclassify them after translation. Keeping the sets in
|
|
8
|
+
* `convert.ts` would make `codegen.ts` import it back (convert → codegen), so
|
|
9
|
+
* the knowledge lives here with zero dependencies.
|
|
10
|
+
*
|
|
11
|
+
* C4 contract: an object in these sets is never a translation gap, and its
|
|
12
|
+
* geometry is never emitted as a modeling call. See the per-set docs below for
|
|
13
|
+
* the evidence behind each classification.
|
|
14
|
+
*/
|
|
15
|
+
/** Non-modeling structural/datum types: never translation gaps. They carry
|
|
16
|
+
* no feature semantics (containers, datum planes/lines/origins, groups) —
|
|
17
|
+
* their semantics are consumed by the translator (Body.Group ordering,
|
|
18
|
+
* datum-plane UpToFace anchors), not emitted as cad calls.
|
|
19
|
+
*
|
|
20
|
+
* GOTCHA (PadTest, 2026-09-21): a `PartDesign::Plane` also stores a `Shape`
|
|
21
|
+
* `.brp` member — the plane FACE. The generic "any object with shape evidence
|
|
22
|
+
* is a shape asset" rule therefore imported it and fed it into the Body's
|
|
23
|
+
* union chain, which both corrupts the solid and fails at run time
|
|
24
|
+
* (`[loadBrep] imported shape contains no solid sub-shapes`). Datum shapes are
|
|
25
|
+
* SUPPORT geometry for attachment/up-to resolution, never modeling solids. */
|
|
26
|
+
export declare const STRUCTURAL_TYPES: Set<string>;
|
|
27
|
+
/**
|
|
28
|
+
* 2026-09-20 sweep triage: assembly/import container types — links, assembly
|
|
29
|
+
* containers, import placeholders (Inventor/VRML). They reference or embed
|
|
30
|
+
* external/other geometry but produce no modeling semantics of their own;
|
|
31
|
+
* preserved-only. Modeling features (Part::Mirroring,
|
|
32
|
+
* PartDesign::AdditiveSphere, …) are deliberately NOT here — they stay
|
|
33
|
+
* explicit H7 gaps until translated.
|
|
34
|
+
*/
|
|
35
|
+
export declare const STRUCTURAL_TYPES_EXTENDED: Set<string>;
|
|
36
|
+
/**
|
|
37
|
+
* H7 companion (2026-09-20): FEM workbench objects carry SIMULATION semantics
|
|
38
|
+
* (analysis containers, meshes, solver settings, boundary conditions, result
|
|
39
|
+
* objects, post-processing filters) — no modeling geometry. They used to fall
|
|
40
|
+
* into `type-not-whitelisted` and block whole files whose modeling part was a
|
|
41
|
+
* single box. Like structural types they are `preserved-only`; their
|
|
42
|
+
* regenerable field data (FemMesh / result Data properties) is deliberately NOT
|
|
43
|
+
* carried into the container.
|
|
44
|
+
*
|
|
45
|
+
* DECISION (2026-09-21): the rule is the NAMESPACE, not an enumerated list.
|
|
46
|
+
* Census of the 56-sample corpus (fcstd-port `out/probe-fem-types.mjs`): 29
|
|
47
|
+
* distinct `Fem::` types, **every one** an analysis / mesh / solver / result /
|
|
48
|
+
* constraint / filter object, zero modeling features; and the 3,201-file
|
|
49
|
+
* FreeCAD library contains **0** `Fem::` objects, so the rule's blast radius is
|
|
50
|
+
* exactly the FEM workbench. The previous enumerated list cost four
|
|
51
|
+
* whack-a-mole rounds (each fix uncovered the next layer, because the sweep
|
|
52
|
+
* report records only the first 4 reasons per file: fixed
|
|
53
|
+
* FluidBoundary/Gear/Heatflux/InitialTemperature, then
|
|
54
|
+
* PlaneRotation/Pulley/Temperature/Transform, then three more). The namespace
|
|
55
|
+
* closes the family permanently.
|
|
56
|
+
*
|
|
57
|
+
* Note this classification is a LAST resort: an object with shape evidence is
|
|
58
|
+
* taken by the shape-asset path and a Python object by `python-opaque` long
|
|
59
|
+
* before `auditMapping` consults this predicate.
|
|
60
|
+
*
|
|
61
|
+
* Remote task on record (user decision, 2026-09-20): faijs will port FreeCAD's
|
|
62
|
+
* FEM analysis capability in the future — separate feature; this classification
|
|
63
|
+
* only stops simulation objects from blocking conversion.
|
|
64
|
+
*
|
|
65
|
+
* @param type - the FCStd object type, e.g. "Fem::ConstraintFixed".
|
|
66
|
+
* @returns true when the type belongs to the FEM (simulation) workbench.
|
|
67
|
+
*/
|
|
68
|
+
export declare function isFemStructural(type: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* True when the type carries no modeling semantics — structural/datum/
|
|
71
|
+
* container/drawing/documentation or FEM simulation.
|
|
72
|
+
*
|
|
73
|
+
* `codegen.ts` uses this to short-circuit such objects to `preserved-only`
|
|
74
|
+
* before translation, which is what keeps datum planes out of Body feature
|
|
75
|
+
* chains and keeps their `.brp` face assets out of the shape-asset import path.
|
|
76
|
+
* `convert.ts` uses it for the C4 post-translation reclassification, so the two
|
|
77
|
+
* can never disagree.
|
|
78
|
+
*
|
|
79
|
+
* @param type - the FCStd object type, e.g. "PartDesign::Plane".
|
|
80
|
+
* @returns true when the object must never produce a modeling call or be a shape asset.
|
|
81
|
+
*/
|
|
82
|
+
export declare function isNonModelingType(type: string): boolean;
|
|
83
|
+
//# sourceMappingURL=structural-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-types.d.ts","sourceRoot":"","sources":["../../src/fcstd/structural-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;8EAU8E;AAC9E,eAAO,MAAM,gBAAgB,aAoB3B,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,aAOpC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIvD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-modeling FCStd object types — the single source of truth shared by the
|
|
3
|
+
* C4 disposition audit (`convert.ts`) and the code generator (`codegen.ts`).
|
|
4
|
+
*
|
|
5
|
+
* Why a separate module: `codegen.ts` must skip these objects BEFORE it calls
|
|
6
|
+
* the translator (a datum plane must never enter a Body's feature chain), and
|
|
7
|
+
* `convert.ts` must reclassify them after translation. Keeping the sets in
|
|
8
|
+
* `convert.ts` would make `codegen.ts` import it back (convert → codegen), so
|
|
9
|
+
* the knowledge lives here with zero dependencies.
|
|
10
|
+
*
|
|
11
|
+
* C4 contract: an object in these sets is never a translation gap, and its
|
|
12
|
+
* geometry is never emitted as a modeling call. See the per-set docs below for
|
|
13
|
+
* the evidence behind each classification.
|
|
14
|
+
*/
|
|
15
|
+
/** Non-modeling structural/datum types: never translation gaps. They carry
|
|
16
|
+
* no feature semantics (containers, datum planes/lines/origins, groups) —
|
|
17
|
+
* their semantics are consumed by the translator (Body.Group ordering,
|
|
18
|
+
* datum-plane UpToFace anchors), not emitted as cad calls.
|
|
19
|
+
*
|
|
20
|
+
* GOTCHA (PadTest, 2026-09-21): a `PartDesign::Plane` also stores a `Shape`
|
|
21
|
+
* `.brp` member — the plane FACE. The generic "any object with shape evidence
|
|
22
|
+
* is a shape asset" rule therefore imported it and fed it into the Body's
|
|
23
|
+
* union chain, which both corrupts the solid and fails at run time
|
|
24
|
+
* (`[loadBrep] imported shape contains no solid sub-shapes`). Datum shapes are
|
|
25
|
+
* SUPPORT geometry for attachment/up-to resolution, never modeling solids. */
|
|
26
|
+
export const STRUCTURAL_TYPES = new Set([
|
|
27
|
+
'PartDesign::Body', 'App::Origin', 'App::Plane', 'App::Line',
|
|
28
|
+
'App::DocumentObjectGroup', 'App::Part', 'PartDesign::Plane', 'PartDesign::Line',
|
|
29
|
+
'PartDesign::CoordinateSystem',
|
|
30
|
+
// H10 companion fix (plan §3.5): datum/annotation types, not modeling
|
|
31
|
+
// features — previously misclassified as translation gaps.
|
|
32
|
+
'App::Point', 'App::Annotation',
|
|
33
|
+
// 2026-09-20 sweep regression triage: Part workbench datum plane (same
|
|
34
|
+
// semantics as App::Plane) and a document text record — non-modeling.
|
|
35
|
+
'Part::Plane', 'App::TextDocument',
|
|
36
|
+
// Part workbench datum line (FEMExample) — same semantics as App::Line.
|
|
37
|
+
'Part::Line',
|
|
38
|
+
// 2026-09-21 triage (ArchDetail corpus): TechDraw is FreeCAD's 2D DRAWING
|
|
39
|
+
// workbench. A page, an SVG template and a projected view are documentation
|
|
40
|
+
// output — they render a shape onto a sheet and own no modeling geometry
|
|
41
|
+
// (probe: none of the three carries a Shape .brp; DrawViewDraft only links
|
|
42
|
+
// its source via `Source`, and a page links its template + views). Same
|
|
43
|
+
// category as App::TextDocument/App::Annotation above. Their modeling
|
|
44
|
+
// content is translated independently through the objects they reference.
|
|
45
|
+
'TechDraw::DrawPage', 'TechDraw::DrawSVGTemplate', 'TechDraw::DrawViewDraft',
|
|
46
|
+
]);
|
|
47
|
+
/**
|
|
48
|
+
* 2026-09-20 sweep triage: assembly/import container types — links, assembly
|
|
49
|
+
* containers, import placeholders (Inventor/VRML). They reference or embed
|
|
50
|
+
* external/other geometry but produce no modeling semantics of their own;
|
|
51
|
+
* preserved-only. Modeling features (Part::Mirroring,
|
|
52
|
+
* PartDesign::AdditiveSphere, …) are deliberately NOT here — they stay
|
|
53
|
+
* explicit H7 gaps until translated.
|
|
54
|
+
*/
|
|
55
|
+
export const STRUCTURAL_TYPES_EXTENDED = new Set([
|
|
56
|
+
'App::Link',
|
|
57
|
+
'App::LinkElement',
|
|
58
|
+
'Assembly::AssemblyObject',
|
|
59
|
+
'Assembly::JointGroup',
|
|
60
|
+
'App::InventorObject',
|
|
61
|
+
'App::VRMLObject',
|
|
62
|
+
]);
|
|
63
|
+
/**
|
|
64
|
+
* H7 companion (2026-09-20): FEM workbench objects carry SIMULATION semantics
|
|
65
|
+
* (analysis containers, meshes, solver settings, boundary conditions, result
|
|
66
|
+
* objects, post-processing filters) — no modeling geometry. They used to fall
|
|
67
|
+
* into `type-not-whitelisted` and block whole files whose modeling part was a
|
|
68
|
+
* single box. Like structural types they are `preserved-only`; their
|
|
69
|
+
* regenerable field data (FemMesh / result Data properties) is deliberately NOT
|
|
70
|
+
* carried into the container.
|
|
71
|
+
*
|
|
72
|
+
* DECISION (2026-09-21): the rule is the NAMESPACE, not an enumerated list.
|
|
73
|
+
* Census of the 56-sample corpus (fcstd-port `out/probe-fem-types.mjs`): 29
|
|
74
|
+
* distinct `Fem::` types, **every one** an analysis / mesh / solver / result /
|
|
75
|
+
* constraint / filter object, zero modeling features; and the 3,201-file
|
|
76
|
+
* FreeCAD library contains **0** `Fem::` objects, so the rule's blast radius is
|
|
77
|
+
* exactly the FEM workbench. The previous enumerated list cost four
|
|
78
|
+
* whack-a-mole rounds (each fix uncovered the next layer, because the sweep
|
|
79
|
+
* report records only the first 4 reasons per file: fixed
|
|
80
|
+
* FluidBoundary/Gear/Heatflux/InitialTemperature, then
|
|
81
|
+
* PlaneRotation/Pulley/Temperature/Transform, then three more). The namespace
|
|
82
|
+
* closes the family permanently.
|
|
83
|
+
*
|
|
84
|
+
* Note this classification is a LAST resort: an object with shape evidence is
|
|
85
|
+
* taken by the shape-asset path and a Python object by `python-opaque` long
|
|
86
|
+
* before `auditMapping` consults this predicate.
|
|
87
|
+
*
|
|
88
|
+
* Remote task on record (user decision, 2026-09-20): faijs will port FreeCAD's
|
|
89
|
+
* FEM analysis capability in the future — separate feature; this classification
|
|
90
|
+
* only stops simulation objects from blocking conversion.
|
|
91
|
+
*
|
|
92
|
+
* @param type - the FCStd object type, e.g. "Fem::ConstraintFixed".
|
|
93
|
+
* @returns true when the type belongs to the FEM (simulation) workbench.
|
|
94
|
+
*/
|
|
95
|
+
export function isFemStructural(type) {
|
|
96
|
+
return type.startsWith('Fem::');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* True when the type carries no modeling semantics — structural/datum/
|
|
100
|
+
* container/drawing/documentation or FEM simulation.
|
|
101
|
+
*
|
|
102
|
+
* `codegen.ts` uses this to short-circuit such objects to `preserved-only`
|
|
103
|
+
* before translation, which is what keeps datum planes out of Body feature
|
|
104
|
+
* chains and keeps their `.brp` face assets out of the shape-asset import path.
|
|
105
|
+
* `convert.ts` uses it for the C4 post-translation reclassification, so the two
|
|
106
|
+
* can never disagree.
|
|
107
|
+
*
|
|
108
|
+
* @param type - the FCStd object type, e.g. "PartDesign::Plane".
|
|
109
|
+
* @returns true when the object must never produce a modeling call or be a shape asset.
|
|
110
|
+
*/
|
|
111
|
+
export function isNonModelingType(type) {
|
|
112
|
+
return STRUCTURAL_TYPES.has(type)
|
|
113
|
+
|| STRUCTURAL_TYPES_EXTENDED.has(type)
|
|
114
|
+
|| isFemStructural(type);
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=structural-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-types.js","sourceRoot":"","sources":["../../src/fcstd/structural-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;8EAU8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IACtC,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW;IAC5D,0BAA0B,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB;IAChF,8BAA8B;IAC9B,sEAAsE;IACtE,2DAA2D;IAC3D,YAAY,EAAE,iBAAiB;IAC/B,uEAAuE;IACvE,sEAAsE;IACtE,aAAa,EAAE,mBAAmB;IAClC,wEAAwE;IACxE,YAAY;IACZ,0EAA0E;IAC1E,4EAA4E;IAC5E,yEAAyE;IACzE,2EAA2E;IAC3E,wEAAwE;IACxE,sEAAsE;IACtE,0EAA0E;IAC1E,oBAAoB,EAAE,2BAA2B,EAAE,yBAAyB;CAC7E,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IAC/C,WAAW;IACX,kBAAkB;IAClB,0BAA0B;IAC1B,sBAAsB;IACtB,qBAAqB;IACrB,iBAAiB;CAClB,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;WAC5B,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC;WACnC,eAAe,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["/**\n * Non-modeling FCStd object types — the single source of truth shared by the\n * C4 disposition audit (`convert.ts`) and the code generator (`codegen.ts`).\n *\n * Why a separate module: `codegen.ts` must skip these objects BEFORE it calls\n * the translator (a datum plane must never enter a Body's feature chain), and\n * `convert.ts` must reclassify them after translation. Keeping the sets in\n * `convert.ts` would make `codegen.ts` import it back (convert → codegen), so\n * the knowledge lives here with zero dependencies.\n *\n * C4 contract: an object in these sets is never a translation gap, and its\n * geometry is never emitted as a modeling call. See the per-set docs below for\n * the evidence behind each classification.\n */\n\n/** Non-modeling structural/datum types: never translation gaps. They carry\n * no feature semantics (containers, datum planes/lines/origins, groups) —\n * their semantics are consumed by the translator (Body.Group ordering,\n * datum-plane UpToFace anchors), not emitted as cad calls.\n *\n * GOTCHA (PadTest, 2026-09-21): a `PartDesign::Plane` also stores a `Shape`\n * `.brp` member — the plane FACE. The generic \"any object with shape evidence\n * is a shape asset\" rule therefore imported it and fed it into the Body's\n * union chain, which both corrupts the solid and fails at run time\n * (`[loadBrep] imported shape contains no solid sub-shapes`). Datum shapes are\n * SUPPORT geometry for attachment/up-to resolution, never modeling solids. */\nexport const STRUCTURAL_TYPES = new Set([\n 'PartDesign::Body', 'App::Origin', 'App::Plane', 'App::Line',\n 'App::DocumentObjectGroup', 'App::Part', 'PartDesign::Plane', 'PartDesign::Line',\n 'PartDesign::CoordinateSystem',\n // H10 companion fix (plan §3.5): datum/annotation types, not modeling\n // features — previously misclassified as translation gaps.\n 'App::Point', 'App::Annotation',\n // 2026-09-20 sweep regression triage: Part workbench datum plane (same\n // semantics as App::Plane) and a document text record — non-modeling.\n 'Part::Plane', 'App::TextDocument',\n // Part workbench datum line (FEMExample) — same semantics as App::Line.\n 'Part::Line',\n // 2026-09-21 triage (ArchDetail corpus): TechDraw is FreeCAD's 2D DRAWING\n // workbench. A page, an SVG template and a projected view are documentation\n // output — they render a shape onto a sheet and own no modeling geometry\n // (probe: none of the three carries a Shape .brp; DrawViewDraft only links\n // its source via `Source`, and a page links its template + views). Same\n // category as App::TextDocument/App::Annotation above. Their modeling\n // content is translated independently through the objects they reference.\n 'TechDraw::DrawPage', 'TechDraw::DrawSVGTemplate', 'TechDraw::DrawViewDraft',\n]);\n\n/**\n * 2026-09-20 sweep triage: assembly/import container types — links, assembly\n * containers, import placeholders (Inventor/VRML). They reference or embed\n * external/other geometry but produce no modeling semantics of their own;\n * preserved-only. Modeling features (Part::Mirroring,\n * PartDesign::AdditiveSphere, …) are deliberately NOT here — they stay\n * explicit H7 gaps until translated.\n */\nexport const STRUCTURAL_TYPES_EXTENDED = new Set([\n 'App::Link',\n 'App::LinkElement',\n 'Assembly::AssemblyObject',\n 'Assembly::JointGroup',\n 'App::InventorObject',\n 'App::VRMLObject',\n]);\n\n/**\n * H7 companion (2026-09-20): FEM workbench objects carry SIMULATION semantics\n * (analysis containers, meshes, solver settings, boundary conditions, result\n * objects, post-processing filters) — no modeling geometry. They used to fall\n * into `type-not-whitelisted` and block whole files whose modeling part was a\n * single box. Like structural types they are `preserved-only`; their\n * regenerable field data (FemMesh / result Data properties) is deliberately NOT\n * carried into the container.\n *\n * DECISION (2026-09-21): the rule is the NAMESPACE, not an enumerated list.\n * Census of the 56-sample corpus (fcstd-port `out/probe-fem-types.mjs`): 29\n * distinct `Fem::` types, **every one** an analysis / mesh / solver / result /\n * constraint / filter object, zero modeling features; and the 3,201-file\n * FreeCAD library contains **0** `Fem::` objects, so the rule's blast radius is\n * exactly the FEM workbench. The previous enumerated list cost four\n * whack-a-mole rounds (each fix uncovered the next layer, because the sweep\n * report records only the first 4 reasons per file: fixed\n * FluidBoundary/Gear/Heatflux/InitialTemperature, then\n * PlaneRotation/Pulley/Temperature/Transform, then three more). The namespace\n * closes the family permanently.\n *\n * Note this classification is a LAST resort: an object with shape evidence is\n * taken by the shape-asset path and a Python object by `python-opaque` long\n * before `auditMapping` consults this predicate.\n *\n * Remote task on record (user decision, 2026-09-20): faijs will port FreeCAD's\n * FEM analysis capability in the future — separate feature; this classification\n * only stops simulation objects from blocking conversion.\n *\n * @param type - the FCStd object type, e.g. \"Fem::ConstraintFixed\".\n * @returns true when the type belongs to the FEM (simulation) workbench.\n */\nexport function isFemStructural(type: string): boolean {\n return type.startsWith('Fem::');\n}\n\n/**\n * True when the type carries no modeling semantics — structural/datum/\n * container/drawing/documentation or FEM simulation.\n *\n * `codegen.ts` uses this to short-circuit such objects to `preserved-only`\n * before translation, which is what keeps datum planes out of Body feature\n * chains and keeps their `.brp` face assets out of the shape-asset import path.\n * `convert.ts` uses it for the C4 post-translation reclassification, so the two\n * can never disagree.\n *\n * @param type - the FCStd object type, e.g. \"PartDesign::Plane\".\n * @returns true when the object must never produce a modeling call or be a shape asset.\n */\nexport function isNonModelingType(type: string): boolean {\n return STRUCTURAL_TYPES.has(type)\n || STRUCTURAL_TYPES_EXTENDED.has(type)\n || isFemStructural(type);\n}\n"]}
|
package/dist/fcstd/unpack.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import { type Result } from '../
|
|
1
|
+
import { type Result } from '../api/result.js';
|
|
2
|
+
/**
|
|
3
|
+
* One raw file inside the FCStd ZIP container.
|
|
4
|
+
*/
|
|
2
5
|
export interface FcstdMember {
|
|
3
6
|
/** path inside the ZIP, e.g. "Document.xml", "PartShape.brp" */
|
|
4
7
|
path: string;
|
|
8
|
+
/** the member's raw bytes */
|
|
5
9
|
bytes: Uint8Array;
|
|
6
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The unpacked FCStd container: all ZIP members plus the advisory comment.
|
|
13
|
+
*/
|
|
7
14
|
export interface FcstdArchive {
|
|
8
15
|
members: Map<string, Uint8Array>;
|
|
9
16
|
/** advisory ZIP comment; may be empty (2/56 samples have empty comments) */
|
|
10
17
|
zipComment: string;
|
|
11
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Structured unpack failure: not a valid ZIP, or missing root `Document.xml`.
|
|
21
|
+
*/
|
|
12
22
|
export type UnpackError = {
|
|
13
23
|
kind: 'not-zip';
|
|
14
24
|
message: string;
|
|
@@ -18,8 +28,17 @@ export type UnpackError = {
|
|
|
18
28
|
};
|
|
19
29
|
/**
|
|
20
30
|
* Unpack an FCStd file. Only requirement: valid ZIP + root `Document.xml`.
|
|
31
|
+
*
|
|
32
|
+
* @param data - the raw FCStd file bytes.
|
|
33
|
+
* @returns the unpacked archive, or a structured UnpackError.
|
|
21
34
|
*/
|
|
22
35
|
export declare function unpackFcstd(data: Uint8Array): Result<FcstdArchive, UnpackError>;
|
|
23
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* UTF-8 text decode helper for XML members.
|
|
38
|
+
*
|
|
39
|
+
* @param archive - the unpacked FCStd container.
|
|
40
|
+
* @param path - member path inside the ZIP, e.g. "Document.xml".
|
|
41
|
+
* @returns the member decoded as UTF-8 text, or undefined when absent.
|
|
42
|
+
*/
|
|
24
43
|
export declare function memberText(archive: FcstdArchive, path: string): string | undefined;
|
|
25
44
|
//# sourceMappingURL=unpack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unpack.d.ts","sourceRoot":"","sources":["../../src/fcstd/unpack.ts"],"names":[],"mappings":"AAUA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"unpack.d.ts","sourceRoot":"","sources":["../../src/fcstd/unpack.ts"],"names":[],"mappings":"AAUA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACjC,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAkB/E;AAiBD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIlF"}
|