microcad_core/geo3d/
reflect.rs1use super::*;
9use cgmath::InnerSpace;
10
11pub trait Reflect3D<T = Self> {
13 fn reflect_3d(&self, plane: &Plane) -> T;
15}
16
17pub trait Mirror3D<T = Self>: Reflect3D<T> + Into<Geometry3D> {
19 fn mirror_3d(self, plane: &Plane) -> Geometries3D {
21 let orig: Geometry3D = self.into();
22 let refl: Geometry3D = orig.reflect_3d(plane);
23 Geometries3D::new(vec![orig, refl])
24 }
25}
26
27impl Reflect3D for crate::Vec3 {
28 fn reflect_3d(&self, plane: &Plane) -> Self {
29 let n = plane.n.normalize(); let v = *self - plane.p; let dist = v.dot(n); *self - 2.0 * dist * n }
34}
35
36impl Reflect3D for cgmath::Vector3<f32> {
37 fn reflect_3d(&self, plane: &Plane) -> Self {
38 let n: cgmath::Vector3<f32> = plane.n.normalize().cast().expect("Valid cast"); let p: cgmath::Vector3<f32> = plane.p.cast().expect("Valid cast");
40 let v = *self - p; let dist = v.dot(n); *self - 2.0 * dist * n }
44}
45
46impl Reflect3D for TriangleMesh {
47 fn reflect_3d(&self, plane: &Plane) -> Self {
48 Self {
49 positions: self
50 .positions
51 .iter()
52 .map(|pos| pos.reflect_3d(plane))
53 .collect(),
54 normals: self.normals.clone(), triangle_indices: self
56 .triangle_indices
57 .iter()
58 .map(|tri| tri.flipped())
59 .collect(),
60 }
61 }
62}
63
64impl Mirror3D for TriangleMesh {}
65
66impl Reflect3D for Geometries3D {
67 fn reflect_3d(&self, plane: &Plane) -> Self {
68 Self::from_iter(
69 self.iter()
70 .map(|geometry| std::rc::Rc::new(geometry.as_ref().reflect_3d(plane))),
71 )
72 }
73}
74
75impl Mirror3D for Geometries3D {}
76
77impl Reflect3D for Geometry3D {
78 fn reflect_3d(&self, plane: &Plane) -> Self {
79 match &self {
80 Geometry3D::Mesh(triangle_mesh) => triangle_mesh.reflect_3d(plane).into(),
81 Geometry3D::Manifold(manifold) => TriangleMesh::from(manifold.to_mesh())
82 .reflect_3d(plane)
83 .into(),
84 Geometry3D::Collection(collection) => collection.reflect_3d(plane).into(),
85 }
86 }
87}
88
89impl Mirror3D for Geometry3D {}