Skip to main content

egml_core/model/geometry/primitives/
surface_kind.rs

1use crate::model::geometry::complexes::CompositeSurface;
2use crate::model::geometry::primitives::{
3    AbstractSurface, AsAbstractSurface, AsAbstractSurfaceMut, Polygon, Surface, TriangulatedSurface,
4};
5use crate::model::geometry::{DirectPosition, Envelope};
6use crate::{Error, impl_abstract_surface_traits};
7use nalgebra::Isometry3;
8
9/// Discriminated union of all concrete surface implementations.
10#[derive(Debug, Clone, PartialEq)]
11pub enum SurfaceKind {
12    /// A patched [`Surface`].
13    Surface(Surface),
14    /// A planar [`Polygon`].
15    Polygon(Polygon),
16    /// A topology-aware [`CompositeSurface`].
17    CompositeSurface(CompositeSurface),
18}
19
20impl AsAbstractSurface for SurfaceKind {
21    fn abstract_surface(&self) -> &AbstractSurface {
22        match self {
23            Self::Surface(x) => x.abstract_surface(),
24            Self::Polygon(x) => x.abstract_surface(),
25            Self::CompositeSurface(x) => x.abstract_surface(),
26        }
27    }
28}
29
30impl AsAbstractSurfaceMut for SurfaceKind {
31    fn abstract_surface_mut(&mut self) -> &mut AbstractSurface {
32        match self {
33            Self::Surface(x) => x.abstract_surface_mut(),
34            Self::Polygon(x) => x.abstract_surface_mut(),
35            Self::CompositeSurface(x) => x.abstract_surface_mut(),
36        }
37    }
38}
39
40impl_abstract_surface_traits!(SurfaceKind);
41
42impl SurfaceKind {
43    pub fn area_3d(&self) -> Result<f64, Error> {
44        match self {
45            Self::Surface(x) => x.area_3d(),
46            Self::Polygon(x) => x.area_3d(),
47            Self::CompositeSurface(x) => x.area_3d(),
48        }
49    }
50
51    pub fn triangulate(&self) -> Result<TriangulatedSurface, Error> {
52        match self {
53            Self::Surface(x) => x.triangulate(),
54            Self::Polygon(x) => x.triangulate(),
55            Self::CompositeSurface(x) => x.triangulate(),
56        }
57    }
58
59    pub fn compute_envelope(&self) -> Option<Envelope> {
60        match self {
61            Self::Surface(x) => x.compute_envelope(),
62            Self::Polygon(x) => x.compute_envelope(),
63            Self::CompositeSurface(x) => x.compute_envelope(),
64        }
65    }
66
67    pub fn apply_transform(&mut self, m: &Isometry3<f64>) {
68        match self {
69            Self::Surface(x) => x.apply_transform(m),
70            Self::Polygon(x) => x.apply_transform(m),
71            Self::CompositeSurface(x) => x.apply_transform(m),
72        }
73    }
74
75    pub fn points(&self) -> Vec<&DirectPosition> {
76        match self {
77            Self::Surface(x) => x.points(),
78            Self::Polygon(x) => x.points(),
79            Self::CompositeSurface(x) => x.points(),
80        }
81    }
82}