@@ -133,6 +133,32 @@ impl<S: Clone + Send + Sync + Debug> Sketch<S> {
133133 result
134134 }
135135 }
136+
137+ /// Return a copy of this `Sketch` whose polygons are normalised so that
138+ /// exterior rings wind counter-clockwise and interior rings clockwise.
139+ pub fn orient ( & self ) -> Sketch < S > {
140+ // Re-build the collection, orienting only what’s supported.
141+ let oriented_geoms: Vec < Geometry < Real > > = self
142+ . geometry
143+ . iter ( )
144+ . map ( |geom| match geom {
145+ Geometry :: Polygon ( p) => {
146+ Geometry :: Polygon ( p. clone ( ) . orient ( Direction :: Default ) )
147+ }
148+ Geometry :: MultiPolygon ( mp) => {
149+ Geometry :: MultiPolygon ( mp. clone ( ) . orient ( Direction :: Default ) )
150+ }
151+ // Everything else keeps its original orientation.
152+ _ => geom. clone ( ) ,
153+ } )
154+ . collect ( ) ;
155+
156+ Sketch {
157+ geometry : GeometryCollection ( oriented_geoms) ,
158+ bounding_box : OnceLock :: new ( ) ,
159+ metadata : self . metadata . clone ( ) ,
160+ }
161+ }
136162}
137163
138164impl < S : Clone + Send + Sync + Debug > CSGOps for Sketch < S > {
@@ -421,7 +447,7 @@ impl<S: Clone + Send + Sync + Debug> CSGOps for Sketch<S> {
421447 self . bounding_box = OnceLock :: new ( ) ;
422448 }
423449
424- /// Invert this Mesh (flip inside vs. outside)
450+ /// Invert this Sketch (flip inside vs. outside)
425451 fn inverse ( & self ) -> Sketch < S > {
426452 let sketch = self . clone ( ) ;
427453 //for p in &mut sketch.polygons {
0 commit comments