@hatiolab/figure-model 0.1.36 → 0.1.38

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 (61) hide show
  1. package/dist/index.d.ts +6 -3
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +6 -3
  4. package/dist/index.js.map +1 -1
  5. package/dist/v3-asset-types.d.ts +89 -16
  6. package/dist/v3-asset-types.d.ts.map +1 -1
  7. package/dist/v3-asset.d.ts.map +1 -1
  8. package/dist/v3-asset.js +34 -25
  9. package/dist/v3-asset.js.map +1 -1
  10. package/dist/v3-authoring-actions.d.ts +226 -0
  11. package/dist/v3-authoring-actions.d.ts.map +1 -0
  12. package/dist/v3-authoring-actions.js +812 -0
  13. package/dist/v3-authoring-actions.js.map +1 -0
  14. package/dist/v3-capabilities.d.ts.map +1 -1
  15. package/dist/v3-capabilities.js +4 -77
  16. package/dist/v3-capabilities.js.map +1 -1
  17. package/dist/v3-cost.d.ts +14 -0
  18. package/dist/v3-cost.d.ts.map +1 -0
  19. package/dist/v3-cost.js +69 -0
  20. package/dist/v3-cost.js.map +1 -0
  21. package/dist/v3-driver.d.ts +24 -1
  22. package/dist/v3-driver.d.ts.map +1 -1
  23. package/dist/v3-driver.js +68 -2
  24. package/dist/v3-driver.js.map +1 -1
  25. package/dist/v3-from-v2.d.ts +25 -1
  26. package/dist/v3-from-v2.d.ts.map +1 -1
  27. package/dist/v3-from-v2.js +598 -21
  28. package/dist/v3-from-v2.js.map +1 -1
  29. package/dist/v3-gate.d.ts +59 -6
  30. package/dist/v3-gate.d.ts.map +1 -1
  31. package/dist/v3-gate.js +291 -45
  32. package/dist/v3-gate.js.map +1 -1
  33. package/dist/v3-graph-types.d.ts +9 -1
  34. package/dist/v3-graph-types.d.ts.map +1 -1
  35. package/dist/v3-graph.d.ts.map +1 -1
  36. package/dist/v3-graph.js +53 -1
  37. package/dist/v3-graph.js.map +1 -1
  38. package/dist/v3-json.d.ts +0 -1
  39. package/dist/v3-json.d.ts.map +1 -1
  40. package/dist/v3-json.js +16 -1
  41. package/dist/v3-json.js.map +1 -1
  42. package/dist/v3-kernel-version.d.ts +1 -1
  43. package/dist/v3-kernel-version.js +1 -1
  44. package/dist/v3-mesh-compare.d.ts +2 -5
  45. package/dist/v3-mesh-compare.d.ts.map +1 -1
  46. package/dist/v3-mesh-compare.js +2 -145
  47. package/dist/v3-mesh-compare.js.map +1 -1
  48. package/dist/v3-shape-sampling.d.ts +14 -0
  49. package/dist/v3-shape-sampling.d.ts.map +1 -0
  50. package/dist/v3-shape-sampling.js +120 -0
  51. package/dist/v3-shape-sampling.js.map +1 -0
  52. package/dist/v3-surface.d.ts +15 -0
  53. package/dist/v3-surface.d.ts.map +1 -0
  54. package/dist/v3-surface.js +104 -0
  55. package/dist/v3-surface.js.map +1 -0
  56. package/docs/prototypes/v3-asset.schema.json +0 -8
  57. package/docs/v3-asset-persistence.md +1 -1
  58. package/docs/v3-legacy-risk-audit-2026-09-23.md +39 -0
  59. package/docs/v3-operator-contracts.md +1 -0
  60. package/docs/v3-shape-dimension-contract.md +111 -0
  61. package/package.json +1 -1
@@ -1,84 +1,5 @@
1
- /*
2
- * Copyright © HatioLab Inc. All rights reserved.
3
- */
4
- /*
5
- * Surface points for the mesh-level comparison (ADR-0087 stage review, designer's ruling 1).
6
- *
7
- * An oriented box cannot see a section, a hollow or a corner: a cylinder that is not round, a hollow box that is
8
- * not hollow and a corner that stopped scaling all pass a box check. This module samples the surface of a body
9
- * from its definition, so V2 and V3 can be compared as shapes. It needs no three.js: both sides are sampled from
10
- * their parameters with the same sampler, so the comparison asks whether the two definitions describe the same
11
- * body, at the same place, to within `SAME_TOLERANCE_MM`.
12
- *
13
- * What the sampler follows is what things-scene draws (2026-09-22, `threed/geometry-bank.ts`, `figure/figure-shape.ts`):
14
- * cube · wall a box
15
- * cylinder a unit cylinder with equal end radii, scaled by size: x ≠ z is an elliptic cylinder, not a frustum
16
- * sphere a unit sphere scaled by size: an ellipsoid when the sizes differ
17
- * rect a section outlined by `roundedRect`: straight edges and quadratic Bézier corners whose control
18
- * point is the corner itself, sampled with SEGMENT_PRESETS[0] divisions; pushed along Y
19
- * rect + hollow outer outline for the walls, inner outline inset by `wall` with round − wall, floor slab below
20
- * polygon the path as written, pushed along Y
21
- *
22
- * The rounded corner is a Bézier, not a circular arc. A renderer that draws V3's `rounded-box` with a circular arc
23
- * differs from V2 by up to 0.06 × round at the corner's middle; the shape contract names the Bézier as the curve.
24
- */
25
- import { SEGMENT_PRESETS } from "./types.js";
26
- /** Divisions per Bézier corner, the number things-scene's `roundedRect` asks `getPoints` for. */
27
- const CORNER_DIVISIONS = SEGMENT_PRESETS[0];
28
- /** Points on the outline of a rounded rectangle in the X–Z plane, centred, y = 0. */
29
- function roundedOutline(width, depth, roundX, roundZ) {
30
- // Each semi-axis is bounded by its own half-section (shape-dimension contract §1). V2's single-radius clamp
31
- // min(r, w/2, d/2) happens before scaling and is applied by the converter, not here.
32
- const rx = Math.min(roundX, width / 2);
33
- const rz = Math.min(roundZ, depth / 2);
34
- const hw = width / 2, hd = depth / 2;
35
- if (rx <= 0 && rz <= 0)
36
- return [[-hw, 0, -hd], [hw, 0, -hd], [hw, 0, hd], [-hw, 0, hd]];
37
- const pts = [];
38
- // Corner k: quadratic Bézier from the end of one straight edge to the start of the next, control at the corner.
39
- const corners = [
40
- [[hw - rx, 0, -hd], [hw, 0, -hd], [hw, 0, -hd + rz]],
41
- [[hw, 0, hd - rz], [hw, 0, hd], [hw - rx, 0, hd]],
42
- [[-hw + rx, 0, hd], [-hw, 0, hd], [-hw, 0, hd - rz]],
43
- [[-hw, 0, -hd + rz], [-hw, 0, -hd], [-hw + rx, 0, -hd]]
44
- ];
45
- for (const [p0, c, p2] of corners) {
46
- pts.push(p0);
47
- for (let i = 1; i < CORNER_DIVISIONS; i++) {
48
- const t = i / CORNER_DIVISIONS, a = (1 - t) * (1 - t), b = 2 * (1 - t) * t, d = t * t;
49
- pts.push([a * p0[0] + b * c[0] + d * p2[0], 0, a * p0[2] + b * c[2] + d * p2[2]]);
50
- }
51
- pts.push(p2);
52
- }
53
- return pts;
54
- }
55
- function lift(outline, y) {
56
- return outline.map(([x, , z]) => [x, y, z]);
57
- }
58
- /** Points on an elliptic cylinder about local Y: both end rims. */
59
- function cylinderPoints(rx, rz, length, segments) {
60
- const pts = [];
61
- for (const y of [-length / 2, length / 2])
62
- for (let i = 0; i < segments; i++) {
63
- const a = (i / segments) * Math.PI * 2;
64
- pts.push([rx * Math.cos(a), y, rz * Math.sin(a)]);
65
- }
66
- return pts;
67
- }
68
- /** Points on an ellipsoid: a fixed latitude–longitude grid. */
69
- function spherePoints(rx, ry, rz) {
70
- const pts = [];
71
- const rings = 6, around = 12;
72
- for (let j = 1; j < rings; j++) {
73
- const phi = (j / rings) * Math.PI;
74
- for (let i = 0; i < around; i++) {
75
- const th = (i / around) * Math.PI * 2;
76
- pts.push([rx * Math.sin(phi) * Math.cos(th), ry * Math.cos(phi), rz * Math.sin(phi) * Math.sin(th)]);
77
- }
78
- }
79
- pts.push([0, ry, 0], [0, -ry, 0]);
80
- return pts;
81
- }
1
+ import { boxPoints, cylinderPoints, spherePoints, roundedOutline, lift } from "./v3-shape-sampling.js";
2
+ export { v3ShapePoints, transformPoints } from "./v3-shape-sampling.js";
82
3
  /** Surface points of a V2 part body in its own frame, as things-scene builds the geometry. */
83
4
  export function v2BodyPoints(body) {
84
5
  const { x: w, y: h, z: d } = body.size;
@@ -107,70 +28,6 @@ export function v2BodyPoints(body) {
107
28
  }
108
29
  }
109
30
  }
110
- function boxPoints(w, h, d) {
111
- const pts = [];
112
- for (const sx of [-1, 1])
113
- for (const sy of [-1, 1])
114
- for (const sz of [-1, 1])
115
- pts.push([(sx * w) / 2, (sy * h) / 2, (sz * d) / 2]);
116
- return pts;
117
- }
118
- /** Surface points of a V3 shape in its own frame. */
119
- export function v3ShapePoints(shape, segments) {
120
- const d = shape.dimensions;
121
- switch (shape.provider) {
122
- case 'box':
123
- return boxPoints(d.width, d.height, d.depth);
124
- case 'cylinder':
125
- return cylinderPoints(d.radius, d.radius, d.length, segments ?? 12);
126
- case 'ellipticCylinder':
127
- return cylinderPoints(d.radiusX, d.radiusZ, d.length, segments ?? 12);
128
- case 'roundedBoxXZ': {
129
- const outer = roundedOutline(d.width, d.depth, d.roundX, d.roundZ);
130
- return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2)];
131
- }
132
- case 'hollowBoxXZ': {
133
- const outer = roundedOutline(d.width, d.depth, d.roundX, d.roundZ);
134
- const inner = roundedOutline(d.width - 2 * d.wallX, d.depth - 2 * d.wallZ, Math.max(d.roundX - d.wallX, 0), Math.max(d.roundZ - d.wallZ, 0));
135
- return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2), ...lift(inner, d.height / 2), ...lift(inner, -d.height / 2 + d.floor)];
136
- }
137
- case 'frustum': {
138
- const pts = [];
139
- const seg = segments ?? 12;
140
- for (const [y, r] of [[-d.height / 2, d.radiusBottom], [d.height / 2, d.radiusTop]])
141
- for (let i = 0; i < seg; i++) {
142
- const a = (i / seg) * Math.PI * 2;
143
- pts.push([r * Math.cos(a), y, r * Math.sin(a)]);
144
- }
145
- return pts;
146
- }
147
- case 'sphere':
148
- return spherePoints(d.radiusX, d.radiusY, d.radiusZ);
149
- case 'roundedBox': {
150
- const outer = roundedOutline(d.width, d.depth, d.round, d.round);
151
- return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2)];
152
- }
153
- case 'hollowBox': {
154
- const outer = roundedOutline(d.width, d.depth, d.round, d.round);
155
- // The inner outline: each wall inset by its own thickness, corner reduced by the thickness on each axis.
156
- const inner = roundedOutline(d.width - 2 * d.wallX, d.depth - 2 * d.wallZ, Math.max(d.round - d.wallX, 0), Math.max(d.round - d.wallZ, 0));
157
- return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2), ...lift(inner, d.height / 2), ...lift(inner, -d.height / 2 + d.floor)];
158
- }
159
- case 'polygon': {
160
- const profile = shape.profile ?? [];
161
- return [...profile.map(q => [q.x, -d.height / 2, q.y]), ...profile.map(q => [q.x, d.height / 2, q.y])];
162
- }
163
- case 'portal':
164
- return (shape.profile ?? []).flatMap(q => [[q.x, q.y, -d.depth / 2], [q.x, q.y, d.depth / 2]]);
165
- }
166
- }
167
- export function transformPoints(points, r, t) {
168
- return points.map(([x, y, z]) => [
169
- r[0][0] * x + r[0][1] * y + r[0][2] * z + t[0],
170
- r[1][0] * x + r[1][1] * y + r[1][2] * z + t[1],
171
- r[2][0] * x + r[2][1] * y + r[2][2] * z + t[2]
172
- ]);
173
- }
174
31
  export function scalePoints(points, f) {
175
32
  return points.map(([x, y, z]) => [x * f.x, y * f.y, z * f.z]);
176
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"v3-mesh-compare.js","sourceRoot":"","sources":["../src/v3-mesh-compare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"v3-mesh-compare.js","sourceRoot":"","sources":["../src/v3-mesh-compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { V3Shape } from './v3-graph-types.ts';
2
+ export type Point = [number, number, number];
3
+ /** Points on the outline of a rounded rectangle in the X–Z plane, centred, y = 0. */
4
+ export declare function roundedOutline(width: number, depth: number, roundX: number, roundZ: number): Point[];
5
+ export declare function lift(outline: Point[], y: number): Point[];
6
+ /** Points on an elliptic cylinder about local Y: both end rims. */
7
+ export declare function cylinderPoints(rx: number, rz: number, length: number, segments: number): Point[];
8
+ /** Points on an ellipsoid: a fixed latitude–longitude grid. */
9
+ export declare function spherePoints(rx: number, ry: number, rz: number): Point[];
10
+ export declare function boxPoints(w: number, h: number, d: number): Point[];
11
+ /** Surface points of a V3 shape in its own frame. */
12
+ export declare function v3ShapePoints(shape: V3Shape, segments?: number): Point[];
13
+ export declare function transformPoints(points: readonly Point[], r: number[][], t: readonly number[]): Point[];
14
+ //# sourceMappingURL=v3-shape-sampling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v3-shape-sampling.d.ts","sourceRoot":"","sources":["../src/v3-shape-sampling.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,MAAM,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAK5C,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,CA2BpG;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,CAEzD;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,EAAE,CAQhG;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,KAAK,EAAE,CAaxE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,CAIlE;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,CA+CxE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,EAAE,CAMtG"}
@@ -0,0 +1,120 @@
1
+ /** Divisions per Bézier corner, the number things-scene's `roundedRect` asks `getPoints` for. */
2
+ const CORNER_DIVISIONS = 8;
3
+ /** Points on the outline of a rounded rectangle in the X–Z plane, centred, y = 0. */
4
+ export function roundedOutline(width, depth, roundX, roundZ) {
5
+ // Each semi-axis is bounded by its own half-section (shape-dimension contract §1).
6
+ const rx = Math.min(roundX, width / 2);
7
+ const rz = Math.min(roundZ, depth / 2);
8
+ const hw = width / 2, hd = depth / 2;
9
+ if (rx <= 0 && rz <= 0)
10
+ return [[-hw, 0, -hd], [hw, 0, -hd], [hw, 0, hd], [-hw, 0, hd]];
11
+ const pts = [];
12
+ // Corner k: quadratic Bézier from the end of one straight edge to the start of the next, control at the corner.
13
+ const corners = [
14
+ [[hw - rx, 0, -hd], [hw, 0, -hd], [hw, 0, -hd + rz]],
15
+ [[hw, 0, hd - rz], [hw, 0, hd], [hw - rx, 0, hd]],
16
+ [[-hw + rx, 0, hd], [-hw, 0, hd], [-hw, 0, hd - rz]],
17
+ [[-hw, 0, -hd + rz], [-hw, 0, -hd], [-hw + rx, 0, -hd]]
18
+ ];
19
+ for (const [p0, c, p2] of corners) {
20
+ pts.push(p0);
21
+ for (let i = 1; i < CORNER_DIVISIONS; i++) {
22
+ const t = i / CORNER_DIVISIONS, a = (1 - t) * (1 - t), b = 2 * (1 - t) * t, d = t * t;
23
+ pts.push([a * p0[0] + b * c[0] + d * p2[0], 0, a * p0[2] + b * c[2] + d * p2[2]]);
24
+ }
25
+ pts.push(p2);
26
+ }
27
+ return pts;
28
+ }
29
+ export function lift(outline, y) {
30
+ return outline.map(([x, , z]) => [x, y, z]);
31
+ }
32
+ /** Points on an elliptic cylinder about local Y: both end rims. */
33
+ export function cylinderPoints(rx, rz, length, segments) {
34
+ const pts = [];
35
+ for (const y of [-length / 2, length / 2])
36
+ for (let i = 0; i < segments; i++) {
37
+ const a = (i / segments) * Math.PI * 2;
38
+ pts.push([rx * Math.cos(a), y, rz * Math.sin(a)]);
39
+ }
40
+ return pts;
41
+ }
42
+ /** Points on an ellipsoid: a fixed latitude–longitude grid. */
43
+ export function spherePoints(rx, ry, rz) {
44
+ const pts = [];
45
+ const rings = 6, around = 12;
46
+ for (let j = 1; j < rings; j++) {
47
+ const phi = (j / rings) * Math.PI;
48
+ for (let i = 0; i < around; i++) {
49
+ const th = (i / around) * Math.PI * 2;
50
+ pts.push([rx * Math.sin(phi) * Math.cos(th), ry * Math.cos(phi), rz * Math.sin(phi) * Math.sin(th)]);
51
+ }
52
+ }
53
+ pts.push([0, ry, 0], [0, -ry, 0]);
54
+ return pts;
55
+ }
56
+ export function boxPoints(w, h, d) {
57
+ const pts = [];
58
+ for (const sx of [-1, 1])
59
+ for (const sy of [-1, 1])
60
+ for (const sz of [-1, 1])
61
+ pts.push([(sx * w) / 2, (sy * h) / 2, (sz * d) / 2]);
62
+ return pts;
63
+ }
64
+ /** Surface points of a V3 shape in its own frame. */
65
+ export function v3ShapePoints(shape, segments) {
66
+ const d = shape.dimensions;
67
+ switch (shape.provider) {
68
+ case 'box':
69
+ return boxPoints(d.width, d.height, d.depth);
70
+ case 'cylinder':
71
+ return cylinderPoints(d.radius, d.radius, d.length, segments ?? 12);
72
+ case 'ellipticCylinder':
73
+ return cylinderPoints(d.radiusX, d.radiusZ, d.length, segments ?? 12);
74
+ case 'roundedBoxXZ': {
75
+ const outer = roundedOutline(d.width, d.depth, d.roundX, d.roundZ);
76
+ return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2)];
77
+ }
78
+ case 'hollowBoxXZ': {
79
+ const outer = roundedOutline(d.width, d.depth, d.roundX, d.roundZ);
80
+ const inner = roundedOutline(d.width - 2 * d.wallX, d.depth - 2 * d.wallZ, Math.max(d.roundX - d.wallX, 0), Math.max(d.roundZ - d.wallZ, 0));
81
+ return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2), ...lift(inner, d.height / 2), ...lift(inner, -d.height / 2 + d.floor)];
82
+ }
83
+ case 'frustum': {
84
+ const pts = [];
85
+ const seg = segments ?? 12;
86
+ for (const [y, r] of [[-d.height / 2, d.radiusBottom], [d.height / 2, d.radiusTop]])
87
+ for (let i = 0; i < seg; i++) {
88
+ const a = (i / seg) * Math.PI * 2;
89
+ pts.push([r * Math.cos(a), y, r * Math.sin(a)]);
90
+ }
91
+ return pts;
92
+ }
93
+ case 'sphere':
94
+ return spherePoints(d.radiusX, d.radiusY, d.radiusZ);
95
+ case 'roundedBox': {
96
+ const outer = roundedOutline(d.width, d.depth, d.round, d.round);
97
+ return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2)];
98
+ }
99
+ case 'hollowBox': {
100
+ const outer = roundedOutline(d.width, d.depth, d.round, d.round);
101
+ // The inner outline: each wall inset by its own thickness, corner reduced by the thickness on each axis.
102
+ const inner = roundedOutline(d.width - 2 * d.wallX, d.depth - 2 * d.wallZ, Math.max(d.round - d.wallX, 0), Math.max(d.round - d.wallZ, 0));
103
+ return [...lift(outer, -d.height / 2), ...lift(outer, d.height / 2), ...lift(inner, d.height / 2), ...lift(inner, -d.height / 2 + d.floor)];
104
+ }
105
+ case 'polygon': {
106
+ const profile = shape.profile ?? [];
107
+ return [...profile.map(q => [q.x, -d.height / 2, q.y]), ...profile.map(q => [q.x, d.height / 2, q.y])];
108
+ }
109
+ case 'portal':
110
+ return (shape.profile ?? []).flatMap(q => [[q.x, q.y, -d.depth / 2], [q.x, q.y, d.depth / 2]]);
111
+ }
112
+ }
113
+ export function transformPoints(points, r, t) {
114
+ return points.map(([x, y, z]) => [
115
+ r[0][0] * x + r[0][1] * y + r[0][2] * z + t[0],
116
+ r[1][0] * x + r[1][1] * y + r[1][2] * z + t[1],
117
+ r[2][0] * x + r[2][1] * y + r[2][2] * z + t[2]
118
+ ]);
119
+ }
120
+ //# sourceMappingURL=v3-shape-sampling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v3-shape-sampling.js","sourceRoot":"","sources":["../src/v3-shape-sampling.ts"],"names":[],"mappings":"AAQA,iGAAiG;AACjG,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAE1B,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,KAAa,EAAE,MAAc,EAAE,MAAc;IACzF,mFAAmF;IACnF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;IACtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;IACtC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,EAClB,EAAE,GAAG,KAAK,GAAG,CAAC,CAAA;IAChB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IACvF,MAAM,GAAG,GAAY,EAAE,CAAA;IACvB,gHAAgH;IAChH,MAAM,OAAO,GAAiC;QAC5C,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KACxD,CAAA;IACD,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QAClC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,gBAAgB,EAC5B,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EACrB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EACnB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACX,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACnF,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAgB,EAAE,CAAS;IAC9C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7C,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,EAAU,EAAE,EAAU,EAAE,MAAc,EAAE,QAAgB;IACrF,MAAM,GAAG,GAAY,EAAE,CAAA;IACvB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;YACtC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACnD,CAAC;IACH,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,YAAY,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU;IAC7D,MAAM,GAAG,GAAY,EAAE,CAAA;IACvB,MAAM,KAAK,GAAG,CAAC,EACb,MAAM,GAAG,EAAE,CAAA;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,CAAA;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;YACrC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACtG,CAAC;IACH,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACjC,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS;IACvD,MAAM,GAAG,GAAY,EAAE,CAAA;IACvB,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAAE,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAAE,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAClI,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,QAAiB;IAC7D,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAA;IAC1B,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC;QACvB,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,MAAO,EAAE,CAAC,CAAC,KAAM,CAAC,CAAA;QACjD,KAAK,UAAU;YACb,OAAO,cAAc,CAAC,CAAC,CAAC,MAAO,EAAE,CAAC,CAAC,MAAO,EAAE,CAAC,CAAC,MAAO,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAA;QACxE,KAAK,kBAAkB;YACrB,OAAO,cAAc,CAAC,CAAC,CAAC,OAAQ,EAAE,CAAC,CAAC,OAAQ,EAAE,CAAC,CAAC,MAAO,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAA;QAC1E,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,MAAO,EAAE,CAAC,CAAC,MAAO,CAAC,CAAA;YACtE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,CAAC,CAAA;QACxE,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,MAAO,EAAE,CAAC,CAAC,MAAO,CAAC,CAAA;YACtE,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAM,GAAG,CAAC,GAAG,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,GAAG,CAAC,GAAG,CAAC,CAAC,KAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,CAAC,CAAA;YACpJ,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,GAAG,CAAC,CAAC,KAAM,CAAC,CAAC,CAAA;QAClJ,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,GAAG,GAAY,EAAE,CAAA;YACvB,MAAM,GAAG,GAAG,QAAQ,IAAI,EAAE,CAAA;YAC1B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,EAAE,CAAC,CAAC,YAAa,CAAC,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,EAAE,CAAC,CAAC,SAAU,CAAC,CAAU;gBAC9F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;oBACjC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;gBACjD,CAAC;YACH,OAAO,GAAG,CAAA;QACZ,CAAC;QACD,KAAK,QAAQ;YACX,OAAO,YAAY,CAAC,CAAC,CAAC,OAAQ,EAAE,CAAC,CAAC,OAAQ,EAAE,CAAC,CAAC,OAAQ,CAAC,CAAA;QACzD,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,CAAC,CAAA;YACpE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,CAAC,CAAA;QACxE,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,CAAC,CAAA;YACpE,yGAAyG;YACzG,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAM,GAAG,CAAC,GAAG,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,KAAM,GAAG,CAAC,GAAG,CAAC,CAAC,KAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAM,GAAG,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAM,GAAG,CAAC,CAAC,KAAM,EAAE,CAAC,CAAC,CAAC,CAAA;YAClJ,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,MAAO,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,GAAG,CAAC,CAAC,KAAM,CAAC,CAAC,CAAA;QAClJ,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAA;YACnC,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAU,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAU,CAAC,CAAC,CAAA;QAC5H,CAAC;QACD,KAAK,QAAQ;YACX,OAAO,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAM,GAAG,CAAC,CAAC,CAAY,CAAC,CAAA;IAC/G,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAwB,EAAE,CAAa,EAAE,CAAoB;IAC3F,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE;QACrD,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE;QACrD,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE;KACtD,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ type Dynamic = any;
2
+ export interface V3SurfaceContext {
3
+ /** Every node output's type, from the compiled graph. */
4
+ types: Dynamic;
5
+ /** Which node writes each output. */
6
+ writers: Map<string, Dynamic>;
7
+ model: Dynamic;
8
+ assetFrame: string;
9
+ }
10
+ /** Check that a `{ placement, feature }` pair names a supported planar face, and say which one. */
11
+ export declare function resolveV3Surface(ctx: V3SurfaceContext, contact: Dynamic, path: string): Dynamic;
12
+ /** Where a resolved surface sits, and which way it faces, for one evaluation of the graph. */
13
+ export declare function evaluateV3Surface(values: Dynamic, s: Dynamic): Dynamic;
14
+ export {};
15
+ //# sourceMappingURL=v3-surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v3-surface.d.ts","sourceRoot":"","sources":["../src/v3-surface.ts"],"names":[],"mappings":"AASA,KAAK,OAAO,GAAG,GAAG,CAAA;AAiBlB,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAA;IACd,qCAAqC;IACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAgD/F;AAED,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAuBtE"}
@@ -0,0 +1,104 @@
1
+ /*
2
+ * One reader for "this face of this part, in the asset frame". The capability bindings named their contacts this
3
+ * way first; the declared occupancy names the face it is mounted on the same way (V3 designer's ruling
4
+ * 2026-09-23), and neither writes the rule twice.
5
+ *
6
+ * A surface is a pair of graph outputs: an actual placement and a `feature@1` on the same shape. That pairing is
7
+ * what makes it a real face of a real drawn body, rather than any transform an author points at.
8
+ */
9
+ import { V3ContractError as ContractError } from "./v3-contract.js";
10
+ const fail = (code, path, message) => {
11
+ throw new ContractError(code, path, message);
12
+ };
13
+ /** Outward normals in the shape's own frame, by feature name. */
14
+ const NORMALS = {
15
+ left: [-1, 0, 0],
16
+ right: [1, 0, 0],
17
+ bottom: [0, -1, 0],
18
+ top: [0, 1, 0],
19
+ back: [0, 0, -1],
20
+ front: [0, 0, 1],
21
+ start: [0, -1, 0],
22
+ end: [0, 1, 0]
23
+ };
24
+ /** Check that a `{ placement, feature }` pair names a supported planar face, and say which one. */
25
+ export function resolveV3Surface(ctx, contact, path) {
26
+ const { types, writers, model, assetFrame } = ctx;
27
+ if (!contact || typeof contact !== 'object' || Array.isArray(contact))
28
+ fail('SCHEMA', path, 'object required');
29
+ for (const k of ['placement', 'feature'])
30
+ if (!Object.hasOwn(contact, k))
31
+ fail('SCHEMA', path, `missing ${k}`);
32
+ for (const k of Object.keys(contact))
33
+ if (!['placement', 'feature'].includes(k))
34
+ fail('SCHEMA', path, `unknown ${k}`);
35
+ const typeOf = (ref) => {
36
+ if (typeof ref !== 'string' || !ref.trim())
37
+ fail('SCHEMA', path, 'nonempty string required');
38
+ if (!Object.hasOwn(types, ref))
39
+ fail('TARGET_ABSENT', path, ref);
40
+ return types[ref];
41
+ };
42
+ const placedType = typeOf(contact.placement), featureType = typeOf(contact.feature);
43
+ const place = writers.get(contact.placement), feature = writers.get(contact.feature);
44
+ let source = place, selection;
45
+ if (place?.op === 'select-item@1') {
46
+ const repeat = writers.get(place.args[0]), assembly = repeat?.op === 'repeat@1' ? writers.get(repeat.args[1]) : null;
47
+ if (assembly?.op !== 'assembly@1' || !assembly.args.includes(place.params.member))
48
+ fail('SURFACE_PROVENANCE', path, 'selected member must belong to the referenced repeat assembly');
49
+ source = writers.get(place.params.member);
50
+ if (source?.op !== 'member@1')
51
+ fail('SURFACE_PROVENANCE', path, 'selected source must be a declared template member');
52
+ if (model.inputs.some((i) => i.id === place.args[1] && i.role === 'state'))
53
+ fail('TARGET_STATE', path, 'binding target index must not change as animation state');
54
+ selection = { collection: place.args[0], index: place.args[1], member: place.params.member };
55
+ }
56
+ else if (place?.op !== 'place@1')
57
+ fail('SURFACE_PROVENANCE', path, 'actual placement or selected repeated member required');
58
+ if (feature?.op !== 'feature@1')
59
+ fail('SURFACE_PROVENANCE', path, 'provider feature required');
60
+ if (placedType.kind !== 'placed' || placedType.frame !== assetFrame || featureType.kind !== 'transform')
61
+ fail('FRAME_TYPE', path, 'contact must be in asset frame');
62
+ if (source.args[0] !== feature.args[0])
63
+ fail('SURFACE_OWNER', path, 'feature belongs to a different shape declaration');
64
+ const provider = types[feature.args[0]].provider, face = feature.params.name;
65
+ /*
66
+ Flat faces only. A rounded box is flat top and bottom whichever way its corners are rounded, so the per-axis
67
+ form (`rounded-box@2`, provider `roundedBoxXZ`) offers the same two faces as `rounded-box@1`; a hollow box
68
+ likewise. Everything else — a sphere, a frustum's slant, a cylinder's barrel — is not a plane to rest on.
69
+ */
70
+ const allowed = provider === 'box'
71
+ ? ['left', 'right', 'bottom', 'top', 'back', 'front']
72
+ : provider === 'roundedBox' || provider === 'roundedBoxXZ' || provider === 'hollowBox' || provider === 'hollowBoxXZ'
73
+ ? ['bottom', 'top']
74
+ : provider === 'cylinder'
75
+ ? ['start', 'end']
76
+ : [];
77
+ if (!allowed.includes(face))
78
+ fail('SURFACE_UNSUPPORTED', path, 'feature is not a supported planar surface');
79
+ return { ...contact, geometryId: selection ? null : place.id, selection, provider, face, frame: featureType.from, normal: NORMALS[face] };
80
+ }
81
+ /** Where a resolved surface sits, and which way it faces, for one evaluation of the graph. */
82
+ export function evaluateV3Surface(values, s) {
83
+ const placed = values[s.placement], local = values[s.feature], r = placed.pose.r;
84
+ const normal = r.map((row) => row.reduce((v, x, i) => v + x * s.normal[i], 0));
85
+ const t = r.map((row, j) => placed.pose.t[j] + row.reduce((v, x, i) => v + x * local.t[i], 0));
86
+ let geometryId = s.geometryId;
87
+ if (s.selection) {
88
+ const q = s.selection, item = values[q.collection].items.find((g) => g.index === values[q.index] && g.key === q.member);
89
+ if (!item)
90
+ fail('TARGET_ABSENT', s.placement, 'selected repeated item is absent');
91
+ geometryId = item.id;
92
+ }
93
+ return {
94
+ placement: s.placement,
95
+ feature: s.feature,
96
+ geometryId,
97
+ provider: s.provider,
98
+ face: s.face,
99
+ pose: { r: r.map((row) => [...row]), t },
100
+ normal,
101
+ provenance: 'verified-planar-surface'
102
+ };
103
+ }
104
+ //# sourceMappingURL=v3-surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v3-surface.js","sourceRoot":"","sources":["../src/v3-surface.ts"],"names":[],"mappings":"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"}
@@ -18,14 +18,6 @@
18
18
  "properties": {
19
19
  "target": {"type": "string", "minLength": 1},
20
20
  "segments": {"enum": [8,12,16,24,32,48]},
21
- "legacyCapability": {
22
- "type": "object", "additionalProperties": false, "required": ["roles", "accepts", "capacity"],
23
- "properties": {
24
- "roles": {"type": "array", "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
25
- "accepts": {"type": "array", "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
26
- "capacity": {"type": "integer", "minimum": 1, "maximum": 9007199254740991}
27
- }
28
- },
29
21
  "material": {
30
22
  "type": "object", "additionalProperties": false, "required": ["token"],
31
23
  "properties": {
@@ -42,7 +42,7 @@ appearance는 모든 `place@1`/`member@1`에 정확히 하나씩 필요하다.
42
42
 
43
43
  원기둥 분할 수는 현재 지원 preset으로 명시 저장한다. 사용자에게 분할 수 직접 입력 UI를 추가하지 않았다. 다른 provider에 임의의 segments를 붙이는 것은 거부한다. 재질은 token/preset/transparent/emissive 범위를 지원하며 미지원 필드를 조용히 버리지 않고 거부한다.
44
44
 
45
- 로봇 tool-seat의 기존 capability는 `legacyCapability`라는 비실행 메타데이터로 보존한다. `slot`을 `seat`/`grip`으로 자동 해석하거나 tool-seat solid를 숨기지 않는다. 이 필드는 형식 검사를 거치지만 V3 기능의 검증 완료를 의미하지 않는다.
45
+ 부품에 붙어 있던 구버전 capability 메타데이터는 정본에 자리를 두지 않는다(2026-09-23). 변환기는 그것을 `PART_CAPABILITY` 손실로 보고하고, 어느 자산도 그 값을 담지 않았다. 자리만 남겨 두면 검증된 binding과 구별되지 않으므로 없앴다. `slot`을 `seat`/`grip`으로 자동 해석하지도 않는다. 이 의미를 V3로 가져오려면 검증되는 binding으로 다시 저작한다.
46
46
 
47
47
  ## 검증 결과
48
48
 
@@ -0,0 +1,39 @@
1
+ # V3의 V2 잔재 위험 점검
2
+
3
+ 2026-09-23. figure-model, things-scene, things-factory 소스 정적 점검.
4
+ 목표는 V2 재현이 아니라 V3의 독립적 저작·평가 계약이다. 표본 통과는 전체 범위 증명이 아니다.
5
+ 이 문서는 전체 제품 전환 완료 선언이 아니다. 운영 DB, 배포, 설치 버전은 변경하지 않았다.
6
+
7
+ ## 우선순위와 조치
8
+
9
+ | 우선순위 | 근거 | 위험 | 조치/완료 기준 |
10
+ | --- | --- | --- | --- |
11
+ | P1 | things-factory `figure-service/server/service/figure/figure-source.ts`, `figure-mutation.ts` | V3 저장은 별도 경로지만 기존 생성·수정·복원은 V2 parseSource를 사용한다. V3 데이터 전환 뒤 제품 경로가 깨질 수 있다. | 전환 전 저장·발행·복원·AI·썸네일 전체 V3 경로 시험. 이번 점검에서 운영 경로 전환하지 않음. |
12
+ | P1 | things-scene `src/figure/v3/figure-v3-rig.ts`의 clipOf | driver ID의 `/` 앞부분을 재생 그룹으로 해석한다. V3 타입은 ID 문자열 형식을 요구하지 않는다. 이름 변경이 동작을 바꿀 수 있다. | 명시적 재생 그룹 계약을 설계하고 소비처와 변환기를 함께 수정. ID는 불투명 식별자. 런타임에서 V2 이름을 추측하는 fallback은 최종 제거. |
13
+ | P2 | `src/v3-asset-types.ts`, `v3-asset.ts`, scene rig | legacyCapability가 V3 정본·평가·렌더러에 남아 있다. 검증된 binding과 혼동되고 유지 비용이 생긴다. | V3 binding으로 재저작하거나 변환 보고서에 보존. 정본에서 제거할 때 fixture·소비처 동시 수정. 단순 삭제로 의미 손실을 숨기지 않음. |
14
+ | P2 | `src/v3-gate.ts` → `v3-mesh-compare.ts` | 제품 검사기가 V2 비교용 코드를 의존한다. 비교용 변경이 제품 판정에 전파된다. | 이번 변경에서 V3 형상 유틸리티를 `v3-shape-sampling.ts`로 분리. migration이 유틸리티를 사용하고 역방향 의존을 금지하는 테스트 추가. |
15
+ | P2 | things-scene `src/figure/v3/figure-v3-real-object.ts` effectiveDepth | depth 생략 시 평면 크기 배율의 기하평균으로 높이를 결정하는 V2 정책이 V3 소비처에 남아 있다. | V3 설계 입력과 씬 크기 매핑 정책을 명시. 자동 기하평균은 V3 보편 규칙으로 취급하지 말 것. 정책 변경 시 기존 배치의 변화 검증. |
16
+ | P2 | `src/index.ts`, `v3-capabilities.ts`, `v3-asset.ts` | 공개 진입점에 V2 변환·비교 API가 섞이고 capability/placement 목록을 V2 types에서 가져온다. | 제품 공통 어휘와 구버전 전용 계약을 분리하고 V3 전용 진입점과 migration 진입점을 설계. 이번 점검에서는 package.json/exports를 변경하지 않음. |
17
+
18
+ ## 유지할 것과 격리할 것
19
+
20
+ - min/max, 상태 의존 치수, 표시 여부, 구간별 매핑은 V3 자체 용도로 평가한다. V2가 도입 계기였다는 이유로 삭제하지 않는다.
21
+ - 변환기, V2 기준 구현, 비교 시험은 이행 도구다. 존재 자체가 문제가 아니라 제품 런타임의 역방향 의존이 문제다.
22
+ - 공유된 축/벡터 타입 자체는 호환성 실행 코드가 아니다. 다만 V3 정책을 V2 목록과 묶어서는 안 된다.
23
+ - 구면·타원·둥근 모서리의 정의는 독립적인 V3 형상 계약으로 설명한다. V2 화면 일치는 계약의 근거가 아니다.
24
+ - 실제 binding 의미를 검증하지 못한 legacy 메타데이터는 기능 구현으로 집계하지 않는다.
25
+
26
+ ## 이번 변경의 한계
27
+
28
+ 형상 샘플링의 파일 경계를 분리했을 뿐 연속 표면의 보수적 경계를 새로 증명하지 않았다.
29
+ 유한 샘플의 min/max 또는 Hausdorff 결과를 연속 형상 전체의 보장으로 해석해서는 안 된다.
30
+ 기존 API 재수출은 이행 도구를 깨뜨리지 않기 위해 유지했지만, V3 검사기의 내부 의존은 제거했다.
31
+ 이 테스트는 알려진 migration/V2 실행 파일로의 정적 의존을 차단하며 모든 의미적 호환 잔재를 검출하지는 않는다.
32
+
33
+ ## 후속 검증 기준
34
+
35
+ 1. V2 fixture 없이 작성한 V3 자산으로 생성·편집·리사이즈·동작·저장·재열기 검증.
36
+ 2. driver ID를 바꿔도 재생 그룹과 동작이 유지되는 테스트.
37
+ 3. V3 정본/평가 결과에 legacyCapability가 없고 binding 의미가 명시되는 테스트.
38
+ 4. 씬 크기 입력이 occupancy 수정과 독립적이며 높이 정책이 명시되는 테스트.
39
+ 5. migration 도구를 제품 런타임 의존 그래프에서 제외한 빌드·실행 검증.
@@ -76,6 +76,7 @@ args 순서와 output 이름은 버전별 연산 계약이다. 전체 연산 cat
76
76
  | mul@1 | a,b | value=a*b | overflow/nonfinite |
77
77
  | div@1 | a,b | value=a/b | b=0, overflow/nonfinite |
78
78
  | geomean@1 | a,b[,c] (동일 차원) | value=(a·b[·c])^(1/n) | 음수 입력 |
79
+ | at-least@1 | a,b (동일 차원) | value=flag(a≥b). **flag 는 치수·pose·occupancy 로 못 간다** — appearance.visibility 만 받는다 (V3 설계자 결정 2026-09-22) | 없음 |
79
80
  | curve@1 | x, at₀,v₀, at₁,v₁, … (at 는 x 와 같은 차원, v 는 한 차원; 키 2개 이상) | value=키 사이는 직선, 키 밖은 끝 값 유지 (piecewise-linear; V3 설계자 승인 2026-09-22) | at 가 strictly increasing 이 아님 (index 로 보고) |
80
81
  | sphere-shape@1 | radiusX,radiusY,radiusZ (길이) | shape(sphere) | 반지름≤0 |
81
82
  | polygon-shape@1 | height, x0,z0, x1,z1, … (길이, 점 3개 이상) | shape(polygon; 단면은 X–Z, Y 로 민다) | height≤0, 단면이 한 축으로 퍼지지 않음 |