@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-geo.js","sourceRoot":"","sources":["../../src/fcstd/external-geo.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M6.3 — external geometry resolution: decode ExternalGeometry links\n * (App::PropertyLinkSubList), load the source object's .brp via OCCT,\n * extract the named edge polyline (TopExp::MapShapes + IndexedMap order —\n * Edge13 = wireframe edgeGroups[12], verified against hole_puzzle.fcstd),\n * and project it into sketch-local 2D via the sketch Placement inverse.\n *\n * Result: fixed 2D segments/points that the solver treats as immutable\n * constraints targets (geoId -3, -4, ... in link order).\n */\nimport { initOcctWasm } from '../occt-kernel/occtKernel.js';\nimport { memberText, type FcstdArchive } from './unpack.js';\nimport type { FcstdDocument, FcstdObject, FcstdProperty } from './document.js';\n\nexport interface ExternalLink {\n /** source object name, e.g. \"Chamfer002\" */\n obj: string;\n /** sub-element name, e.g. \"Edge13\" */\n sub: string;\n /** resolved sketch-local 2D polyline */\n polyline: [number, number][];\n}\n\nexport interface ExternalGeoResult {\n links: ExternalLink[];\n failures: { obj: string; sub: string; reason: string }[];\n}\n\n/** Quaternion (x,y,z,w) inverse-rotate + translate into sketch-local frame. */\nfunction makeInverseTransformer(q: [number, number, number, number], p: [number, number, number]) {\n const n = Math.hypot(q[0], q[1], q[2], q[3]);\n const [qx, qy, qz, qw] = [-q[0] / n, -q[1] / n, -q[2] / n, q[3] / n]; // conjugate\n return (w: [number, number, number]): [number, number, number] => {\n // local = R⁻¹ · (world − P): subtract the translation FIRST, then rotate\n // by the conjugate quaternion. GOTCHA (probe-hole-ext.ts): rotating first\n // and subtracting after (R⁻¹·v − P) is only correct for identity rotation\n // — with Sketch005's 90° placement it shifted projected points by the\n // rotated translation (−140,30 instead of (−40,40)) and the solver chased\n // the wrong frame (delta 1.0e2).\n const [vx, vy, vz] = [w[0] - p[0], w[1] - p[1], w[2] - p[2]];\n const tx = 2 * (qy * vz - qz * vy);\n const ty = 2 * (qz * vx - qx * vz);\n const tz = 2 * (qx * vy - qy * vx);\n const rx = vx + qw * tx + (qy * tz - qz * ty);\n const ry = vy + qw * ty + (qz * tx - qx * tz);\n const rz = vz + qw * tz + (qx * ty - qy * tx);\n return [rx, ry, rz];\n };\n}\n\nfunction placementOf(obj: FcstdObject): { q: [number, number, number, number]; p: [number, number, number] } {\n const el = obj.properties.get('Placement')?.children[0];\n const a = el?.attributes ?? {};\n return {\n p: [Number(a['Px'] ?? 0), Number(a['Py'] ?? 0), Number(a['Pz'] ?? 0)],\n q: [Number(a['Q0'] ?? 0), Number(a['Q1'] ?? 0), Number(a['Q2'] ?? 0), Number(a['Q3'] ?? 1)],\n };\n}\n\n/**\n * Resolve every external link of a sketch to sketch-local 2D polylines.\n * `externalGeoProp` is the sketch's ExternalGeometry property.\n */\nexport async function resolveExternalGeometry(\n externalGeoProp: FcstdProperty | undefined,\n doc: FcstdDocument,\n archive: FcstdArchive,\n sketchPlacement: FcstdProperty | undefined,\n): Promise<ExternalGeoResult> {\n const links: ExternalLink[] = [];\n const failures: ExternalGeoResult['failures'] = [];\n const listEl = externalGeoProp?.children[0];\n if (!listEl) return { links, failures };\n\n const skPl = placementOf({ name: '', type: '', properties: new Map([['Placement', sketchPlacement ?? { name: 'Placement', type: '', tagName: 'Property', children: [], valueXml: '', valueText: '', attributes: {} } as FcstdProperty]]) as never });\n const toLocal = makeInverseTransformer(skPl.q, skPl.p);\n\n const kernel: {\n fromBREP: (s: string) => unknown;\n wireframe: (s: unknown, deflection: number) => { points: Float32Array; edgeGroups: number[] };\n } = (await initOcctWasm()) as never;\n\n const brpCache = new Map<string, { points: Float32Array; edgeGroups: number[] } | undefined>();\n const wireframeOf = (objName: string) => {\n if (brpCache.has(objName)) return brpCache.get(objName);\n const src = doc.objects.find((o) => o.name === objName);\n const brpFile = src?.properties.get('Shape')?.children[0]?.attributes['file'];\n if (!brpFile) {\n brpCache.set(objName, undefined);\n return undefined;\n }\n const brp = memberText(archive, brpFile);\n if (!brp) {\n brpCache.set(objName, undefined);\n return undefined;\n }\n try {\n const shape = kernel.fromBREP(brp);\n const wf = kernel.wireframe(shape, 0.01);\n brpCache.set(objName, wf);\n return wf;\n } catch {\n brpCache.set(objName, undefined);\n return undefined;\n }\n };\n\n for (const link of listEl.children) {\n const obj = link.attributes['obj'] ?? '';\n const sub = link.attributes['sub'] ?? '';\n const ord = Number(sub.replace('Edge', ''));\n if (!obj || !sub.startsWith('Edge') || !Number.isInteger(ord) || ord < 1) {\n failures.push({ obj, sub, reason: `unsupported sub-element: ${sub}` });\n continue;\n }\n const wf = wireframeOf(obj);\n if (!wf) {\n failures.push({ obj, sub, reason: 'source shape not loadable' });\n continue;\n }\n const idx = ord - 1; // Edge13 → edgeGroups[12]\n const g0 = wf.edgeGroups[idx * 3];\n const g1 = wf.edgeGroups[idx * 3 + 1];\n if (g0 === undefined || g1 === undefined) {\n failures.push({ obj, sub, reason: `edge ordinal out of range (${wf.edgeGroups.length / 3} edges)` });\n continue;\n }\n const n = Math.floor(g1 / 3);\n const polyline: [number, number][] = [];\n for (let p = 0; p < n; p++) {\n const w: [number, number, number] = [\n wf.points[g0 + p * 3]!, wf.points[g0 + p * 3 + 1]!, wf.points[g0 + p * 3 + 2]!,\n ];\n const l = toLocal(w);\n polyline.push([l[0], l[1]]);\n }\n // drop consecutive duplicates\n const deduped = polyline.filter(\n (pt, i) => i === 0 || Math.hypot(pt[0] - polyline[i - 1]![0], pt[1] - polyline[i - 1]![1]) > 1e-9,\n );\n if (deduped.length >= 2) links.push({ obj, sub, polyline: deduped });\n else failures.push({ obj, sub, reason: 'degenerate polyline' });\n }\n return { links, failures };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"external-geo.js","sourceRoot":"","sources":["../../src/fcstd/external-geo.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M6.3 — external geometry resolution: decode ExternalGeometry links\n * (App::PropertyLinkSubList), load the source object's .brp via OCCT,\n * extract the named edge polyline (TopExp::MapShapes + IndexedMap order —\n * Edge13 = wireframe edgeGroups[12], verified against hole_puzzle.fcstd),\n * and project it into sketch-local 2D via the sketch Placement inverse.\n *\n * Result: fixed 2D segments/points that the solver treats as immutable\n * constraints targets (geoId -3, -4, ... in link order).\n */\nimport { initOcctWasm } from '../occt-kernel/occtKernel.js';\nimport { memberText, type FcstdArchive } from './unpack.js';\nimport type { FcstdDocument, FcstdObject, FcstdProperty } from './document.js';\n\n/**\n * One resolved external-geometry link of a sketch.\n */\nexport interface ExternalLink {\n /** source object name, e.g. \"Chamfer002\" */\n obj: string;\n /** sub-element name, e.g. \"Edge13\" */\n sub: string;\n /** resolved sketch-local 2D polyline */\n polyline: [number, number][];\n}\n\n/**\n * Result of external-geometry resolution: successfully projected links plus\n * per-link failures (with a human-readable reason) for the caller to report.\n */\nexport interface ExternalGeoResult {\n links: ExternalLink[];\n failures: { obj: string; sub: string; reason: string }[];\n}\n\n/** Quaternion (x,y,z,w) inverse-rotate + translate into sketch-local frame. */\nfunction makeInverseTransformer(q: [number, number, number, number], p: [number, number, number]) {\n const n = Math.hypot(q[0], q[1], q[2], q[3]);\n const [qx, qy, qz, qw] = [-q[0] / n, -q[1] / n, -q[2] / n, q[3] / n]; // conjugate\n return (w: [number, number, number]): [number, number, number] => {\n // local = R⁻¹ · (world − P): subtract the translation FIRST, then rotate\n // by the conjugate quaternion. GOTCHA (probe-hole-ext.ts): rotating first\n // and subtracting after (R⁻¹·v − P) is only correct for identity rotation\n // — with Sketch005's 90° placement it shifted projected points by the\n // rotated translation (−140,30 instead of (−40,40)) and the solver chased\n // the wrong frame (delta 1.0e2).\n const [vx, vy, vz] = [w[0] - p[0], w[1] - p[1], w[2] - p[2]];\n const tx = 2 * (qy * vz - qz * vy);\n const ty = 2 * (qz * vx - qx * vz);\n const tz = 2 * (qx * vy - qy * vx);\n const rx = vx + qw * tx + (qy * tz - qz * ty);\n const ry = vy + qw * ty + (qz * tx - qx * tz);\n const rz = vz + qw * tz + (qx * ty - qy * tx);\n return [rx, ry, rz];\n };\n}\n\nfunction placementOf(obj: FcstdObject): { q: [number, number, number, number]; p: [number, number, number] } {\n const el = obj.properties.get('Placement')?.children[0];\n const a = el?.attributes ?? {};\n return {\n p: [Number(a['Px'] ?? 0), Number(a['Py'] ?? 0), Number(a['Pz'] ?? 0)],\n q: [Number(a['Q0'] ?? 0), Number(a['Q1'] ?? 0), Number(a['Q2'] ?? 0), Number(a['Q3'] ?? 1)],\n };\n}\n\n/**\n * The `.brp` member holding an object's shape: the `Shape` property when\n * present, else `SubShape` (GOTCHA, hole_puzzle corpus 2026-09-20: PartDesign\n * features like Chamfer002/Pocket002 store their result cache in SubShape and\n * have NO Shape property — external links pointing at them failed with\n * \"source shape not loadable\" before the fallback existed).\n *\n * @param obj - the FCStd object to inspect.\n * @returns the .brp member file name, or undefined when neither Shape nor SubShape carries one.\n */\nexport function shapeBrpFile(obj: FcstdObject): string | undefined {\n return obj.properties.get('Shape')?.children[0]?.attributes['file']\n ?? obj.properties.get('SubShape')?.children[0]?.attributes['file'];\n}\n\n/**\n * Resolve every external link of a sketch to sketch-local 2D polylines.\n *\n * @param externalGeoProp - the sketch's ExternalGeometry property.\n * @param doc - the parsed FCStd document, used to locate source objects and their shapes.\n * @param archive - the FCStd container, used to read the source `.brp` shape files.\n * @param sketchPlacement - the sketch's Placement property, whose inverse maps\n * source geometry into sketch-local coordinates.\n * @returns the resolved sketch-local polylines per link, plus a failure entry\n * (with reason) for every link that could not be resolved.\n */\nexport async function resolveExternalGeometry(\n externalGeoProp: FcstdProperty | undefined,\n doc: FcstdDocument,\n archive: FcstdArchive,\n sketchPlacement: FcstdProperty | undefined,\n): Promise<ExternalGeoResult> {\n const links: ExternalLink[] = [];\n const failures: ExternalGeoResult['failures'] = [];\n const listEl = externalGeoProp?.children[0];\n if (!listEl) return { links, failures };\n\n const skPl = placementOf({ name: '', type: '', properties: new Map([['Placement', sketchPlacement ?? { name: 'Placement', type: '', tagName: 'Property', children: [], valueXml: '', valueText: '', attributes: {} } as FcstdProperty]]) as never });\n const toLocal = makeInverseTransformer(skPl.q, skPl.p);\n\n const kernel: {\n fromBREP: (s: string) => unknown;\n wireframe: (s: unknown, deflection: number) => { points: Float32Array; edgeGroups: number[] };\n } = (await initOcctWasm()) as never;\n\n const brpCache = new Map<string, { points: Float32Array; edgeGroups: number[] } | undefined>();\n const wireframeOf = (objName: string) => {\n if (brpCache.has(objName)) return brpCache.get(objName);\n const src = doc.objects.find((o) => o.name === objName);\n const brpFile = src ? shapeBrpFile(src) : undefined;\n if (!brpFile) {\n brpCache.set(objName, undefined);\n return undefined;\n }\n const brp = memberText(archive, brpFile);\n if (!brp) {\n brpCache.set(objName, undefined);\n return undefined;\n }\n try {\n const shape = kernel.fromBREP(brp);\n const wf = kernel.wireframe(shape, 0.01);\n brpCache.set(objName, wf);\n return wf;\n } catch {\n brpCache.set(objName, undefined);\n return undefined;\n }\n };\n\n for (const link of listEl.children) {\n const obj = link.attributes['obj'] ?? '';\n const sub = link.attributes['sub'] ?? '';\n const ord = Number(sub.replace('Edge', ''));\n if (!obj || !sub.startsWith('Edge') || !Number.isInteger(ord) || ord < 1) {\n failures.push({ obj, sub, reason: `unsupported sub-element: ${sub}` });\n continue;\n }\n const wf = wireframeOf(obj);\n if (!wf) {\n failures.push({ obj, sub, reason: 'source shape not loadable' });\n continue;\n }\n const idx = ord - 1; // Edge13 → edgeGroups[12]\n const g0 = wf.edgeGroups[idx * 3];\n const g1 = wf.edgeGroups[idx * 3 + 1];\n if (g0 === undefined || g1 === undefined) {\n failures.push({ obj, sub, reason: `edge ordinal out of range (${wf.edgeGroups.length / 3} edges)` });\n continue;\n }\n const n = Math.floor(g1 / 3);\n const polyline: [number, number][] = [];\n for (let p = 0; p < n; p++) {\n const w: [number, number, number] = [\n wf.points[g0 + p * 3]!, wf.points[g0 + p * 3 + 1]!, wf.points[g0 + p * 3 + 2]!,\n ];\n const l = toLocal(w);\n polyline.push([l[0], l[1]]);\n }\n // drop consecutive duplicates\n const deduped = polyline.filter(\n (pt, i) => i === 0 || Math.hypot(pt[0] - polyline[i - 1]![0], pt[1] - polyline[i - 1]![1]) > 1e-9,\n );\n if (deduped.length >= 2) links.push({ obj, sub, polyline: deduped });\n else failures.push({ obj, sub, reason: 'degenerate polyline' });\n }\n return { links, failures };\n}\n"]}
|
|
@@ -11,9 +11,13 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { FcstdObject } from './document.js';
|
|
13
13
|
import { type ExpressionBinding } from './expressions.js';
|
|
14
|
+
/**
|
|
15
|
+
* One cad-op call in the M4 call plan (lowered to .fai.js by M5).
|
|
16
|
+
*/
|
|
14
17
|
export interface CadCall {
|
|
15
18
|
/** target variable name (partN, assigned by M5) */
|
|
16
19
|
out: string;
|
|
20
|
+
/** cad-op name, e.g. "cad.box" */
|
|
17
21
|
op: string;
|
|
18
22
|
/** positional + named params, JSON-serializable */
|
|
19
23
|
params: Record<string, unknown>;
|
|
@@ -23,6 +27,14 @@ export interface CadCall {
|
|
|
23
27
|
literals?: unknown[];
|
|
24
28
|
/** FCStd object this call came from */
|
|
25
29
|
source: string;
|
|
30
|
+
/**
|
|
31
|
+
* When true, `inputs` is bookkeeping-only (dependency tracking / variable
|
|
32
|
+
* remapping / consumed-set) and must NOT be rendered as positional args —
|
|
33
|
+
* the real args come from `params`. Used by params-only ops like
|
|
34
|
+
* `cad.compound` whose members live in `params.members` (rendering `inputs`
|
|
35
|
+
* positionally would shadow `params`).
|
|
36
|
+
*/
|
|
37
|
+
noPositionalArgs?: boolean;
|
|
26
38
|
}
|
|
27
39
|
/**
|
|
28
40
|
* A raw JS expression argument that M5 renders verbatim instead of JSON-encoding.
|
|
@@ -50,6 +62,10 @@ export declare function jsExpr(code: string): JsExpr;
|
|
|
50
62
|
* @returns true when `v` is a `JsExpr` marker.
|
|
51
63
|
*/
|
|
52
64
|
export declare function isJsExpr(v: unknown): v is JsExpr;
|
|
65
|
+
/**
|
|
66
|
+
* Outcome of translating one FCStd object: a cad-op call plan, an explicit
|
|
67
|
+
* bake with reason, or preserved-only (no geometry emitted).
|
|
68
|
+
*/
|
|
53
69
|
export type TranslateVerdict = {
|
|
54
70
|
kind: 'translated';
|
|
55
71
|
calls: CadCall[];
|
|
@@ -61,14 +77,50 @@ export type TranslateVerdict = {
|
|
|
61
77
|
kind: 'preserved-only';
|
|
62
78
|
reason: string;
|
|
63
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* H7 (hole_puzzle corpus, 2026-09-20): marker input for a subtract whose base
|
|
82
|
+
* is implied by the Body's feature order (no explicit BaseFeature property).
|
|
83
|
+
* Codegen retargets this at the chain head when folding the feature into its
|
|
84
|
+
* Body chain. Never a legal variable name (contains `::`), so it cannot be
|
|
85
|
+
* confused with a real input.
|
|
86
|
+
*/
|
|
87
|
+
export declare const BODY_CHAIN_BASE = "::body-chain-base::";
|
|
88
|
+
/**
|
|
89
|
+
* True when the object type is on the M4.1 translation whitelist.
|
|
90
|
+
*
|
|
91
|
+
* @param type - the FCStd object type, e.g. "Part::Box".
|
|
92
|
+
* @returns true when the type is whitelisted for translation.
|
|
93
|
+
*/
|
|
64
94
|
export declare function isWhitelisted(type: string): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* H10 (plan §3.1/§3.5): C4's Python exception, decided by PROPERTY presence —
|
|
97
|
+
* NOT by the `Python` type-name suffix. Matches the library profile's
|
|
98
|
+
* pythonObjects口径 (profile.mjs: type contains "Python" or carries
|
|
99
|
+
* Python/Proxy properties); here only the property evidence qualifies, so a
|
|
100
|
+
* Python-suffixed type without the property stays a plain translation gap.
|
|
101
|
+
* @param obj - the FCStd object to inspect.
|
|
102
|
+
* @returns true when the object is a Python-scripted feature whose serialized
|
|
103
|
+
* shape is opaque (legitimate `python-baked` under C4).
|
|
104
|
+
*/
|
|
105
|
+
export declare function isPythonOpaque(obj: FcstdObject): boolean;
|
|
65
106
|
/**
|
|
66
107
|
* M11.1/M11.2: the ExpressionEngine binding for `name`, if any. `value` is
|
|
67
108
|
* undefined for non-constant expressions (references/arithmetic) — the caller
|
|
68
109
|
* must bake with an explicit reason instead of estimating.
|
|
110
|
+
*
|
|
111
|
+
* @param obj - the FCStd object whose ExpressionEngine to inspect.
|
|
112
|
+
* @param name - the property name to look up.
|
|
113
|
+
* @returns the binding for `name`, or undefined when the object has no
|
|
114
|
+
* ExpressionEngine binding for it.
|
|
69
115
|
*/
|
|
70
116
|
export declare function expressionBindingOf(obj: FcstdObject, name: string): ExpressionBinding | undefined;
|
|
71
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* M11.2: detect a non-constant expression binding on a property.
|
|
119
|
+
*
|
|
120
|
+
* @param obj - the FCStd object whose ExpressionEngine to inspect.
|
|
121
|
+
* @param name - the property name to look up.
|
|
122
|
+
* @returns true when `name` has a binding that is NOT a constant expression.
|
|
123
|
+
*/
|
|
72
124
|
export declare function hasNonConstantBinding(obj: FcstdObject, name: string): boolean;
|
|
73
125
|
/**
|
|
74
126
|
* M9.1 — Pad/Pocket `Type` enumeration (App::PropertyEnumeration, stored as
|
|
@@ -79,6 +131,14 @@ export declare function hasNonConstantBinding(obj: FcstdObject, name: string): b
|
|
|
79
131
|
* A missing Type property means Length (0) — the FreeCAD default.
|
|
80
132
|
*/
|
|
81
133
|
export type FeatureType = 'Length' | 'ThroughAll' | 'UpToLast' | 'UpToFirst' | 'UpToFace' | 'TwoLengths' | 'unknown';
|
|
134
|
+
/**
|
|
135
|
+
* Read the Pad/Pocket `Type` enumeration of an object (M9.1).
|
|
136
|
+
*
|
|
137
|
+
* @param obj - the FCStd Pad or Pocket object.
|
|
138
|
+
* @param kind - which type-enum table to apply (Pad vs Pocket labels differ).
|
|
139
|
+
* @returns the parsed feature type; 'Length' when Type is missing, 'unknown'
|
|
140
|
+
* when the stored label/index is not recognized.
|
|
141
|
+
*/
|
|
82
142
|
export declare function featureTypeOf(obj: FcstdObject, kind: 'pad' | 'pocket'): FeatureType;
|
|
83
143
|
/**
|
|
84
144
|
* Parse a PartDesign ReferenceAxis reference into a 3D axis + pivot point.
|
|
@@ -88,12 +148,21 @@ export declare function featureTypeOf(obj: FcstdObject, kind: 'pad' | 'pocket'):
|
|
|
88
148
|
* that PartDesign revolves around = +Z) or an edge/vertex of another feature.
|
|
89
149
|
* Edge/vertex axes require resolving referenced geometry, which the port does
|
|
90
150
|
* not yet do (explicit downgrade, no silent loss).
|
|
151
|
+
*
|
|
152
|
+
* @param ref - the ReferenceAxis (or Direction) LinkSub string, may be undefined.
|
|
153
|
+
* @returns a unit axis and pivot point, or undefined when the reference names
|
|
154
|
+
* edge/vertex geometry (unsupported).
|
|
91
155
|
*/
|
|
92
156
|
export declare function parseReferenceAxis(ref: string | undefined): {
|
|
93
157
|
axis: [number, number, number];
|
|
94
158
|
at: [number, number, number];
|
|
95
159
|
} | undefined;
|
|
96
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* Placement position (translation) of an object.
|
|
162
|
+
*
|
|
163
|
+
* @param obj - the FCStd object to read.
|
|
164
|
+
* @returns the (Px, Py, Pz) translation from its Placement, or (0,0,0) when absent.
|
|
165
|
+
*/
|
|
97
166
|
export declare function placementPos(obj: FcstdObject): [number, number, number];
|
|
98
167
|
/**
|
|
99
168
|
* M4 translate one object. `inputVar` maps a dependency object name to the
|
|
@@ -102,6 +171,19 @@ export declare function placementPos(obj: FcstdObject): [number, number, number]
|
|
|
102
171
|
* `docObjects` (optional) is the full document object list — needed by the
|
|
103
172
|
* UpToFace datum-plane path to read the target plane's Placement (plan
|
|
104
173
|
* extrude-upto-face §4.3-C1). When absent, UpToFace keeps the explicit bake.
|
|
174
|
+
*
|
|
175
|
+
* @param obj - the FCStd object to translate.
|
|
176
|
+
* @param inputVar - resolves a dependency object name to the variable holding
|
|
177
|
+
* its geometry (sketch contours or prior solid).
|
|
178
|
+
* @param docObjects - the full document object list, needed by the UpToFace
|
|
179
|
+
* datum-plane path; optional.
|
|
180
|
+
* @param shapeCarriers - objects whose Shape is stored as a .brp member; optional.
|
|
181
|
+
* @param brokenShapeAssets - objects whose Shape `file` attribute points at a missing/empty member (explicit gap); optional.
|
|
182
|
+
* @returns the cad-op call plan, or an explicit bake/preserve verdict with reason.
|
|
105
183
|
*/
|
|
106
|
-
export declare function translateObject(obj: FcstdObject, inputVar: (depName: string) => string | undefined, docObjects?: readonly FcstdObject[]
|
|
184
|
+
export declare function translateObject(obj: FcstdObject, inputVar: (depName: string) => string | undefined, docObjects?: readonly FcstdObject[],
|
|
185
|
+
/** H7: names of objects whose Shape is stored as a .brp member (probed from the ZIP). */
|
|
186
|
+
shapeCarriers?: ReadonlySet<string>,
|
|
187
|
+
/** E4: objects whose Shape `file` attribute points at a missing/empty member. */
|
|
188
|
+
brokenShapeAssets?: ReadonlySet<string>): TranslateVerdict;
|
|
107
189
|
//# sourceMappingURL=feature-translate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-translate.d.ts","sourceRoot":"","sources":["../../src/fcstd/feature-translate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAyB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-translate.d.ts","sourceRoot":"","sources":["../../src/fcstd/feature-translate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { parseExpressionEngine } from './expressions.js';
|
|
2
2
|
import { placementOf, quatToMatrix } from './placement.js';
|
|
3
|
+
import { shapeBrpFile } from './external-geo.js';
|
|
3
4
|
/**
|
|
4
5
|
* Wrap raw JS source as a verbatim argument (`JsExpr`).
|
|
5
6
|
*
|
|
@@ -18,6 +19,14 @@ export function jsExpr(code) {
|
|
|
18
19
|
export function isJsExpr(v) {
|
|
19
20
|
return typeof v === 'object' && v !== null && typeof v.__jsExpr === 'string';
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* H7 (hole_puzzle corpus, 2026-09-20): marker input for a subtract whose base
|
|
24
|
+
* is implied by the Body's feature order (no explicit BaseFeature property).
|
|
25
|
+
* Codegen retargets this at the chain head when folding the feature into its
|
|
26
|
+
* Body chain. Never a legal variable name (contains `::`), so it cannot be
|
|
27
|
+
* confused with a real input.
|
|
28
|
+
*/
|
|
29
|
+
export const BODY_CHAIN_BASE = '::body-chain-base::';
|
|
21
30
|
/** M4.1 whitelist (plan §5.5.5 measurable types only). */
|
|
22
31
|
const WHITELIST = new Set([
|
|
23
32
|
'Part::Box',
|
|
@@ -32,15 +41,40 @@ const WHITELIST = new Set([
|
|
|
32
41
|
'PartDesign::PolarPattern',
|
|
33
42
|
'PartDesign::Fillet',
|
|
34
43
|
'PartDesign::Chamfer',
|
|
35
|
-
// M13.1 (probed on real corpus —
|
|
44
|
+
// M13.1 (probed on real corpus — fcstd-port/tools/probe-m13-types.ts):
|
|
36
45
|
// Part::Compound carries a Links PropertyLinkList; Part::Sphere carries
|
|
37
46
|
// Radius (+ optional Angle like Cylinder).
|
|
38
47
|
'Part::Compound',
|
|
39
48
|
'Part::Sphere',
|
|
40
49
|
]);
|
|
50
|
+
/**
|
|
51
|
+
* True when the object type is on the M4.1 translation whitelist.
|
|
52
|
+
*
|
|
53
|
+
* @param type - the FCStd object type, e.g. "Part::Box".
|
|
54
|
+
* @returns true when the type is whitelisted for translation.
|
|
55
|
+
*/
|
|
41
56
|
export function isWhitelisted(type) {
|
|
42
57
|
return WHITELIST.has(type);
|
|
43
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* H10 (plan §3.1/§3.5): C4's Python exception, decided by PROPERTY presence —
|
|
61
|
+
* NOT by the `Python` type-name suffix. Matches the library profile's
|
|
62
|
+
* pythonObjects口径 (profile.mjs: type contains "Python" or carries
|
|
63
|
+
* Python/Proxy properties); here only the property evidence qualifies, so a
|
|
64
|
+
* Python-suffixed type without the property stays a plain translation gap.
|
|
65
|
+
* @param obj - the FCStd object to inspect.
|
|
66
|
+
* @returns true when the object is a Python-scripted feature whose serialized
|
|
67
|
+
* shape is opaque (legitimate `python-baked` under C4).
|
|
68
|
+
*/
|
|
69
|
+
export function isPythonOpaque(obj) {
|
|
70
|
+
for (const [name, prop] of obj.properties) {
|
|
71
|
+
if (name === 'Python' || name === 'Proxy')
|
|
72
|
+
return true;
|
|
73
|
+
if (prop.type === 'App::PropertyPythonObject')
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
44
78
|
function propNum(obj, name) {
|
|
45
79
|
// M11.1: an ExpressionEngine binding overrides the stored <Float> value
|
|
46
80
|
// (FreeCAD recomputes bound properties from expressions on load). A
|
|
@@ -59,6 +93,11 @@ function propNum(obj, name) {
|
|
|
59
93
|
* M11.1/M11.2: the ExpressionEngine binding for `name`, if any. `value` is
|
|
60
94
|
* undefined for non-constant expressions (references/arithmetic) — the caller
|
|
61
95
|
* must bake with an explicit reason instead of estimating.
|
|
96
|
+
*
|
|
97
|
+
* @param obj - the FCStd object whose ExpressionEngine to inspect.
|
|
98
|
+
* @param name - the property name to look up.
|
|
99
|
+
* @returns the binding for `name`, or undefined when the object has no
|
|
100
|
+
* ExpressionEngine binding for it.
|
|
62
101
|
*/
|
|
63
102
|
export function expressionBindingOf(obj, name) {
|
|
64
103
|
const bindings = parseExpressionEngine(obj.properties.get('ExpressionEngine'));
|
|
@@ -67,7 +106,13 @@ export function expressionBindingOf(obj, name) {
|
|
|
67
106
|
const norm = (p) => (p.startsWith('.') ? p.slice(1) : p);
|
|
68
107
|
return bindings.find((b) => norm(b.path) === name);
|
|
69
108
|
}
|
|
70
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* M11.2: detect a non-constant expression binding on a property.
|
|
111
|
+
*
|
|
112
|
+
* @param obj - the FCStd object whose ExpressionEngine to inspect.
|
|
113
|
+
* @param name - the property name to look up.
|
|
114
|
+
* @returns true when `name` has a binding that is NOT a constant expression.
|
|
115
|
+
*/
|
|
71
116
|
export function hasNonConstantBinding(obj, name) {
|
|
72
117
|
const b = expressionBindingOf(obj, name);
|
|
73
118
|
return b !== undefined && b.value === undefined;
|
|
@@ -95,6 +140,14 @@ const POCKET_TYPES = {
|
|
|
95
140
|
'0': 'Length', '1': 'ThroughAll', '2': 'UpToFirst', '3': 'UpToFace', '4': 'TwoLengths',
|
|
96
141
|
Length: 'Length', ThroughAll: 'ThroughAll', UpToFirst: 'UpToFirst', UpToFace: 'UpToFace', TwoLengths: 'TwoLengths',
|
|
97
142
|
};
|
|
143
|
+
/**
|
|
144
|
+
* Read the Pad/Pocket `Type` enumeration of an object (M9.1).
|
|
145
|
+
*
|
|
146
|
+
* @param obj - the FCStd Pad or Pocket object.
|
|
147
|
+
* @param kind - which type-enum table to apply (Pad vs Pocket labels differ).
|
|
148
|
+
* @returns the parsed feature type; 'Length' when Type is missing, 'unknown'
|
|
149
|
+
* when the stored label/index is not recognized.
|
|
150
|
+
*/
|
|
98
151
|
export function featureTypeOf(obj, kind) {
|
|
99
152
|
const el = obj.properties.get('Type')?.children[0];
|
|
100
153
|
const raw = el?.attributes['value'];
|
|
@@ -185,6 +238,10 @@ function edgeRefArgs(baseVar, ordinals) {
|
|
|
185
238
|
* that PartDesign revolves around = +Z) or an edge/vertex of another feature.
|
|
186
239
|
* Edge/vertex axes require resolving referenced geometry, which the port does
|
|
187
240
|
* not yet do (explicit downgrade, no silent loss).
|
|
241
|
+
*
|
|
242
|
+
* @param ref - the ReferenceAxis (or Direction) LinkSub string, may be undefined.
|
|
243
|
+
* @returns a unit axis and pivot point, or undefined when the reference names
|
|
244
|
+
* edge/vertex geometry (unsupported).
|
|
188
245
|
*/
|
|
189
246
|
export function parseReferenceAxis(ref) {
|
|
190
247
|
const at = [0, 0, 0];
|
|
@@ -213,7 +270,12 @@ export function parseReferenceAxis(ref) {
|
|
|
213
270
|
function profileLink(obj) {
|
|
214
271
|
return propLink(obj, 'Profile') ?? propLink(obj, 'Sketch');
|
|
215
272
|
}
|
|
216
|
-
/**
|
|
273
|
+
/**
|
|
274
|
+
* Placement position (translation) of an object.
|
|
275
|
+
*
|
|
276
|
+
* @param obj - the FCStd object to read.
|
|
277
|
+
* @returns the (Px, Py, Pz) translation from its Placement, or (0,0,0) when absent.
|
|
278
|
+
*/
|
|
217
279
|
export function placementPos(obj) {
|
|
218
280
|
// Property → <PropertyPlacement Px=... Py=... Pz=.../>
|
|
219
281
|
const pp = obj.properties.get('Placement')?.children[0];
|
|
@@ -225,6 +287,40 @@ export function placementPos(obj) {
|
|
|
225
287
|
Number(pp.attributes['Pz'] ?? 0),
|
|
226
288
|
];
|
|
227
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* A frozen `.brp` shape delivered through the container's `assets/` becomes an
|
|
292
|
+
* addressable Shape via `cad.import_brep` — the **platform** BREP-asset import
|
|
293
|
+
* op (`api/import-brep.ts`), which reads through the host asset resolver and
|
|
294
|
+
* returns a BREP-backed Shape the rest of the chain can consume.
|
|
295
|
+
*
|
|
296
|
+
* GOTCHA (2026-09-21, found while verifying ArchDetail): the shape-asset rounds
|
|
297
|
+
* used to emit a made-up `cad.import_shape`, which is **not** in the cad
|
|
298
|
+
* namespace. 42 of the 50 corpus products therefore parsed clean but could not
|
|
299
|
+
* RUN — `cliCheck` validates syntax and script-local references, never the
|
|
300
|
+
* callee's existence, so only a real `run --mode brep` exposes this.
|
|
301
|
+
*
|
|
302
|
+
* Contract details:
|
|
303
|
+
* - asset: the asset file name WITHOUT extension — that is the key rule of the
|
|
304
|
+
* documented directory mode of `FsAssetResolver` (`key = basename(file)`),
|
|
305
|
+
* which is how a container's `assets/` directory is exposed.
|
|
306
|
+
*
|
|
307
|
+
* C6 (non-solid first-class): `cad.import_brep` always imports with
|
|
308
|
+
* `allowNonSolid` (wire/face/shell are first-class). There is no `format`
|
|
309
|
+
* hint — the op goes straight to `loadBrep` on the OCCT kernel, which needs
|
|
310
|
+
* no format detection. Booleans / up-to targets that require a solid still
|
|
311
|
+
* fail at the **use site**, never at the import site.
|
|
312
|
+
*
|
|
313
|
+
* @param obj - the FCStd object whose frozen shape is being imported.
|
|
314
|
+
* @param assetFile - the `.brp` member name recorded on the object's Shape/SubShape property.
|
|
315
|
+
* @returns the `cad.import_brep` call binding `obj.name` to the imported geometry.
|
|
316
|
+
*/
|
|
317
|
+
function shapeAssetCall(obj, assetFile) {
|
|
318
|
+
const asset = assetFile.replace(/^.*[/\\]/, '').replace(/\.brp$/i, '');
|
|
319
|
+
return {
|
|
320
|
+
out: obj.name, op: 'cad.import_brep', source: obj.name, inputs: [],
|
|
321
|
+
params: { asset },
|
|
322
|
+
};
|
|
323
|
+
}
|
|
228
324
|
/**
|
|
229
325
|
* M4 translate one object. `inputVar` maps a dependency object name to the
|
|
230
326
|
* variable holding its geometry (sketch contours or prior solid).
|
|
@@ -232,9 +328,77 @@ export function placementPos(obj) {
|
|
|
232
328
|
* `docObjects` (optional) is the full document object list — needed by the
|
|
233
329
|
* UpToFace datum-plane path to read the target plane's Placement (plan
|
|
234
330
|
* extrude-upto-face §4.3-C1). When absent, UpToFace keeps the explicit bake.
|
|
331
|
+
*
|
|
332
|
+
* @param obj - the FCStd object to translate.
|
|
333
|
+
* @param inputVar - resolves a dependency object name to the variable holding
|
|
334
|
+
* its geometry (sketch contours or prior solid).
|
|
335
|
+
* @param docObjects - the full document object list, needed by the UpToFace
|
|
336
|
+
* datum-plane path; optional.
|
|
337
|
+
* @param shapeCarriers - objects whose Shape is stored as a .brp member; optional.
|
|
338
|
+
* @param brokenShapeAssets - objects whose Shape `file` attribute points at a missing/empty member (explicit gap); optional.
|
|
339
|
+
* @returns the cad-op call plan, or an explicit bake/preserve verdict with reason.
|
|
235
340
|
*/
|
|
236
|
-
export function translateObject(obj, inputVar, docObjects
|
|
341
|
+
export function translateObject(obj, inputVar, docObjects,
|
|
342
|
+
/** H7: names of objects whose Shape is stored as a .brp member (probed from the ZIP). */
|
|
343
|
+
shapeCarriers,
|
|
344
|
+
/** E4: objects whose Shape `file` attribute points at a missing/empty member. */
|
|
345
|
+
brokenShapeAssets) {
|
|
346
|
+
// E4 (H12): a Shape/SubShape `file` attribute whose member is missing or
|
|
347
|
+
// zero-bytes in the archive is a BROKEN asset, not a shape-asset — surface
|
|
348
|
+
// it as an explicit convert-time gap instead of letting the object fall
|
|
349
|
+
// through to python-opaque (which would silently swallow the defect).
|
|
350
|
+
if (brokenShapeAssets?.has(obj.name)) {
|
|
351
|
+
return { kind: 'baked', reason: 'shape-asset-broken: frozen .brp member missing or empty' };
|
|
352
|
+
}
|
|
353
|
+
// H7 follow-up (Body-less CAM corpus, 2026-09-20): a SubShape property whose
|
|
354
|
+
// .brp member exists is the feature's own RESULT cache — the pocketed/
|
|
355
|
+
// filleted geometry is already a fact delivered via assets/. shape-asset
|
|
356
|
+
// beats an honest-but-useless dependency gap for Body-less files. Only
|
|
357
|
+
// SubShape qualifies (Pads also carry Shape in these files — they must keep
|
|
358
|
+
// the normal translation path).
|
|
359
|
+
if (shapeCarriers?.has(obj.name) && obj.properties.has('SubShape')) {
|
|
360
|
+
// The result cache is a real, addressable solid: downstream features
|
|
361
|
+
// (Fillet Base→Pocket, Cut Base→…) must resolve it as a variable, so the
|
|
362
|
+
// verdict emits a real load call instead of zero calls (hole_puzzle
|
|
363
|
+
// GOTCHA: zero-call objects got no codegen variable and consumers gapped
|
|
364
|
+
// with fillet-missing-base / cut-missing-dependency).
|
|
365
|
+
const assetFile = obj.properties.get('SubShape')?.children[0]?.attributes['file'] ?? `${obj.name}.SubShape.brp`;
|
|
366
|
+
return {
|
|
367
|
+
kind: 'translated',
|
|
368
|
+
calls: [shapeAssetCall(obj, assetFile)],
|
|
369
|
+
reason: 'shape-asset',
|
|
370
|
+
};
|
|
371
|
+
}
|
|
237
372
|
if (!isWhitelisted(obj.type)) {
|
|
373
|
+
// GOTCHA (EngineBlock corpus, 2026-09-20): Shape-asset evidence PRECEDES
|
|
374
|
+
// python-opaque. Draft circles carry Proxy (python evidence) AND a real
|
|
375
|
+
// Shape .brp member; python-opaque baked them silently and downstream
|
|
376
|
+
// Part::Extrusion gapped with extrusion-missing-base. Geometry is an
|
|
377
|
+
// existing fact — import it.
|
|
378
|
+
if (shapeCarriers?.has(obj.name)) {
|
|
379
|
+
const assetFile = shapeBrpFile(obj) ?? `${obj.name}.Shape.brp`;
|
|
380
|
+
return {
|
|
381
|
+
kind: 'translated',
|
|
382
|
+
calls: [shapeAssetCall(obj, assetFile)],
|
|
383
|
+
reason: 'shape-asset',
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
// H10: property-evidenced Python features bake legitimately (C4) —
|
|
387
|
+
// auditMapping renames this reason to `python-baked`. Everything else is
|
|
388
|
+
// a plain translation gap.
|
|
389
|
+
if (isPythonOpaque(obj))
|
|
390
|
+
return { kind: 'baked', reason: 'python-opaque' };
|
|
391
|
+
// H7 first cut: a Part::Feature is a pure Shape carrier (corpus probe:
|
|
392
|
+
// property surface is Shape [+ShapeMaterial] only; geometry lives in the
|
|
393
|
+
// ZIP's .brp member). With shape evidence there is nothing to translate —
|
|
394
|
+
// the geometry is delivered via assets/ (build-fai-zip M2.3 already copies
|
|
395
|
+
// it), so record `translated` with no cad calls. Without evidence it is an
|
|
396
|
+
// explicit gap, never a silent bake.
|
|
397
|
+
if (obj.type === 'Part::Feature') {
|
|
398
|
+
if (shapeCarriers?.has(obj.name))
|
|
399
|
+
return { kind: 'translated', calls: [], reason: 'shape-asset' };
|
|
400
|
+
return { kind: 'baked', reason: 'shape-asset-missing' };
|
|
401
|
+
}
|
|
238
402
|
return { kind: 'baked', reason: `type-not-whitelisted: ${obj.type}` };
|
|
239
403
|
}
|
|
240
404
|
const out = obj.name; // M5 renames to partN
|
|
@@ -283,11 +447,16 @@ export function translateObject(obj, inputVar, docObjects) {
|
|
|
283
447
|
if (vars.length === 0 || vars.some((v) => v === undefined)) {
|
|
284
448
|
return { kind: 'baked', reason: 'compound-missing-members' };
|
|
285
449
|
}
|
|
450
|
+
// `Part::Compound` 是几何对象(`Part::Feature` 子类,带 Shape + Placement)。
|
|
451
|
+
// 用平台几何 compound(`cad.compound`,内核 `makeCompound`,持 OCCT 句柄,
|
|
452
|
+
// 可变换/可导出),不再借用 ../3d_editor 的结构分组 op `cad.group`。
|
|
453
|
+
// members 经 `params.members` 传递;`inputs` 仅作依赖登记(consumed / 变量重映射),
|
|
454
|
+
// 由 `noPositionalArgs` 保证不被 renderArgs 当作位置参数渲染。
|
|
286
455
|
return {
|
|
287
456
|
kind: 'translated',
|
|
288
457
|
calls: [{
|
|
289
|
-
out, op: 'cad.
|
|
290
|
-
params: { members: vars },
|
|
458
|
+
out, op: 'cad.compound', source: obj.name, inputs: vars,
|
|
459
|
+
noPositionalArgs: true, params: { members: vars },
|
|
291
460
|
}],
|
|
292
461
|
};
|
|
293
462
|
}
|
|
@@ -515,7 +684,13 @@ export function translateObject(obj, inputVar, docObjects) {
|
|
|
515
684
|
const midplane = propBool(obj, 'Midplane');
|
|
516
685
|
const base = propLink(obj, 'BaseFeature');
|
|
517
686
|
const profileVar = profile ? inputVar(profile) : undefined;
|
|
518
|
-
|
|
687
|
+
// GOTCHA (hole_puzzle corpus, 2026-09-20): FreeCAD 0.20+ PartDesign
|
|
688
|
+
// files routinely OMIT BaseFeature on interior features — the base is
|
|
689
|
+
// implied by the Body's feature order (chain head). A MISSING property
|
|
690
|
+
// is "no explicit base" → emit the subtract with the BODY_CHAIN_BASE
|
|
691
|
+
// marker; codegen retargets it at the chain head when folding. Only an
|
|
692
|
+
// EXPLICIT base that fails to resolve is a dependency gap.
|
|
693
|
+
const baseVar = base ? inputVar(base) : BODY_CHAIN_BASE;
|
|
519
694
|
if (!profileVar || !baseVar)
|
|
520
695
|
return { kind: 'baked', reason: 'pocket-missing-dependency' };
|
|
521
696
|
if (hasNonConstantBinding(obj, 'Length')) {
|
|
@@ -586,14 +761,19 @@ export function translateObject(obj, inputVar, docObjects) {
|
|
|
586
761
|
];
|
|
587
762
|
return { kind: 'translated', reason: 'pocket-uptofirst-via-baseFeature', calls };
|
|
588
763
|
}
|
|
589
|
-
if (ftype !== 'Length' && ftype !== 'TwoLengths') {
|
|
764
|
+
if (ftype !== 'Length' && ftype !== 'TwoLengths' && ftype !== 'ThroughAll') {
|
|
590
765
|
return { kind: 'baked', reason: `pocket-type-${ftype}-unsupported` };
|
|
591
766
|
}
|
|
592
767
|
if (midplane)
|
|
593
768
|
return { kind: 'baked', reason: 'pocket-midplane-unsupported' };
|
|
594
769
|
// Pocket cuts INTO the material: extrude the profile opposite the normal
|
|
595
770
|
// (or along it when Reversed), then subtract from base.
|
|
596
|
-
|
|
771
|
+
// ThroughAll (hole_puzzle corpus, 2026-09-20): FreeCAD truncates the
|
|
772
|
+
// prism against the base solid, so a depth far beyond any realistic
|
|
773
|
+
// base extent is safe — the subtract is exact either way.
|
|
774
|
+
const THROUGH_ALL_DEPTH = 1e6;
|
|
775
|
+
const depth = ftype === 'ThroughAll' ? THROUGH_ALL_DEPTH : len;
|
|
776
|
+
const signed = reversed ? depth : -depth;
|
|
597
777
|
const cutVar = `${out}_cut`;
|
|
598
778
|
const calls = [{
|
|
599
779
|
out: cutVar, op: 'cad.extrude', source: obj.name, inputs: [profileVar], literals: [[0, 0, signed]], params: {},
|