@code3d/core 0.0.1-alpha.4 → 0.0.1-alpha.7
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/README.md +42 -5
- package/bld/chunks/{chunk-J77FMYFY.js → chunk-4WLVDYUJ.js} +992 -545
- package/bld/chunks/chunk-4WLVDYUJ.js.map +7 -0
- package/bld/chunks/{chunk-PAIFBNU4.js → chunk-C3AJ6WNB.js} +2 -2
- package/bld/chunks/{chunk-OQLJDJIF.js → chunk-TCMEEKWL.js} +2 -2
- package/bld/chunks/{chunk-ZMT6EFHL.js → chunk-VHSPHJ5F.js} +3 -3
- package/bld/library/bound-solver.d.ts +29 -5
- package/bld/library/bound-solver.d.ts.map +1 -1
- package/bld/library/cached.d.ts +5 -3
- package/bld/library/cached.d.ts.map +1 -1
- package/bld/library/index.d.ts +4 -4
- package/bld/library/index.d.ts.map +1 -1
- package/bld/library/index.js +17 -3
- package/bld/library/kernel-cache.d.ts +6 -3
- package/bld/library/kernel-cache.d.ts.map +1 -1
- package/bld/library/relation-solver.d.ts +12 -7
- package/bld/library/relation-solver.d.ts.map +1 -1
- package/bld/library/replicad.js +2 -2
- package/bld/library/runtime.d.ts +218 -82
- package/bld/library/runtime.d.ts.map +1 -1
- package/bld/library/sketch.d.ts +2 -2
- package/bld/library/sketch.d.ts.map +1 -1
- package/bld/library/topology.d.ts +2 -0
- package/bld/library/topology.d.ts.map +1 -1
- package/bld/node/index.js +19 -5
- package/bld/node/replicad.js +4 -4
- package/bld/tooling/index.d.ts +3 -3
- package/bld/tooling/index.d.ts.map +1 -1
- package/bld/tooling/index.js +18 -10
- package/package.json +1 -1
- package/src/library/bound-solver.ts +103 -73
- package/src/library/cached.ts +29 -8
- package/src/library/index.ts +15 -4
- package/src/library/kernel-cache.ts +37 -5
- package/src/library/relation-solver.ts +194 -110
- package/src/library/runtime.ts +1046 -442
- package/src/library/sketch.ts +3 -3
- package/src/library/topology.ts +13 -2
- package/src/tooling/index.ts +15 -7
- package/bld/chunks/chunk-J77FMYFY.js.map +0 -7
- /package/bld/chunks/{chunk-PAIFBNU4.js.map → chunk-C3AJ6WNB.js.map} +0 -0
- /package/bld/chunks/{chunk-OQLJDJIF.js.map → chunk-TCMEEKWL.js.map} +0 -0
- /package/bld/chunks/{chunk-ZMT6EFHL.js.map → chunk-VHSPHJ5F.js.map} +0 -0
|
@@ -132,12 +132,12 @@ var binaryTypes = {
|
|
|
132
132
|
};
|
|
133
133
|
function encodeKernelArtifact(signature, value) {
|
|
134
134
|
const chunks = [];
|
|
135
|
-
let
|
|
135
|
+
let offset2 = 0;
|
|
136
136
|
const references2 = /* @__PURE__ */ new Map();
|
|
137
137
|
function binary(kind, bytes2) {
|
|
138
|
-
const node = [kind, [
|
|
138
|
+
const node = [kind, [offset2, bytes2.byteLength]];
|
|
139
139
|
chunks.push(bytes2);
|
|
140
|
-
|
|
140
|
+
offset2 += bytes2.byteLength;
|
|
141
141
|
return node;
|
|
142
142
|
}
|
|
143
143
|
__name(binary, "binary");
|
|
@@ -202,13 +202,13 @@ function encodeKernelArtifact(signature, value) {
|
|
|
202
202
|
}
|
|
203
203
|
__name(encodeObject, "encodeObject");
|
|
204
204
|
const metadata = encoder.encode(JSON.stringify([signature, encode(value)]));
|
|
205
|
-
const bytes = new Uint8Array(4 + metadata.byteLength +
|
|
205
|
+
const bytes = new Uint8Array(4 + metadata.byteLength + offset2);
|
|
206
206
|
new DataView(bytes.buffer).setUint32(0, metadata.byteLength, true);
|
|
207
207
|
bytes.set(metadata, 4);
|
|
208
|
-
|
|
208
|
+
offset2 = 4 + metadata.byteLength;
|
|
209
209
|
for (const chunk of chunks) {
|
|
210
|
-
bytes.set(chunk,
|
|
211
|
-
|
|
210
|
+
bytes.set(chunk, offset2);
|
|
211
|
+
offset2 += chunk.byteLength;
|
|
212
212
|
}
|
|
213
213
|
return bytes;
|
|
214
214
|
}
|
|
@@ -280,20 +280,20 @@ function decodeKernelArtifact(bytes, signature) {
|
|
|
280
280
|
return object;
|
|
281
281
|
}
|
|
282
282
|
case "view": {
|
|
283
|
-
const [name, buffer,
|
|
283
|
+
const [name, buffer, offset2, length] = data;
|
|
284
284
|
if (!Object.hasOwn(binaryTypes, name))
|
|
285
285
|
throw new Error("Invalid kernel artifact view");
|
|
286
286
|
return register(
|
|
287
|
-
new binaryTypes[name](decode(buffer),
|
|
287
|
+
new binaryTypes[name](decode(buffer), offset2, length)
|
|
288
288
|
);
|
|
289
289
|
}
|
|
290
290
|
case "shape":
|
|
291
291
|
case "ArrayBuffer": {
|
|
292
|
-
const [
|
|
293
|
-
if (!Number.isSafeInteger(
|
|
292
|
+
const [offset2, length] = data;
|
|
293
|
+
if (!Number.isSafeInteger(offset2) || !Number.isSafeInteger(length) || offset2 < 0 || length < 0 || start + offset2 + length > bytes.byteLength) {
|
|
294
294
|
throw new Error("Invalid kernel artifact binary range");
|
|
295
295
|
}
|
|
296
|
-
const chunk = bytes.slice(start +
|
|
296
|
+
const chunk = bytes.slice(start + offset2, start + offset2 + length);
|
|
297
297
|
if (kind === "ArrayBuffer") return register(chunk.buffer);
|
|
298
298
|
const shape = decodeShape(chunk);
|
|
299
299
|
shapes.push(shape);
|
|
@@ -369,6 +369,7 @@ __name(estimateRetainedBytes, "estimateRetainedBytes");
|
|
|
369
369
|
// packages/core/src/library/kernel-cache.ts
|
|
370
370
|
function createComputationCache({
|
|
371
371
|
maximumBytes = 2 * 1024 ** 3,
|
|
372
|
+
minimumPersistenceMilliseconds = 1,
|
|
372
373
|
nativeAllocatedBytes
|
|
373
374
|
}) {
|
|
374
375
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -386,6 +387,15 @@ function createComputationCache({
|
|
|
386
387
|
const persisted = /* @__PURE__ */ new Set();
|
|
387
388
|
const pendingPersistence = /* @__PURE__ */ new Map();
|
|
388
389
|
let externalBytes = 0;
|
|
390
|
+
function setKernelCacheBudget2(bytes) {
|
|
391
|
+
maximumBytes = bytes;
|
|
392
|
+
evictHistoricalEntries();
|
|
393
|
+
}
|
|
394
|
+
__name(setKernelCacheBudget2, "setKernelCacheBudget");
|
|
395
|
+
function setKernelCachePersistenceThreshold2(milliseconds) {
|
|
396
|
+
minimumPersistenceMilliseconds = milliseconds;
|
|
397
|
+
}
|
|
398
|
+
__name(setKernelCachePersistenceThreshold2, "setKernelCachePersistenceThreshold");
|
|
389
399
|
function setKernelExternalBytes2(bytes) {
|
|
390
400
|
externalBytes = bytes;
|
|
391
401
|
evictHistoricalEntries();
|
|
@@ -426,8 +436,10 @@ function createComputationCache({
|
|
|
426
436
|
function evaluateCachedArtifact2(key, lifecycle, compute, codec) {
|
|
427
437
|
const hit = findKernelOperation2(key, lifecycle, codec);
|
|
428
438
|
if (hit) return hit;
|
|
439
|
+
const started = performance.now();
|
|
429
440
|
const value = compute();
|
|
430
|
-
|
|
441
|
+
const milliseconds = performance.now() - started;
|
|
442
|
+
acceptKernelOperation2(key, lifecycle, value, milliseconds, codec);
|
|
431
443
|
return { id: key.id, value };
|
|
432
444
|
}
|
|
433
445
|
__name(evaluateCachedArtifact2, "evaluateCachedArtifact");
|
|
@@ -455,8 +467,8 @@ function createComputationCache({
|
|
|
455
467
|
function lookup(key, lifecycle, codec, read) {
|
|
456
468
|
currentEvaluation?.checkCancelled?.();
|
|
457
469
|
const { id, signature } = key;
|
|
458
|
-
let
|
|
459
|
-
if (!
|
|
470
|
+
let cached = entries.get(id);
|
|
471
|
+
if (!cached && codec !== false) {
|
|
460
472
|
const bytes = read();
|
|
461
473
|
if (bytes) {
|
|
462
474
|
let restored;
|
|
@@ -468,25 +480,26 @@ function createComputationCache({
|
|
|
468
480
|
misses += 1;
|
|
469
481
|
return void 0;
|
|
470
482
|
}
|
|
471
|
-
|
|
483
|
+
cached = retainEntry(key, lifecycle, restored, true);
|
|
472
484
|
persistentHits += 1;
|
|
473
485
|
persisted.add(id);
|
|
474
486
|
}
|
|
475
487
|
}
|
|
476
|
-
if (!
|
|
488
|
+
if (!cached) {
|
|
477
489
|
misses += 1;
|
|
478
490
|
return void 0;
|
|
479
491
|
}
|
|
480
|
-
if (
|
|
492
|
+
if (cached.signature !== signature)
|
|
481
493
|
throw new Error(`Kernel operation cache identity collision: ${id}`);
|
|
482
494
|
hits += 1;
|
|
483
|
-
const value =
|
|
484
|
-
if (codec !== false)
|
|
485
|
-
|
|
495
|
+
const value = cached.instantiate(cached.value);
|
|
496
|
+
if (cached.persistenceEligible && codec !== false)
|
|
497
|
+
persist(key, cached.value, codec, true);
|
|
498
|
+
touchEntry(id, cached);
|
|
486
499
|
return { id, value };
|
|
487
500
|
}
|
|
488
501
|
__name(lookup, "lookup");
|
|
489
|
-
function acceptKernelOperation2(key, lifecycle, value, codec) {
|
|
502
|
+
function acceptKernelOperation2(key, lifecycle, value, milliseconds, codec) {
|
|
490
503
|
const existing = entries.get(key.id);
|
|
491
504
|
if (existing) {
|
|
492
505
|
if (existing.signature !== key.signature)
|
|
@@ -501,8 +514,14 @@ function createComputationCache({
|
|
|
501
514
|
lifecycle.release(value);
|
|
502
515
|
throw error;
|
|
503
516
|
}
|
|
504
|
-
const entry = retainEntry(
|
|
505
|
-
|
|
517
|
+
const entry = retainEntry(
|
|
518
|
+
key,
|
|
519
|
+
lifecycle,
|
|
520
|
+
retained,
|
|
521
|
+
milliseconds >= minimumPersistenceMilliseconds
|
|
522
|
+
);
|
|
523
|
+
if (entry.persistenceEligible && codec !== false)
|
|
524
|
+
persist(key, retained, codec);
|
|
506
525
|
touchEntry(key.id, entry);
|
|
507
526
|
}
|
|
508
527
|
__name(acceptKernelOperation2, "acceptKernelOperation");
|
|
@@ -548,8 +567,9 @@ function createComputationCache({
|
|
|
548
567
|
pendingPersistence.clear();
|
|
549
568
|
}
|
|
550
569
|
__name(flushPendingPersistence, "flushPendingPersistence");
|
|
551
|
-
function retainEntry(key, lifecycle, retained) {
|
|
570
|
+
function retainEntry(key, lifecycle, retained, persistenceEligible) {
|
|
552
571
|
const entry = {
|
|
572
|
+
persistenceEligible,
|
|
553
573
|
estimatedBytes: 256 + estimateRetainedBytes(key.signature) + lifecycle.estimateBytes(retained),
|
|
554
574
|
signature: key.signature,
|
|
555
575
|
value: retained,
|
|
@@ -624,6 +644,8 @@ function createComputationCache({
|
|
|
624
644
|
beginKernelOperationEvaluation: beginKernelOperationEvaluation2,
|
|
625
645
|
clearKernelOperationCache: clearKernelOperationCache2,
|
|
626
646
|
kernelOperationCacheStats: kernelOperationCacheStats2,
|
|
647
|
+
setKernelCacheBudget: setKernelCacheBudget2,
|
|
648
|
+
setKernelCachePersistenceThreshold: setKernelCachePersistenceThreshold2,
|
|
627
649
|
setKernelArtifactStore: setKernelArtifactStore2,
|
|
628
650
|
findKernelOperation: findKernelOperation2,
|
|
629
651
|
findKernelOperations: findKernelOperations2,
|
|
@@ -642,6 +664,8 @@ var {
|
|
|
642
664
|
beginKernelOperationEvaluation,
|
|
643
665
|
clearKernelOperationCache,
|
|
644
666
|
kernelOperationCacheStats,
|
|
667
|
+
setKernelCacheBudget,
|
|
668
|
+
setKernelCachePersistenceThreshold,
|
|
645
669
|
setKernelArtifactStore,
|
|
646
670
|
findKernelOperation,
|
|
647
671
|
findKernelOperations,
|
|
@@ -706,19 +730,19 @@ var dataLifecycle = {
|
|
|
706
730
|
release() {
|
|
707
731
|
}
|
|
708
732
|
};
|
|
709
|
-
function
|
|
733
|
+
function cache(compute, args, options) {
|
|
710
734
|
const operation = cachedArtifact(
|
|
711
|
-
(...
|
|
712
|
-
const value = compute(...
|
|
735
|
+
(...args2) => {
|
|
736
|
+
const value = compute(...args2);
|
|
713
737
|
if (value && typeof value === "object" && "then" in value && typeof value.then === "function")
|
|
714
|
-
throw new Error("
|
|
738
|
+
throw new Error("cache() requires a synchronous computation.");
|
|
715
739
|
return value;
|
|
716
740
|
},
|
|
717
741
|
{ identity: compute, codec: options }
|
|
718
742
|
);
|
|
719
|
-
return (...
|
|
743
|
+
return args === void 0 ? (...args2) => operation(...args2).value : operation(...args).value;
|
|
720
744
|
}
|
|
721
|
-
__name(
|
|
745
|
+
__name(cache, "cache");
|
|
722
746
|
function cachedArtifact(compute, {
|
|
723
747
|
key,
|
|
724
748
|
lifecycle = dataLifecycle,
|
|
@@ -735,7 +759,7 @@ function cachedArtifact(compute, {
|
|
|
735
759
|
));
|
|
736
760
|
const find = /* @__PURE__ */ __name((key2) => findKernelOperation(key2, lifecycle, persistence), "find");
|
|
737
761
|
const findMany = /* @__PURE__ */ __name((keys) => findKernelOperations(keys, lifecycle, persistence), "findMany");
|
|
738
|
-
const accept = /* @__PURE__ */ __name((key2, value) => acceptKernelOperation(key2, lifecycle, value, persistence), "accept");
|
|
762
|
+
const accept = /* @__PURE__ */ __name((key2, value, milliseconds) => acceptKernelOperation(key2, lifecycle, value, milliseconds, persistence), "accept");
|
|
739
763
|
return Object.assign(
|
|
740
764
|
(...args) => {
|
|
741
765
|
return evaluateCachedArtifact(
|
|
@@ -1974,12 +1998,12 @@ function candidates(first, second, tolerance2) {
|
|
|
1974
1998
|
const gap = Math.abs(perpendicular2);
|
|
1975
1999
|
if (gap > second.radius + tolerance2) return [];
|
|
1976
2000
|
const normalized = gap / second.radius;
|
|
1977
|
-
const
|
|
2001
|
+
const offset2 = Math.abs(gap - second.radius) <= tolerance2 ? 0 : second.radius * Math.sqrt(Math.max(0, (1 - normalized) * (1 + normalized)));
|
|
1978
2002
|
const foot2 = [
|
|
1979
2003
|
second.center[0] + perpendicular2 * unit3[1],
|
|
1980
2004
|
second.center[1] - perpendicular2 * unit3[0]
|
|
1981
2005
|
];
|
|
1982
|
-
return [-
|
|
2006
|
+
return [-offset2, offset2].map((along2) => [
|
|
1983
2007
|
foot2[0] + along2 * unit3[0],
|
|
1984
2008
|
foot2[1] + along2 * unit3[1]
|
|
1985
2009
|
]);
|
|
@@ -2001,9 +2025,9 @@ function candidates(first, second, tolerance2) {
|
|
|
2001
2025
|
first.center[0] + along * scale3 * unit2[0],
|
|
2002
2026
|
first.center[1] + along * scale3 * unit2[1]
|
|
2003
2027
|
];
|
|
2004
|
-
return [-height, height].map((
|
|
2005
|
-
foot[0] -
|
|
2006
|
-
foot[1] +
|
|
2028
|
+
return [-height, height].map((offset2) => [
|
|
2029
|
+
foot[0] - offset2 * unit2[1],
|
|
2030
|
+
foot[1] + offset2 * unit2[0]
|
|
2007
2031
|
]);
|
|
2008
2032
|
}
|
|
2009
2033
|
__name(candidates, "candidates");
|
|
@@ -3333,7 +3357,17 @@ function stableEdgeGroups(shape, topology, groups) {
|
|
|
3333
3357
|
topology,
|
|
3334
3358
|
groups.map((group2) => group2.edgeId)
|
|
3335
3359
|
);
|
|
3336
|
-
|
|
3360
|
+
const linear = new Map(
|
|
3361
|
+
edges.map((edge) => [
|
|
3362
|
+
edge.hashCode,
|
|
3363
|
+
edge.geomType === "LINE"
|
|
3364
|
+
])
|
|
3365
|
+
);
|
|
3366
|
+
return groups.map((group2, index) => ({
|
|
3367
|
+
...group2,
|
|
3368
|
+
edgeId: ids[index],
|
|
3369
|
+
linear: linear.get(group2.edgeId) ?? false
|
|
3370
|
+
}));
|
|
3337
3371
|
} finally {
|
|
3338
3372
|
deleteShapes(edges);
|
|
3339
3373
|
}
|
|
@@ -5163,6 +5197,28 @@ function modelMaterialColor(snapshot) {
|
|
|
5163
5197
|
__name(modelMaterialColor, "modelMaterialColor");
|
|
5164
5198
|
|
|
5165
5199
|
// packages/core/src/library/bound-solver.ts
|
|
5200
|
+
function externalRotationFrame(action, self, reference, inverse = false) {
|
|
5201
|
+
if ("axis" in action) {
|
|
5202
|
+
const axis = composeTransforms(rotation(reference), action.axis);
|
|
5203
|
+
return {
|
|
5204
|
+
center: axis.position,
|
|
5205
|
+
quaternion: axisRotation(axis, inverse ? -action.angle : action.angle).quaternion
|
|
5206
|
+
};
|
|
5207
|
+
}
|
|
5208
|
+
const local = inverse ? invertTransform(rotation(action.rotation)) : rotation(action.rotation);
|
|
5209
|
+
const before = inverse ? composeTransforms(rotation(self), local) : rotation(self);
|
|
5210
|
+
return {
|
|
5211
|
+
center: addVectors(
|
|
5212
|
+
rotateVector(action.point, reference),
|
|
5213
|
+
rotateVector(action.displacement, before.quaternion)
|
|
5214
|
+
),
|
|
5215
|
+
quaternion: composeTransforms(
|
|
5216
|
+
composeTransforms(before, local),
|
|
5217
|
+
invertTransform(before)
|
|
5218
|
+
).quaternion
|
|
5219
|
+
};
|
|
5220
|
+
}
|
|
5221
|
+
__name(externalRotationFrame, "externalRotationFrame");
|
|
5166
5222
|
var axes = [
|
|
5167
5223
|
[1, 0, 0],
|
|
5168
5224
|
[0, 1, 0],
|
|
@@ -5194,28 +5250,15 @@ function solveBodies(bodies) {
|
|
|
5194
5250
|
"Cyclic external rotation axes cannot determine an authored orientation."
|
|
5195
5251
|
);
|
|
5196
5252
|
visiting.add(index);
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
);
|
|
5207
|
-
}
|
|
5208
|
-
return pose2;
|
|
5209
|
-
});
|
|
5210
|
-
const pose = candidates2[0] ?? identityRigidTransform;
|
|
5211
|
-
if (candidates2.some(
|
|
5212
|
-
(candidate) => !transformsAreEquivalent(
|
|
5213
|
-
rotation(candidate.quaternion),
|
|
5214
|
-
rotation(pose.quaternion)
|
|
5215
|
-
)
|
|
5216
|
-
)) {
|
|
5217
|
-
throw new Error(
|
|
5218
|
-
`Conflicting explicit rotations for ${bodies[index].name}.`
|
|
5253
|
+
let pose = bodies[index].initial ?? identityRigidTransform;
|
|
5254
|
+
for (const action of bodies[index].transformations ?? []) {
|
|
5255
|
+
if ("offset" in action) continue;
|
|
5256
|
+
pose = "local" in action ? composeTransforms(pose, action.local) : "point" in action ? composeTransforms(pose, rotation(action.rotation)) : composeTransforms(
|
|
5257
|
+
axisRotation(
|
|
5258
|
+
composeTransforms(seed2(action.body), action.axis),
|
|
5259
|
+
action.angle
|
|
5260
|
+
),
|
|
5261
|
+
pose
|
|
5219
5262
|
);
|
|
5220
5263
|
}
|
|
5221
5264
|
visiting.delete(index);
|
|
@@ -5232,17 +5275,18 @@ function solveBodies(bodies) {
|
|
|
5232
5275
|
const known = positioned.get(index);
|
|
5233
5276
|
if (known) return known;
|
|
5234
5277
|
let pose = {
|
|
5235
|
-
quaternion: identityRigidTransform.quaternion,
|
|
5278
|
+
quaternion: (bodies[index].initial ?? identityRigidTransform).quaternion,
|
|
5236
5279
|
position: {
|
|
5237
|
-
constant:
|
|
5280
|
+
constant: (bodies[index].initial ?? identityRigidTransform).position,
|
|
5238
5281
|
columns: variables.flatMap(
|
|
5239
5282
|
(body) => axes.map((axis) => body === index ? axis : origin)
|
|
5240
5283
|
)
|
|
5241
5284
|
}
|
|
5242
5285
|
};
|
|
5243
|
-
const
|
|
5244
|
-
|
|
5245
|
-
|
|
5286
|
+
for (const action of bodies[index].transformations ?? []) {
|
|
5287
|
+
if ("offset" in action) {
|
|
5288
|
+
pose = { ...pose, position: shiftPoint(pose.position, action.offset) };
|
|
5289
|
+
} else if ("local" in action) {
|
|
5246
5290
|
pose = {
|
|
5247
5291
|
position: shiftPoint(
|
|
5248
5292
|
pose.position,
|
|
@@ -5255,12 +5299,12 @@ function solveBodies(bodies) {
|
|
|
5255
5299
|
};
|
|
5256
5300
|
} else {
|
|
5257
5301
|
const axisPose = positionBody(action.body);
|
|
5258
|
-
const
|
|
5259
|
-
|
|
5260
|
-
|
|
5302
|
+
const { center, quaternion: q } = externalRotationFrame(
|
|
5303
|
+
action,
|
|
5304
|
+
pose.quaternion,
|
|
5305
|
+
axisPose.quaternion
|
|
5261
5306
|
);
|
|
5262
|
-
const
|
|
5263
|
-
const axisPoint = shiftPoint(axisPose.position, axis.position);
|
|
5307
|
+
const axisPoint = shiftPoint(axisPose.position, center);
|
|
5264
5308
|
const rotatedAxis = rotatePoint(axisPoint, q);
|
|
5265
5309
|
pose = {
|
|
5266
5310
|
position: addPoints(
|
|
@@ -5282,12 +5326,16 @@ function solveBodies(bodies) {
|
|
|
5282
5326
|
const preferences = /* @__PURE__ */ new Map();
|
|
5283
5327
|
bodies.forEach(
|
|
5284
5328
|
(body, owner) => body.relations.forEach((relation) => {
|
|
5285
|
-
const baseline =
|
|
5329
|
+
const baseline = undoActions(
|
|
5330
|
+
poses[owner],
|
|
5331
|
+
body.transformations ?? [],
|
|
5332
|
+
poses
|
|
5333
|
+
);
|
|
5286
5334
|
for (let axis = 0; axis < 3; axis++) {
|
|
5287
5335
|
const preference = {
|
|
5288
5336
|
id: relation.id,
|
|
5289
5337
|
coefficients: baseline.position.columns.map((column) => column[axis]),
|
|
5290
|
-
value: -baseline.position.constant[axis]
|
|
5338
|
+
value: (body.initial?.position[axis] ?? 0) - baseline.position.constant[axis]
|
|
5291
5339
|
};
|
|
5292
5340
|
preferences.set(
|
|
5293
5341
|
JSON.stringify([preference.coefficients, preference.value]),
|
|
@@ -5315,14 +5363,8 @@ function solveBodies(bodies) {
|
|
|
5315
5363
|
source.position,
|
|
5316
5364
|
rotateVector(center, targetFrame.quaternion)
|
|
5317
5365
|
);
|
|
5318
|
-
const targetPoint = shiftPoint(
|
|
5319
|
-
|
|
5320
|
-
addVectors(
|
|
5321
|
-
targetFrame.position,
|
|
5322
|
-
rotateVector(relation.offset ?? origin, targetFrame.quaternion)
|
|
5323
|
-
)
|
|
5324
|
-
);
|
|
5325
|
-
for (const localAxis of relation.offset ? axes : [axes[1]]) {
|
|
5366
|
+
const targetPoint = shiftPoint(target.position, targetFrame.position);
|
|
5367
|
+
for (const localAxis of [axes[1]]) {
|
|
5326
5368
|
const normal = rotateVector(localAxis, targetFrame.quaternion);
|
|
5327
5369
|
equations.push({
|
|
5328
5370
|
id: relation.id,
|
|
@@ -5357,8 +5399,8 @@ function solveBodies(bodies) {
|
|
|
5357
5399
|
}));
|
|
5358
5400
|
}
|
|
5359
5401
|
__name(solveBodies, "solveBodies");
|
|
5360
|
-
function shiftPoint(point3,
|
|
5361
|
-
return { ...point3, constant: addVectors(point3.constant,
|
|
5402
|
+
function shiftPoint(point3, offset2) {
|
|
5403
|
+
return { ...point3, constant: addVectors(point3.constant, offset2) };
|
|
5362
5404
|
}
|
|
5363
5405
|
__name(shiftPoint, "shiftPoint");
|
|
5364
5406
|
function rotatePoint(point3, quaternion) {
|
|
@@ -5377,9 +5419,14 @@ function addPoints(left, right) {
|
|
|
5377
5419
|
};
|
|
5378
5420
|
}
|
|
5379
5421
|
__name(addPoints, "addPoints");
|
|
5380
|
-
function
|
|
5422
|
+
function undoActions(pose, actions, poses) {
|
|
5381
5423
|
for (const action of [...actions].reverse()) {
|
|
5382
|
-
if ("
|
|
5424
|
+
if ("offset" in action) {
|
|
5425
|
+
pose = {
|
|
5426
|
+
...pose,
|
|
5427
|
+
position: shiftPoint(pose.position, negateVector(action.offset))
|
|
5428
|
+
};
|
|
5429
|
+
} else if ("local" in action) {
|
|
5383
5430
|
const inverse = invertTransform(action.local);
|
|
5384
5431
|
pose = {
|
|
5385
5432
|
position: shiftPoint(
|
|
@@ -5393,12 +5440,13 @@ function undoRotations(pose, actions, poses) {
|
|
|
5393
5440
|
};
|
|
5394
5441
|
} else {
|
|
5395
5442
|
const axisPose = poses[action.body];
|
|
5396
|
-
const
|
|
5397
|
-
|
|
5398
|
-
|
|
5443
|
+
const { center, quaternion: q } = externalRotationFrame(
|
|
5444
|
+
action,
|
|
5445
|
+
pose.quaternion,
|
|
5446
|
+
axisPose.quaternion,
|
|
5447
|
+
true
|
|
5399
5448
|
);
|
|
5400
|
-
const
|
|
5401
|
-
const axisPoint = shiftPoint(axisPose.position, axis.position);
|
|
5449
|
+
const axisPoint = shiftPoint(axisPose.position, center);
|
|
5402
5450
|
const rotatedAxis = rotatePoint(axisPoint, q);
|
|
5403
5451
|
pose = {
|
|
5404
5452
|
position: addPoints(
|
|
@@ -5414,7 +5462,7 @@ function undoRotations(pose, actions, poses) {
|
|
|
5414
5462
|
}
|
|
5415
5463
|
return pose;
|
|
5416
5464
|
}
|
|
5417
|
-
__name(
|
|
5465
|
+
__name(undoActions, "undoActions");
|
|
5418
5466
|
function solveTranslations(equations, preferences, dimension) {
|
|
5419
5467
|
const basis = [];
|
|
5420
5468
|
const magnitude = Math.max(
|
|
@@ -5503,54 +5551,40 @@ function solveTranslations(equations, preferences, dimension) {
|
|
|
5503
5551
|
__name(solveTranslations, "solveTranslations");
|
|
5504
5552
|
|
|
5505
5553
|
// packages/core/src/library/relation-solver.ts
|
|
5506
|
-
function
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
)
|
|
5524
|
-
}
|
|
5554
|
+
function applyExternalRotation(pose, action, reference, inverse = false) {
|
|
5555
|
+
const { center, quaternion } = externalRotationFrame(
|
|
5556
|
+
action,
|
|
5557
|
+
pose.quaternion,
|
|
5558
|
+
reference.quaternion,
|
|
5559
|
+
inverse
|
|
5560
|
+
);
|
|
5561
|
+
const point3 = addVectors(reference.position, center);
|
|
5562
|
+
return composeTransforms(
|
|
5563
|
+
{ quaternion, position: subtract2(point3, rotateVector(point3, quaternion)) },
|
|
5564
|
+
pose
|
|
5565
|
+
);
|
|
5566
|
+
}
|
|
5567
|
+
__name(applyExternalRotation, "applyExternalRotation");
|
|
5568
|
+
function beforeTransformations(pose, relation, poses) {
|
|
5569
|
+
for (const action of [...relation.actions].reverse()) {
|
|
5570
|
+
if ("offset" in action) {
|
|
5571
|
+
pose = { ...pose, position: subtract2(pose.position, action.offset) };
|
|
5572
|
+
} else
|
|
5573
|
+
pose = "local" in action ? composeTransforms(pose, invertTransform(action.local)) : applyExternalRotation(pose, action, poses[action.body], true);
|
|
5525
5574
|
}
|
|
5526
5575
|
return pose;
|
|
5527
5576
|
}
|
|
5528
|
-
__name(
|
|
5529
|
-
function
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
pose.position,
|
|
5536
|
-
rotateVector(
|
|
5537
|
-
relation.offset,
|
|
5538
|
-
composeTransforms(target, relation.target.transform).quaternion
|
|
5539
|
-
)
|
|
5540
|
-
)
|
|
5541
|
-
};
|
|
5577
|
+
__name(beforeTransformations, "beforeTransformations");
|
|
5578
|
+
function afterTransformations(pose, relation, poses) {
|
|
5579
|
+
for (const action of relation.actions) {
|
|
5580
|
+
if ("offset" in action) {
|
|
5581
|
+
pose = { ...pose, position: addVectors(pose.position, action.offset) };
|
|
5582
|
+
} else
|
|
5583
|
+
pose = "local" in action ? composeTransforms(pose, action.local) : applyExternalRotation(pose, action, poses[action.body]);
|
|
5542
5584
|
}
|
|
5543
|
-
for (const action of relation.rotations)
|
|
5544
|
-
pose = "local" in action ? composeTransforms(pose, action.local) : composeTransforms(
|
|
5545
|
-
axisRotation(
|
|
5546
|
-
composeTransforms(poses[action.body], action.axis),
|
|
5547
|
-
action.angle
|
|
5548
|
-
),
|
|
5549
|
-
pose
|
|
5550
|
-
);
|
|
5551
5585
|
return pose;
|
|
5552
5586
|
}
|
|
5553
|
-
__name(
|
|
5587
|
+
__name(afterTransformations, "afterTransformations");
|
|
5554
5588
|
function directionRotation(from, to) {
|
|
5555
5589
|
const product = dot(from, to);
|
|
5556
5590
|
if (product < -1 + 1e-10) return [...perpendicular(from), 0];
|
|
@@ -5673,8 +5707,19 @@ function solveBodies2(bodies) {
|
|
|
5673
5707
|
if (relation.kind === "align")
|
|
5674
5708
|
validateAlignment(relation.source.geometry, relation.target.geometry);
|
|
5675
5709
|
const active = bodies.flatMap(
|
|
5676
|
-
(body, i) => body.relations.length ? [i] : []
|
|
5710
|
+
(body, i) => body.relations.length || body.transformations?.length ? [i] : []
|
|
5677
5711
|
);
|
|
5712
|
+
const unplace = /* @__PURE__ */ __name((pose, owner, poses2) => beforeTransformations(
|
|
5713
|
+
pose,
|
|
5714
|
+
{ actions: bodies[owner].transformations ?? [] },
|
|
5715
|
+
poses2
|
|
5716
|
+
), "unplace");
|
|
5717
|
+
const place = /* @__PURE__ */ __name((pose, owner, poses2) => afterTransformations(
|
|
5718
|
+
pose,
|
|
5719
|
+
{ actions: bodies[owner].transformations ?? [] },
|
|
5720
|
+
poses2
|
|
5721
|
+
), "place");
|
|
5722
|
+
const baselinePose = /* @__PURE__ */ __name((pose, poses2, owner) => unplace(pose, owner, poses2), "baselinePose");
|
|
5678
5723
|
const flexible = bodies.map(
|
|
5679
5724
|
(body) => body.relations.some((r) => r.kind === "align")
|
|
5680
5725
|
);
|
|
@@ -5685,26 +5730,13 @@ function solveBodies2(bodies) {
|
|
|
5685
5730
|
const unique = [
|
|
5686
5731
|
...new Map(relations.map((entry) => [key(entry), entry])).entries()
|
|
5687
5732
|
].sort(([a], [b]) => a.localeCompare(b)).map(([, entry]) => entry);
|
|
5688
|
-
let poses = bodies.map(() => identityRigidTransform);
|
|
5689
|
-
for (const owner of active)
|
|
5690
|
-
const authored = unique.find(
|
|
5691
|
-
(entry) => entry.owner === owner && entry.relation.rotations.length
|
|
5692
|
-
)?.relation ?? unique.find(
|
|
5693
|
-
(entry) => entry.owner === owner && entry.relation.kind === "align" && entry.relation.offset
|
|
5694
|
-
)?.relation;
|
|
5695
|
-
if (authored)
|
|
5696
|
-
poses[owner] = afterRelation(
|
|
5697
|
-
identityRigidTransform,
|
|
5698
|
-
authored,
|
|
5699
|
-
poses,
|
|
5700
|
-
owner
|
|
5701
|
-
);
|
|
5702
|
-
}
|
|
5733
|
+
let poses = bodies.map((body) => body.initial ?? identityRigidTransform);
|
|
5734
|
+
for (const owner of active) poses[owner] = place(poses[owner], owner, poses);
|
|
5703
5735
|
for (const { owner, relation } of unique) {
|
|
5704
5736
|
if (relation.kind !== "align") continue;
|
|
5705
5737
|
const sourceSelf = relation.source.body === owner;
|
|
5706
5738
|
if (relation.target.body === relation.source.body) continue;
|
|
5707
|
-
const baseline =
|
|
5739
|
+
const baseline = baselinePose(poses[owner], poses, owner);
|
|
5708
5740
|
const source = transformGeometry(
|
|
5709
5741
|
relation.source.geometry,
|
|
5710
5742
|
relation.source.body === owner ? baseline : poses[relation.source.body]
|
|
@@ -5713,12 +5745,7 @@ function solveBodies2(bodies) {
|
|
|
5713
5745
|
relation.target.body === owner ? baseline : poses[relation.target.body]
|
|
5714
5746
|
);
|
|
5715
5747
|
const seed2 = sourceSelf ? alignmentSeed(source, target) : alignmentSeed(target, source);
|
|
5716
|
-
poses[owner] =
|
|
5717
|
-
composeTransforms(seed2, baseline),
|
|
5718
|
-
relation,
|
|
5719
|
-
poses,
|
|
5720
|
-
owner
|
|
5721
|
-
);
|
|
5748
|
+
poses[owner] = place(composeTransforms(seed2, baseline), owner, poses);
|
|
5722
5749
|
}
|
|
5723
5750
|
const geometryScale = Math.max(
|
|
5724
5751
|
1,
|
|
@@ -5728,12 +5755,23 @@ function solveBodies2(bodies) {
|
|
|
5728
5755
|
) : []
|
|
5729
5756
|
)
|
|
5730
5757
|
);
|
|
5731
|
-
const
|
|
5732
|
-
(body) =>
|
|
5758
|
+
const fullVariables = active.flatMap(
|
|
5759
|
+
(body) => (
|
|
5760
|
+
// Bound-only bodies without authored rotations have exactly identity
|
|
5761
|
+
// orientation. Do not numerically perturb those fixed axes: native bound
|
|
5762
|
+
// queries can introduce noise that prevents convergence at the identity.
|
|
5763
|
+
Array.from(
|
|
5764
|
+
{
|
|
5765
|
+
length: flexible[body] || bodies[body].transformations?.some((action) => !("offset" in action)) ? 6 : 3
|
|
5766
|
+
},
|
|
5767
|
+
(_, axis) => ({ body, axis })
|
|
5768
|
+
)
|
|
5769
|
+
)
|
|
5733
5770
|
);
|
|
5771
|
+
let variables = fullVariables.filter((variable) => variable.axis < 3);
|
|
5734
5772
|
const residual2 = /* @__PURE__ */ __name((candidate) => [
|
|
5735
5773
|
...unique.flatMap(({ owner, relation: r }) => {
|
|
5736
|
-
const baseline =
|
|
5774
|
+
const baseline = baselinePose(candidate[owner], candidate, owner);
|
|
5737
5775
|
const source = r.source.body === owner ? baseline : candidate[r.source.body], target = r.target.body === owner ? baseline : candidate[r.target.body];
|
|
5738
5776
|
if (r.kind === "align")
|
|
5739
5777
|
return alignmentResidual(
|
|
@@ -5755,27 +5793,25 @@ function solveBodies2(bodies) {
|
|
|
5755
5793
|
source.position,
|
|
5756
5794
|
rotateVector(center, frame.quaternion)
|
|
5757
5795
|
);
|
|
5758
|
-
const b =
|
|
5759
|
-
frame,
|
|
5760
|
-
translation(r.offset ?? origin)
|
|
5761
|
-
).position;
|
|
5796
|
+
const b = frame.position;
|
|
5762
5797
|
const delta = rotateVector(
|
|
5763
5798
|
subtract2(a, b),
|
|
5764
5799
|
invertTransform(frame).quaternion
|
|
5765
5800
|
);
|
|
5766
|
-
return
|
|
5801
|
+
return [delta[1]];
|
|
5767
5802
|
}),
|
|
5768
5803
|
...active.flatMap((owner) => {
|
|
5769
5804
|
if (flexible[owner]) return [];
|
|
5770
|
-
const
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5805
|
+
const initial = bodies[owner].initial ?? identityRigidTransform;
|
|
5806
|
+
const unplaced = unplace(candidate[owner], owner, candidate);
|
|
5807
|
+
const orientationResidual = /* @__PURE__ */ __name((pose) => composeTransforms(
|
|
5808
|
+
invertTransform(rotation(initial.quaternion)),
|
|
5809
|
+
rotation(pose.quaternion)
|
|
5810
|
+
).quaternion.slice(0, 3), "orientationResidual");
|
|
5811
|
+
return [
|
|
5812
|
+
...bodies[owner].relations.length ? [] : subtract2(unplaced.position, initial.position),
|
|
5813
|
+
...orientationResidual(unplaced)
|
|
5814
|
+
];
|
|
5779
5815
|
})
|
|
5780
5816
|
], "residual");
|
|
5781
5817
|
const perturb = /* @__PURE__ */ __name((base, steps) => {
|
|
@@ -5795,10 +5831,61 @@ function solveBodies2(bodies) {
|
|
|
5795
5831
|
};
|
|
5796
5832
|
});
|
|
5797
5833
|
}, "perturb");
|
|
5834
|
+
const settleBoundTranslations = /* @__PURE__ */ __name(() => {
|
|
5835
|
+
if (!active.some((owner) => !flexible[owner])) return poses;
|
|
5836
|
+
const free = active.flatMap((body) => [0, 1, 2].map((axis) => ({ body, axis })));
|
|
5837
|
+
if (!free.length) return poses;
|
|
5838
|
+
const shift = /* @__PURE__ */ __name((steps) => {
|
|
5839
|
+
const result = poses.map((pose) => ({
|
|
5840
|
+
...pose,
|
|
5841
|
+
position: [...pose.position]
|
|
5842
|
+
}));
|
|
5843
|
+
free.forEach(({ body, axis }, i) => {
|
|
5844
|
+
result[body].position[axis] += steps[i];
|
|
5845
|
+
});
|
|
5846
|
+
return result;
|
|
5847
|
+
}, "shift");
|
|
5848
|
+
const preferences = /* @__PURE__ */ __name((candidate2) => unique.filter(({ owner }) => !flexible[owner]).flatMap(
|
|
5849
|
+
({ owner }) => subtract2(
|
|
5850
|
+
baselinePose(candidate2[owner], candidate2, owner).position,
|
|
5851
|
+
bodies[owner].initial?.position ?? [0, 0, 0]
|
|
5852
|
+
)
|
|
5853
|
+
), "preferences");
|
|
5854
|
+
const h = 1e-5;
|
|
5855
|
+
const initial = residual2(poses), preference = preferences(poses);
|
|
5856
|
+
const columns = free.map((_, i) => {
|
|
5857
|
+
const plus = shift(free.map((_2, j) => i === j ? h : 0));
|
|
5858
|
+
const minus = shift(free.map((_2, j) => i === j ? -h : 0));
|
|
5859
|
+
const a = residual2(plus), b = residual2(minus), p = preferences(plus), q = preferences(minus);
|
|
5860
|
+
return {
|
|
5861
|
+
constraints: a.map((v, j) => (v - b[j]) / (2 * h)),
|
|
5862
|
+
preferences: p.map((v, j) => (v - q[j]) / (2 * h))
|
|
5863
|
+
};
|
|
5864
|
+
});
|
|
5865
|
+
const step = solveTranslations(
|
|
5866
|
+
initial.map((value, i) => ({
|
|
5867
|
+
id: "bound translation",
|
|
5868
|
+
value: -value,
|
|
5869
|
+
coefficients: columns.map((column) => column.constraints[i])
|
|
5870
|
+
})),
|
|
5871
|
+
preference.map((value, i) => ({
|
|
5872
|
+
id: "pre-action position",
|
|
5873
|
+
value: -value,
|
|
5874
|
+
coefficients: columns.map((column) => column.preferences[i])
|
|
5875
|
+
})),
|
|
5876
|
+
free.length
|
|
5877
|
+
);
|
|
5878
|
+
const candidate = shift(step);
|
|
5879
|
+
return residual2(candidate).every((value) => Math.abs(value) < 1e-8) ? candidate : poses;
|
|
5880
|
+
}, "settleBoundTranslations");
|
|
5798
5881
|
let values = residual2(poses), damping = 1e-5;
|
|
5799
5882
|
const norm = /* @__PURE__ */ __name((values2) => values2.reduce((sum, x) => sum + x * x, 0), "norm");
|
|
5800
|
-
for (let iteration = 0; iteration <
|
|
5801
|
-
if (
|
|
5883
|
+
for (let iteration = 0; iteration < 168; iteration++) {
|
|
5884
|
+
if (iteration === 8) {
|
|
5885
|
+
variables = fullVariables;
|
|
5886
|
+
damping = 1e-5;
|
|
5887
|
+
}
|
|
5888
|
+
if (values.every((v) => Math.abs(v) < 1e-8)) return settleBoundTranslations();
|
|
5802
5889
|
const h = 1e-6;
|
|
5803
5890
|
const columns = variables.map((_, i) => {
|
|
5804
5891
|
const shifted = residual2(
|
|
@@ -5807,7 +5894,13 @@ function solveBodies2(bodies) {
|
|
|
5807
5894
|
variables.map((_2, j) => i === j ? h : 0)
|
|
5808
5895
|
)
|
|
5809
5896
|
);
|
|
5810
|
-
|
|
5897
|
+
const opposite = residual2(
|
|
5898
|
+
perturb(
|
|
5899
|
+
poses,
|
|
5900
|
+
variables.map((_2, j) => i === j ? -h : 0)
|
|
5901
|
+
)
|
|
5902
|
+
);
|
|
5903
|
+
return values.map((_2, j) => (shifted[j] - opposite[j]) / (2 * h));
|
|
5811
5904
|
});
|
|
5812
5905
|
const multiply2 = /* @__PURE__ */ __name((a, b) => a.reduce((sum, x, i) => sum + x * b[i], 0), "multiply");
|
|
5813
5906
|
const matrix = columns.map((a, i) => [
|
|
@@ -5830,10 +5923,10 @@ __name(solveBodies2, "solveBodies");
|
|
|
5830
5923
|
function eliminate(matrix) {
|
|
5831
5924
|
const n = matrix.length;
|
|
5832
5925
|
for (let i = 0; i < n; i++) {
|
|
5833
|
-
let
|
|
5926
|
+
let pivot2 = i;
|
|
5834
5927
|
for (let j = i + 1; j < n; j++)
|
|
5835
|
-
if (Math.abs(matrix[j][i]) > Math.abs(matrix[
|
|
5836
|
-
[matrix[i], matrix[
|
|
5928
|
+
if (Math.abs(matrix[j][i]) > Math.abs(matrix[pivot2][i])) pivot2 = j;
|
|
5929
|
+
[matrix[i], matrix[pivot2]] = [matrix[pivot2], matrix[i]];
|
|
5837
5930
|
for (let j = i + 1; j < n; j++) {
|
|
5838
5931
|
const factor = matrix[j][i] / matrix[i][i];
|
|
5839
5932
|
for (let k = i; k <= n; k++) matrix[j][k] -= factor * matrix[i][k];
|
|
@@ -5977,10 +6070,10 @@ function openShell(shape, topology, thickness, removedIds, sourceVolume) {
|
|
|
5977
6070
|
__name(openShell, "openShell");
|
|
5978
6071
|
function closedShell(shape, topology, thickness, sourceVolume) {
|
|
5979
6072
|
const oc = getOC8();
|
|
5980
|
-
const
|
|
6073
|
+
const offset2 = new oc.BRepOffsetAPI_MakeOffsetShape();
|
|
5981
6074
|
let parallel;
|
|
5982
6075
|
try {
|
|
5983
|
-
|
|
6076
|
+
offset2.PerformByJoin(
|
|
5984
6077
|
shape.wrapped,
|
|
5985
6078
|
-thickness,
|
|
5986
6079
|
tolerance,
|
|
@@ -5990,9 +6083,9 @@ function closedShell(shape, topology, thickness, sourceVolume) {
|
|
|
5990
6083
|
oc.GeomAbs_JoinType.GeomAbs_Arc,
|
|
5991
6084
|
false
|
|
5992
6085
|
);
|
|
5993
|
-
if (!
|
|
6086
|
+
if (!offset2.IsDone())
|
|
5994
6087
|
throw new Error("OpenCascade could not build the cavity offset.");
|
|
5995
|
-
const raw = castOwnedShape3D(
|
|
6088
|
+
const raw = castOwnedShape3D(offset2.Shape());
|
|
5996
6089
|
try {
|
|
5997
6090
|
parallel = singleSolid(raw);
|
|
5998
6091
|
} finally {
|
|
@@ -6049,7 +6142,7 @@ function closedShell(shape, topology, thickness, sourceVolume) {
|
|
|
6049
6142
|
}
|
|
6050
6143
|
} finally {
|
|
6051
6144
|
parallel?.delete();
|
|
6052
|
-
|
|
6145
|
+
offset2.delete();
|
|
6053
6146
|
}
|
|
6054
6147
|
}
|
|
6055
6148
|
__name(closedShell, "closedShell");
|
|
@@ -17942,19 +18035,19 @@ function getAxisAlignedRayLoopIntersections(loop, p, dir) {
|
|
|
17942
18035
|
}
|
|
17943
18036
|
const ts7 = [];
|
|
17944
18037
|
let f8;
|
|
17945
|
-
let
|
|
18038
|
+
let offset2;
|
|
17946
18039
|
let axis;
|
|
17947
18040
|
const dirIsDecreasing = dir === "left" || dir === "up";
|
|
17948
18041
|
if (dir === "left" || dir === "right") {
|
|
17949
18042
|
f8 = /* @__PURE__ */ __name((ps2) => toPowerBasis(ps2)[1], "f");
|
|
17950
|
-
|
|
18043
|
+
offset2 = [0, -y];
|
|
17951
18044
|
axis = 0;
|
|
17952
18045
|
} else {
|
|
17953
18046
|
f8 = /* @__PURE__ */ __name((ps2) => toPowerBasis(ps2)[0], "f");
|
|
17954
|
-
|
|
18047
|
+
offset2 = [-x, 0];
|
|
17955
18048
|
axis = 1;
|
|
17956
18049
|
}
|
|
17957
|
-
const translatedPs = ps.map(translate(
|
|
18050
|
+
const translatedPs = ps.map(translate(offset2));
|
|
17958
18051
|
const poly = f8(translatedPs);
|
|
17959
18052
|
const ts_ = roots(poly, 0 - DELTA, 1 + DELTA)?.map((r) => r.t) || [];
|
|
17960
18053
|
for (let i2 = 0; i2 < ts_.length; i2++) {
|
|
@@ -19930,9 +20023,9 @@ import {
|
|
|
19930
20023
|
measureShapeSurfaceProperties
|
|
19931
20024
|
} from "replicad";
|
|
19932
20025
|
function inspectShapeTopology(original, topology, options = {}) {
|
|
19933
|
-
const
|
|
20026
|
+
const offset2 = options.offset ?? 0;
|
|
19934
20027
|
const limit = options.limit ?? 48;
|
|
19935
|
-
if (!Number.isSafeInteger(
|
|
20028
|
+
if (!Number.isSafeInteger(offset2) || offset2 < 0 || !Number.isSafeInteger(limit) || limit < 1 || limit > 200)
|
|
19936
20029
|
throw new Error(
|
|
19937
20030
|
"Topology pages require a nonnegative offset and a limit from 1 to 200."
|
|
19938
20031
|
);
|
|
@@ -19980,7 +20073,7 @@ function inspectShapeTopology(original, topology, options = {}) {
|
|
|
19980
20073
|
(id, index) => !options.ids || options.ids.some((requested) => sameTopologyId(requested, id)) ? [{ kind, id, index }] : []
|
|
19981
20074
|
)
|
|
19982
20075
|
);
|
|
19983
|
-
const page = all.slice(
|
|
20076
|
+
const page = all.slice(offset2, offset2 + limit);
|
|
19984
20077
|
const childIndices = /* @__PURE__ */ __name((parent, kind) => {
|
|
19985
20078
|
const children = shapeSubshapes(parent, kind);
|
|
19986
20079
|
try {
|
|
@@ -20059,8 +20152,8 @@ function inspectShapeTopology(original, topology, options = {}) {
|
|
|
20059
20152
|
method: "kernel-enclosure"
|
|
20060
20153
|
},
|
|
20061
20154
|
total: all.length,
|
|
20062
|
-
offset,
|
|
20063
|
-
...
|
|
20155
|
+
offset: offset2,
|
|
20156
|
+
...offset2 + page.length < all.length ? { nextOffset: offset2 + page.length } : {},
|
|
20064
20157
|
items,
|
|
20065
20158
|
units: "model",
|
|
20066
20159
|
coordinates: "scene",
|
|
@@ -20188,6 +20281,18 @@ function inspectSurface(face) {
|
|
|
20188
20281
|
__name(inspectSurface, "inspectSurface");
|
|
20189
20282
|
|
|
20190
20283
|
// packages/core/src/library/runtime.ts
|
|
20284
|
+
function isAxisSelection(pivot2) {
|
|
20285
|
+
return pivot2.kind === "axisLine" || pivot2.kind === "axisEdge";
|
|
20286
|
+
}
|
|
20287
|
+
__name(isAxisSelection, "isAxisSelection");
|
|
20288
|
+
function selectionReference(pivot2) {
|
|
20289
|
+
return pivot2.kind === "axisLine" ? pivot2.axis : pivot2.kind === "pivotPoint" ? pivot2.point : void 0;
|
|
20290
|
+
}
|
|
20291
|
+
__name(selectionReference, "selectionReference");
|
|
20292
|
+
function mapSelectionReference(pivot2, map) {
|
|
20293
|
+
return pivot2.kind === "axisLine" ? { ...pivot2, axis: map(pivot2.axis) } : pivot2.kind === "pivotPoint" ? { ...pivot2, point: map(pivot2.point) } : pivot2;
|
|
20294
|
+
}
|
|
20295
|
+
__name(mapSelectionReference, "mapSelectionReference");
|
|
20191
20296
|
var activeRelate;
|
|
20192
20297
|
var valueTraces = /* @__PURE__ */ new WeakMap();
|
|
20193
20298
|
var operationTraces = /* @__PURE__ */ new WeakMap();
|
|
@@ -20208,6 +20313,7 @@ function valueTrace(value) {
|
|
|
20208
20313
|
__name(valueTrace, "valueTrace");
|
|
20209
20314
|
function transformSolveContext(context, transform) {
|
|
20210
20315
|
return {
|
|
20316
|
+
frame: composeTransforms(transform, context.frame),
|
|
20211
20317
|
poses: new Map(
|
|
20212
20318
|
[...context.poses].map(([model, pose]) => [
|
|
20213
20319
|
model,
|
|
@@ -20436,7 +20542,7 @@ function modelTopologyReference(value) {
|
|
|
20436
20542
|
__name(modelTopologyReference, "modelTopologyReference");
|
|
20437
20543
|
function modelTopologyIds(value, kind) {
|
|
20438
20544
|
const topology = value instanceof ModelTopologyElement ? value[anchorReferenceValue].topology : void 0;
|
|
20439
|
-
const source = isModelObject(value) ? value : value instanceof
|
|
20545
|
+
const source = isModelObject(value) ? value : value instanceof RelationExpression ? value.self() : topology?.source;
|
|
20440
20546
|
const geometry = isModelObject(source) ? source[modelGeometry]()?.value : void 0;
|
|
20441
20547
|
if (!geometry) return void 0;
|
|
20442
20548
|
return topologyChildren(
|
|
@@ -20447,40 +20553,27 @@ function modelTopologyIds(value, kind) {
|
|
|
20447
20553
|
);
|
|
20448
20554
|
}
|
|
20449
20555
|
__name(modelTopologyIds, "modelTopologyIds");
|
|
20450
|
-
var
|
|
20451
|
-
constructor(
|
|
20452
|
-
this.
|
|
20453
|
-
this.source = source;
|
|
20454
|
-
this.target = target;
|
|
20455
|
-
this.displacement = displacement;
|
|
20456
|
-
this.rotations = rotations;
|
|
20556
|
+
var RelationExpression = class {
|
|
20557
|
+
constructor(definition, context, relationId, previous, spatialOperation) {
|
|
20558
|
+
this.definition = definition;
|
|
20457
20559
|
this.context = context;
|
|
20458
|
-
this.
|
|
20560
|
+
this.relationId = relationId;
|
|
20561
|
+
this.spatialOperation = spatialOperation;
|
|
20459
20562
|
valueTraces.set(this, {
|
|
20460
20563
|
sourceRefs: [...previous ? valueTrace(previous).sourceRefs : []],
|
|
20461
20564
|
parameters: [...previous ? valueTrace(previous).parameters : []]
|
|
20462
20565
|
});
|
|
20463
20566
|
}
|
|
20464
|
-
|
|
20465
|
-
source;
|
|
20466
|
-
target;
|
|
20467
|
-
displacement;
|
|
20468
|
-
rotations;
|
|
20567
|
+
definition;
|
|
20469
20568
|
context;
|
|
20470
|
-
|
|
20569
|
+
relationId;
|
|
20570
|
+
spatialOperation;
|
|
20471
20571
|
static {
|
|
20472
|
-
__name(this, "
|
|
20473
|
-
}
|
|
20474
|
-
get sourceRefs() {
|
|
20475
|
-
return valueTrace(this).sourceRefs;
|
|
20476
|
-
}
|
|
20477
|
-
get parameters() {
|
|
20478
|
-
return valueTrace(this).parameters;
|
|
20572
|
+
__name(this, "RelationExpression");
|
|
20479
20573
|
}
|
|
20480
|
-
spatialOperation;
|
|
20481
20574
|
/** @internal */
|
|
20482
20575
|
attachSource(sourceRef) {
|
|
20483
|
-
const refs = this.sourceRefs;
|
|
20576
|
+
const refs = valueTrace(this).sourceRefs;
|
|
20484
20577
|
if (!refs.some(
|
|
20485
20578
|
(ref) => ref.file === sourceRef.file && ref.start === sourceRef.start && ref.end === sourceRef.end
|
|
20486
20579
|
))
|
|
@@ -20488,7 +20581,7 @@ var ConstraintExpression = class {
|
|
|
20488
20581
|
}
|
|
20489
20582
|
/** @internal */
|
|
20490
20583
|
attachParameters(parameters) {
|
|
20491
|
-
appendUniqueParameters(this.parameters, parameters);
|
|
20584
|
+
appendUniqueParameters(valueTrace(this).parameters, parameters);
|
|
20492
20585
|
}
|
|
20493
20586
|
/** @internal */
|
|
20494
20587
|
self() {
|
|
@@ -20496,79 +20589,89 @@ var ConstraintExpression = class {
|
|
|
20496
20589
|
}
|
|
20497
20590
|
/** @internal */
|
|
20498
20591
|
traceReference() {
|
|
20592
|
+
if (this.definition.kind === "transformation")
|
|
20593
|
+
return {
|
|
20594
|
+
kind: "transformation",
|
|
20595
|
+
transformationId: this.relationId,
|
|
20596
|
+
self: this.context?.self
|
|
20597
|
+
};
|
|
20499
20598
|
const rebind = /* @__PURE__ */ __name((model) => model === this.context?.original ? this.context.self : model, "rebind");
|
|
20500
20599
|
return {
|
|
20501
|
-
|
|
20502
|
-
|
|
20503
|
-
|
|
20600
|
+
kind: "constraint",
|
|
20601
|
+
constraintId: this.relationId,
|
|
20602
|
+
source: rebind(this.definition.source.model),
|
|
20603
|
+
target: rebind(this.definition.target.model),
|
|
20504
20604
|
self: this.context?.self
|
|
20505
20605
|
};
|
|
20506
20606
|
}
|
|
20507
20607
|
/** @internal */
|
|
20508
20608
|
storeFor(model, original) {
|
|
20509
20609
|
const isSelf = /* @__PURE__ */ __name((candidate) => candidate === model || candidate === original, "isSelf");
|
|
20510
|
-
if (!isSelf(this.source.model) && !isSelf(this.target.model))
|
|
20511
|
-
throw new Error(
|
|
20512
|
-
"The constraint returned by relate() must involve self or the original receiver."
|
|
20513
|
-
);
|
|
20514
20610
|
const bind = /* @__PURE__ */ __name((reference) => ({
|
|
20515
20611
|
...reference,
|
|
20516
20612
|
model: isSelf(reference.model) ? void 0 : reference.model
|
|
20517
20613
|
}), "bind");
|
|
20518
|
-
const
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20614
|
+
const definition = this.definition;
|
|
20615
|
+
if (definition.kind !== "transformation" && !isSelf(definition.source.model) && !isSelf(definition.target.model))
|
|
20616
|
+
throw new Error(
|
|
20617
|
+
"The constraint returned by relate() must involve self or the original receiver."
|
|
20618
|
+
);
|
|
20619
|
+
const stored = definition.kind === "transformation" ? {
|
|
20620
|
+
kind: "transformation",
|
|
20621
|
+
id: this.relationId,
|
|
20622
|
+
actions: definition.actions.map((action) => {
|
|
20623
|
+
const storedAction = {
|
|
20624
|
+
...action,
|
|
20625
|
+
..."pivot" in action ? {
|
|
20626
|
+
pivot: mapSelectionReference(action.pivot, bind)
|
|
20627
|
+
} : {}
|
|
20628
|
+
};
|
|
20629
|
+
valueTraces.set(storedAction, {
|
|
20630
|
+
sourceRefs: [...valueTrace(action).sourceRefs],
|
|
20631
|
+
parameters: [...valueTrace(action).parameters]
|
|
20632
|
+
});
|
|
20633
|
+
return storedAction;
|
|
20634
|
+
})
|
|
20635
|
+
} : {
|
|
20636
|
+
kind: definition.kind,
|
|
20637
|
+
id: this.relationId,
|
|
20638
|
+
source: bind(definition.source),
|
|
20639
|
+
target: bind(definition.target)
|
|
20528
20640
|
};
|
|
20529
20641
|
valueTraces.set(stored, {
|
|
20530
|
-
sourceRefs: [...this.sourceRefs],
|
|
20531
|
-
parameters: [...this.parameters]
|
|
20642
|
+
sourceRefs: [...valueTrace(this).sourceRefs],
|
|
20643
|
+
parameters: [...valueTrace(this).parameters]
|
|
20532
20644
|
});
|
|
20533
20645
|
return stored;
|
|
20534
20646
|
}
|
|
20535
20647
|
/** @internal */
|
|
20536
|
-
preview() {
|
|
20648
|
+
preview(preceding = []) {
|
|
20537
20649
|
if (!this.context) return void 0;
|
|
20538
|
-
const
|
|
20539
|
-
const selection =
|
|
20650
|
+
const pivot2 = this.spatialOperation?.pivot;
|
|
20651
|
+
const selection = pivot2 ? {
|
|
20540
20652
|
...this.spatialOperation,
|
|
20541
|
-
pivot: {
|
|
20542
|
-
...
|
|
20543
|
-
|
|
20544
|
-
|
|
20545
|
-
model: pivot.axis.model === this.context.self || pivot.axis.model === this.context.original ? void 0 : pivot.axis.model
|
|
20546
|
-
}
|
|
20547
|
-
}
|
|
20653
|
+
pivot: mapSelectionReference(pivot2, (reference) => ({
|
|
20654
|
+
...reference,
|
|
20655
|
+
model: reference.model === this.context.self || reference.model === this.context.original ? void 0 : reference.model
|
|
20656
|
+
}))
|
|
20548
20657
|
} : this.spatialOperation;
|
|
20549
|
-
return this.context.
|
|
20550
|
-
this.context.self.nodeId,
|
|
20658
|
+
return this.context.self[previewRelation](
|
|
20551
20659
|
this.storeFor(this.context.self, this.context.original),
|
|
20552
|
-
selection
|
|
20660
|
+
selection,
|
|
20661
|
+
preceding
|
|
20553
20662
|
);
|
|
20554
20663
|
}
|
|
20664
|
+
/** @internal */
|
|
20665
|
+
continuationArguments() {
|
|
20666
|
+
return [this.definition, this.context, this.relationId, this];
|
|
20667
|
+
}
|
|
20555
20668
|
};
|
|
20556
|
-
var Constraint = class _Constraint extends
|
|
20669
|
+
var Constraint = class _Constraint extends RelationExpression {
|
|
20557
20670
|
static {
|
|
20558
20671
|
__name(this, "Constraint");
|
|
20559
20672
|
}
|
|
20560
|
-
constructor(
|
|
20561
|
-
super(
|
|
20562
|
-
kind,
|
|
20563
|
-
source,
|
|
20564
|
-
target,
|
|
20565
|
-
displacement,
|
|
20566
|
-
rotations,
|
|
20567
|
-
context,
|
|
20568
|
-
constraintId,
|
|
20569
|
-
previous
|
|
20570
|
-
);
|
|
20571
|
-
this.spatialOperation = spatialOperation;
|
|
20673
|
+
constructor(definition) {
|
|
20674
|
+
super(definition, activeRelate, `constraint-${nextConstraintId++}`);
|
|
20572
20675
|
}
|
|
20573
20676
|
/** @internal */
|
|
20574
20677
|
static create(source, target, kind = "on") {
|
|
@@ -20578,132 +20681,210 @@ var Constraint = class _Constraint extends ConstraintExpression {
|
|
|
20578
20681
|
throw new Error(
|
|
20579
20682
|
"align() requires points, curves, or surfaces; select geometry on a solid or group."
|
|
20580
20683
|
);
|
|
20581
|
-
return new _Constraint(kind, source, target);
|
|
20582
|
-
}
|
|
20583
|
-
|
|
20584
|
-
|
|
20585
|
-
|
|
20586
|
-
|
|
20587
|
-
|
|
20588
|
-
|
|
20589
|
-
|
|
20590
|
-
|
|
20591
|
-
|
|
20592
|
-
|
|
20593
|
-
|
|
20684
|
+
return new _Constraint({ kind, source, target });
|
|
20685
|
+
}
|
|
20686
|
+
};
|
|
20687
|
+
var Transformation = class extends RelationExpression {
|
|
20688
|
+
static {
|
|
20689
|
+
__name(this, "Transformation");
|
|
20690
|
+
}
|
|
20691
|
+
/** @internal */
|
|
20692
|
+
constructor(action, previous) {
|
|
20693
|
+
const args = previous?.continuationArguments();
|
|
20694
|
+
super(
|
|
20695
|
+
{ kind: "transformation", actions: [action] },
|
|
20696
|
+
args ? args[1] : activeRelate,
|
|
20697
|
+
args?.[2] ?? `transformation-${nextConstraintId++}`,
|
|
20698
|
+
previous,
|
|
20699
|
+
"pivot" in action ? { kind: "rotate", pivot: action.pivot } : void 0
|
|
20594
20700
|
);
|
|
20701
|
+
valueTraces.set(action, valueTrace(this));
|
|
20595
20702
|
}
|
|
20596
|
-
|
|
20597
|
-
|
|
20598
|
-
|
|
20599
|
-
|
|
20600
|
-
/** @code3d.param id {kind: 'vertex', label: 'Pivot vertex'} */
|
|
20601
|
-
pivotVertex(id) {
|
|
20602
|
-
return new ConstraintPivotChain(this, { kind: "pivotVertex", id });
|
|
20603
|
-
}
|
|
20604
|
-
/** Select a positioned axis in the composition. */
|
|
20605
|
-
around(axis) {
|
|
20606
|
-
const reference = anchorReference(axis);
|
|
20607
|
-
if (reference.kind !== "line")
|
|
20608
|
-
throw new Error("around() requires an axis or straight edge.");
|
|
20609
|
-
const geometry = reference.topology?.source[modelGeometry]()?.value ?? (reference.whole && isModelObject(reference.model) ? reference.model[modelGeometry]()?.value : void 0);
|
|
20610
|
-
if (geometry) {
|
|
20611
|
-
const straight = reference.topology ? withTopologyShape(
|
|
20612
|
-
geometry.shape,
|
|
20613
|
-
geometry.topology,
|
|
20614
|
-
reference.topology.selection,
|
|
20615
|
-
(shape) => shape.geomType === "LINE"
|
|
20616
|
-
) : geometry.shape.geomType === "LINE";
|
|
20617
|
-
if (!straight)
|
|
20618
|
-
throw new Error(
|
|
20619
|
-
"around() requires a straight axis; curved edges do not define one rotation axis."
|
|
20620
|
-
);
|
|
20621
|
-
}
|
|
20622
|
-
return new ConstraintAroundChain(this, { kind: "around", axis: reference });
|
|
20703
|
+
};
|
|
20704
|
+
var TransformationRotation = class extends RelationExpression {
|
|
20705
|
+
static {
|
|
20706
|
+
__name(this, "TransformationRotation");
|
|
20623
20707
|
}
|
|
20624
|
-
|
|
20625
|
-
|
|
20708
|
+
constructor() {
|
|
20709
|
+
super(
|
|
20710
|
+
{ kind: "transformation", actions: [] },
|
|
20711
|
+
activeRelate,
|
|
20712
|
+
`transformation-${nextConstraintId++}`
|
|
20713
|
+
);
|
|
20626
20714
|
}
|
|
20627
|
-
|
|
20628
|
-
withRotation(pivot, angles, previous) {
|
|
20715
|
+
withRotation(pivot2, angles, previous) {
|
|
20629
20716
|
assertFiniteVector(
|
|
20630
20717
|
"rotate",
|
|
20631
20718
|
typeof angles === "number" ? [angles, 0, 0] : angles
|
|
20632
20719
|
);
|
|
20633
|
-
return new
|
|
20634
|
-
this.kind,
|
|
20635
|
-
this.source,
|
|
20636
|
-
this.target,
|
|
20637
|
-
this.displacement,
|
|
20638
|
-
[...this.rotations, { pivot, angles }],
|
|
20639
|
-
this.context,
|
|
20640
|
-
this.constraintId,
|
|
20641
|
-
previous,
|
|
20642
|
-
{ kind: "rotate", pivot }
|
|
20643
|
-
);
|
|
20644
|
-
}
|
|
20645
|
-
/** @internal */
|
|
20646
|
-
chainArguments() {
|
|
20647
|
-
return [
|
|
20648
|
-
this.kind,
|
|
20649
|
-
this.source,
|
|
20650
|
-
this.target,
|
|
20651
|
-
this.displacement,
|
|
20652
|
-
this.rotations,
|
|
20653
|
-
this.context,
|
|
20654
|
-
this.constraintId,
|
|
20655
|
-
this
|
|
20656
|
-
];
|
|
20720
|
+
return new Transformation({ pivot: pivot2, angles }, previous);
|
|
20657
20721
|
}
|
|
20658
20722
|
};
|
|
20659
|
-
|
|
20723
|
+
function rotationPointReference(point3) {
|
|
20724
|
+
const reference = anchorReference(point3);
|
|
20725
|
+
if (reference.kind !== "point")
|
|
20726
|
+
throw new Error("pivotPoint() requires a point reference.");
|
|
20727
|
+
return reference;
|
|
20728
|
+
}
|
|
20729
|
+
__name(rotationPointReference, "rotationPointReference");
|
|
20730
|
+
function rotationAxisReference(axis) {
|
|
20731
|
+
const reference = anchorReference(axis);
|
|
20732
|
+
if (reference.kind !== "line")
|
|
20733
|
+
throw new Error("axisLine() requires an axis or straight edge.");
|
|
20734
|
+
const geometry = reference.topology?.source[modelGeometry]()?.value ?? (reference.whole && isModelObject(reference.model) ? reference.model[modelGeometry]()?.value : void 0);
|
|
20735
|
+
if (geometry) {
|
|
20736
|
+
const straight = reference.topology ? withTopologyShape(
|
|
20737
|
+
geometry.shape,
|
|
20738
|
+
geometry.topology,
|
|
20739
|
+
reference.topology.selection,
|
|
20740
|
+
(shape) => shape.geomType === "LINE"
|
|
20741
|
+
) : geometry.shape.geomType === "LINE";
|
|
20742
|
+
if (!straight)
|
|
20743
|
+
throw new Error(
|
|
20744
|
+
"axisLine() requires a straight axis; curved edges do not define one rotation axis."
|
|
20745
|
+
);
|
|
20746
|
+
}
|
|
20747
|
+
return reference;
|
|
20748
|
+
}
|
|
20749
|
+
__name(rotationAxisReference, "rotationAxisReference");
|
|
20750
|
+
var PivotRotation = class extends RelationExpression {
|
|
20660
20751
|
/** @internal */
|
|
20661
|
-
constructor(
|
|
20662
|
-
super(...
|
|
20663
|
-
|
|
20752
|
+
constructor(chain, selection, previous) {
|
|
20753
|
+
super(...(previous ?? chain).continuationArguments(), {
|
|
20754
|
+
kind: selection.offset ? "pivotOffset" : selection.kind,
|
|
20755
|
+
pivot: selection
|
|
20756
|
+
});
|
|
20757
|
+
this.chain = chain;
|
|
20664
20758
|
this.selection = selection;
|
|
20665
|
-
this.spatialOperation = { kind: selection.kind, pivot: selection };
|
|
20666
20759
|
}
|
|
20667
|
-
|
|
20760
|
+
chain;
|
|
20668
20761
|
selection;
|
|
20669
20762
|
static {
|
|
20670
|
-
__name(this, "
|
|
20763
|
+
__name(this, "PivotRotation");
|
|
20671
20764
|
}
|
|
20672
20765
|
rotate(x = 0, y = 0, z = 0) {
|
|
20673
|
-
return this.
|
|
20766
|
+
return this.chain.withRotation(this.selection, [x, y, z], this);
|
|
20767
|
+
}
|
|
20768
|
+
};
|
|
20769
|
+
var PivotChain = class extends PivotRotation {
|
|
20770
|
+
static {
|
|
20771
|
+
__name(this, "PivotChain");
|
|
20772
|
+
}
|
|
20773
|
+
pivotOffset(x = 0, y = 0, z = 0) {
|
|
20774
|
+
assertFiniteVector("pivotOffset", [x, y, z]);
|
|
20775
|
+
return new PivotRotation(
|
|
20776
|
+
this.chain,
|
|
20777
|
+
{ ...this.selection, offset: [x, y, z] },
|
|
20778
|
+
this
|
|
20779
|
+
);
|
|
20674
20780
|
}
|
|
20675
20781
|
};
|
|
20676
|
-
var
|
|
20782
|
+
var AxisRotation = class extends RelationExpression {
|
|
20677
20783
|
/** @internal */
|
|
20678
|
-
constructor(
|
|
20679
|
-
super(...
|
|
20680
|
-
|
|
20784
|
+
constructor(chain, selection, previous) {
|
|
20785
|
+
super(...(previous ?? chain).continuationArguments(), {
|
|
20786
|
+
kind: selection.offset ? "axisOffset" : selection.kind,
|
|
20787
|
+
pivot: selection
|
|
20788
|
+
});
|
|
20789
|
+
this.chain = chain;
|
|
20681
20790
|
this.selection = selection;
|
|
20682
|
-
this.spatialOperation = { kind: selection.kind, pivot: selection };
|
|
20683
20791
|
}
|
|
20684
|
-
|
|
20792
|
+
chain;
|
|
20685
20793
|
selection;
|
|
20686
20794
|
static {
|
|
20687
|
-
__name(this, "
|
|
20795
|
+
__name(this, "AxisRotation");
|
|
20688
20796
|
}
|
|
20689
20797
|
rotate(angle = 0) {
|
|
20690
|
-
return this.
|
|
20798
|
+
return this.chain.withRotation(this.selection, angle, this);
|
|
20799
|
+
}
|
|
20800
|
+
};
|
|
20801
|
+
var AxisChain = class extends AxisRotation {
|
|
20802
|
+
static {
|
|
20803
|
+
__name(this, "AxisChain");
|
|
20804
|
+
}
|
|
20805
|
+
axisOffset(x = 0, y = 0, z = 0) {
|
|
20806
|
+
assertFiniteVector("axisOffset", [x, y, z]);
|
|
20807
|
+
return new AxisRotation(
|
|
20808
|
+
this.chain,
|
|
20809
|
+
{ ...this.selection, offset: [x, y, z] },
|
|
20810
|
+
this
|
|
20811
|
+
);
|
|
20691
20812
|
}
|
|
20692
20813
|
};
|
|
20814
|
+
function selectedAxis(axis, offset2) {
|
|
20815
|
+
return composeTransforms(axis.transform, translation(offset2 ?? origin));
|
|
20816
|
+
}
|
|
20817
|
+
__name(selectedAxis, "selectedAxis");
|
|
20818
|
+
function offset(x = 0, y = 0, z = 0) {
|
|
20819
|
+
assertFiniteVector("offset", [x, y, z]);
|
|
20820
|
+
return new Transformation({ offset: [x, y, z] });
|
|
20821
|
+
}
|
|
20822
|
+
__name(offset, "offset");
|
|
20823
|
+
function rotate2(x = 0, y = 0, z = 0) {
|
|
20824
|
+
assertFiniteVector("rotate", [x, y, z]);
|
|
20825
|
+
return new Transformation({
|
|
20826
|
+
pivot: { kind: "pivot", point: origin, implicit: true },
|
|
20827
|
+
angles: [x, y, z]
|
|
20828
|
+
});
|
|
20829
|
+
}
|
|
20830
|
+
__name(rotate2, "rotate");
|
|
20831
|
+
function pivot([x = 0, y = 0, z = 0] = origin) {
|
|
20832
|
+
assertFiniteVector("pivot", [x, y, z]);
|
|
20833
|
+
return new PivotChain(new TransformationRotation(), {
|
|
20834
|
+
kind: "pivot",
|
|
20835
|
+
point: [x, y, z]
|
|
20836
|
+
});
|
|
20837
|
+
}
|
|
20838
|
+
__name(pivot, "pivot");
|
|
20839
|
+
function pivotVertex(id) {
|
|
20840
|
+
assertTopologyId("vertex", id);
|
|
20841
|
+
return new PivotChain(new TransformationRotation(), {
|
|
20842
|
+
kind: "pivotVertex",
|
|
20843
|
+
id
|
|
20844
|
+
});
|
|
20845
|
+
}
|
|
20846
|
+
__name(pivotVertex, "pivotVertex");
|
|
20847
|
+
function pivotPoint(point3) {
|
|
20848
|
+
return new PivotChain(new TransformationRotation(), {
|
|
20849
|
+
kind: "pivotPoint",
|
|
20850
|
+
point: rotationPointReference(point3)
|
|
20851
|
+
});
|
|
20852
|
+
}
|
|
20853
|
+
__name(pivotPoint, "pivotPoint");
|
|
20854
|
+
function axisEdge(id) {
|
|
20855
|
+
assertTopologyId("edge", id);
|
|
20856
|
+
return new AxisChain(new TransformationRotation(), {
|
|
20857
|
+
kind: "axisEdge",
|
|
20858
|
+
id
|
|
20859
|
+
});
|
|
20860
|
+
}
|
|
20861
|
+
__name(axisEdge, "axisEdge");
|
|
20862
|
+
function axisLine(axis) {
|
|
20863
|
+
return new AxisChain(new TransformationRotation(), {
|
|
20864
|
+
kind: "axisLine",
|
|
20865
|
+
axis: rotationAxisReference(axis)
|
|
20866
|
+
});
|
|
20867
|
+
}
|
|
20868
|
+
__name(axisLine, "axisLine");
|
|
20693
20869
|
var modelGeometry = /* @__PURE__ */ Symbol("modelGeometry");
|
|
20694
20870
|
var referenceBounds = /* @__PURE__ */ Symbol("referenceBounds");
|
|
20695
20871
|
var referenceBoundsParts = /* @__PURE__ */ Symbol("referenceBoundsParts");
|
|
20696
20872
|
var modelSnapshotQueries = /* @__PURE__ */ Symbol("modelSnapshotQueries");
|
|
20697
|
-
var
|
|
20873
|
+
var previewRelation = /* @__PURE__ */ Symbol("previewRelation");
|
|
20698
20874
|
var RelationObject = class _RelationObject {
|
|
20699
20875
|
static {
|
|
20700
20876
|
__name(this, "RelationObject");
|
|
20701
20877
|
}
|
|
20702
20878
|
nodeId;
|
|
20703
|
-
|
|
20879
|
+
placements;
|
|
20880
|
+
get constraints() {
|
|
20881
|
+
return this.placements.filter(
|
|
20882
|
+
(value) => value.kind !== "transformation"
|
|
20883
|
+
);
|
|
20884
|
+
}
|
|
20704
20885
|
constructor(init = {}) {
|
|
20705
20886
|
this.nodeId = init.nodeId ?? `node-${nextNodeId++}`;
|
|
20706
|
-
this.
|
|
20887
|
+
this.placements = [...init.placements ?? []];
|
|
20707
20888
|
valueTraces.set(this, {
|
|
20708
20889
|
sourceRefs: [...init.sourceRefs ?? []],
|
|
20709
20890
|
parameters: [...init.parameters ?? []]
|
|
@@ -20715,6 +20896,17 @@ var RelationObject = class _RelationObject {
|
|
|
20715
20896
|
get parameters() {
|
|
20716
20897
|
return valueTrace(this).parameters;
|
|
20717
20898
|
}
|
|
20899
|
+
edgeReference(_id) {
|
|
20900
|
+
throw new Error(
|
|
20901
|
+
"axisEdge() requires model topology. Use axisLine(lineRef) for a line reference."
|
|
20902
|
+
);
|
|
20903
|
+
}
|
|
20904
|
+
rotationAxis(pivot2) {
|
|
20905
|
+
return pivot2.kind === "axisLine" ? pivot2.axis : this.edgeReference(pivot2.id);
|
|
20906
|
+
}
|
|
20907
|
+
rotationPoint(pivot2) {
|
|
20908
|
+
return pivot2.kind === "pivot" ? pivot2.point : pivot2.kind === "pivotVertex" ? this.vertexPosition(pivot2.id) : pivot2.point.transform.position;
|
|
20909
|
+
}
|
|
20718
20910
|
vertexPosition(_id) {
|
|
20719
20911
|
throw new Error(
|
|
20720
20912
|
"pivotVertex() requires model topology, not a sketch reference frame. Use pivot([x, y, z]) instead."
|
|
@@ -20730,15 +20922,15 @@ var RelationObject = class _RelationObject {
|
|
|
20730
20922
|
} finally {
|
|
20731
20923
|
activeRelate = previous;
|
|
20732
20924
|
}
|
|
20733
|
-
const
|
|
20734
|
-
const stored =
|
|
20735
|
-
if (!(constraint instanceof Constraint))
|
|
20925
|
+
const relations = Array.isArray(built) ? built : [built];
|
|
20926
|
+
const stored = relations.map((constraint) => {
|
|
20927
|
+
if (!(constraint instanceof Constraint) && !(constraint instanceof Transformation))
|
|
20736
20928
|
throw new Error(
|
|
20737
|
-
"relate() requires a completed Constraint; finish pivot
|
|
20929
|
+
"relate() requires a completed Constraint or Transformation; finish the pivot or axis selector with rotate()."
|
|
20738
20930
|
);
|
|
20739
20931
|
return constraint.storeFor(this, original);
|
|
20740
20932
|
});
|
|
20741
|
-
this.
|
|
20933
|
+
this.placements.push(...stored);
|
|
20742
20934
|
return uniqueModels(stored.flatMap(constraintReferences));
|
|
20743
20935
|
}
|
|
20744
20936
|
[referenceBounds](reference, transform) {
|
|
@@ -20825,22 +21017,32 @@ var RelationObject = class _RelationObject {
|
|
|
20825
21017
|
arrow
|
|
20826
21018
|
};
|
|
20827
21019
|
}
|
|
20828
|
-
|
|
20829
|
-
return constraint.
|
|
20830
|
-
if (
|
|
20831
|
-
|
|
20832
|
-
|
|
20833
|
-
|
|
20834
|
-
|
|
21020
|
+
bodyActions(constraint, indices) {
|
|
21021
|
+
return constraint.actions.map((action) => {
|
|
21022
|
+
if ("offset" in action) return { offset: action.offset };
|
|
21023
|
+
const { pivot: pivot2, angles } = action;
|
|
21024
|
+
if (isAxisSelection(pivot2)) {
|
|
21025
|
+
const axis = this.rotationAxis(pivot2);
|
|
21026
|
+
return axis.model ? {
|
|
21027
|
+
body: indices.get(axis.model),
|
|
21028
|
+
axis: selectedAxis(axis, pivot2.offset),
|
|
21029
|
+
angle: angles * (axis.direction ?? 1)
|
|
20835
21030
|
} : {
|
|
20836
21031
|
local: axisRotation(
|
|
20837
|
-
|
|
20838
|
-
angles * (
|
|
21032
|
+
selectedAxis(axis, pivot2.offset),
|
|
21033
|
+
angles * (axis.direction ?? 1)
|
|
20839
21034
|
)
|
|
20840
21035
|
};
|
|
20841
21036
|
}
|
|
21037
|
+
if (pivot2.kind === "pivotPoint" && pivot2.point.model)
|
|
21038
|
+
return {
|
|
21039
|
+
body: indices.get(pivot2.point.model),
|
|
21040
|
+
point: pivot2.point.transform.position,
|
|
21041
|
+
rotation: rotationAround(origin, angles).quaternion,
|
|
21042
|
+
displacement: pivot2.offset ?? origin
|
|
21043
|
+
};
|
|
20842
21044
|
const frame = translation(
|
|
20843
|
-
|
|
21045
|
+
addVectors(this.rotationPoint(pivot2), pivot2.offset ?? origin)
|
|
20844
21046
|
);
|
|
20845
21047
|
return {
|
|
20846
21048
|
local: composeTransforms(
|
|
@@ -20851,90 +21053,329 @@ var RelationObject = class _RelationObject {
|
|
|
20851
21053
|
});
|
|
20852
21054
|
}
|
|
20853
21055
|
/** @internal */
|
|
20854
|
-
[
|
|
21056
|
+
[previewRelation](constraint, selection, preceding = [], original) {
|
|
21057
|
+
let placements = [...(original ?? this).placements];
|
|
21058
|
+
const index = placements.findIndex((value) => value.id === constraint?.id);
|
|
21059
|
+
if (index < 0) {
|
|
21060
|
+
placements.push(
|
|
21061
|
+
...preceding.map(
|
|
21062
|
+
(value) => value.storeFor(this, value.continuationArguments()[1].original)
|
|
21063
|
+
)
|
|
21064
|
+
);
|
|
21065
|
+
if (constraint) placements.push(constraint);
|
|
21066
|
+
} else if (constraint) {
|
|
21067
|
+
placements[index] = constraint;
|
|
21068
|
+
let end = index + 1;
|
|
21069
|
+
if (constraint.kind !== "transformation")
|
|
21070
|
+
while (end < placements.length && placements[end].kind !== "transformation")
|
|
21071
|
+
end++;
|
|
21072
|
+
placements = placements.slice(0, end);
|
|
21073
|
+
}
|
|
20855
21074
|
const owner = this.copyRelations({
|
|
20856
|
-
nodeId,
|
|
20857
|
-
|
|
21075
|
+
nodeId: this.nodeId,
|
|
21076
|
+
placements
|
|
20858
21077
|
});
|
|
20859
21078
|
const context = _RelationObject.createSolveContext([
|
|
20860
21079
|
owner,
|
|
20861
|
-
...selection
|
|
21080
|
+
...selection && selectionReference(selection.pivot)?.model ? [selectionReference(selection.pivot).model] : []
|
|
20862
21081
|
]);
|
|
20863
21082
|
return {
|
|
20864
21083
|
object: {
|
|
20865
|
-
nodeId,
|
|
21084
|
+
nodeId: this.nodeId,
|
|
20866
21085
|
compositionTransform: toTransform(owner.solvePose(context)),
|
|
20867
21086
|
constraints: owner.constraints.map(
|
|
20868
21087
|
(value) => owner.constraintSnapshot(value, context)
|
|
20869
|
-
)
|
|
21088
|
+
),
|
|
21089
|
+
transformations: owner.transformationSnapshots(context),
|
|
21090
|
+
relationStages: owner.relationStageSnapshots(context)
|
|
20870
21091
|
},
|
|
20871
|
-
spatial: selection ? owner.
|
|
21092
|
+
spatial: selection && constraint?.kind === "transformation" ? owner.relationSpatial(constraint, selection, context) : constraint?.kind === "transformation" && constraint.actions.at(-1) && "offset" in constraint.actions.at(-1) ? owner.transformationOffsetSpatial(constraint, context) : void 0
|
|
20872
21093
|
};
|
|
20873
21094
|
}
|
|
20874
|
-
|
|
21095
|
+
relationSpatial(constraint, selection, context, actionIndex) {
|
|
21096
|
+
context = this.placementStageContext(constraint, context);
|
|
20875
21097
|
const models = [...context.poses.keys()];
|
|
20876
|
-
const actions = this.
|
|
20877
|
-
|
|
20878
|
-
new Map(models.map((model, i) => [model, i]))
|
|
20879
|
-
);
|
|
20880
|
-
const stage = actions.length - (selection.kind === "rotate" ? 1 : 0);
|
|
21098
|
+
const actions = this.placementActions(constraint, context);
|
|
21099
|
+
const stage = actionIndex ?? (selection.kind === "rotate" ? constraint.actions.length - 1 - [...constraint.actions].reverse().findIndex((action) => "angles" in action) : actions.length);
|
|
20881
21100
|
const finalPose = this.solvePose(context);
|
|
20882
|
-
|
|
20883
|
-
|
|
20884
|
-
|
|
20885
|
-
|
|
20886
|
-
|
|
20887
|
-
|
|
20888
|
-
|
|
20889
|
-
|
|
20890
|
-
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
const pivot = selection.pivot;
|
|
21101
|
+
const following = this.followingActions(constraint, context);
|
|
21102
|
+
const before = beforeTransformations(
|
|
21103
|
+
beforeTransformations(
|
|
21104
|
+
finalPose,
|
|
21105
|
+
{ actions: following },
|
|
21106
|
+
models.map((model) => model.solvePose(context))
|
|
21107
|
+
),
|
|
21108
|
+
{
|
|
21109
|
+
actions: actions.slice(stage)
|
|
21110
|
+
},
|
|
21111
|
+
models.map((model) => model.solvePose(context))
|
|
21112
|
+
);
|
|
21113
|
+
const pivot2 = selection.pivot;
|
|
21114
|
+
const axis = isAxisSelection(pivot2) ? this.rotationAxis(pivot2) : void 0;
|
|
20897
21115
|
let frame;
|
|
20898
|
-
if (
|
|
21116
|
+
if (axis) {
|
|
20899
21117
|
frame = composeTransforms(
|
|
20900
|
-
|
|
20901
|
-
(
|
|
21118
|
+
axis.model ? axis.model.solvePose(context) : before,
|
|
21119
|
+
(axis.direction ?? 1) === 1 ? selectedAxis(axis, pivot2.offset) : composeTransforms(
|
|
21120
|
+
selectedAxis(axis, pivot2.offset),
|
|
21121
|
+
rotation([1, 0, 0, 0])
|
|
21122
|
+
)
|
|
20902
21123
|
);
|
|
21124
|
+
} else if (pivot2.kind === "pivotPoint" && pivot2.point.model) {
|
|
21125
|
+
const center = composeTransforms(
|
|
21126
|
+
pivot2.point.model.solvePose(context),
|
|
21127
|
+
pivot2.point.transform
|
|
21128
|
+
).position;
|
|
21129
|
+
frame = {
|
|
21130
|
+
position: addVectors(
|
|
21131
|
+
center,
|
|
21132
|
+
rotateVector(pivot2.offset ?? origin, before.quaternion)
|
|
21133
|
+
),
|
|
21134
|
+
quaternion: before.quaternion
|
|
21135
|
+
};
|
|
20903
21136
|
} else {
|
|
20904
21137
|
const local = translation(
|
|
20905
|
-
|
|
21138
|
+
addVectors(
|
|
21139
|
+
this.rotationPoint(pivot2),
|
|
21140
|
+
pivot2.offset ?? origin
|
|
21141
|
+
)
|
|
20906
21142
|
);
|
|
20907
21143
|
frame = composeTransforms(before, local);
|
|
20908
21144
|
}
|
|
20909
|
-
const
|
|
21145
|
+
const selected = constraint.actions[stage];
|
|
21146
|
+
const angles = selected && "angles" in selected ? selected.angles : origin;
|
|
20910
21147
|
const rotationVector = typeof angles === "number" ? [0, angles, 0] : angles;
|
|
21148
|
+
const poses = models.map((model) => model.solvePose(context));
|
|
21149
|
+
let actionPose = afterTransformations(
|
|
21150
|
+
before,
|
|
21151
|
+
{ actions: actions.slice(stage, stage + 1) },
|
|
21152
|
+
poses
|
|
21153
|
+
);
|
|
21154
|
+
const remainder = [...actions.slice(stage + 1), ...following];
|
|
21155
|
+
for (const action of remainder) {
|
|
21156
|
+
const next = afterTransformations(
|
|
21157
|
+
actionPose,
|
|
21158
|
+
{
|
|
21159
|
+
actions: [action]
|
|
21160
|
+
},
|
|
21161
|
+
poses
|
|
21162
|
+
);
|
|
21163
|
+
if ("body" in action)
|
|
21164
|
+
frame = composeTransforms(
|
|
21165
|
+
composeTransforms(next, invertTransform(actionPose)),
|
|
21166
|
+
frame
|
|
21167
|
+
);
|
|
21168
|
+
else if ("offset" in action) {
|
|
21169
|
+
frame = {
|
|
21170
|
+
...frame,
|
|
21171
|
+
position: addVectors(
|
|
21172
|
+
frame.position,
|
|
21173
|
+
addVectors(next.position, negateVector(actionPose.position))
|
|
21174
|
+
)
|
|
21175
|
+
};
|
|
21176
|
+
}
|
|
21177
|
+
actionPose = next;
|
|
21178
|
+
}
|
|
20911
21179
|
const localFrame = relativeTransform(frame, finalPose);
|
|
20912
21180
|
return {
|
|
20913
21181
|
nodeId: this.nodeId,
|
|
20914
21182
|
kind: selection.kind,
|
|
20915
21183
|
spatial: {
|
|
20916
21184
|
origin: localFrame.position,
|
|
20917
|
-
vector: selection.kind === "rotate" ? rotationVector :
|
|
21185
|
+
vector: selection.kind === "rotate" ? rotationVector : selection.kind === "pivotOffset" || selection.kind === "axisOffset" ? pivot2.offset ?? origin : pivot2.kind === "pivot" ? pivot2.point : origin,
|
|
20918
21186
|
frame: localFrame,
|
|
20919
21187
|
rotation: rotationVector,
|
|
20920
|
-
axisOnly:
|
|
21188
|
+
axisOnly: isAxisSelection(pivot2),
|
|
21189
|
+
reference: {
|
|
21190
|
+
...pivot2.kind === "axisEdge" || pivot2.kind === "pivotVertex" ? { kind: pivot2.kind, id: pivot2.id } : pivot2.kind === "axisLine" || pivot2.kind === "pivotPoint" ? {
|
|
21191
|
+
kind: pivot2.kind,
|
|
21192
|
+
nodeId: selectionReference(pivot2).model?.nodeId ?? this.nodeId,
|
|
21193
|
+
name: selectionReference(pivot2).name
|
|
21194
|
+
} : { kind: pivot2.kind, point: pivot2.point },
|
|
21195
|
+
offset: pivot2.offset ?? origin,
|
|
21196
|
+
offsetExplicit: pivot2.offset !== void 0,
|
|
21197
|
+
explicit: !pivot2.implicit,
|
|
21198
|
+
rotation: axis && (axis.direction ?? 1) !== 1 ? [0, -rotationVector[1], 0] : rotationVector,
|
|
21199
|
+
frame: axis && (axis.direction ?? 1) !== 1 ? composeTransforms(localFrame, rotation([1, 0, 0, 0])) : localFrame
|
|
21200
|
+
}
|
|
20921
21201
|
}
|
|
20922
21202
|
};
|
|
20923
21203
|
}
|
|
20924
|
-
|
|
21204
|
+
placementActions(value, context) {
|
|
21205
|
+
const indices = new Map(
|
|
21206
|
+
[...context.poses.keys()].map((model, i) => [model, i])
|
|
21207
|
+
);
|
|
21208
|
+
return this.bodyActions(value, indices).map(
|
|
21209
|
+
(action) => "offset" in action ? { offset: rotateVector(action.offset, context.frame.quaternion) } : action
|
|
21210
|
+
);
|
|
21211
|
+
}
|
|
21212
|
+
/** Pose at the end of this segment; later constraints have their own input pose. */
|
|
21213
|
+
placementStageContext(placement, context) {
|
|
21214
|
+
const index = this.placements.indexOf(placement);
|
|
21215
|
+
let end = index + 1;
|
|
21216
|
+
if (placement.kind !== "transformation")
|
|
21217
|
+
while (end < this.placements.length && this.placements[end].kind !== "transformation")
|
|
21218
|
+
end++;
|
|
21219
|
+
while (end < this.placements.length && this.placements[end].kind === "transformation")
|
|
21220
|
+
end++;
|
|
21221
|
+
if (end >= this.placements.length) return context;
|
|
21222
|
+
return transformSolveContext(
|
|
21223
|
+
_RelationObject.createSolveContext(
|
|
21224
|
+
[this],
|
|
21225
|
+
/* @__PURE__ */ new Map([[this, this.placements.slice(0, end)]])
|
|
21226
|
+
),
|
|
21227
|
+
context.frame
|
|
21228
|
+
);
|
|
21229
|
+
}
|
|
21230
|
+
followingActions(placement, context) {
|
|
21231
|
+
let start = this.placements.indexOf(placement) + 1;
|
|
21232
|
+
if (placement.kind !== "transformation")
|
|
21233
|
+
while (start < this.placements.length && this.placements[start].kind !== "transformation")
|
|
21234
|
+
start++;
|
|
21235
|
+
const values = [];
|
|
21236
|
+
while (start < this.placements.length && this.placements[start].kind === "transformation")
|
|
21237
|
+
values.push(this.placements[start++]);
|
|
21238
|
+
return values.flatMap((value) => this.placementActions(value, context));
|
|
21239
|
+
}
|
|
21240
|
+
relationStageSnapshots(context) {
|
|
21241
|
+
if (!this.placements.length) return void 0;
|
|
21242
|
+
const stages = [];
|
|
21243
|
+
let start = 0;
|
|
21244
|
+
while (start < this.placements.length) {
|
|
21245
|
+
let end = start;
|
|
21246
|
+
while (end < this.placements.length && this.placements[end].kind !== "transformation")
|
|
21247
|
+
end++;
|
|
21248
|
+
while (end < this.placements.length && this.placements[end].kind === "transformation")
|
|
21249
|
+
end++;
|
|
21250
|
+
const values = this.placements.slice(start, end);
|
|
21251
|
+
const stage = this.placementStageContext(values[0], context);
|
|
21252
|
+
stages.push({
|
|
21253
|
+
constraintIds: values.filter((value) => value.kind !== "transformation").map((value) => value.id),
|
|
21254
|
+
transformationIds: values.filter((value) => value.kind === "transformation").map((value) => value.id),
|
|
21255
|
+
compositionTransform: toTransform(this.solvePose(stage)),
|
|
21256
|
+
offsetFrame: toTransform(stage.frame)
|
|
21257
|
+
});
|
|
21258
|
+
start = end;
|
|
21259
|
+
}
|
|
21260
|
+
return stages;
|
|
21261
|
+
}
|
|
21262
|
+
transformationSnapshots(context) {
|
|
21263
|
+
const values = this.placements.filter(
|
|
21264
|
+
(value) => value.kind === "transformation"
|
|
21265
|
+
);
|
|
21266
|
+
if (!values.length) return void 0;
|
|
21267
|
+
return values.map(
|
|
21268
|
+
(value) => this.transformationSnapshot(
|
|
21269
|
+
value,
|
|
21270
|
+
this.placementStageContext(value, context)
|
|
21271
|
+
)
|
|
21272
|
+
);
|
|
21273
|
+
}
|
|
21274
|
+
followingReferenceFrame(frame, actions, context) {
|
|
21275
|
+
const models = [...context.poses.keys()];
|
|
21276
|
+
const poses = models.map((model) => model.solvePose(context));
|
|
21277
|
+
let pose = beforeTransformations(this.solvePose(context), { actions }, poses);
|
|
21278
|
+
for (const action of actions) {
|
|
21279
|
+
const next = afterTransformations(pose, { actions: [action] }, poses);
|
|
21280
|
+
if ("body" in action)
|
|
21281
|
+
frame = composeTransforms(
|
|
21282
|
+
composeTransforms(next, invertTransform(pose)),
|
|
21283
|
+
frame
|
|
21284
|
+
);
|
|
21285
|
+
pose = next;
|
|
21286
|
+
}
|
|
21287
|
+
return frame;
|
|
21288
|
+
}
|
|
21289
|
+
transformationSnapshot(value, context) {
|
|
21290
|
+
const models = [...context.poses.keys()];
|
|
21291
|
+
const actions = this.placementActions(value, context);
|
|
21292
|
+
const following = this.followingActions(value, context);
|
|
21293
|
+
const offsets = value.actions.flatMap((action, index) => {
|
|
21294
|
+
if (!("offset" in action)) return [];
|
|
21295
|
+
const frame = this.followingReferenceFrame(
|
|
21296
|
+
context.frame,
|
|
21297
|
+
[...actions.slice(index + 1), ...following],
|
|
21298
|
+
context
|
|
21299
|
+
);
|
|
21300
|
+
return [
|
|
21301
|
+
{
|
|
21302
|
+
value: action.offset,
|
|
21303
|
+
frame: toTransform(frame),
|
|
21304
|
+
sourceRefs: valueTrace(action).sourceRefs
|
|
21305
|
+
}
|
|
21306
|
+
];
|
|
21307
|
+
});
|
|
21308
|
+
const rotations = value.actions.flatMap(
|
|
21309
|
+
(action, index) => "pivot" in action ? [
|
|
21310
|
+
{
|
|
21311
|
+
spatial: this.relationSpatial(
|
|
21312
|
+
value,
|
|
21313
|
+
{ kind: "rotate", pivot: action.pivot },
|
|
21314
|
+
context,
|
|
21315
|
+
index
|
|
21316
|
+
).spatial,
|
|
21317
|
+
sourceRefs: valueTrace(action).sourceRefs
|
|
21318
|
+
}
|
|
21319
|
+
] : []
|
|
21320
|
+
);
|
|
21321
|
+
return {
|
|
21322
|
+
id: value.id,
|
|
21323
|
+
offsets,
|
|
21324
|
+
rotations,
|
|
21325
|
+
offsetFrame: toTransform(context.frame),
|
|
21326
|
+
sourceRefs: [...valueTrace(value).sourceRefs],
|
|
21327
|
+
parameters: [...valueTrace(value).parameters]
|
|
21328
|
+
};
|
|
21329
|
+
}
|
|
21330
|
+
transformationOffsetSpatial(value, context) {
|
|
21331
|
+
const offset2 = this.transformationSnapshot(value, context).offsets.at(-1);
|
|
21332
|
+
const local = relativeTransform(
|
|
21333
|
+
{ ...offset2.frame, position: this.solvePose(context).position },
|
|
21334
|
+
this.solvePose(context)
|
|
21335
|
+
);
|
|
21336
|
+
return {
|
|
21337
|
+
nodeId: this.nodeId,
|
|
21338
|
+
kind: "offset",
|
|
21339
|
+
spatial: { origin, vector: offset2.value, frame: local }
|
|
21340
|
+
};
|
|
21341
|
+
}
|
|
21342
|
+
static createSolveContext(roots2, overrides = /* @__PURE__ */ new Map()) {
|
|
20925
21343
|
const models = [];
|
|
20926
21344
|
const indices = /* @__PURE__ */ new Map();
|
|
20927
21345
|
const collect = /* @__PURE__ */ __name((model) => {
|
|
20928
21346
|
if (indices.has(model)) return;
|
|
20929
21347
|
indices.set(model, models.length);
|
|
20930
21348
|
models.push(model);
|
|
20931
|
-
model.
|
|
21349
|
+
(overrides.get(model) ?? model.placements).flatMap(constraintReferences).forEach(collect);
|
|
20932
21350
|
}, "collect");
|
|
20933
21351
|
roots2.forEach(collect);
|
|
21352
|
+
const programs = models.map((model) => {
|
|
21353
|
+
const placements = overrides.get(model) ?? model.placements;
|
|
21354
|
+
let last = placements.length - 1;
|
|
21355
|
+
while (last >= 0 && placements[last].kind === "transformation") last--;
|
|
21356
|
+
let start = last;
|
|
21357
|
+
while (start > 0 && placements[start - 1].kind !== "transformation")
|
|
21358
|
+
start--;
|
|
21359
|
+
const initial = start > 0 ? _RelationObject.createSolveContext(
|
|
21360
|
+
[model],
|
|
21361
|
+
new Map(overrides).set(model, placements.slice(0, start))
|
|
21362
|
+
).poses.get(model) : identityRigidTransform;
|
|
21363
|
+
return {
|
|
21364
|
+
initial,
|
|
21365
|
+
constraints: placements.slice(Math.max(0, start), last + 1).filter(
|
|
21366
|
+
(value) => value.kind !== "transformation"
|
|
21367
|
+
),
|
|
21368
|
+
transformations: placements.slice(last + 1).filter(
|
|
21369
|
+
(value) => value.kind === "transformation"
|
|
21370
|
+
).flatMap((value) => model.bodyActions(value, indices))
|
|
21371
|
+
};
|
|
21372
|
+
});
|
|
20934
21373
|
const poses = solveBodies2(
|
|
20935
|
-
models.map((model) => ({
|
|
21374
|
+
models.map((model, index) => ({
|
|
21375
|
+
initial: programs[index].initial,
|
|
21376
|
+
transformations: programs[index].transformations,
|
|
20936
21377
|
name: model.name,
|
|
20937
|
-
relations:
|
|
21378
|
+
relations: programs[index].constraints.map(
|
|
20938
21379
|
(constraint) => constraint.kind === "align" ? {
|
|
20939
21380
|
kind: "align",
|
|
20940
21381
|
id: constraint.id,
|
|
@@ -20947,9 +21388,7 @@ var RelationObject = class _RelationObject {
|
|
|
20947
21388
|
body: indices.get(constraint.target.model ?? model),
|
|
20948
21389
|
geometry: (constraint.target.model ?? model).alignmentGeometry(constraint.target),
|
|
20949
21390
|
transform: constraint.target.transform
|
|
20950
|
-
}
|
|
20951
|
-
offset: constraint.offset,
|
|
20952
|
-
rotations: model.bodyRotations(constraint, indices)
|
|
21391
|
+
}
|
|
20953
21392
|
} : {
|
|
20954
21393
|
kind: "on",
|
|
20955
21394
|
id: constraint.id,
|
|
@@ -20965,63 +21404,25 @@ var RelationObject = class _RelationObject {
|
|
|
20965
21404
|
body: indices.get(constraint.target.model ?? model),
|
|
20966
21405
|
transform: constraint.target.transform,
|
|
20967
21406
|
facing: constraint.target.bound.facing
|
|
20968
|
-
}
|
|
20969
|
-
offset: constraint.offset,
|
|
20970
|
-
rotations: model.bodyRotations(constraint, indices)
|
|
21407
|
+
}
|
|
20971
21408
|
}
|
|
20972
21409
|
)
|
|
20973
21410
|
}))
|
|
20974
21411
|
);
|
|
20975
21412
|
return {
|
|
20976
|
-
poses: new Map(models.map((model, index) => [model, poses[index]]))
|
|
21413
|
+
poses: new Map(models.map((model, index) => [model, poses[index]])),
|
|
21414
|
+
frame: identityRigidTransform
|
|
20977
21415
|
};
|
|
20978
21416
|
}
|
|
20979
21417
|
constraintSnapshot(constraint, context) {
|
|
20980
|
-
const lastRotation = constraint.rotations.at(-1);
|
|
20981
|
-
const rotationSpatial = lastRotation ? this.constraintSpatial(
|
|
20982
|
-
constraint,
|
|
20983
|
-
{ kind: "rotate", pivot: lastRotation.pivot },
|
|
20984
|
-
context
|
|
20985
|
-
).spatial : void 0;
|
|
20986
21418
|
const source = constraint.source.model ?? this;
|
|
20987
21419
|
const target = constraint.target.model ?? this;
|
|
20988
|
-
const
|
|
20989
|
-
const
|
|
20990
|
-
|
|
20991
|
-
new Map(models.map((model, i) => [model, i]))
|
|
20992
|
-
);
|
|
20993
|
-
let before = this.solvePose(context);
|
|
20994
|
-
for (const action of [...actions].reverse()) {
|
|
20995
|
-
before = "local" in action ? composeTransforms(before, invertTransform(action.local)) : composeTransforms(
|
|
20996
|
-
axisRotation(
|
|
20997
|
-
composeTransforms(
|
|
20998
|
-
models[action.body].solvePose(context),
|
|
20999
|
-
action.axis
|
|
21000
|
-
),
|
|
21001
|
-
-action.angle
|
|
21002
|
-
),
|
|
21003
|
-
before
|
|
21004
|
-
);
|
|
21005
|
-
}
|
|
21006
|
-
const sourcePose = source === this ? before : source.solvePose(context);
|
|
21007
|
-
const targetPose = target === this ? before : target.solvePose(context);
|
|
21008
|
-
let offsetFrame = composeTransforms(
|
|
21009
|
-
targetPose,
|
|
21420
|
+
const sourcePose = source.solvePose(context);
|
|
21421
|
+
const contactFrame = composeTransforms(
|
|
21422
|
+
target.solvePose(context),
|
|
21010
21423
|
constraint.target.transform
|
|
21011
21424
|
);
|
|
21012
21425
|
if (constraint.kind === "align") {
|
|
21013
|
-
for (const action of actions)
|
|
21014
|
-
if ("body" in action)
|
|
21015
|
-
offsetFrame = composeTransforms(
|
|
21016
|
-
axisRotation(
|
|
21017
|
-
composeTransforms(
|
|
21018
|
-
models[action.body].solvePose(context),
|
|
21019
|
-
action.axis
|
|
21020
|
-
),
|
|
21021
|
-
action.angle
|
|
21022
|
-
),
|
|
21023
|
-
offsetFrame
|
|
21024
|
-
);
|
|
21025
21426
|
return {
|
|
21026
21427
|
id: constraint.id,
|
|
21027
21428
|
kind: "align",
|
|
@@ -21029,16 +21430,12 @@ var RelationObject = class _RelationObject {
|
|
|
21029
21430
|
target: anchorSnapshot(target, constraint.target),
|
|
21030
21431
|
sourceElement: source.relationElement(constraint.source),
|
|
21031
21432
|
targetElement: target.relationElement(constraint.target),
|
|
21032
|
-
offsetDirection: 1,
|
|
21033
|
-
offset: constraint.offset ?? origin,
|
|
21034
|
-
offsetFrame: toTransform(offsetFrame),
|
|
21035
|
-
rotation: rotationSpatial,
|
|
21036
21433
|
sourceRefs: [...valueTrace(constraint).sourceRefs],
|
|
21037
21434
|
parameters: [...valueTrace(constraint).parameters]
|
|
21038
21435
|
};
|
|
21039
21436
|
}
|
|
21040
21437
|
const orientation = composeTransforms(
|
|
21041
|
-
invertTransform(rotation(
|
|
21438
|
+
invertTransform(rotation(contactFrame.quaternion)),
|
|
21042
21439
|
rotation(sourcePose.quaternion)
|
|
21043
21440
|
).quaternion;
|
|
21044
21441
|
const bounds = source[referenceBounds](
|
|
@@ -21054,9 +21451,9 @@ var RelationObject = class _RelationObject {
|
|
|
21054
21451
|
{
|
|
21055
21452
|
position: addVectors(
|
|
21056
21453
|
sourcePose.position,
|
|
21057
|
-
rotateVector(center,
|
|
21454
|
+
rotateVector(center, contactFrame.quaternion)
|
|
21058
21455
|
),
|
|
21059
|
-
quaternion:
|
|
21456
|
+
quaternion: contactFrame.quaternion
|
|
21060
21457
|
},
|
|
21061
21458
|
sourcePose
|
|
21062
21459
|
);
|
|
@@ -21065,19 +21462,6 @@ var RelationObject = class _RelationObject {
|
|
|
21065
21462
|
bounds[1][1] - bounds[0][1],
|
|
21066
21463
|
bounds[1][2] - bounds[0][2]
|
|
21067
21464
|
];
|
|
21068
|
-
for (const action of actions) {
|
|
21069
|
-
if ("body" in action)
|
|
21070
|
-
offsetFrame = composeTransforms(
|
|
21071
|
-
axisRotation(
|
|
21072
|
-
composeTransforms(
|
|
21073
|
-
models[action.body].solvePose(context),
|
|
21074
|
-
action.axis
|
|
21075
|
-
),
|
|
21076
|
-
action.angle
|
|
21077
|
-
),
|
|
21078
|
-
offsetFrame
|
|
21079
|
-
);
|
|
21080
|
-
}
|
|
21081
21465
|
return {
|
|
21082
21466
|
id: constraint.id,
|
|
21083
21467
|
kind: constraint.kind,
|
|
@@ -21111,10 +21495,6 @@ var RelationObject = class _RelationObject {
|
|
|
21111
21495
|
transform: toTransform(constraint.target.transform),
|
|
21112
21496
|
bound: constraint.target.bound
|
|
21113
21497
|
},
|
|
21114
|
-
offsetDirection: source === this ? 1 : -1,
|
|
21115
|
-
offset: constraint.offset ?? origin,
|
|
21116
|
-
offsetFrame: toTransform(offsetFrame),
|
|
21117
|
-
rotation: rotationSpatial,
|
|
21118
21498
|
sourceRefs: [...valueTrace(constraint).sourceRefs],
|
|
21119
21499
|
parameters: [...valueTrace(constraint).parameters]
|
|
21120
21500
|
};
|
|
@@ -21130,7 +21510,7 @@ var SketchFrame = class _SketchFrame extends RelationObject {
|
|
|
21130
21510
|
operation = storedOperation("sketch");
|
|
21131
21511
|
constructor(source, init = {}) {
|
|
21132
21512
|
super({
|
|
21133
|
-
|
|
21513
|
+
placements: source?.placements,
|
|
21134
21514
|
sourceRefs: source?.sourceRefs,
|
|
21135
21515
|
parameters: source?.parameters,
|
|
21136
21516
|
...init
|
|
@@ -21147,7 +21527,7 @@ var SketchFrame = class _SketchFrame extends RelationObject {
|
|
|
21147
21527
|
relatedObjects() {
|
|
21148
21528
|
return [
|
|
21149
21529
|
...this.source ? [this.source] : [],
|
|
21150
|
-
...this.
|
|
21530
|
+
...this.placements.flatMap(constraintReferences)
|
|
21151
21531
|
];
|
|
21152
21532
|
}
|
|
21153
21533
|
attachOperationTrace(siteId, execution, order, sourceRef, outputIndex = 0) {
|
|
@@ -21198,7 +21578,7 @@ var SketchFrame = class _SketchFrame extends RelationObject {
|
|
|
21198
21578
|
return related;
|
|
21199
21579
|
}
|
|
21200
21580
|
face(region) {
|
|
21201
|
-
return sketchFaceModel(region, this.
|
|
21581
|
+
return sketchFaceModel(region, this.placements, this);
|
|
21202
21582
|
}
|
|
21203
21583
|
snapshot() {
|
|
21204
21584
|
const context = RelationObject.createSolveContext([this]);
|
|
@@ -21207,7 +21587,9 @@ var SketchFrame = class _SketchFrame extends RelationObject {
|
|
|
21207
21587
|
compositionTransform: toTransform(this.solvePose(context)),
|
|
21208
21588
|
constraints: this.constraints.map(
|
|
21209
21589
|
(constraint) => this.constraintSnapshot(constraint, context)
|
|
21210
|
-
)
|
|
21590
|
+
),
|
|
21591
|
+
transformations: this.transformationSnapshots(context),
|
|
21592
|
+
relationStages: this.relationStageSnapshots(context)
|
|
21211
21593
|
};
|
|
21212
21594
|
}
|
|
21213
21595
|
/** Related finite models, expressed in this sketch's local editing plane. */
|
|
@@ -21471,9 +21853,9 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21471
21853
|
);
|
|
21472
21854
|
}
|
|
21473
21855
|
originOffset(dx = 0, dy = 0, dz = 0) {
|
|
21474
|
-
const
|
|
21475
|
-
assertFiniteVector("originOffset",
|
|
21476
|
-
return this.withOrigin(
|
|
21856
|
+
const offset2 = [dx, dy, dz];
|
|
21857
|
+
assertFiniteVector("originOffset", offset2);
|
|
21858
|
+
return this.withOrigin(offset2, { kind: "originOffset" });
|
|
21477
21859
|
}
|
|
21478
21860
|
originPoint(point3) {
|
|
21479
21861
|
const reference = anchorReference(point3);
|
|
@@ -21499,8 +21881,8 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21499
21881
|
const position2 = this.elements.center.transform.position;
|
|
21500
21882
|
return this.withOrigin(position2, { kind: "originCenter" });
|
|
21501
21883
|
}
|
|
21502
|
-
withOrigin(
|
|
21503
|
-
const transform = translation(negateVector(
|
|
21884
|
+
withOrigin(offset2, selection) {
|
|
21885
|
+
const transform = translation(negateVector(offset2));
|
|
21504
21886
|
const operation = storedOperation(selection.kind, [
|
|
21505
21887
|
{ model: this, role: "source", index: 0 }
|
|
21506
21888
|
]);
|
|
@@ -21510,7 +21892,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21510
21892
|
role: "reference",
|
|
21511
21893
|
index: 0
|
|
21512
21894
|
});
|
|
21513
|
-
operation.spatial = { origin, vector:
|
|
21895
|
+
operation.spatial = { origin, vector: offset2 };
|
|
21514
21896
|
if (selection.kind === "originVertex") {
|
|
21515
21897
|
operation.selections.push({
|
|
21516
21898
|
kind: "vertex",
|
|
@@ -21539,7 +21921,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21539
21921
|
transformElement(element, transform)
|
|
21540
21922
|
])
|
|
21541
21923
|
),
|
|
21542
|
-
|
|
21924
|
+
placements: this.mapConstraintGeometry(
|
|
21543
21925
|
(element) => transformElement(element, transform),
|
|
21544
21926
|
(point3) => composeTransforms(transform, translation(point3)).position
|
|
21545
21927
|
)
|
|
@@ -21575,15 +21957,37 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21575
21957
|
}
|
|
21576
21958
|
mapConstraintGeometry(mapElement, mapPoint) {
|
|
21577
21959
|
const mapReference = /* @__PURE__ */ __name((reference) => reference.model ? reference : { ...reference, ...mapElement(reference) }, "mapReference");
|
|
21578
|
-
|
|
21960
|
+
const zero = mapPoint(origin);
|
|
21961
|
+
const mapVector = /* @__PURE__ */ __name((vector2) => mapPoint(vector2).map(
|
|
21962
|
+
(value, index) => value - zero[index]
|
|
21963
|
+
), "mapVector");
|
|
21964
|
+
const scale3 = Math.hypot(...mapVector([1, 0, 0]));
|
|
21965
|
+
return this.placements.map((constraint) => {
|
|
21579
21966
|
const mapped = {
|
|
21580
21967
|
...constraint,
|
|
21581
|
-
|
|
21582
|
-
|
|
21583
|
-
|
|
21584
|
-
|
|
21585
|
-
|
|
21586
|
-
|
|
21968
|
+
...constraint.kind === "transformation" ? {} : {
|
|
21969
|
+
source: mapReference(constraint.source),
|
|
21970
|
+
target: mapReference(constraint.target)
|
|
21971
|
+
},
|
|
21972
|
+
...constraint.kind === "transformation" ? {
|
|
21973
|
+
actions: constraint.actions.map((action) => {
|
|
21974
|
+
if ("offset" in action) return action;
|
|
21975
|
+
const mappedAction = {
|
|
21976
|
+
...action,
|
|
21977
|
+
pivot: action.pivot.kind === "pivot" ? { ...action.pivot, point: mapPoint(action.pivot.point) } : mapSelectionReference(action.pivot, mapReference)
|
|
21978
|
+
};
|
|
21979
|
+
if (action.pivot.offset) {
|
|
21980
|
+
mappedAction.pivot = {
|
|
21981
|
+
...mappedAction.pivot,
|
|
21982
|
+
offset: isAxisSelection(action.pivot) ? selectionReference(action.pivot)?.model ? action.pivot.offset : action.pivot.offset.map(
|
|
21983
|
+
(value) => value * scale3
|
|
21984
|
+
) : mapVector(action.pivot.offset)
|
|
21985
|
+
};
|
|
21986
|
+
}
|
|
21987
|
+
valueTraces.set(mappedAction, valueTrace(action));
|
|
21988
|
+
return mappedAction;
|
|
21989
|
+
})
|
|
21990
|
+
} : {}
|
|
21587
21991
|
};
|
|
21588
21992
|
valueTraces.set(mapped, valueTrace(constraint));
|
|
21589
21993
|
return mapped;
|
|
@@ -21614,7 +22018,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21614
22018
|
{
|
|
21615
22019
|
geometryAnchor: scaleElement(this.geometryAnchor, factor),
|
|
21616
22020
|
elements: scaleElements(this.elements, factor),
|
|
21617
|
-
|
|
22021
|
+
placements: this.mapConstraintGeometry(
|
|
21618
22022
|
(element) => scaleElement(element, factor),
|
|
21619
22023
|
(point3) => scaleFrame(translation(point3), factor).position
|
|
21620
22024
|
)
|
|
@@ -21650,7 +22054,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21650
22054
|
name: "Extrude",
|
|
21651
22055
|
geometry,
|
|
21652
22056
|
material: this.materialSnapshot,
|
|
21653
|
-
|
|
22057
|
+
placements: this.placements,
|
|
21654
22058
|
sourceRefs: this.sourceRefs,
|
|
21655
22059
|
parameters: this.allParameters(),
|
|
21656
22060
|
meshTolerance: this.meshTolerance,
|
|
@@ -21797,7 +22201,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21797
22201
|
return [
|
|
21798
22202
|
...this.children,
|
|
21799
22203
|
...this.operation.inputs.map((input) => input.model),
|
|
21800
|
-
...this.
|
|
22204
|
+
...this.placements.flatMap(constraintReferences)
|
|
21801
22205
|
];
|
|
21802
22206
|
}
|
|
21803
22207
|
/** @internal */
|
|
@@ -21813,7 +22217,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21813
22217
|
);
|
|
21814
22218
|
const parameters = uniqueParameters([
|
|
21815
22219
|
...this.parameters,
|
|
21816
|
-
...this.
|
|
22220
|
+
...this.placements.flatMap(
|
|
21817
22221
|
(constraint) => valueTrace(constraint).parameters
|
|
21818
22222
|
)
|
|
21819
22223
|
]);
|
|
@@ -21825,6 +22229,8 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21825
22229
|
compositionTransform: toTransform(pose),
|
|
21826
22230
|
transform: toTransform(inComposition ? pose : identityRigidTransform),
|
|
21827
22231
|
constraints,
|
|
22232
|
+
transformations: this.transformationSnapshots(solveContext),
|
|
22233
|
+
relationStages: this.relationStageSnapshots(solveContext),
|
|
21828
22234
|
origin,
|
|
21829
22235
|
elements: snapshotElements({
|
|
21830
22236
|
...this.elements,
|
|
@@ -21919,7 +22325,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21919
22325
|
name: "Loft",
|
|
21920
22326
|
geometry,
|
|
21921
22327
|
material: this.materialSnapshot,
|
|
21922
|
-
|
|
22328
|
+
placements: this.placements,
|
|
21923
22329
|
sourceRefs: inputs.flatMap((input) => input.sourceRefs),
|
|
21924
22330
|
parameters: uniqueParameters(
|
|
21925
22331
|
inputs.flatMap((input) => input.allParameters())
|
|
@@ -21947,7 +22353,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21947
22353
|
geometry: evaluation.geometry,
|
|
21948
22354
|
name: this.name,
|
|
21949
22355
|
material: this.materialSnapshot,
|
|
21950
|
-
|
|
22356
|
+
placements: this.placements,
|
|
21951
22357
|
sourceRefs: [this, ...others].flatMap((model) => model.sourceRefs),
|
|
21952
22358
|
parameters: uniqueParameters(
|
|
21953
22359
|
[this, ...others].flatMap((model) => model.allParameters())
|
|
@@ -22065,7 +22471,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22065
22471
|
allParameters() {
|
|
22066
22472
|
return uniqueParameters([
|
|
22067
22473
|
...this.parameters,
|
|
22068
|
-
...this.
|
|
22474
|
+
...this.placements.flatMap(
|
|
22069
22475
|
(constraint) => valueTrace(constraint).parameters
|
|
22070
22476
|
)
|
|
22071
22477
|
]);
|
|
@@ -22197,19 +22603,22 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22197
22603
|
} : reference
|
|
22198
22604
|
);
|
|
22199
22605
|
}
|
|
22606
|
+
edgeReference(id) {
|
|
22607
|
+
return { ...rotationAxisReference(this.edge(id)), model: void 0 };
|
|
22608
|
+
}
|
|
22200
22609
|
vertexPosition(id) {
|
|
22201
22610
|
return anchorReference(this.vertex(id)).transform.position;
|
|
22202
22611
|
}
|
|
22203
22612
|
copyRelations(init) {
|
|
22204
22613
|
return this.copy(init, this.operation);
|
|
22205
22614
|
}
|
|
22206
|
-
/** Fix the assembly frame once
|
|
22615
|
+
/** Fix the assembly frame once in the first member's solved local coordinates. */
|
|
22207
22616
|
static createAssembly(children) {
|
|
22208
22617
|
const context = _ModelObject.createSolveContext(children);
|
|
22209
|
-
|
|
22210
|
-
|
|
22211
|
-
|
|
22212
|
-
|
|
22618
|
+
return children.length ? transformSolveContext(
|
|
22619
|
+
context,
|
|
22620
|
+
invertTransform(children[0].solvePose(context))
|
|
22621
|
+
) : context;
|
|
22213
22622
|
}
|
|
22214
22623
|
requireGeometry() {
|
|
22215
22624
|
if (!this.geometry) {
|
|
@@ -22279,7 +22688,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22279
22688
|
material: this.materialSnapshot,
|
|
22280
22689
|
children: this.children,
|
|
22281
22690
|
assembly: this.assembly,
|
|
22282
|
-
|
|
22691
|
+
placements: this.placements,
|
|
22283
22692
|
elements: this.elements,
|
|
22284
22693
|
sourceRefs: this.sourceRefs,
|
|
22285
22694
|
parameters: this.parameters,
|
|
@@ -22815,19 +23224,32 @@ function isConstraint(value) {
|
|
|
22815
23224
|
return value instanceof Constraint;
|
|
22816
23225
|
}
|
|
22817
23226
|
__name(isConstraint, "isConstraint");
|
|
22818
|
-
function
|
|
22819
|
-
return value instanceof
|
|
22820
|
-
}
|
|
22821
|
-
__name(
|
|
22822
|
-
function
|
|
22823
|
-
return value.preview();
|
|
23227
|
+
function isRelationExpression(value) {
|
|
23228
|
+
return value instanceof RelationExpression;
|
|
23229
|
+
}
|
|
23230
|
+
__name(isRelationExpression, "isRelationExpression");
|
|
23231
|
+
function relationPreview(value, preceding = []) {
|
|
23232
|
+
return value.preview(preceding);
|
|
23233
|
+
}
|
|
23234
|
+
__name(relationPreview, "relationPreview");
|
|
23235
|
+
function currentRelationSelf() {
|
|
23236
|
+
return activeRelate?.self;
|
|
23237
|
+
}
|
|
23238
|
+
__name(currentRelationSelf, "currentRelationSelf");
|
|
23239
|
+
function relationSelectionPreview(self, preceding, context) {
|
|
23240
|
+
return self[previewRelation](
|
|
23241
|
+
void 0,
|
|
23242
|
+
void 0,
|
|
23243
|
+
preceding,
|
|
23244
|
+
(preceding[0] ?? context)?.continuationArguments()[1]?.original
|
|
23245
|
+
);
|
|
22824
23246
|
}
|
|
22825
|
-
__name(
|
|
22826
|
-
function
|
|
23247
|
+
__name(relationSelectionPreview, "relationSelectionPreview");
|
|
23248
|
+
function instrumentRelation(constraint, sourceRef, parameters) {
|
|
22827
23249
|
constraint.attachSource(sourceRef);
|
|
22828
23250
|
constraint.attachParameters(parameters);
|
|
22829
23251
|
}
|
|
22830
|
-
__name(
|
|
23252
|
+
__name(instrumentRelation, "instrumentRelation");
|
|
22831
23253
|
function instrumentModelOperation(object, instrumentation) {
|
|
22832
23254
|
object.attachSource(instrumentation.sourceRef);
|
|
22833
23255
|
object.attachParameters(instrumentation.parameters);
|
|
@@ -22840,10 +23262,10 @@ function instrumentModelOperation(object, instrumentation) {
|
|
|
22840
23262
|
);
|
|
22841
23263
|
}
|
|
22842
23264
|
__name(instrumentModelOperation, "instrumentModelOperation");
|
|
22843
|
-
function
|
|
23265
|
+
function relationTraceReference(constraint) {
|
|
22844
23266
|
return constraint.traceReference();
|
|
22845
23267
|
}
|
|
22846
|
-
__name(
|
|
23268
|
+
__name(relationTraceReference, "relationTraceReference");
|
|
22847
23269
|
function modelObjectRuntimeInfo(object) {
|
|
22848
23270
|
return {
|
|
22849
23271
|
nodeId: object.nodeId,
|
|
@@ -22970,7 +23392,7 @@ function planModelSnapshotQueries(objects) {
|
|
|
22970
23392
|
sourceRef,
|
|
22971
23393
|
weight: (1 + (input.geometry.topology?.edges.ids.length ?? 0) + (input.geometry.topology?.surfaces.ids.length ?? 0)) * queries.length,
|
|
22972
23394
|
encode: /* @__PURE__ */ __name(() => encodeKernelArtifact(id, input.geometry), "encode"),
|
|
22973
|
-
accept: /* @__PURE__ */ __name((query, value) => snapshotQuery.accept(query.key, value), "accept")
|
|
23395
|
+
accept: /* @__PURE__ */ __name((query, value, milliseconds) => snapshotQuery.accept(query.key, value, milliseconds), "accept")
|
|
22974
23396
|
}));
|
|
22975
23397
|
}
|
|
22976
23398
|
__name(planModelSnapshotQueries, "planModelSnapshotQueries");
|
|
@@ -22984,7 +23406,9 @@ function executeSnapshotQueryBatch(id, bytes, queries, checkCancelled, onResult,
|
|
|
22984
23406
|
onRestore?.(performance.now() - started);
|
|
22985
23407
|
for (const query of queries) {
|
|
22986
23408
|
checkCancelled();
|
|
22987
|
-
|
|
23409
|
+
const started2 = performance.now();
|
|
23410
|
+
const value = computeSnapshotQuery(geometry, query);
|
|
23411
|
+
onResult(query, value, performance.now() - started2);
|
|
22988
23412
|
}
|
|
22989
23413
|
} finally {
|
|
22990
23414
|
geometry.shape.delete();
|
|
@@ -23045,7 +23469,14 @@ function retainModelGeometry(objects) {
|
|
|
23045
23469
|
}
|
|
23046
23470
|
__name(retainModelGeometry, "retainModelGeometry");
|
|
23047
23471
|
var authoringApi = Object.freeze({
|
|
23048
|
-
|
|
23472
|
+
offset,
|
|
23473
|
+
rotate: rotate2,
|
|
23474
|
+
pivot,
|
|
23475
|
+
pivotVertex,
|
|
23476
|
+
pivotPoint,
|
|
23477
|
+
axisEdge,
|
|
23478
|
+
axisLine,
|
|
23479
|
+
cache,
|
|
23049
23480
|
font,
|
|
23050
23481
|
googleFont,
|
|
23051
23482
|
text,
|
|
@@ -23124,7 +23555,10 @@ function disposeModelGeometryValue(geometry) {
|
|
|
23124
23555
|
__name(disposeModelGeometryValue, "disposeModelGeometryValue");
|
|
23125
23556
|
var kernelShape = cachedArtifact(
|
|
23126
23557
|
(_operation, _arguments, _inputs, compute) => compute(),
|
|
23127
|
-
{
|
|
23558
|
+
{
|
|
23559
|
+
key: /* @__PURE__ */ __name((operation, arguments_, inputs) => kernelOperationKey(`kernel-shape:${operation}`, arguments_, inputs), "key"),
|
|
23560
|
+
lifecycle: shapeLifecycle
|
|
23561
|
+
}
|
|
23128
23562
|
);
|
|
23129
23563
|
function evaluateKernelShape(operation, arguments_, inputs, compute) {
|
|
23130
23564
|
return kernelShape(
|
|
@@ -23143,7 +23577,10 @@ var evaluateModelGeometry = cachedArtifact(
|
|
|
23143
23577
|
referenceBasis: result.referenceBasis
|
|
23144
23578
|
};
|
|
23145
23579
|
},
|
|
23146
|
-
{
|
|
23580
|
+
{
|
|
23581
|
+
key: /* @__PURE__ */ __name((operation, arguments_, inputs) => kernelOperationKey(`model-geometry:${operation}`, arguments_, inputs), "key"),
|
|
23582
|
+
lifecycle: modelGeometryLifecycle
|
|
23583
|
+
}
|
|
23147
23584
|
);
|
|
23148
23585
|
function createModelGeometryValue(shape, topology) {
|
|
23149
23586
|
try {
|
|
@@ -23167,15 +23604,15 @@ function evaluateSolidGeometry(operation, arguments_, inputs, compute) {
|
|
|
23167
23604
|
);
|
|
23168
23605
|
}
|
|
23169
23606
|
__name(evaluateSolidGeometry, "evaluateSolidGeometry");
|
|
23170
|
-
function renderMesh(artifact, shape,
|
|
23171
|
-
const
|
|
23172
|
-
if (
|
|
23173
|
-
return
|
|
23607
|
+
function renderMesh(artifact, shape, cache2, tolerance2, topology) {
|
|
23608
|
+
const cached = cache2.get(shape);
|
|
23609
|
+
if (cached) {
|
|
23610
|
+
return cached;
|
|
23174
23611
|
}
|
|
23175
23612
|
const mesh = evaluateSnapshotQuery(
|
|
23176
23613
|
meshQuery(artifact, shape, tolerance2, topology)
|
|
23177
23614
|
);
|
|
23178
|
-
|
|
23615
|
+
cache2.set(shape, mesh);
|
|
23179
23616
|
return mesh;
|
|
23180
23617
|
}
|
|
23181
23618
|
__name(renderMesh, "renderMesh");
|
|
@@ -23211,7 +23648,7 @@ function meshUVs(shape, vertexCount) {
|
|
|
23211
23648
|
const faces = shape.faces;
|
|
23212
23649
|
const location = new (getOC12()).TopLoc_Location();
|
|
23213
23650
|
const uvs = new Float32Array(vertexCount * 2);
|
|
23214
|
-
let
|
|
23651
|
+
let offset2 = 0;
|
|
23215
23652
|
try {
|
|
23216
23653
|
for (const face of faces) {
|
|
23217
23654
|
const triangulation = getOC12().BRep_Tool.Triangulation(
|
|
@@ -23229,8 +23666,8 @@ function meshUVs(shape, vertexCount) {
|
|
|
23229
23666
|
const uv = triangulation.UVNode(index + 1);
|
|
23230
23667
|
try {
|
|
23231
23668
|
const u8 = uv.X(), v = uv.Y();
|
|
23232
|
-
uvs[(
|
|
23233
|
-
uvs[(
|
|
23669
|
+
uvs[(offset2 + index) * 2] = u8;
|
|
23670
|
+
uvs[(offset2 + index) * 2 + 1] = v;
|
|
23234
23671
|
minU = Math.min(minU, u8);
|
|
23235
23672
|
maxU = Math.max(maxU, u8);
|
|
23236
23673
|
minV = Math.min(minV, v);
|
|
@@ -23240,11 +23677,11 @@ function meshUVs(shape, vertexCount) {
|
|
|
23240
23677
|
}
|
|
23241
23678
|
}
|
|
23242
23679
|
for (let index = 0; index < count; index++) {
|
|
23243
|
-
const base = (
|
|
23680
|
+
const base = (offset2 + index) * 2;
|
|
23244
23681
|
uvs[base] = maxU === minU ? 0 : (uvs[base] - minU) / (maxU - minU);
|
|
23245
23682
|
uvs[base + 1] = maxV === minV ? 0 : (uvs[base + 1] - minV) / (maxV - minV);
|
|
23246
23683
|
}
|
|
23247
|
-
|
|
23684
|
+
offset2 += count;
|
|
23248
23685
|
} finally {
|
|
23249
23686
|
triangulation.delete();
|
|
23250
23687
|
}
|
|
@@ -23256,7 +23693,7 @@ function meshUVs(shape, vertexCount) {
|
|
|
23256
23693
|
}
|
|
23257
23694
|
}
|
|
23258
23695
|
__name(meshUVs, "meshUVs");
|
|
23259
|
-
function sketchFaceModel(region,
|
|
23696
|
+
function sketchFaceModel(region, placements, source) {
|
|
23260
23697
|
const curves = [region.outer, ...region.holes].map(
|
|
23261
23698
|
(loop) => loop.map(
|
|
23262
23699
|
(curve) => curve.kind === "line" ? ["line", curve.points] : curve.kind === "circle" ? ["circle", curve.center, curve.radius] : ["arc", curve.center, curve.radius, curve.start, curve.sweep]
|
|
@@ -23272,7 +23709,7 @@ function sketchFaceModel(region, constraints, source) {
|
|
|
23272
23709
|
return ModelObject.create({
|
|
23273
23710
|
kind: "face",
|
|
23274
23711
|
name: "Sketch face",
|
|
23275
|
-
|
|
23712
|
+
placements,
|
|
23276
23713
|
geometry,
|
|
23277
23714
|
geometryAnchor: plane,
|
|
23278
23715
|
elements: { plane },
|
|
@@ -23411,10 +23848,9 @@ function solidElements(bounds) {
|
|
|
23411
23848
|
__name(solidElements, "solidElements");
|
|
23412
23849
|
function constraintReferences(constraint) {
|
|
23413
23850
|
return [
|
|
23414
|
-
constraint.source.model,
|
|
23415
|
-
constraint.
|
|
23416
|
-
|
|
23417
|
-
(action) => action.pivot.kind === "around" ? action.pivot.axis.model : void 0
|
|
23851
|
+
...constraint.kind === "transformation" ? [] : [constraint.source.model, constraint.target.model],
|
|
23852
|
+
...(constraint.kind === "transformation" ? constraint.actions : []).map(
|
|
23853
|
+
(action) => "pivot" in action ? selectionReference(action.pivot)?.model : void 0
|
|
23418
23854
|
)
|
|
23419
23855
|
].filter((model) => !!model);
|
|
23420
23856
|
}
|
|
@@ -24238,8 +24674,8 @@ function sketchPointResolver(layers) {
|
|
|
24238
24674
|
const visiting = /* @__PURE__ */ new Set();
|
|
24239
24675
|
const resolve = /* @__PURE__ */ __name((ref) => {
|
|
24240
24676
|
const key = JSON.stringify([ref.layer, ref.id]);
|
|
24241
|
-
const
|
|
24242
|
-
if (
|
|
24677
|
+
const cached = resolved.get(key);
|
|
24678
|
+
if (cached) return cached;
|
|
24243
24679
|
const point3 = points.get(key);
|
|
24244
24680
|
if (!point3) throw new Error(`Missing sketch point ${ref.id}.`);
|
|
24245
24681
|
if (visiting.has(key))
|
|
@@ -24743,10 +25179,12 @@ export {
|
|
|
24743
25179
|
setKernelNativeMemoryCounter,
|
|
24744
25180
|
clearKernelOperationCache,
|
|
24745
25181
|
kernelOperationCacheStats,
|
|
25182
|
+
setKernelCacheBudget,
|
|
25183
|
+
setKernelCachePersistenceThreshold,
|
|
24746
25184
|
setKernelArtifactStore,
|
|
24747
25185
|
setKernelExternalBytes,
|
|
24748
25186
|
identifyCachedFunction,
|
|
24749
|
-
|
|
25187
|
+
cache,
|
|
24750
25188
|
googleFontUrl,
|
|
24751
25189
|
googleFontSources,
|
|
24752
25190
|
installFontEngine,
|
|
@@ -24787,6 +25225,13 @@ export {
|
|
|
24787
25225
|
modelElementReference,
|
|
24788
25226
|
modelTopologyReference,
|
|
24789
25227
|
modelTopologyIds,
|
|
25228
|
+
offset,
|
|
25229
|
+
rotate2 as rotate,
|
|
25230
|
+
pivot,
|
|
25231
|
+
pivotVertex,
|
|
25232
|
+
pivotPoint,
|
|
25233
|
+
axisEdge,
|
|
25234
|
+
axisLine,
|
|
24790
25235
|
circle,
|
|
24791
25236
|
ellipse,
|
|
24792
25237
|
rectangle,
|
|
@@ -24813,11 +25258,13 @@ export {
|
|
|
24813
25258
|
intersect,
|
|
24814
25259
|
isModelObject,
|
|
24815
25260
|
isConstraint,
|
|
24816
|
-
|
|
24817
|
-
|
|
24818
|
-
|
|
25261
|
+
isRelationExpression,
|
|
25262
|
+
relationPreview,
|
|
25263
|
+
currentRelationSelf,
|
|
25264
|
+
relationSelectionPreview,
|
|
25265
|
+
instrumentRelation,
|
|
24819
25266
|
instrumentModelOperation,
|
|
24820
|
-
|
|
25267
|
+
relationTraceReference,
|
|
24821
25268
|
modelObjectRuntimeInfo,
|
|
24822
25269
|
relatedModelObjects,
|
|
24823
25270
|
planModelSnapshotQueries,
|
|
@@ -24839,4 +25286,4 @@ export {
|
|
|
24839
25286
|
assertSketchDragConnections,
|
|
24840
25287
|
solveSketchSnapshot
|
|
24841
25288
|
};
|
|
24842
|
-
//# sourceMappingURL=chunk-
|
|
25289
|
+
//# sourceMappingURL=chunk-4WLVDYUJ.js.map
|