mod chain;
mod interval;
mod monotone;
mod point;
mod status;
mod sweep;
mod vertex_type;
pub use monotone::*;
pub use sweep::sweep_line_triangulation;
pub use vertex_type::VertexType;
use super::TesselationMeta;
use crate::{
math::IndexType,
mesh::{Face3d, FaceBasics, IndexedVertex2D, MeshType3D, Triangulation},
};
#[derive(Debug, Clone, PartialEq)]
pub struct SweepMeta<V: IndexType> {
#[cfg(feature = "sweep_debug")]
pub vertex_type: Vec<(V, VertexType)>,
phantom: std::marker::PhantomData<V>,
}
impl<V: IndexType> Default for SweepMeta<V> {
fn default() -> Self {
SweepMeta {
#[cfg(feature = "sweep_debug")]
vertex_type: Vec::new(),
phantom: std::marker::PhantomData,
}
}
}
impl<V: IndexType> SweepMeta<V> {
#[cfg(feature = "sweep_debug")]
pub fn update_type(&mut self, i: V, t: VertexType) {
for (j, ty) in self.vertex_type.iter_mut() {
if *j == i {
*ty = t;
}
}
}
}
pub fn sweep_line<T: MeshType3D, Tri: MonotoneTriangulator<V = T::V, Vec2 = T::Vec2>>(
face: &T::Face,
mesh: &T::Mesh,
indices: &mut Triangulation<T::V>,
meta: &mut TesselationMeta<T::V>,
) {
debug_assert!(face.may_be_curved() || face.is_planar2(mesh));
let vec2s: Vec<_> = face
.vertices_2d(mesh)
.map(|(p, i)| IndexedVertex2D::<T::V, T::Vec2>::new(p, i))
.collect();
sweep_line_triangulation::<Tri>(indices, &vec2s, &mut meta.sweep);
}
#[cfg(test)]
mod tests {
use crate::{prelude::*, tesselate::sweep::LinearMonoTriangulator};
fn verify_triangulation<T: MeshType3D>(mesh: &T::Mesh, f: T::F) {
let face = mesh.face(f);
let vec2s = face.vec2s(mesh);
assert!(
T::Poly::from_iter(vec2s.iter().map(|v| v.vec)).is_ccw(),
"Polygon must be counterclockwise"
);
let mut indices = Vec::new();
let mut tri = Triangulation::new(&mut indices);
let mut meta = TesselationMeta::default();
sweep_line::<T, LinearMonoTriangulator<T::V, T::Vec2>>(face, &mesh, &mut tri, &mut meta);
tri.verify_full::<T::Vec2, T::Poly>(&vec2s);
}
}