egml_core/model/geometry/aggregates/
multi_surface.rs

1use crate::error::Error;
2use crate::model::base::AbstractGml;
3use crate::model::geometry::{DirectPosition, Polygon, TriangulatedSurface};
4use crate::operations::geometry::Geometry;
5use crate::operations::triangulate::Triangulate;
6use nalgebra::Isometry3;
7use rayon::prelude::*;
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct MultiSurface {
11    pub abstract_gml: AbstractGml,
12    surface_member: Vec<Polygon>,
13}
14
15impl MultiSurface {
16    pub fn new(abstract_gml: AbstractGml, members: Vec<Polygon>) -> Result<Self, Error> {
17        if members.is_empty() {
18            return Err(Error::MustNotBeEmpty("multi surface"));
19        }
20
21        Ok(Self {
22            abstract_gml,
23            surface_member: members,
24        })
25    }
26
27    pub fn surface_member(&self) -> &Vec<Polygon> {
28        self.surface_member.as_ref()
29    }
30
31    pub fn set_surface_member(&mut self, val: Vec<Polygon>) -> Result<(), Error> {
32        if val.is_empty() {
33            return Err(Error::MustNotBeEmpty("multi surface"));
34        }
35        self.surface_member = val;
36        Ok(())
37    }
38}
39
40impl Geometry for MultiSurface {
41    fn points(&self) -> Vec<&DirectPosition> {
42        self.surface_member.iter().fold(Vec::new(), |mut acc, x| {
43            acc.extend(x.points().iter());
44            acc
45        })
46    }
47
48    fn apply_transform(&mut self, m: &Isometry3<f64>) {
49        self.surface_member.par_iter_mut().for_each(|p| {
50            p.apply_transform(m);
51        });
52    }
53}
54
55impl Triangulate for MultiSurface {
56    fn triangulate(&self) -> Result<TriangulatedSurface, Error> {
57        let triangulated_surfaces: Vec<TriangulatedSurface> = self
58            .surface_member
59            .iter()
60            .map(|x| x.triangulate())
61            .collect::<Result<Vec<TriangulatedSurface>, Error>>()?;
62
63        let combined_triangulated_surface =
64            TriangulatedSurface::from_triangulated_surfaces(triangulated_surfaces)?;
65        Ok(combined_triangulated_surface)
66    }
67}