Skip to content

Commit

Permalink
Merge pull request #1967 from hannobraun/boundary
Browse files Browse the repository at this point in the history
Merge `BoundaryOnCurve` and `BoundingVertices`
  • Loading branch information
hannobraun authored Jul 27, 2023
2 parents 895fa6f + 1478400 commit 8dfb4ff
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 74 deletions.
18 changes: 9 additions & 9 deletions crates/fj-core/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::collections::BTreeMap;
use fj_math::Point;

use crate::{
geometry::{BoundaryOnCurve, GlobalPath, SurfacePath},
geometry::{CurveBoundary, GlobalPath, SurfacePath},
objects::{GlobalEdge, HalfEdge, Surface, Vertex},
storage::{Handle, HandleWrapper},
};
Expand Down Expand Up @@ -141,7 +141,7 @@ impl HalfEdgeApprox {
fn approx_edge(
path: &SurfacePath,
surface: &Surface,
boundary: BoundaryOnCurve,
boundary: CurveBoundary<Point<1>>,
tolerance: impl Into<Tolerance>,
) -> GlobalEdgeApprox {
// There are different cases of varying complexity. Circles are the hard
Expand Down Expand Up @@ -185,7 +185,7 @@ fn approx_edge(
}
(SurfacePath::Line(line), _) => {
let range_u =
BoundaryOnCurve::from(boundary.inner.map(|point_curve| {
CurveBoundary::from(boundary.inner.map(|point_curve| {
[path.point_from_path_coords(point_curve).u]
}));

Expand Down Expand Up @@ -218,7 +218,7 @@ fn approx_edge(
#[derive(Default)]
pub struct EdgeCache {
edge_approx: BTreeMap<
(HandleWrapper<GlobalEdge>, BoundaryOnCurve),
(HandleWrapper<GlobalEdge>, CurveBoundary<Point<1>>),
GlobalEdgeApprox,
>,
vertex_approx: BTreeMap<HandleWrapper<Vertex>, Point<3>>,
Expand All @@ -234,7 +234,7 @@ impl EdgeCache {
fn get_edge(
&self,
handle: Handle<GlobalEdge>,
boundary: BoundaryOnCurve,
boundary: CurveBoundary<Point<1>>,
) -> Option<GlobalEdgeApprox> {
if let Some(approx) =
self.edge_approx.get(&(handle.clone().into(), boundary))
Expand All @@ -256,7 +256,7 @@ impl EdgeCache {
fn insert_edge(
&mut self,
handle: Handle<GlobalEdge>,
boundary: BoundaryOnCurve,
boundary: CurveBoundary<Point<1>>,
approx: GlobalEdgeApprox,
) -> GlobalEdgeApprox {
self.edge_approx
Expand Down Expand Up @@ -302,7 +302,7 @@ mod tests {

use crate::{
algorithms::approx::{Approx, ApproxPoint},
geometry::{BoundaryOnCurve, GlobalPath, SurfaceGeometry},
geometry::{CurveBoundary, GlobalPath, SurfaceGeometry},
objects::{HalfEdge, Surface},
operations::BuildHalfEdge,
services::Services,
Expand Down Expand Up @@ -344,7 +344,7 @@ mod tests {
let mut services = Services::new();

let path = GlobalPath::circle_from_radius(1.);
let boundary = BoundaryOnCurve::from([[0.], [TAU]]);
let boundary = CurveBoundary::from([[0.], [TAU]]);

let surface = Surface::new(SurfaceGeometry {
u: path,
Expand Down Expand Up @@ -384,7 +384,7 @@ mod tests {
let approx = (&half_edge, surface.deref()).approx(tolerance);

let expected_approx =
(&half_edge.path(), BoundaryOnCurve::from([[0.], [TAU]]))
(&half_edge.path(), CurveBoundary::from([[0.], [TAU]]))
.approx(tolerance)
.into_iter()
.map(|(_, point_surface)| {
Expand Down
14 changes: 7 additions & 7 deletions crates/fj-core/src/algorithms/approx/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ use std::iter;

use fj_math::{Circle, Point, Scalar, Sign};

use crate::geometry::{BoundaryOnCurve, GlobalPath, SurfacePath};
use crate::geometry::{CurveBoundary, GlobalPath, SurfacePath};

use super::{Approx, Tolerance};

impl Approx for (&SurfacePath, BoundaryOnCurve) {
impl Approx for (&SurfacePath, CurveBoundary<Point<1>>) {
type Approximation = Vec<(Point<1>, Point<2>)>;
type Cache = ();

Expand All @@ -56,7 +56,7 @@ impl Approx for (&SurfacePath, BoundaryOnCurve) {
}
}

impl Approx for (GlobalPath, BoundaryOnCurve) {
impl Approx for (GlobalPath, CurveBoundary<Point<1>>) {
type Approximation = Vec<(Point<1>, Point<3>)>;
type Cache = ();

Expand All @@ -82,7 +82,7 @@ impl Approx for (GlobalPath, BoundaryOnCurve) {
/// from the circle.
fn approx_circle<const D: usize>(
circle: &Circle<D>,
boundary: impl Into<BoundaryOnCurve>,
boundary: impl Into<CurveBoundary<Point<1>>>,
tolerance: Tolerance,
) -> Vec<(Point<1>, Point<D>)> {
let boundary = boundary.into();
Expand Down Expand Up @@ -127,7 +127,7 @@ impl PathApproxParams {

pub fn points(
&self,
boundary: impl Into<BoundaryOnCurve>,
boundary: impl Into<CurveBoundary<Point<1>>>,
) -> impl Iterator<Item = Point<1>> + '_ {
let boundary = boundary.into();

Expand Down Expand Up @@ -170,7 +170,7 @@ mod tests {

use fj_math::{Circle, Point, Scalar};

use crate::algorithms::approx::{path::BoundaryOnCurve, Tolerance};
use crate::algorithms::approx::{path::CurveBoundary, Tolerance};

use super::PathApproxParams;

Expand Down Expand Up @@ -220,7 +220,7 @@ mod tests {
test_path([[TAU - 2.], [0.]], [2., 1.]);

fn test_path(
boundary: impl Into<BoundaryOnCurve>,
boundary: impl Into<CurveBoundary<Point<1>>>,
expected_coords: impl IntoIterator<Item = impl Into<Scalar>>,
) {
// Choose radius and tolerance such, that we need 4 vertices to
Expand Down
83 changes: 76 additions & 7 deletions crates/fj-core/src/geometry/boundary.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,95 @@
use std::{
cmp::Ordering,
hash::{Hash, Hasher},
};

use fj_math::Point;

use crate::{objects::Vertex, storage::HandleWrapper};

/// A boundary on a curve
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct BoundaryOnCurve {
///
/// This struct is generic, because different situations require different
/// representations of a boundary. In some cases, curve coordinates are enough,
/// in other cases, vertices are required, and sometimes you need both.
#[derive(Clone, Copy, Debug)]
pub struct CurveBoundary<T: CurveBoundaryElement> {
/// The raw representation of the boundary
pub inner: [Point<1>; 2],
pub inner: [T::Repr; 2],
}

impl BoundaryOnCurve {
impl<T: CurveBoundaryElement> CurveBoundary<T> {
/// Reverse the direction of the boundary
///
/// Returns a new instance of this struct, which has its direction reversed.
#[must_use]
pub fn reverse(self) -> Self {
let [a, b] = self.inner;
Self { inner: [b, a] }
}

/// Normalize the boundary
///
/// Returns a new instance of this struct, which has the bounding elements
/// in a defined order. This can be used to compare a boundary while
/// disregarding its direction.
#[must_use]
pub fn normalize(mut self) -> Self {
self.inner.sort();
self
}
}

impl<T: CurveBoundaryElement> Eq for CurveBoundary<T> {}

impl<T: CurveBoundaryElement> PartialEq for CurveBoundary<T> {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}

impl<T> From<[T; 2]> for BoundaryOnCurve
impl<S, T: CurveBoundaryElement> From<[S; 2]> for CurveBoundary<T>
where
T: Into<Point<1>>,
S: Into<T::Repr>,
{
fn from(boundary: [T; 2]) -> Self {
fn from(boundary: [S; 2]) -> Self {
let inner = boundary.map(Into::into);
Self { inner }
}
}

impl<T: CurveBoundaryElement> Hash for CurveBoundary<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner.hash(state);
}
}

impl<T: CurveBoundaryElement> Ord for CurveBoundary<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.inner.cmp(&other.inner)
}
}

impl<T: CurveBoundaryElement> PartialOrd for CurveBoundary<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.inner.partial_cmp(&other.inner)
}
}

/// An element of a curve boundary
///
/// Used for the type parameter of [`CurveBoundary`].
pub trait CurveBoundaryElement {
/// The representation the curve boundary element
///
/// This is the actual data stored in [`CurveBoundary`].
type Repr: Eq + Hash + Ord;
}

impl CurveBoundaryElement for Point<1> {
type Repr = Self;
}

impl CurveBoundaryElement for Vertex {
type Repr = HandleWrapper<Vertex>;
}
31 changes: 0 additions & 31 deletions crates/fj-core/src/geometry/bounding_vertices.rs

This file was deleted.

4 changes: 1 addition & 3 deletions crates/fj-core/src/geometry/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
//! Types that are tied to objects, but aren't objects themselves
mod boundary;
mod bounding_vertices;
mod path;
mod surface;

pub use self::{
boundary::BoundaryOnCurve,
bounding_vertices::BoundingVertices,
boundary::{CurveBoundary, CurveBoundaryElement},
path::{GlobalPath, SurfacePath},
surface::SurfaceGeometry,
};
8 changes: 4 additions & 4 deletions crates/fj-core/src/objects/kinds/edge.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fj_math::Point;

use crate::{
geometry::{BoundaryOnCurve, SurfacePath},
geometry::{CurveBoundary, SurfacePath},
objects::{Curve, Vertex},
storage::{Handle, HandleWrapper},
};
Expand Down Expand Up @@ -41,7 +41,7 @@ use crate::{
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct HalfEdge {
path: SurfacePath,
boundary: BoundaryOnCurve,
boundary: CurveBoundary<Point<1>>,
curve: HandleWrapper<Curve>,
start_vertex: HandleWrapper<Vertex>,
global_form: HandleWrapper<GlobalEdge>,
Expand All @@ -51,7 +51,7 @@ impl HalfEdge {
/// Create an instance of `HalfEdge`
pub fn new(
path: SurfacePath,
boundary: impl Into<BoundaryOnCurve>,
boundary: impl Into<CurveBoundary<Point<1>>>,
curve: Handle<Curve>,
start_vertex: Handle<Vertex>,
global_form: Handle<GlobalEdge>,
Expand All @@ -71,7 +71,7 @@ impl HalfEdge {
}

/// Access the boundary points of the half-edge on the curve
pub fn boundary(&self) -> BoundaryOnCurve {
pub fn boundary(&self) -> CurveBoundary<Point<1>> {
self.boundary
}

Expand Down
4 changes: 2 additions & 2 deletions crates/fj-core/src/operations/build/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use fj_interop::ext::ArrayExt;
use fj_math::{Arc, Point, Scalar};

use crate::{
geometry::{BoundaryOnCurve, SurfacePath},
geometry::{CurveBoundary, SurfacePath},
objects::{Curve, GlobalEdge, HalfEdge, Vertex},
operations::Insert,
services::Services,
Expand All @@ -13,7 +13,7 @@ pub trait BuildHalfEdge {
/// Create a half-edge that is not joined to another
fn unjoined(
path: SurfacePath,
boundary: impl Into<BoundaryOnCurve>,
boundary: impl Into<CurveBoundary<Point<1>>>,
services: &mut Services,
) -> HalfEdge {
let curve = Curve::new().insert(services);
Expand Down
7 changes: 4 additions & 3 deletions crates/fj-core/src/operations/join/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::ops::RangeInclusive;

use fj_math::Point;
use itertools::Itertools;

use crate::{
geometry::{BoundaryOnCurve, SurfacePath},
geometry::{CurveBoundary, SurfacePath},
objects::{Cycle, HalfEdge},
operations::{BuildHalfEdge, Insert, UpdateCycle, UpdateHalfEdge},
services::Services,
Expand All @@ -17,7 +18,7 @@ pub trait JoinCycle {
fn add_joined_edges<Es>(&self, edges: Es, services: &mut Services) -> Self
where
Es: IntoIterator<
Item = (Handle<HalfEdge>, SurfacePath, BoundaryOnCurve),
Item = (Handle<HalfEdge>, SurfacePath, CurveBoundary<Point<1>>),
>,
Es::IntoIter: Clone + ExactSizeIterator;

Expand Down Expand Up @@ -64,7 +65,7 @@ impl JoinCycle for Cycle {
fn add_joined_edges<Es>(&self, edges: Es, services: &mut Services) -> Self
where
Es: IntoIterator<
Item = (Handle<HalfEdge>, SurfacePath, BoundaryOnCurve),
Item = (Handle<HalfEdge>, SurfacePath, CurveBoundary<Point<1>>),
>,
Es::IntoIter: Clone + ExactSizeIterator,
{
Expand Down
Loading

0 comments on commit 8dfb4ff

Please sign in to comment.