graphic design tool
git clone https://git.lucas.co/cce-designer.git
refactor: the Remesh subnet's switch is transfer_switch1, not result1
A Remesh saved with result1 is renamed on load, its output's wire with
it, so it keeps matching the template.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md | 6 ++++--
nodes/remesh.json | 4 ++--
src/app.rs | 27 +++++++++++++++++++++++++++
src/main.rs | 35 +++++++++++++++++++++++++++++++++--
4 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index af7796e..60439b6 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1185,7 +1185,7 @@ into and its passes read, bypassed and rewired. `nodes/remesh.json`:
```
remesh1 (node) input1 → repeat1 → transfer1 ─┐
- └──────────── result1 (switch on Transfer) → output1
+ └──────────── transfer_switch1 (on Transfer) → output1
repeat1 (repeat, Iterations = chi("../Iterations"), Stop When Unchanged on)
input1 → split1 → collapse1 → flip1 → relax1 → project1 → output1
seed1 ───────────────────────────────────────┘ (Surface)
@@ -1241,7 +1241,9 @@ position, flags and values (`recompose_native_embryo`, which does both
now). The native node's **Split / Collapse / Flip / Project** switches are
not rows of the subnet — the passes are nodes — so one that was off
BYPASSES its node inside (`REMESH_PASS_SWITCHES`).
-`a_native_remesh_recomposes_on_load` is the test. A saved simnet holding a
+`a_native_remesh_recomposes_on_load` is the test. The switch was
+`result1` for its first day; a Remesh saved then is renamed on load
+(`rename_remesh_switch`, `a_remesh_saved_with_result1_is_renamed_on_load`). A saved simnet holding a
remesh changes its JSON by this, so its solve goes on from the frame in
hand under a new key ("An edit is in from the next frame").
diff --git a/nodes/remesh.json b/nodes/remesh.json
index 6bea3ea..c6806be 100644
--- a/nodes/remesh.json
+++ b/nodes/remesh.json
@@ -292,7 +292,7 @@
"geometry_visible": false
},
{
- "name": "result1",
+ "name": "transfer_switch1",
"type": "switch",
"position": [
0.0,
@@ -324,7 +324,7 @@
"params": [
{
"name": "Input",
- "default": "result1"
+ "default": "transfer_switch1"
}
],
"geometry_visible": false
diff --git a/src/app.rs b/src/app.rs
index e2ee10d..1715a67 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1082,6 +1082,33 @@ pub fn merge_template_defs(root: &mut FsNode, templates: &[NodeTemplate]) {
}
recompose_native_embryo(root, templates);
+ // The Remesh subnet's switch was `result1` for its first day
+ // (2026-09-30), and is `transfer_switch1`: a saved Remesh is renamed to
+ // match, its output's wire with it, or it would stop matching the
+ // template by its children's names and take no template change again.
+ fn rename_remesh_switch(node: &mut FsNode) {
+ for c in &mut node.children {
+ if c.node_type == "node"
+ && c.children.iter().any(|k| k.name == "result1" && k.node_type == "switch")
+ && c.children.iter().any(|k| k.name == "repeat1" && k.node_type == "repeat")
+ && !c.children.iter().any(|k| k.name == "transfer_switch1")
+ {
+ for k in &mut c.children {
+ if k.name == "result1" {
+ k.name = "transfer_switch1".into();
+ }
+ for p in &mut k.params {
+ if p.kind() == ParamKind::Node && p.text().trim() == "result1" {
+ p.set_text("transfer_switch1".to_string());
+ }
+ }
+ }
+ }
+ rename_remesh_switch(c);
+ }
+ }
+ rename_remesh_switch(root);
+
// A KERNEL SUBNET — a Sphere, Box, Plane or Extrude instance saved while
// those templates were `input → opencl → output` subnets (until
// 2026-09-24) — becomes the native node of that type: id, name,
diff --git a/src/main.rs b/src/main.rs
index 30710b8..4648b17 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11077,14 +11077,14 @@ mod tests {
let t = templates.children.iter().find(|t| t.name == "Remesh").expect("the Remesh template");
assert_eq!(t.node_type, "node", "the Remesh is a subnet");
let names: Vec<&str> = t.children.iter().map(|c| c.name.as_str()).collect();
- assert_eq!(names, ["input1", "repeat1", "transfer1", "result1", "output1"]);
+ assert_eq!(names, ["input1", "repeat1", "transfer1", "transfer_switch1", "output1"]);
let repeat = &t.children[1];
assert_eq!(repeat.node_type, "repeat");
let passes: Vec<(&str, &str)> = repeat.children.iter().map(|c| (c.name.as_str(), c.node_type.as_str())).collect();
assert_eq!(passes, [("input1", "input"), ("seed1", "seed"), ("split1", "split_edges"), ("collapse1", "collapse_edges"),
("flip1", "flip_edges"), ("relax1", "relax"), ("project1", "project"), ("output1", "output")]);
for c in &t.children {
- assert_eq!(c.geometry_visible, c.name == "result1", "only result1 draws: {}", c.name);
+ assert_eq!(c.geometry_visible, c.name == "transfer_switch1", "only transfer_switch1 draws: {}", c.name);
}
let tagged = [
@@ -11196,6 +11196,37 @@ mod tests {
assert!(g.num_points() > 0 && g == made, "the recomposed remesh makes the mesh the native one made");
}
+ /// The Remesh subnet's switch was `result1` for a day; a Remesh saved
+ /// then loads with it renamed, and its output wired to the new name.
+ #[test]
+ fn a_remesh_saved_with_result1_is_renamed_on_load() {
+ let templates_root = crate::app::load_fs_tree();
+ let templates = crate::app::flatten_node_templates(&templates_root);
+ let mut old = templates_root.children.iter().find(|t| t.name == "Remesh").unwrap().clone();
+ crate::app::regenerate_node_ids(&mut old);
+ old.name = "remesh1".into();
+ for k in &mut old.children {
+ if k.name == "transfer_switch1" {
+ k.name = "result1".into();
+ }
+ for p in &mut k.params {
+ if p.text() == "transfer_switch1" {
+ p.set_text("result1");
+ }
+ }
+ }
+ let mut root = modelling_root("1.0", vec![old]);
+ root.children[1].params.iter_mut().find(|p| p.name == "Input").unwrap().set_text("sphere 1");
+ crate::app::merge_template_defs(&mut root, &templates);
+ let r = &root.children[1];
+ let names: Vec<&str> = r.children.iter().map(|c| c.name.as_str()).collect();
+ assert_eq!(names, ["input1", "repeat1", "transfer1", "transfer_switch1", "output1"]);
+ let out = r.children.iter().find(|c| c.name == "output1").unwrap();
+ assert_eq!(out.params.iter().find(|p| p.name == "Input").unwrap().text(), "transfer_switch1");
+ let (g, err) = eval_node(&root, "remesh1");
+ assert!(err.is_none() && g.num_points() > 0, "{err:?}");
+ }
+
/// A Repeat runs its chain Iterations times, each pass on the last one's
/// result; a Seed inside reads what the loop began from. Dived in, its
/// chain is shown as the LAST pass saw it, as a simnet's is shown as its