@code3d/core 0.0.1-alpha.6 → 0.0.1-alpha.8
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 +53 -3
- package/bld/chunks/{chunk-3RIMOCPP.js → chunk-EWPRWRLV.js} +2 -2
- package/bld/chunks/{chunk-T6COR2SG.js → chunk-HSU2FH3L.js} +3 -3
- package/bld/chunks/{chunk-T3RAUNSF.js → chunk-MICNLFBF.js} +452 -107
- package/bld/chunks/chunk-MICNLFBF.js.map +7 -0
- package/bld/chunks/{chunk-KYW4AWKO.js → chunk-OAVABPL5.js} +2 -2
- 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 +5 -3
- package/bld/library/kernel-cache.d.ts +5 -3
- package/bld/library/kernel-cache.d.ts.map +1 -1
- package/bld/library/loft.d.ts.map +1 -1
- package/bld/library/replicad.js +2 -2
- package/bld/library/runtime.d.ts +61 -6
- package/bld/library/runtime.d.ts.map +1 -1
- package/bld/library/topology.d.ts +4 -2
- package/bld/library/topology.d.ts.map +1 -1
- package/bld/node/index.js +7 -5
- package/bld/node/replicad.js +4 -4
- package/bld/tooling/index.d.ts +2 -2
- package/bld/tooling/index.d.ts.map +1 -1
- package/bld/tooling/index.js +4 -2
- package/package.json +1 -1
- package/src/library/cached.ts +29 -8
- package/src/library/index.ts +5 -2
- package/src/library/kernel-cache.ts +29 -5
- package/src/library/loft.ts +5 -1
- package/src/library/runtime.ts +508 -43
- package/src/library/shell.ts +3 -3
- package/src/library/topology.ts +24 -15
- package/src/tooling/index.ts +2 -0
- package/bld/chunks/chunk-T3RAUNSF.js.map +0 -7
- /package/bld/chunks/{chunk-3RIMOCPP.js.map → chunk-EWPRWRLV.js.map} +0 -0
- /package/bld/chunks/{chunk-T6COR2SG.js.map → chunk-HSU2FH3L.js.map} +0 -0
- /package/bld/chunks/{chunk-KYW4AWKO.js.map → chunk-OAVABPL5.js.map} +0 -0
|
@@ -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();
|
|
@@ -391,6 +392,10 @@ function createComputationCache({
|
|
|
391
392
|
evictHistoricalEntries();
|
|
392
393
|
}
|
|
393
394
|
__name(setKernelCacheBudget2, "setKernelCacheBudget");
|
|
395
|
+
function setKernelCachePersistenceThreshold2(milliseconds) {
|
|
396
|
+
minimumPersistenceMilliseconds = milliseconds;
|
|
397
|
+
}
|
|
398
|
+
__name(setKernelCachePersistenceThreshold2, "setKernelCachePersistenceThreshold");
|
|
394
399
|
function setKernelExternalBytes2(bytes) {
|
|
395
400
|
externalBytes = bytes;
|
|
396
401
|
evictHistoricalEntries();
|
|
@@ -431,8 +436,10 @@ function createComputationCache({
|
|
|
431
436
|
function evaluateCachedArtifact2(key, lifecycle, compute, codec) {
|
|
432
437
|
const hit = findKernelOperation2(key, lifecycle, codec);
|
|
433
438
|
if (hit) return hit;
|
|
439
|
+
const started = performance.now();
|
|
434
440
|
const value = compute();
|
|
435
|
-
|
|
441
|
+
const milliseconds = performance.now() - started;
|
|
442
|
+
acceptKernelOperation2(key, lifecycle, value, milliseconds, codec);
|
|
436
443
|
return { id: key.id, value };
|
|
437
444
|
}
|
|
438
445
|
__name(evaluateCachedArtifact2, "evaluateCachedArtifact");
|
|
@@ -460,8 +467,8 @@ function createComputationCache({
|
|
|
460
467
|
function lookup(key, lifecycle, codec, read) {
|
|
461
468
|
currentEvaluation?.checkCancelled?.();
|
|
462
469
|
const { id, signature } = key;
|
|
463
|
-
let
|
|
464
|
-
if (!
|
|
470
|
+
let cached = entries.get(id);
|
|
471
|
+
if (!cached && codec !== false) {
|
|
465
472
|
const bytes = read();
|
|
466
473
|
if (bytes) {
|
|
467
474
|
let restored;
|
|
@@ -473,25 +480,26 @@ function createComputationCache({
|
|
|
473
480
|
misses += 1;
|
|
474
481
|
return void 0;
|
|
475
482
|
}
|
|
476
|
-
|
|
483
|
+
cached = retainEntry(key, lifecycle, restored, true);
|
|
477
484
|
persistentHits += 1;
|
|
478
485
|
persisted.add(id);
|
|
479
486
|
}
|
|
480
487
|
}
|
|
481
|
-
if (!
|
|
488
|
+
if (!cached) {
|
|
482
489
|
misses += 1;
|
|
483
490
|
return void 0;
|
|
484
491
|
}
|
|
485
|
-
if (
|
|
492
|
+
if (cached.signature !== signature)
|
|
486
493
|
throw new Error(`Kernel operation cache identity collision: ${id}`);
|
|
487
494
|
hits += 1;
|
|
488
|
-
const value =
|
|
489
|
-
if (codec !== false)
|
|
490
|
-
|
|
495
|
+
const value = cached.instantiate(cached.value);
|
|
496
|
+
if (cached.persistenceEligible && codec !== false)
|
|
497
|
+
persist(key, cached.value, codec, true);
|
|
498
|
+
touchEntry(id, cached);
|
|
491
499
|
return { id, value };
|
|
492
500
|
}
|
|
493
501
|
__name(lookup, "lookup");
|
|
494
|
-
function acceptKernelOperation2(key, lifecycle, value, codec) {
|
|
502
|
+
function acceptKernelOperation2(key, lifecycle, value, milliseconds, codec) {
|
|
495
503
|
const existing = entries.get(key.id);
|
|
496
504
|
if (existing) {
|
|
497
505
|
if (existing.signature !== key.signature)
|
|
@@ -506,8 +514,14 @@ function createComputationCache({
|
|
|
506
514
|
lifecycle.release(value);
|
|
507
515
|
throw error;
|
|
508
516
|
}
|
|
509
|
-
const entry = retainEntry(
|
|
510
|
-
|
|
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);
|
|
511
525
|
touchEntry(key.id, entry);
|
|
512
526
|
}
|
|
513
527
|
__name(acceptKernelOperation2, "acceptKernelOperation");
|
|
@@ -553,8 +567,9 @@ function createComputationCache({
|
|
|
553
567
|
pendingPersistence.clear();
|
|
554
568
|
}
|
|
555
569
|
__name(flushPendingPersistence, "flushPendingPersistence");
|
|
556
|
-
function retainEntry(key, lifecycle, retained) {
|
|
570
|
+
function retainEntry(key, lifecycle, retained, persistenceEligible) {
|
|
557
571
|
const entry = {
|
|
572
|
+
persistenceEligible,
|
|
558
573
|
estimatedBytes: 256 + estimateRetainedBytes(key.signature) + lifecycle.estimateBytes(retained),
|
|
559
574
|
signature: key.signature,
|
|
560
575
|
value: retained,
|
|
@@ -630,6 +645,7 @@ function createComputationCache({
|
|
|
630
645
|
clearKernelOperationCache: clearKernelOperationCache2,
|
|
631
646
|
kernelOperationCacheStats: kernelOperationCacheStats2,
|
|
632
647
|
setKernelCacheBudget: setKernelCacheBudget2,
|
|
648
|
+
setKernelCachePersistenceThreshold: setKernelCachePersistenceThreshold2,
|
|
633
649
|
setKernelArtifactStore: setKernelArtifactStore2,
|
|
634
650
|
findKernelOperation: findKernelOperation2,
|
|
635
651
|
findKernelOperations: findKernelOperations2,
|
|
@@ -649,6 +665,7 @@ var {
|
|
|
649
665
|
clearKernelOperationCache,
|
|
650
666
|
kernelOperationCacheStats,
|
|
651
667
|
setKernelCacheBudget,
|
|
668
|
+
setKernelCachePersistenceThreshold,
|
|
652
669
|
setKernelArtifactStore,
|
|
653
670
|
findKernelOperation,
|
|
654
671
|
findKernelOperations,
|
|
@@ -713,19 +730,19 @@ var dataLifecycle = {
|
|
|
713
730
|
release() {
|
|
714
731
|
}
|
|
715
732
|
};
|
|
716
|
-
function
|
|
733
|
+
function cache(compute, args, options) {
|
|
717
734
|
const operation = cachedArtifact(
|
|
718
|
-
(...
|
|
719
|
-
const value = compute(...
|
|
735
|
+
(...args2) => {
|
|
736
|
+
const value = compute(...args2);
|
|
720
737
|
if (value && typeof value === "object" && "then" in value && typeof value.then === "function")
|
|
721
|
-
throw new Error("
|
|
738
|
+
throw new Error("cache() requires a synchronous computation.");
|
|
722
739
|
return value;
|
|
723
740
|
},
|
|
724
741
|
{ identity: compute, codec: options }
|
|
725
742
|
);
|
|
726
|
-
return (...
|
|
743
|
+
return args === void 0 ? (...args2) => operation(...args2).value : operation(...args).value;
|
|
727
744
|
}
|
|
728
|
-
__name(
|
|
745
|
+
__name(cache, "cache");
|
|
729
746
|
function cachedArtifact(compute, {
|
|
730
747
|
key,
|
|
731
748
|
lifecycle = dataLifecycle,
|
|
@@ -742,7 +759,7 @@ function cachedArtifact(compute, {
|
|
|
742
759
|
));
|
|
743
760
|
const find = /* @__PURE__ */ __name((key2) => findKernelOperation(key2, lifecycle, persistence), "find");
|
|
744
761
|
const findMany = /* @__PURE__ */ __name((keys) => findKernelOperations(keys, lifecycle, persistence), "findMany");
|
|
745
|
-
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");
|
|
746
763
|
return Object.assign(
|
|
747
764
|
(...args) => {
|
|
748
765
|
return evaluateCachedArtifact(
|
|
@@ -1092,9 +1109,9 @@ function sketchCurveClosestParameter(curve, position2) {
|
|
|
1092
1109
|
);
|
|
1093
1110
|
if (curve.kind === "circle") return sketchPositiveAngle(angle) / tau;
|
|
1094
1111
|
const sign3 = Math.sign(curve.sweep), sweep = Math.abs(curve.sweep);
|
|
1095
|
-
const
|
|
1096
|
-
if (
|
|
1097
|
-
return
|
|
1112
|
+
const distance4 = sketchPositiveAngle(sign3 * (angle - curve.start));
|
|
1113
|
+
if (distance4 <= sweep) return sweep ? distance4 / sweep : 0;
|
|
1114
|
+
return distance4 - sweep < tau - distance4 ? 1 : 0;
|
|
1098
1115
|
}
|
|
1099
1116
|
__name(sketchCurveClosestParameter, "sketchCurveClosestParameter");
|
|
1100
1117
|
function sketchCurveBounds(curve) {
|
|
@@ -2416,15 +2433,15 @@ function endpointPolicy(problem, point3, scope) {
|
|
|
2416
2433
|
controls.delete(point3);
|
|
2417
2434
|
if (controls.size) return { kind: "endpoint", anchors: [...controls] };
|
|
2418
2435
|
const graph = neighbors(problem);
|
|
2419
|
-
const
|
|
2420
|
-
for (const [p, d] of
|
|
2436
|
+
const distance4 = /* @__PURE__ */ new Map([[point3, 0]]);
|
|
2437
|
+
for (const [p, d] of distance4)
|
|
2421
2438
|
for (const next of graph[p])
|
|
2422
|
-
if (scope.has(next) && !
|
|
2439
|
+
if (scope.has(next) && !distance4.has(next)) distance4.set(next, d + 1);
|
|
2423
2440
|
let farthest = -1, max12 = 0;
|
|
2424
2441
|
for (const p of scope)
|
|
2425
|
-
if ((
|
|
2442
|
+
if ((distance4.get(p) ?? 0) > max12) {
|
|
2426
2443
|
farthest = p;
|
|
2427
|
-
max12 =
|
|
2444
|
+
max12 = distance4.get(p);
|
|
2428
2445
|
}
|
|
2429
2446
|
return { kind: "endpoint", anchors: farthest < 0 ? [] : [farthest] };
|
|
2430
2447
|
}
|
|
@@ -3095,22 +3112,22 @@ function nearestPoint(point3, geometry) {
|
|
|
3095
3112
|
case "ellipse": {
|
|
3096
3113
|
const y = cross2(geometry.normal, geometry.major);
|
|
3097
3114
|
const x0 = dot(delta, geometry.major), y0 = dot(delta, y);
|
|
3098
|
-
const
|
|
3115
|
+
const distance4 = /* @__PURE__ */ __name((angle2) => (geometry.radius * Math.cos(angle2) - x0) ** 2 + (geometry.minorRadius * Math.sin(angle2) - y0) ** 2, "distance");
|
|
3099
3116
|
const step = Math.PI / 16, candidates2 = [];
|
|
3100
3117
|
for (let i = 0; i < 32; i++) {
|
|
3101
3118
|
const angle2 = i * step;
|
|
3102
|
-
if (
|
|
3119
|
+
if (distance4(angle2) > distance4(angle2 - step) || distance4(angle2) > distance4(angle2 + step))
|
|
3103
3120
|
continue;
|
|
3104
3121
|
let lower = angle2 - step, upper = angle2 + step;
|
|
3105
3122
|
for (let iteration = 0; iteration < 64; iteration++) {
|
|
3106
3123
|
const a = lower + (upper - lower) * 0.3819660112501051, b = upper - (upper - lower) * 0.3819660112501051;
|
|
3107
|
-
if (
|
|
3124
|
+
if (distance4(a) < distance4(b)) upper = b;
|
|
3108
3125
|
else lower = a;
|
|
3109
3126
|
}
|
|
3110
3127
|
candidates2.push((lower + upper) / 2);
|
|
3111
3128
|
}
|
|
3112
3129
|
const angle = candidates2.reduce(
|
|
3113
|
-
(best, angle2) =>
|
|
3130
|
+
(best, angle2) => distance4(angle2) < distance4(best) ? angle2 : best,
|
|
3114
3131
|
candidates2[0]
|
|
3115
3132
|
);
|
|
3116
3133
|
return addVectors(
|
|
@@ -3283,8 +3300,8 @@ function filletEdges(shape, source, radius, edgeIds) {
|
|
|
3283
3300
|
return modifyEdges("fillet", shape, source, radius, edgeIds);
|
|
3284
3301
|
}
|
|
3285
3302
|
__name(filletEdges, "filletEdges");
|
|
3286
|
-
function chamferEdges(shape, source,
|
|
3287
|
-
return modifyEdges("chamfer", shape, source,
|
|
3303
|
+
function chamferEdges(shape, source, distance4, edgeIds) {
|
|
3304
|
+
return modifyEdges("chamfer", shape, source, distance4, edgeIds);
|
|
3288
3305
|
}
|
|
3289
3306
|
__name(chamferEdges, "chamferEdges");
|
|
3290
3307
|
function booleanWithTopology(left, right, operation) {
|
|
@@ -3511,7 +3528,7 @@ function modifyEdges(kind, shape, source, amount, requestedIds) {
|
|
|
3511
3528
|
return {
|
|
3512
3529
|
shape: result,
|
|
3513
3530
|
topology: transferShapeTopology(
|
|
3514
|
-
[{ shape, topology: source,
|
|
3531
|
+
[{ shape, topology: source, namespace: "preserve" }],
|
|
3515
3532
|
result,
|
|
3516
3533
|
builder
|
|
3517
3534
|
),
|
|
@@ -3586,15 +3603,18 @@ function transferShapeTopology(inputs, output, history) {
|
|
|
3586
3603
|
const transfer = /* @__PURE__ */ __name((kind) => {
|
|
3587
3604
|
const originals = [];
|
|
3588
3605
|
const results = topologyShapes(output, kind);
|
|
3606
|
+
let nextId = 1;
|
|
3589
3607
|
try {
|
|
3590
3608
|
const candidates2 = inputs.flatMap((input, inputIndex) => {
|
|
3591
3609
|
const shapes = topologyShapes(input.shape, kind);
|
|
3592
3610
|
originals.push(shapes);
|
|
3593
3611
|
const source = input.topology[topologyMetadata[kind].plural];
|
|
3594
3612
|
assertTopologyLength(kind, shapes, source);
|
|
3613
|
+
if (input.namespace === "preserve")
|
|
3614
|
+
nextId = Math.max(nextId, source.nextId);
|
|
3595
3615
|
return shapes.map((shape, index) => {
|
|
3596
3616
|
const id = source.ids[index];
|
|
3597
|
-
const inherited2 = input.
|
|
3617
|
+
const inherited2 = typeof input.namespace === "number" ? inheritedTopologyId(input.namespace, id) : input.namespace === "preserve" || typeof id !== "number" ? id : void 0;
|
|
3598
3618
|
const unchanged = matchingOutputShapes(shape.wrapped, results);
|
|
3599
3619
|
if (unchanged.length) return { id: inherited2, matches: unchanged };
|
|
3600
3620
|
if (typeof history !== "function") {
|
|
@@ -3631,10 +3651,8 @@ function transferShapeTopology(inputs, output, history) {
|
|
|
3631
3651
|
inherited.set(index, candidate.id);
|
|
3632
3652
|
}
|
|
3633
3653
|
}
|
|
3634
|
-
|
|
3635
|
-
return stableTopology(
|
|
3636
|
-
results.map((_, index) => inherited.get(index) ?? nextId++)
|
|
3637
|
-
);
|
|
3654
|
+
const ids = results.map((_, index) => inherited.get(index) ?? nextId++);
|
|
3655
|
+
return stableTopology(ids, nextId);
|
|
3638
3656
|
} finally {
|
|
3639
3657
|
originals.forEach(deleteShapes);
|
|
3640
3658
|
deleteShapes(results);
|
|
@@ -3693,11 +3711,14 @@ function stableGroupIds(kind, shapes, topology, kernelIds) {
|
|
|
3693
3711
|
}
|
|
3694
3712
|
__name(stableGroupIds, "stableGroupIds");
|
|
3695
3713
|
function initialTopology(shapes) {
|
|
3696
|
-
return stableTopology(
|
|
3714
|
+
return stableTopology(
|
|
3715
|
+
shapes.map((_, index) => index + 1),
|
|
3716
|
+
shapes.length + 1
|
|
3717
|
+
);
|
|
3697
3718
|
}
|
|
3698
3719
|
__name(initialTopology, "initialTopology");
|
|
3699
|
-
function stableTopology(ids) {
|
|
3700
|
-
return { ids };
|
|
3720
|
+
function stableTopology(ids, nextId) {
|
|
3721
|
+
return { ids, nextId };
|
|
3701
3722
|
}
|
|
3702
3723
|
__name(stableTopology, "stableTopology");
|
|
3703
3724
|
function shapeTopology(vertices, edges, surfaces) {
|
|
@@ -3798,7 +3819,11 @@ function loftWithTopology(sections, spine, ruled) {
|
|
|
3798
3819
|
ruled,
|
|
3799
3820
|
holes.map((wires) => wires[0])
|
|
3800
3821
|
);
|
|
3801
|
-
return booleanWithTopology(
|
|
3822
|
+
return booleanWithTopology(
|
|
3823
|
+
{ ...outer, namespace: "intermediate" },
|
|
3824
|
+
{ ...inner, namespace: "intermediate" },
|
|
3825
|
+
"cut"
|
|
3826
|
+
);
|
|
3802
3827
|
} finally {
|
|
3803
3828
|
inner?.shape.delete();
|
|
3804
3829
|
outer?.shape.delete();
|
|
@@ -6036,7 +6061,7 @@ function openShell(shape, topology, thickness, removedIds, sourceVolume) {
|
|
|
6036
6061
|
return {
|
|
6037
6062
|
shape: result,
|
|
6038
6063
|
topology: transferShapeTopology(
|
|
6039
|
-
[{ shape, topology,
|
|
6064
|
+
[{ shape, topology, namespace: "preserve" }],
|
|
6040
6065
|
result,
|
|
6041
6066
|
builder
|
|
6042
6067
|
)
|
|
@@ -6112,7 +6137,7 @@ function closedShell(shape, topology, thickness, sourceVolume) {
|
|
|
6112
6137
|
return {
|
|
6113
6138
|
shape: result,
|
|
6114
6139
|
topology: transferShapeTopology(
|
|
6115
|
-
[{ shape, topology,
|
|
6140
|
+
[{ shape, topology, namespace: "preserve" }],
|
|
6116
6141
|
result,
|
|
6117
6142
|
cut2
|
|
6118
6143
|
)
|
|
@@ -20264,6 +20289,7 @@ function inspectSurface(face) {
|
|
|
20264
20289
|
__name(inspectSurface, "inspectSurface");
|
|
20265
20290
|
|
|
20266
20291
|
// packages/core/src/library/runtime.ts
|
|
20292
|
+
var observeDistance;
|
|
20267
20293
|
function isAxisSelection(pivot2) {
|
|
20268
20294
|
return pivot2.kind === "axisLine" || pivot2.kind === "axisEdge";
|
|
20269
20295
|
}
|
|
@@ -20279,10 +20305,16 @@ __name(mapSelectionReference, "mapSelectionReference");
|
|
|
20279
20305
|
var activeRelate;
|
|
20280
20306
|
var valueTraces = /* @__PURE__ */ new WeakMap();
|
|
20281
20307
|
var operationTraces = /* @__PURE__ */ new WeakMap();
|
|
20282
|
-
function beginModelEvaluation(checkCancelled) {
|
|
20308
|
+
function beginModelEvaluation(checkCancelled, distanceObserver) {
|
|
20283
20309
|
valueTraces = /* @__PURE__ */ new WeakMap();
|
|
20284
20310
|
operationTraces = /* @__PURE__ */ new WeakMap();
|
|
20285
|
-
|
|
20311
|
+
const previous = observeDistance;
|
|
20312
|
+
observeDistance = distanceObserver;
|
|
20313
|
+
const finish = beginKernelOperationEvaluation(checkCancelled);
|
|
20314
|
+
return () => {
|
|
20315
|
+
observeDistance = previous;
|
|
20316
|
+
finish();
|
|
20317
|
+
};
|
|
20286
20318
|
}
|
|
20287
20319
|
__name(beginModelEvaluation, "beginModelEvaluation");
|
|
20288
20320
|
function valueTrace(value) {
|
|
@@ -20710,10 +20742,10 @@ function rotationPointReference(point3) {
|
|
|
20710
20742
|
return reference;
|
|
20711
20743
|
}
|
|
20712
20744
|
__name(rotationPointReference, "rotationPointReference");
|
|
20713
|
-
function
|
|
20745
|
+
function straightAxisReference(axis, operation = "axisLine()") {
|
|
20714
20746
|
const reference = anchorReference(axis);
|
|
20715
20747
|
if (reference.kind !== "line")
|
|
20716
|
-
throw new Error(
|
|
20748
|
+
throw new Error(`${operation} requires an axis or straight edge.`);
|
|
20717
20749
|
const geometry = reference.topology?.source[modelGeometry]()?.value ?? (reference.whole && isModelObject(reference.model) ? reference.model[modelGeometry]()?.value : void 0);
|
|
20718
20750
|
if (geometry) {
|
|
20719
20751
|
const straight = reference.topology ? withTopologyShape(
|
|
@@ -20724,12 +20756,12 @@ function rotationAxisReference(axis) {
|
|
|
20724
20756
|
) : geometry.shape.geomType === "LINE";
|
|
20725
20757
|
if (!straight)
|
|
20726
20758
|
throw new Error(
|
|
20727
|
-
|
|
20759
|
+
`${operation} requires a straight axis; curved edges do not define one axis.`
|
|
20728
20760
|
);
|
|
20729
20761
|
}
|
|
20730
20762
|
return reference;
|
|
20731
20763
|
}
|
|
20732
|
-
__name(
|
|
20764
|
+
__name(straightAxisReference, "straightAxisReference");
|
|
20733
20765
|
var PivotRotation = class extends RelationExpression {
|
|
20734
20766
|
/** @internal */
|
|
20735
20767
|
constructor(chain, selection, previous) {
|
|
@@ -20845,7 +20877,7 @@ __name(axisEdge, "axisEdge");
|
|
|
20845
20877
|
function axisLine(axis) {
|
|
20846
20878
|
return new AxisChain(new TransformationRotation(), {
|
|
20847
20879
|
kind: "axisLine",
|
|
20848
|
-
axis:
|
|
20880
|
+
axis: straightAxisReference(axis)
|
|
20849
20881
|
});
|
|
20850
20882
|
}
|
|
20851
20883
|
__name(axisLine, "axisLine");
|
|
@@ -21736,33 +21768,64 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21736
21768
|
operation
|
|
21737
21769
|
);
|
|
21738
21770
|
}
|
|
21739
|
-
/**
|
|
21740
|
-
|
|
21771
|
+
/**
|
|
21772
|
+
* Measure finite geometry in this model's local frame, or in relativeTo's frame.
|
|
21773
|
+
* An explicit reference includes solved placement and nested group occurrences.
|
|
21774
|
+
* Empty groups have no finite bounds.
|
|
21775
|
+
*/
|
|
21776
|
+
bounds(relativeTo) {
|
|
21777
|
+
const target = relativeTo === void 0 ? this : requireModelObject(relativeTo, "bounds requires a reference model.");
|
|
21778
|
+
const transform = target.localFrames([this])[0];
|
|
21779
|
+
const [minimum, maximum] = this[referenceBounds](
|
|
21780
|
+
this.relationAnchorReference(),
|
|
21781
|
+
transform
|
|
21782
|
+
);
|
|
21783
|
+
return {
|
|
21784
|
+
minimum,
|
|
21785
|
+
maximum,
|
|
21786
|
+
size: [
|
|
21787
|
+
maximum[0] - minimum[0],
|
|
21788
|
+
maximum[1] - minimum[1],
|
|
21789
|
+
maximum[2] - minimum[2]
|
|
21790
|
+
]
|
|
21791
|
+
};
|
|
21792
|
+
}
|
|
21793
|
+
/**
|
|
21794
|
+
* Model-origin coordinates in relativeTo's local frame, including placement.
|
|
21795
|
+
* This model's origin in its own frame is always [0, 0, 0], even for point models.
|
|
21796
|
+
*/
|
|
21797
|
+
position(relativeTo) {
|
|
21798
|
+
const target = requireModelObject(
|
|
21799
|
+
relativeTo,
|
|
21800
|
+
"position requires a reference model."
|
|
21801
|
+
);
|
|
21802
|
+
return target.localFrames([this])[0].position;
|
|
21803
|
+
}
|
|
21804
|
+
/** Resolve source frames without losing nested occurrence positions. */
|
|
21805
|
+
localFrames(sources) {
|
|
21741
21806
|
const members = this.memberPoses();
|
|
21742
|
-
const external = sources.
|
|
21807
|
+
const external = sources.filter((model) => !members.has(model));
|
|
21743
21808
|
const context = external.length ? _ModelObject.createSolveContext([this, ...external]) : void 0;
|
|
21744
21809
|
return sources.map((source) => {
|
|
21745
|
-
const
|
|
21746
|
-
const {
|
|
21747
|
-
kind,
|
|
21748
|
-
transform: frame,
|
|
21749
|
-
topology,
|
|
21750
|
-
members: nested,
|
|
21751
|
-
bound,
|
|
21752
|
-
facing
|
|
21753
|
-
} = source instanceof _ModelObject ? source.exposedElement() : reference;
|
|
21754
|
-
const memberPose = members.get(reference.model);
|
|
21810
|
+
const memberPose = members.get(source);
|
|
21755
21811
|
if (memberPose === null)
|
|
21756
21812
|
throw new Error(
|
|
21757
21813
|
"The point or element belongs to multiple occurrences. Expose it through the intended child model's named reference."
|
|
21758
21814
|
);
|
|
21759
|
-
|
|
21760
|
-
|
|
21761
|
-
|
|
21762
|
-
|
|
21815
|
+
return memberPose ?? relativeTransform(source.solvePose(context), this.solvePose(context));
|
|
21816
|
+
});
|
|
21817
|
+
}
|
|
21818
|
+
/** Resolve both own and occurrence references into this model's local frame. */
|
|
21819
|
+
localElements(sources) {
|
|
21820
|
+
const references2 = sources.map(anchorReference);
|
|
21821
|
+
const transforms = this.localFrames(
|
|
21822
|
+
references2.map((reference) => reference.model)
|
|
21823
|
+
);
|
|
21824
|
+
return sources.map((source, index) => {
|
|
21825
|
+
const { kind, transform, topology, parts, members, bound, facing } = source instanceof _ModelObject ? source.exposedElement() : references2[index];
|
|
21763
21826
|
return transformElement(
|
|
21764
|
-
{ kind, transform
|
|
21765
|
-
|
|
21827
|
+
{ kind, transform, topology, parts, members, bound, facing },
|
|
21828
|
+
transforms[index]
|
|
21766
21829
|
);
|
|
21767
21830
|
});
|
|
21768
21831
|
}
|
|
@@ -21804,7 +21867,11 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
21804
21867
|
/** @internal */
|
|
21805
21868
|
exposedElement() {
|
|
21806
21869
|
if (this.kind === "group")
|
|
21807
|
-
return {
|
|
21870
|
+
return {
|
|
21871
|
+
...this.geometryAnchor,
|
|
21872
|
+
parts: this.geometryParts(),
|
|
21873
|
+
members: this.elements
|
|
21874
|
+
};
|
|
21808
21875
|
const geometry = this.requireGeometry().value;
|
|
21809
21876
|
const kind = this.kind === "face" ? "surface" : this.kind;
|
|
21810
21877
|
const selection = kind === "solid" ? { kind } : {
|
|
@@ -22009,14 +22076,14 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22009
22076
|
storedOperation("scaled", [{ model: this, role: "source", index: 0 }])
|
|
22010
22077
|
);
|
|
22011
22078
|
}
|
|
22012
|
-
extrude(
|
|
22079
|
+
extrude(distance4 = 10) {
|
|
22013
22080
|
if (this.kind !== "face")
|
|
22014
22081
|
throw new Error("extrude requires a single face model.");
|
|
22015
|
-
if (!Number.isFinite(
|
|
22082
|
+
if (!Number.isFinite(distance4) || distance4 === 0)
|
|
22016
22083
|
throw new Error("Extrusion distance must be finite and non-zero.");
|
|
22017
22084
|
const source = this.requireGeometry();
|
|
22018
22085
|
const direction = rotateVector(
|
|
22019
|
-
[0,
|
|
22086
|
+
[0, distance4, 0],
|
|
22020
22087
|
this.geometryAnchor.transform.quaternion
|
|
22021
22088
|
);
|
|
22022
22089
|
const geometry = evaluateSolidGeometry(
|
|
@@ -22027,7 +22094,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22027
22094
|
{
|
|
22028
22095
|
shape: source.value.shape,
|
|
22029
22096
|
topology: source.value.topology,
|
|
22030
|
-
|
|
22097
|
+
namespace: 1
|
|
22031
22098
|
},
|
|
22032
22099
|
direction
|
|
22033
22100
|
)
|
|
@@ -22094,8 +22161,8 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22094
22161
|
})
|
|
22095
22162
|
);
|
|
22096
22163
|
}
|
|
22097
|
-
chamfer(
|
|
22098
|
-
assertPositive("distance",
|
|
22164
|
+
chamfer(distance4 = 1, edgeIds) {
|
|
22165
|
+
assertPositive("distance", distance4);
|
|
22099
22166
|
const source = this.requireSolidGeometry();
|
|
22100
22167
|
const selectedEdgeIds = resolveEdgeSelection(
|
|
22101
22168
|
source.value.topology.edges,
|
|
@@ -22103,13 +22170,13 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22103
22170
|
);
|
|
22104
22171
|
const geometry = evaluateSolidGeometry(
|
|
22105
22172
|
"chamfer",
|
|
22106
|
-
[
|
|
22173
|
+
[distance4, selectedEdgeIds],
|
|
22107
22174
|
[source],
|
|
22108
22175
|
() => {
|
|
22109
22176
|
const result = chamferEdges(
|
|
22110
22177
|
source.value.shape,
|
|
22111
22178
|
source.value.topology,
|
|
22112
|
-
|
|
22179
|
+
distance4,
|
|
22113
22180
|
selectedEdgeIds
|
|
22114
22181
|
);
|
|
22115
22182
|
return { shape: result.shape, topology: result.topology };
|
|
@@ -22423,12 +22490,12 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22423
22490
|
{
|
|
22424
22491
|
shape: geometry.value.shape,
|
|
22425
22492
|
topology: geometry.value.topology,
|
|
22426
|
-
|
|
22493
|
+
namespace: otherIndex === 0 ? 1 : "intermediate"
|
|
22427
22494
|
},
|
|
22428
22495
|
{
|
|
22429
22496
|
shape: operand.value,
|
|
22430
22497
|
topology: otherGeometry.value.topology,
|
|
22431
|
-
|
|
22498
|
+
namespace: otherIndex + 2
|
|
22432
22499
|
},
|
|
22433
22500
|
operation
|
|
22434
22501
|
);
|
|
@@ -22477,6 +22544,176 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22477
22544
|
}
|
|
22478
22545
|
return members;
|
|
22479
22546
|
}
|
|
22547
|
+
/** Finite members in this value's saved local assembly, without re-solving children. */
|
|
22548
|
+
geometryParts(transform = identityRigidTransform) {
|
|
22549
|
+
if (this.geometry)
|
|
22550
|
+
return [{ source: this, selection: { kind: "solid" }, transform, scale: 1 }];
|
|
22551
|
+
return this.children.flatMap(
|
|
22552
|
+
(child) => child.geometryParts(
|
|
22553
|
+
composeTransforms(transform, child.solvePose(this.assembly))
|
|
22554
|
+
)
|
|
22555
|
+
);
|
|
22556
|
+
}
|
|
22557
|
+
/** @internal */
|
|
22558
|
+
static distance(a, b, axis) {
|
|
22559
|
+
const left = anchorReference(a), right = anchorReference(b);
|
|
22560
|
+
const axisReference = axis !== void 0 && typeof axis !== "string" && !Array.isArray(axis) ? straightAxisReference(axis, "distance() axis") : void 0;
|
|
22561
|
+
const context = _ModelObject.createSolveContext([
|
|
22562
|
+
left.model,
|
|
22563
|
+
right.model,
|
|
22564
|
+
...axisReference ? [axisReference.model] : []
|
|
22565
|
+
]);
|
|
22566
|
+
const topologyParts = /* @__PURE__ */ __name((reference) => reference.topology ? [reference.topology] : reference.parts ?? (reference.whole && reference.model instanceof _ModelObject ? reference.model.geometryParts() : void 0), "topologyParts");
|
|
22567
|
+
const parts = /* @__PURE__ */ __name((reference) => {
|
|
22568
|
+
const pose = reference.model.solvePose(context);
|
|
22569
|
+
const frame = composeTransforms(pose, reference.transform);
|
|
22570
|
+
if (reference.kind === "point") return [{ points: [frame.position] }];
|
|
22571
|
+
const topology = topologyParts(reference);
|
|
22572
|
+
if (topology)
|
|
22573
|
+
return topology.map((part) => ({
|
|
22574
|
+
geometry: part.source.requireGeometry(),
|
|
22575
|
+
selection: part.selection,
|
|
22576
|
+
scale: part.scale,
|
|
22577
|
+
transform: composeTransforms(pose, part.transform)
|
|
22578
|
+
}));
|
|
22579
|
+
if (reference.bound) {
|
|
22580
|
+
const [x, z] = reference.bound.size;
|
|
22581
|
+
const corners = x === 0 && z === 0 ? [origin] : x === 0 ? [
|
|
22582
|
+
[0, 0, -z / 2],
|
|
22583
|
+
[0, 0, z / 2]
|
|
22584
|
+
] : z === 0 ? [
|
|
22585
|
+
[-x / 2, 0, 0],
|
|
22586
|
+
[x / 2, 0, 0]
|
|
22587
|
+
] : [
|
|
22588
|
+
[-x / 2, 0, -z / 2],
|
|
22589
|
+
[x / 2, 0, -z / 2],
|
|
22590
|
+
[x / 2, 0, z / 2],
|
|
22591
|
+
[-x / 2, 0, z / 2]
|
|
22592
|
+
];
|
|
22593
|
+
return [
|
|
22594
|
+
{
|
|
22595
|
+
points: corners.map(
|
|
22596
|
+
(point3) => composeTransforms(frame, translation(point3)).position
|
|
22597
|
+
)
|
|
22598
|
+
}
|
|
22599
|
+
];
|
|
22600
|
+
}
|
|
22601
|
+
throw new Error(
|
|
22602
|
+
"distance() requires finite geometry or a point; select an edge or face instead of an infinite axis or plane."
|
|
22603
|
+
);
|
|
22604
|
+
}, "parts");
|
|
22605
|
+
const first = parts(left), second = parts(right);
|
|
22606
|
+
if (!first.length || !second.length)
|
|
22607
|
+
throw new Error("distance() cannot measure an empty group.");
|
|
22608
|
+
const record = /* @__PURE__ */ __name((result, direction2) => {
|
|
22609
|
+
if (observeDistance) {
|
|
22610
|
+
const operands = [left, right].map((reference) => {
|
|
22611
|
+
const topology = topologyParts(reference);
|
|
22612
|
+
const elements = topology && reference.kind !== "point" ? topology.map(
|
|
22613
|
+
(part) => snapshotElements({
|
|
22614
|
+
[reference.name]: {
|
|
22615
|
+
...reference,
|
|
22616
|
+
topology: part,
|
|
22617
|
+
members: void 0
|
|
22618
|
+
}
|
|
22619
|
+
})[0]
|
|
22620
|
+
) : [
|
|
22621
|
+
snapshotElements({
|
|
22622
|
+
[reference.name]: { ...reference, members: void 0 }
|
|
22623
|
+
})[0]
|
|
22624
|
+
];
|
|
22625
|
+
return { nodeId: reference.model.nodeId, elements };
|
|
22626
|
+
});
|
|
22627
|
+
observeDistance(
|
|
22628
|
+
{
|
|
22629
|
+
...result,
|
|
22630
|
+
axis: direction2,
|
|
22631
|
+
axisName: typeof axis === "string" ? axis : void 0,
|
|
22632
|
+
operands,
|
|
22633
|
+
placements: [...context.poses].map(([model, pose]) => ({
|
|
22634
|
+
nodeId: model.nodeId,
|
|
22635
|
+
transform: toTransform(pose)
|
|
22636
|
+
}))
|
|
22637
|
+
},
|
|
22638
|
+
[...context.poses.keys()]
|
|
22639
|
+
);
|
|
22640
|
+
}
|
|
22641
|
+
return result.value;
|
|
22642
|
+
}, "record");
|
|
22643
|
+
if (axis === void 0) {
|
|
22644
|
+
let result;
|
|
22645
|
+
for (const a2 of first)
|
|
22646
|
+
for (const b2 of second) {
|
|
22647
|
+
const candidate = "points" in a2 && a2.points.length === 1 && "points" in b2 && b2.points.length === 1 ? {
|
|
22648
|
+
value: Math.hypot(
|
|
22649
|
+
...a2.points[0].map((value, i) => value - b2.points[0][i])
|
|
22650
|
+
),
|
|
22651
|
+
start: a2.points[0],
|
|
22652
|
+
end: b2.points[0]
|
|
22653
|
+
} : distanceBetweenParts(a2, b2).value;
|
|
22654
|
+
if (!result || candidate.value < result.value) result = candidate;
|
|
22655
|
+
if (result.value === 0) return record(result);
|
|
22656
|
+
}
|
|
22657
|
+
return record(result);
|
|
22658
|
+
}
|
|
22659
|
+
const direction = axisReference ? rotateVector(
|
|
22660
|
+
[0, 1, 0],
|
|
22661
|
+
composeTransforms(
|
|
22662
|
+
axisReference.model.solvePose(context),
|
|
22663
|
+
axisReference.transform
|
|
22664
|
+
).quaternion
|
|
22665
|
+
) : typeof axis === "string" ? distanceAxes[axis] : axis;
|
|
22666
|
+
assertFiniteVector("distance() axis", direction);
|
|
22667
|
+
const magnitude = Math.hypot(...direction);
|
|
22668
|
+
if (magnitude === 0) throw new Error("distance() axis must be non-zero.");
|
|
22669
|
+
const normalized = direction.map(
|
|
22670
|
+
(value) => value / magnitude
|
|
22671
|
+
);
|
|
22672
|
+
const project = invertTransform(frameFromYAxis(origin, normalized));
|
|
22673
|
+
const projectedBounds = /* @__PURE__ */ __name((parts2) => {
|
|
22674
|
+
const bounds = parts2.map((part) => {
|
|
22675
|
+
if ("points" in part)
|
|
22676
|
+
return pointBounds(
|
|
22677
|
+
part.points.map(
|
|
22678
|
+
(point3) => composeTransforms(project, translation(point3)).position
|
|
22679
|
+
)
|
|
22680
|
+
);
|
|
22681
|
+
return evaluateSnapshotQuery(
|
|
22682
|
+
boundsQuery(
|
|
22683
|
+
part.geometry,
|
|
22684
|
+
composeTransforms(project, part.transform),
|
|
22685
|
+
part.selection,
|
|
22686
|
+
part.scale
|
|
22687
|
+
)
|
|
22688
|
+
);
|
|
22689
|
+
});
|
|
22690
|
+
return [
|
|
22691
|
+
[0, 1, 2].map(
|
|
22692
|
+
(i) => Math.min(...bounds.map((value) => value[0][i]))
|
|
22693
|
+
),
|
|
22694
|
+
[0, 1, 2].map(
|
|
22695
|
+
(i) => Math.max(...bounds.map((value) => value[1][i]))
|
|
22696
|
+
)
|
|
22697
|
+
];
|
|
22698
|
+
}, "projectedBounds");
|
|
22699
|
+
const aBounds = projectedBounds(first), bBounds = projectedBounds(second);
|
|
22700
|
+
const [aMin, aMax] = [aBounds[0][1], aBounds[1][1]], [bMin, bMax] = [bBounds[0][1], bBounds[1][1]];
|
|
22701
|
+
const overlap2 = (Math.max(aMin, bMin) + Math.min(aMax, bMax)) / 2;
|
|
22702
|
+
const [start, end] = bMin > aMax ? [aMax, bMin] : aMin > bMax ? [aMin, bMax] : [overlap2, overlap2];
|
|
22703
|
+
const center = [0, 1, 2].map(
|
|
22704
|
+
(i) => (Math.max(aBounds[0][i], bBounds[0][i]) + Math.min(aBounds[1][i], bBounds[1][i])) / 2
|
|
22705
|
+
);
|
|
22706
|
+
const unproject = invertTransform(project);
|
|
22707
|
+
const at = /* @__PURE__ */ __name((y) => composeTransforms(unproject, translation([center[0], y, center[2]])).position, "at");
|
|
22708
|
+
return record(
|
|
22709
|
+
{
|
|
22710
|
+
value: Math.max(0, bMin - aMax, aMin - bMax),
|
|
22711
|
+
start: at(start),
|
|
22712
|
+
end: at(end)
|
|
22713
|
+
},
|
|
22714
|
+
normalized
|
|
22715
|
+
);
|
|
22716
|
+
}
|
|
22480
22717
|
/** Bounds of the selected finite geometry after a rigid transform. */
|
|
22481
22718
|
[referenceBoundsParts](reference, transform) {
|
|
22482
22719
|
if (reference.bound)
|
|
@@ -22508,6 +22745,15 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22508
22745
|
)
|
|
22509
22746
|
];
|
|
22510
22747
|
}
|
|
22748
|
+
if (reference.parts)
|
|
22749
|
+
return reference.parts.map(
|
|
22750
|
+
(part) => boundsQuery(
|
|
22751
|
+
part.source.requireGeometry(),
|
|
22752
|
+
composeTransforms(transform, part.transform),
|
|
22753
|
+
part.selection,
|
|
22754
|
+
part.scale
|
|
22755
|
+
)
|
|
22756
|
+
);
|
|
22511
22757
|
return [{ bounds: super[referenceBounds](reference, transform) }];
|
|
22512
22758
|
}
|
|
22513
22759
|
/** Bounds of the selected finite geometry after a rigid transform. */
|
|
@@ -22587,7 +22833,7 @@ var ModelObject = class _ModelObject extends RelationObject {
|
|
|
22587
22833
|
);
|
|
22588
22834
|
}
|
|
22589
22835
|
edgeReference(id) {
|
|
22590
|
-
return { ...
|
|
22836
|
+
return { ...straightAxisReference(this.edge(id)), model: void 0 };
|
|
22591
22837
|
}
|
|
22592
22838
|
vertexPosition(id) {
|
|
22593
22839
|
return anchorReference(this.vertex(id)).transform.position;
|
|
@@ -22951,11 +23197,11 @@ function assertCoilClearance(radius, wireRadius, pitch, turns) {
|
|
|
22951
23197
|
else upper = middle;
|
|
22952
23198
|
}
|
|
22953
23199
|
const separation = Math.min(fullTurn * turns, (lower + upper) / 2);
|
|
22954
|
-
const
|
|
23200
|
+
const distance4 = Math.hypot(
|
|
22955
23201
|
2 * radius * Math.sin(separation / 2),
|
|
22956
23202
|
pitch * separation / fullTurn
|
|
22957
23203
|
);
|
|
22958
|
-
if (
|
|
23204
|
+
if (distance4 <= 2 * wireRadius) {
|
|
22959
23205
|
throw new Error(
|
|
22960
23206
|
"Coil turns must not touch or overlap; increase pitch or decrease wireRadius."
|
|
22961
23207
|
);
|
|
@@ -23148,12 +23394,16 @@ function group(children, name = "Group") {
|
|
|
23148
23394
|
});
|
|
23149
23395
|
}
|
|
23150
23396
|
__name(group, "group");
|
|
23397
|
+
function distance2(a, b, axis) {
|
|
23398
|
+
return ModelObject.distance(a, b, axis);
|
|
23399
|
+
}
|
|
23400
|
+
__name(distance2, "distance");
|
|
23151
23401
|
function union(operands) {
|
|
23152
23402
|
const { first, others } = booleanOperands("union", operands);
|
|
23153
23403
|
return first[combineModels]("fuse", others);
|
|
23154
23404
|
}
|
|
23155
23405
|
__name(union, "union");
|
|
23156
|
-
function extrude(face,
|
|
23406
|
+
function extrude(face, distance4 = 10) {
|
|
23157
23407
|
const faces = (Array.isArray(face) ? face : [face]).map(
|
|
23158
23408
|
(value) => requireModelKind(
|
|
23159
23409
|
value,
|
|
@@ -23161,7 +23411,7 @@ function extrude(face, distance3 = 10) {
|
|
|
23161
23411
|
"extrude requires a face model or an array of face models."
|
|
23162
23412
|
)
|
|
23163
23413
|
);
|
|
23164
|
-
const solids = faces.map((value) => value.extrude(
|
|
23414
|
+
const solids = faces.map((value) => value.extrude(distance4));
|
|
23165
23415
|
return Array.isArray(face) ? solids : solids[0];
|
|
23166
23416
|
}
|
|
23167
23417
|
__name(extrude, "extrude");
|
|
@@ -23261,6 +23511,83 @@ function relatedModelObjects(object) {
|
|
|
23261
23511
|
return object.relatedObjects();
|
|
23262
23512
|
}
|
|
23263
23513
|
__name(relatedModelObjects, "relatedModelObjects");
|
|
23514
|
+
var distanceAxes = { x: [1, 0, 0], y: [0, 1, 0], z: [0, 0, 1] };
|
|
23515
|
+
function withDistanceShape(part, visit) {
|
|
23516
|
+
if (!("points" in part))
|
|
23517
|
+
return withTransformedGeometry(part.geometry.value, part, visit);
|
|
23518
|
+
const points = part.points;
|
|
23519
|
+
if (points.length <= 2) {
|
|
23520
|
+
const shape = points.length === 1 ? makeVertex(toPoint(points[0])) : makeLine2(toPoint(points[0]), toPoint(points[1]));
|
|
23521
|
+
try {
|
|
23522
|
+
return visit(shape);
|
|
23523
|
+
} finally {
|
|
23524
|
+
shape.delete();
|
|
23525
|
+
}
|
|
23526
|
+
}
|
|
23527
|
+
const edges = [];
|
|
23528
|
+
let wire;
|
|
23529
|
+
let face;
|
|
23530
|
+
try {
|
|
23531
|
+
points.forEach(
|
|
23532
|
+
(point3, index) => edges.push(
|
|
23533
|
+
makeLine2(toPoint(point3), toPoint(points[(index + 1) % points.length]))
|
|
23534
|
+
)
|
|
23535
|
+
);
|
|
23536
|
+
wire = assembleWire(edges);
|
|
23537
|
+
face = makeFace(wire);
|
|
23538
|
+
return visit(face);
|
|
23539
|
+
} finally {
|
|
23540
|
+
face?.delete();
|
|
23541
|
+
wire?.delete();
|
|
23542
|
+
edges.forEach((edge) => edge.delete());
|
|
23543
|
+
}
|
|
23544
|
+
}
|
|
23545
|
+
__name(withDistanceShape, "withDistanceShape");
|
|
23546
|
+
var distanceBetweenParts = cachedArtifact(
|
|
23547
|
+
(a, b) => withDistanceShape(
|
|
23548
|
+
a,
|
|
23549
|
+
(left) => withDistanceShape(b, (right) => {
|
|
23550
|
+
const query = new (getOC12()).BRepExtrema_DistShapeShape();
|
|
23551
|
+
try {
|
|
23552
|
+
query.LoadS1(left.wrapped);
|
|
23553
|
+
query.LoadS2(right.wrapped);
|
|
23554
|
+
query.Perform();
|
|
23555
|
+
if (!query.IsDone())
|
|
23556
|
+
throw new Error("distance() could not measure these geometries.");
|
|
23557
|
+
const first = query.PointOnShape1(1), second = query.PointOnShape2(1);
|
|
23558
|
+
try {
|
|
23559
|
+
return {
|
|
23560
|
+
value: query.Value(),
|
|
23561
|
+
start: [first.X(), first.Y(), first.Z()],
|
|
23562
|
+
end: [second.X(), second.Y(), second.Z()]
|
|
23563
|
+
};
|
|
23564
|
+
} finally {
|
|
23565
|
+
first.delete();
|
|
23566
|
+
second.delete();
|
|
23567
|
+
}
|
|
23568
|
+
} finally {
|
|
23569
|
+
query.delete();
|
|
23570
|
+
}
|
|
23571
|
+
})
|
|
23572
|
+
),
|
|
23573
|
+
{
|
|
23574
|
+
key: /* @__PURE__ */ __name((a, b) => kernelOperationKey(
|
|
23575
|
+
"distance-witnesses",
|
|
23576
|
+
[a, b].map(
|
|
23577
|
+
(part) => "points" in part ? ["points", part.points] : [
|
|
23578
|
+
"shape",
|
|
23579
|
+
part.geometry.id,
|
|
23580
|
+
part.selection.kind,
|
|
23581
|
+
part.selection.kind === "solid" ? null : part.selection.id,
|
|
23582
|
+
part.transform.position,
|
|
23583
|
+
part.transform.quaternion,
|
|
23584
|
+
part.scale
|
|
23585
|
+
]
|
|
23586
|
+
),
|
|
23587
|
+
[a, b].flatMap((part) => "points" in part ? [] : [part.geometry])
|
|
23588
|
+
), "key")
|
|
23589
|
+
}
|
|
23590
|
+
);
|
|
23264
23591
|
function boundsQuery(geometry, transform, selection = { kind: "solid" }, scale3 = 1) {
|
|
23265
23592
|
return {
|
|
23266
23593
|
inputId: geometry.id,
|
|
@@ -23375,7 +23702,7 @@ function planModelSnapshotQueries(objects) {
|
|
|
23375
23702
|
sourceRef,
|
|
23376
23703
|
weight: (1 + (input.geometry.topology?.edges.ids.length ?? 0) + (input.geometry.topology?.surfaces.ids.length ?? 0)) * queries.length,
|
|
23377
23704
|
encode: /* @__PURE__ */ __name(() => encodeKernelArtifact(id, input.geometry), "encode"),
|
|
23378
|
-
accept: /* @__PURE__ */ __name((query, value) => snapshotQuery.accept(query.key, value), "accept")
|
|
23705
|
+
accept: /* @__PURE__ */ __name((query, value, milliseconds) => snapshotQuery.accept(query.key, value, milliseconds), "accept")
|
|
23379
23706
|
}));
|
|
23380
23707
|
}
|
|
23381
23708
|
__name(planModelSnapshotQueries, "planModelSnapshotQueries");
|
|
@@ -23389,7 +23716,9 @@ function executeSnapshotQueryBatch(id, bytes, queries, checkCancelled, onResult,
|
|
|
23389
23716
|
onRestore?.(performance.now() - started);
|
|
23390
23717
|
for (const query of queries) {
|
|
23391
23718
|
checkCancelled();
|
|
23392
|
-
|
|
23719
|
+
const started2 = performance.now();
|
|
23720
|
+
const value = computeSnapshotQuery(geometry, query);
|
|
23721
|
+
onResult(query, value, performance.now() - started2);
|
|
23393
23722
|
}
|
|
23394
23723
|
} finally {
|
|
23395
23724
|
geometry.shape.delete();
|
|
@@ -23457,7 +23786,7 @@ var authoringApi = Object.freeze({
|
|
|
23457
23786
|
pivotPoint,
|
|
23458
23787
|
axisEdge,
|
|
23459
23788
|
axisLine,
|
|
23460
|
-
|
|
23789
|
+
cache,
|
|
23461
23790
|
font,
|
|
23462
23791
|
googleFont,
|
|
23463
23792
|
text,
|
|
@@ -23481,6 +23810,7 @@ var authoringApi = Object.freeze({
|
|
|
23481
23810
|
frustum,
|
|
23482
23811
|
regularPrism,
|
|
23483
23812
|
group,
|
|
23813
|
+
distance: distance2,
|
|
23484
23814
|
union,
|
|
23485
23815
|
cut,
|
|
23486
23816
|
intersect
|
|
@@ -23585,15 +23915,15 @@ function evaluateSolidGeometry(operation, arguments_, inputs, compute) {
|
|
|
23585
23915
|
);
|
|
23586
23916
|
}
|
|
23587
23917
|
__name(evaluateSolidGeometry, "evaluateSolidGeometry");
|
|
23588
|
-
function renderMesh(artifact, shape,
|
|
23589
|
-
const
|
|
23590
|
-
if (
|
|
23591
|
-
return
|
|
23918
|
+
function renderMesh(artifact, shape, cache2, tolerance2, topology) {
|
|
23919
|
+
const cached = cache2.get(shape);
|
|
23920
|
+
if (cached) {
|
|
23921
|
+
return cached;
|
|
23592
23922
|
}
|
|
23593
23923
|
const mesh = evaluateSnapshotQuery(
|
|
23594
23924
|
meshQuery(artifact, shape, tolerance2, topology)
|
|
23595
23925
|
);
|
|
23596
|
-
|
|
23926
|
+
cache2.set(shape, mesh);
|
|
23597
23927
|
return mesh;
|
|
23598
23928
|
}
|
|
23599
23929
|
__name(renderMesh, "renderMesh");
|
|
@@ -23778,7 +24108,7 @@ function buildLoftGeometry(sections, spine, ruled) {
|
|
|
23778
24108
|
section.transform
|
|
23779
24109
|
),
|
|
23780
24110
|
topology: section.geometry.value.topology,
|
|
23781
|
-
|
|
24111
|
+
namespace: index + 1
|
|
23782
24112
|
});
|
|
23783
24113
|
}
|
|
23784
24114
|
if (spine) {
|
|
@@ -23858,6 +24188,10 @@ function axisAlignedBounds(bounds, transform) {
|
|
|
23858
24188
|
}
|
|
23859
24189
|
__name(axisAlignedBounds, "axisAlignedBounds");
|
|
23860
24190
|
function computeTransformedBounds(geometry, query) {
|
|
24191
|
+
return withTransformedGeometry(geometry, query, shapeBounds);
|
|
24192
|
+
}
|
|
24193
|
+
__name(computeTransformedBounds, "computeTransformedBounds");
|
|
24194
|
+
function withTransformedGeometry(geometry, query, visit) {
|
|
23861
24195
|
const { transform, selection, scale: scale3 } = query;
|
|
23862
24196
|
return withTopologyShape(
|
|
23863
24197
|
geometry.shape,
|
|
@@ -23868,7 +24202,7 @@ function computeTransformedBounds(geometry, query) {
|
|
|
23868
24202
|
try {
|
|
23869
24203
|
const moved = shapeWithTransform(scaled, transform);
|
|
23870
24204
|
try {
|
|
23871
|
-
return
|
|
24205
|
+
return visit(moved);
|
|
23872
24206
|
} finally {
|
|
23873
24207
|
moved.delete();
|
|
23874
24208
|
}
|
|
@@ -23878,7 +24212,7 @@ function computeTransformedBounds(geometry, query) {
|
|
|
23878
24212
|
}
|
|
23879
24213
|
);
|
|
23880
24214
|
}
|
|
23881
|
-
__name(
|
|
24215
|
+
__name(withTransformedGeometry, "withTransformedGeometry");
|
|
23882
24216
|
function pointBounds(points) {
|
|
23883
24217
|
if (!points.length)
|
|
23884
24218
|
throw new Error("Empty geometry has no directional bounds.");
|
|
@@ -23980,6 +24314,10 @@ function transformElement(element, transform) {
|
|
|
23980
24314
|
...element.topology,
|
|
23981
24315
|
transform: composeTransforms(transform, element.topology.transform)
|
|
23982
24316
|
} : void 0,
|
|
24317
|
+
parts: element.parts?.map((part) => ({
|
|
24318
|
+
...part,
|
|
24319
|
+
transform: composeTransforms(transform, part.transform)
|
|
24320
|
+
})),
|
|
23983
24321
|
members: element.members ? Object.fromEntries(
|
|
23984
24322
|
Object.entries(element.members).map(([name, member]) => [
|
|
23985
24323
|
name,
|
|
@@ -24004,6 +24342,11 @@ function scaleElement(element, factor) {
|
|
|
24004
24342
|
scale: element.topology.scale * factor,
|
|
24005
24343
|
transform: scaleFrame(element.topology.transform, factor)
|
|
24006
24344
|
} : void 0,
|
|
24345
|
+
parts: element.parts?.map((part) => ({
|
|
24346
|
+
...part,
|
|
24347
|
+
scale: part.scale * factor,
|
|
24348
|
+
transform: scaleFrame(part.transform, factor)
|
|
24349
|
+
})),
|
|
24007
24350
|
members: element.members ? scaleElements(element.members, factor) : void 0,
|
|
24008
24351
|
transform: {
|
|
24009
24352
|
...element.transform,
|
|
@@ -24655,8 +24998,8 @@ function sketchPointResolver(layers) {
|
|
|
24655
24998
|
const visiting = /* @__PURE__ */ new Set();
|
|
24656
24999
|
const resolve = /* @__PURE__ */ __name((ref) => {
|
|
24657
25000
|
const key = JSON.stringify([ref.layer, ref.id]);
|
|
24658
|
-
const
|
|
24659
|
-
if (
|
|
25001
|
+
const cached = resolved.get(key);
|
|
25002
|
+
if (cached) return cached;
|
|
24660
25003
|
const point3 = points.get(key);
|
|
24661
25004
|
if (!point3) throw new Error(`Missing sketch point ${ref.id}.`);
|
|
24662
25005
|
if (visiting.has(key))
|
|
@@ -24971,7 +25314,7 @@ __name(solvedProblem, "solvedProblem");
|
|
|
24971
25314
|
|
|
24972
25315
|
// packages/core/src/library/sketch-regions.ts
|
|
24973
25316
|
var tau2 = 2 * Math.PI;
|
|
24974
|
-
var
|
|
25317
|
+
var distance3 = /* @__PURE__ */ __name((a, b) => Math.hypot(a[0] - b[0], a[1] - b[1]), "distance");
|
|
24975
25318
|
function sketchRegions(layers) {
|
|
24976
25319
|
const resolve = sketchPointResolver(layers);
|
|
24977
25320
|
const points = new Map(
|
|
@@ -24993,7 +25336,7 @@ function sketchRegions(layers) {
|
|
|
24993
25336
|
const vertices = [];
|
|
24994
25337
|
const vertex = /* @__PURE__ */ __name((position2, tolerance2) => {
|
|
24995
25338
|
const index = vertices.findIndex(
|
|
24996
|
-
(v) =>
|
|
25339
|
+
(v) => distance3(v.position, position2) <= Math.min(v.tolerance, tolerance2)
|
|
24997
25340
|
);
|
|
24998
25341
|
if (index >= 0) return index;
|
|
24999
25342
|
vertices.push({ position: position2, tolerance: tolerance2, edges: [] });
|
|
@@ -25023,7 +25366,7 @@ function sketchRegions(layers) {
|
|
|
25023
25366
|
) || contacts.some(
|
|
25024
25367
|
(c) => c.parameters.some((_, j) => {
|
|
25025
25368
|
const curve = j === 0 ? a.curve : b.curve;
|
|
25026
|
-
return curve.kind === "circle" ||
|
|
25369
|
+
return curve.kind === "circle" || distance3(c.position, sketchCurvePosition(curve, 0)) > sketchCurveTolerance(curve) && distance3(c.position, sketchCurvePosition(curve, 1)) > sketchCurveTolerance(curve);
|
|
25027
25370
|
})
|
|
25028
25371
|
))
|
|
25029
25372
|
throw new Error(
|
|
@@ -25098,7 +25441,7 @@ function overlap(a, b, intersections) {
|
|
|
25098
25441
|
if (a.kind === "line" || b.kind === "line") {
|
|
25099
25442
|
if (a.kind !== "line" || b.kind !== "line" || intersections.length < 2)
|
|
25100
25443
|
return false;
|
|
25101
|
-
} else if (
|
|
25444
|
+
} else if (distance3(a.center, b.center) > Math.min(sketchCurveTolerance(a), sketchCurveTolerance(b)) || Math.abs(a.radius - b.radius) > Math.min(sketchCurveTolerance(a), sketchCurveTolerance(b)))
|
|
25102
25445
|
return false;
|
|
25103
25446
|
const cuts = [0, ...intersections, 1].sort((a2, b2) => a2 - b2);
|
|
25104
25447
|
return cuts.slice(1).some(
|
|
@@ -25161,10 +25504,11 @@ export {
|
|
|
25161
25504
|
clearKernelOperationCache,
|
|
25162
25505
|
kernelOperationCacheStats,
|
|
25163
25506
|
setKernelCacheBudget,
|
|
25507
|
+
setKernelCachePersistenceThreshold,
|
|
25164
25508
|
setKernelArtifactStore,
|
|
25165
25509
|
setKernelExternalBytes,
|
|
25166
25510
|
identifyCachedFunction,
|
|
25167
|
-
|
|
25511
|
+
cache,
|
|
25168
25512
|
googleFontUrl,
|
|
25169
25513
|
googleFontSources,
|
|
25170
25514
|
installFontEngine,
|
|
@@ -25231,6 +25575,7 @@ export {
|
|
|
25231
25575
|
regularPrism,
|
|
25232
25576
|
primitiveConstructor,
|
|
25233
25577
|
group,
|
|
25578
|
+
distance2 as distance,
|
|
25234
25579
|
union,
|
|
25235
25580
|
extrude,
|
|
25236
25581
|
text,
|
|
@@ -25266,4 +25611,4 @@ export {
|
|
|
25266
25611
|
assertSketchDragConnections,
|
|
25267
25612
|
solveSketchSnapshot
|
|
25268
25613
|
};
|
|
25269
|
-
//# sourceMappingURL=chunk-
|
|
25614
|
+
//# sourceMappingURL=chunk-MICNLFBF.js.map
|