mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
CadDocument: reindex mate connectors on feature delete and reorder
mate_cs_a/mate_cs_b are feature indices. remove_feature() remapped sketch_ref through the deletion but not the mate connectors, and move_feature() swapped sketch_ref but not the mate connectors. Deleting or reordering any feature ahead of a connector slid both references onto whatever features landed on those slots. Nothing reported it. recompute() only rejects out-of-range and non-CoordSys targets, and a shifted index normally lands on the assembly's other CoordSys — an assembly carries at least two by construction. So the mate resolved against the wrong frames and moved the wrong body, silently. Extracted a remap lambda in remove_feature() and a swap_ref lambda in move_feature(), applied to sketch_ref and both mate connectors. Two tests, both confirmed red before the fix. [mate] tags green here: 395 assertions / 29 cases — the first end-to-end kernel compile of this fork. Ported from snaporca; CadDocument.cpp is byte-identical across forks again. Refs: snaporca-kqih Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0a2faedc32
commit
8ff7ba440d
@@ -1856,18 +1856,31 @@ bool CadDocument::remove_feature(int index)
|
||||
for (auto it = remove.rbegin(); it != remove.rend(); ++it)
|
||||
features.erase(features.begin() + *it);
|
||||
|
||||
// Remap surviving sketch_ref through the deletions: subtract the count of
|
||||
// Remap surviving feature references through the deletions: subtract the count of
|
||||
// removed indices that sat before it; orphaned refs (target removed) -> -1.
|
||||
for (auto& f : features) {
|
||||
if (f.type != CadFeatureType::Extrude || f.sketch_ref < 0)
|
||||
continue;
|
||||
if (std::binary_search(remove.begin(), remove.end(), f.sketch_ref)) {
|
||||
f.sketch_ref = -1;
|
||||
//
|
||||
// This must cover EVERY field holding a feature index, not just sketch_ref. A mate's two
|
||||
// connectors are such indices, and leaving them behind slid them onto whatever features
|
||||
// landed on those slots — silently, because recompute() only rejects out-of-range and
|
||||
// non-CoordSys targets, and a shifted index usually lands on the assembly's other CoordSys.
|
||||
auto remap = [&remove](int& ref) {
|
||||
if (ref < 0)
|
||||
return;
|
||||
if (std::binary_search(remove.begin(), remove.end(), ref)) {
|
||||
ref = -1;
|
||||
} else {
|
||||
int shift = 0;
|
||||
for (int r : remove)
|
||||
if (r < f.sketch_ref) ++shift;
|
||||
f.sketch_ref -= shift;
|
||||
if (r < ref) ++shift;
|
||||
ref -= shift;
|
||||
}
|
||||
};
|
||||
for (auto& f : features) {
|
||||
if (f.type == CadFeatureType::Extrude) {
|
||||
remap(f.sketch_ref);
|
||||
} else if (f.type == CadFeatureType::Mate) {
|
||||
remap(f.mate_cs_a);
|
||||
remap(f.mate_cs_b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1885,11 +1898,19 @@ bool CadDocument::move_feature(int index, int delta)
|
||||
std::vector<CadFeature> snapshot = features;
|
||||
std::swap(features[index], features[target]);
|
||||
|
||||
// The two slots traded places: fix any sketch_ref that pointed at either.
|
||||
// The two slots traded places: fix every feature reference that pointed at either —
|
||||
// a mate's connectors as well as sketch_ref, for the reason given in remove_feature().
|
||||
auto swap_ref = [index, target](int& ref) {
|
||||
if (ref == index) ref = target;
|
||||
else if (ref == target) ref = index;
|
||||
};
|
||||
for (auto& f : features) {
|
||||
if (f.type != CadFeatureType::Extrude) continue;
|
||||
if (f.sketch_ref == index) f.sketch_ref = target;
|
||||
else if (f.sketch_ref == target) f.sketch_ref = index;
|
||||
if (f.type == CadFeatureType::Extrude) {
|
||||
swap_ref(f.sketch_ref);
|
||||
} else if (f.type == CadFeatureType::Mate) {
|
||||
swap_ref(f.mate_cs_a);
|
||||
swap_ref(f.mate_cs_b);
|
||||
}
|
||||
}
|
||||
|
||||
return commit_or_rollback(*this, snapshot);
|
||||
|
||||
Reference in New Issue
Block a user