egml_core/model/geometry/primitives/
solid.rs1use crate::error::Error;
2use crate::model::base::AbstractGml;
3use crate::model::geometry::{DirectPosition, SurfaceProperty, 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 Solid {
11 pub abstract_gml: AbstractGml,
12 members: Vec<SurfaceProperty>,
13}
14
15impl Solid {
16 pub fn new(abstract_gml: AbstractGml, members: Vec<SurfaceProperty>) -> Result<Self, Error> {
17 if members.is_empty() {
18 return Err(Error::MustNotBeEmpty("solid"));
19 }
20
21 Ok(Self {
22 abstract_gml,
23 members,
24 })
25 }
26
27 pub fn members(&self) -> &Vec<SurfaceProperty> {
28 self.members.as_ref()
29 }
30
31 pub fn set_members(&mut self, val: Vec<SurfaceProperty>) -> Result<(), Error> {
32 if val.is_empty() {
33 return Err(Error::MustNotBeEmpty("solid"));
34 }
35 self.members = val;
36 Ok(())
37 }
38}
39
40impl Geometry for Solid {
41 fn points(&self) -> Vec<&DirectPosition> {
42 self.members.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.members.par_iter_mut().for_each(|p| {
50 p.apply_transform(m);
51 });
52 }
53}
54
55impl Triangulate for Solid {
56 fn triangulate(&self) -> Result<TriangulatedSurface, Error> {
57 let triangulated_surfaces: Vec<TriangulatedSurface> = self
58 .members
59 .iter()
60 .flat_map(|x| &x.linear_ring)
61 .map(|x| x.triangulate())
62 .collect::<Result<Vec<TriangulatedSurface>, Error>>()?;
63
64 let combined_triangulated_surface =
65 TriangulatedSurface::from_triangulated_surfaces(triangulated_surfaces)?;
66 Ok(combined_triangulated_surface)
67 }
68}