microcad_core/geo3d/
geometry.rs1use crate::{
5 traits::{Center, TotalMemory, VertexCount},
6 *,
7};
8
9use derive_more::From;
10use std::rc::Rc;
11use strum::IntoStaticStr;
12
13use crate::geo3d::*;
14
15#[derive(IntoStaticStr, From, Clone)]
17pub enum Geometry3D {
18 Mesh(TriangleMesh),
20 Manifold(Rc<Manifold>),
22 Collection(Geometries3D),
24}
25
26impl std::fmt::Debug for Geometry3D {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 let name: &'static str = self.into();
29 write!(f, "{name}")
30 }
31}
32
33impl Geometry3D {
34 pub fn name(&self) -> &'static str {
36 self.into()
37 }
38
39 pub fn boolean_op(&self, other: &Geometry3D, op: BooleanOp) -> Option<Self> {
41 let a: Rc<Manifold> = self.clone().into();
42 let b: Rc<Manifold> = other.clone().into();
43 Some(Geometry3D::Manifold(Rc::new(a.boolean(&b, op.into()))))
44 }
45
46 pub fn hull(&self) -> Self {
48 match &self {
49 Geometry3D::Mesh(triangle_mesh) => triangle_mesh.to_manifold().convex_hull().into(),
50 Geometry3D::Manifold(manifold) => manifold.convex_hull().into(),
51 Geometry3D::Collection(collection) => TriangleMesh::from(collection)
52 .to_manifold()
53 .convex_hull()
54 .into(),
55 }
56 }
57
58 pub fn with_bounds(self) -> WithBounds3D<Geometry3D> {
60 let bounds = self.calc_bounds_3d();
61 WithBounds3D {
62 bounds,
63 inner: self,
64 }
65 }
66}
67
68impl CalcBounds3D for Geometry3D {
69 fn calc_bounds_3d(&self) -> Bounds3D {
70 match self {
71 Geometry3D::Mesh(triangle_mesh) => triangle_mesh.calc_bounds_3d(),
72 Geometry3D::Manifold(manifold) => {
73 TriangleMesh::from(manifold.get_mesh_gl(0)).calc_bounds_3d()
74 }
75 Geometry3D::Collection(collection) => collection.calc_bounds_3d(),
76 }
77 }
78}
79
80impl Transformed3D for Geometry3D {
81 fn transformed_3d(&self, mat: &Mat4) -> Self {
82 TriangleMesh::from(self.clone()).transformed_3d(mat).into()
83 }
84}
85
86impl Center for Geometry3D {
87 fn center(&self) -> Self {
88 let d: Vec3 = self.calc_bounds_3d().center();
89 self.transformed_3d(&Mat4::from_translation(-d))
90 }
91}
92
93impl From<Manifold> for Geometry3D {
94 fn from(manifold: Manifold) -> Self {
95 Geometry3D::Manifold(Rc::new(manifold))
96 }
97}
98
99impl From<Geometry3D> for Rc<Manifold> {
100 fn from(geo: Geometry3D) -> Self {
101 match geo {
102 Geometry3D::Mesh(triangle_mesh) => Rc::new(triangle_mesh.to_manifold()),
103 Geometry3D::Manifold(manifold) => manifold,
104 Geometry3D::Collection(ref collection) => {
105 Rc::new(TriangleMesh::from(collection).to_manifold())
106 }
107 }
108 }
109}
110
111impl TotalMemory for Rc<Manifold> {} impl TotalMemory for Geometry3D {
114 fn heap_memory(&self) -> usize {
115 match &self {
116 Geometry3D::Mesh(triangle_mesh) => triangle_mesh.heap_memory(),
117 Geometry3D::Manifold(manifold) => manifold.heap_memory(),
118 Geometry3D::Collection(collection) => collection.heap_memory(),
119 }
120 }
121}
122
123impl VertexCount for Rc<Manifold> {
124 fn vertex_count(&self) -> usize {
125 0 }
127}
128
129impl VertexCount for Geometry3D {
130 fn vertex_count(&self) -> usize {
131 match &self {
132 Geometry3D::Mesh(triangle_mesh) => triangle_mesh.vertex_count(),
133 Geometry3D::Manifold(manifold) => manifold.vertex_count(),
134 Geometry3D::Collection(collection) => collection.vertex_count(),
135 }
136 }
137}