@faicad/faijs-sketch 0.18.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.
Files changed (59) hide show
  1. package/LICENSE +28 -0
  2. package/NOTICE +28 -0
  3. package/dist/bspline.d.ts +58 -0
  4. package/dist/bspline.d.ts.map +1 -0
  5. package/dist/bspline.js +93 -0
  6. package/dist/bspline.js.map +1 -0
  7. package/dist/canonical.d.ts +205 -0
  8. package/dist/canonical.d.ts.map +1 -0
  9. package/dist/canonical.js +12 -0
  10. package/dist/canonical.js.map +1 -0
  11. package/dist/contour.d.ts +43 -0
  12. package/dist/contour.d.ts.map +1 -0
  13. package/dist/contour.js +132 -0
  14. package/dist/contour.js.map +1 -0
  15. package/dist/faces.d.ts +28 -0
  16. package/dist/faces.d.ts.map +1 -0
  17. package/dist/faces.js +46 -0
  18. package/dist/faces.js.map +1 -0
  19. package/dist/fcstd-types.d.ts +177 -0
  20. package/dist/fcstd-types.d.ts.map +1 -0
  21. package/dist/fcstd-types.js +67 -0
  22. package/dist/fcstd-types.js.map +1 -0
  23. package/dist/index.d.ts +36 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +28 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/namespace.d.ts +51 -0
  28. package/dist/namespace.d.ts.map +1 -0
  29. package/dist/namespace.js +67 -0
  30. package/dist/namespace.js.map +1 -0
  31. package/dist/node.d.ts +14 -0
  32. package/dist/node.d.ts.map +1 -0
  33. package/dist/node.js +34 -0
  34. package/dist/node.js.map +1 -0
  35. package/dist/op.d.ts +67 -0
  36. package/dist/op.d.ts.map +1 -0
  37. package/dist/op.js +104 -0
  38. package/dist/op.js.map +1 -0
  39. package/dist/planegcs-backend.d.ts +46 -0
  40. package/dist/planegcs-backend.d.ts.map +1 -0
  41. package/dist/planegcs-backend.js +696 -0
  42. package/dist/planegcs-backend.js.map +1 -0
  43. package/dist/project.d.ts +115 -0
  44. package/dist/project.d.ts.map +1 -0
  45. package/dist/project.js +329 -0
  46. package/dist/project.js.map +1 -0
  47. package/dist/solve.d.ts +21 -0
  48. package/dist/solve.d.ts.map +1 -0
  49. package/dist/solve.js +102 -0
  50. package/dist/solve.js.map +1 -0
  51. package/dist/solver.d.ts +63 -0
  52. package/dist/solver.d.ts.map +1 -0
  53. package/dist/solver.js +28 -0
  54. package/dist/solver.js.map +1 -0
  55. package/dist/verify.d.ts +53 -0
  56. package/dist/verify.d.ts.map +1 -0
  57. package/dist/verify.js +71 -0
  58. package/dist/verify.js.map +1 -0
  59. package/package.json +65 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * project — single-point conversion between the canonical sketch model and the\n * two downstream projection dialects (§4.5).\n *\n * canonical ⇄ FCStd (`fcstd-types`, integer ConstraintType + PointPos)\n * canonical ⇄ CadQuery (tag + string constraint names, 0..1 positions)\n *\n * One implementation, two projections: the FCStd side feeds the planegcs solve\n * pipeline; the CadQuery side feeds `cq-compat-sketch`. Constraints with no\n * counterpart in a target dialect raise an explicit `E_SKETCHC_*` — never a\n * silent downgrade.\n */\nimport { PointPos, type FcstdGeoRef, type FcstdSketchGeom, type FcstdSketchCon } from './fcstd-types.js'\nimport { ConstraintType } from './fcstd-types.js'\nimport type { At, Ref, SketchConstraint, SketchConstraintKind, SketchGeom } from './canonical.js'\n\n/** Projection error with a stable `E_SKETCHC_*` code. */\nexport class SketchProjectionError extends Error {\n constructor(public readonly code: string, message: string) {\n super(`${code}: ${message}`)\n this.name = 'SketchProjectionError'\n }\n}\n\n// ── at / Ref resolution ──\n\n/**\n * Map a canonical `At` to an FCStd `PointPos`. Throws `E_SKETCHC_UNMAPPED` when there is no counterpart.\n *\n * @param at - the canonical position.\n * @returns the FCStd `PointPos` integer.\n */\nexport function atToFreeCad(at: At | undefined): number {\n if (at === undefined) return PointPos.none\n if (at === 'start') return PointPos.start\n if (at === 'end') return PointPos.end\n if (at === 'center') return PointPos.mid\n if (at === 'mid') {\n throw new SketchProjectionError('E_SKETCHC_UNMAPPED', 'at \"mid\" (arc/line midpoint) has no FCStd PointPos')\n }\n if (typeof at === 'number') {\n if (at === 0) return PointPos.start\n if (at === 1) return PointPos.end\n throw new SketchProjectionError('E_SKETCHC_UNMAPPED', `parametric at ${at} has no FCStd PointPos`)\n }\n throw new SketchProjectionError('E_SKETCHC_UNMAPPED', `unsupported at ${String(at)}`)\n}\n\n/**\n * Map an FCStd `PointPos` to a canonical `At` (`mid` FCStd means the centre).\n *\n * @param pos - the FCStd `PointPos` integer.\n * @returns the canonical position, or `undefined` for `none`.\n */\nexport function atFromFreeCad(pos: number): At | undefined {\n switch (pos) {\n case PointPos.none: return undefined\n case PointPos.start: return 'start'\n case PointPos.end: return 'end'\n case PointPos.mid: return 'center'\n default: return undefined\n }\n}\n\n/**\n * Map a canonical `At` to a CadQuery 0..1 parameter (`null` = the arc-centre `None` argument).\n *\n * @param at - the canonical position.\n * @returns the CadQuery 0..1 parameter, or `null` for centre.\n */\nexport function atToCadQuery(at: At | undefined): number | null {\n if (at === undefined) return null\n if (at === 'start') return 0\n if (at === 'end') return 1\n if (at === 'mid') return 0.5\n if (at === 'center') return null\n return at\n}\n\n/**\n * Map a CadQuery 0..1 parameter to a canonical `At`.\n *\n * @param v - the CadQuery parameter, or `null`/`undefined` for centre.\n * @returns the canonical position, or `undefined` for `null`/`undefined`.\n */\nexport function atFromCadQuery(v: number | null | undefined): At | undefined {\n if (v === null || v === undefined) return undefined\n if (v === 0) return 'start'\n if (v === 1) return 'end'\n if (v === 0.5) return 'mid'\n return v\n}\n\n/**\n * Build the tag → index lookup for a geometry list in one pass.\n *\n * @param geoms - canonical geometry list.\n * @returns tag → geometry index.\n */\nexport function buildTagIndex(geoms: SketchGeom[]): Map<string, number> {\n const index = new Map<string, number>()\n geoms.forEach((g, i) => {\n if (g.tag !== undefined) index.set(g.tag, i)\n })\n return index\n}\n\n/**\n * Resolve a canonical `Ref` to an FCStd `(geoId, pos)` pair.\n *\n * @param ref - the canonical reference (tag or index + at).\n * @param tagIndex - tag → index map (from {@link buildTagIndex}).\n * @param geoms - the geometry array (for bounds checking of index refs).\n * @returns the FCStd `(geoId, pos)` pair.\n * @throws SketchProjectionError `E_SKETCHC_BAD_REF` for unknown tag or out-of-range index.\n */\nexport function refToFreeCad(ref: Ref, tagIndex: Map<string, number>, geoms: SketchGeom[]): FcstdGeoRef {\n let geoId: number\n if ('tag' in ref) {\n const found = tagIndex.get(ref.tag)\n if (found === undefined) {\n throw new SketchProjectionError('E_SKETCHC_BAD_REF', `unknown tag \"${ref.tag}\"`)\n }\n geoId = found\n } else {\n if (!Number.isInteger(ref.index) || ref.index < 0 || ref.index >= geoms.length) {\n throw new SketchProjectionError('E_SKETCHC_BAD_REF', `index ${ref.index} out of range [0, ${geoms.length})`)\n }\n geoId = ref.index\n }\n return { geoId, pos: atToFreeCad(ref.at) }\n}\n\n// ── geometry projection ──\n\n/**\n * Project canonical geometry to the FCStd shape consumed by the solver.\n *\n * @param geoms - canonical geometry.\n * @returns FCStd geometry records (same order/index).\n * @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_GEOM` for reserved kinds.\n */\nexport function toFreeCadGeoms(geoms: SketchGeom[]): FcstdSketchGeom[] {\n return geoms.map((g, index): FcstdSketchGeom => {\n switch (g.kind) {\n case 'line':\n return { kind: 'line', index, x1: g.x1, y1: g.y1, z1: 0, x2: g.x2, y2: g.y2, z2: 0 }\n case 'circle':\n return { kind: 'circle', index, cx: g.cx, cy: g.cy, cz: 0, radius: g.r }\n case 'arc': {\n // Pass the canonical signed span (a0, a1) through unchanged. planegcs builds\n // the arc from the pinned start/end endpoints *and* the signed start/end\n // angles, so a CW arc (a1 < a0) is drawn as the short clockwise arc.\n // Normalising a1 into a CCW span would instead produce the long arc through\n // those same endpoints. Arc orientation is carried back to the caller via\n // solveSketch (input ccw preserved), not recovered here.\n const a0 = g.a0\n const a1 = g.a1\n return {\n kind: 'arc', index, cx: g.cx, cy: g.cy, cz: 0, radius: g.r,\n startAngle: a0, endAngle: a1,\n x1: g.cx + g.r * Math.cos(a0), y1: g.cy + g.r * Math.sin(a0), z1: 0,\n x2: g.cx + g.r * Math.cos(a1), y2: g.cy + g.r * Math.sin(a1), z2: 0,\n }\n }\n case 'point':\n case 'ellipse':\n case 'bspline':\n throw new SketchProjectionError('E_SKETCHC_UNSUPPORTED_GEOM', `geometry kind \"${g.kind}\" is not supported in the first release`)\n }\n })\n}\n\n/**\n * Project FCStd geometry back to the canonical model (reserved kinds are reported).\n *\n * @param geoms - FCStd geometry records from the solver.\n * @returns canonical geometry (same order/index).\n */\nexport function fromFreeCadGeoms(geoms: FcstdSketchGeom[]): SketchGeom[] {\n return geoms.map((g): SketchGeom => {\n switch (g.kind) {\n case 'line':\n return { kind: 'line', x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2 }\n case 'circle':\n return { kind: 'circle', cx: g.cx, cy: g.cy, r: g.radius }\n case 'arc': {\n const ccw = normalizeArcCcw(g.startAngle, g.endAngle)\n return { kind: 'arc', cx: g.cx, cy: g.cy, r: g.radius, a0: g.startAngle, a1: g.endAngle, ccw }\n }\n case 'point':\n return { kind: 'point', x: g.x, y: g.y }\n case 'ellipse':\n return { kind: 'ellipse', cx: g.cx, cy: g.cy, rx: g.majorRadius, ry: g.minorRadius, angle: g.angleXU }\n case 'bspline':\n return { kind: 'bspline', poles: g.poles, knots: g.knots, degree: g.degree, periodic: g.periodic }\n }\n })\n}\n\n/** True when the arc span is counter-clockwise as stored. */\nfunction normalizeArcCcw(startAngle: number, endAngle: number): boolean {\n let sweep = endAngle - startAngle\n while (sweep <= 0) sweep += 2 * Math.PI\n while (sweep > 2 * Math.PI) sweep -= 2 * Math.PI\n return sweep > 0\n}\n\n// ── constraint projection ──\n\n/** FCStd constraint shape produced by one canonical constraint. */\ninterface FcstdConstraintShape {\n type: number\n refs: FcstdGeoRef[]\n value?: number\n}\n\n/** `'noop'`: no FCStd constraint is needed (the implicit fixed frame covers it). */\ntype Mapped = FcstdConstraintShape | 'noop'\n\nfunction mapConstraint(c: SketchConstraint, tagIndex: Map<string, number>, geoms: SketchGeom[]): Mapped {\n const ref = (r: Ref): FcstdGeoRef => refToFreeCad(r, tagIndex, geoms)\n switch (c.kind) {\n case 'fixed':\n // FCStd has no explicit fixed constraint — the implicit fixed frame\n // (RtPnt + H/V axes) absorbs the rigid-body DoF (§4.5).\n return 'noop'\n case 'coincident':\n return { type: ConstraintType.Coincident, refs: [ref(c.a), ref(c.b)] }\n case 'horizontal':\n return { type: ConstraintType.Horizontal, refs: [ref(c.of)] }\n case 'vertical':\n return { type: ConstraintType.Vertical, refs: [ref(c.of)] }\n case 'parallel':\n return { type: ConstraintType.Parallel, refs: [ref(c.a), ref(c.b)] }\n case 'perpendicular':\n return { type: ConstraintType.Perpendicular, refs: [ref(c.a), ref(c.b)] }\n case 'tangent':\n return { type: ConstraintType.Tangent, refs: [ref(c.a), ref(c.b)] }\n case 'distance':\n return { type: ConstraintType.Distance, refs: [ref(c.a), ref(c.b)], value: c.value }\n case 'distanceX':\n return { type: ConstraintType.DistanceX, refs: [ref(c.a), ref(c.b)], value: c.value }\n case 'distanceY':\n return { type: ConstraintType.DistanceY, refs: [ref(c.a), ref(c.b)], value: c.value }\n case 'length': {\n // Length is expressed as a point-to-point Distance over the element ends.\n const base = ref(c.of)\n const start = { geoId: base.geoId, pos: PointPos.start }\n const end = { geoId: base.geoId, pos: PointPos.end }\n return { type: ConstraintType.Distance, refs: [start, end], value: c.value }\n }\n case 'angle':\n return { type: ConstraintType.Angle, refs: [ref(c.a), ref(c.b)], value: c.value }\n case 'orientation':\n throw new SketchProjectionError('E_SKETCHC_UNMAPPED', 'constraint \"orientation\" has no FCStd counterpart')\n case 'radius':\n return { type: ConstraintType.Radius, refs: [ref(c.of)], value: c.value }\n case 'diameter':\n return { type: ConstraintType.Diameter, refs: [ref(c.of)], value: c.value }\n case 'arcAngle':\n throw new SketchProjectionError('E_SKETCHC_UNMAPPED', 'constraint \"arcAngle\" has no FCStd counterpart')\n case 'equal':\n return { type: ConstraintType.Equal, refs: [ref(c.a), ref(c.b)] }\n case 'pointOnObject':\n return { type: ConstraintType.PointOnObject, refs: [ref(c.p), ref(c.on)] }\n case 'symmetric':\n return { type: ConstraintType.Symmetric, refs: [ref(c.p1), ref(c.p2), ref(c.about)] }\n }\n}\n\n/** Result of projecting canonical constraints to FCStd. */\nexport interface ProjectedConstraints {\n /** FCStd constraints (index matches the canonical constraint order for kept items). */\n constraints: FcstdSketchCon[]\n /** canonical constraint indices mapped to a deliberate no-op (fixed). */\n noops: number[]\n}\n\n/**\n * Project canonical constraints to the FCStd shape the solver consumes.\n *\n * @param constraints - canonical constraints.\n * @param geoms - canonical geometry (for tag/index resolution).\n * @returns FCStd constraints plus the no-op (`fixed`) indices.\n */\nexport function toFreeCadConstraints(constraints: SketchConstraint[], geoms: SketchGeom[]): ProjectedConstraints {\n const tagIndex = buildTagIndex(geoms)\n const out: FcstdSketchCon[] = []\n const noops: number[] = []\n constraints.forEach((c, index) => {\n const mapped = mapConstraint(c, tagIndex, geoms)\n if (mapped === 'noop') {\n noops.push(index)\n return\n }\n out.push({ index, type: mapped.type, refs: mapped.refs, value: mapped.value ?? 0, isDriving: true, name: '' })\n })\n return { constraints: out, noops }\n}\n\n// ── CadQuery projection (constraint type names) ──\n\n/** CadQuery constraint names for the canonical kinds it supports (the other 8). */\nexport const CONSTRAINT_KIND_TO_CADQUERY: Partial<Record<SketchConstraintKind, string>> = {\n fixed: 'FixedPoint',\n coincident: 'Coincident',\n angle: 'Angle',\n length: 'Length',\n distance: 'Distance',\n radius: 'Radius',\n orientation: 'Orientation',\n arcAngle: 'ArcAngle',\n}\n\n/** CadQuery constraint name → canonical kind. */\nexport const CADQUERY_TO_CONSTRAINT_KIND: Record<string, SketchConstraintKind> = Object.fromEntries(\n Object.entries(CONSTRAINT_KIND_TO_CADQUERY).map(([kind, name]) => [name, kind as SketchConstraintKind]),\n)\n\n/**\n * Map a canonical constraint kind to its CadQuery name.\n *\n * @param kind - canonical constraint kind.\n * @returns the CadQuery constraint name.\n * @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_BY_CQ` when CQ has no counterpart.\n */\nexport function constraintKindToCadQuery(kind: SketchConstraintKind): string {\n const name = CONSTRAINT_KIND_TO_CADQUERY[kind]\n if (!name) {\n throw new SketchProjectionError('E_SKETCHC_UNSUPPORTED_BY_CQ', `constraint \"${kind}\" is not supported by CadQuery`)\n }\n return name\n}\n\n/**\n * Map a CadQuery constraint name to its canonical kind.\n *\n * @param name - CadQuery constraint name.\n * @returns the canonical kind.\n * @throws SketchProjectionError `E_SKETCHC_UNSUPPORTED_CONSTRAINT` for unknown names.\n */\nexport function constraintKindFromCadQuery(name: string): SketchConstraintKind {\n const kind = CADQUERY_TO_CONSTRAINT_KIND[name]\n if (!kind) {\n throw new SketchProjectionError('E_SKETCHC_UNSUPPORTED_CONSTRAINT', `unknown CadQuery constraint \"${name}\"`)\n }\n return kind\n}"]}
@@ -0,0 +1,21 @@
1
+ import type { SketchConstraint, SketchGeom, SolveOutcome } from './canonical.js';
2
+ import { type PlanegcsSolverOptions } from './planegcs-backend.js';
3
+ import type { ExternalFixedSeg, SketchSolver } from './solver.js';
4
+ /** Options for {@link solveSketch}. */
5
+ export interface SolveSketchOptions extends PlanegcsSolverOptions {
6
+ /** A pre-built solver (avoids re-instantiating the wasm module per call). */
7
+ solver?: SketchSolver;
8
+ /** Pre-projected fixed external geometry the constraints may reference. */
9
+ external?: ExternalFixedSeg[];
10
+ }
11
+ /**
12
+ * Solve a canonical sketch.
13
+ *
14
+ * @param geoms - canonical geometry; stored coordinates are the initial guess.
15
+ * @param constraints - canonical constraints (default: none — a declarative sketch).
16
+ * @param opts - solver selection / external geometry.
17
+ * @returns the solved geometry plus explicit diagnostics.
18
+ * @throws SketchProjectionError for bad refs / unsupported geometry / unmapped constraints.
19
+ */
20
+ export declare function solveSketch(geoms: SketchGeom[], constraints?: SketchConstraint[], opts?: SolveSketchOptions): Promise<SolveOutcome>;
21
+ //# sourceMappingURL=solve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve.d.ts","sourceRoot":"","sources":["../src/solve.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,EAAe,MAAM,gBAAgB,CAAA;AAE7F,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEjE,uCAAuC;AACvC,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB;IAC/D,6EAA6E;IAC7E,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAA;CAC9B;AAyBD;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,UAAU,EAAE,EACnB,WAAW,GAAE,gBAAgB,EAAO,EACpC,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,YAAY,CAAC,CAwDvB"}
package/dist/solve.js ADDED
@@ -0,0 +1,102 @@
1
+ /**
2
+ * solve — `solveSketch`: the canonical-model entry to the planegcs pipeline.
3
+ *
4
+ * Projects canonical geometry/constraints to the FCStd shape the backend
5
+ * consumes, solves, and projects the solved geometry back. Under- and
6
+ * over-constraint are allowed and surface through `SolveOutcome.status` (§5);
7
+ * projection errors (bad ref, unsupported geometry, unmapped constraint) are
8
+ * raised so the caller can surface them explicitly rather than silently.
9
+ */
10
+ import { isOk } from '@faicad/faijs/api/result';
11
+ import { fromFreeCadGeoms, toFreeCadConstraints, toFreeCadGeoms } from './project.js';
12
+ import { createPlanegcsSolver } from './planegcs-backend.js';
13
+ /** Resolve a solver from the options (explicit solver → wasm source → error). */
14
+ async function resolveSolver(opts) {
15
+ if (opts?.solver)
16
+ return opts.solver;
17
+ if (opts?.wasmPath !== undefined || opts?.wasmBytes !== undefined) {
18
+ return createPlanegcsSolver({ wasmPath: opts.wasmPath, wasmBytes: opts.wasmBytes });
19
+ }
20
+ throw new Error('E_SKETCHC_NO_WASM: solveSketch needs opts.solver, opts.wasmPath or opts.wasmBytes');
21
+ }
22
+ /** Probe the wrapper's remaining-DoF report when the backend exposes one. */
23
+ function readDof(solver) {
24
+ const probe = solver.getDof;
25
+ if (typeof probe === 'function') {
26
+ try {
27
+ const v = probe.call(solver);
28
+ if (typeof v === 'number' && Number.isFinite(v))
29
+ return v;
30
+ }
31
+ catch {
32
+ /* backend does not report DoF */
33
+ }
34
+ }
35
+ return -1;
36
+ }
37
+ /**
38
+ * Solve a canonical sketch.
39
+ *
40
+ * @param geoms - canonical geometry; stored coordinates are the initial guess.
41
+ * @param constraints - canonical constraints (default: none — a declarative sketch).
42
+ * @param opts - solver selection / external geometry.
43
+ * @returns the solved geometry plus explicit diagnostics.
44
+ * @throws SketchProjectionError for bad refs / unsupported geometry / unmapped constraints.
45
+ */
46
+ export async function solveSketch(geoms, constraints = [], opts) {
47
+ const fcstdGeoms = toFreeCadGeoms(geoms);
48
+ const projected = toFreeCadConstraints(constraints, geoms);
49
+ const solver = await resolveSolver(opts);
50
+ const result = await solver.solve(fcstdGeoms, projected.constraints, opts?.external);
51
+ if (!isOk(result)) {
52
+ return {
53
+ geoms, converged: false, status: 'failed', dof: -1,
54
+ problemConstraints: [], droppedConstraints: [], reason: 'solver-error',
55
+ };
56
+ }
57
+ const raw = result.value;
58
+ const solvedCanonical = fromFreeCadGeoms(raw.geoms).map((g, i) => {
59
+ const input = geoms[i];
60
+ const tag = input?.tag;
61
+ // Preserve the author's arc orientation (ccw) across the solve. The FCStd
62
+ // round-trip only reports a CCW-normalised span (see fromFreeCadGeoms), so a
63
+ // CW arc would otherwise come back as ccw:true and be rebuilt as the long CCW
64
+ // arc through arcToHandles — the A3 regression class. The solver only relocates
65
+ // coordinates; it does not change which arc (CW minor vs CCW) the author intended.
66
+ if (g.kind === 'arc' && input?.kind === 'arc') {
67
+ const withCcw = { ...g, ccw: input.ccw };
68
+ return tag === undefined ? withCcw : { ...withCcw, tag };
69
+ }
70
+ return tag === undefined ? g : { ...g, tag };
71
+ });
72
+ let status;
73
+ let dof;
74
+ if (raw.converged) {
75
+ dof = readDof(solver);
76
+ if (raw.droppedConstraints.length > 0) {
77
+ status = 'redundant';
78
+ }
79
+ else if (dof > 0) {
80
+ status = 'underconstrained';
81
+ }
82
+ else {
83
+ status = 'solved';
84
+ }
85
+ }
86
+ else {
87
+ dof = -1;
88
+ status = raw.reason === 'conflicting' ? 'conflicting'
89
+ : raw.reason === 'redundant' ? 'redundant'
90
+ : 'failed';
91
+ }
92
+ return {
93
+ geoms: solvedCanonical,
94
+ converged: raw.converged,
95
+ status,
96
+ dof,
97
+ problemConstraints: raw.problemConstraints,
98
+ droppedConstraints: raw.droppedConstraints,
99
+ reason: raw.converged ? undefined : raw.reason,
100
+ };
101
+ }
102
+ //# sourceMappingURL=solve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve.js","sourceRoot":"","sources":["../src/solve.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * solve — `solveSketch`: the canonical-model entry to the planegcs pipeline.\n *\n * Projects canonical geometry/constraints to the FCStd shape the backend\n * consumes, solves, and projects the solved geometry back. Under- and\n * over-constraint are allowed and surface through `SolveOutcome.status` (§5);\n * projection errors (bad ref, unsupported geometry, unmapped constraint) are\n * raised so the caller can surface them explicitly rather than silently.\n */\nimport { isOk } from '@faicad/faijs/api/result'\nimport type { SketchConstraint, SketchGeom, SolveOutcome, SolveStatus } from './canonical.js'\nimport { fromFreeCadGeoms, toFreeCadConstraints, toFreeCadGeoms } from './project.js'\nimport { createPlanegcsSolver, type PlanegcsSolverOptions } from './planegcs-backend.js'\nimport type { ExternalFixedSeg, SketchSolver } from './solver.js'\n\n/** Options for {@link solveSketch}. */\nexport interface SolveSketchOptions extends PlanegcsSolverOptions {\n /** A pre-built solver (avoids re-instantiating the wasm module per call). */\n solver?: SketchSolver\n /** Pre-projected fixed external geometry the constraints may reference. */\n external?: ExternalFixedSeg[]\n}\n\n/** Resolve a solver from the options (explicit solver → wasm source → error). */\nasync function resolveSolver(opts?: SolveSketchOptions): Promise<SketchSolver> {\n if (opts?.solver) return opts.solver\n if (opts?.wasmPath !== undefined || opts?.wasmBytes !== undefined) {\n return createPlanegcsSolver({ wasmPath: opts.wasmPath, wasmBytes: opts.wasmBytes })\n }\n throw new Error('E_SKETCHC_NO_WASM: solveSketch needs opts.solver, opts.wasmPath or opts.wasmBytes')\n}\n\n/** Probe the wrapper's remaining-DoF report when the backend exposes one. */\nfunction readDof(solver: SketchSolver): number {\n const probe = (solver as unknown as { getDof?: () => number }).getDof\n if (typeof probe === 'function') {\n try {\n const v = probe.call(solver)\n if (typeof v === 'number' && Number.isFinite(v)) return v\n } catch {\n /* backend does not report DoF */\n }\n }\n return -1\n}\n\n/**\n * Solve a canonical sketch.\n *\n * @param geoms - canonical geometry; stored coordinates are the initial guess.\n * @param constraints - canonical constraints (default: none — a declarative sketch).\n * @param opts - solver selection / external geometry.\n * @returns the solved geometry plus explicit diagnostics.\n * @throws SketchProjectionError for bad refs / unsupported geometry / unmapped constraints.\n */\nexport async function solveSketch(\n geoms: SketchGeom[],\n constraints: SketchConstraint[] = [],\n opts?: SolveSketchOptions,\n): Promise<SolveOutcome> {\n const fcstdGeoms = toFreeCadGeoms(geoms)\n const projected = toFreeCadConstraints(constraints, geoms)\n const solver = await resolveSolver(opts)\n\n const result = await solver.solve(fcstdGeoms, projected.constraints, opts?.external)\n if (!isOk(result)) {\n return {\n geoms, converged: false, status: 'failed', dof: -1,\n problemConstraints: [], droppedConstraints: [], reason: 'solver-error',\n }\n }\n\n const raw = result.value\n const solvedCanonical = fromFreeCadGeoms(raw.geoms).map((g, i) => {\n const input = geoms[i]\n const tag = input?.tag\n // Preserve the author's arc orientation (ccw) across the solve. The FCStd\n // round-trip only reports a CCW-normalised span (see fromFreeCadGeoms), so a\n // CW arc would otherwise come back as ccw:true and be rebuilt as the long CCW\n // arc through arcToHandles — the A3 regression class. The solver only relocates\n // coordinates; it does not change which arc (CW minor vs CCW) the author intended.\n if (g.kind === 'arc' && input?.kind === 'arc') {\n const withCcw = { ...g, ccw: input.ccw }\n return tag === undefined ? withCcw : { ...withCcw, tag }\n }\n return tag === undefined ? g : { ...g, tag }\n })\n\n let status: SolveStatus\n let dof: number\n if (raw.converged) {\n dof = readDof(solver)\n if (raw.droppedConstraints.length > 0) {\n status = 'redundant'\n } else if (dof > 0) {\n status = 'underconstrained'\n } else {\n status = 'solved'\n }\n } else {\n dof = -1\n status = raw.reason === 'conflicting' ? 'conflicting'\n : raw.reason === 'redundant' ? 'redundant'\n : 'failed'\n }\n\n return {\n geoms: solvedCanonical,\n converged: raw.converged,\n status,\n dof,\n problemConstraints: raw.problemConstraints,\n droppedConstraints: raw.droppedConstraints,\n reason: raw.converged ? undefined : raw.reason,\n }\n}"]}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * M3.2 — SketchSolver interface (D5) with the planegcs WASM backend.
3
+ *
4
+ * faijs depends only on this interface; the WASM implementation is swappable
5
+ * (前文 B R2/R3). Input: parsed sketch geometry + constraints (M3.1 types).
6
+ * Output: solved geometry or a structured failure — the caller (M3.5) decides
7
+ * between solution and initial-value fallback (D2).
8
+ */
9
+ import type { Result } from '@faicad/faijs/api/result';
10
+ import type { FcstdSketchGeom, FcstdSketchCon } from './fcstd-types.js';
11
+ /**
12
+ * Result of one solver run: the solved geometry plus convergence status and
13
+ * diagnostics for the caller's L0/L1/L2 decision (D2).
14
+ */
15
+ export interface FcstdSolveOutcome {
16
+ /** geometry after solve, same order/index as input */
17
+ geoms: FcstdSketchGeom[];
18
+ /** true when the solver reports Success with no conflicts */
19
+ converged: boolean;
20
+ /** diagnostics when not converged */
21
+ reason?: 'conflicting' | 'redundant' | 'failed' | 'unsupported-constraint';
22
+ /** constraint indices the solver flagged */
23
+ problemConstraints: number[];
24
+ /** constraint indices dropped because their GCS shape could not be pushed */
25
+ droppedConstraints: number[];
26
+ }
27
+ /**
28
+ * One pre-projected external geometry segment passed to the solver as fixed
29
+ * (immutable) geometry.
30
+ */
31
+ export interface ExternalFixedSeg {
32
+ /** negative geoId in link order: -3, -4, ... (GeoEnum.RefExt downward) */
33
+ geoId: number;
34
+ /** the projected sketch-local 2D polyline (immutable to the solver) */
35
+ polyline: [number, number][];
36
+ }
37
+ /**
38
+ * Solver abstraction (D5): faijs depends only on this interface; the WASM
39
+ * implementation is swappable.
40
+ */
41
+ export interface SketchSolver {
42
+ /**
43
+ * Solve constraints against the given geometry. The input geometry's stored
44
+ * coordinates are used as the initial guess (D2 — they are FreeCAD's last
45
+ * solution and the ideal starting point).
46
+ *
47
+ * `external` carries pre-projected fixed geometry (M6.3): immutable 2D
48
+ * polylines that constraints may reference by negative geoId. When a
49
+ * constraint references an external geoId not present here, the solver
50
+ * drops that constraint (recorded in droppedConstraints).
51
+ */
52
+ solve(geoms: FcstdSketchGeom[], constraints: FcstdSketchCon[], external?: ExternalFixedSeg[]): Promise<Result<FcstdSolveOutcome, never>>;
53
+ }
54
+ /** Constraint types the planegcs backend can express (P0 set, plan §7 M3.4). */
55
+ export declare const SUPPORTED_CONSTRAINT_TYPES: Set<number>;
56
+ /**
57
+ * Check whether every constraint in a sketch is expressible by the backend.
58
+ *
59
+ * @param constraints - the parsed sketch constraints.
60
+ * @returns true when every constraint's type is in SUPPORTED_CONSTRAINT_TYPES.
61
+ */
62
+ export declare function allConstraintsSupported(constraints: FcstdSketchCon[]): boolean;
63
+ //# sourceMappingURL=solver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAExE;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,sDAAsD;IACtD,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,wBAAwB,CAAC;IAC3E,4CAA4C;IAC5C,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,6EAA6E;IAC7E,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;OASG;IACH,KAAK,CACH,KAAK,EAAE,eAAe,EAAE,EACxB,WAAW,EAAE,cAAc,EAAE,EAC7B,QAAQ,CAAC,EAAE,gBAAgB,EAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC;CAC9C;AAED,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,aAgBrC,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAE9E"}
package/dist/solver.js ADDED
@@ -0,0 +1,28 @@
1
+ /** Constraint types the planegcs backend can express (P0 set, plan §7 M3.4). */
2
+ export const SUPPORTED_CONSTRAINT_TYPES = new Set([
3
+ 1, // Coincident
4
+ 2, // Horizontal
5
+ 3, // Vertical
6
+ 4, // Parallel
7
+ 5, // Tangent
8
+ 6, // Distance
9
+ 7, // DistanceX
10
+ 8, // DistanceY
11
+ 9, // Angle
12
+ 10, // Perpendicular
13
+ 11, // Radius
14
+ 12, // Equal
15
+ 13, // PointOnObject
16
+ 14, // Symmetric
17
+ 18, // Diameter
18
+ ]);
19
+ /**
20
+ * Check whether every constraint in a sketch is expressible by the backend.
21
+ *
22
+ * @param constraints - the parsed sketch constraints.
23
+ * @returns true when every constraint's type is in SUPPORTED_CONSTRAINT_TYPES.
24
+ */
25
+ export function allConstraintsSupported(constraints) {
26
+ return constraints.every((c) => SUPPORTED_CONSTRAINT_TYPES.has(c.type));
27
+ }
28
+ //# sourceMappingURL=solver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solver.js","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"AA6DA,gFAAgF;AAChF,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAS;IACxD,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,WAAW;IACd,CAAC,EAAE,WAAW;IACd,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,WAAW;IACd,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,QAAQ;IACX,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,YAAY;IAChB,EAAE,EAAE,WAAW;CAChB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAA6B;IACnE,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["/**\n * M3.2 — SketchSolver interface (D5) with the planegcs WASM backend.\n *\n * faijs depends only on this interface; the WASM implementation is swappable\n * (前文 B R2/R3). Input: parsed sketch geometry + constraints (M3.1 types).\n * Output: solved geometry or a structured failure — the caller (M3.5) decides\n * between solution and initial-value fallback (D2).\n */\nimport type { Result } from '@faicad/faijs/api/result';\nimport type { FcstdSketchGeom, FcstdSketchCon } from './fcstd-types.js';\n\n/**\n * Result of one solver run: the solved geometry plus convergence status and\n * diagnostics for the caller's L0/L1/L2 decision (D2).\n */\nexport interface FcstdSolveOutcome {\n /** geometry after solve, same order/index as input */\n geoms: FcstdSketchGeom[];\n /** true when the solver reports Success with no conflicts */\n converged: boolean;\n /** diagnostics when not converged */\n reason?: 'conflicting' | 'redundant' | 'failed' | 'unsupported-constraint';\n /** constraint indices the solver flagged */\n problemConstraints: number[];\n /** constraint indices dropped because their GCS shape could not be pushed */\n droppedConstraints: number[];\n}\n\n/**\n * One pre-projected external geometry segment passed to the solver as fixed\n * (immutable) geometry.\n */\nexport interface ExternalFixedSeg {\n /** negative geoId in link order: -3, -4, ... (GeoEnum.RefExt downward) */\n geoId: number;\n /** the projected sketch-local 2D polyline (immutable to the solver) */\n polyline: [number, number][];\n}\n\n/**\n * Solver abstraction (D5): faijs depends only on this interface; the WASM\n * implementation is swappable.\n */\nexport interface SketchSolver {\n /**\n * Solve constraints against the given geometry. The input geometry's stored\n * coordinates are used as the initial guess (D2 — they are FreeCAD's last\n * solution and the ideal starting point).\n *\n * `external` carries pre-projected fixed geometry (M6.3): immutable 2D\n * polylines that constraints may reference by negative geoId. When a\n * constraint references an external geoId not present here, the solver\n * drops that constraint (recorded in droppedConstraints).\n */\n solve(\n geoms: FcstdSketchGeom[],\n constraints: FcstdSketchCon[],\n external?: ExternalFixedSeg[],\n ): Promise<Result<FcstdSolveOutcome, never>>;\n}\n\n/** Constraint types the planegcs backend can express (P0 set, plan §7 M3.4). */\nexport const SUPPORTED_CONSTRAINT_TYPES = new Set<number>([\n 1, // Coincident\n 2, // Horizontal\n 3, // Vertical\n 4, // Parallel\n 5, // Tangent\n 6, // Distance\n 7, // DistanceX\n 8, // DistanceY\n 9, // Angle\n 10, // Perpendicular\n 11, // Radius\n 12, // Equal\n 13, // PointOnObject\n 14, // Symmetric\n 18, // Diameter\n]);\n\n/**\n * Check whether every constraint in a sketch is expressible by the backend.\n *\n * @param constraints - the parsed sketch constraints.\n * @returns true when every constraint's type is in SUPPORTED_CONSTRAINT_TYPES.\n */\nexport function allConstraintsSupported(constraints: FcstdSketchCon[]): boolean {\n return constraints.every((c) => SUPPORTED_CONSTRAINT_TYPES.has(c.type));\n}\n"]}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * M3.5 — solved-vs-stored comparison (D2/V2).
3
+ *
4
+ * The on-disk coordinates ARE FreeCAD's last solution, so a correct pipeline
5
+ * re-derives (nearly) the same geometry. maxPointDistance is the V2 metric;
6
+ * its tolerance T1 is calibrated from the sample-set distribution, not
7
+ * pre-set (plan §8).
8
+ */
9
+ import type { FcstdSketchGeom } from './fcstd-types.js';
10
+ import type { FcstdSolveOutcome } from './solver.js';
11
+ /**
12
+ * P4: exported for testability — anchor points used by maxPointDistance.
13
+ *
14
+ * @param g - the sketch geometry element (point/line/circle/arc/ellipse/bspline).
15
+ * @returns the element's comparison anchor points (center/endpoints as applicable).
16
+ */
17
+ export declare function anchorPoints(g: FcstdSketchGeom): {
18
+ x: number;
19
+ y: number;
20
+ }[];
21
+ /**
22
+ * Maximum anchor-point distance between two geometry lists (same indexing).
23
+ *
24
+ * @param a - first geometry list (e.g. the solver result).
25
+ * @param b - second geometry list (e.g. the stored geometry).
26
+ * @returns the maximum Euclidean distance between corresponding anchor points
27
+ * (0 when the lists have no comparable points).
28
+ */
29
+ export declare function maxPointDistance(a: FcstdSketchGeom[], b: FcstdSketchGeom[]): number;
30
+ /**
31
+ * Three-level downgrade verdict (D3) for one sketch.
32
+ */
33
+ export interface SketchVerdict {
34
+ /** solved quality level: L0 = solved & matches, L1 = flagged, L2 = baked */
35
+ level: 'L0' | 'L1' | 'L2';
36
+ /** human-readable reason for a non-L0 verdict */
37
+ reason?: string;
38
+ /** max anchor distance between re-solved and stored geometry */
39
+ maxDelta?: number;
40
+ }
41
+ /**
42
+ * Three-level downgrade (D3). L0 = solved & matches stored (delta <= T1).
43
+ * L1 = solver result kept but flagged, stored coords used instead.
44
+ * L2 = baked (unsupported geometry/constraints, external geometry).
45
+ *
46
+ * @param outcome - the solver result, or undefined when none was produced.
47
+ * @param stored - the on-disk (stored) geometry to compare against.
48
+ * @param t1 - the calibrated distance tolerance for the L0/L1 split.
49
+ * @param preBlocked - pre-solve downgrade reason; when set the sketch is L2.
50
+ * @returns the classification verdict for the sketch.
51
+ */
52
+ export declare function classifySketch(outcome: FcstdSolveOutcome | undefined, stored: FcstdSketchGeom[], t1: number, preBlocked?: string): SketchVerdict;
53
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,eAAe,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAgB3E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,eAAe,EAAE,EAAE,CAAC,EAAE,eAAe,EAAE,GAAG,MAAM,CAanF;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,MAAM,EAAE,eAAe,EAAE,EACzB,EAAE,EAAE,MAAM,EACV,UAAU,CAAC,EAAE,MAAM,GAClB,aAAa,CASf"}
package/dist/verify.js ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * P4: exported for testability — anchor points used by maxPointDistance.
3
+ *
4
+ * @param g - the sketch geometry element (point/line/circle/arc/ellipse/bspline).
5
+ * @returns the element's comparison anchor points (center/endpoints as applicable).
6
+ */
7
+ export function anchorPoints(g) {
8
+ switch (g.kind) {
9
+ case 'point':
10
+ return [{ x: g.x, y: g.y }];
11
+ case 'line':
12
+ return [{ x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];
13
+ case 'circle':
14
+ return [{ x: g.cx, y: g.cy }];
15
+ case 'arc':
16
+ return [{ x: g.cx, y: g.cy }, { x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];
17
+ case 'ellipse':
18
+ return [{ x: g.cx, y: g.cy }];
19
+ case 'bspline':
20
+ // P4: spline anchors are its exact endpoints (poles move with them)
21
+ return [{ x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];
22
+ }
23
+ }
24
+ /**
25
+ * Maximum anchor-point distance between two geometry lists (same indexing).
26
+ *
27
+ * @param a - first geometry list (e.g. the solver result).
28
+ * @param b - second geometry list (e.g. the stored geometry).
29
+ * @returns the maximum Euclidean distance between corresponding anchor points
30
+ * (0 when the lists have no comparable points).
31
+ */
32
+ export function maxPointDistance(a, b) {
33
+ let max = 0;
34
+ const n = Math.min(a.length, b.length);
35
+ for (let i = 0; i < n; i++) {
36
+ const pa = anchorPoints(a[i]);
37
+ const pb = anchorPoints(b[i]);
38
+ const m = Math.min(pa.length, pb.length);
39
+ for (let k = 0; k < m; k++) {
40
+ const d = Math.hypot(pa[k].x - pb[k].x, pa[k].y - pb[k].y);
41
+ if (Number.isFinite(d) && d > max)
42
+ max = d;
43
+ }
44
+ }
45
+ return max;
46
+ }
47
+ /**
48
+ * Three-level downgrade (D3). L0 = solved & matches stored (delta <= T1).
49
+ * L1 = solver result kept but flagged, stored coords used instead.
50
+ * L2 = baked (unsupported geometry/constraints, external geometry).
51
+ *
52
+ * @param outcome - the solver result, or undefined when none was produced.
53
+ * @param stored - the on-disk (stored) geometry to compare against.
54
+ * @param t1 - the calibrated distance tolerance for the L0/L1 split.
55
+ * @param preBlocked - pre-solve downgrade reason; when set the sketch is L2.
56
+ * @returns the classification verdict for the sketch.
57
+ */
58
+ export function classifySketch(outcome, stored, t1, preBlocked) {
59
+ if (preBlocked)
60
+ return { level: 'L2', reason: preBlocked };
61
+ if (!outcome)
62
+ return { level: 'L2', reason: 'no-solver-result' };
63
+ if (!outcome.converged) {
64
+ return { level: 'L1', reason: outcome.reason ?? 'solve-failed' };
65
+ }
66
+ const maxDelta = maxPointDistance(outcome.geoms, stored);
67
+ if (maxDelta <= t1)
68
+ return { level: 'L0', maxDelta };
69
+ return { level: 'L1', reason: 'delta-exceeds-t1', maxDelta };
70
+ }
71
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M3.5 — solved-vs-stored comparison (D2/V2).\n *\n * The on-disk coordinates ARE FreeCAD's last solution, so a correct pipeline\n * re-derives (nearly) the same geometry. maxPointDistance is the V2 metric;\n * its tolerance T1 is calibrated from the sample-set distribution, not\n * pre-set (plan §8).\n */\nimport type { FcstdSketchGeom } from './fcstd-types.js';\nimport type { FcstdSolveOutcome } from './solver.js';\n\n/**\n * P4: exported for testability — anchor points used by maxPointDistance.\n *\n * @param g - the sketch geometry element (point/line/circle/arc/ellipse/bspline).\n * @returns the element's comparison anchor points (center/endpoints as applicable).\n */\nexport function anchorPoints(g: FcstdSketchGeom): { x: number; y: number }[] {\n switch (g.kind) {\n case 'point':\n return [{ x: g.x, y: g.y }];\n case 'line':\n return [{ x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];\n case 'circle':\n return [{ x: g.cx, y: g.cy }];\n case 'arc':\n return [{ x: g.cx, y: g.cy }, { x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];\n case 'ellipse':\n return [{ x: g.cx, y: g.cy }];\n case 'bspline':\n // P4: spline anchors are its exact endpoints (poles move with them)\n return [{ x: g.x1, y: g.y1 }, { x: g.x2, y: g.y2 }];\n }\n}\n\n/**\n * Maximum anchor-point distance between two geometry lists (same indexing).\n *\n * @param a - first geometry list (e.g. the solver result).\n * @param b - second geometry list (e.g. the stored geometry).\n * @returns the maximum Euclidean distance between corresponding anchor points\n * (0 when the lists have no comparable points).\n */\nexport function maxPointDistance(a: FcstdSketchGeom[], b: FcstdSketchGeom[]): number {\n let max = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n const pa = anchorPoints(a[i]!);\n const pb = anchorPoints(b[i]!);\n const m = Math.min(pa.length, pb.length);\n for (let k = 0; k < m; k++) {\n const d = Math.hypot(pa[k]!.x - pb[k]!.x, pa[k]!.y - pb[k]!.y);\n if (Number.isFinite(d) && d > max) max = d;\n }\n }\n return max;\n}\n\n/**\n * Three-level downgrade verdict (D3) for one sketch.\n */\nexport interface SketchVerdict {\n /** solved quality level: L0 = solved & matches, L1 = flagged, L2 = baked */\n level: 'L0' | 'L1' | 'L2';\n /** human-readable reason for a non-L0 verdict */\n reason?: string;\n /** max anchor distance between re-solved and stored geometry */\n maxDelta?: number;\n}\n\n/**\n * Three-level downgrade (D3). L0 = solved & matches stored (delta <= T1).\n * L1 = solver result kept but flagged, stored coords used instead.\n * L2 = baked (unsupported geometry/constraints, external geometry).\n *\n * @param outcome - the solver result, or undefined when none was produced.\n * @param stored - the on-disk (stored) geometry to compare against.\n * @param t1 - the calibrated distance tolerance for the L0/L1 split.\n * @param preBlocked - pre-solve downgrade reason; when set the sketch is L2.\n * @returns the classification verdict for the sketch.\n */\nexport function classifySketch(\n outcome: FcstdSolveOutcome | undefined,\n stored: FcstdSketchGeom[],\n t1: number,\n preBlocked?: string,\n): SketchVerdict {\n if (preBlocked) return { level: 'L2', reason: preBlocked };\n if (!outcome) return { level: 'L2', reason: 'no-solver-result' };\n if (!outcome.converged) {\n return { level: 'L1', reason: outcome.reason ?? 'solve-failed' };\n }\n const maxDelta = maxPointDistance(outcome.geoms, stored);\n if (maxDelta <= t1) return { level: 'L0', maxDelta };\n return { level: 'L1', reason: 'delta-exceeds-t1', maxDelta };\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@faicad/faijs-sketch",
3
+ "version": "0.18.0",
4
+ "description": "faijs sketch & constraint capability library — canonical model, planegcs solving, contour extraction and face construction",
5
+ "keywords": [
6
+ "faijs",
7
+ "cad",
8
+ "sketch",
9
+ "constraint",
10
+ "solver",
11
+ "planegcs"
12
+ ],
13
+ "license": "MIT",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://gitcode.com/Faicad/faijs.git"
17
+ },
18
+ "type": "module",
19
+ "sideEffects": false,
20
+ "main": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "./node": {
28
+ "types": "./dist/node.d.ts",
29
+ "default": "./dist/node.js"
30
+ },
31
+ "./canonical": {
32
+ "types": "./dist/canonical.d.ts",
33
+ "default": "./dist/canonical.js"
34
+ },
35
+ "./*": {
36
+ "types": "./dist/*.d.ts",
37
+ "default": "./dist/*.js"
38
+ }
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "NOTICE",
43
+ "LICENSE"
44
+ ],
45
+ "dependencies": {
46
+ "@salusoft89/planegcs": "1.2.0"
47
+ },
48
+ "peerDependencies": {
49
+ "@faicad/faijs": "^0.18.0"
50
+ },
51
+ "devDependencies": {
52
+ "occt-wasm": "^3.8.4",
53
+ "three": "^0.184.0",
54
+ "@types/three": "^0.184.1",
55
+ "typescript": "*",
56
+ "vitest": "*"
57
+ },
58
+ "scripts": {
59
+ "build": "tsc -p tsconfig.build.json && node ../../scripts/fix-import-extensions.mjs dist",
60
+ "typecheck": "tsc --noEmit",
61
+ "test": "vitest run",
62
+ "test:install": "vitest run -c vitest.install.config.ts",
63
+ "lint": "eslint src"
64
+ }
65
+ }