test: failing regression test for #266: Multi-profile solid.extrude with body_name names only the first body (#281)
* test: reproduce #266 (Multi-profile solid.extrude with body_name names only the first body) * fix: name every body of a multi-body feature after body_name (#266) A new-body feature that makes more bodies than it was given names now stores Ribs (2), Ribs (3)... for the rest instead of falling back to generic BodyN names. Command-time only: saved designs keep their names. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT * fix: keep body_name list for the multi-body naming step (#266) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT --------- Co-authored-by: bherbruck <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2 files changed
+39
-1
No files matched your search
@@ -443,10 +443,33 @@ fn add_feature_in(s: &mut Session, p: &Value, kind: FeatureKind, world: bool) ->
|
||||
if !names.is_empty()
|
||||
&& let Some(f) = s.doc_mut().feature_mut(id)
|
||||
{
|
||||
f.body_names = names;
|
||||
f.body_names = names.clone();
|
||||
}
|
||||
s.active_sketch = None;
|
||||
s.refresh();
|
||||
// A feature that makes more bodies than it was given names (a multi-profile extrude with one
|
||||
// `body_name`) names the rest after the first: `Ribs`, `Ribs (2)`, `Ribs (3)`… (#266). The
|
||||
// names are stored on the feature, so recomputes and saved designs keep them.
|
||||
if let Some(base) = names.first().map(|n| n.trim().to_string()).filter(|n| !n.is_empty()) {
|
||||
let st = s.model.state();
|
||||
let made = st.bodies.iter().filter(|b| b.feature == id).count();
|
||||
if made > names.len() {
|
||||
let mut taken: std::collections::BTreeSet<String> = st.bodies.iter().map(|b| b.name.clone()).collect();
|
||||
taken.extend(names.iter().cloned());
|
||||
let mut i = 1usize;
|
||||
while names.len() < made {
|
||||
i += 1;
|
||||
let n = format!("{base} ({i})");
|
||||
if taken.insert(n.clone()) {
|
||||
names.push(n);
|
||||
}
|
||||
}
|
||||
if let Some(f) = s.doc_mut().feature_mut(id) {
|
||||
f.body_names = names;
|
||||
}
|
||||
s.refresh();
|
||||
}
|
||||
}
|
||||
let r = s.model.result(id).cloned();
|
||||
if let Some(e) = r.as_ref().and_then(|r| r.error.clone()) {
|
||||
return Err(EngineError::Other(e));
|
||||
|
||||
@@ -2489,6 +2489,21 @@ fn special_files_are_refused_by_every_file_command() {
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// Every body a multi-profile `new` extrude creates carries its `body_name`, not a generic BodyN (#266).
|
||||
#[test]
|
||||
fn multi_profile_extrude_names_every_body_after_body_name() {
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "sketch.create", json!({"plane": "XY", "name": "R"}));
|
||||
for x in [0, 10, 20] {
|
||||
run(&mut s, "sketch.rectangle.two_point", json!({"p0": [x, 0], "p1": [x + 5, 30]}));
|
||||
}
|
||||
run(&mut s, "sketch.finish", json!({}));
|
||||
run(&mut s, "solid.extrude", json!({"distance": "10", "operation": "new_body", "body_name": "Ribs"}));
|
||||
let names: Vec<String> = s.model.state().bodies.iter().map(|b| b.name.clone()).collect();
|
||||
assert!(names.iter().all(|n| n.starts_with("Ribs")), "{names:?}");
|
||||
assert!(rel(volume(&mut s), 4500.0) < 1e-6);
|
||||
}
|
||||
|
||||
/// Renaming one pattern copy leaves the other copies' names alone (#265).
|
||||
#[test]
|
||||
fn renaming_a_pattern_copy_keeps_the_other_copies_names() {
|
||||
|
||||
Reference in new issue
Block a user