Skip to main content

egml_core/model/geometry/primitives/
surface_kind.rs

1use crate::model::common::{
2    ApplyTransform, ComputeEnvelope, GeometryType, HasGeometryType, IterGeometries, Triangulate,
3    Triangulation,
4};
5use crate::model::geometry::primitives::{AsSurface, AsSurfaceMut, Surface, TriangulatedSurface};
6use crate::model::geometry::refs::AbstractGeometryKindRef;
7use crate::model::geometry::{DirectPosition, Envelope};
8use crate::{Error, impl_surface_mut_traits, impl_surface_traits};
9use nalgebra::{Isometry3, Rotation3, Scale3, Transform3, Vector3};
10
11#[derive(Debug, Clone, PartialEq)]
12pub enum SurfaceKind {
13    TriangulatedSurface(TriangulatedSurface),
14}
15
16impl AsSurface for SurfaceKind {
17    fn surface(&self) -> &Surface {
18        match self {
19            SurfaceKind::TriangulatedSurface(x) => x.surface(),
20        }
21    }
22}
23
24impl AsSurfaceMut for SurfaceKind {
25    fn surface_mut(&mut self) -> &mut Surface {
26        match self {
27            SurfaceKind::TriangulatedSurface(x) => x.surface_mut(),
28        }
29    }
30}
31
32impl_surface_traits!(SurfaceKind);
33impl_surface_mut_traits!(SurfaceKind);
34
35impl HasGeometryType for SurfaceKind {
36    fn geometry_type(&self) -> GeometryType {
37        match self {
38            SurfaceKind::TriangulatedSurface(x) => x.geometry_type(),
39        }
40    }
41}
42
43#[macro_export]
44macro_rules! impl_from_for_surface_kind {
45    ($variant:ident, $type:ty) => {
46        impl From<$type> for $crate::model::geometry::primitives::surface_kind::SurfaceKind {
47            #[allow(unreachable_code)]
48            fn from(x: $type) -> Self {
49                $crate::model::geometry::primitives::surface_kind::SurfaceKind::$variant(x.into())
50            }
51        }
52        $crate::impl_from_for_abstract_surface_kind!(SurfaceKind, $type);
53    };
54    ($variant:ident) => {
55        $crate::impl_from_for_surface_kind!($variant, $variant);
56    };
57}
58
59#[macro_export]
60macro_rules! impl_try_from_for_surface_kind {
61    ($variant:ident, $type:ty) => {
62        impl TryFrom<$crate::model::geometry::primitives::surface_kind::SurfaceKind> for $type {
63            type Error = ();
64            #[allow(unreachable_code)]
65            fn try_from(
66                x: $crate::model::geometry::primitives::surface_kind::SurfaceKind,
67            ) -> Result<Self, ()> {
68                match x {
69                    $crate::model::geometry::primitives::surface_kind::SurfaceKind::$variant(k) => {
70                        k.try_into().map_err(|_| ())
71                    }
72                    #[allow(unreachable_patterns)]
73                    _ => Err(()),
74                }
75            }
76        }
77        $crate::impl_try_from_for_abstract_surface_kind!(SurfaceKind, $type);
78    };
79    ($variant:ident) => {
80        $crate::impl_try_from_for_surface_kind!($variant, $variant);
81    };
82}
83
84impl_from_for_surface_kind!(TriangulatedSurface);
85impl_try_from_for_surface_kind!(TriangulatedSurface);
86
87impl SurfaceKind {
88    pub fn area_3d(&self) -> Result<f64, Error> {
89        match self {
90            SurfaceKind::TriangulatedSurface(x) => x.area_3d(),
91        }
92    }
93
94    pub fn points(&self) -> Vec<&DirectPosition> {
95        match self {
96            SurfaceKind::TriangulatedSurface(x) => x.points(),
97        }
98    }
99}
100
101impl IterGeometries for SurfaceKind {
102    fn iter_geometries(&self) -> Box<dyn Iterator<Item = AbstractGeometryKindRef<'_>> + '_> {
103        match self {
104            SurfaceKind::TriangulatedSurface(x) => x.iter_geometries(),
105        }
106    }
107}
108
109impl ApplyTransform for SurfaceKind {
110    fn apply_transform(&mut self, transform: Transform3<f64>) {
111        match self {
112            SurfaceKind::TriangulatedSurface(x) => x.apply_transform(transform),
113        }
114    }
115
116    fn apply_isometry(&mut self, isometry: Isometry3<f64>) {
117        match self {
118            SurfaceKind::TriangulatedSurface(x) => x.apply_isometry(isometry),
119        }
120    }
121
122    fn apply_translation(&mut self, vector: Vector3<f64>) {
123        match self {
124            SurfaceKind::TriangulatedSurface(x) => x.apply_translation(vector),
125        }
126    }
127
128    fn apply_rotation(&mut self, rotation: Rotation3<f64>) {
129        match self {
130            SurfaceKind::TriangulatedSurface(x) => x.apply_rotation(rotation),
131        }
132    }
133
134    fn apply_scale(&mut self, scale: Scale3<f64>) {
135        match self {
136            SurfaceKind::TriangulatedSurface(x) => x.apply_scale(scale),
137        }
138    }
139}
140
141impl ComputeEnvelope for SurfaceKind {
142    fn compute_envelope(&self) -> Option<Envelope> {
143        match self {
144            SurfaceKind::TriangulatedSurface(x) => x.compute_envelope(),
145        }
146    }
147}
148
149impl Triangulate for SurfaceKind {
150    fn triangulate(&self) -> Result<Triangulation, Error> {
151        match self {
152            SurfaceKind::TriangulatedSurface(x) => Ok(Triangulation::new(x.clone(), Vec::new())),
153        }
154    }
155}