Skip to content

Commit 79ef713

Browse files
committed
void update boundary provenance
1 parent e2e36ac commit 79ef713

2 files changed

Lines changed: 64 additions & 15 deletions

File tree

src/void/api/solids.js

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,8 +2307,9 @@ function edgeKey(a, b) {
23072307
};
23082308
},
23092309

2310-
resolveEdgeFromSource(source = {}) {
2310+
resolveEdgeFromSource(source = {}, options = {}) {
23112311
if (source?.type !== 'solid-edge') return null;
2312+
const allowGlobalFallback = options?.allowGlobalFallback !== false;
23122313
const targetSolidId = String(source?.solid_id || '');
23132314
const targetFeatureId = String(source?.solid_feature_id || '');
23142315
const sourceFaceId = Number(source?.face_id);
@@ -2380,11 +2381,13 @@ function edgeKey(a, b) {
23802381
}
23812382
if (byFeature.length) searchSets.push(byFeature);
23822383
}
2383-
const all = [];
2384-
for (const solid of solids) {
2385-
if (solid?.id) all.push(String(solid.id));
2384+
if (allowGlobalFallback) {
2385+
const all = [];
2386+
for (const solid of solids) {
2387+
if (solid?.id) all.push(String(solid.id));
2388+
}
2389+
if (all.length) searchSets.push(all);
23862390
}
2387-
if (all.length) searchSets.push(all);
23882391
let best = null;
23892392
let bestScore = Infinity;
23902393
const scanSet = (wanted = []) => {
@@ -2418,7 +2421,7 @@ function edgeKey(a, b) {
24182421
return best;
24192422
},
24202423

2421-
resolvePointFromSource(source = {}) {
2424+
resolvePointFromSource(source = {}, options = {}) {
24222425
if (source?.type !== 'solid-edge') return null;
24232426
const targetSolidId = String(source?.solid_id || '');
24242427
const sourceFaceId = Number(source?.face_id);
@@ -2432,7 +2435,7 @@ function edgeKey(a, b) {
24322435
if (world) return world;
24332436
}
24342437
}
2435-
const seg = this.resolveEdgeFromSource(source);
2438+
const seg = this.resolveEdgeFromSource(source, options);
24362439
if (!seg) return null;
24372440
const kind = source?.point_kind || 'mid';
24382441
if (kind === 'a') return seg.aWorld;
@@ -2946,9 +2949,10 @@ function edgeKey(a, b) {
29462949
};
29472950
},
29482951

2949-
resolveSketchFrameForSource(source, preferredFrame = null) {
2952+
resolveSketchFrameForSource(source, preferredFrame = null, options = {}) {
29502953
const sourceType = String(source?.type || '');
29512954
if (sourceType !== 'solid-face' && sourceType !== 'face') return null;
2955+
const allowGlobalFallback = options?.allowGlobalFallback !== false;
29522956
const solidId = String(source?.solid_id || '');
29532957
const preferredSolidId = solidId || null;
29542958
const view = solidId ? this._meshViews.get(solidId) : null;
@@ -3060,7 +3064,7 @@ function edgeKey(a, b) {
30603064
evalView(c.sid, c.meshView, 0.06);
30613065
}
30623066
}
3063-
if (!best) {
3067+
if (!best && allowGlobalFallback) {
30643068
for (const c of candidates) {
30653069
const bias = preferredSolidId && c.sid === preferredSolidId ? 0.02 : 0;
30663070
evalView(c.sid, c.meshView, bias);
@@ -3075,12 +3079,14 @@ function edgeKey(a, b) {
30753079
};
30763080
},
30773081

3078-
refreshSketchFaceAttachments() {
3082+
refreshSketchFaceAttachments(options = {}) {
30793083
const api = getApi();
30803084
const features = api.features.list() || [];
3085+
const eligible = options?.eligibleSketchIds instanceof Set ? options.eligibleSketchIds : null;
30813086
let changed = false;
30823087
for (const feature of features) {
30833088
if (feature?.type !== 'sketch') continue;
3089+
if (eligible && !eligible.has(String(feature?.id || ''))) continue;
30843090
const target = feature?.target || {};
30853091
let source = target?.source || null;
30863092
let resolved = null;
@@ -3134,7 +3140,11 @@ function edgeKey(a, b) {
31343140
}
31353141
if (source?.type !== 'solid-face' && source?.type !== 'face') continue;
31363142
if (!resolved) {
3137-
resolved = this.resolveSketchFrameForSource(source, feature.plane || null);
3143+
// Auto-refresh path must not drift to unrelated/newer solids when
3144+
// the original source solid/face no longer exists.
3145+
resolved = this.resolveSketchFrameForSource(source, feature.plane || null, {
3146+
allowGlobalFallback: false
3147+
});
31383148
}
31393149
if (!resolved?.frame) continue;
31403150
const frame = this.applyOffsetToFrame(resolved.frame, Number(feature?.target?.offset || 0));
@@ -3371,14 +3381,49 @@ function edgeKey(a, b) {
33713381
}
33723382
this._meshCache = result?.meshCache || new Map();
33733383
this.syncRuntime();
3384+
const allFeatures = api.features.list() || [];
3385+
const featureIndexById = new Map(allFeatures.map((f, i) => [String(f?.id || ''), i]));
3386+
const eligibleSketchIds = new Set();
3387+
const getFeatureIndex = (fid) => {
3388+
const key = String(fid || '');
3389+
if (!key) return -1;
3390+
const idx = featureIndexById.get(key);
3391+
return Number.isFinite(idx) ? Number(idx) : -1;
3392+
};
3393+
const hasFutureSourceDependency = (sketchFeature) => {
3394+
const sketchIndex = getFeatureIndex(sketchFeature?.id);
3395+
if (sketchIndex < 0) return false;
3396+
const sourceFeatureIds = new Set();
3397+
const targetSource = sketchFeature?.target?.source || null;
3398+
const targetSourceFeatureId = String(targetSource?.solid_feature_id || '');
3399+
if (targetSourceFeatureId) sourceFeatureIds.add(targetSourceFeatureId);
3400+
const entities = Array.isArray(sketchFeature?.entities) ? sketchFeature.entities : [];
3401+
for (const entity of entities) {
3402+
if (!entity?.derived) continue;
3403+
const src = entity?.source || null;
3404+
const srcFeatureId = String(src?.solid_feature_id || '');
3405+
if (srcFeatureId) sourceFeatureIds.add(srcFeatureId);
3406+
}
3407+
for (const srcId of sourceFeatureIds) {
3408+
const srcIndex = getFeatureIndex(srcId);
3409+
if (srcIndex > sketchIndex) return true;
3410+
}
3411+
return false;
3412+
};
3413+
for (const feature of allFeatures) {
3414+
if (feature?.type !== 'sketch') continue;
3415+
if (hasFutureSourceDependency(feature)) continue;
3416+
eligibleSketchIds.add(String(feature?.id || ''));
3417+
}
33743418
let derivedChanged = false;
3375-
for (const feature of (api.features.list() || [])) {
3419+
for (const feature of allFeatures) {
33763420
if (feature?.type !== 'sketch') continue;
3421+
if (!eligibleSketchIds.has(String(feature?.id || ''))) continue;
33773422
if (api.interact?.refreshDerivedSketchGeometry?.(feature)) {
33783423
derivedChanged = true;
33793424
}
33803425
}
3381-
const rebound = this.refreshSketchFaceAttachments();
3426+
const rebound = this.refreshSketchFaceAttachments({ eligibleSketchIds });
33823427
if (rebound || derivedChanged) {
33833428
if (persist) {
33843429
await api.document.save({

src/void/sketch/create.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,7 +2063,9 @@ function refreshDerivedSketchGeometry(feature) {
20632063
let changed = false;
20642064

20652065
const updatePointFromSource = (point, source) => {
2066-
const world = api.solids?.resolvePointFromSource?.(source) || null;
2066+
const world = api.solids?.resolvePointFromSource?.(source, {
2067+
allowGlobalFallback: false
2068+
}) || null;
20672069
if (!world) return;
20682070
const local = this.worldToSketchLocal(world, basis);
20692071
if (!local) return;
@@ -2078,7 +2080,9 @@ function refreshDerivedSketchGeometry(feature) {
20782080
updatePointFromSource(point, point.source || null);
20792081
}
20802082
for (const line of derivedLines) {
2081-
const seg = api.solids?.resolveEdgeFromSource?.(line.source || null);
2083+
const seg = api.solids?.resolveEdgeFromSource?.(line.source || null, {
2084+
allowGlobalFallback: false
2085+
});
20822086
if (!seg) continue;
20832087
const p1 = byId.get(line.a);
20842088
const p2 = byId.get(line.b);

0 commit comments

Comments
 (0)