egml_core/model/geometry/primitives/
triangulated_surface.rs1use crate::error::Error;
2use crate::impl_surface_traits;
3use crate::model::geometry::Envelope;
4use crate::model::geometry::primitives::surface_patch_kind::SurfacePatchKind;
5use crate::model::geometry::primitives::{
6 AsSurface, AsSurfaceMut, Surface, SurfacePatchArrayProperty, Triangle,
7};
8use nalgebra::Isometry3;
9
10#[derive(Debug, Clone, PartialEq)]
15pub struct TriangulatedSurface {
16 pub(crate) surface: Surface,
17}
18
19impl TriangulatedSurface {
20 pub fn new(surface: Surface) -> Result<Self, Error> {
22 Ok(TriangulatedSurface { surface })
23 }
24
25 pub fn surface(&self) -> &Surface {
26 &self.surface
27 }
28}
29
30impl TriangulatedSurface {
31 pub fn from_triangles(triangles: Vec<Triangle>) -> Result<Self, Error> {
37 if triangles.is_empty() {
38 return Err(Error::TooFewElements {
39 geometry: "gml:TriangulatedSurface",
40 minimum: 1,
41 spec: Some("OGC 07-036 §10.5.11.4"),
42 id: None,
43 detail: None,
44 });
45 }
46
47 let patches: Vec<SurfacePatchKind> = triangles
48 .into_iter()
49 .map(SurfacePatchKind::Triangle)
50 .collect();
51 let surface_patch_array_property: SurfacePatchArrayProperty =
52 SurfacePatchArrayProperty::new(patches);
53
54 Self::new(Surface::new(surface_patch_array_property))
55 }
56
57 pub fn from_triangulated_surfaces(surfaces: Vec<TriangulatedSurface>) -> Result<Self, Error> {
63 if surfaces.is_empty() {
64 return Err(Error::TooFewElements {
65 geometry: "TriangulatedSurface::from_triangulated_surfaces",
66 minimum: 1,
67 spec: None,
68 id: None,
69 detail: None,
70 });
71 }
72
73 let patches: Vec<SurfacePatchKind> = surfaces
74 .into_iter()
75 .flat_map(|surface| surface.surface.into_patches().patches)
76 .collect();
77
78 let surface_patch_array_property: SurfacePatchArrayProperty =
79 SurfacePatchArrayProperty::new(patches);
80
81 let surface = Surface::new(surface_patch_array_property);
82 Ok(TriangulatedSurface { surface })
83 }
84
85 pub fn triangles(&self) -> Vec<&Triangle> {
87 self.surface
88 .patches()
89 .patches()
90 .iter()
91 .filter_map(|patch| match patch {
92 SurfacePatchKind::Triangle(triangle) => Some(triangle),
93 _ => None,
94 })
95 .collect()
96 }
97
98 pub fn apply_transform(&mut self, m: &Isometry3<f64>) {
99 self.surface.apply_transform(m);
100 }
101
102 pub fn compute_envelope(&self) -> Option<Envelope> {
104 self.surface.compute_envelope()
105 }
106}
107
108impl AsSurface for TriangulatedSurface {
109 fn surface(&self) -> &Surface {
110 &self.surface
111 }
112}
113
114impl AsSurfaceMut for TriangulatedSurface {
115 fn surface_mut(&mut self) -> &mut Surface {
116 &mut self.surface
117 }
118}
119
120impl_surface_traits!(TriangulatedSurface);