egml_transform/
triangulate.rs1use crate::Error;
2use egml_core::model::geometry::{
3 DirectPosition, LinearRing, MultiSurface, Polygon, Solid, Triangle, TriangulatedSurface,
4};
5use egml_core::operations::geometry::Geometry;
6use itertools::Itertools;
7
8pub fn triangulate_polygon(polygon: &Polygon) -> Result<TriangulatedSurface, Error> {
9 let mut triangulated_surface = triangulate_linear_ring(&polygon.exterior)?;
10
11 let mut interior_triangulated_surface: Vec<TriangulatedSurface> = polygon
13 .interior
14 .iter()
15 .map(triangulate_linear_ring)
16 .collect::<Result<Vec<_>, _>>()?;
17 interior_triangulated_surface
18 .iter_mut()
19 .for_each(|x| triangulated_surface.append_patches(x.patches().clone()));
20
21 Ok(triangulated_surface)
22}
23
24pub fn triangulate_linear_ring(linear_ring: &LinearRing) -> Result<TriangulatedSurface, Error> {
25 let first_point = *linear_ring.points().first().unwrap();
28 let mut triangles: Vec<Triangle> = Vec::new();
29
30 for (prev, next) in linear_ring
31 .points()
32 .into_iter()
33 .skip(1)
34 .collect::<Vec<&DirectPosition>>()
35 .iter()
36 .tuple_windows()
37 {
38 let new_triangle = Triangle::new(*first_point, **prev, **next)?;
39 triangles.push(new_triangle);
40 }
41
42 let triangulated_surface = TriangulatedSurface::new(triangles)?;
43 Ok(triangulated_surface)
44}
45
46pub fn triangulate_multi_surface(
47 multi_surface: &MultiSurface,
48) -> Result<Vec<TriangulatedSurface>, Error> {
49 let triangulated_surfaces: Vec<TriangulatedSurface> = multi_surface
50 .surface_member()
51 .iter()
52 .map(triangulate_polygon)
53 .collect::<Result<Vec<TriangulatedSurface>, Error>>()?;
54
55 Ok(triangulated_surfaces)
56}
57
58pub fn triangulate_solid(solid: &Solid) -> Result<Vec<TriangulatedSurface>, Error> {
59 let triangulated_surfaces: Vec<TriangulatedSurface> = solid
60 .members()
61 .iter()
62 .map(triangulate_linear_ring)
63 .collect::<Result<Vec<TriangulatedSurface>, Error>>()?;
64
65 Ok(triangulated_surfaces)
66}