egml_core/model/geometry/primitives/
triangulated_surface.rs1use crate::error::Error;
2use crate::model::geometry::{DirectPosition, Triangle};
3use crate::operations::geometry::Geometry;
4use nalgebra::Isometry3;
5use rayon::prelude::*;
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct TriangulatedSurface {
9 patches: Vec<Triangle>,
10}
11
12impl TriangulatedSurface {
13 pub fn new(patches: Vec<Triangle>) -> Result<Self, Error> {
14 if patches.is_empty() {
15 return Err(Error::MustNotBeEmpty("triangulated surface"));
16 }
17
18 Ok(TriangulatedSurface { patches })
19 }
20
21 pub fn from_triangulated_surfaces(surfaces: Vec<TriangulatedSurface>) -> Result<Self, Error> {
22 if surfaces.is_empty() {
23 return Err(Error::MustNotBeEmpty("surfaces to combine"));
24 }
25
26 let total_patches: Vec<Triangle> = surfaces
27 .into_iter()
28 .flat_map(|surface| surface.patches)
29 .collect();
30
31 Ok(TriangulatedSurface {
32 patches: total_patches,
33 })
34 }
35
36 pub fn patches(&self) -> &Vec<Triangle> {
37 self.patches.as_ref()
38 }
39
40 pub fn append_patches(&mut self, mut patches: Vec<Triangle>) {
41 self.patches.append(&mut patches)
42 }
43
44 pub fn number_of_patches(&self) -> usize {
45 self.patches.len()
46 }
47}
48
49impl Geometry for TriangulatedSurface {
50 fn points(&self) -> Vec<&DirectPosition> {
51 self.patches.iter().fold(Vec::new(), |mut acc, x| {
52 acc.extend(x.points().iter());
53 acc
54 })
55 }
56
57 fn apply_transform(&mut self, m: &Isometry3<f64>) {
58 self.patches.par_iter_mut().for_each(|p| {
59 p.apply_transform(m);
60 });
61 }
62}