mirror of
https://github.com/hannobraun/Fornjot
synced 2025-01-11 10:47:09 +00:00
Merge pull request #1616 from hannobraun/curve
Merge `Curve` into `HalfEdge`
This commit is contained in:
commit
dffd7bbe22
@ -9,7 +9,7 @@ use std::collections::BTreeMap;
|
||||
|
||||
use crate::{
|
||||
geometry::path::{GlobalPath, SurfacePath},
|
||||
objects::{Curve, GlobalEdge, HalfEdge, Surface},
|
||||
objects::{GlobalEdge, HalfEdge, Surface},
|
||||
storage::{Handle, ObjectId},
|
||||
};
|
||||
|
||||
@ -41,7 +41,7 @@ impl Approx for (&Handle<HalfEdge>, &Surface) {
|
||||
Some(approx) => approx,
|
||||
None => {
|
||||
let approx = approx_edge(
|
||||
half_edge.curve(),
|
||||
&half_edge.curve(),
|
||||
surface,
|
||||
range,
|
||||
tolerance,
|
||||
@ -56,14 +56,10 @@ impl Approx for (&Handle<HalfEdge>, &Surface) {
|
||||
.map(|point| {
|
||||
let point_surface = half_edge
|
||||
.curve()
|
||||
.path()
|
||||
.point_from_path_coords(point.local_form);
|
||||
|
||||
ApproxPoint::new(point_surface, point.global_form)
|
||||
.with_source((
|
||||
half_edge.curve().clone(),
|
||||
point.local_form,
|
||||
))
|
||||
.with_source((half_edge.clone(), point.local_form))
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
@ -95,7 +91,7 @@ impl HalfEdgeApprox {
|
||||
}
|
||||
|
||||
fn approx_edge(
|
||||
curve: &Curve,
|
||||
curve: &SurfacePath,
|
||||
surface: &Surface,
|
||||
range: RangeOnPath,
|
||||
tolerance: impl Into<Tolerance>,
|
||||
@ -106,14 +102,14 @@ fn approx_edge(
|
||||
// This will probably all be unified eventually, as `SurfacePath` and
|
||||
// `GlobalPath` grow APIs that are better suited to implementing this code
|
||||
// in a more abstract way.
|
||||
let points = match (curve.path(), surface.geometry().u) {
|
||||
let points = match (curve, surface.geometry().u) {
|
||||
(SurfacePath::Circle(_), GlobalPath::Circle(_)) => {
|
||||
todo!(
|
||||
"Approximating a circle on a curved surface not supported yet."
|
||||
)
|
||||
}
|
||||
(SurfacePath::Circle(_), GlobalPath::Line(_)) => {
|
||||
(curve.path(), range)
|
||||
(curve, range)
|
||||
.approx_with_cache(tolerance, &mut ())
|
||||
.into_iter()
|
||||
.map(|(point_curve, point_surface)| {
|
||||
@ -142,7 +138,7 @@ fn approx_edge(
|
||||
(SurfacePath::Line(line), _) => {
|
||||
let range_u =
|
||||
RangeOnPath::from(range.boundary.map(|point_curve| {
|
||||
[curve.path().point_from_path_coords(point_curve).u]
|
||||
[curve.point_from_path_coords(point_curve).u]
|
||||
}));
|
||||
|
||||
let approx_u = (surface.geometry().u, range_u)
|
||||
@ -151,7 +147,7 @@ fn approx_edge(
|
||||
let mut points = Vec::new();
|
||||
for (u, _) in approx_u {
|
||||
let t = (u.t - line.origin().u) / line.direction().u;
|
||||
let point_surface = curve.path().point_from_path_coords([t]);
|
||||
let point_surface = curve.point_from_path_coords([t]);
|
||||
let point_global =
|
||||
surface.geometry().point_from_surface_coords(point_surface);
|
||||
points.push((u, point_global));
|
||||
@ -323,10 +319,8 @@ mod tests {
|
||||
.approx(tolerance)
|
||||
.into_iter()
|
||||
.map(|(point_local, _)| {
|
||||
let point_surface = half_edge
|
||||
.curve()
|
||||
.path()
|
||||
.point_from_path_coords(point_local);
|
||||
let point_surface =
|
||||
half_edge.curve().point_from_path_coords(point_local);
|
||||
let point_global =
|
||||
surface.geometry().point_from_surface_coords(point_surface);
|
||||
ApproxPoint::new(point_surface, point_global)
|
||||
@ -355,7 +349,7 @@ mod tests {
|
||||
let approx = (&half_edge, surface.deref()).approx(tolerance);
|
||||
|
||||
let expected_approx =
|
||||
(half_edge.curve().path(), RangeOnPath::from([[0.], [TAU]]))
|
||||
(&half_edge.curve(), RangeOnPath::from([[0.], [TAU]]))
|
||||
.approx(tolerance)
|
||||
.into_iter()
|
||||
.map(|(_, point_surface)| {
|
||||
|
@ -19,10 +19,7 @@ use std::{
|
||||
|
||||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
objects::{Curve, HalfEdge},
|
||||
storage::Handle,
|
||||
};
|
||||
use crate::{objects::HalfEdge, storage::Handle};
|
||||
|
||||
pub use self::tolerance::{InvalidTolerance, Tolerance};
|
||||
|
||||
@ -121,5 +118,4 @@ impl<const D: usize> PartialOrd for ApproxPoint<D> {
|
||||
/// The source of an [`ApproxPoint`]
|
||||
pub trait Source: Any + Debug {}
|
||||
|
||||
impl Source for (Handle<Curve>, Point<1>) {}
|
||||
impl Source for (Handle<HalfEdge>, Point<1>) {}
|
||||
|
@ -36,7 +36,7 @@ use crate::geometry::path::{GlobalPath, SurfacePath};
|
||||
|
||||
use super::{Approx, Tolerance};
|
||||
|
||||
impl Approx for (SurfacePath, RangeOnPath) {
|
||||
impl Approx for (&SurfacePath, RangeOnPath) {
|
||||
type Approximation = Vec<(Point<1>, Point<2>)>;
|
||||
type Cache = ();
|
||||
|
||||
@ -49,7 +49,7 @@ impl Approx for (SurfacePath, RangeOnPath) {
|
||||
|
||||
match path {
|
||||
SurfacePath::Circle(circle) => {
|
||||
approx_circle(&circle, range, tolerance.into())
|
||||
approx_circle(circle, range, tolerance.into())
|
||||
}
|
||||
SurfacePath::Line(_) => vec![],
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ impl CurveEdgeIntersection {
|
||||
};
|
||||
|
||||
let edge_as_segment = {
|
||||
let edge_curve_as_line = match half_edge.curve().path() {
|
||||
let edge_curve_as_line = match half_edge.curve() {
|
||||
SurfacePath::Line(line) => line,
|
||||
_ => {
|
||||
todo!("Curve-edge intersection only supports line segments")
|
||||
|
@ -17,7 +17,7 @@ impl Intersect for (&HorizontalRayToTheRight<2>, &Handle<HalfEdge>) {
|
||||
fn intersect(self) -> Option<Self::Intersection> {
|
||||
let (ray, edge) = self;
|
||||
|
||||
let line = match edge.curve().path() {
|
||||
let line = match edge.curve() {
|
||||
SurfacePath::Line(line) => line,
|
||||
SurfacePath::Circle(_) => {
|
||||
todo!("Casting rays against circles is not supported yet")
|
||||
|
@ -18,11 +18,7 @@ impl Reverse for Handle<HalfEdge> {
|
||||
[b, a]
|
||||
};
|
||||
|
||||
HalfEdge::new(
|
||||
self.curve().clone(),
|
||||
vertices,
|
||||
self.global_form().clone(),
|
||||
)
|
||||
HalfEdge::new(self.curve(), vertices, self.global_form().clone())
|
||||
.insert(objects)
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
builder::SurfaceBuilder,
|
||||
geometry::path::{GlobalPath, SurfacePath},
|
||||
insert::Insert,
|
||||
objects::{Curve, Objects, Surface},
|
||||
objects::{Objects, Surface},
|
||||
partial::{PartialObject, PartialSurface},
|
||||
services::Service,
|
||||
storage::Handle,
|
||||
@ -12,7 +12,7 @@ use crate::{
|
||||
|
||||
use super::{Sweep, SweepCache};
|
||||
|
||||
impl Sweep for (Handle<Curve>, &Surface) {
|
||||
impl Sweep for (SurfacePath, &Surface) {
|
||||
type Swept = Handle<Surface>;
|
||||
|
||||
fn sweep_with_cache(
|
||||
@ -47,7 +47,7 @@ impl Sweep for (Handle<Curve>, &Surface) {
|
||||
}
|
||||
}
|
||||
|
||||
let u = match curve.path() {
|
||||
let u = match curve {
|
||||
SurfacePath::Circle(circle) => {
|
||||
let center = surface
|
||||
.geometry()
|
||||
|
@ -35,8 +35,7 @@ impl Sweep for (Handle<HalfEdge>, &Surface, Color) {
|
||||
// we're sweeping.
|
||||
{
|
||||
let surface = Partial::from(
|
||||
(edge.curve().clone(), surface)
|
||||
.sweep_with_cache(path, cache, objects),
|
||||
(edge.curve(), surface).sweep_with_cache(path, cache, objects),
|
||||
);
|
||||
face.surface = surface;
|
||||
}
|
||||
|
@ -109,8 +109,7 @@ impl Sweep for Handle<Face> {
|
||||
.into_iter()
|
||||
.zip(top_cycle.write().half_edges.iter_mut())
|
||||
{
|
||||
top.write().curve.write().path =
|
||||
Some(bottom.curve().path().into());
|
||||
top.write().curve = Some(bottom.curve().into());
|
||||
|
||||
let boundary = bottom.boundary();
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
use fj_math::Transform;
|
||||
|
||||
use crate::{
|
||||
objects::{Curve, Objects},
|
||||
services::Service,
|
||||
};
|
||||
|
||||
use super::{TransformCache, TransformObject};
|
||||
|
||||
impl TransformObject for Curve {
|
||||
fn transform_with_cache(
|
||||
self,
|
||||
_: &Transform,
|
||||
_: &mut Service<Objects>,
|
||||
_: &mut TransformCache,
|
||||
) -> Self {
|
||||
// Don't need to transform path, as that's defined in surface
|
||||
// coordinates, and thus transforming `surface` takes care of it.
|
||||
let path = self.path();
|
||||
|
||||
Self::new(path)
|
||||
}
|
||||
}
|
@ -15,10 +15,9 @@ impl TransformObject for HalfEdge {
|
||||
objects: &mut Service<Objects>,
|
||||
cache: &mut TransformCache,
|
||||
) -> Self {
|
||||
let curve = self
|
||||
.curve()
|
||||
.clone()
|
||||
.transform_with_cache(transform, objects, cache);
|
||||
// Don't need to transform curve, as that's defined in surface
|
||||
// coordinates.
|
||||
let curve = self.curve();
|
||||
let boundary = self.boundary().zip_ext(self.surface_vertices()).map(
|
||||
|(point, surface_vertex)| {
|
||||
let surface_vertex = surface_vertex
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! API for transforming objects
|
||||
|
||||
mod curve;
|
||||
mod cycle;
|
||||
mod edge;
|
||||
mod face;
|
||||
|
@ -1,9 +0,0 @@
|
||||
use crate::partial::PartialCurve;
|
||||
|
||||
/// Builder API for [`PartialCurve`]
|
||||
pub trait CurveBuilder {
|
||||
// No methods are currently defined. This trait serves as a placeholder, to
|
||||
// make it clear where to add such methods, once necessary.
|
||||
}
|
||||
|
||||
impl CurveBuilder for PartialCurve {}
|
@ -76,13 +76,13 @@ pub trait HalfEdgeBuilder {
|
||||
impl HalfEdgeBuilder for PartialHalfEdge {
|
||||
fn update_as_u_axis(&mut self) -> SurfacePath {
|
||||
let path = SurfacePath::u_axis();
|
||||
self.curve.write().path = Some(path.into());
|
||||
self.curve = Some(path.into());
|
||||
path
|
||||
}
|
||||
|
||||
fn update_as_v_axis(&mut self) -> SurfacePath {
|
||||
let path = SurfacePath::v_axis();
|
||||
self.curve.write().path = Some(path.into());
|
||||
self.curve = Some(path.into());
|
||||
path
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
||||
radius: impl Into<Scalar>,
|
||||
) -> SurfacePath {
|
||||
let path = SurfacePath::circle_from_radius(radius);
|
||||
self.curve.write().path = Some(path.into());
|
||||
self.curve = Some(path.into());
|
||||
|
||||
let [a_curve, b_curve] =
|
||||
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));
|
||||
@ -133,7 +133,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
||||
|
||||
let path =
|
||||
SurfacePath::circle_from_center_and_radius(arc.center, arc.radius);
|
||||
self.curve.write().path = Some(path.into());
|
||||
self.curve = Some(path.into());
|
||||
|
||||
let [a_curve, b_curve] =
|
||||
[arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));
|
||||
@ -175,12 +175,12 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
||||
let points = [start, end].zip_ext(points_surface);
|
||||
|
||||
let path = SurfacePath::from_points_with_line_coords(points);
|
||||
self.curve.write().path = Some(path.into());
|
||||
self.curve = Some(path.into());
|
||||
|
||||
path
|
||||
} else {
|
||||
let (path, _) = SurfacePath::line_from_points(points_surface);
|
||||
self.curve.write().path = Some(path.into());
|
||||
self.curve = Some(path.into());
|
||||
|
||||
for (vertex, position) in
|
||||
self.vertices.each_mut_ext().zip_ext([0., 1.])
|
||||
@ -211,8 +211,6 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
||||
) {
|
||||
let path = self
|
||||
.curve
|
||||
.read()
|
||||
.path
|
||||
.expect("Can't infer vertex positions without curve");
|
||||
let MaybeSurfacePath::Defined(path) = path else {
|
||||
panic!("Can't infer vertex positions with undefined path");
|
||||
@ -254,43 +252,41 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
||||
other: &Partial<HalfEdge>,
|
||||
surface: &SurfaceGeometry,
|
||||
) {
|
||||
self.curve.write().path =
|
||||
other.read().curve.read().path.as_ref().and_then(|path| {
|
||||
// We have information about the other edge's surface available.
|
||||
// We need to use that to interpret what the other edge's curve
|
||||
// path means for our curve path.
|
||||
self.curve = other.read().curve.as_ref().and_then(|path| {
|
||||
// We have information about the other edge's surface available. We
|
||||
// need to use that to interpret what the other edge's curve path
|
||||
// means for our curve path.
|
||||
match surface.u {
|
||||
GlobalPath::Circle(circle) => {
|
||||
// The other surface is curved. We're entering some
|
||||
// dodgy territory here, as only some edge cases can be
|
||||
// The other surface is curved. We're entering some dodgy
|
||||
// territory here, as only some edge cases can be
|
||||
// represented using our current curve/surface
|
||||
// representation.
|
||||
match path {
|
||||
MaybeSurfacePath::Defined(SurfacePath::Line(_))
|
||||
| MaybeSurfacePath::UndefinedLine => {
|
||||
// We're dealing with a line on a rounded
|
||||
// surface.
|
||||
// We're dealing with a line on a rounded surface.
|
||||
//
|
||||
// Based on the current uses of this method, we
|
||||
// can make some assumptions:
|
||||
// Based on the current uses of this method, we can
|
||||
// make some assumptions:
|
||||
//
|
||||
// 1. The line is parallel to the u-axis of the
|
||||
// other surface.
|
||||
// 2. The surface that *our* edge is in is a
|
||||
// plane that is parallel to the the plane of
|
||||
// the circle that defines the curvature of
|
||||
// the other surface.
|
||||
// 2. The surface that *our* edge is in is a plane
|
||||
// that is parallel to the the plane of the
|
||||
// circle that defines the curvature of the other
|
||||
// surface.
|
||||
//
|
||||
// These assumptions are necessary preconditions
|
||||
// for the following code to work. But
|
||||
// unfortunately, I see no way to check those
|
||||
// preconditions here, as neither the other line
|
||||
// nor our surface is necessarily defined yet.
|
||||
// These assumptions are necessary preconditions for
|
||||
// the following code to work. But unfortunately, I
|
||||
// see no way to check those preconditions here, as
|
||||
// neither the other line nor our surface is
|
||||
// necessarily defined yet.
|
||||
//
|
||||
// Handling this case anyway feels like a grave
|
||||
// sin, but I don't know what else to do. If you
|
||||
// tracked some extremely subtle and annoying
|
||||
// bug back to this code, I apologize.
|
||||
// Handling this case anyway feels like a grave sin,
|
||||
// but I don't know what else to do. If you tracked
|
||||
// some extremely subtle and annoying bug back to
|
||||
// this code, I apologize.
|
||||
//
|
||||
// I hope that I'll come up with a better curve/
|
||||
// surface representation before this becomes a
|
||||
@ -314,17 +310,15 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
||||
match path {
|
||||
MaybeSurfacePath::Defined(SurfacePath::Line(_))
|
||||
| MaybeSurfacePath::UndefinedLine => {
|
||||
// The other edge is a line segment on a plane.
|
||||
// That means our edge must be a line segment
|
||||
// too.
|
||||
// The other edge is a line segment on a plane. That
|
||||
// means our edge must be a line segment too.
|
||||
Some(MaybeSurfacePath::UndefinedLine)
|
||||
}
|
||||
_ => {
|
||||
// The other edge is a circle or arc on a plane.
|
||||
// I'm actually not sure what that means for our
|
||||
// edge. We might be able to represent it
|
||||
// somehow, but let's leave that as an exercise
|
||||
// for later.
|
||||
// The other edge is a circle or arc on a plane. I'm
|
||||
// actually not sure what that means for our edge.
|
||||
// We might be able to represent it somehow, but
|
||||
// let's leave that as an exercise for later.
|
||||
todo!("Can't connect edge to circle on plane")
|
||||
}
|
||||
}
|
||||
|
@ -96,10 +96,9 @@ impl FaceBuilder for PartialFace {
|
||||
for half_edge in &mut self.exterior.write().half_edges {
|
||||
let mut half_edge = half_edge.write();
|
||||
|
||||
let mut curve = half_edge.curve.clone();
|
||||
let mut curve = curve.write();
|
||||
let mut curve = half_edge.curve;
|
||||
|
||||
if let Some(path) = &mut curve.path {
|
||||
if let Some(path) = &mut curve {
|
||||
match path {
|
||||
MaybeSurfacePath::Defined(_) => {
|
||||
// Path is already defined. Nothing to infer.
|
||||
|
@ -1,7 +1,6 @@
|
||||
//! API for building objects
|
||||
|
||||
// These are new-style builders that build on top of the partial object API.
|
||||
mod curve;
|
||||
mod cycle;
|
||||
mod edge;
|
||||
mod face;
|
||||
@ -14,7 +13,6 @@ mod vertex;
|
||||
use std::array;
|
||||
|
||||
pub use self::{
|
||||
curve::CurveBuilder,
|
||||
cycle::CycleBuilder,
|
||||
edge::{GlobalEdgeBuilder, HalfEdgeBuilder},
|
||||
face::FaceBuilder,
|
||||
|
@ -1,21 +1,6 @@
|
||||
//! Paths through 2D and 3D space
|
||||
//!
|
||||
//! See [`SurfacePath`] and [`GlobalPath`].
|
||||
//!
|
||||
//! # Implementation Note
|
||||
//!
|
||||
//! This is a bit of an in-between module. It is closely associated with
|
||||
//! [`Curve`] and [`Surface`]s, but paths are not really objects themselves, as
|
||||
//! logically speaking, they are owned and not referenced.
|
||||
//!
|
||||
//! On the other hand, the types in this module don't follow the general style
|
||||
//! of types in `fj-math`.
|
||||
//!
|
||||
//! We'll see how it shakes out. Maybe it will stay its own thing, maybe it will
|
||||
//! move to `fj-math`, maybe something else entirely will happen.
|
||||
//!
|
||||
//! [`Curve`]: crate::objects::Curve
|
||||
//! [`Surface`]: crate::objects::Surface
|
||||
|
||||
use fj_math::{Circle, Line, Point, Scalar, Transform, Vector};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use crate::{
|
||||
objects::{
|
||||
Curve, Cycle, Face, GlobalEdge, GlobalVertex, HalfEdge, Objects, Shell,
|
||||
Cycle, Face, GlobalEdge, GlobalVertex, HalfEdge, Objects, Shell,
|
||||
Sketch, Solid, Surface, SurfaceVertex,
|
||||
},
|
||||
services::{Service, ServiceObjectsExt},
|
||||
@ -34,7 +34,6 @@ macro_rules! impl_insert {
|
||||
}
|
||||
|
||||
impl_insert!(
|
||||
Curve, curves;
|
||||
Cycle, cycles;
|
||||
Face, faces;
|
||||
GlobalEdge, global_edges;
|
||||
|
@ -1,19 +0,0 @@
|
||||
use crate::geometry::path::SurfacePath;
|
||||
|
||||
/// A curve, defined in local surface coordinates
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct Curve {
|
||||
path: SurfacePath,
|
||||
}
|
||||
|
||||
impl Curve {
|
||||
/// Construct a new instance of `Curve`
|
||||
pub fn new(path: SurfacePath) -> Self {
|
||||
Self { path }
|
||||
}
|
||||
|
||||
/// Access the path that defines the curve
|
||||
pub fn path(&self) -> SurfacePath {
|
||||
self.path
|
||||
}
|
||||
}
|
@ -55,7 +55,7 @@ impl Cycle {
|
||||
let [a, b] = first.boundary();
|
||||
let edge_direction_positive = a < b;
|
||||
|
||||
let circle = match first.curve().path() {
|
||||
let circle = match first.curve() {
|
||||
SurfacePath::Circle(circle) => circle,
|
||||
SurfacePath::Line(_) => unreachable!(
|
||||
"Invalid cycle: less than 3 edges, but not all are circles"
|
||||
|
@ -2,7 +2,8 @@ use fj_interop::ext::ArrayExt;
|
||||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
objects::{Curve, GlobalVertex, SurfaceVertex},
|
||||
geometry::path::SurfacePath,
|
||||
objects::{GlobalVertex, SurfaceVertex},
|
||||
storage::Handle,
|
||||
};
|
||||
|
||||
@ -44,7 +45,7 @@ use crate::{
|
||||
/// <https://github.com/hannobraun/Fornjot/issues/1608>
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct HalfEdge {
|
||||
curve: Handle<Curve>,
|
||||
curve: SurfacePath,
|
||||
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
|
||||
global_form: Handle<GlobalEdge>,
|
||||
}
|
||||
@ -52,7 +53,7 @@ pub struct HalfEdge {
|
||||
impl HalfEdge {
|
||||
/// Create an instance of `HalfEdge`
|
||||
pub fn new(
|
||||
curve: Handle<Curve>,
|
||||
curve: SurfacePath,
|
||||
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
|
||||
global_form: Handle<GlobalEdge>,
|
||||
) -> Self {
|
||||
@ -64,8 +65,8 @@ impl HalfEdge {
|
||||
}
|
||||
|
||||
/// Access the curve that defines the half-edge's geometry
|
||||
pub fn curve(&self) -> &Handle<Curve> {
|
||||
&self.curve
|
||||
pub fn curve(&self) -> SurfacePath {
|
||||
self.curve
|
||||
}
|
||||
|
||||
/// Access the boundary points of the half-edge on the curve
|
||||
|
@ -1,4 +1,3 @@
|
||||
pub mod curve;
|
||||
pub mod cycle;
|
||||
pub mod edge;
|
||||
pub mod face;
|
||||
|
@ -79,7 +79,6 @@ mod stores;
|
||||
|
||||
pub use self::{
|
||||
full::{
|
||||
curve::Curve,
|
||||
cycle::{Cycle, HalfEdgesOfCycle},
|
||||
edge::{GlobalEdge, HalfEdge, VerticesInNormalizedOrder},
|
||||
face::{Face, FaceSet, Handedness},
|
||||
|
@ -2,7 +2,7 @@ use std::any::Any;
|
||||
|
||||
use crate::{
|
||||
objects::{
|
||||
Curve, Cycle, Face, GlobalEdge, GlobalVertex, HalfEdge, Objects, Shell,
|
||||
Cycle, Face, GlobalEdge, GlobalVertex, HalfEdge, Objects, Shell,
|
||||
Sketch, Solid, Surface, SurfaceVertex,
|
||||
},
|
||||
storage::{Handle, ObjectId},
|
||||
@ -108,7 +108,6 @@ macro_rules! object {
|
||||
}
|
||||
|
||||
object!(
|
||||
Curve, "curve", curves;
|
||||
Cycle, "cycle", cycles;
|
||||
Face, "face", faces;
|
||||
GlobalEdge, "global edge", global_edges;
|
||||
|
@ -6,16 +6,13 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
Curve, Cycle, Face, GlobalEdge, GlobalVertex, HalfEdge, Shell, Sketch,
|
||||
Solid, Surface, SurfaceVertex,
|
||||
Cycle, Face, GlobalEdge, GlobalVertex, HalfEdge, Shell, Sketch, Solid,
|
||||
Surface, SurfaceVertex,
|
||||
};
|
||||
|
||||
/// The available object stores
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Objects {
|
||||
/// Store for [`Curve`]s
|
||||
pub curves: Store<Curve>,
|
||||
|
||||
/// Store for [`Cycle`]s
|
||||
pub cycles: Store<Cycle>,
|
||||
|
||||
|
@ -16,7 +16,7 @@ mod wrapper;
|
||||
|
||||
pub use self::{
|
||||
objects::{
|
||||
curve::{MaybeSurfacePath, PartialCurve},
|
||||
curve::MaybeSurfacePath,
|
||||
cycle::PartialCycle,
|
||||
edge::{PartialGlobalEdge, PartialHalfEdge},
|
||||
face::PartialFace,
|
||||
|
@ -1,43 +1,8 @@
|
||||
use fj_math::Scalar;
|
||||
|
||||
use crate::{
|
||||
geometry::path::SurfacePath,
|
||||
objects::{Curve, Objects},
|
||||
partial::{FullToPartialCache, PartialObject},
|
||||
services::Service,
|
||||
};
|
||||
use crate::geometry::path::SurfacePath;
|
||||
|
||||
/// A partial [`Curve`]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PartialCurve {
|
||||
/// The path that defines the curve
|
||||
pub path: Option<MaybeSurfacePath>,
|
||||
}
|
||||
|
||||
impl PartialObject for PartialCurve {
|
||||
type Full = Curve;
|
||||
|
||||
fn from_full(curve: &Self::Full, _: &mut FullToPartialCache) -> Self {
|
||||
Self {
|
||||
path: Some(curve.path().into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn build(self, _: &mut Service<Objects>) -> Self::Full {
|
||||
let path = match self.path.expect("Need path to build curve") {
|
||||
MaybeSurfacePath::Defined(path) => path,
|
||||
undefined => {
|
||||
panic!(
|
||||
"Trying to build curve with undefined path: {undefined:?}"
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Curve::new(path)
|
||||
}
|
||||
}
|
||||
|
||||
/// The definition of a surface path within [`PartialCurve`]
|
||||
/// The definition of a surface path within a partial object
|
||||
///
|
||||
/// Can be a fully defined [`SurfacePath`], or just the type of path might be
|
||||
/// known.
|
||||
|
@ -4,10 +4,8 @@ use fj_interop::ext::ArrayExt;
|
||||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
objects::{
|
||||
Curve, GlobalEdge, GlobalVertex, HalfEdge, Objects, SurfaceVertex,
|
||||
},
|
||||
partial::{FullToPartialCache, Partial, PartialObject},
|
||||
objects::{GlobalEdge, GlobalVertex, HalfEdge, Objects, SurfaceVertex},
|
||||
partial::{FullToPartialCache, MaybeSurfacePath, Partial, PartialObject},
|
||||
services::Service,
|
||||
};
|
||||
|
||||
@ -15,7 +13,7 @@ use crate::{
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PartialHalfEdge {
|
||||
/// The curve that the half-edge is defined in
|
||||
pub curve: Partial<Curve>,
|
||||
pub curve: Option<MaybeSurfacePath>,
|
||||
|
||||
/// The vertices that bound the half-edge on the curve
|
||||
pub vertices: [(Option<Point<1>>, Partial<SurfaceVertex>); 2],
|
||||
@ -32,7 +30,7 @@ impl PartialObject for PartialHalfEdge {
|
||||
cache: &mut FullToPartialCache,
|
||||
) -> Self {
|
||||
Self {
|
||||
curve: Partial::from_full(half_edge.curve().clone(), cache),
|
||||
curve: Some(half_edge.curve().into()),
|
||||
vertices: half_edge
|
||||
.boundary()
|
||||
.zip_ext(half_edge.surface_vertices())
|
||||
@ -50,7 +48,14 @@ impl PartialObject for PartialHalfEdge {
|
||||
}
|
||||
|
||||
fn build(self, objects: &mut Service<Objects>) -> Self::Full {
|
||||
let curve = self.curve.build(objects);
|
||||
let curve = match self.curve.expect("Need path to build curve") {
|
||||
MaybeSurfacePath::Defined(path) => path,
|
||||
undefined => {
|
||||
panic!(
|
||||
"Trying to build curve with undefined path: {undefined:?}"
|
||||
)
|
||||
}
|
||||
};
|
||||
let vertices = self.vertices.map(|vertex| {
|
||||
let position_curve = vertex
|
||||
.0
|
||||
@ -67,7 +72,7 @@ impl PartialObject for PartialHalfEdge {
|
||||
|
||||
impl Default for PartialHalfEdge {
|
||||
fn default() -> Self {
|
||||
let curve = Partial::<Curve>::new();
|
||||
let curve = None;
|
||||
let vertices = array::from_fn(|_| {
|
||||
let surface_form = Partial::default();
|
||||
(None, surface_form)
|
||||
|
@ -33,7 +33,6 @@ macro_rules! impl_trait {
|
||||
}
|
||||
|
||||
impl_trait!(
|
||||
Curve, PartialCurve;
|
||||
Cycle, PartialCycle;
|
||||
Face, PartialFace;
|
||||
GlobalEdge, PartialGlobalEdge;
|
||||
|
@ -1,12 +0,0 @@
|
||||
use crate::objects::Curve;
|
||||
|
||||
use super::{Validate, ValidationConfig, ValidationError};
|
||||
|
||||
impl Validate for Curve {
|
||||
fn validate_with_config(
|
||||
&self,
|
||||
_: &ValidationConfig,
|
||||
_: &mut Vec<ValidationError>,
|
||||
) {
|
||||
}
|
||||
}
|
@ -101,10 +101,8 @@ impl CycleValidationError {
|
||||
.boundary()
|
||||
.zip_ext([half_edge.start_vertex(), next.start_vertex()]);
|
||||
for (position_on_curve, surface_vertex) in boundary_and_vertices {
|
||||
let curve_position_on_surface = half_edge
|
||||
.curve()
|
||||
.path()
|
||||
.point_from_path_coords(position_on_curve);
|
||||
let curve_position_on_surface =
|
||||
half_edge.curve().point_from_path_coords(position_on_curve);
|
||||
let surface_position_from_vertex = surface_vertex.position();
|
||||
|
||||
let distance = curve_position_on_surface
|
||||
|
@ -184,7 +184,7 @@ mod tests {
|
||||
.boundary()
|
||||
.zip_ext(valid.surface_vertices().map(Clone::clone));
|
||||
|
||||
HalfEdge::new(valid.curve().clone(), vertices, global_form)
|
||||
HalfEdge::new(valid.curve(), vertices, global_form)
|
||||
};
|
||||
|
||||
valid.validate_and_return_first_error()?;
|
||||
@ -211,11 +211,7 @@ mod tests {
|
||||
(Point::from([0.]), surface_vertex.clone())
|
||||
});
|
||||
|
||||
HalfEdge::new(
|
||||
valid.curve().clone(),
|
||||
vertices,
|
||||
valid.global_form().clone(),
|
||||
)
|
||||
HalfEdge::new(valid.curve(), vertices, valid.global_form().clone())
|
||||
};
|
||||
|
||||
valid.validate_and_return_first_error()?;
|
||||
|
@ -291,7 +291,7 @@ mod tests {
|
||||
let boundary = boundary.zip_ext(surface_vertices);
|
||||
|
||||
HalfEdge::new(
|
||||
half_edge.curve().clone(),
|
||||
half_edge.curve(),
|
||||
boundary,
|
||||
half_edge.global_form().clone(),
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! Infrastructure for validating objects
|
||||
|
||||
mod curve;
|
||||
mod cycle;
|
||||
mod edge;
|
||||
mod face;
|
||||
|
Loading…
Reference in New Issue
Block a user