forked from 1b-agent/fieldcraft-upstream
ui-egui: select faces, edges, vertices, bodies, nodes and elements by picking
A click in the viewport picks what is under the pointer through the selection filter (the selection bar, top centre): geometry faces, edges, vertices and bodies, or mesh nodes, element faces and elements. Shift adds, Cmd/Ctrl adds or removes, a click on nothing clears, Escape clears; with Box on, a left drag selects the visible nodes, element faces or elements inside the box. What a click would pick is highlighted under the pointer with its name beside it. The selection is kept in the model's persistent terms: geometry by name (GeometryRef, named through the mesh's geometry tags or the drawn bodies' face names), so it survives a remesh, and the mesh by label (labels the model loses drop out). It reads as a set's members. Picking runs on the CPU against the triangles both renderers draw. The selection and the hover are drawn as an overlay in the theme's new pick_selected and pick_hover colours (light and dark), outlined; the GPU draws it as a second small layer, so a hover change uploads only that. Command forms that apply to part of the model (sets, boundary conditions, loads, sections, couplings) get a Target row whose Use selection fills the members, or makes a set of the selection and names it. A right click offers Create set from selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
This commit is contained in:
1 parent
32c67d1988
commit
9e269a9f45
8 files changed
+1686
-59
No files matched your search
@@ -6,10 +6,10 @@
|
||||
use egui::{RichText, vec2};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::ModelApp;
|
||||
use crate::browser::{self, Def};
|
||||
use crate::frame::{Level, heading};
|
||||
use crate::theme::{Tokens, label_font};
|
||||
use crate::{ModelApp, selection};
|
||||
|
||||
/// The panel's width.
|
||||
pub const WIDTH: f32 = 310.0;
|
||||
@@ -59,7 +59,11 @@ pub fn panel(app: &mut ModelApp, ui: &mut egui::Ui) {
|
||||
}
|
||||
|
||||
/// The open command's parameters as JSON, with the command's parameter documentation; OK runs it.
|
||||
/// A command that applies to part of the model (a set, a boundary condition, a load, a section, a
|
||||
/// coupling) has a Target row that takes the viewport's selection.
|
||||
fn form(app: &mut ModelApp, ui: &mut egui::Ui, t: &Tokens) {
|
||||
let selected = (!app.pick.selection.is_empty()).then(|| app.pick.selection.summary());
|
||||
let mut use_selection = false;
|
||||
let Some(d) = app.dialog.as_mut() else { return };
|
||||
let Some(spec) = fieldcraft_engine::find_command(d.command) else {
|
||||
app.dialog = None;
|
||||
@@ -74,6 +78,23 @@ fn form(app: &mut ModelApp, ui: &mut egui::Ui, t: &Tokens) {
|
||||
});
|
||||
ui.add_space(4.0);
|
||||
ui.label(RichText::new(spec.id).small().color(t.text_dim));
|
||||
let params = serde_json::from_str::<Value>(&d.text).unwrap_or(Value::Null);
|
||||
if let Some(target) = selection::target(spec.id, ¶ms) {
|
||||
heading(ui, t, Level::Section, |ui| {
|
||||
ui.label(RichText::new("Target").size(12.0));
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
let tip = match target {
|
||||
selection::Target::Members => "The selection becomes the set's members (geometry by name, the mesh by label)",
|
||||
selection::Target::Set | selection::Target::TargetSet => "Makes a set of the selection (model.set.create) and names it here",
|
||||
};
|
||||
use_selection = ui.add_enabled(selected.is_some(), egui::Button::new("Use selection")).on_hover_text(tip).clicked();
|
||||
match &selected {
|
||||
Some(text) => ui.label(RichText::new(text).color(t.pick_selected)),
|
||||
None => ui.label(RichText::new("Pick in the viewport, or type the names below").color(t.text_dim)),
|
||||
};
|
||||
});
|
||||
}
|
||||
heading(ui, t, Level::Section, |ui| {
|
||||
ui.label(RichText::new("Parameters").size(12.0));
|
||||
});
|
||||
@@ -98,6 +119,11 @@ fn form(app: &mut ModelApp, ui: &mut egui::Ui, t: &Tokens) {
|
||||
app.dialog = None;
|
||||
} else if run {
|
||||
let _ = app.run_dialog();
|
||||
} else if use_selection
|
||||
&& let Err(e) = app.use_selection_in_dialog()
|
||||
&& let Some(d) = app.dialog.as_mut()
|
||||
{
|
||||
d.error = Some(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user