mirror of https://github.com/hannobraun/Fornjot
Merge pull request #1305 from hannobraun/partial
Start extracting new builder API from partial object API
This commit is contained in:
commit
412f1b26f0
|
@ -197,6 +197,7 @@ mod tests {
|
|||
|
||||
use crate::{
|
||||
algorithms::approx::{path::RangeOnPath, Approx, ApproxPoint},
|
||||
builder::CurveBuilder,
|
||||
objects::{Curve, Objects, Surface},
|
||||
partial::HasPartial,
|
||||
path::GlobalPath,
|
||||
|
@ -213,7 +214,7 @@ mod tests {
|
|||
.insert(Surface::new(GlobalPath::x_axis(), [0., 0., 1.]))?;
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface))
|
||||
.as_line_from_points([[1., 1.], [2., 1.]])
|
||||
.update_as_line_from_points([[1., 1.], [2., 1.]])
|
||||
.build(&objects)?;
|
||||
let range = RangeOnPath::from([[0.], [1.]]);
|
||||
|
||||
|
@ -234,7 +235,7 @@ mod tests {
|
|||
))?;
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface))
|
||||
.as_line_from_points([[1., 1.], [1., 2.]])
|
||||
.update_as_line_from_points([[1., 1.], [1., 2.]])
|
||||
.build(&objects)?;
|
||||
let range = RangeOnPath::from([[0.], [1.]]);
|
||||
|
||||
|
@ -253,7 +254,7 @@ mod tests {
|
|||
objects.surfaces.insert(Surface::new(path, [0., 0., 1.]))?;
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_line_from_points([[0., 1.], [1., 1.]])
|
||||
.update_as_line_from_points([[0., 1.], [1., 1.]])
|
||||
.build(&objects)?;
|
||||
|
||||
let range = RangeOnPath::from([[0.], [TAU]]);
|
||||
|
@ -285,7 +286,7 @@ mod tests {
|
|||
.insert(Surface::new(GlobalPath::x_axis(), [0., 0., 1.]))?;
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface))
|
||||
.as_circle_from_radius(1.)
|
||||
.update_as_circle_from_radius(1.)
|
||||
.build(&objects)?;
|
||||
|
||||
let range = RangeOnPath::from([[0.], [TAU]]);
|
||||
|
|
|
@ -75,6 +75,7 @@ mod tests {
|
|||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
builder::CurveBuilder,
|
||||
objects::{Curve, HalfEdge, Objects},
|
||||
partial::HasPartial,
|
||||
};
|
||||
|
@ -88,7 +89,7 @@ mod tests {
|
|||
let surface = objects.surfaces.xy_plane();
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
let half_edge = HalfEdge::partial()
|
||||
.with_surface(Some(surface))
|
||||
|
@ -113,7 +114,7 @@ mod tests {
|
|||
let surface = objects.surfaces.xy_plane();
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
let half_edge = HalfEdge::partial()
|
||||
.with_surface(Some(surface))
|
||||
|
@ -138,7 +139,7 @@ mod tests {
|
|||
let surface = objects.surfaces.xy_plane();
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
let half_edge = HalfEdge::partial()
|
||||
.with_surface(Some(surface))
|
||||
|
@ -158,7 +159,7 @@ mod tests {
|
|||
let surface = objects.surfaces.xy_plane();
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
let half_edge = HalfEdge::partial()
|
||||
.with_surface(Some(surface))
|
||||
|
|
|
@ -150,6 +150,7 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
builder::CurveBuilder,
|
||||
objects::{Curve, Face, Objects},
|
||||
partial::HasPartial,
|
||||
};
|
||||
|
@ -164,7 +165,7 @@ mod tests {
|
|||
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_line_from_points([[-3., 0.], [-2., 0.]])
|
||||
.update_as_line_from_points([[-3., 0.], [-2., 0.]])
|
||||
.build(&objects)?;
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
|
|
@ -67,6 +67,7 @@ mod tests {
|
|||
|
||||
use crate::{
|
||||
algorithms::intersect::CurveFaceIntersection,
|
||||
builder::CurveBuilder,
|
||||
objects::{Curve, Face, Objects},
|
||||
partial::HasPartial,
|
||||
};
|
||||
|
@ -124,7 +125,7 @@ mod tests {
|
|||
let expected_curves = surfaces.try_map_ext(|surface| {
|
||||
Curve::partial()
|
||||
.with_surface(Some(surface))
|
||||
.as_line_from_points([[0., 0.], [1., 0.]])
|
||||
.update_as_line_from_points([[0., 0.], [1., 0.]])
|
||||
.build(&objects)
|
||||
})?;
|
||||
let expected_intervals =
|
||||
|
|
|
@ -92,6 +92,7 @@ mod tests {
|
|||
|
||||
use crate::{
|
||||
algorithms::transform::TransformObject,
|
||||
builder::CurveBuilder,
|
||||
objects::{Curve, Objects},
|
||||
partial::HasPartial,
|
||||
};
|
||||
|
@ -122,11 +123,11 @@ mod tests {
|
|||
|
||||
let expected_xy = Curve::partial()
|
||||
.with_surface(Some(xy.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
let expected_xz = Curve::partial()
|
||||
.with_surface(Some(xz.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
|
||||
assert_eq!(
|
||||
|
|
|
@ -168,6 +168,7 @@ mod tests {
|
|||
|
||||
use crate::{
|
||||
algorithms::sweep::Sweep,
|
||||
builder::CurveBuilder,
|
||||
objects::{Curve, HalfEdge, Objects, Vertex},
|
||||
partial::HasPartial,
|
||||
};
|
||||
|
@ -179,7 +180,7 @@ mod tests {
|
|||
let surface = objects.surfaces.xz_plane();
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
let vertex = Vertex::partial()
|
||||
.with_position(Some([0.]))
|
||||
|
|
|
@ -1,29 +1,24 @@
|
|||
use fj_math::Transform;
|
||||
|
||||
use crate::{
|
||||
objects::{GlobalCurve, Objects},
|
||||
partial::PartialCurve,
|
||||
storage::Handle,
|
||||
objects::Objects,
|
||||
partial::{PartialCurve, PartialGlobalCurve},
|
||||
validate::ValidationError,
|
||||
};
|
||||
|
||||
use super::TransformObject;
|
||||
|
||||
impl TransformObject for Handle<GlobalCurve> {
|
||||
impl TransformObject for PartialGlobalCurve {
|
||||
fn transform(
|
||||
self,
|
||||
_: &Transform,
|
||||
objects: &Objects,
|
||||
_: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
// `GlobalCurve` doesn't contain any internal geometry. If it did, that
|
||||
// would just be redundant with the geometry of other objects, and this
|
||||
// other geometry is already being transformed by other implementations
|
||||
// of this trait.
|
||||
//
|
||||
// All we need to do here is create a new `GlobalCurve` instance, to
|
||||
// make sure the transformed `GlobalCurve` has a different identity than
|
||||
// the original one.
|
||||
Ok(objects.global_curves.insert(GlobalCurve)?)
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,20 +29,19 @@ impl TransformObject for PartialCurve {
|
|||
objects: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let surface = self
|
||||
.surface
|
||||
.surface()
|
||||
.map(|surface| surface.transform(transform, objects))
|
||||
.transpose()?;
|
||||
let global_form = self
|
||||
.global_form
|
||||
.map(|global_form| global_form.0.transform(transform, objects))
|
||||
.global_form()
|
||||
.map(|global_form| global_form.transform(transform, objects))
|
||||
.transpose()?;
|
||||
|
||||
// Don't need to transform `self.path`, as that's defined in surface
|
||||
// coordinates, and thus transforming `surface` takes care of it.
|
||||
Ok(Self {
|
||||
surface,
|
||||
path: self.path,
|
||||
global_form: global_form.map(Into::into),
|
||||
})
|
||||
Ok(Self::default()
|
||||
.with_surface(surface)
|
||||
.with_path(self.path())
|
||||
.with_global_form(global_form))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,10 +57,7 @@ impl TransformObject for PartialGlobalEdge {
|
|||
transform: &Transform,
|
||||
objects: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let curve = self
|
||||
.curve
|
||||
.map(|curve| curve.0.transform(transform, objects))
|
||||
.transpose()?;
|
||||
let curve = self.curve.transform(transform, objects)?;
|
||||
let vertices = self
|
||||
.vertices
|
||||
.map(|vertices| {
|
||||
|
@ -70,9 +67,6 @@ impl TransformObject for PartialGlobalEdge {
|
|||
})
|
||||
.transpose()?;
|
||||
|
||||
Ok(Self {
|
||||
curve: curve.map(Into::into),
|
||||
vertices,
|
||||
})
|
||||
Ok(Self { curve, vertices })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,20 +14,19 @@ impl TransformObject for PartialVertex {
|
|||
transform: &Transform,
|
||||
objects: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let curve = self.curve.transform(transform, objects)?;
|
||||
let curve = self.curve().transform(transform, objects)?;
|
||||
let surface_form = self
|
||||
.surface_form
|
||||
.surface_form()
|
||||
.into_partial()
|
||||
.transform(transform, objects)?
|
||||
.into();
|
||||
|
||||
// Don't need to transform `self.position`, as that is in curve
|
||||
// coordinates and thus transforming the curve takes care of it.
|
||||
Ok(Self {
|
||||
position: self.position,
|
||||
curve,
|
||||
surface_form,
|
||||
})
|
||||
Ok(Self::default()
|
||||
.with_position(self.position())
|
||||
.with_curve(Some(curve))
|
||||
.with_surface_form(surface_form))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,18 +37,17 @@ impl TransformObject for PartialSurfaceVertex {
|
|||
objects: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let surface = self
|
||||
.surface
|
||||
.surface()
|
||||
.map(|surface| surface.transform(transform, objects))
|
||||
.transpose()?;
|
||||
let global_form = self.global_form.transform(transform, objects)?;
|
||||
let global_form = self.global_form().transform(transform, objects)?;
|
||||
|
||||
// Don't need to transform `self.position`, as that is in surface
|
||||
// coordinates and thus transforming the surface takes care of it.
|
||||
Ok(Self {
|
||||
position: self.position,
|
||||
surface,
|
||||
global_form,
|
||||
})
|
||||
Ok(Self::default()
|
||||
.with_position(self.position())
|
||||
.with_surface(surface)
|
||||
.with_global_form(Some(global_form)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,9 +58,9 @@ impl TransformObject for PartialGlobalVertex {
|
|||
_: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let position = self
|
||||
.position
|
||||
.position()
|
||||
.map(|position| transform.transform_point(&position));
|
||||
|
||||
Ok(Self { position })
|
||||
Ok(Self::default().with_position(position))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
use fj_math::{Point, Scalar, Vector};
|
||||
|
||||
use crate::{partial::PartialCurve, path::SurfacePath};
|
||||
|
||||
/// Builder API for [`PartialCurve`]
|
||||
pub trait CurveBuilder {
|
||||
/// Update partial curve to represent the u-axis
|
||||
fn update_as_u_axis(self) -> Self;
|
||||
|
||||
/// Update partial curve to represent the v-axis
|
||||
fn update_as_v_axis(self) -> Self;
|
||||
|
||||
/// Update partial curve as a circle, from the provided radius
|
||||
fn update_as_circle_from_radius(self, radius: impl Into<Scalar>) -> Self;
|
||||
|
||||
/// Update partial curve as a line, from the provided points
|
||||
fn update_as_line_from_points(
|
||||
self,
|
||||
points: [impl Into<Point<2>>; 2],
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
impl CurveBuilder for PartialCurve {
|
||||
fn update_as_u_axis(self) -> Self {
|
||||
let a = Point::origin();
|
||||
let b = a + Vector::unit_u();
|
||||
|
||||
self.update_as_line_from_points([a, b])
|
||||
}
|
||||
|
||||
fn update_as_v_axis(self) -> Self {
|
||||
let a = Point::origin();
|
||||
let b = a + Vector::unit_v();
|
||||
|
||||
self.update_as_line_from_points([a, b])
|
||||
}
|
||||
|
||||
fn update_as_circle_from_radius(self, radius: impl Into<Scalar>) -> Self {
|
||||
self.with_path(Some(SurfacePath::circle_from_radius(radius)))
|
||||
}
|
||||
|
||||
fn update_as_line_from_points(
|
||||
self,
|
||||
points: [impl Into<Point<2>>; 2],
|
||||
) -> Self {
|
||||
self.with_path(Some(SurfacePath::line_from_points(points)))
|
||||
}
|
||||
}
|
|
@ -1,11 +1,22 @@
|
|||
//! API for building objects
|
||||
|
||||
// These are the old-style builders that need to be transferred to the partial
|
||||
// object API. Issue:
|
||||
// https://github.com/hannobraun/Fornjot/issues/1147
|
||||
mod face;
|
||||
mod shell;
|
||||
mod sketch;
|
||||
mod solid;
|
||||
|
||||
// These are new-style builders that build on top of the partial object API.
|
||||
mod curve;
|
||||
mod vertex;
|
||||
|
||||
pub use self::{
|
||||
face::FaceBuilder, shell::ShellBuilder, sketch::SketchBuilder,
|
||||
curve::CurveBuilder,
|
||||
face::FaceBuilder,
|
||||
shell::ShellBuilder,
|
||||
sketch::SketchBuilder,
|
||||
solid::SolidBuilder,
|
||||
vertex::{GlobalVertexBuilder, SurfaceVertexBuilder, VertexBuilder},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
objects::{Curve, GlobalVertex, Surface},
|
||||
partial::{
|
||||
HasPartial, MaybePartial, PartialGlobalVertex, PartialSurfaceVertex,
|
||||
PartialVertex,
|
||||
},
|
||||
};
|
||||
|
||||
/// Builder API for [`PartialVertex`]
|
||||
pub trait VertexBuilder {
|
||||
/// Remove the surface form of the partial vertex, inferring it on build
|
||||
fn infer_surface_form(self) -> Self;
|
||||
}
|
||||
|
||||
impl VertexBuilder for PartialVertex {
|
||||
fn infer_surface_form(self) -> Self {
|
||||
self.with_surface_form(Some(PartialSurfaceVertex::default()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder API for [`PartialSurfaceVertex`]
|
||||
pub trait SurfaceVertexBuilder {
|
||||
/// Infer the global form of the partial vertex
|
||||
fn infer_global_form(self) -> Self;
|
||||
}
|
||||
|
||||
impl SurfaceVertexBuilder for PartialSurfaceVertex {
|
||||
fn infer_global_form(self) -> Self {
|
||||
self.with_global_form(Some(GlobalVertex::partial()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder API for [`PartialGlobalVertex`]
|
||||
pub trait GlobalVertexBuilder {
|
||||
/// Update partial global vertex from the given curve and position on it
|
||||
fn update_from_curve_and_position(
|
||||
self,
|
||||
curve: impl Into<MaybePartial<Curve>>,
|
||||
position: impl Into<Point<1>>,
|
||||
) -> Self;
|
||||
|
||||
/// Update partial global vertex from the given surface and position on it
|
||||
fn update_from_surface_and_position(
|
||||
self,
|
||||
surface: &Surface,
|
||||
position: impl Into<Point<2>>,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
impl GlobalVertexBuilder for PartialGlobalVertex {
|
||||
fn update_from_curve_and_position(
|
||||
self,
|
||||
curve: impl Into<MaybePartial<Curve>>,
|
||||
position: impl Into<Point<1>>,
|
||||
) -> Self {
|
||||
let curve = curve.into().into_partial();
|
||||
|
||||
let path = curve.path().expect(
|
||||
"Need path to create `GlobalVertex` from curve and position",
|
||||
);
|
||||
let surface = curve.surface().expect(
|
||||
"Need surface to create `GlobalVertex` from curve and position",
|
||||
);
|
||||
|
||||
let position_surface = path.point_from_path_coords(position);
|
||||
self.update_from_surface_and_position(&surface, position_surface)
|
||||
}
|
||||
|
||||
fn update_from_surface_and_position(
|
||||
self,
|
||||
surface: &Surface,
|
||||
position: impl Into<Point<2>>,
|
||||
) -> Self {
|
||||
self.with_position(Some(surface.point_from_surface_coords(position)))
|
||||
}
|
||||
}
|
|
@ -360,6 +360,7 @@ impl<T> Iterator for Iter<T> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
builder::CurveBuilder,
|
||||
objects::{
|
||||
Curve, Cycle, Face, GlobalCurve, GlobalVertex, HalfEdge, Objects,
|
||||
Shell, Sketch, Solid, SurfaceVertex, Vertex,
|
||||
|
@ -376,7 +377,7 @@ mod tests {
|
|||
let surface = objects.surfaces.xy_plane();
|
||||
let object = Curve::partial()
|
||||
.with_surface(Some(surface))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects);
|
||||
|
||||
assert_eq!(1, object.curve_iter().count());
|
||||
|
@ -593,7 +594,7 @@ mod tests {
|
|||
let surface = objects.surfaces.xy_plane();
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_u_axis()
|
||||
.update_as_u_axis()
|
||||
.build(&objects)?;
|
||||
let global_vertex = objects
|
||||
.global_vertices
|
||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
|||
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
|
||||
Surface, SurfaceVertex, Vertex,
|
||||
},
|
||||
path::SurfacePath,
|
||||
storage::Handle,
|
||||
validate::ValidationError,
|
||||
};
|
||||
|
@ -30,6 +31,24 @@ pub enum MaybePartial<T: HasPartial> {
|
|||
}
|
||||
|
||||
impl<T: HasPartial> MaybePartial<T> {
|
||||
/// Indicate whether this is a full object
|
||||
pub fn is_full(&self) -> bool {
|
||||
if let Self::Full(_) = self {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Indicate whether this is a partial object
|
||||
pub fn is_partial(&self) -> bool {
|
||||
if let Self::Partial(_) = self {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// If this is a partial object, update it
|
||||
///
|
||||
/// This is useful whenever a partial object can infer something about its
|
||||
|
@ -95,25 +114,37 @@ where
|
|||
// `MaybePartial<T>`, as that would conflict.
|
||||
|
||||
impl MaybePartial<Curve> {
|
||||
/// Access the global form
|
||||
pub fn global_form(&self) -> Option<Handle<GlobalCurve>> {
|
||||
/// Access the path
|
||||
pub fn path(&self) -> Option<SurfacePath> {
|
||||
match self {
|
||||
Self::Full(full) => Some(full.global_form().clone()),
|
||||
Self::Partial(partial) => {
|
||||
partial.global_form.clone().map(Into::into)
|
||||
MaybePartial::Full(full) => Some(full.path()),
|
||||
MaybePartial::Partial(partial) => partial.path(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the surface
|
||||
pub fn surface(&self) -> Option<Handle<Surface>> {
|
||||
match self {
|
||||
MaybePartial::Full(full) => Some(full.surface().clone()),
|
||||
MaybePartial::Partial(partial) => partial.surface(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the global form
|
||||
pub fn global_form(&self) -> Option<MaybePartial<GlobalCurve>> {
|
||||
match self {
|
||||
Self::Full(full) => Some(full.global_form().clone().into()),
|
||||
Self::Partial(partial) => partial.global_form(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MaybePartial<GlobalEdge> {
|
||||
/// Access the curve
|
||||
pub fn curve(&self) -> Option<&Handle<GlobalCurve>> {
|
||||
pub fn curve(&self) -> MaybePartial<GlobalCurve> {
|
||||
match self {
|
||||
Self::Full(full) => Some(full.curve()),
|
||||
Self::Partial(partial) => {
|
||||
partial.curve.as_ref().map(|wrapper| &wrapper.0)
|
||||
}
|
||||
Self::Full(full) => full.curve().clone().into(),
|
||||
Self::Partial(partial) => partial.curve.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,15 +185,15 @@ impl MaybePartial<SurfaceVertex> {
|
|||
pub fn position(&self) -> Option<Point<2>> {
|
||||
match self {
|
||||
Self::Full(full) => Some(full.position()),
|
||||
Self::Partial(partial) => partial.position,
|
||||
Self::Partial(partial) => partial.position(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the surface
|
||||
pub fn surface(&self) -> Option<&Handle<Surface>> {
|
||||
pub fn surface(&self) -> Option<Handle<Surface>> {
|
||||
match self {
|
||||
Self::Full(full) => Some(full.surface()),
|
||||
Self::Partial(partial) => partial.surface.as_ref(),
|
||||
Self::Full(full) => Some(full.surface().clone()),
|
||||
Self::Partial(partial) => partial.surface(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +203,7 @@ impl MaybePartial<Vertex> {
|
|||
pub fn surface_form(&self) -> MaybePartial<SurfaceVertex> {
|
||||
match self {
|
||||
Self::Full(full) => full.surface_form().clone().into(),
|
||||
Self::Partial(partial) => partial.surface_form.clone(),
|
||||
Self::Partial(partial) => partial.surface_form(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ mod traits;
|
|||
pub use self::{
|
||||
maybe_partial::MaybePartial,
|
||||
objects::{
|
||||
curve::PartialCurve,
|
||||
curve::{PartialCurve, PartialGlobalCurve},
|
||||
cycle::PartialCycle,
|
||||
edge::{PartialGlobalEdge, PartialHalfEdge},
|
||||
vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex},
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
use fj_math::{Point, Scalar, Vector};
|
||||
|
||||
use crate::{
|
||||
objects::{Curve, GlobalCurve, Objects, Surface},
|
||||
partial::MaybePartial,
|
||||
path::SurfacePath,
|
||||
storage::{Handle, HandleWrapper},
|
||||
storage::Handle,
|
||||
validate::ValidationError,
|
||||
};
|
||||
|
||||
/// A partial [`Curve`]
|
||||
///
|
||||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PartialCurve {
|
||||
/// The path that defines the [`Curve`]
|
||||
///
|
||||
/// Must be provided before calling [`PartialCurve::build`].
|
||||
pub path: Option<SurfacePath>,
|
||||
|
||||
/// The surface that the [`Curve`] is defined in
|
||||
///
|
||||
/// Must be provided before calling [`PartialCurve::build`].
|
||||
pub surface: Option<Handle<Surface>>,
|
||||
|
||||
/// The global form of the [`Curve`]
|
||||
///
|
||||
/// Will be computed from `path` and `surface` in [`PartialCurve::build`],
|
||||
/// if not provided.
|
||||
pub global_form: Option<HandleWrapper<GlobalCurve>>,
|
||||
path: Option<SurfacePath>,
|
||||
surface: Option<Handle<Surface>>,
|
||||
global_form: Option<MaybePartial<GlobalCurve>>,
|
||||
}
|
||||
|
||||
impl PartialCurve {
|
||||
/// Access the path that defines the [`Curve`]
|
||||
pub fn path(&self) -> Option<SurfacePath> {
|
||||
self.path
|
||||
}
|
||||
|
||||
/// Access the surface that the [`Curve`] is defined in
|
||||
pub fn surface(&self) -> Option<Handle<Surface>> {
|
||||
self.surface.clone()
|
||||
}
|
||||
|
||||
/// Access the global form of the [`Curve`]
|
||||
pub fn global_form(&self) -> Option<MaybePartial<GlobalCurve>> {
|
||||
self.global_form.clone()
|
||||
}
|
||||
|
||||
/// Provide a path for the partial curve
|
||||
pub fn with_path(mut self, path: Option<SurfacePath>) -> Self {
|
||||
if let Some(path) = path {
|
||||
|
@ -49,7 +51,7 @@ impl PartialCurve {
|
|||
/// Provide a global form for the partial curve
|
||||
pub fn with_global_form(
|
||||
mut self,
|
||||
global_form: Option<impl Into<HandleWrapper<GlobalCurve>>>,
|
||||
global_form: Option<impl Into<MaybePartial<GlobalCurve>>>,
|
||||
) -> Self {
|
||||
if let Some(global_form) = global_form {
|
||||
self.global_form = Some(global_form.into());
|
||||
|
@ -57,32 +59,6 @@ impl PartialCurve {
|
|||
self
|
||||
}
|
||||
|
||||
/// Update partial curve to represent the u-axis
|
||||
pub fn as_u_axis(self) -> Self {
|
||||
let a = Point::origin();
|
||||
let b = a + Vector::unit_u();
|
||||
|
||||
self.as_line_from_points([a, b])
|
||||
}
|
||||
|
||||
/// Update partial curve to represent the v-axis
|
||||
pub fn as_v_axis(self) -> Self {
|
||||
let a = Point::origin();
|
||||
let b = a + Vector::unit_v();
|
||||
|
||||
self.as_line_from_points([a, b])
|
||||
}
|
||||
|
||||
/// Update partial curve as a circle, from the provided radius
|
||||
pub fn as_circle_from_radius(self, radius: impl Into<Scalar>) -> Self {
|
||||
self.with_path(Some(SurfacePath::circle_from_radius(radius)))
|
||||
}
|
||||
|
||||
/// Update partial curve as a line, from the provided points
|
||||
pub fn as_line_from_points(self, points: [impl Into<Point<2>>; 2]) -> Self {
|
||||
self.with_path(Some(SurfacePath::line_from_points(points)))
|
||||
}
|
||||
|
||||
/// Build a full [`Curve`] from the partial curve
|
||||
pub fn build(
|
||||
self,
|
||||
|
@ -95,7 +71,8 @@ impl PartialCurve {
|
|||
let global_form = match self.global_form {
|
||||
Some(global_form) => global_form,
|
||||
None => objects.global_curves.insert(GlobalCurve)?.into(),
|
||||
};
|
||||
}
|
||||
.into_full(objects)?;
|
||||
|
||||
Ok(objects
|
||||
.curves
|
||||
|
@ -112,3 +89,31 @@ impl From<&Curve> for PartialCurve {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A partial [`GlobalCurve`]
|
||||
///
|
||||
/// This struct might seem unnecessary. [`GlobalCurve`] literally has nothing in
|
||||
/// it. Why would we need to represent a part of nothing? However, having this
|
||||
/// provides some regularity that helps simplify some things within the partial
|
||||
/// object and builder APIs.
|
||||
///
|
||||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct PartialGlobalCurve;
|
||||
|
||||
impl PartialGlobalCurve {
|
||||
/// Build a full [`GlobalCurve`] from the partial global curve
|
||||
pub fn build(
|
||||
self,
|
||||
objects: &Objects,
|
||||
) -> Result<Handle<GlobalCurve>, ValidationError> {
|
||||
let global_curve = objects.global_curves.insert(GlobalCurve)?;
|
||||
Ok(global_curve)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&GlobalCurve> for PartialGlobalCurve {
|
||||
fn from(_: &GlobalCurve) -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
builder::CurveBuilder,
|
||||
objects::{
|
||||
Curve, Cycle, HalfEdge, Objects, Surface, SurfaceVertex, Vertex,
|
||||
},
|
||||
|
@ -12,7 +13,7 @@ use crate::{
|
|||
/// A partial [`Cycle`]
|
||||
///
|
||||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PartialCycle {
|
||||
/// The surface that the [`Cycle`] is defined in
|
||||
pub surface: Option<Handle<Surface>>,
|
||||
|
@ -82,7 +83,7 @@ impl PartialCycle {
|
|||
|
||||
let curve = Curve::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.as_line_from_points([position_prev, position_next]);
|
||||
.update_as_line_from_points([position_prev, position_next]);
|
||||
|
||||
let [from, to] =
|
||||
[(0., from), (1., to)].map(|(position, surface_form)| {
|
||||
|
|
|
@ -2,19 +2,20 @@ use fj_interop::ext::ArrayExt;
|
|||
use fj_math::{Point, Scalar};
|
||||
|
||||
use crate::{
|
||||
builder::{CurveBuilder, GlobalVertexBuilder},
|
||||
objects::{
|
||||
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
|
||||
Surface, SurfaceVertex, Vertex, VerticesInNormalizedOrder,
|
||||
},
|
||||
partial::{HasPartial, MaybePartial},
|
||||
storage::{Handle, HandleWrapper},
|
||||
storage::Handle,
|
||||
validate::ValidationError,
|
||||
};
|
||||
|
||||
/// A partial [`HalfEdge`]
|
||||
///
|
||||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PartialHalfEdge {
|
||||
/// The surface that the [`HalfEdge`]'s [`Curve`] is defined in
|
||||
pub surface: Option<Handle<Surface>>,
|
||||
|
@ -35,10 +36,10 @@ impl PartialHalfEdge {
|
|||
/// Extract the global curve from either the curve or global form
|
||||
///
|
||||
/// If a global curve is available through both, the curve is preferred.
|
||||
pub fn extract_global_curve(&self) -> Option<Handle<GlobalCurve>> {
|
||||
pub fn extract_global_curve(&self) -> MaybePartial<GlobalCurve> {
|
||||
self.curve
|
||||
.global_form()
|
||||
.or_else(|| self.global_form.curve().cloned())
|
||||
.unwrap_or_else(|| self.global_form.curve())
|
||||
}
|
||||
|
||||
/// Access the vertices of the global form, if available
|
||||
|
@ -127,11 +128,11 @@ impl PartialHalfEdge {
|
|||
objects: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let curve = Curve::partial()
|
||||
.with_global_form(self.extract_global_curve())
|
||||
.with_global_form(Some(self.extract_global_curve()))
|
||||
.with_surface(self.surface.clone())
|
||||
.as_circle_from_radius(radius);
|
||||
.update_as_circle_from_radius(radius);
|
||||
|
||||
let path = curve.path.expect("Expected path that was just created");
|
||||
let path = curve.path().expect("Expected path that was just created");
|
||||
|
||||
let [a_curve, b_curve] =
|
||||
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));
|
||||
|
@ -141,7 +142,7 @@ impl PartialHalfEdge {
|
|||
.map(|[global_form, _]| global_form)
|
||||
.unwrap_or_else(|| {
|
||||
GlobalVertex::partial()
|
||||
.from_curve_and_position(curve.clone(), a_curve)
|
||||
.update_from_curve_and_position(curve.clone(), a_curve)
|
||||
.into()
|
||||
});
|
||||
|
||||
|
@ -190,11 +191,10 @@ impl PartialHalfEdge {
|
|||
|
||||
let surface = self
|
||||
.surface
|
||||
.as_ref()
|
||||
.clone()
|
||||
.or_else(|| from_surface.surface())
|
||||
.or_else(|| to_surface.surface())
|
||||
.expect("Can't infer line segment without a surface")
|
||||
.clone();
|
||||
.expect("Can't infer line segment without a surface");
|
||||
let points = [&from_surface, &to_surface].map(|vertex| {
|
||||
vertex
|
||||
.position()
|
||||
|
@ -202,9 +202,9 @@ impl PartialHalfEdge {
|
|||
});
|
||||
|
||||
let curve = Curve::partial()
|
||||
.with_global_form(self.extract_global_curve())
|
||||
.with_global_form(Some(self.extract_global_curve()))
|
||||
.with_surface(Some(surface))
|
||||
.as_line_from_points(points);
|
||||
.update_as_line_from_points(points);
|
||||
|
||||
let [back, front] = {
|
||||
let vertices = [(from, 0.), (to, 1.)].map(|(vertex, position)| {
|
||||
|
@ -252,9 +252,11 @@ impl PartialHalfEdge {
|
|||
vertices.zip_ext(global_forms).map(|(vertex, global_form)| {
|
||||
vertex.update_partial(|vertex| {
|
||||
vertex.clone().with_surface_form(Some(
|
||||
vertex.surface_form.update_partial(|surface_vertex| {
|
||||
vertex.surface_form().update_partial(
|
||||
|surface_vertex| {
|
||||
surface_vertex.with_global_form(global_form)
|
||||
}),
|
||||
},
|
||||
),
|
||||
))
|
||||
})
|
||||
})
|
||||
|
@ -312,12 +314,12 @@ impl From<&HalfEdge> for PartialHalfEdge {
|
|||
/// A partial [`GlobalEdge`]
|
||||
///
|
||||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PartialGlobalEdge {
|
||||
/// The curve that the [`GlobalEdge`] is defined in
|
||||
///
|
||||
/// Must be provided before [`PartialGlobalEdge::build`] is called.
|
||||
pub curve: Option<HandleWrapper<GlobalCurve>>,
|
||||
pub curve: MaybePartial<GlobalCurve>,
|
||||
|
||||
/// The vertices that bound the [`GlobalEdge`] in the curve
|
||||
///
|
||||
|
@ -327,9 +329,12 @@ pub struct PartialGlobalEdge {
|
|||
|
||||
impl PartialGlobalEdge {
|
||||
/// Update the partial global edge with the given curve
|
||||
pub fn with_curve(mut self, curve: Option<Handle<GlobalCurve>>) -> Self {
|
||||
pub fn with_curve(
|
||||
mut self,
|
||||
curve: Option<impl Into<MaybePartial<GlobalCurve>>>,
|
||||
) -> Self {
|
||||
if let Some(curve) = curve {
|
||||
self.curve = Some(curve.into());
|
||||
self.curve = curve.into();
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -362,9 +367,7 @@ impl PartialGlobalEdge {
|
|||
self,
|
||||
objects: &Objects,
|
||||
) -> Result<Handle<GlobalEdge>, ValidationError> {
|
||||
let curve = self
|
||||
.curve
|
||||
.expect("Can't build `GlobalEdge` without `GlobalCurve`");
|
||||
let curve = self.curve.into_full(objects)?;
|
||||
let vertices = self
|
||||
.vertices
|
||||
.expect("Can't build `GlobalEdge` without vertices")
|
||||
|
@ -379,7 +382,7 @@ impl PartialGlobalEdge {
|
|||
impl From<&GlobalEdge> for PartialGlobalEdge {
|
||||
fn from(global_edge: &GlobalEdge) -> Self {
|
||||
Self {
|
||||
curve: Some(global_edge.curve().clone().into()),
|
||||
curve: global_edge.curve().clone().into(),
|
||||
vertices: Some(
|
||||
global_edge
|
||||
.vertices()
|
||||
|
|
|
@ -5,7 +5,7 @@ pub mod vertex;
|
|||
|
||||
use crate::{
|
||||
objects::{
|
||||
Curve, Cycle, GlobalEdge, GlobalVertex, HalfEdge, Objects,
|
||||
Curve, Cycle, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
|
||||
SurfaceVertex, Vertex,
|
||||
},
|
||||
storage::Handle,
|
||||
|
@ -13,8 +13,8 @@ use crate::{
|
|||
|
||||
use super::{
|
||||
HasPartial, MaybePartial, Partial, PartialCurve, PartialCycle,
|
||||
PartialGlobalEdge, PartialGlobalVertex, PartialHalfEdge,
|
||||
PartialSurfaceVertex, PartialVertex,
|
||||
PartialGlobalCurve, PartialGlobalEdge, PartialGlobalVertex,
|
||||
PartialHalfEdge, PartialSurfaceVertex, PartialVertex,
|
||||
};
|
||||
|
||||
macro_rules! impl_traits {
|
||||
|
@ -49,6 +49,7 @@ macro_rules! impl_traits {
|
|||
impl_traits!(
|
||||
Curve, PartialCurve;
|
||||
Cycle, PartialCycle;
|
||||
GlobalCurve, PartialGlobalCurve;
|
||||
GlobalEdge, PartialGlobalEdge;
|
||||
GlobalVertex, PartialGlobalVertex;
|
||||
HalfEdge, PartialHalfEdge;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
builder::GlobalVertexBuilder,
|
||||
objects::{Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex},
|
||||
partial::{HasPartial, MaybePartial},
|
||||
partial::MaybePartial,
|
||||
storage::Handle,
|
||||
validate::ValidationError,
|
||||
};
|
||||
|
@ -10,26 +11,29 @@ use crate::{
|
|||
/// A partial [`Vertex`]
|
||||
///
|
||||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PartialVertex {
|
||||
/// The position of the [`Vertex`] on the [`Curve`]
|
||||
///
|
||||
/// Must be provided before [`PartialVertex::build`] is called.
|
||||
pub position: Option<Point<1>>,
|
||||
|
||||
/// The curve that the [`Vertex`] is defined in
|
||||
///
|
||||
/// Must be provided before [`PartialVertex::build`] is called.
|
||||
pub curve: MaybePartial<Curve>,
|
||||
|
||||
/// The surface form of the [`Vertex`]
|
||||
///
|
||||
/// Can be provided, if already available, or computed from the position on
|
||||
/// the [`Curve`].
|
||||
pub surface_form: MaybePartial<SurfaceVertex>,
|
||||
position: Option<Point<1>>,
|
||||
curve: MaybePartial<Curve>,
|
||||
surface_form: MaybePartial<SurfaceVertex>,
|
||||
}
|
||||
|
||||
impl PartialVertex {
|
||||
/// Access the position of the [`Vertex`] on the curve
|
||||
pub fn position(&self) -> Option<Point<1>> {
|
||||
self.position
|
||||
}
|
||||
|
||||
/// Access the curve that the [`Vertex`] is defined in
|
||||
pub fn curve(&self) -> MaybePartial<Curve> {
|
||||
self.curve.clone()
|
||||
}
|
||||
|
||||
/// Access the surface form of the [`Vertex`]
|
||||
pub fn surface_form(&self) -> MaybePartial<SurfaceVertex> {
|
||||
self.surface_form.clone()
|
||||
}
|
||||
|
||||
/// Provide a position for the partial vertex
|
||||
pub fn with_position(
|
||||
mut self,
|
||||
|
@ -63,19 +67,13 @@ impl PartialVertex {
|
|||
self
|
||||
}
|
||||
|
||||
/// Remove the surface form of the partial vertex, inferring it on build
|
||||
pub fn infer_surface_form(mut self) -> Self {
|
||||
self.surface_form = SurfaceVertex::partial().into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a full [`Vertex`] from the partial vertex
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics, if no position has been provided.
|
||||
/// Panics, if position has not been provided.
|
||||
///
|
||||
/// Panics, if no curve has been provided.
|
||||
/// Panics, if curve has not been provided.
|
||||
pub fn build(
|
||||
self,
|
||||
objects: &Objects,
|
||||
|
@ -121,24 +119,27 @@ impl From<&Vertex> for PartialVertex {
|
|||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct PartialSurfaceVertex {
|
||||
/// The position of the [`SurfaceVertex`] in the [`Surface`]
|
||||
///
|
||||
/// Must be provided before [`PartialSurfaceVertex::build`] is called.
|
||||
pub position: Option<Point<2>>,
|
||||
|
||||
/// The surface that the [`SurfaceVertex`] is defined in
|
||||
///
|
||||
/// Must be provided before [`PartialSurfaceVertex::build`] is called.
|
||||
pub surface: Option<Handle<Surface>>,
|
||||
|
||||
/// The global form of the [`SurfaceVertex`]
|
||||
///
|
||||
/// Can be provided, if already available, or computed from the position on
|
||||
/// the [`Surface`].
|
||||
pub global_form: MaybePartial<GlobalVertex>,
|
||||
position: Option<Point<2>>,
|
||||
surface: Option<Handle<Surface>>,
|
||||
global_form: MaybePartial<GlobalVertex>,
|
||||
}
|
||||
|
||||
impl PartialSurfaceVertex {
|
||||
/// Access the position of the [`SurfaceVertex`]
|
||||
pub fn position(&self) -> Option<Point<2>> {
|
||||
self.position
|
||||
}
|
||||
|
||||
/// Access the surface that the [`SurfaceVertex`] is defined in
|
||||
pub fn surface(&self) -> Option<Handle<Surface>> {
|
||||
self.surface.clone()
|
||||
}
|
||||
|
||||
/// Access the global form of the [`SurfaceVertex`]
|
||||
pub fn global_form(&self) -> MaybePartial<GlobalVertex> {
|
||||
self.global_form.clone()
|
||||
}
|
||||
|
||||
/// Provide a position for the partial surface vertex
|
||||
pub fn with_position(
|
||||
mut self,
|
||||
|
@ -169,19 +170,7 @@ impl PartialSurfaceVertex {
|
|||
self
|
||||
}
|
||||
|
||||
/// Remove the global form of the partial vertex, inferring it on build
|
||||
pub fn infer_global_form(mut self) -> Self {
|
||||
self.global_form = GlobalVertex::partial().into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a full [`SurfaceVertex`] from the partial surface vertex
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics, if no position has been provided.
|
||||
///
|
||||
/// Panics, if no surface has been provided.
|
||||
pub fn build(
|
||||
self,
|
||||
objects: &Objects,
|
||||
|
@ -196,7 +185,7 @@ impl PartialSurfaceVertex {
|
|||
let global_form = self
|
||||
.global_form
|
||||
.update_partial(|global_form| {
|
||||
global_form.from_surface_and_position(&surface, position)
|
||||
global_form.update_from_surface_and_position(&surface, position)
|
||||
})
|
||||
.into_full(objects)?;
|
||||
|
||||
|
@ -223,13 +212,15 @@ impl From<&SurfaceVertex> for PartialSurfaceVertex {
|
|||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct PartialGlobalVertex {
|
||||
/// The position of the [`GlobalVertex`]
|
||||
///
|
||||
/// Must be provided before [`PartialGlobalVertex::build`] is called.
|
||||
pub position: Option<Point<3>>,
|
||||
position: Option<Point<3>>,
|
||||
}
|
||||
|
||||
impl PartialGlobalVertex {
|
||||
/// Access the position of the [`GlobalVertex`]
|
||||
pub fn position(&self) -> Option<Point<3>> {
|
||||
self.position
|
||||
}
|
||||
|
||||
/// Provide a position for the partial global vertex
|
||||
pub fn with_position(
|
||||
mut self,
|
||||
|
@ -241,35 +232,6 @@ impl PartialGlobalVertex {
|
|||
self
|
||||
}
|
||||
|
||||
/// Update partial global vertex from the given curve and position on it
|
||||
pub fn from_curve_and_position(
|
||||
self,
|
||||
curve: impl Into<MaybePartial<Curve>>,
|
||||
position: impl Into<Point<1>>,
|
||||
) -> Self {
|
||||
let curve = curve.into().into_partial();
|
||||
|
||||
let path = curve.path.expect(
|
||||
"Need path to create `GlobalVertex` from curve and position",
|
||||
);
|
||||
let surface = curve.surface.expect(
|
||||
"Need surface to create `GlobalVertex` from curve and position",
|
||||
);
|
||||
|
||||
let position_surface = path.point_from_path_coords(position);
|
||||
self.from_surface_and_position(&surface, position_surface)
|
||||
}
|
||||
|
||||
/// Update partial global vertex from the given surface and position on it
|
||||
pub fn from_surface_and_position(
|
||||
mut self,
|
||||
surface: &Surface,
|
||||
position: impl Into<Point<2>>,
|
||||
) -> Self {
|
||||
self.position = Some(surface.point_from_surface_coords(position));
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a full [`GlobalVertex`] from the partial global vertex
|
||||
pub fn build(
|
||||
self,
|
||||
|
|
|
@ -196,6 +196,7 @@ mod tests {
|
|||
use fj_interop::ext::ArrayExt;
|
||||
|
||||
use crate::{
|
||||
builder::VertexBuilder,
|
||||
objects::{GlobalCurve, HalfEdge, Objects},
|
||||
partial::HasPartial,
|
||||
validate::Validate2,
|
||||
|
|
|
@ -179,6 +179,7 @@ impl SurfaceVertexValidationError {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
builder::{CurveBuilder, SurfaceVertexBuilder},
|
||||
objects::{Curve, GlobalVertex, Objects, SurfaceVertex, Vertex},
|
||||
partial::HasPartial,
|
||||
validate::Validate2,
|
||||
|
@ -193,7 +194,7 @@ mod tests {
|
|||
.with_curve(Some(
|
||||
Curve::partial()
|
||||
.with_surface(Some(objects.surfaces.xy_plane()))
|
||||
.as_u_axis(),
|
||||
.update_as_u_axis(),
|
||||
))
|
||||
.build(&objects)?;
|
||||
let invalid = Vertex::new(
|
||||
|
@ -221,7 +222,7 @@ mod tests {
|
|||
.with_curve(Some(
|
||||
Curve::partial()
|
||||
.with_surface(Some(objects.surfaces.xy_plane()))
|
||||
.as_u_axis(),
|
||||
.update_as_u_axis(),
|
||||
))
|
||||
.build(&objects)?;
|
||||
let invalid = Vertex::new(
|
||||
|
|
Loading…
Reference in New Issue