mod point_cloud;
pub use point_cloud::*;
mod tri_mesh;
pub use tri_mesh::*;
pub use crate::prelude::*;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Geometry {
Points(PointCloud),
Triangles(TriMesh),
}
impl Geometry {
pub fn compute_normals(&mut self) {
if let Self::Triangles(mesh) = self {
mesh.compute_normals()
}
}
pub fn compute_tangents(&mut self) {
if let Self::Triangles(mesh) = self {
mesh.compute_tangents()
}
}
pub fn compute_aabb(&mut self) -> AxisAlignedBoundingBox {
match self {
Self::Triangles(mesh) => mesh.compute_aabb(),
Self::Points(point_cloud) => point_cloud.compute_aabb(),
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Indices {
None,
U8(Vec<u8>),
U16(Vec<u16>),
U32(Vec<u32>),
}
impl Indices {
pub fn into_u32(self) -> Option<Vec<u32>> {
match self {
Self::None => None,
Self::U8(mut values) => Some(values.drain(..).map(|i| i as u32).collect::<Vec<_>>()),
Self::U16(mut values) => Some(values.drain(..).map(|i| i as u32).collect::<Vec<_>>()),
Self::U32(values) => Some(values),
}
}
pub fn to_u32(&self) -> Option<Vec<u32>> {
match self {
Self::None => None,
Self::U8(values) => Some(values.iter().map(|i| *i as u32).collect::<Vec<_>>()),
Self::U16(values) => Some(values.iter().map(|i| *i as u32).collect::<Vec<_>>()),
Self::U32(values) => Some(values.clone()),
}
}
pub fn len(&self) -> Option<usize> {
match self {
Self::None => None,
Self::U8(values) => Some(values.len()),
Self::U16(values) => Some(values.len()),
Self::U32(values) => Some(values.len()),
}
}
pub fn is_empty(&self) -> bool {
self.len().map(|i| i == 0).unwrap_or(true)
}
}
impl std::default::Default for Indices {
fn default() -> Self {
Self::None
}
}
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Positions {
F32(Vec<Vec3>),
F64(Vec<Vector3<f64>>),
}
impl Positions {
pub fn into_f32(self) -> Vec<Vec3> {
match self {
Self::F32(values) => values,
Self::F64(mut values) => values
.drain(..)
.map(|v| Vec3::new(v.x as f32, v.y as f32, v.z as f32))
.collect::<Vec<_>>(),
}
}
pub fn to_f32(&self) -> Vec<Vec3> {
match self {
Self::F32(values) => values.clone(),
Self::F64(values) => values
.iter()
.map(|v| Vec3::new(v.x as f32, v.y as f32, v.z as f32))
.collect::<Vec<_>>(),
}
}
pub fn into_f64(self) -> Vec<Vector3<f64>> {
match self {
Self::F32(mut values) => values
.drain(..)
.map(|v| Vector3::new(v.x as f64, v.y as f64, v.z as f64))
.collect::<Vec<_>>(),
Self::F64(values) => values,
}
}
pub fn to_f64(&self) -> Vec<Vector3<f64>> {
match self {
Self::F32(values) => values
.iter()
.map(|v| Vector3::new(v.x as f64, v.y as f64, v.z as f64))
.collect::<Vec<_>>(),
Self::F64(values) => values.clone(),
}
}
pub fn len(&self) -> usize {
match self {
Self::F32(values) => values.len(),
Self::F64(values) => values.len(),
}
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn compute_aabb(&self) -> AxisAlignedBoundingBox {
match self {
Positions::F32(ref positions) => AxisAlignedBoundingBox::new_with_positions(positions),
Positions::F64(ref positions) => AxisAlignedBoundingBox::new_with_positions(
&positions
.iter()
.map(|v| Vec3::new(v.x as f32, v.y as f32, v.z as f32))
.collect::<Vec<_>>(),
),
}
}
}
impl std::default::Default for Positions {
fn default() -> Self {
Self::F32(Vec::new())
}
}
impl std::fmt::Debug for Positions {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut d = f.debug_struct("Positions");
match self {
Self::F32(ind) => d.field("f32", &ind.len()),
Self::F64(ind) => d.field("f64", &ind.len()),
};
d.finish()
}
}