Skip to content

Commit

Permalink
Merge pull request #2453 from hannobraun/geom
Browse files Browse the repository at this point in the history
Add `SurfaceGeom::triangle_at`; rewrite point/vector conversion on top of it
  • Loading branch information
hannobraun authored Aug 13, 2024
2 parents 6e747ac + 884c284 commit b78358d
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 78 deletions.
6 changes: 5 additions & 1 deletion crates/fj-core/src/algorithms/approx/circle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ pub fn approx_circle<const D: usize>(
points
}

struct PathApproxParams {
/// Path approximation parameters for a circle
pub struct PathApproxParams {
increment: Scalar,
}

impl PathApproxParams {
/// Compute path approximation parameters for the given circle and tolerance
pub fn for_circle<const D: usize>(
circle: &Circle<D>,
tolerance: impl Into<Tolerance>,
Expand All @@ -82,10 +84,12 @@ impl PathApproxParams {
Self { increment }
}

/// Return the increment
pub fn increment(&self) -> Scalar {
self.increment
}

/// Generate points to approximate the circle within the boundary
pub fn points(
&self,
boundary: impl Into<CurveBoundary<Point<1>>>,
Expand Down
14 changes: 10 additions & 4 deletions crates/fj-core/src/algorithms/approx/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ fn approx_circle_on_straight_surface(
surface: &SurfaceGeom,
tolerance: impl Into<Tolerance>,
) -> Vec<ApproxPoint<1>> {
let tolerance = tolerance.into();

approx_circle(circle, boundary, tolerance)
.into_iter()
.map(|(point_curve, point_surface)| {
Expand All @@ -93,7 +95,8 @@ fn approx_circle_on_straight_surface(
// point available, so it needs to be computed later anyway, in
// the general case.

let point_global = surface.point_from_surface_coords(point_surface);
let point_global =
surface.point_from_surface_coords(point_surface, tolerance);
ApproxPoint::new(point_curve, point_global)
})
.collect()
Expand All @@ -105,6 +108,8 @@ fn approx_line_on_any_surface(
surface: &SurfaceGeom,
tolerance: impl Into<Tolerance>,
) -> Vec<ApproxPoint<1>> {
let tolerance = tolerance.into();

let range_u = CurveBoundary::from(
boundary
.inner
Expand All @@ -121,7 +126,8 @@ fn approx_line_on_any_surface(
for (u, _) in approx_u {
let t = (u.t - line.origin().u) / line.direction().u;
let point_surface = line.point_from_line_coords([t]);
let point_global = surface.point_from_surface_coords(point_surface);
let point_global =
surface.point_from_surface_coords(point_surface, tolerance);
points.push(ApproxPoint::new(u, point_global));
}

Expand Down Expand Up @@ -258,7 +264,7 @@ mod tests {
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(point_surface);
.point_from_surface_coords(point_surface, tolerance);
ApproxPoint::new(point_local, point_global)
})
.collect::<Vec<_>>();
Expand Down Expand Up @@ -286,7 +292,7 @@ mod tests {
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(point_surface);
.point_from_surface_coords(point_surface, tolerance);
ApproxPoint::new(point_local, point_global)
})
.collect::<Vec<_>>();
Expand Down
1 change: 1 addition & 0 deletions crates/fj-core/src/algorithms/approx/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub fn approx_cycle(
half_edge.curve(),
surface,
start_position_curve,
tolerance,
&mut cache.vertex,
geometry,
);
Expand Down
5 changes: 4 additions & 1 deletion crates/fj-core/src/algorithms/approx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ use vertex::VertexApproxCache;

use crate::geometry::Geometry;

pub use self::tolerance::{InvalidTolerance, Tolerance};
pub use self::{
circle::PathApproxParams,
tolerance::{InvalidTolerance, Tolerance},
};

/// Approximate an object
pub trait Approx: Sized {
Expand Down
5 changes: 3 additions & 2 deletions crates/fj-core/src/algorithms/approx/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ use crate::{
topology::{Curve, Surface, Vertex},
};

use super::ApproxPoint;
use super::{ApproxPoint, Tolerance};

/// # Approximate a vertex position
pub fn approx_vertex(
vertex: Handle<Vertex>,
curve: &Handle<Curve>,
surface: &Handle<Surface>,
position_curve: Point<1>,
tolerance: impl Into<Tolerance>,
cache: &mut VertexApproxCache,
geometry: &Geometry,
) -> ApproxPoint<1> {
Expand All @@ -32,7 +33,7 @@ pub fn approx_vertex(
None => {
let position_global = geometry
.of_surface(surface)
.point_from_surface_coords(position_surface);
.point_from_surface_coords(position_surface, tolerance);
cache.insert(vertex, position_global)
}
};
Expand Down
29 changes: 24 additions & 5 deletions crates/fj-core/src/algorithms/bounding_volume/face.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::ops::Deref;

use fj_math::Aabb;
use fj_math::{Aabb, Vector};

use crate::{
algorithms::approx::Tolerance,
geometry::{Geometry, GlobalPath, SurfaceGeom},
topology::Face,
};
Expand All @@ -29,10 +30,28 @@ impl super::BoundingVolume<3> for &Face {

aabb_bottom.merged(&aabb_top)
}
GlobalPath::Line(_) => Aabb {
min: surface.point_from_surface_coords(aabb2.min),
max: surface.point_from_surface_coords(aabb2.max),
},
GlobalPath::Line(_) => {
// A bounding volume must include the body it bounds,
// but does not need to match it precisely. So it's
// okay, if it's a bit larger.
//
// Let's just choose a reasonable tolerance value here,
// then make sure we enlarge the AABB accordingly, to
// make sure it fits.
let tolerance_f64 = 0.001;
let tolerance = Tolerance::from_scalar(tolerance_f64)
.expect("Tolerance provided is larger than zero");
let offset = Vector::from([tolerance_f64; 3]);

Aabb {
min: surface.point_from_surface_coords(
aabb2.min, tolerance,
) - offset,
max: surface.point_from_surface_coords(
aabb2.max, tolerance,
) + offset,
}
}
}
})
}
Expand Down
22 changes: 11 additions & 11 deletions crates/fj-core/src/algorithms/triangulate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,32 +180,32 @@ mod tests {
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(a);
.point_from_surface_coords(a, core.tolerance());
let b = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(b);
.point_from_surface_coords(b, core.tolerance());
let e = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(e);
.point_from_surface_coords(e, core.tolerance());
let f = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(f);
.point_from_surface_coords(f, core.tolerance());
let g = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(g);
.point_from_surface_coords(g, core.tolerance());
let h = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(h);
.point_from_surface_coords(h, core.tolerance());

// Let's test that some correct triangles are present. We don't need to
// test them all.
Expand Down Expand Up @@ -275,27 +275,27 @@ mod tests {
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(a);
.point_from_surface_coords(a, core.tolerance());
let b = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(b);
.point_from_surface_coords(b, core.tolerance());
let c = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(c);
.point_from_surface_coords(c, core.tolerance());
let d = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(d);
.point_from_surface_coords(d, core.tolerance());
let e = core
.layers
.geometry
.of_surface(&surface)
.point_from_surface_coords(e);
.point_from_surface_coords(e, core.tolerance());

assert!(triangles.contains_triangle([a, b, d]));
assert!(triangles.contains_triangle([a, d, e]));
Expand Down
Loading

0 comments on commit b78358d

Please sign in to comment.