1use crate::{SurfaceMesh, Vec2, Vec3, Vec4, with_context_mut};
36use glam::UVec3;
37
38pub trait IntoFaceList {
45 fn into_face_list(self) -> Vec<Vec<u32>>;
47}
48
49impl IntoFaceList for Vec<UVec3> {
50 fn into_face_list(self) -> Vec<Vec<u32>> {
51 self.into_iter().map(|f| vec![f.x, f.y, f.z]).collect()
52 }
53}
54
55impl IntoFaceList for Vec<[u32; 3]> {
56 fn into_face_list(self) -> Vec<Vec<u32>> {
57 self.into_iter().map(|f| f.to_vec()).collect()
58 }
59}
60
61impl IntoFaceList for Vec<Vec<u32>> {
62 fn into_face_list(self) -> Vec<Vec<u32>> {
63 self
64 }
65}
66
67pub fn register_surface_mesh(
81 name: impl Into<String>,
82 vertices: Vec<Vec3>,
83 faces: impl IntoFaceList,
84) -> SurfaceMeshHandle {
85 let name = name.into();
86 let faces = faces.into_face_list();
87 let n_verts = vertices.len();
88
89 for (i, face) in faces.iter().enumerate() {
91 assert!(
92 face.len() >= 3,
93 "Face {i} has {} vertices (minimum 3 required)",
94 face.len()
95 );
96 for &idx in face {
97 assert!(
98 (idx as usize) < n_verts,
99 "Face {i} contains vertex index {idx} but mesh only has {n_verts} vertices"
100 );
101 }
102 }
103
104 let mesh = SurfaceMesh::new(name.clone(), vertices, faces);
105
106 with_context_mut(|ctx| {
107 ctx.registry
108 .register(Box::new(mesh))
109 .expect("failed to register surface mesh");
110 ctx.update_extents();
111 });
112
113 SurfaceMeshHandle { name }
114}
115
116impl_structure_accessors! {
117 get_fn = get_surface_mesh,
118 with_fn = with_surface_mesh,
119 with_ref_fn = with_surface_mesh_ref,
120 handle = SurfaceMeshHandle,
121 type_name = "SurfaceMesh",
122 rust_type = SurfaceMesh,
123 doc_name = "surface mesh"
124}
125
126#[derive(Clone)]
145pub struct SurfaceMeshHandle {
146 name: String,
147}
148
149impl SurfaceMeshHandle {
150 #[must_use]
152 pub fn name(&self) -> &str {
153 &self.name
154 }
155
156 pub fn set_surface_color(&self, color: Vec3) -> &Self {
160 with_surface_mesh(&self.name, |mesh| {
161 mesh.set_surface_color(color);
162 });
163 self
164 }
165
166 pub fn set_edge_color(&self, color: Vec3) -> &Self {
168 with_surface_mesh(&self.name, |mesh| {
169 mesh.set_edge_color(color);
170 });
171 self
172 }
173
174 pub fn set_edge_width(&self, width: f32) -> &Self {
176 with_surface_mesh(&self.name, |mesh| {
177 mesh.set_edge_width(width);
178 });
179 self
180 }
181
182 pub fn set_show_edges(&self, show: bool) -> &Self {
184 with_surface_mesh(&self.name, |mesh| {
185 mesh.set_show_edges(show);
186 });
187 self
188 }
189
190 pub fn set_backface_color(&self, color: Vec3) -> &Self {
192 with_surface_mesh(&self.name, |mesh| {
193 mesh.set_backface_color(color);
194 });
195 self
196 }
197
198 pub fn set_transparency(&self, transparency: f32) -> &Self {
200 with_surface_mesh(&self.name, |mesh| {
201 mesh.set_transparency(transparency);
202 });
203 self
204 }
205
206 pub fn set_material(&self, material: &str) -> &Self {
208 use polyscope_core::Structure;
209 with_surface_mesh(&self.name, |mesh| {
210 mesh.set_material(material);
211 });
212 self
213 }
214
215 pub fn add_vertex_scalar_quantity(&self, name: &str, values: Vec<f32>) -> &Self {
219 with_surface_mesh(&self.name, |mesh| {
220 mesh.add_vertex_scalar_quantity(name, values);
221 });
222 self
223 }
224
225 pub fn add_face_scalar_quantity(&self, name: &str, values: Vec<f32>) -> &Self {
227 with_surface_mesh(&self.name, |mesh| {
228 mesh.add_face_scalar_quantity(name, values);
229 });
230 self
231 }
232
233 pub fn add_vertex_color_quantity(&self, name: &str, colors: Vec<Vec3>) -> &Self {
235 with_surface_mesh(&self.name, |mesh| {
236 mesh.add_vertex_color_quantity(name, colors);
237 });
238 self
239 }
240
241 pub fn add_vertex_color_quantity_with_alpha(&self, name: &str, colors: Vec<Vec4>) -> &Self {
246 with_surface_mesh(&self.name, |mesh| {
247 mesh.add_vertex_color_quantity_with_alpha(name, colors);
248 });
249 self
250 }
251
252 pub fn add_face_color_quantity(&self, name: &str, colors: Vec<Vec3>) -> &Self {
254 with_surface_mesh(&self.name, |mesh| {
255 mesh.add_face_color_quantity(name, colors);
256 });
257 self
258 }
259
260 pub fn add_face_color_quantity_with_alpha(&self, name: &str, colors: Vec<Vec4>) -> &Self {
265 with_surface_mesh(&self.name, |mesh| {
266 mesh.add_face_color_quantity_with_alpha(name, colors);
267 });
268 self
269 }
270
271 pub fn add_vertex_vector_quantity(&self, name: &str, vectors: Vec<Vec3>) -> &Self {
273 with_surface_mesh(&self.name, |mesh| {
274 mesh.add_vertex_vector_quantity(name, vectors);
275 });
276 self
277 }
278
279 pub fn add_face_vector_quantity(&self, name: &str, vectors: Vec<Vec3>) -> &Self {
281 with_surface_mesh(&self.name, |mesh| {
282 mesh.add_face_vector_quantity(name, vectors);
283 });
284 self
285 }
286
287 pub fn add_vertex_parameterization_quantity(&self, name: &str, coords: Vec<Vec2>) -> &Self {
289 with_surface_mesh(&self.name, |mesh| {
290 mesh.add_vertex_parameterization_quantity(name, coords);
291 });
292 self
293 }
294
295 pub fn add_corner_parameterization_quantity(&self, name: &str, coords: Vec<Vec2>) -> &Self {
297 with_surface_mesh(&self.name, |mesh| {
298 mesh.add_corner_parameterization_quantity(name, coords);
299 });
300 self
301 }
302
303 pub fn add_vertex_intrinsic_vector_quantity(
305 &self,
306 name: &str,
307 vectors: Vec<Vec2>,
308 basis_x: Vec<Vec3>,
309 basis_y: Vec<Vec3>,
310 ) -> &Self {
311 with_surface_mesh(&self.name, |mesh| {
312 mesh.add_vertex_intrinsic_vector_quantity(name, vectors, basis_x, basis_y);
313 });
314 self
315 }
316
317 pub fn add_vertex_intrinsic_vector_quantity_auto(
319 &self,
320 name: &str,
321 vectors: Vec<Vec2>,
322 ) -> &Self {
323 with_surface_mesh(&self.name, |mesh| {
324 mesh.add_vertex_intrinsic_vector_quantity_auto(name, vectors);
325 });
326 self
327 }
328
329 pub fn add_face_intrinsic_vector_quantity(
331 &self,
332 name: &str,
333 vectors: Vec<Vec2>,
334 basis_x: Vec<Vec3>,
335 basis_y: Vec<Vec3>,
336 ) -> &Self {
337 with_surface_mesh(&self.name, |mesh| {
338 mesh.add_face_intrinsic_vector_quantity(name, vectors, basis_x, basis_y);
339 });
340 self
341 }
342
343 pub fn add_face_intrinsic_vector_quantity_auto(&self, name: &str, vectors: Vec<Vec2>) -> &Self {
345 with_surface_mesh(&self.name, |mesh| {
346 mesh.add_face_intrinsic_vector_quantity_auto(name, vectors);
347 });
348 self
349 }
350
351 pub fn add_one_form_quantity(
353 &self,
354 name: &str,
355 values: Vec<f32>,
356 orientations: Vec<bool>,
357 ) -> &Self {
358 with_surface_mesh(&self.name, |mesh| {
359 mesh.add_one_form_quantity(name, values, orientations);
360 });
361 self
362 }
363}