Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/mesh/flatten_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ impl<S: Clone + Debug + Send + Sync> Mesh<S> {
geometry: new_gc,
bounding_box: OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,
origin_transform: Sketch::<S>::prepare_origin_vec_and_quat(self.origin),
}
}

Expand Down Expand Up @@ -154,6 +156,8 @@ impl<S: Clone + Debug + Send + Sync> Mesh<S> {
geometry: new_gc,
bounding_box: OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,
origin_transform: Sketch::<S>::prepare_origin_vec_and_quat(self.origin),
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/mesh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub struct Mesh<S: Clone + Send + Sync + Debug> {

/// Metadata
pub metadata: Option<S>,

/// Origin
pub origin: Vertex,
}

impl<S: Clone + Send + Sync + Debug + PartialEq> Mesh<S> {
Expand All @@ -80,6 +83,7 @@ impl<S: Clone + Send + Sync + Debug + PartialEq> Mesh<S> {
polygons: polys,
bounding_box: std::sync::OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,
}
}
}
Expand Down Expand Up @@ -450,6 +454,7 @@ impl<S: Clone + Send + Sync + Debug> CSG for Mesh<S> {
polygons: Vec::new(),
bounding_box: OnceLock::new(),
metadata: None,
origin: Default::default(),
}
}

Expand Down Expand Up @@ -492,6 +497,7 @@ impl<S: Clone + Send + Sync + Debug> CSG for Mesh<S> {
polygons: final_polys,
bounding_box: OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,
}
}

Expand Down Expand Up @@ -546,6 +552,7 @@ impl<S: Clone + Send + Sync + Debug> CSG for Mesh<S> {
polygons: final_polys,
bounding_box: OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,
}
}

Expand Down Expand Up @@ -578,6 +585,7 @@ impl<S: Clone + Send + Sync + Debug> CSG for Mesh<S> {
polygons: a.all_polygons(),
bounding_box: OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,
}
}

Expand Down Expand Up @@ -791,6 +799,7 @@ impl<S: Clone + Send + Sync + Debug> From<Sketch<S>> for Mesh<S> {
polygons: final_polygons,
bounding_box: OnceLock::new(),
metadata: None,
origin: sketch.origin,
}
}
}
7 changes: 7 additions & 0 deletions src/mesh/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ pub struct Vertex {
pub normal: Vector3<Real>,
}

/// Default to a position of (0, 0, 0) facing +Z
impl Default for Vertex {
fn default() -> Self {
Vertex::new(Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 0.0, 1.0))
}
}

impl Vertex {
/// Create a new [`Vertex`].
///
Expand Down
105 changes: 84 additions & 21 deletions src/sketch/extrudes.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
//! Functions to extrude, revolve, loft, and otherwise transform 2D `Sketch`s into 3D `Mesh`s

use crate::apply_origin_transform;
use crate::errors::ValidationError;
use crate::float_types::{Real, tolerance};
use crate::mesh::Mesh;
use crate::mesh::polygon::Polygon;
use crate::mesh::vertex::Vertex;
use crate::sketch::Sketch;
use crate::sketch::{OriginTransformVecQuat, Sketch};
use crate::traits::CSG;
use geo::{Area, CoordsIter, LineString, Polygon as GeoPolygon};
use nalgebra::{Point3, Vector3};
use std::fmt::Debug;
use std::sync::OnceLock;

impl<S: Clone + Debug + Send + Sync> Sketch<S> {
#[inline]
/// Linearly extrude this (2D) shape in the +Z direction by `height`.
///
/// This is just a convenience wrapper around extrude_vector using Vector3::new(0.0, 0.0, height)
Expand Down Expand Up @@ -89,24 +91,33 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
return Mesh::new();
}

// !TODO! Find a way to avoid re-allocating so much
// Collect 3-D polygons generated from every `geo` geometry in the sketch
let mut out: Vec<Polygon<S>> = Vec::new();

for geom in &self.geometry {
Self::extrude_geometry(geom, direction, &self.metadata, &mut out);
Self::extrude_geometry(
geom,
direction,
self.origin_transform,
&self.metadata,
&mut out,
);
}

Mesh {
polygons: out,
bounding_box: OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,
}
}

/// A helper to handle any Geometry
fn extrude_geometry(
geom: &geo::Geometry<Real>,
direction: Vector3<Real>,
origin_transform: OriginTransformVecQuat,
metadata: &Option<S>,
out_polygons: &mut Vec<Polygon<S>>,
) {
Expand All @@ -127,19 +138,37 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {

// bottom
for tri in &tris {
let v0 = Vertex::new(tri[2], -Vector3::z());
let v1 = Vertex::new(tri[1], -Vector3::z());
let v2 = Vertex::new(tri[0], -Vector3::z());
let v0 = apply_origin_transform!(
Vertex::new(tri[2], -Vector3::z()),
origin_transform
);
let v1 = apply_origin_transform!(
Vertex::new(tri[1], -Vector3::z()),
origin_transform
);
let v2 = apply_origin_transform!(
Vertex::new(tri[0], -Vector3::z()),
origin_transform
);
out_polygons.push(Polygon::new(vec![v0, v1, v2], metadata.clone()));
}
// top
for tri in &tris {
let p0 = tri[0] + direction;
let p1 = tri[1] + direction;
let p2 = tri[2] + direction;
let v0 = Vertex::new(p0, Vector3::z());
let v1 = Vertex::new(p1, Vector3::z());
let v2 = Vertex::new(p2, Vector3::z());
let v0 = apply_origin_transform!(
Vertex::new(p0, Vector3::z()),
origin_transform
);
let v1 = apply_origin_transform!(
Vertex::new(p1, Vector3::z()),
origin_transform
);
let v2 = apply_origin_transform!(
Vertex::new(p2, Vector3::z()),
origin_transform
);
out_polygons.push(Polygon::new(vec![v0, v1, v2], metadata.clone()));
}

Expand All @@ -156,10 +185,22 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
let t_j = b_j + direction;
out_polygons.push(Polygon::new(
vec![
Vertex::new(b_i, Vector3::zeros()),
Vertex::new(b_j, Vector3::zeros()),
Vertex::new(t_j, Vector3::zeros()),
Vertex::new(t_i, Vector3::zeros()),
apply_origin_transform!(
Vertex::new(b_i, Vector3::zeros()),
origin_transform
),
apply_origin_transform!(
Vertex::new(b_j, Vector3::zeros()),
origin_transform
),
apply_origin_transform!(
Vertex::new(t_j, Vector3::zeros()),
origin_transform
),
apply_origin_transform!(
Vertex::new(t_i, Vector3::zeros()),
origin_transform
),
],
metadata.clone(),
));
Expand All @@ -171,14 +212,21 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
Self::extrude_geometry(
&geo::Geometry::Polygon(poly.clone()),
direction,
origin_transform,
metadata,
out_polygons,
);
}
},
geo::Geometry::GeometryCollection(gc) => {
for sub in &gc.0 {
Self::extrude_geometry(sub, direction, metadata, out_polygons);
Self::extrude_geometry(
sub,
direction,
origin_transform,
metadata,
out_polygons,
);
}
},
geo::Geometry::LineString(ls) => {
Expand All @@ -195,10 +243,22 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
let normal = (b_j - b_i).cross(&(t_i - b_i)).normalize();
out_polygons.push(Polygon::new(
vec![
Vertex::new(b_i, normal),
Vertex::new(b_j, normal),
Vertex::new(t_j, normal),
Vertex::new(t_i, normal),
apply_origin_transform!(
Vertex::new(b_i, normal),
origin_transform
),
apply_origin_transform!(
Vertex::new(b_j, normal),
origin_transform
),
apply_origin_transform!(
Vertex::new(t_j, normal),
origin_transform
),
apply_origin_transform!(
Vertex::new(t_i, normal),
origin_transform
),
],
metadata.clone(),
));
Expand All @@ -215,10 +275,10 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
let normal = (b1 - b0).cross(&(t0 - b0)).normalize();
out_polygons.push(Polygon::new(
vec![
Vertex::new(b0, normal),
Vertex::new(b1, normal),
Vertex::new(t1, normal),
Vertex::new(t0, normal),
apply_origin_transform!(Vertex::new(b0, normal), origin_transform),
apply_origin_transform!(Vertex::new(b1, normal), origin_transform),
apply_origin_transform!(Vertex::new(t1, normal), origin_transform),
apply_origin_transform!(Vertex::new(t0, normal), origin_transform),
],
metadata.clone(),
));
Expand All @@ -230,6 +290,7 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
Self::extrude_geometry(
&geo::Geometry::Polygon(poly2d),
direction,
origin_transform,
metadata,
out_polygons,
);
Expand All @@ -241,6 +302,7 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
Self::extrude_geometry(
&geo::Geometry::Polygon(poly2d),
direction,
origin_transform,
metadata,
out_polygons,
);
Expand Down Expand Up @@ -810,6 +872,7 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
polygons: new_polygons,
bounding_box: OnceLock::new(),
metadata: self.metadata.clone(),
origin: self.origin,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The origin field is now correctly propagated to the Mesh created by revolve. However, the origin_transform is not being applied to the vertices of the revolved geometry. This means the resulting mesh will be located at the world origin, not at the sketch's origin, which is inconsistent with extrude_vector.

To fix this, self.origin_transform should be passed down to the revolve_ring and build_cap_polygon helper functions. Then, the apply_origin_transform! macro should be used on each created Vertex, similar to how it's done in extrude_geometry.

})
}

Expand Down
2 changes: 2 additions & 0 deletions src/sketch/hershey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
geometry: geo_coll,
bounding_box: OnceLock::new(),
metadata,
origin: Default::default(),
origin_transform: Sketch::<S>::prepare_origin_vec_and_quat(Default::default()),
}
}
}
Expand Down
Loading