use crate::{SurfaceMesh, Vec2, Vec3, Vec4, with_context_mut};
use glam::UVec3;
pub trait IntoFaceList {
fn into_face_list(self) -> Vec<Vec<u32>>;
}
impl IntoFaceList for Vec<UVec3> {
fn into_face_list(self) -> Vec<Vec<u32>> {
self.into_iter().map(|f| vec![f.x, f.y, f.z]).collect()
}
}
impl IntoFaceList for Vec<[u32; 3]> {
fn into_face_list(self) -> Vec<Vec<u32>> {
self.into_iter().map(|f| f.to_vec()).collect()
}
}
impl IntoFaceList for Vec<Vec<u32>> {
fn into_face_list(self) -> Vec<Vec<u32>> {
self
}
}
pub fn register_surface_mesh(
name: impl Into<String>,
vertices: Vec<Vec3>,
faces: impl IntoFaceList,
) -> SurfaceMeshHandle {
let name = name.into();
let faces = faces.into_face_list();
let n_verts = vertices.len();
for (i, face) in faces.iter().enumerate() {
assert!(
face.len() >= 3,
"Face {i} has {} vertices (minimum 3 required)",
face.len()
);
for &idx in face {
assert!(
(idx as usize) < n_verts,
"Face {i} contains vertex index {idx} but mesh only has {n_verts} vertices"
);
}
}
let mesh = SurfaceMesh::new(name.clone(), vertices, faces);
with_context_mut(|ctx| {
ctx.registry
.register(Box::new(mesh))
.expect("failed to register surface mesh");
ctx.update_extents();
});
SurfaceMeshHandle { name }
}
impl_structure_accessors! {
get_fn = get_surface_mesh,
with_fn = with_surface_mesh,
with_ref_fn = with_surface_mesh_ref,
handle = SurfaceMeshHandle,
type_name = "SurfaceMesh",
rust_type = SurfaceMesh,
doc_name = "surface mesh"
}
#[derive(Clone)]
pub struct SurfaceMeshHandle {
name: String,
}
impl SurfaceMeshHandle {
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
pub fn set_surface_color(&self, color: Vec3) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.set_surface_color(color);
});
self
}
pub fn set_edge_color(&self, color: Vec3) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.set_edge_color(color);
});
self
}
pub fn set_edge_width(&self, width: f32) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.set_edge_width(width);
});
self
}
pub fn set_show_edges(&self, show: bool) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.set_show_edges(show);
});
self
}
pub fn set_backface_color(&self, color: Vec3) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.set_backface_color(color);
});
self
}
pub fn set_transparency(&self, transparency: f32) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.set_transparency(transparency);
});
self
}
pub fn set_material(&self, material: &str) -> &Self {
use polyscope_core::Structure;
with_surface_mesh(&self.name, |mesh| {
mesh.set_material(material);
});
self
}
pub fn add_vertex_scalar_quantity(&self, name: &str, values: Vec<f32>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_vertex_scalar_quantity(name, values);
});
self
}
pub fn add_face_scalar_quantity(&self, name: &str, values: Vec<f32>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_face_scalar_quantity(name, values);
});
self
}
pub fn add_vertex_color_quantity(&self, name: &str, colors: Vec<Vec3>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_vertex_color_quantity(name, colors);
});
self
}
pub fn add_vertex_color_quantity_with_alpha(&self, name: &str, colors: Vec<Vec4>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_vertex_color_quantity_with_alpha(name, colors);
});
self
}
pub fn add_face_color_quantity(&self, name: &str, colors: Vec<Vec3>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_face_color_quantity(name, colors);
});
self
}
pub fn add_face_color_quantity_with_alpha(&self, name: &str, colors: Vec<Vec4>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_face_color_quantity_with_alpha(name, colors);
});
self
}
pub fn add_vertex_vector_quantity(&self, name: &str, vectors: Vec<Vec3>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_vertex_vector_quantity(name, vectors);
});
self
}
pub fn add_face_vector_quantity(&self, name: &str, vectors: Vec<Vec3>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_face_vector_quantity(name, vectors);
});
self
}
pub fn add_vertex_parameterization_quantity(&self, name: &str, coords: Vec<Vec2>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_vertex_parameterization_quantity(name, coords);
});
self
}
pub fn add_corner_parameterization_quantity(&self, name: &str, coords: Vec<Vec2>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_corner_parameterization_quantity(name, coords);
});
self
}
pub fn add_vertex_intrinsic_vector_quantity(
&self,
name: &str,
vectors: Vec<Vec2>,
basis_x: Vec<Vec3>,
basis_y: Vec<Vec3>,
) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_vertex_intrinsic_vector_quantity(name, vectors, basis_x, basis_y);
});
self
}
pub fn add_vertex_intrinsic_vector_quantity_auto(
&self,
name: &str,
vectors: Vec<Vec2>,
) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_vertex_intrinsic_vector_quantity_auto(name, vectors);
});
self
}
pub fn add_face_intrinsic_vector_quantity(
&self,
name: &str,
vectors: Vec<Vec2>,
basis_x: Vec<Vec3>,
basis_y: Vec<Vec3>,
) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_face_intrinsic_vector_quantity(name, vectors, basis_x, basis_y);
});
self
}
pub fn add_face_intrinsic_vector_quantity_auto(&self, name: &str, vectors: Vec<Vec2>) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_face_intrinsic_vector_quantity_auto(name, vectors);
});
self
}
pub fn add_one_form_quantity(
&self,
name: &str,
values: Vec<f32>,
orientations: Vec<bool>,
) -> &Self {
with_surface_mesh(&self.name, |mesh| {
mesh.add_one_form_quantity(name, values, orientations);
});
self
}
}