@faicad/faijs 0.13.1 → 0.13.2

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.
Files changed (93) hide show
  1. package/dist/api/edge-ref.d.ts +3 -2
  2. package/dist/api/edge-ref.d.ts.map +1 -1
  3. package/dist/api/edge-ref.js +3 -2
  4. package/dist/api/edge-ref.js.map +1 -1
  5. package/dist/api/internal/compat-op.d.ts +2 -0
  6. package/dist/api/internal/compat-op.d.ts.map +1 -1
  7. package/dist/api/internal/compat-op.js +8 -1
  8. package/dist/api/internal/compat-op.js.map +1 -1
  9. package/dist/browser.d.ts +0 -2
  10. package/dist/browser.d.ts.map +1 -1
  11. package/dist/browser.js +2 -2
  12. package/dist/browser.js.map +1 -1
  13. package/dist/fcstd/attachment.d.ts +65 -0
  14. package/dist/fcstd/attachment.d.ts.map +1 -0
  15. package/dist/fcstd/attachment.js +87 -0
  16. package/dist/fcstd/attachment.js.map +1 -0
  17. package/dist/fcstd/build-fai-zip.d.ts +11 -0
  18. package/dist/fcstd/build-fai-zip.d.ts.map +1 -1
  19. package/dist/fcstd/build-fai-zip.js +9 -1
  20. package/dist/fcstd/build-fai-zip.js.map +1 -1
  21. package/dist/fcstd/cli.d.ts +3 -0
  22. package/dist/fcstd/cli.d.ts.map +1 -0
  23. package/dist/fcstd/cli.js +37 -0
  24. package/dist/fcstd/cli.js.map +1 -0
  25. package/dist/fcstd/codegen.d.ts +14 -1
  26. package/dist/fcstd/codegen.d.ts.map +1 -1
  27. package/dist/fcstd/codegen.js +11 -2
  28. package/dist/fcstd/codegen.js.map +1 -1
  29. package/dist/fcstd/container.d.ts +16 -1
  30. package/dist/fcstd/container.d.ts.map +1 -1
  31. package/dist/fcstd/container.js +12 -1
  32. package/dist/fcstd/container.js.map +1 -1
  33. package/dist/fcstd/contour.d.ts +9 -1
  34. package/dist/fcstd/contour.d.ts.map +1 -1
  35. package/dist/fcstd/contour.js +12 -1
  36. package/dist/fcstd/contour.js.map +1 -1
  37. package/dist/fcstd/convert.d.ts +47 -2
  38. package/dist/fcstd/convert.d.ts.map +1 -1
  39. package/dist/fcstd/convert.js +82 -13
  40. package/dist/fcstd/convert.js.map +1 -1
  41. package/dist/fcstd/document.d.ts +8 -1
  42. package/dist/fcstd/document.d.ts.map +1 -1
  43. package/dist/fcstd/document.js +4 -1
  44. package/dist/fcstd/document.js.map +1 -1
  45. package/dist/fcstd/expressions.d.ts +14 -1
  46. package/dist/fcstd/expressions.d.ts.map +1 -1
  47. package/dist/fcstd/expressions.js +11 -1
  48. package/dist/fcstd/expressions.js.map +1 -1
  49. package/dist/fcstd/external-geo.d.ts +15 -1
  50. package/dist/fcstd/external-geo.d.ts.map +1 -1
  51. package/dist/fcstd/external-geo.js +8 -1
  52. package/dist/fcstd/external-geo.js.map +1 -1
  53. package/dist/fcstd/feature-translate.d.ts +65 -3
  54. package/dist/fcstd/feature-translate.d.ts.map +1 -1
  55. package/dist/fcstd/feature-translate.js +82 -4
  56. package/dist/fcstd/feature-translate.js.map +1 -1
  57. package/dist/fcstd/index.d.ts +23 -0
  58. package/dist/fcstd/index.d.ts.map +1 -0
  59. package/dist/fcstd/index.js +19 -0
  60. package/dist/fcstd/index.js.map +1 -0
  61. package/dist/fcstd/placement.d.ts +49 -6
  62. package/dist/fcstd/placement.d.ts.map +1 -1
  63. package/dist/fcstd/placement.js +46 -6
  64. package/dist/fcstd/placement.js.map +1 -1
  65. package/dist/fcstd/planegcs-backend.d.ts +16 -1
  66. package/dist/fcstd/planegcs-backend.d.ts.map +1 -1
  67. package/dist/fcstd/planegcs-backend.js +16 -1
  68. package/dist/fcstd/planegcs-backend.js.map +1 -1
  69. package/dist/fcstd/sketch-parse.d.ts +43 -0
  70. package/dist/fcstd/sketch-parse.d.ts.map +1 -1
  71. package/dist/fcstd/sketch-parse.js +26 -0
  72. package/dist/fcstd/sketch-parse.js.map +1 -1
  73. package/dist/fcstd/sketch-solver.d.ts +20 -2
  74. package/dist/fcstd/sketch-solver.d.ts.map +1 -1
  75. package/dist/fcstd/sketch-solver.js +6 -1
  76. package/dist/fcstd/sketch-solver.js.map +1 -1
  77. package/dist/fcstd/sketch-verify.d.ts +19 -1
  78. package/dist/fcstd/sketch-verify.d.ts.map +1 -1
  79. package/dist/fcstd/sketch-verify.js +14 -1
  80. package/dist/fcstd/sketch-verify.js.map +1 -1
  81. package/dist/fcstd/unpack.d.ts +21 -2
  82. package/dist/fcstd/unpack.d.ts.map +1 -1
  83. package/dist/fcstd/unpack.js +11 -2
  84. package/dist/fcstd/unpack.js.map +1 -1
  85. package/dist/fcstd-convert.d.ts +30 -0
  86. package/dist/fcstd-convert.d.ts.map +1 -0
  87. package/dist/fcstd-convert.js +27 -0
  88. package/dist/fcstd-convert.js.map +1 -0
  89. package/dist/weapp.d.ts +22 -0
  90. package/dist/weapp.d.ts.map +1 -0
  91. package/dist/weapp.js +23 -0
  92. package/dist/weapp.js.map +1 -0
  93. package/package.json +18 -5
@@ -1,5 +1,8 @@
1
1
  import { type FcstdArchive } from './unpack.js';
2
2
  import type { FcstdDocument, FcstdProperty } from './document.js';
3
+ /**
4
+ * One resolved external-geometry link of a sketch.
5
+ */
3
6
  export interface ExternalLink {
4
7
  /** source object name, e.g. "Chamfer002" */
5
8
  obj: string;
@@ -8,6 +11,10 @@ export interface ExternalLink {
8
11
  /** resolved sketch-local 2D polyline */
9
12
  polyline: [number, number][];
10
13
  }
14
+ /**
15
+ * Result of external-geometry resolution: successfully projected links plus
16
+ * per-link failures (with a human-readable reason) for the caller to report.
17
+ */
11
18
  export interface ExternalGeoResult {
12
19
  links: ExternalLink[];
13
20
  failures: {
@@ -18,7 +25,14 @@ export interface ExternalGeoResult {
18
25
  }
19
26
  /**
20
27
  * Resolve every external link of a sketch to sketch-local 2D polylines.
21
- * `externalGeoProp` is the sketch's ExternalGeometry property.
28
+ *
29
+ * @param externalGeoProp - the sketch's ExternalGeometry property.
30
+ * @param doc - the parsed FCStd document, used to locate source objects and their shapes.
31
+ * @param archive - the FCStd container, used to read the source `.brp` shape files.
32
+ * @param sketchPlacement - the sketch's Placement property, whose inverse maps
33
+ * source geometry into sketch-local coordinates.
34
+ * @returns the resolved sketch-local polylines per link, plus a failure entry
35
+ * (with reason) for every link that could not be resolved.
22
36
  */
23
37
  export declare function resolveExternalGeometry(externalGeoProp: FcstdProperty | undefined, doc: FcstdDocument, archive: FcstdArchive, sketchPlacement: FcstdProperty | undefined): Promise<ExternalGeoResult>;
24
38
  //# sourceMappingURL=external-geo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-geo.d.ts","sourceRoot":"","sources":["../../src/fcstd/external-geo.ts"],"names":[],"mappings":"AAWA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAe,aAAa,EAAE,MAAM,eAAe,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC1D;AAiCD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,aAAa,GAAG,SAAS,EAC1C,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,YAAY,EACrB,eAAe,EAAE,aAAa,GAAG,SAAS,GACzC,OAAO,CAAC,iBAAiB,CAAC,CA4E5B"}
1
+ {"version":3,"file":"external-geo.d.ts","sourceRoot":"","sources":["../../src/fcstd/external-geo.ts"],"names":[],"mappings":"AAWA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAe,aAAa,EAAE,MAAM,eAAe,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC1D;AAiCD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,aAAa,GAAG,SAAS,EAC1C,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,YAAY,EACrB,eAAe,EAAE,aAAa,GAAG,SAAS,GACzC,OAAO,CAAC,iBAAiB,CAAC,CA4E5B"}
@@ -41,7 +41,14 @@ function placementOf(obj) {
41
41
  }
42
42
  /**
43
43
  * Resolve every external link of a sketch to sketch-local 2D polylines.
44
- * `externalGeoProp` is the sketch's ExternalGeometry property.
44
+ *
45
+ * @param externalGeoProp - the sketch's ExternalGeometry property.
46
+ * @param doc - the parsed FCStd document, used to locate source objects and their shapes.
47
+ * @param archive - the FCStd container, used to read the source `.brp` shape files.
48
+ * @param sketchPlacement - the sketch's Placement property, whose inverse maps
49
+ * source geometry into sketch-local coordinates.
50
+ * @returns the resolved sketch-local polylines per link, plus a failure entry
51
+ * (with reason) for every link that could not be resolved.
45
52
  */
46
53
  export async function resolveExternalGeometry(externalGeoProp, doc, archive, sketchPlacement) {
47
54
  const links = [];
@@ -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 * 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?.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"]}
@@ -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>;
@@ -50,6 +54,10 @@ export declare function jsExpr(code: string): JsExpr;
50
54
  * @returns true when `v` is a `JsExpr` marker.
51
55
  */
52
56
  export declare function isJsExpr(v: unknown): v is JsExpr;
57
+ /**
58
+ * Outcome of translating one FCStd object: a cad-op call plan, an explicit
59
+ * bake with reason, or preserved-only (no geometry emitted).
60
+ */
53
61
  export type TranslateVerdict = {
54
62
  kind: 'translated';
55
63
  calls: CadCall[];
@@ -61,14 +69,42 @@ export type TranslateVerdict = {
61
69
  kind: 'preserved-only';
62
70
  reason: string;
63
71
  };
72
+ /**
73
+ * True when the object type is on the M4.1 translation whitelist.
74
+ *
75
+ * @param type - the FCStd object type, e.g. "Part::Box".
76
+ * @returns true when the type is whitelisted for translation.
77
+ */
64
78
  export declare function isWhitelisted(type: string): boolean;
79
+ /**
80
+ * H10 (plan §3.1/§3.5): C4's Python exception, decided by PROPERTY presence —
81
+ * NOT by the `Python` type-name suffix. Matches the library profile's
82
+ * pythonObjects口径 (profile.mjs: type contains "Python" or carries
83
+ * Python/Proxy properties); here only the property evidence qualifies, so a
84
+ * Python-suffixed type without the property stays a plain translation gap.
85
+ * @param obj - the FCStd object to inspect.
86
+ * @returns true when the object is a Python-scripted feature whose serialized
87
+ * shape is opaque (legitimate `python-baked` under C4).
88
+ */
89
+ export declare function isPythonOpaque(obj: FcstdObject): boolean;
65
90
  /**
66
91
  * M11.1/M11.2: the ExpressionEngine binding for `name`, if any. `value` is
67
92
  * undefined for non-constant expressions (references/arithmetic) — the caller
68
93
  * must bake with an explicit reason instead of estimating.
94
+ *
95
+ * @param obj - the FCStd object whose ExpressionEngine to inspect.
96
+ * @param name - the property name to look up.
97
+ * @returns the binding for `name`, or undefined when the object has no
98
+ * ExpressionEngine binding for it.
69
99
  */
70
100
  export declare function expressionBindingOf(obj: FcstdObject, name: string): ExpressionBinding | undefined;
71
- /** M11.2: true when `name` has a binding that is NOT a constant expression. */
101
+ /**
102
+ * M11.2: detect a non-constant expression binding on a property.
103
+ *
104
+ * @param obj - the FCStd object whose ExpressionEngine to inspect.
105
+ * @param name - the property name to look up.
106
+ * @returns true when `name` has a binding that is NOT a constant expression.
107
+ */
72
108
  export declare function hasNonConstantBinding(obj: FcstdObject, name: string): boolean;
73
109
  /**
74
110
  * M9.1 — Pad/Pocket `Type` enumeration (App::PropertyEnumeration, stored as
@@ -79,6 +115,14 @@ export declare function hasNonConstantBinding(obj: FcstdObject, name: string): b
79
115
  * A missing Type property means Length (0) — the FreeCAD default.
80
116
  */
81
117
  export type FeatureType = 'Length' | 'ThroughAll' | 'UpToLast' | 'UpToFirst' | 'UpToFace' | 'TwoLengths' | 'unknown';
118
+ /**
119
+ * Read the Pad/Pocket `Type` enumeration of an object (M9.1).
120
+ *
121
+ * @param obj - the FCStd Pad or Pocket object.
122
+ * @param kind - which type-enum table to apply (Pad vs Pocket labels differ).
123
+ * @returns the parsed feature type; 'Length' when Type is missing, 'unknown'
124
+ * when the stored label/index is not recognized.
125
+ */
82
126
  export declare function featureTypeOf(obj: FcstdObject, kind: 'pad' | 'pocket'): FeatureType;
83
127
  /**
84
128
  * Parse a PartDesign ReferenceAxis reference into a 3D axis + pivot point.
@@ -88,12 +132,21 @@ export declare function featureTypeOf(obj: FcstdObject, kind: 'pad' | 'pocket'):
88
132
  * that PartDesign revolves around = +Z) or an edge/vertex of another feature.
89
133
  * Edge/vertex axes require resolving referenced geometry, which the port does
90
134
  * not yet do (explicit downgrade, no silent loss).
135
+ *
136
+ * @param ref - the ReferenceAxis (or Direction) LinkSub string, may be undefined.
137
+ * @returns a unit axis and pivot point, or undefined when the reference names
138
+ * edge/vertex geometry (unsupported).
91
139
  */
92
140
  export declare function parseReferenceAxis(ref: string | undefined): {
93
141
  axis: [number, number, number];
94
142
  at: [number, number, number];
95
143
  } | undefined;
96
- /** Placement position (Px/Py/Pz) of an object. */
144
+ /**
145
+ * Placement position (translation) of an object.
146
+ *
147
+ * @param obj - the FCStd object to read.
148
+ * @returns the (Px, Py, Pz) translation from its Placement, or (0,0,0) when absent.
149
+ */
97
150
  export declare function placementPos(obj: FcstdObject): [number, number, number];
98
151
  /**
99
152
  * M4 translate one object. `inputVar` maps a dependency object name to the
@@ -102,6 +155,15 @@ export declare function placementPos(obj: FcstdObject): [number, number, number]
102
155
  * `docObjects` (optional) is the full document object list — needed by the
103
156
  * UpToFace datum-plane path to read the target plane's Placement (plan
104
157
  * extrude-upto-face §4.3-C1). When absent, UpToFace keeps the explicit bake.
158
+ *
159
+ * @param obj - the FCStd object to translate.
160
+ * @param inputVar - resolves a dependency object name to the variable holding
161
+ * its geometry (sketch contours or prior solid).
162
+ * @param docObjects - the full document object list, needed by the UpToFace
163
+ * datum-plane path; optional.
164
+ * @returns the cad-op call plan, or an explicit bake/preserve verdict with reason.
105
165
  */
106
- export declare function translateObject(obj: FcstdObject, inputVar: (depName: string) => string | undefined, docObjects?: readonly FcstdObject[]): TranslateVerdict;
166
+ export declare function translateObject(obj: FcstdObject, inputVar: (depName: string) => string | undefined, docObjects?: readonly FcstdObject[],
167
+ /** H7: names of objects whose Shape is stored as a .brp member (probed from the ZIP). */
168
+ shapeCarriers?: ReadonlySet<string>): TranslateVerdict;
107
169
  //# 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;AAGjF,MAAM,WAAW,OAAO;IACtB,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,gFAAgF;IAChF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACrB,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAEhD;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuB/C,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAeD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAKjG;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAG7E;AAoBD;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GACnB,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;AAW/F,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,WAAW,CAMnF;AAwED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,SAAS,CAYxI;AAWD,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CASvE;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EACjD,UAAU,CAAC,EAAE,SAAS,WAAW,EAAE,GAClC,gBAAgB,CAoflB"}
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;AAGjF;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,gFAAgF;IAChF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACrB,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAEhD;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuB/C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAMxD;AAeD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAKjG;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAG7E;AAoBD;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GACnB,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;AAW/F;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,WAAW,CAMnF;AAwED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,SAAS,CAYxI;AAWD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CASvE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EACjD,UAAU,CAAC,EAAE,SAAS,WAAW,EAAE;AACnC,yFAAyF;AACzF,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAClC,gBAAgB,CAkgBlB"}
@@ -32,15 +32,40 @@ const WHITELIST = new Set([
32
32
  'PartDesign::PolarPattern',
33
33
  'PartDesign::Fillet',
34
34
  'PartDesign::Chamfer',
35
- // M13.1 (probed on real corpus — scripts/probe-m13-types.ts):
35
+ // M13.1 (probed on real corpus — fcstd-port/tools/probe-m13-types.ts):
36
36
  // Part::Compound carries a Links PropertyLinkList; Part::Sphere carries
37
37
  // Radius (+ optional Angle like Cylinder).
38
38
  'Part::Compound',
39
39
  'Part::Sphere',
40
40
  ]);
41
+ /**
42
+ * True when the object type is on the M4.1 translation whitelist.
43
+ *
44
+ * @param type - the FCStd object type, e.g. "Part::Box".
45
+ * @returns true when the type is whitelisted for translation.
46
+ */
41
47
  export function isWhitelisted(type) {
42
48
  return WHITELIST.has(type);
43
49
  }
50
+ /**
51
+ * H10 (plan §3.1/§3.5): C4's Python exception, decided by PROPERTY presence —
52
+ * NOT by the `Python` type-name suffix. Matches the library profile's
53
+ * pythonObjects口径 (profile.mjs: type contains "Python" or carries
54
+ * Python/Proxy properties); here only the property evidence qualifies, so a
55
+ * Python-suffixed type without the property stays a plain translation gap.
56
+ * @param obj - the FCStd object to inspect.
57
+ * @returns true when the object is a Python-scripted feature whose serialized
58
+ * shape is opaque (legitimate `python-baked` under C4).
59
+ */
60
+ export function isPythonOpaque(obj) {
61
+ for (const [name, prop] of obj.properties) {
62
+ if (name === 'Python' || name === 'Proxy')
63
+ return true;
64
+ if (prop.type === 'App::PropertyPythonObject')
65
+ return true;
66
+ }
67
+ return false;
68
+ }
44
69
  function propNum(obj, name) {
45
70
  // M11.1: an ExpressionEngine binding overrides the stored <Float> value
46
71
  // (FreeCAD recomputes bound properties from expressions on load). A
@@ -59,6 +84,11 @@ function propNum(obj, name) {
59
84
  * M11.1/M11.2: the ExpressionEngine binding for `name`, if any. `value` is
60
85
  * undefined for non-constant expressions (references/arithmetic) — the caller
61
86
  * must bake with an explicit reason instead of estimating.
87
+ *
88
+ * @param obj - the FCStd object whose ExpressionEngine to inspect.
89
+ * @param name - the property name to look up.
90
+ * @returns the binding for `name`, or undefined when the object has no
91
+ * ExpressionEngine binding for it.
62
92
  */
63
93
  export function expressionBindingOf(obj, name) {
64
94
  const bindings = parseExpressionEngine(obj.properties.get('ExpressionEngine'));
@@ -67,7 +97,13 @@ export function expressionBindingOf(obj, name) {
67
97
  const norm = (p) => (p.startsWith('.') ? p.slice(1) : p);
68
98
  return bindings.find((b) => norm(b.path) === name);
69
99
  }
70
- /** M11.2: true when `name` has a binding that is NOT a constant expression. */
100
+ /**
101
+ * M11.2: detect a non-constant expression binding on a property.
102
+ *
103
+ * @param obj - the FCStd object whose ExpressionEngine to inspect.
104
+ * @param name - the property name to look up.
105
+ * @returns true when `name` has a binding that is NOT a constant expression.
106
+ */
71
107
  export function hasNonConstantBinding(obj, name) {
72
108
  const b = expressionBindingOf(obj, name);
73
109
  return b !== undefined && b.value === undefined;
@@ -95,6 +131,14 @@ const POCKET_TYPES = {
95
131
  '0': 'Length', '1': 'ThroughAll', '2': 'UpToFirst', '3': 'UpToFace', '4': 'TwoLengths',
96
132
  Length: 'Length', ThroughAll: 'ThroughAll', UpToFirst: 'UpToFirst', UpToFace: 'UpToFace', TwoLengths: 'TwoLengths',
97
133
  };
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
+ */
98
142
  export function featureTypeOf(obj, kind) {
99
143
  const el = obj.properties.get('Type')?.children[0];
100
144
  const raw = el?.attributes['value'];
@@ -185,6 +229,10 @@ function edgeRefArgs(baseVar, ordinals) {
185
229
  * that PartDesign revolves around = +Z) or an edge/vertex of another feature.
186
230
  * Edge/vertex axes require resolving referenced geometry, which the port does
187
231
  * not yet do (explicit downgrade, no silent loss).
232
+ *
233
+ * @param ref - the ReferenceAxis (or Direction) LinkSub string, may be undefined.
234
+ * @returns a unit axis and pivot point, or undefined when the reference names
235
+ * edge/vertex geometry (unsupported).
188
236
  */
189
237
  export function parseReferenceAxis(ref) {
190
238
  const at = [0, 0, 0];
@@ -213,7 +261,12 @@ export function parseReferenceAxis(ref) {
213
261
  function profileLink(obj) {
214
262
  return propLink(obj, 'Profile') ?? propLink(obj, 'Sketch');
215
263
  }
216
- /** Placement position (Px/Py/Pz) of an object. */
264
+ /**
265
+ * Placement position (translation) of an object.
266
+ *
267
+ * @param obj - the FCStd object to read.
268
+ * @returns the (Px, Py, Pz) translation from its Placement, or (0,0,0) when absent.
269
+ */
217
270
  export function placementPos(obj) {
218
271
  // Property → <PropertyPlacement Px=... Py=... Pz=.../>
219
272
  const pp = obj.properties.get('Placement')?.children[0];
@@ -232,9 +285,34 @@ export function placementPos(obj) {
232
285
  * `docObjects` (optional) is the full document object list — needed by the
233
286
  * UpToFace datum-plane path to read the target plane's Placement (plan
234
287
  * extrude-upto-face §4.3-C1). When absent, UpToFace keeps the explicit bake.
288
+ *
289
+ * @param obj - the FCStd object to translate.
290
+ * @param inputVar - resolves a dependency object name to the variable holding
291
+ * its geometry (sketch contours or prior solid).
292
+ * @param docObjects - the full document object list, needed by the UpToFace
293
+ * datum-plane path; optional.
294
+ * @returns the cad-op call plan, or an explicit bake/preserve verdict with reason.
235
295
  */
236
- export function translateObject(obj, inputVar, docObjects) {
296
+ export function translateObject(obj, inputVar, docObjects,
297
+ /** H7: names of objects whose Shape is stored as a .brp member (probed from the ZIP). */
298
+ shapeCarriers) {
237
299
  if (!isWhitelisted(obj.type)) {
300
+ // H10: property-evidenced Python features bake legitimately (C4) —
301
+ // auditMapping renames this reason to `python-baked`. Everything else is
302
+ // a plain translation gap.
303
+ if (isPythonOpaque(obj))
304
+ return { kind: 'baked', reason: 'python-opaque' };
305
+ // H7 first cut: a Part::Feature is a pure Shape carrier (corpus probe:
306
+ // property surface is Shape [+ShapeMaterial] only; geometry lives in the
307
+ // ZIP's .brp member). With shape evidence there is nothing to translate —
308
+ // the geometry is delivered via assets/ (build-fai-zip M2.3 already copies
309
+ // it), so record `translated` with no cad calls. Without evidence it is an
310
+ // explicit gap, never a silent bake.
311
+ if (obj.type === 'Part::Feature') {
312
+ if (shapeCarriers?.has(obj.name))
313
+ return { kind: 'translated', calls: [], reason: 'shape-asset' };
314
+ return { kind: 'baked', reason: 'shape-asset-missing' };
315
+ }
238
316
  return { kind: 'baked', reason: `type-not-whitelisted: ${obj.type}` };
239
317
  }
240
318
  const out = obj.name; // M5 renames to partN