@faicad/faijs-fcstd 0.17.0
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/LICENSE +29 -0
- package/NOTICE +20 -0
- package/dist/attachment.d.ts +72 -0
- package/dist/attachment.d.ts.map +1 -0
- package/dist/attachment.js +93 -0
- package/dist/attachment.js.map +1 -0
- package/dist/bspline.d.ts +58 -0
- package/dist/bspline.d.ts.map +1 -0
- package/dist/bspline.js +93 -0
- package/dist/bspline.js.map +1 -0
- package/dist/build-fai-zip.d.ts +40 -0
- package/dist/build-fai-zip.d.ts.map +1 -0
- package/dist/build-fai-zip.js +111 -0
- package/dist/build-fai-zip.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +37 -0
- package/dist/cli.js.map +1 -0
- package/dist/codegen.d.ts +83 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +618 -0
- package/dist/codegen.js.map +1 -0
- package/dist/container.d.ts +75 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +36 -0
- package/dist/container.js.map +1 -0
- package/dist/contour.d.ts +43 -0
- package/dist/contour.d.ts.map +1 -0
- package/dist/contour.js +132 -0
- package/dist/contour.js.map +1 -0
- package/dist/convert.d.ts +69 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/convert.js +303 -0
- package/dist/convert.js.map +1 -0
- package/dist/document.d.ts +48 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +140 -0
- package/dist/document.js.map +1 -0
- package/dist/expressions.d.ts +79 -0
- package/dist/expressions.d.ts.map +1 -0
- package/dist/expressions.js +162 -0
- package/dist/expressions.js.map +1 -0
- package/dist/external-geo.d.ts +49 -0
- package/dist/external-geo.d.ts.map +1 -0
- package/dist/external-geo.js +140 -0
- package/dist/external-geo.js.map +1 -0
- package/dist/feature-translate.d.ts +193 -0
- package/dist/feature-translate.d.ts.map +1 -0
- package/dist/feature-translate.js +1441 -0
- package/dist/feature-translate.js.map +1 -0
- package/dist/fillet-edges.d.ts +26 -0
- package/dist/fillet-edges.d.ts.map +1 -0
- package/dist/fillet-edges.js +36 -0
- package/dist/fillet-edges.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/placement.d.ts +93 -0
- package/dist/placement.d.ts.map +1 -0
- package/dist/placement.js +117 -0
- package/dist/placement.js.map +1 -0
- package/dist/planegcs-backend.d.ts +34 -0
- package/dist/planegcs-backend.d.ts.map +1 -0
- package/dist/planegcs-backend.js +665 -0
- package/dist/planegcs-backend.js.map +1 -0
- package/dist/sketch-parse.d.ts +199 -0
- package/dist/sketch-parse.d.ts.map +1 -0
- package/dist/sketch-parse.js +263 -0
- package/dist/sketch-parse.js.map +1 -0
- package/dist/sketch-solver.d.ts +63 -0
- package/dist/sketch-solver.d.ts.map +1 -0
- package/dist/sketch-solver.js +28 -0
- package/dist/sketch-solver.js.map +1 -0
- package/dist/sketch-verify.d.ts +53 -0
- package/dist/sketch-verify.d.ts.map +1 -0
- package/dist/sketch-verify.js +71 -0
- package/dist/sketch-verify.js.map +1 -0
- package/dist/structural-types.d.ts +96 -0
- package/dist/structural-types.d.ts.map +1 -0
- package/dist/structural-types.js +155 -0
- package/dist/structural-types.js.map +1 -0
- package/dist/unpack.d.ts +44 -0
- package/dist/unpack.d.ts.map +1 -0
- package/dist/unpack.js +64 -0
- package/dist/unpack.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract a Placement from a PropertyPlacement element (or missing → identity).
|
|
3
|
+
*
|
|
4
|
+
* @param prop - the Placement property (App::PropertyPlacement) or undefined.
|
|
5
|
+
* @returns the parsed placement; identity when `prop` is missing.
|
|
6
|
+
*/
|
|
7
|
+
export function placementOfProp(prop) {
|
|
8
|
+
const el = prop?.children[0];
|
|
9
|
+
const a = el?.attributes ?? {};
|
|
10
|
+
return {
|
|
11
|
+
p: [Number(a['Px'] ?? 0), Number(a['Py'] ?? 0), Number(a['Pz'] ?? 0)],
|
|
12
|
+
q: [Number(a['Q0'] ?? 0), Number(a['Q1'] ?? 0), Number(a['Q2'] ?? 0), Number(a['Q3'] ?? 1)],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Convenience: the object's Placement property (identity when absent).
|
|
17
|
+
*
|
|
18
|
+
* @param obj - the FCStd object to read.
|
|
19
|
+
* @returns the object's placement, or identity when it has none.
|
|
20
|
+
*/
|
|
21
|
+
export function placementOf(obj) {
|
|
22
|
+
return placementOfProp(obj.properties.get('Placement'));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 3×3 row-major rotation matrix from a (x,y,z,w) quaternion.
|
|
26
|
+
*
|
|
27
|
+
* @param q - the quaternion in (x, y, z, w) order.
|
|
28
|
+
* @returns the 3×3 row-major rotation matrix (9 entries).
|
|
29
|
+
* @throws when the quaternion has a zero/non-finite norm.
|
|
30
|
+
*/
|
|
31
|
+
export function quatToMatrix(q) {
|
|
32
|
+
const [x, y, z, w] = q;
|
|
33
|
+
const n = Math.hypot(x, y, z, w);
|
|
34
|
+
if (!Number.isFinite(n) || n === 0)
|
|
35
|
+
throw new Error(`invalid quaternion norm: ${n}`);
|
|
36
|
+
const nx = x / n, ny = y / n, nz = z / n, nw = w / n;
|
|
37
|
+
const s = 2; // components are already normalized; scale factor is exactly 2
|
|
38
|
+
return [
|
|
39
|
+
1 - s * (ny * ny + nz * nz), s * (nx * ny - nw * nz), s * (nx * nz + nw * ny),
|
|
40
|
+
s * (nx * ny + nw * nz), 1 - s * (nx * nx + nz * nz), s * (ny * nz - nw * nx),
|
|
41
|
+
s * (nx * nz - nw * ny), s * (ny * nz + nw * nx), 1 - s * (nx * nx + ny * ny),
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Apply placement (rotate then translate) to a point.
|
|
46
|
+
*
|
|
47
|
+
* @param pl - the placement to apply.
|
|
48
|
+
* @param w - the world-space input point (mm).
|
|
49
|
+
* @returns the transformed point (mm).
|
|
50
|
+
*/
|
|
51
|
+
export function applyPlacement(pl, w) {
|
|
52
|
+
const m = quatToMatrix(pl.q);
|
|
53
|
+
const r = (i) => m[i * 3] * w[0] + m[i * 3 + 1] * w[1] + m[i * 3 + 2] * w[2];
|
|
54
|
+
return [r(0) + pl.p[0], r(1) + pl.p[1], r(2) + pl.p[2]];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Apply the inverse placement (translate back, rotate by conjugate).
|
|
58
|
+
*
|
|
59
|
+
* @param pl - the placement whose inverse is applied.
|
|
60
|
+
* @param w - the world-space input point (mm).
|
|
61
|
+
* @returns the point mapped into the placement-local frame (mm).
|
|
62
|
+
*/
|
|
63
|
+
export function invertApplyPlacement(pl, w) {
|
|
64
|
+
const d = [w[0] - pl.p[0], w[1] - pl.p[1], w[2] - pl.p[2]];
|
|
65
|
+
const inv = { p: [0, 0, 0], q: [-pl.q[0], -pl.q[1], -pl.q[2], pl.q[3]] };
|
|
66
|
+
return applyPlacement(inv, d);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* M8.3 — quaternion → XYZ euler angles in DEGREES, matching the convention of
|
|
70
|
+
* `rotateBrep` (brep/brep-ops.ts): THREE.Euler(order 'XYZ'), i.e. the rotation
|
|
71
|
+
* matrix is RX·RY·RZ (column vectors; Z applied first). Pinned against THREE
|
|
72
|
+
* itself in placement.test.ts — not from memory.
|
|
73
|
+
*
|
|
74
|
+
* @param q - the quaternion in (x, y, z, w) order.
|
|
75
|
+
* @returns (x, y, z) euler angles in degrees.
|
|
76
|
+
*/
|
|
77
|
+
export function quatToEulerXYZDeg(q) {
|
|
78
|
+
const m = quatToMatrix(q);
|
|
79
|
+
// M = RX·RY·RZ (row-major 3×3): m[2] = +sinY, m[5] = -sinX·cosY, m[8] = cosX·cosY
|
|
80
|
+
const sy = m[2];
|
|
81
|
+
const y = Math.asin(Math.max(-1, Math.min(1, sy)));
|
|
82
|
+
if (Math.abs(sy) < 1 - 1e-9) {
|
|
83
|
+
const x = Math.atan2(-m[5], m[8]);
|
|
84
|
+
const z = Math.atan2(-m[1], m[0]);
|
|
85
|
+
return [(x * 180) / Math.PI, (y * 180) / Math.PI, (z * 180) / Math.PI];
|
|
86
|
+
}
|
|
87
|
+
// gimbal lock: Y = ±90°, X and Z are coupled — set Z = 0; x from m[3]/m[4]
|
|
88
|
+
const x = Math.atan2(m[3], m[4]);
|
|
89
|
+
return [(x * 180) / Math.PI, (y * 180) / Math.PI, 0];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* True when the placement is (approximately) the identity — no transform needed.
|
|
93
|
+
*
|
|
94
|
+
* @param pl - the placement to test.
|
|
95
|
+
* @param eps - tolerance for both translation and quaternion components.
|
|
96
|
+
* @returns true when the placement is within `eps` of identity.
|
|
97
|
+
*/
|
|
98
|
+
export function isIdentityPlacement(pl, eps = 1e-9) {
|
|
99
|
+
return (Math.abs(pl.p[0]) < eps && Math.abs(pl.p[1]) < eps && Math.abs(pl.p[2]) < eps &&
|
|
100
|
+
Math.abs(pl.q[0]) < eps && Math.abs(pl.q[1]) < eps && Math.abs(pl.q[2]) < eps &&
|
|
101
|
+
Math.abs(Math.abs(pl.q[3]) - 1) < eps);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* M8.3 — orthonormal sketch-plane basis (u, v) from the placement rotation:
|
|
105
|
+
* u = rotated X axis, v = rotated Y axis, normal = rotated Z. Points on the
|
|
106
|
+
* sketch plane (z≈0 in local coords) map to global as p·u + q·v.
|
|
107
|
+
*
|
|
108
|
+
* @param pl - the placement whose rotation defines the plane.
|
|
109
|
+
* @returns the rotated X axis (u), Y axis (v) and plane normal (n).
|
|
110
|
+
*/
|
|
111
|
+
export function planeBasis(pl) {
|
|
112
|
+
const m = quatToMatrix(pl.q);
|
|
113
|
+
// column i of the matrix = image of the i-th basis vector
|
|
114
|
+
const col = (i) => [m[i], m[i + 3], m[i + 6]];
|
|
115
|
+
return { u: col(0), v: col(1), n: col(2) };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=placement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement.js","sourceRoot":"","sources":["../src/placement.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M8.1 — PropertyPlacement parsing and quaternion math.\n *\n * FCStd stores placements as `<Property name=\"Placement\"\n * type=\"App::PropertyPlacement\"><PropertyPlacement Px=\"..\" Py=\"..\" Pz=\"..\"\n * Q0=\"..\" Q1=\"..\" Q2=\"..\" Q3=\"..\"/></Property>` where (Q0,Q1,Q2,Q3) is the\n * rotation quaternion in (x,y,z,w) order — Q3 is the scalar component\n * (identity = 0,0,0,1; calibrated against FreeCAD sources and pinned by\n * placement.test.ts analytical solutions).\n *\n * AttachmentOffset uses the same nested element shape inside\n * `App::PropertyPlacementSub`-style properties.\n */\nimport type { FcstdObject } from './document.js';\n\n/**\n * A placement: translation plus rotation quaternion (x, y, z, w).\n */\nexport interface Placement {\n /** translation (mm) */\n p: [number, number, number];\n /** rotation quaternion (x, y, z, w) */\n q: [number, number, number, number];\n}\n\n/**\n * Extract a Placement from a PropertyPlacement element (or missing → identity).\n *\n * @param prop - the Placement property (App::PropertyPlacement) or undefined.\n * @returns the parsed placement; identity when `prop` is missing.\n */\nexport function placementOfProp(prop: FcstdObject['properties'] extends Map<string, infer V> ? V | undefined : never): Placement {\n const el = prop?.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 * Convenience: the object's Placement property (identity when absent).\n *\n * @param obj - the FCStd object to read.\n * @returns the object's placement, or identity when it has none.\n */\nexport function placementOf(obj: FcstdObject): Placement {\n return placementOfProp(obj.properties.get('Placement'));\n}\n\n/**\n * 3×3 row-major rotation matrix from a (x,y,z,w) quaternion.\n *\n * @param q - the quaternion in (x, y, z, w) order.\n * @returns the 3×3 row-major rotation matrix (9 entries).\n * @throws when the quaternion has a zero/non-finite norm.\n */\nexport function quatToMatrix(q: [number, number, number, number]): number[] {\n const [x, y, z, w] = q;\n const n = Math.hypot(x, y, z, w);\n if (!Number.isFinite(n) || n === 0) throw new Error(`invalid quaternion norm: ${n}`);\n const nx = x / n, ny = y / n, nz = z / n, nw = w / n;\n const s = 2; // components are already normalized; scale factor is exactly 2\n return [\n 1 - s * (ny * ny + nz * nz), s * (nx * ny - nw * nz), s * (nx * nz + nw * ny),\n s * (nx * ny + nw * nz), 1 - s * (nx * nx + nz * nz), s * (ny * nz - nw * nx),\n s * (nx * nz - nw * ny), s * (ny * nz + nw * nx), 1 - s * (nx * nx + ny * ny),\n ];\n}\n\n/**\n * Apply placement (rotate then translate) to a point.\n *\n * @param pl - the placement to apply.\n * @param w - the world-space input point (mm).\n * @returns the transformed point (mm).\n */\nexport function applyPlacement(pl: Placement, w: [number, number, number]): [number, number, number] {\n const m = quatToMatrix(pl.q);\n const r = (i: number): number => m[i * 3]! * w[0] + m[i * 3 + 1]! * w[1] + m[i * 3 + 2]! * w[2];\n return [r(0) + pl.p[0], r(1) + pl.p[1], r(2) + pl.p[2]];\n}\n\n/**\n * Apply the inverse placement (translate back, rotate by conjugate).\n *\n * @param pl - the placement whose inverse is applied.\n * @param w - the world-space input point (mm).\n * @returns the point mapped into the placement-local frame (mm).\n */\nexport function invertApplyPlacement(pl: Placement, w: [number, number, number]): [number, number, number] {\n const d: [number, number, number] = [w[0] - pl.p[0], w[1] - pl.p[1], w[2] - pl.p[2]];\n const inv: Placement = { p: [0, 0, 0], q: [-pl.q[0], -pl.q[1], -pl.q[2], pl.q[3]] };\n return applyPlacement(inv, d);\n}\n\n/**\n * M8.3 — quaternion → XYZ euler angles in DEGREES, matching the convention of\n * `rotateBrep` (brep/brep-ops.ts): THREE.Euler(order 'XYZ'), i.e. the rotation\n * matrix is RX·RY·RZ (column vectors; Z applied first). Pinned against THREE\n * itself in placement.test.ts — not from memory.\n *\n * @param q - the quaternion in (x, y, z, w) order.\n * @returns (x, y, z) euler angles in degrees.\n */\nexport function quatToEulerXYZDeg(q: [number, number, number, number]): [number, number, number] {\n const m = quatToMatrix(q);\n // M = RX·RY·RZ (row-major 3×3): m[2] = +sinY, m[5] = -sinX·cosY, m[8] = cosX·cosY\n const sy = m[2]!;\n const y = Math.asin(Math.max(-1, Math.min(1, sy)));\n if (Math.abs(sy) < 1 - 1e-9) {\n const x = Math.atan2(-m[5]!, m[8]!);\n const z = Math.atan2(-m[1]!, m[0]!);\n return [(x * 180) / Math.PI, (y * 180) / Math.PI, (z * 180) / Math.PI];\n }\n // gimbal lock: Y = ±90°, X and Z are coupled — set Z = 0; x from m[3]/m[4]\n const x = Math.atan2(m[3]!, m[4]!);\n return [(x * 180) / Math.PI, (y * 180) / Math.PI, 0];\n}\n\n/**\n * True when the placement is (approximately) the identity — no transform needed.\n *\n * @param pl - the placement to test.\n * @param eps - tolerance for both translation and quaternion components.\n * @returns true when the placement is within `eps` of identity.\n */\nexport function isIdentityPlacement(pl: Placement, eps = 1e-9): boolean {\n return (\n Math.abs(pl.p[0]) < eps && Math.abs(pl.p[1]) < eps && Math.abs(pl.p[2]) < eps &&\n Math.abs(pl.q[0]) < eps && Math.abs(pl.q[1]) < eps && Math.abs(pl.q[2]) < eps &&\n Math.abs(Math.abs(pl.q[3]) - 1) < eps\n );\n}\n\n/**\n * M8.3 — orthonormal sketch-plane basis (u, v) from the placement rotation:\n * u = rotated X axis, v = rotated Y axis, normal = rotated Z. Points on the\n * sketch plane (z≈0 in local coords) map to global as p·u + q·v.\n *\n * @param pl - the placement whose rotation defines the plane.\n * @returns the rotated X axis (u), Y axis (v) and plane normal (n).\n */\nexport function planeBasis(pl: Placement): { u: [number, number, number]; v: [number, number, number]; n: [number, number, number] } {\n const m = quatToMatrix(pl.q);\n // column i of the matrix = image of the i-th basis vector\n const col = (i: number): [number, number, number] => [m[i]!, m[i + 3]!, m[i + 6]!];\n return { u: col(0), v: col(1), n: col(2) };\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { GcsWrapper } from '@salusoft89/planegcs';
|
|
2
|
+
import { type Result } from '@faicad/faijs/api/result';
|
|
3
|
+
import type { SketchGeom, SketchCon } from './sketch-parse.js';
|
|
4
|
+
import type { SolveOutcome, SketchSolver } from './sketch-solver.js';
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the planegcs WASM binary path from the installed package.
|
|
7
|
+
*
|
|
8
|
+
* @returns the absolute path of `planegcs.wasm` inside `@salusoft89/planegcs`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function planegcsWasmPath(): string;
|
|
11
|
+
/**
|
|
12
|
+
* Instantiate the planegcs WASM solver.
|
|
13
|
+
*
|
|
14
|
+
* @returns a `SketchSolver` backed by the planegcs WASM module.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createPlanegcsSolver(): Promise<SketchSolver>;
|
|
17
|
+
/**
|
|
18
|
+
* planegcs WASM implementation of the `SketchSolver` interface (M3.2–M3.4):
|
|
19
|
+
* pushes geometry/constraints into the GCS, solves, and pulls the solved
|
|
20
|
+
* parameters back into `SketchGeom` values.
|
|
21
|
+
*/
|
|
22
|
+
export declare class PlanegcsSolver implements SketchSolver {
|
|
23
|
+
private wrapper;
|
|
24
|
+
constructor(wrapper: GcsWrapper);
|
|
25
|
+
solve(geoms: SketchGeom[], constraints: SketchCon[], external?: import('./sketch-solver.js').ExternalFixedSeg[]): Promise<Result<SolveOutcome, never>>;
|
|
26
|
+
private constraintToPrimitives;
|
|
27
|
+
private pullBack;
|
|
28
|
+
/** Read a point's solved coordinates from the sketch index.
|
|
29
|
+
* apply_solution() already pulled every primitive's solved values back into
|
|
30
|
+
* sketch_index (gcs_wrapper.js:104-108), so get_primitive is authoritative. */
|
|
31
|
+
private readPoint;
|
|
32
|
+
private readCircleRadius;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=planegcs-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planegcs-backend.d.ts","sourceRoot":"","sources":["../src/planegcs-backend.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAQrE;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAGlE;AAOD;;;;GAIG;AACH,qBAAa,cAAe,YAAW,YAAY;IACrC,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,UAAU;IAEjC,KAAK,CACT,KAAK,EAAE,UAAU,EAAE,EACnB,WAAW,EAAE,SAAS,EAAE,EACxB,QAAQ,CAAC,EAAE,OAAO,oBAAoB,EAAE,gBAAgB,EAAE,GACzD,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IA8OvC,OAAO,CAAC,sBAAsB;IAyR9B,OAAO,CAAC,QAAQ;IA0EhB;;mFAE+E;IAC/E,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,gBAAgB;CAIzB"}
|