@@ -6,8 +6,8 @@ use crate::mesh::Mesh;
66use crate :: traits:: CSG ;
77use geo:: algorithm:: winding_order:: Winding ;
88use 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} ;
1313use 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