Skip to content

Commit 0efbc53

Browse files
committed
initial implementation of Sketch::triangulate
1 parent db1e852 commit 0efbc53

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

src/sketch/mod.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use crate::mesh::Mesh;
66
use crate::traits::CSG;
77
use geo::algorithm::winding_order::Winding;
88
use geo::{
9-
AffineOps, AffineTransform, BooleanOps as GeoBooleanOps, BoundingRect, Coord, Geometry,
10-
GeometryCollection, LineString, MultiPolygon, Orient, Polygon as GeoPolygon, Rect,
9+
AffineOps, AffineTransform, BooleanOps as GeoBooleanOps, BoundingRect, Coord, CoordsIter,
10+
Geometry, GeometryCollection, LineString, MultiPolygon, Orient, Polygon as GeoPolygon, Rect,
1111
orient::Direction,
1212
};
1313
use nalgebra::{Matrix4, Point3, partial_max, partial_min};
@@ -135,6 +135,49 @@ impl<S: Clone + Send + Sync + Debug> Sketch<S> {
135135
result
136136
}
137137
}
138+
139+
/// Triangulate all polygons in this Sketch.
140+
///
141+
/// This function converts all polygons (including those from MultiPolygons) contained
142+
/// in the Sketch's geometry into a list of triangles. Each triangle is represented as
143+
/// a `[Point3<Real>; 3]`, where the Z-coordinate is 0.0.
144+
///
145+
/// # Returns
146+
///
147+
/// A `Vec<[Point3<Real>; 3]>` containing all the triangles resulting from the triangulation.
148+
pub fn triangulate(&self) -> Vec<[Point3<Real>; 3]> {
149+
let mut all_triangles = Vec::new();
150+
151+
for geom in &self.geometry {
152+
match geom {
153+
geo::Geometry::Polygon(poly) => {
154+
let outer: Vec<[Real; 2]> = poly.exterior().coords_iter().map(|c| [c.x, c.y]).collect();
155+
let holes: Vec<Vec<[Real; 2]>> = poly.interiors().iter()
156+
.map(|ring| ring.coords_iter().map(|c| [c.x, c.y]).collect())
157+
.collect();
158+
let hole_refs: Vec<&[[Real; 2]]> = holes.iter().map(|v| &v[..]).collect();
159+
let tris = Self::triangulate_2d(&outer, &hole_refs);
160+
all_triangles.extend(tris);
161+
},
162+
geo::Geometry::MultiPolygon(mp) => {
163+
for poly in &mp.0 {
164+
let outer: Vec<[Real; 2]> = poly.exterior().coords_iter().map(|c| [c.x, c.y]).collect();
165+
let holes: Vec<Vec<[Real; 2]>> = poly.interiors().iter()
166+
.map(|ring| ring.coords_iter().map(|c| [c.x, c.y]).collect())
167+
.collect();
168+
let hole_refs: Vec<&[[Real; 2]]> = holes.iter().map(|v| &v[..]).collect();
169+
let tris = Self::triangulate_2d(&outer, &hole_refs);
170+
all_triangles.extend(tris);
171+
}
172+
},
173+
// For other geometry types (LineString, Point, etc.), we might choose to ignore them
174+
// or handle them differently if needed. Currently, ignoring them.
175+
_ => {}
176+
}
177+
}
178+
179+
all_triangles
180+
}
138181

139182
/// Return a copy of this `Sketch` whose polygons are normalised so that
140183
/// exterior rings wind counter-clockwise and interior rings clockwise.

0 commit comments

Comments
 (0)