Move GenPolyline to geometry::traits

This commit is contained in:
Hanno Braun 2024-09-17 19:19:42 +02:00
parent a1f043b9e0
commit 5a4a1ad732
3 changed files with 85 additions and 82 deletions

View File

@ -1,10 +1,8 @@
use std::{collections::BTreeMap, sync::Arc};
use fj_math::Point;
use crate::{storage::Handle, topology::Surface};
use super::{CurveBoundary, Path, Tolerance};
use super::{traits::GenPolyline, Path};
/// The geometric definition of a curve
#[derive(Clone, Debug, Default)]
@ -73,81 +71,3 @@ pub enum CurveGeom2 {
geometry: Arc<dyn GenPolyline<3>>,
},
}
/// # Generate polylines, the uniform representation of curve geometry
///
/// This trait provides a generic and uniform interface to curve geometry. It is
/// implemented by types that represent specific kinds of curve geometry.
///
/// It is generic over the dimensionality of the generated polyline. Typically,
/// two variants should be implemented per curve geometry type:
///
/// - `CurveGeom2<2>` for surface-local geometry.
/// - `CurveGeom2<3>` for global 3D geometry.
///
///
/// ## Determinism
///
/// For a given curve and a given tolerance, the uniform representation of a
/// curve must be deterministic. This means that the same representation must be
/// returned, regardless of which points on the curve are queried, and in what
/// order.
pub trait GenPolyline<const D: usize> {
/// # Access the origin of the curve
fn origin(&self) -> Point<D>;
/// # Compute a line segment to approximate the curve at this point
///
/// ## Degenerate Case
///
/// If the curve requires no approximation (meaning it is a line), then per
/// convention, a degenerate line segment is returned, that collapses to the
/// provided point.
fn line_segment_at(
&self,
point: Point<1>,
tolerance: Tolerance,
) -> [Point<D>; 2];
/// # Generate a polyline within the provided boundary
fn generate_polyline(
&self,
boundary: CurveBoundary<Point<1>>,
tolerance: Tolerance,
) -> Vec<Point<1>>;
}
// This implementation is temporary, to ease the transition towards a curve
// geometry trait. Eventually, `CurveGeom2` is expected to replace `Path`.
impl<const D: usize> GenPolyline<D> for Path<D> {
fn origin(&self) -> Point<D> {
match self {
Self::Circle(circle) => circle.origin(),
Self::Line(line) => line.origin(),
}
}
fn line_segment_at(
&self,
point: Point<1>,
tolerance: Tolerance,
) -> [Point<D>; 2] {
match self {
Self::Circle(circle) => circle.line_segment_at(point, tolerance),
Self::Line(line) => line.line_segment_at(point, tolerance),
}
}
fn generate_polyline(
&self,
boundary: CurveBoundary<Point<1>>,
tolerance: Tolerance,
) -> Vec<Point<1>> {
match self {
Self::Circle(circle) => {
circle.generate_polyline(boundary, tolerance)
}
Self::Line(line) => line.generate_polyline(boundary, tolerance),
}
}
}

View File

@ -13,10 +13,11 @@ mod vertex;
pub use self::{
boundary::{CurveBoundary, CurveBoundaryElement},
curve::{CurveGeom, CurveGeom2, GenPolyline, LocalCurveGeom},
curve::{CurveGeom, CurveGeom2, LocalCurveGeom},
geometry::Geometry,
path::Path,
surface::SurfaceGeom,
tolerance::{InvalidTolerance, Tolerance},
traits::GenPolyline,
vertex::{LocalVertexGeom, VertexGeom},
};

View File

@ -10,3 +10,85 @@
//! As of this writing, the transition from the previous, more limited, geometry
//! system to the new one based on uniform representation is still ongoing. As a
//! result of that, this module might still be incomplete.
use fj_math::Point;
use super::{CurveBoundary, Path, Tolerance};
/// # Generate polylines, the uniform representation of curve geometry
///
/// This trait provides a generic and uniform interface to curve geometry. It is
/// implemented by types that represent specific kinds of curve geometry.
///
/// It is generic over the dimensionality of the generated polyline. Typically,
/// two variants should be implemented per curve geometry type:
///
/// - `CurveGeom2<2>` for surface-local geometry.
/// - `CurveGeom2<3>` for global 3D geometry.
///
///
/// ## Determinism
///
/// For a given curve and a given tolerance, the uniform representation of a
/// curve must be deterministic. This means that the same representation must be
/// returned, regardless of which points on the curve are queried, and in what
/// order.
pub trait GenPolyline<const D: usize> {
/// # Access the origin of the curve
fn origin(&self) -> Point<D>;
/// # Compute a line segment to approximate the curve at this point
///
/// ## Degenerate Case
///
/// If the curve requires no approximation (meaning it is a line), then per
/// convention, a degenerate line segment is returned, that collapses to the
/// provided point.
fn line_segment_at(
&self,
point: Point<1>,
tolerance: Tolerance,
) -> [Point<D>; 2];
/// # Generate a polyline within the provided boundary
fn generate_polyline(
&self,
boundary: CurveBoundary<Point<1>>,
tolerance: Tolerance,
) -> Vec<Point<1>>;
}
// This implementation is temporary, to ease the transition towards a curve
// geometry trait. Eventually, `CurveGeom2` is expected to replace `Path`.
impl<const D: usize> GenPolyline<D> for Path<D> {
fn origin(&self) -> Point<D> {
match self {
Self::Circle(circle) => circle.origin(),
Self::Line(line) => line.origin(),
}
}
fn line_segment_at(
&self,
point: Point<1>,
tolerance: Tolerance,
) -> [Point<D>; 2] {
match self {
Self::Circle(circle) => circle.line_segment_at(point, tolerance),
Self::Line(line) => line.line_segment_at(point, tolerance),
}
}
fn generate_polyline(
&self,
boundary: CurveBoundary<Point<1>>,
tolerance: Tolerance,
) -> Vec<Point<1>> {
match self {
Self::Circle(circle) => {
circle.generate_polyline(boundary, tolerance)
}
Self::Line(line) => line.generate_polyline(boundary, tolerance),
}
}
}