fix file-open pipeline: detect_mode misclassified zcd and brace-containing source, new_file left stale viewport

This commit is contained in:
jess 2026-03-31 01:51:51 -07:00
parent 9b21350c87
commit 2cbd4355ab
1 changed files with 85 additions and 5 deletions

View File

@ -429,17 +429,17 @@ impl App {
{ {
match ext.to_lowercase().as_str() { match ext.to_lowercase().as_str() {
"scad" => { self.mode = InputMode::Scad; return; } "scad" => { self.mode = InputMode::Scad; return; }
"crd" | "obj" | "stl" | "3mf" => { self.mode = InputMode::Expr; return; } "crd" | "zcd" | "obj" | "stl" | "3mf" => { self.mode = InputMode::Expr; return; }
_ => {} _ => {}
} }
} }
let s = self.source.text(); let s = self.source.text();
let s = s.trim(); let s = s.trim();
if s.contains('{') || s.starts_with("module ") let has_scad_blocks = s.contains('{') && s.contains(';');
|| s.starts_with("for ") || s.starts_with("if ") let has_scad_keywords = s.starts_with("module ")
|| s.starts_with("difference") || s.starts_with("union") || s.starts_with("difference") || s.starts_with("union")
|| s.starts_with("intersection") || s.starts_with("intersection");
{ if has_scad_keywords || (has_scad_blocks && !s.starts_with("let ") && !s.starts_with("sch ") && !s.starts_with("//")) {
self.mode = InputMode::Scad; self.mode = InputMode::Scad;
} else { } else {
self.mode = InputMode::Expr; self.mode = InputMode::Expr;
@ -576,7 +576,13 @@ impl App {
self.mode = InputMode::Expr; self.mode = InputMode::Expr;
self.info = None; self.info = None;
self.error = None; self.error = None;
self.scene_objects.clear();
self.selected_object = None;
self.needs_cast = false;
self.needs_plot = false;
self.md_items.clear(); self.md_items.clear();
self.viewport.set_graph(&default_sphere_graph());
self.viewport.set_bounds(2.0);
self.status = Some("new file".into()); self.status = Some("new file".into());
} }
@ -2295,4 +2301,78 @@ mod tests {
let graph = cord_expr::resolve_scene(scene); let graph = cord_expr::resolve_scene(scene);
assert!(evaluate(&graph, 1.0, 2.0, 0.0) < 0.0); assert!(evaluate(&graph, 1.0, 2.0, 0.0) < 0.0);
} }
fn sim_reparse(src: &str) -> cord_trig::TrigGraph {
use cord_expr::{classify_from, expr_to_sdf};
let src = src.trim();
let scene = parse_expr_scene(src).expect("parse failed");
let mut graph = scene.graph;
let mut sdf_roots: Vec<cord_trig::ir::NodeId> = Vec::new();
let render_objects: Vec<_> = if scene.cast_all {
scene.all_vars.clone()
} else if !scene.casts.is_empty() {
scene.casts.clone()
} else {
Vec::new()
};
for &(_, id) in &render_objects {
sdf_roots.push(id);
}
let mut plot_nodes: Vec<cord_trig::ir::NodeId> = if scene.plot_all {
let mut nodes: Vec<_> = scene.all_vars.iter().map(|(_, id)| *id).collect();
nodes.extend(&scene.bare_exprs);
nodes
} else {
Vec::new()
};
plot_nodes.extend(&scene.plots);
for &node_id in &plot_nodes {
let info = classify_from(&graph, node_id);
let sdf = expr_to_sdf(&mut graph, node_id, info.dimensions, 0.05, 10.0);
sdf_roots.push(sdf);
}
if sdf_roots.len() >= 2 {
let mut root = sdf_roots[0];
for &node in &sdf_roots[1..] {
root = graph.push(cord_trig::TrigOp::Min(root, node));
}
graph.set_output(root);
} else if sdf_roots.len() == 1 {
graph.set_output(sdf_roots[0]);
} else {
let empty = graph.push(cord_trig::TrigOp::Const(1e10));
graph.set_output(empty);
}
graph
}
#[test]
fn open_file_produces_different_wgsl() {
let default_src = "let s = sphere(3)\ncast()";
let shell_src = std::fs::read_to_string(
concat!(env!("CARGO_MANIFEST_DIR"), "/../../examples/shell.crd")
).expect("can't read shell.crd");
let bolt_src = std::fs::read_to_string(
concat!(env!("CARGO_MANIFEST_DIR"), "/../../examples/bolt.crd")
).expect("can't read bolt.crd");
let default_graph = sim_reparse(default_src);
let shell_graph = sim_reparse(&shell_src);
let bolt_graph = sim_reparse(&bolt_src);
let default_wgsl = cord_shader::generate_wgsl_from_trig(&default_graph);
let shell_wgsl = cord_shader::generate_wgsl_from_trig(&shell_graph);
let bolt_wgsl = cord_shader::generate_wgsl_from_trig(&bolt_graph);
assert_ne!(default_wgsl, shell_wgsl, "shell.crd should produce different WGSL than default");
assert_ne!(default_wgsl, bolt_wgsl, "bolt.crd should produce different WGSL than default");
assert_ne!(shell_wgsl, bolt_wgsl, "shell and bolt should produce different WGSL");
assert!(shell_graph.nodes.len() > 10, "shell should have a nontrivial graph");
assert!(bolt_graph.nodes.len() > 10, "bolt should have a nontrivial graph");
}
} }