Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge BoundaryOnCurve and BoundingVertices #1967

Merged
merged 14 commits into from
Jul 27, 2023
Merged
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
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