forked from 1b-agent/fieldcraft-upstream
Partitions hide their datum plane
geometry.partition hides the plane it cuts by (view state, saved with the model): the cut shows as edges on the cells. The eye or selecting it in the browser shows it again. The crank samples so open without their planes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
dddb2d0584
commit
a0d11f1c22
4 files changed
+24
-5
No files matched your search
@@ -13,6 +13,7 @@ use crate::schema::ProblemKind;
|
||||
use std::sync::Arc;
|
||||
|
||||
use fieldcraft_geometry::{Cut, Design};
|
||||
use fieldcraft_io::{Item, ItemKind, MAX_HIDDEN};
|
||||
use fieldcraft_model::{Datum, Model, Partition};
|
||||
use serde::Deserialize;
|
||||
use serde_json::{Value, json};
|
||||
@@ -443,7 +444,7 @@ fn partition(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let name = super::name(p)?.to_string();
|
||||
let datum: String = super::req(p, "datum")?;
|
||||
let bodies: Vec<String> = super::opt(p, "bodies")?.unwrap_or_default();
|
||||
s.model.add_partition(Partition { name: name.clone(), datum, bodies })?;
|
||||
s.model.add_partition(Partition { name: name.clone(), datum: datum.clone(), bodies })?;
|
||||
recut(s)?;
|
||||
let design = s.design.as_deref().ok_or_else(|| EngineError::Params("open a design first".into()))?;
|
||||
let feature = format!("partition {name}");
|
||||
@@ -456,13 +457,19 @@ fn partition(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if split.is_empty() {
|
||||
return Err(EngineError::Params(format!("partition `{name}`: the plane divides no body of the design")));
|
||||
}
|
||||
let cells: Vec<&str> = design.bodies.iter().map(|b| b.name.as_str()).filter(|b| split.iter().any(|x| b.starts_with(&format!("{x}/")))).collect();
|
||||
let cells: Vec<String> = design.bodies.iter().map(|b| b.name.clone()).filter(|b| split.iter().any(|x| b.starts_with(&format!("{x}/")))).collect();
|
||||
let (faces, bodies): (usize, Vec<String>) = (report.map_or(0, |r| r.faces), design.bodies.iter().map(|b| b.name.clone()).collect());
|
||||
// The cut shows as edges on the cells, so the plane steps out of the way (view state, #295):
|
||||
// selecting it in the browser or its eye shows it again.
|
||||
if s.view.hidden.len() < MAX_HIDDEN {
|
||||
s.view.hidden.insert(Item { kind: ItemKind::Datum, name: datum });
|
||||
}
|
||||
Ok(json!({
|
||||
"name": name,
|
||||
"split": split,
|
||||
"cells": cells,
|
||||
"cut_faces": report.map_or(0, |r| r.faces),
|
||||
"bodies": design.bodies.iter().map(|b| b.name.as_str()).collect::<Vec<_>>(),
|
||||
"cut_faces": faces,
|
||||
"bodies": bodies,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -550,8 +557,13 @@ pub(crate) mod tests {
|
||||
let body = r["split"][0].as_str().unwrap().to_string();
|
||||
assert_eq!(r["cells"], json!([format!("{body}/a"), format!("{body}/b")]));
|
||||
assert_eq!(r["cut_faces"], json!(4));
|
||||
// The datum is in use.
|
||||
// The datum is in use, and hidden: the cut shows as edges on the cells (#295). Its eye
|
||||
// shows it again.
|
||||
assert!(s.execute("geometry.datum.delete", &json!({"name": "Mid"})).is_err());
|
||||
assert!(!s.shows(ItemKind::Datum, "Mid"));
|
||||
s.execute("view.show", &json!({"items": [{"kind": "datum", "name": "Mid"}]})).unwrap();
|
||||
assert!(s.shows(ItemKind::Datum, "Mid"));
|
||||
s.execute("view.hide", &json!({"items": [{"kind": "datum", "name": "Mid"}]})).unwrap();
|
||||
|
||||
// A set on a cut face selects the cut face's pieces.
|
||||
let r = s.execute("geometry.bodies", &json!({})).unwrap();
|
||||
@@ -564,6 +576,7 @@ pub(crate) mod tests {
|
||||
let mut t = Session::default();
|
||||
t.execute("file.open", &json!({"path": file.to_str().unwrap()})).unwrap();
|
||||
assert_eq!(bodies(&t), bodies(&s));
|
||||
assert!(!t.shows(ItemKind::Datum, "Mid"), "still hidden when opened again");
|
||||
// geometry.open again keeps the model, so its partition.
|
||||
let design = dir.join("plate.solidcraft");
|
||||
let r = t.execute("geometry.open", &json!({"path": design.to_str().unwrap()})).unwrap();
|
||||
|
||||
@@ -105,6 +105,7 @@ fn open_sample(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
opened.run_script(&script)?;
|
||||
// A sample just opened has nothing to save: it opens again the same way.
|
||||
opened.saved_revision = Some(opened.revision);
|
||||
opened.saved_view = opened.view.clone();
|
||||
s.replace_with(opened);
|
||||
let mut reply = summary(s, &[]);
|
||||
reply["sample"] = json!(sample.name);
|
||||
|
||||
@@ -879,6 +879,9 @@ mod tests {
|
||||
let mut cells: Vec<String> = CRANK_CELLS.iter().map(|c| c.to_string()).collect();
|
||||
cells.push("CrankArm/b".into());
|
||||
assert_eq!(bodies, cells);
|
||||
// The partitions' datum planes are hidden: the crank opens without a cage of planes.
|
||||
assert!(s.model.datums().len() >= 7 && s.model.datums().keys().all(|d| !s.shows(crate::ItemKind::Datum, d)), "datums shown");
|
||||
assert!(!s.is_dirty(), "a sample just opened has nothing to save");
|
||||
assert!(s.model.ties().is_empty(), "every cut merged");
|
||||
let elements = s.model.elements().values().filter(|e| e.kind == fieldcraft_model::ElementKind::Hex20).count();
|
||||
assert_eq!(elements, s.model.elements().len());
|
||||
|
||||
@@ -222,6 +222,8 @@ mod tests {
|
||||
app.run("geometry.open", json!({"path": design.to_string_lossy()})).unwrap();
|
||||
app.run("geometry.datum", json!({"name": "Mid", "by": {"type": "offset", "plane": "yz", "offset": 15}})).unwrap();
|
||||
app.run("geometry.partition", json!({"name": "Half", "datum": "Mid"})).unwrap();
|
||||
// The partition hides its plane (#295); shown again here to be picked.
|
||||
app.run("view.show", json!({"items": [{"kind": "datum", "name": "Mid"}]})).unwrap();
|
||||
app.run("geometry.datum.point", json!({"name": "P", "by": {"type": "coordinates", "point": [0, 0, 0]}})).unwrap();
|
||||
app.viewport.rect = Some(egui::Rect::from_min_size(egui::pos2(100.0, 50.0), egui::vec2(800.0, 600.0)));
|
||||
app.set_view(StandardView::Iso);
|
||||
|
||||
Reference in new issue
Block a user