@things-factory/figure-ui 10.1.200 → 10.1.201
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/client/modeller/editor.ts +7 -3
- package/client/modeller/fasten-form.ts +18 -35
- package/client/modeller/fasten-geometry.ts +67 -115
- package/client/modeller/figure-fasten-dialog.ts +4 -12
- package/client/modeller/figure-links.ts +6 -7
- package/client/modeller/joint-drag.ts +5 -5
- package/client/modeller/links.ts +35 -99
- package/client/modeller/refusals.ts +2 -6
- package/dist-client/modeller/editor.js +7 -2
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/fasten-form.d.ts +5 -8
- package/dist-client/modeller/fasten-form.js +16 -28
- package/dist-client/modeller/fasten-form.js.map +1 -1
- package/dist-client/modeller/fasten-geometry.d.ts +20 -19
- package/dist-client/modeller/fasten-geometry.js +54 -113
- package/dist-client/modeller/fasten-geometry.js.map +1 -1
- package/dist-client/modeller/figure-fasten-dialog.js +4 -12
- package/dist-client/modeller/figure-fasten-dialog.js.map +1 -1
- package/dist-client/modeller/figure-links.d.ts +1 -1
- package/dist-client/modeller/figure-links.js +6 -7
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/joint-drag.js +5 -5
- package/dist-client/modeller/joint-drag.js.map +1 -1
- package/dist-client/modeller/links.d.ts +19 -26
- package/dist-client/modeller/links.js +36 -94
- package/dist-client/modeller/links.js.map +1 -1
- package/dist-client/modeller/refusals.d.ts +1 -1
- package/dist-client/modeller/refusals.js +2 -6
- package/dist-client/modeller/refusals.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/test/ai-proposal.test.ts +1 -1
- package/test/browser/acceptance-page.js +11 -11
- package/test/browser/detail-page.js +1 -1
- package/test/browser/detail-tabs-page.js +1 -1
- package/test/browser/editing-page.js +1 -1
- package/test/browser/fix-alignment.check.mjs +3 -3
- package/test/browser/links.check.mjs +20 -8
- package/test/browser/modeller-page.js +3 -3
- package/test/browser/part-ids.check.mjs +2 -2
- package/test/browser/parts-page.js +2 -2
- package/test/browser/product-page.check.mjs +3 -3
- package/test/browser/product-page.js +1 -1
- package/test/browser/row-preview.check.mjs +2 -2
- package/test/browser/screen-page.js +3 -3
- package/test/browser/section-page.js +3 -3
- package/test/browser/section.check.mjs +4 -4
- package/test/clip-ai-proposal.test.ts +1 -1
- package/test/clip-consent.test.ts +1 -1
- package/test/command-preview.test.ts +8 -8
- package/test/face-mapping.test.ts +2 -2
- package/test/fasten-drawing.test.ts +14 -2
- package/test/fasten-form.test.ts +11 -3
- package/test/fasten-geometry.test.ts +22 -31
- package/test/fix-alignment.test.ts +16 -4
- package/test/gizmo.test.ts +2 -2
- package/test/joint-drag.test.ts +13 -2
- package/test/joint-fan.test.ts +1 -1
- package/test/joint-frames.test.ts +45 -23
- package/test/joints.ts +1 -1
- package/test/links.test.ts +68 -68
- package/test/live.test.ts +2 -2
- package/test/preview-size.test.ts +1 -1
- package/test/refusals.test.ts +18 -20
- package/test/resize-with-placement.test.ts +6 -6
- package/test/revision.test.ts +4 -5
- package/test/section-panel.test.ts +1 -1
- package/translations/en.json +9 -11
- package/translations/es.json +9 -11
- package/translations/ja.json +9 -11
- package/translations/ko.json +9 -11
- package/translations/ms.json +9 -11
- package/translations/zh.json +9 -11
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { figureJointAsFixed } from '@hatiolab/figure-model';
|
|
1
2
|
import type { FigureFollow, FigureSizeRange } from '@hatiolab/figure-model';
|
|
2
|
-
import type { FigureAsset, FigureAuthoringAction, FigureBindingPlace, FigureFace, FigureJoint } from '@hatiolab/figure-model';
|
|
3
|
+
import type { FigureAsset, FigureAuthoringAction, FigureBindingPlace, FigureFace, FigureFacing, FigureJoint } from '@hatiolab/figure-model';
|
|
3
4
|
import { type FigureRevision } from './revision.js';
|
|
4
5
|
import { type JointAxisVector } from './joint-axis.js';
|
|
5
6
|
export type Axis = 'x' | 'y' | 'z';
|
|
@@ -27,7 +28,7 @@ export declare function heldBy(asset: FigureAsset, part: string): {
|
|
|
27
28
|
} | {
|
|
28
29
|
plane: true;
|
|
29
30
|
} | null;
|
|
30
|
-
/** The word for where a joint end sits: its face's, or the part's origin for an end placed by it (ADR-0107 decision 4). */
|
|
31
|
+
/** The word for where a joint's body0 end sits: its face's, or the part's origin for an end placed by it (ADR-0107 decision 4). */
|
|
31
32
|
export declare const endPlaceKeyOf: (end: object) => string;
|
|
32
33
|
/** Whether a dimension of this part can follow something — box-shaped, whose three sizes are X, Y and Z. */
|
|
33
34
|
export declare function canFollow(asset: FigureAsset, part: string): boolean;
|
|
@@ -126,35 +127,30 @@ export type Alignment = 'centre' | 'min' | 'max' | 'mm' | 'share' | 'input';
|
|
|
126
127
|
*/
|
|
127
128
|
/**
|
|
128
129
|
* The mounting plane of this figure, by its placement (ADR-0093): the floor or the ceiling is Y = 0 and a part stands
|
|
129
|
-
* on it
|
|
130
|
+
* on it or hangs below it; a wall is Z = 0 and a part stands out of it (ADR-0140 3.11).
|
|
130
131
|
*/
|
|
131
132
|
export declare function mountingPlaneOf(asset: FigureAsset): {
|
|
132
133
|
normal: Axis;
|
|
133
|
-
|
|
134
|
+
facings: FigureFacing[];
|
|
134
135
|
};
|
|
135
|
-
export declare function alignAxesOf(asset: FigureAsset,
|
|
136
|
+
export declare function alignAxesOf(asset: FigureAsset, target: {
|
|
136
137
|
part: string;
|
|
137
138
|
face: string;
|
|
138
|
-
} | 'plane'
|
|
139
|
+
} | 'plane'): {
|
|
139
140
|
axis: Axis;
|
|
140
141
|
edges: boolean;
|
|
141
142
|
}[];
|
|
142
|
-
/**
|
|
143
|
-
* The faces of its own a part may be fastened by: its outer faces -- on the mounting plane only the ones the plane takes
|
|
144
|
-
* (a bottom or a top on the floor, a back on a wall) -- and, to another part, its centre, which a roller spins about.
|
|
145
|
-
*/
|
|
146
|
-
export declare function ownFacesOf(asset: FigureAsset, part: string, toPlane: boolean): Array<FigureFace | 'centre'>;
|
|
147
143
|
/**
|
|
148
144
|
* The axes across the face the fastening form asks about in rows: only where the face drawing (`view`, its axes) cannot
|
|
149
145
|
* set the place -- no drawing at all, an axis it does not draw, a place that follows a position field, or one the
|
|
150
146
|
* figure's size may scale.
|
|
151
147
|
*/
|
|
152
|
-
export declare function alignRowsOf(asset: FigureAsset,
|
|
148
|
+
export declare function alignRowsOf(asset: FigureAsset, aim: {
|
|
153
149
|
part: string;
|
|
154
150
|
face: string;
|
|
155
151
|
} | 'plane', view: {
|
|
156
152
|
axes: readonly Axis[];
|
|
157
|
-
} | undefined,
|
|
153
|
+
} | undefined, alignInput?: Partial<Record<Axis, string>>): {
|
|
158
154
|
axis: Axis;
|
|
159
155
|
edges: boolean;
|
|
160
156
|
}[];
|
|
@@ -174,21 +170,19 @@ export declare function shownWhenOf(asset: FigureAsset, part: string): {
|
|
|
174
170
|
/** Whether `part` hangs from `from`, through any number of fastenings. */
|
|
175
171
|
export declare function hangsFrom(asset: FigureAsset, part: string, from: string): boolean;
|
|
176
172
|
/**
|
|
177
|
-
* The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the
|
|
178
|
-
*
|
|
173
|
+
* The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the target and its
|
|
174
|
+
* face, how it meets it, the gap and where across the face) and a change is a change to that.
|
|
179
175
|
* Opening it on the defaults showed a roller fastened by its centre as fastened by its bottom, and fastening again
|
|
180
176
|
* from there broke its turning in place (walk 1, 2026-09-26). Null for a part fastened to nothing.
|
|
181
177
|
*/
|
|
182
178
|
export declare function fasteningOf(revision: FigureRevision, part: string): {
|
|
183
|
-
face: string;
|
|
184
179
|
toPlane: boolean;
|
|
185
180
|
target: string;
|
|
186
181
|
targetFace: string;
|
|
187
|
-
facing:
|
|
182
|
+
facing: FigureFacing;
|
|
188
183
|
gap: number;
|
|
189
184
|
/** The record's gap when it is worked out (a length that follows something): kept as it is until a number is typed. */
|
|
190
185
|
gapKept?: unknown;
|
|
191
|
-
twist: number;
|
|
192
186
|
align: Partial<Record<Axis, Alignment>>;
|
|
193
187
|
alignMm: Partial<Record<Axis, number>>;
|
|
194
188
|
/** Placed by a part's origin (ADR-0107 decision 4): no face to fasten by, and the form does not write it. */
|
|
@@ -206,23 +200,22 @@ export declare function fastenGapOf(form: {
|
|
|
206
200
|
gap?: unknown;
|
|
207
201
|
};
|
|
208
202
|
/**
|
|
209
|
-
* The alignment that keeps the part where it stands when it is fastened
|
|
210
|
-
*
|
|
211
|
-
* its frame slid into it (2026-09-26). Left centred where it already is, and where the target stands turned.
|
|
203
|
+
* The alignment that keeps the part where it stands when it is fastened, as the form holds it: the kernel's place
|
|
204
|
+
* (`figureFastenKeptPlaceOf`, ADR-0140 3.7), a distance on each axis it is off the target's centre.
|
|
212
205
|
*/
|
|
213
206
|
export declare function placeKeptOf(revision: FigureRevision, part: string, target: {
|
|
214
207
|
part: string;
|
|
215
208
|
face: string;
|
|
216
|
-
} | 'plane'
|
|
209
|
+
} | 'plane'): {
|
|
217
210
|
align: Partial<Record<Axis, Alignment>>;
|
|
218
211
|
alignMm: Partial<Record<Axis, number>>;
|
|
219
212
|
alignInput: Partial<Record<Axis, string>>;
|
|
220
213
|
};
|
|
221
214
|
/** The `align` of an attach command from the form's choices: only the axes across that face, and centred ones left out. */
|
|
222
|
-
export declare function alignOf(asset: FigureAsset,
|
|
215
|
+
export declare function alignOf(asset: FigureAsset, target: {
|
|
223
216
|
part: string;
|
|
224
217
|
face: string;
|
|
225
|
-
} | 'plane', how: Partial<Record<Axis, Alignment>>, mm: Partial<Record<Axis, number>>,
|
|
218
|
+
} | 'plane', how: Partial<Record<Axis, Alignment>>, mm: Partial<Record<Axis, number>>, inputs?: Partial<Record<Axis, string>>): Partial<Record<Axis, "min" | "max" | {
|
|
226
219
|
mm: number | {
|
|
227
220
|
from: {
|
|
228
221
|
of: "instance";
|
|
@@ -395,5 +388,5 @@ export declare function rangeDiffers(a: FigureSizeRange, b: FigureSizeRange): bo
|
|
|
395
388
|
* architect's ruling 2026-09-24); the modeller proposes it, the author declares it.
|
|
396
389
|
*/
|
|
397
390
|
export declare function turnsAboutAJoint(asset: FigureAsset): boolean;
|
|
398
|
-
/** The joint made still: its fastening, its place and its row kept, its motion gone. */
|
|
399
|
-
export declare
|
|
391
|
+
/** The joint made still: its fastening, its place and its row kept, its motion gone (the kernel's `figureJointAsFixed`, ADR-0140 D6). */
|
|
392
|
+
export declare const fixedJointOf: typeof figureJointAsFixed;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { figureShapeFaces, figurePartsExtentOf, figureFollowOf, proposeFigureProportion, defaultInstanceSizeRange, foldInstanceSizeRange, figureAttachmentsOf, figureBindingsOf, figureInstanceSizeLimitsOf, figureFollowableAxesOf, figureShapeProviderOf, figureMimicTermsOf, figureFastenKeptPlaceOf, figureFastenAxesOf, figureJointAsFixed, figureJointWithMotion } from '@hatiolab/figure-model';
|
|
2
2
|
import { startingShapeKindOf } from './starting-shape.js';
|
|
3
3
|
import { boxOf } from './align.js';
|
|
4
4
|
import { graphValuesOf } from './revision.js';
|
|
@@ -32,7 +32,7 @@ export function heldBy(asset, part) {
|
|
|
32
32
|
const to = fastenedTo(asset, part);
|
|
33
33
|
return to ? { part: to } : null;
|
|
34
34
|
}
|
|
35
|
-
/** The word for where a joint end sits: its face's, or the part's origin for an end placed by it (ADR-0107 decision 4). */
|
|
35
|
+
/** The word for where a joint's body0 end sits: its face's, or the part's origin for an end placed by it (ADR-0107 decision 4). */
|
|
36
36
|
export const endPlaceKeyOf = (end) => ('face' in end ? `figure.label.face-${end.face}` : 'figure.label.joint-origin');
|
|
37
37
|
/** Whether a dimension of this part can follow something — box-shaped, whose three sizes are X, Y and Z. */
|
|
38
38
|
export function canFollow(asset, part) {
|
|
@@ -234,10 +234,9 @@ export function rowAxesOf(asset, part) {
|
|
|
234
234
|
if (joints.some(o => 'part' in o.body0 && o.body0.part === part))
|
|
235
235
|
return [];
|
|
236
236
|
/* Placed by an origin: no face to lay the row across, and the kernel refuses it. */
|
|
237
|
-
|
|
238
|
-
if (!('face' in j.body0) || !('face' in by))
|
|
237
|
+
if (!('face' in j.body0) || 'at' in j.body1)
|
|
239
238
|
return [];
|
|
240
|
-
return
|
|
239
|
+
return figureFastenAxesOf(asset, { part: j.body0.part, face: j.body0.face });
|
|
241
240
|
}
|
|
242
241
|
/**
|
|
243
242
|
* Why a part cannot be made into a row here, in the terms `rowAxesOf` refuses it: said, not hidden (ADR-0097 §5.5).
|
|
@@ -254,7 +253,7 @@ export function rowBlockOf(asset, part) {
|
|
|
254
253
|
return 'on-plane';
|
|
255
254
|
if (joints.some(o => 'part' in o.body0 && o.body0.part === part))
|
|
256
255
|
return 'holds-parts';
|
|
257
|
-
if (!('face' in j.body0) ||
|
|
256
|
+
if (!('face' in j.body0) || 'at' in j.body1)
|
|
258
257
|
return 'at-origin';
|
|
259
258
|
return undefined;
|
|
260
259
|
}
|
|
@@ -267,43 +266,26 @@ export const rowOf = (asset, part) => asset.joints?.find(o => o.body1.part === p
|
|
|
267
266
|
*/
|
|
268
267
|
/**
|
|
269
268
|
* The mounting plane of this figure, by its placement (ADR-0093): the floor or the ceiling is Y = 0 and a part stands
|
|
270
|
-
* on it
|
|
269
|
+
* on it or hangs below it; a wall is Z = 0 and a part stands out of it (ADR-0140 3.11).
|
|
271
270
|
*/
|
|
272
271
|
export function mountingPlaneOf(asset) {
|
|
273
|
-
return asset.placement === 'wall' ? { normal: 'z',
|
|
272
|
+
return asset.placement === 'wall' ? { normal: 'z', facings: ['meet'] } : { normal: 'y', facings: ['meet', 'flush'] };
|
|
274
273
|
}
|
|
275
|
-
export function alignAxesOf(asset,
|
|
274
|
+
export function alignAxesOf(asset, target) {
|
|
276
275
|
/* The plane has no edges, but a figure that declares its size has sides on it (figure-model 0.1.64). */
|
|
277
|
-
if (target === 'plane')
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (!along)
|
|
283
|
-
return [];
|
|
284
|
-
const theirs = new Set(facesOf(asset, target.part)), mine = new Set(facesOf(asset, part));
|
|
285
|
-
/* A part twisted about the face's normal has no side level with the target's edges. */
|
|
286
|
-
return AXES.filter(axis => axis !== along).map(axis => ({ axis, edges: !twisted && OUTER[axis].every(f => theirs.has(f) && mine.has(f)) }));
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* The faces of its own a part may be fastened by: its outer faces -- on the mounting plane only the ones the plane takes
|
|
290
|
-
* (a bottom or a top on the floor, a back on a wall) -- and, to another part, its centre, which a roller spins about.
|
|
291
|
-
*/
|
|
292
|
-
export function ownFacesOf(asset, part, toPlane) {
|
|
293
|
-
const outer = Object.keys(FIGURE_FACES);
|
|
294
|
-
const plane = mountingPlaneOf(asset);
|
|
295
|
-
return [
|
|
296
|
-
...facesOf(asset, part).filter(face => outer.includes(face) && (!toPlane || plane.faces.includes(face))),
|
|
297
|
-
...(toPlane ? [] : ['centre'])
|
|
298
|
-
];
|
|
276
|
+
if (target === 'plane')
|
|
277
|
+
return figureFastenAxesOf(asset, 'plane').map(axis => ({ axis, edges: hasInstanceSize(asset, axis) }));
|
|
278
|
+
/* The part is lined up by its real extent in the pose it has (ADR-0140 3.4): the target's two sides are what it needs. */
|
|
279
|
+
const theirs = new Set(facesOf(asset, target.part));
|
|
280
|
+
return figureFastenAxesOf(asset, target).map(axis => ({ axis, edges: OUTER[axis].every(f => theirs.has(f)) }));
|
|
299
281
|
}
|
|
300
282
|
/**
|
|
301
283
|
* The axes across the face the fastening form asks about in rows: only where the face drawing (`view`, its axes) cannot
|
|
302
284
|
* set the place -- no drawing at all, an axis it does not draw, a place that follows a position field, or one the
|
|
303
285
|
* figure's size may scale.
|
|
304
286
|
*/
|
|
305
|
-
export function alignRowsOf(asset,
|
|
306
|
-
return alignAxesOf(asset,
|
|
287
|
+
export function alignRowsOf(asset, aim, view, alignInput = {}) {
|
|
288
|
+
return alignAxesOf(asset, aim).filter(({ axis }) => !view || !view.axes.includes(axis) || !!alignInput[axis] || hasInstanceSize(asset, axis));
|
|
307
289
|
}
|
|
308
290
|
/** The controls a part's showing can follow: the figure's state inputs, with their range and label. */
|
|
309
291
|
export function visibilityControlsOf(asset) {
|
|
@@ -335,8 +317,8 @@ export function hangsFrom(asset, part, from) {
|
|
|
335
317
|
return false;
|
|
336
318
|
}
|
|
337
319
|
/**
|
|
338
|
-
* The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the
|
|
339
|
-
*
|
|
320
|
+
* The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the target and its
|
|
321
|
+
* face, how it meets it, the gap and where across the face) and a change is a change to that.
|
|
340
322
|
* Opening it on the defaults showed a roller fastened by its centre as fastened by its bottom, and fastening again
|
|
341
323
|
* from there broke its turning in place (walk 1, 2026-09-26). Null for a part fastened to nothing.
|
|
342
324
|
*/
|
|
@@ -347,10 +329,9 @@ export function fasteningOf(revision, part) {
|
|
|
347
329
|
const toPlane = 'plane' in record.body0;
|
|
348
330
|
const target = 'part' in record.body0 ? record.body0.part : '';
|
|
349
331
|
const targetFace = 'face' in record.body0 ? record.body0.face : 'top';
|
|
350
|
-
const atOrigin = !('plane' in record.body0) && (!('face' in record.body0) ||
|
|
351
|
-
const twist = record.origin?.twist ?? 0;
|
|
332
|
+
const atOrigin = !('plane' in record.body0) && (!('face' in record.body0) || 'at' in record.body1);
|
|
352
333
|
/* Where across the face: as the record says it, and where it says nothing, where the part stands now. */
|
|
353
|
-
const kept = placeKeptOf(revision, part, toPlane ? 'plane' : { part: target, face: targetFace }
|
|
334
|
+
const kept = placeKeptOf(revision, part, toPlane ? 'plane' : { part: target, face: targetFace });
|
|
354
335
|
for (const [axis, how] of Object.entries(record.origin?.align ?? {})) {
|
|
355
336
|
if (how === 'min' || how === 'max' || how === 'centre') {
|
|
356
337
|
kept.align[axis] = how;
|
|
@@ -369,14 +350,12 @@ export function fasteningOf(revision, part) {
|
|
|
369
350
|
}
|
|
370
351
|
const gap = record.origin?.gap;
|
|
371
352
|
return {
|
|
372
|
-
face: 'face' in record.body1 ? record.body1.face : 'centre',
|
|
373
353
|
toPlane,
|
|
374
354
|
target,
|
|
375
355
|
targetFace,
|
|
376
356
|
facing: record.origin?.facing ?? 'meet',
|
|
377
357
|
gap: typeof gap === 'number' ? gap : 0,
|
|
378
358
|
...(gap !== undefined && typeof gap !== 'number' ? { gapKept: gap } : {}),
|
|
379
|
-
twist,
|
|
380
359
|
...kept,
|
|
381
360
|
...(atOrigin ? { atOrigin: true } : {})
|
|
382
361
|
};
|
|
@@ -392,41 +371,17 @@ export function fastenGapOf(form) {
|
|
|
392
371
|
return form.gap ? { gap: form.gap } : {};
|
|
393
372
|
}
|
|
394
373
|
/**
|
|
395
|
-
* The alignment that keeps the part where it stands when it is fastened
|
|
396
|
-
*
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
const asset = revision.asset;
|
|
402
|
-
/* Where it stands as drawn: the pose the command that fastens it sees. */
|
|
403
|
-
const geometry = revision.geometry;
|
|
404
|
-
const poseOf = (id) => geometry.find(g => g.id === id)?.pose;
|
|
405
|
-
const mine = poseOf(part);
|
|
406
|
-
if (!mine)
|
|
407
|
-
return kept;
|
|
408
|
-
let centre = [0, 0, 0];
|
|
409
|
-
if (target !== 'plane') {
|
|
410
|
-
const theirs = poseOf(target.part);
|
|
411
|
-
const upright = theirs?.r.every((row, i) => row.every((v, j) => Math.abs(v - (i === j ? 1 : 0)) < 1e-9));
|
|
412
|
-
if (!theirs || !upright)
|
|
413
|
-
return kept;
|
|
414
|
-
centre = theirs.t;
|
|
415
|
-
}
|
|
416
|
-
for (const { axis } of alignAxesOf(asset, part, target, twisted)) {
|
|
417
|
-
const k = AXES.indexOf(axis);
|
|
418
|
-
const off = Math.round((mine.t[k] - centre[k]) * 10) / 10;
|
|
419
|
-
if (Math.abs(off) < 0.5)
|
|
420
|
-
continue;
|
|
421
|
-
kept.align[axis] = 'mm';
|
|
422
|
-
kept.alignMm[axis] = off;
|
|
423
|
-
}
|
|
424
|
-
return kept;
|
|
374
|
+
* The alignment that keeps the part where it stands when it is fastened, as the form holds it: the kernel's place
|
|
375
|
+
* (`figureFastenKeptPlaceOf`, ADR-0140 3.7), a distance on each axis it is off the target's centre.
|
|
376
|
+
*/
|
|
377
|
+
export function placeKeptOf(revision, part, target) {
|
|
378
|
+
const alignMm = figureFastenKeptPlaceOf(revision.asset, part, target, { ...revision.inputs });
|
|
379
|
+
return { align: Object.fromEntries(Object.keys(alignMm).map(axis => [axis, 'mm'])), alignMm, alignInput: {} };
|
|
425
380
|
}
|
|
426
381
|
/** The `align` of an attach command from the form's choices: only the axes across that face, and centred ones left out. */
|
|
427
|
-
export function alignOf(asset,
|
|
382
|
+
export function alignOf(asset, target, how, mm, inputs = {}) {
|
|
428
383
|
const align = {};
|
|
429
|
-
for (const { axis, edges } of alignAxesOf(asset,
|
|
384
|
+
for (const { axis, edges } of alignAxesOf(asset, target)) {
|
|
430
385
|
const one = how[axis] ?? 'centre';
|
|
431
386
|
const size = asset.designInputs[`size.${axis}`];
|
|
432
387
|
if (one === 'share' && mm[axis] && hasInstanceSize(asset, axis) && size)
|
|
@@ -539,27 +494,23 @@ export function leadersFor(asset, part, kind) {
|
|
|
539
494
|
* control or limits of its own — its range is the leader's times the multiplier.
|
|
540
495
|
*/
|
|
541
496
|
export function motionJoint(joint, m, part) {
|
|
497
|
+
/* Where it is fastened -- its row and its frame's own words too -- is the kernel's to keep (`figureJointWithMotion`, ADR-0140 D6). */
|
|
542
498
|
const moving = {
|
|
543
|
-
id: joint.id,
|
|
544
|
-
body0: joint.body0,
|
|
545
|
-
body1: joint.body1,
|
|
546
|
-
...(joint.origin ? { origin: joint.origin } : {}),
|
|
547
|
-
/* A row keeps being a row when it is given a motion: dropped here, the row went with it (designer 2026-09-27). */
|
|
548
|
-
...(joint.repeat ? { repeat: joint.repeat } : {}),
|
|
549
499
|
type: m.kind === 'slide' ? 'prismatic' : 'revolute',
|
|
550
500
|
axis: (m.axisVector ?? m.axis.toUpperCase())
|
|
551
501
|
};
|
|
502
|
+
const given = (motion) => figureJointWithMotion(joint, { ...moving, ...motion });
|
|
552
503
|
if (m.follow)
|
|
553
|
-
return {
|
|
504
|
+
return given({ mimic: { joint: m.follow, multiplier: m.multiplier, ...(m.offset ? { offset: m.offset } : {}) } });
|
|
554
505
|
if (m.followSum)
|
|
555
|
-
return {
|
|
506
|
+
return given({ mimic: { sum: m.followSum, ...(m.offset ? { offset: m.offset } : {}) } });
|
|
556
507
|
if (m.kind === 'slide' && m.travelSum && !m.travel)
|
|
557
|
-
return {
|
|
508
|
+
return given({ travel: m.travelSum, state: { id: m.id || `${part}-${m.kind}` } });
|
|
558
509
|
if (m.kind === 'slide' && m.travel) {
|
|
559
510
|
const [of, axis] = m.travel.split(':');
|
|
560
|
-
return {
|
|
511
|
+
return given({ travel: { source: { of: 'part', part: of, axis: axis }, ...(m.travelPlus ? { plus: m.travelPlus } : {}) }, state: { id: m.id || `${part}-${m.kind}` } });
|
|
561
512
|
}
|
|
562
|
-
return { ...
|
|
513
|
+
return given({ ...(m.kind === 'continuous' ? {} : { lowerLimit: m.min, upperLimit: m.max }), state: { id: m.id || `${part}-${m.kind}` } });
|
|
563
514
|
}
|
|
564
515
|
/**
|
|
565
516
|
* Why the motion form cannot be saved as it stands, as the kernel would refuse it: a follower's multiplier that is not
|
|
@@ -727,15 +678,6 @@ export function rangeDiffers(a, b) {
|
|
|
727
678
|
export function turnsAboutAJoint(asset) {
|
|
728
679
|
return modelOf(asset).nodes.some(n => n.op === 'axis-turn@1');
|
|
729
680
|
}
|
|
730
|
-
/** The joint made still: its fastening, its place and its row kept, its motion gone. */
|
|
731
|
-
export
|
|
732
|
-
return {
|
|
733
|
-
id: joint.id,
|
|
734
|
-
type: 'fixed',
|
|
735
|
-
body0: joint.body0,
|
|
736
|
-
body1: joint.body1,
|
|
737
|
-
...(joint.origin ? { origin: joint.origin } : {}),
|
|
738
|
-
...(joint.repeat ? { repeat: joint.repeat } : {})
|
|
739
|
-
};
|
|
740
|
-
}
|
|
681
|
+
/** The joint made still: its fastening, its place and its row kept, its motion gone (the kernel's `figureJointAsFixed`, ADR-0140 D6). */
|
|
682
|
+
export const fixedJointOf = figureJointAsFixed;
|
|
741
683
|
//# sourceMappingURL=links.js.map
|