Skip to content

Commit 4199b01

Browse files
authored
Merge pull request #102 from timschmidt/main
Pull in Sketch::triangulate()
2 parents f6b001b + 0efbc53 commit 4199b01

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ converted into a `Mesh<S>`.
129129
- <img src="docs/bspline.png" width="128" alt="top down view of a neer semi-circle shape"/> **`Sketch::bspline(control: &[[Real; 2]], p: usize, segments_per_span: usize, metadata: Option<S>)`**
130130
- <img src="docs/heart.png" width="128" alt="top down view of a cartune heart"/> **`Sketch::heart(width: Real, height: Real, segments: usize, metadata: Option<S>)`**
131131
- <img src="docs/crescent.png" width="128"/> **`Sketch::crescent(outer_r: Real, inner_r: Real, offset: Real, segments: usize, metadata: Option<S>)`** -
132-
- <img src="docs/gear_involute.png" width="128"/> **`Sketch::involute_gear(module_: Real, teeth: usize, pressure_angle_deg: Real, clearance: Real, backlash: Real, segments_per_flank: usize, metadata: Option<S>)`**
132+
- <img src="docs/gear_involute.png" width="128"/> **`Sketch::involute_gear(module: Real, teeth: usize, pressure_angle_deg: Real, clearance: Real, backlash: Real, segments_per_flank: usize, metadata: Option<S>)`**
133133
- **`Sketch::cycloidal_gear(module_: Real, teeth: usize, pin_teeth: usize, clearance: Real, segments_per_flank: usize, metadata: Option<S>)`** - under construction
134134
- **`Sketch::involute_rack(module_: Real, num_teeth: usize, pressure_angle_deg: Real, clearance: Real, backlash: Real, metadata: Option<S>)`** - under construction
135135
- **`Sketch::cycloidal_rack(module_: Real, num_teeth: usize, generating_radius: Real, clearance: Real, segments_per_flank: usize, metadata: Option<S>)`** - under construction
@@ -601,6 +601,7 @@ for Polygon
601601
- rework bezier and bspline using https://github.com/mattatz/curvo
602602
- import functions from https://github.com/nical/lyon/tree/main/crates/geom/src for cubic and quadratic bezier
603603
- https://docs.rs/rgeometry/latest/rgeometry/algorithms/polygonization/fn.two_opt_moves.html and other algorithms from rgeometry crate
604+
- add optional root fillets, dedendum arcs, and backlash/backlash-aware spacing to gears
604605

605606
## Todo shapes
606607
- geodesic domes / goldberg polyhedra

src/sketch/mod.rs

Lines changed: 46 additions & 3 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};
@@ -68,7 +68,7 @@ impl<S: Clone + Send + Sync + Debug> Sketch<S> {
6868
new_sketch
6969
}
7070

71-
/// Triangulate this polygon into a list of triangles, each triangle is [v0, v1, v2].
71+
/// Triangulate an outer polygon and holes into a list of triangles, each triangle is [v0, v1, v2].
7272
pub fn triangulate_2d(
7373
outer: &[[Real; 2]],
7474
holes: &[&[[Real; 2]]],
@@ -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)