mesh: a body the user's partitions cut is not meshed by symmetry (#473)

With a user's partition on a symmetric body, applying the whole body's plan cut it again by its
symmetry plane and mirrored one cell, leaving the other half unmeshed ("the mirror images do not
reach cell Base/b/a"). Such a body is its cells: the symmetry is not used and the plan is refused
with the cells named, as the replay of the saved Pi 5 model shows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-16 07:56:10 -04:00
1 parent 80da2d968b
commit eae709b3c0
1 file changed
+7
+7
View File
@@ -1222,6 +1222,10 @@ fn apply_symmetric(s: &mut Session, name: &str, plan: &MeshPlan) -> Result<Optio
}
let design = s.design.as_deref().ok_or_else(|| EngineError::Params("open a design first".into()))?;
let (Some(shape), Some(d)) = (design.source_body(&plan.body), plan.direction) else { return Ok(None) };
// A body other partitions have cut already is its cells (the whole body's plan is refused).
if plan_cut_names(s, name).is_empty() && design.body(&plan.body).is_none() {
return Ok(None);
}
let planes = symmetry_planes(shape, d, &plan.rings)?;
if planes.is_empty() {
return Ok(None);
@@ -1724,6 +1728,9 @@ mod tests {
assert_eq!(cell["rings"].as_array().map(Vec::len), Some(1), "{cell}");
let whole = s.execute("mesh.plan", &json!({"body": "Plate"})).unwrap();
assert_eq!(whole["body"], "Plate", "{whole}");
// The plate is symmetric too, but the user's partition has cut it: refused, not mirrored.
let e = s.execute("mesh.plan.apply", &json!({"plan": whole["name"]})).unwrap_err().to_string();
assert!(e.contains("cut into the cells"), "{e}");
s.execute("mesh.plan.apply", &json!({"plan": cell["name"]})).unwrap();
}