egml_transform/
triangulate.rs

1use 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    // TODO: no cloning
12    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 points: Vec<DirectPosition> = linear_ring.points().iter().collect();
26
27    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}