Combine: a cut keeps a body joined from separate pieces in one body (#2247)
Thanks @H1D.
This commit is contained in:
1 parent
5eb7640b54
commit
a4c4b411e5
3 files changed
+53
-8
No files matched your search
+10
-6
@@ -1764,8 +1764,9 @@ fn apply_traced(state: &mut ModelState, f: &Feature, tools: Vec<Traced>, op: Ope
|
||||
Operation::Cut | Operation::Intersect => {
|
||||
let bop = if op == Operation::Cut { BoolOp::Cut } else { BoolOp::Intersect };
|
||||
let tools = if op == Operation::Cut { clear_tools_as_one(tools) } else { tools };
|
||||
let affected: std::collections::BTreeSet<String> =
|
||||
target_idx.iter().filter_map(|i| state.bodies.get(*i).map(|b| b.name.clone())).collect();
|
||||
// Each target's pieces before the cut: a body joined from separate pieces stays one.
|
||||
let affected: std::collections::BTreeMap<String, usize> =
|
||||
target_idx.iter().filter_map(|i| state.bodies.get(*i)).map(|b| (b.name.clone(), b.body.lumps().map_or(1, |l| l.len()))).collect();
|
||||
let mut remove = Vec::new();
|
||||
for &ti in &target_idx {
|
||||
let Some(mut acc) = state.bodies.get(ti).map(|b| Some(b.traced())) else { continue };
|
||||
@@ -1793,16 +1794,19 @@ fn apply_traced(state: &mut ModelState, f: &Feature, tools: Vec<Traced>, op: Ope
|
||||
let live: std::collections::BTreeSet<&str> = state.bodies.iter().map(|b| b.name.as_str()).collect();
|
||||
state.threads.retain(|t| live.contains(t.body.as_str()));
|
||||
// A cut can leave a body in pieces: each piece becomes its own body ("Bar", "Bar (1)"),
|
||||
// numbered on past names already taken (a body cut in pieces before).
|
||||
// numbered on past names already taken (a body cut in pieces before). Only a cut that
|
||||
// made more pieces than the body had splits it: the pieces of a join stay together.
|
||||
// Not yet: a cut that splits one piece of such a body still splits all of them; keeping
|
||||
// the untouched ones together needs each new piece traced to the piece it came from.
|
||||
let mut taken: std::collections::BTreeSet<String> = state.bodies.iter().map(|b| b.name.clone()).collect();
|
||||
let mut split: Vec<ModelBody> = Vec::new();
|
||||
for mb in std::mem::take(&mut state.bodies) {
|
||||
if !affected.contains(&mb.name) || state.sheets.iter().any(|s| s.body == mb.name) {
|
||||
let Some(&had) = affected.get(&mb.name).filter(|_| !state.sheets.iter().any(|s| s.body == mb.name)) else {
|
||||
split.push(mb);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let pieces = mb.body.lumps().unwrap_or_else(|_| vec![mb.body.clone()]);
|
||||
if pieces.len() < 2 {
|
||||
if pieces.len() <= had {
|
||||
split.push(mb);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user