STEP import takes up for Y-up files and names for the bodies' names (#1312)
file.insert_step and doc.open on a STEP file take `up` (turn a Y-up file so its up is +Z) and `names` (names for the imported bodies). The MCP tool and the app's control requests pass them through; an import without them works as before. Tests in the kernel's STEP reader, the engine, MCP and the file-load UI; docs/step-import.md and docs/mcp.md describe both.
This commit is contained in:
1 parent
81d9b7e04a
commit
0ee5e97db5
12 files changed
+572
-38
No files matched your search
@@ -196,6 +196,34 @@ fn agent_builds_box_fillet_hole() {
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// `open` hands `up` and `names` to the STEP import, and the tool's schema refuses other values.
|
||||
#[test]
|
||||
fn open_stands_a_y_up_step_file_up() {
|
||||
let mut s = server();
|
||||
tool(&mut s, "execute", json!({"command": "solid.box", "params": {"length": 10, "width": 40, "height": 5}}));
|
||||
let dir = std::env::temp_dir().join(format!("solidcraft-mcp-up-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let step = dir.join("tall.step").to_string_lossy().to_string();
|
||||
tool(&mut s, "export", json!({"path": step}));
|
||||
let height = |s: &mut Server| {
|
||||
let bbox = tool(s, "measure", json!({}))["bodies"][0]["bbox"].clone();
|
||||
bbox["max"][2].as_f64().unwrap() - bbox["min"][2].as_f64().unwrap()
|
||||
};
|
||||
|
||||
let r = tool(&mut s, "open", json!({"path": step}));
|
||||
assert_eq!(r["features"], 1, "{r}");
|
||||
assert!((height(&mut s) - 5.0).abs() < 1e-6, "as written");
|
||||
let r = tool(&mut s, "open", json!({"path": step, "up": "y", "names": "product"}));
|
||||
assert_eq!(r["features"], 2, "the import and the turn: {r}");
|
||||
assert!((height(&mut s) - 40.0).abs() < 1e-6, "Y became Z");
|
||||
|
||||
for args in [json!({"path": step, "up": "x"}), json!({"path": step, "names": "label"}), json!({"path": step, "up": 1})] {
|
||||
let r = raw_tool(&mut s, "open", args.clone());
|
||||
assert_eq!(r["error"]["code"], -32602, "{args}: {r}");
|
||||
}
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_selects_container_or_json_and_reopens_by_contents() {
|
||||
let mut s = server();
|
||||
|
||||
+12
-3
@@ -238,8 +238,17 @@ pub fn tool_definitions() -> Vec<Value> {
|
||||
"Open a design",
|
||||
"Open a .solidcraft design file, a STEP file (.step/.stp: a new design whose bodies come from the file, as an \
|
||||
Import base feature) or a 3MF/STL mesh (.3mf/.stl: mesh bodies). Replaces the current design; insert into it \
|
||||
instead with the file.insert_step (STEP) or file.insert_mesh (3MF/STL) commands.",
|
||||
obj(json!({"path": string("Path to a .solidcraft, .step/.stp, .3mf or .stl file")}), &["path"]),
|
||||
instead with the file.insert_step (STEP) or file.insert_mesh (3MF/STL) commands. A STEP file from a system \
|
||||
that has Y up opens lying on its back: `up: \"y\"` turns it a quarter turn about X (Y becomes Z) with a Move \
|
||||
feature. `names` picks what the bodies are named after when the solids' own names say nothing useful.",
|
||||
obj(
|
||||
json!({
|
||||
"path": string("Path to a .solidcraft, .step/.stp, .3mf or .stl file"),
|
||||
"up": {"type": "string", "enum": ["z", "y"], "description": "STEP only. z (default) keeps the file's axes; y: the file has Y up, so its bodies are turned to stand Z up"},
|
||||
"names": {"type": "string", "enum": ["solid", "product", "instance"], "description": "STEP only. What the bodies are named after: solid (default: the solid's own name, else the product's), product (the part's name) or instance (the assembly occurrence's name, else the product's)"},
|
||||
}),
|
||||
&["path"],
|
||||
),
|
||||
Effect::Files,
|
||||
),
|
||||
tool(
|
||||
@@ -401,7 +410,7 @@ fn dispatch(b: &mut dyn Backend, name: &str, a: &Map<String, Value>) -> Result<V
|
||||
"undo" => exec(b, "edit.undo", json!({})),
|
||||
"redo" => exec(b, "edit.redo", json!({})),
|
||||
"new_design" => exec(b, "file.new", pick(a, &["name"])),
|
||||
"open" => exec(b, "doc.open", pick(a, &["path"])),
|
||||
"open" => exec(b, "doc.open", pick(a, &["path", "up", "names"])),
|
||||
"save" => exec(b, "file.save", pick(a, &["path", "format"])),
|
||||
other => Err(format!("unknown tool `{other}`")),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user