UI: seeds as ticks along their edges, Mesh › Seeds, and seeding the selection

A seed draws a tick at each node it puts on its edge, so a bias shows as ticks
crowding toward an end. The browser lists the seeds under Mesh; a click
selects the seeded edge. The Seed Edges form takes the selected edges with
Use selection. The toolbar entry is ready (its icon renamed with it).

Part of #230.

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-14 20:58:17 -04:00
1 parent e8cada94d0
commit 8df4ea040c
9 files changed
+134 -4

No files matched your search

+48
View File
@@ -296,6 +296,20 @@ enum Act {
ShowResult(String),
}
/// A seed in a few words: `8 exact`, `2.5 min, bias 4 end`.
fn seed_note(s: &fieldcraft_model::Seed) -> String {
let what = match s.divisions {
fieldcraft_model::Divisions::Count(n) => format!("{n}"),
fieldcraft_model::Divisions::Size(h) => format!("size {h}"),
};
let bias = s.bias.map(|b| format!(", bias {} {}", b.ratio, json_name(&b.toward))).unwrap_or_default();
format!("{what} {}{bias}", s.constraint.name())
}
fn json_name<T: serde::Serialize>(v: &T) -> String {
serde_json::to_value(v).ok().and_then(|v| v.as_str().map(str::to_string)).unwrap_or_default()
}
pub fn browser(app: &mut ModelApp, ui: &mut egui::Ui) {
let t = Tokens::get(app.ui.dark);
let mut acts: Vec<Act> = Vec::new();
@@ -485,6 +499,40 @@ fn rows(app: &mut ModelApp, ui: &mut egui::Ui, acts: &mut Vec<Act>) {
&Row { depth: 2, swatch: Some(t.element(kind)), label: kind.name(), note: Some(format!("{n}")), ..Default::default() },
);
}
// Edge seeds: a click selects the seeded edge in the viewport.
let seeds: Vec<(fieldcraft_model::GeometryRef, String)> = app.session.model.seeds().iter().map(|s| (s.edge.clone(), seed_note(s))).collect();
if !seeds.is_empty() {
let r = draw_row(
app,
ui,
egui::Id::new("fc_row_seeds"),
&Row {
depth: 2,
fold: Some(open(app, "seeds")),
icon: Some("mesh.seed.edge"),
label: "Seeds",
note: Some(format!("{}", seeds.len())),
..Default::default()
},
);
if r.fold || r.clicked {
acts.push(Act::Fold("seeds".into()));
}
if open(app, "seeds") {
for (i, (edge, note)) in seeds.into_iter().enumerate() {
let label = format!("{} · {}", edge.body, edge.entity.name().unwrap_or_default());
let r = draw_row(
app,
ui,
egui::Id::new(("fc_row_seed", i)),
&Row { depth: 3, label: &label, note: Some(note), ..Default::default() },
);
if r.clicked {
app.select([crate::selection::Item::Geometry(edge)], crate::selection::Mode::Replace);
}
}
}
}
}
// Definitions.
let groups: [(&str, &str, &[Def]); 7] = [