1use egui::Ui;
4
5const DEFAULT_MATERIALS: &[&str] = &[
7 "clay", "wax", "candy", "flat", "mud", "ceramic", "jade", "normal",
8];
9
10pub fn build_material_selector(
14 ui: &mut Ui,
15 material: &mut String,
16 available_materials: &[&str],
17) -> bool {
18 let materials: &[&str] = if available_materials.is_empty() {
19 DEFAULT_MATERIALS
20 } else {
21 available_materials
22 };
23
24 let mut changed = false;
25 egui::ComboBox::from_label("Material")
26 .selected_text(material.as_str())
27 .show_ui(ui, |ui| {
28 for &mat in materials {
29 if ui
30 .selectable_value(material, mat.to_string(), mat)
31 .changed()
32 {
33 changed = true;
34 }
35 }
36 });
37 changed
38}
39
40pub fn build_point_cloud_ui(
42 ui: &mut Ui,
43 num_points: usize,
44 point_radius: &mut f32,
45 base_color: &mut [f32; 3],
46 material: &mut String,
47 available_materials: &[&str],
48) -> bool {
49 let mut changed = false;
50
51 ui.label(format!("{num_points} points"));
52
53 if build_material_selector(ui, material, available_materials) {
54 changed = true;
55 }
56
57 egui::Grid::new("point_cloud_props")
58 .num_columns(2)
59 .show(ui, |ui| {
60 ui.label("Color:");
61 if ui.color_edit_button_rgb(base_color).changed() {
62 changed = true;
63 }
64 ui.end_row();
65
66 ui.label("Radius:");
67 if ui
68 .add(
69 egui::DragValue::new(point_radius)
70 .speed(0.001)
71 .range(0.001..=0.5),
72 )
73 .changed()
74 {
75 changed = true;
76 }
77 ui.end_row();
78 });
79
80 changed
81}
82
83pub fn build_surface_mesh_ui(
85 ui: &mut Ui,
86 num_vertices: usize,
87 num_faces: usize,
88 num_edges: usize,
89 shade_style: &mut u32,
90 surface_color: &mut [f32; 3],
91 transparency: &mut f32,
92 show_edges: &mut bool,
93 edge_width: &mut f32,
94 edge_color: &mut [f32; 3],
95 backface_policy: &mut u32,
96 material: &mut String,
97 available_materials: &[&str],
98) -> bool {
99 let mut changed = false;
100
101 ui.label(format!(
102 "{num_vertices} verts, {num_faces} faces, {num_edges} edges"
103 ));
104
105 if build_material_selector(ui, material, available_materials) {
106 changed = true;
107 }
108
109 ui.separator();
110
111 egui::ComboBox::from_label("Shading")
113 .selected_text(match *shade_style {
114 0 => "Smooth",
115 1 => "Flat",
116 _ => "Tri-Flat",
117 })
118 .show_ui(ui, |ui| {
119 if ui.selectable_value(shade_style, 0, "Smooth").changed() {
120 changed = true;
121 }
122 if ui.selectable_value(shade_style, 1, "Flat").changed() {
123 changed = true;
124 }
125 if ui.selectable_value(shade_style, 2, "Tri-Flat").changed() {
126 changed = true;
127 }
128 });
129
130 egui::Grid::new("mesh_color_grid")
132 .num_columns(2)
133 .show(ui, |ui| {
134 ui.label("Color:");
135 if ui.color_edit_button_rgb(surface_color).changed() {
136 changed = true;
137 }
138 ui.end_row();
139
140 ui.label("Opacity:");
143 let mut opacity = 1.0 - *transparency;
144 if ui.add(egui::Slider::new(&mut opacity, 0.0..=1.0)).changed() {
145 *transparency = 1.0 - opacity;
146 changed = true;
147 }
148 ui.end_row();
149 });
150
151 ui.separator();
152
153 if ui.checkbox(show_edges, "Show edges").changed() {
155 changed = true;
156 }
157
158 if *show_edges {
159 ui.indent("edges", |ui| {
160 egui::Grid::new("mesh_edge_grid")
161 .num_columns(2)
162 .show(ui, |ui| {
163 ui.label("Width:");
164 if ui
165 .add(egui::DragValue::new(edge_width).speed(0.1).range(0.1..=5.0))
166 .changed()
167 {
168 changed = true;
169 }
170 ui.end_row();
171
172 ui.label("Color:");
173 if ui.color_edit_button_rgb(edge_color).changed() {
174 changed = true;
175 }
176 ui.end_row();
177 });
178 });
179 }
180
181 ui.separator();
182
183 egui::ComboBox::from_label("Backface")
185 .selected_text(match *backface_policy {
186 0 => "Identical",
187 1 => "Different",
188 2 => "Custom",
189 _ => "Cull",
190 })
191 .show_ui(ui, |ui| {
192 if ui
193 .selectable_value(backface_policy, 0, "Identical")
194 .changed()
195 {
196 changed = true;
197 }
198 if ui
199 .selectable_value(backface_policy, 1, "Different")
200 .changed()
201 {
202 changed = true;
203 }
204 if ui.selectable_value(backface_policy, 2, "Custom").changed() {
205 changed = true;
206 }
207 if ui.selectable_value(backface_policy, 3, "Cull").changed() {
208 changed = true;
209 }
210 });
211
212 changed
213}
214
215pub fn build_curve_network_ui(
217 ui: &mut Ui,
218 num_nodes: usize,
219 num_edges: usize,
220 radius: &mut f32,
221 radius_is_relative: &mut bool,
222 color: &mut [f32; 3],
223 render_mode: &mut u32,
224 material: &mut String,
225 available_materials: &[&str],
226) -> bool {
227 let mut changed = false;
228
229 ui.label(format!("{num_nodes} nodes, {num_edges} edges"));
230
231 if build_material_selector(ui, material, available_materials) {
232 changed = true;
233 }
234
235 ui.separator();
236
237 egui::Grid::new("curve_network_grid")
238 .num_columns(2)
239 .show(ui, |ui| {
240 ui.label("Color:");
241 if ui.color_edit_button_rgb(color).changed() {
242 changed = true;
243 }
244 ui.end_row();
245
246 ui.label("Radius:");
247 if ui
248 .add(
249 egui::DragValue::new(radius)
250 .speed(0.001)
251 .range(0.001..=10.0),
252 )
253 .changed()
254 {
255 changed = true;
256 }
257 ui.end_row();
258 });
259
260 egui::ComboBox::from_label("Render")
262 .selected_text(match *render_mode {
263 0 => "Lines",
264 _ => "Tubes",
265 })
266 .show_ui(ui, |ui| {
267 if ui.selectable_value(render_mode, 0, "Lines").changed() {
268 changed = true;
269 }
270 if ui.selectable_value(render_mode, 1, "Tubes").changed() {
271 changed = true;
272 }
273 });
274
275 if ui.checkbox(radius_is_relative, "Relative radius").changed() {
277 changed = true;
278 }
279
280 changed
281}