use crate::{
halfedge::{
HalfEdgeFaceImpl, HalfEdgeImpl, HalfEdgeImplMeshType, HalfEdgeMeshImpl, HalfEdgeVertexImpl,
},
math::{HasPosition, Vector},
mesh::{
CurvedEdge, CurvedEdgePayload, CurvedEdgeType, EdgeBasics, EmptyEdgePayload,
EmptyFacePayload, EmptyMeshPayload, EuclideanMeshType, MeshBasics, MeshType,
MeshTypeHalfEdge,
},
};
use super::{MeshNd64, NdAffine, NdRotate, Polygon2d, VecN, VertexPayloadPNU};
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub struct MeshType2d64PNUCurved;
impl MeshType for MeshType2d64PNUCurved {
type E = usize;
type V = usize;
type F = usize;
type EP = CurvedEdgePayload<2, Self>;
type VP = VertexPayloadPNU<f64, 2>;
type FP = EmptyFacePayload<Self>;
type MP = EmptyMeshPayload<Self>;
type Mesh = Mesh2d64Curved;
type Face = HalfEdgeFaceImpl<Self>;
type Edge = HalfEdgeImpl<Self>;
type Vertex = HalfEdgeVertexImpl<Self>;
}
impl EuclideanMeshType<2> for MeshType2d64PNUCurved {
type S = f64;
type Vec = VecN<f64, 2>;
type Vec2 = VecN<f64, 2>;
type Trans = NdAffine<f64, 2>;
type Rot = NdRotate<f64, 2>;
type Poly = Polygon2d<f64>;
}
impl HalfEdgeImplMeshType for MeshType2d64PNUCurved {}
impl MeshTypeHalfEdge for MeshType2d64PNUCurved {}
impl CurvedEdge<2, MeshType2d64PNUCurved> for HalfEdgeImpl<MeshType2d64PNUCurved> {
fn curve_type(&self) -> CurvedEdgeType<2, MeshType2d64PNUCurved> {
self.payload().curve_type()
}
fn set_curve_type(&mut self, curve_type: CurvedEdgeType<2, MeshType2d64PNUCurved>) {
self.payload_mut().set_curve_type(curve_type);
}
}
pub type Mesh2d64Curved = HalfEdgeMeshImpl<MeshType2d64PNUCurved>;
impl HalfEdgeMeshImpl<MeshType2d64PNUCurved> {
pub fn to_nd<const D: usize>(&self, tol: f64) -> MeshNd64<D> {
MeshNd64::<D>::import_mesh::<_, _, _, _, MeshType2d64PNUCurved>(
self.clone().flatten_curved_edges(tol),
|vp| VertexPayloadPNU::<f64, D>::from_pos(Vector::from_xy(vp.pos().x, vp.pos().y)),
|_ep| {
EmptyEdgePayload::default()
},
|_fp| EmptyFacePayload::default(),
|_mp| EmptyMeshPayload::default(),
)
}
}
#[cfg(test)]
#[cfg(feature = "nalgebra")]
mod tests {
use super::*;
use crate::{extensions::nalgebra::Vec3, prelude::*};
#[test]
fn test_mesh2d64curved_construction() {
let n = 100;
let radius = 1.0;
let mut mesh = Mesh2d64Curved::new();
mesh.insert_regular_star(radius, radius, n);
assert_eq!(mesh.num_vertices(), n);
assert_eq!(mesh.num_edges(), 2 * n);
assert_eq!(mesh.num_faces(), 1);
assert!(mesh.has_consecutive_vertex_ids());
assert!(mesh.is_open());
assert!(mesh.check().is_ok());
let m3d = mesh.to_nd::<3>(1.0);
assert_eq!(m3d.num_vertices(), n);
assert_eq!(m3d.num_edges(), 2 * n);
assert_eq!(m3d.num_faces(), 1);
assert!(m3d.has_consecutive_vertex_ids());
assert!(m3d.is_open());
assert!(m3d.check().is_ok());
let f = m3d.faces().next().expect("no face");
assert!(f.is_convex(&m3d));
assert!(f.is_planar2(&m3d));
assert_eq!(f.normal(&m3d).normalize(), Vec3::from_xyz(0.0, 0.0, 1.0));
let p = f.as_polygon(&m3d);
assert!(
(p.signed_area().abs() - (regular_polygon_area(radius, n))).abs()
<= f64::EPSILON.sqrt()
);
let m10d = mesh.to_nd::<10>(1.0);
assert!(m10d.check().is_ok());
}
}