mirror of https://github.com/hannobraun/Fornjot
Merge pull request #1339 from hannobraun/partial
Clean up partial vertex types
This commit is contained in:
commit
f172d3ae50
|
@ -199,8 +199,8 @@ mod tests {
|
|||
algorithms::{reverse::Reverse, sweep::Sweep},
|
||||
builder::HalfEdgeBuilder,
|
||||
insert::Insert,
|
||||
objects::{Cycle, Face, HalfEdge, Objects, SurfaceVertex, Vertex},
|
||||
partial::HasPartial,
|
||||
objects::{Cycle, Face, HalfEdge, Objects},
|
||||
partial::{HasPartial, PartialSurfaceVertex, PartialVertex},
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -218,63 +218,75 @@ mod tests {
|
|||
let face =
|
||||
(half_edge, Color::default()).sweep([0., 0., 1.], &objects)?;
|
||||
|
||||
let expected_face =
|
||||
{
|
||||
let surface = objects.surfaces.xz_plane();
|
||||
let expected_face = {
|
||||
let surface = objects.surfaces.xz_plane();
|
||||
|
||||
let bottom = HalfEdge::partial()
|
||||
.update_as_line_segment_from_points(
|
||||
surface.clone(),
|
||||
[[0., 0.], [1., 0.]],
|
||||
)
|
||||
.build(&objects)?
|
||||
.insert(&objects)?;
|
||||
let side_up = HalfEdge::partial()
|
||||
.with_surface(surface.clone())
|
||||
.with_back_vertex(Vertex::partial().with_surface_form(
|
||||
bottom.front().surface_form().clone(),
|
||||
))
|
||||
.with_front_vertex(Vertex::partial().with_surface_form(
|
||||
SurfaceVertex::partial().with_position(Some([1., 1.])),
|
||||
))
|
||||
.update_as_line_segment()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?;
|
||||
let top = HalfEdge::partial()
|
||||
.with_surface(surface.clone())
|
||||
.with_back_vertex(Vertex::partial().with_surface_form(
|
||||
SurfaceVertex::partial().with_position(Some([0., 1.])),
|
||||
))
|
||||
.with_front_vertex(Vertex::partial().with_surface_form(
|
||||
side_up.front().surface_form().clone(),
|
||||
))
|
||||
.update_as_line_segment()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?
|
||||
.reverse(&objects)?;
|
||||
let side_down =
|
||||
HalfEdge::partial()
|
||||
.with_surface(surface)
|
||||
.with_back_vertex(Vertex::partial().with_surface_form(
|
||||
bottom.back().surface_form().clone(),
|
||||
))
|
||||
.with_front_vertex(Vertex::partial().with_surface_form(
|
||||
top.front().surface_form().clone(),
|
||||
))
|
||||
.update_as_line_segment()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?
|
||||
.reverse(&objects)?;
|
||||
let bottom = HalfEdge::partial()
|
||||
.update_as_line_segment_from_points(
|
||||
surface.clone(),
|
||||
[[0., 0.], [1., 0.]],
|
||||
)
|
||||
.build(&objects)?
|
||||
.insert(&objects)?;
|
||||
let side_up = HalfEdge::partial()
|
||||
.with_surface(surface.clone())
|
||||
.with_back_vertex(PartialVertex {
|
||||
surface_form: bottom.front().surface_form().clone().into(),
|
||||
..Default::default()
|
||||
})
|
||||
.with_front_vertex(PartialVertex {
|
||||
surface_form: PartialSurfaceVertex {
|
||||
position: Some([1., 1.].into()),
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
..Default::default()
|
||||
})
|
||||
.update_as_line_segment()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?;
|
||||
let top = HalfEdge::partial()
|
||||
.with_surface(surface.clone())
|
||||
.with_back_vertex(PartialVertex {
|
||||
surface_form: PartialSurfaceVertex {
|
||||
position: Some([0., 1.].into()),
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
..Default::default()
|
||||
})
|
||||
.with_front_vertex(PartialVertex {
|
||||
surface_form: side_up.front().surface_form().clone().into(),
|
||||
..Default::default()
|
||||
})
|
||||
.update_as_line_segment()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?
|
||||
.reverse(&objects)?;
|
||||
let side_down = HalfEdge::partial()
|
||||
.with_surface(surface)
|
||||
.with_back_vertex(PartialVertex {
|
||||
surface_form: bottom.back().surface_form().clone().into(),
|
||||
..Default::default()
|
||||
})
|
||||
.with_front_vertex(PartialVertex {
|
||||
surface_form: top.front().surface_form().clone().into(),
|
||||
..Default::default()
|
||||
})
|
||||
.update_as_line_segment()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?
|
||||
.reverse(&objects)?;
|
||||
|
||||
let cycle = objects
|
||||
.cycles
|
||||
.insert(Cycle::new([bottom, side_up, top, side_down]))?;
|
||||
let cycle = objects
|
||||
.cycles
|
||||
.insert(Cycle::new([bottom, side_up, top, side_down]))?;
|
||||
|
||||
Face::partial()
|
||||
.with_exterior(cycle)
|
||||
.build(&objects)?
|
||||
.insert(&objects)?
|
||||
};
|
||||
Face::partial()
|
||||
.with_exterior(cycle)
|
||||
.build(&objects)?
|
||||
.insert(&objects)?
|
||||
};
|
||||
|
||||
assert_eq!(face, expected_face);
|
||||
Ok(())
|
||||
|
|
|
@ -170,8 +170,8 @@ mod tests {
|
|||
algorithms::sweep::Sweep,
|
||||
builder::{CurveBuilder, HalfEdgeBuilder},
|
||||
insert::Insert,
|
||||
objects::{HalfEdge, Objects, Vertex},
|
||||
partial::{HasPartial, PartialCurve},
|
||||
objects::{HalfEdge, Objects},
|
||||
partial::{HasPartial, PartialCurve, PartialVertex},
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -185,11 +185,13 @@ mod tests {
|
|||
};
|
||||
curve.update_as_u_axis();
|
||||
let curve = curve.build(&objects)?.insert(&objects)?;
|
||||
let vertex = Vertex::partial()
|
||||
.with_position(Some([0.]))
|
||||
.with_curve(curve)
|
||||
.build(&objects)?
|
||||
.insert(&objects)?;
|
||||
let vertex = PartialVertex {
|
||||
position: Some([0.].into()),
|
||||
curve: curve.into(),
|
||||
..Default::default()
|
||||
}
|
||||
.build(&objects)?
|
||||
.insert(&objects)?;
|
||||
|
||||
let half_edge =
|
||||
(vertex, surface.clone()).sweep([0., 0., 1.], &objects)?;
|
||||
|
|
|
@ -22,10 +22,10 @@ impl TransformObject for PartialHalfEdge {
|
|||
.into();
|
||||
let vertices = self.vertices().try_map_ext(
|
||||
|vertex| -> Result<_, ValidationError> {
|
||||
Ok(vertex
|
||||
.into_partial()
|
||||
.transform(transform, objects)?
|
||||
.with_curve(curve.clone()))
|
||||
let mut vertex =
|
||||
vertex.into_partial().transform(transform, objects)?;
|
||||
vertex.curve = curve.clone();
|
||||
Ok(vertex)
|
||||
},
|
||||
)?;
|
||||
let global_form = self
|
||||
|
|
|
@ -14,18 +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)?;
|
||||
|
||||
// Don't need to transform `self.position`, as that is in curve
|
||||
// coordinates and thus transforming the curve takes care of it.
|
||||
Ok(Self::default()
|
||||
.with_position(self.position())
|
||||
.with_curve(curve)
|
||||
.with_surface_form(surface_form))
|
||||
Ok(Self {
|
||||
position: self.position,
|
||||
curve,
|
||||
surface_form: surface_form.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,17 +37,19 @@ impl TransformObject for PartialSurfaceVertex {
|
|||
objects: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let surface = self
|
||||
.surface()
|
||||
.surface
|
||||
.clone()
|
||||
.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::default()
|
||||
.with_position(self.position())
|
||||
.with_surface(surface)
|
||||
.with_global_form(Some(global_form)))
|
||||
Ok(Self {
|
||||
position: self.position,
|
||||
surface,
|
||||
global_form,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,9 +60,9 @@ impl TransformObject for PartialGlobalVertex {
|
|||
_: &Objects,
|
||||
) -> Result<Self, ValidationError> {
|
||||
let position = self
|
||||
.position()
|
||||
.position
|
||||
.map(|position| transform.transform_point(&position));
|
||||
|
||||
Ok(Self::default().with_position(position))
|
||||
Ok(Self { position })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
objects::{HalfEdge, Surface, SurfaceVertex, Vertex},
|
||||
partial::{HasPartial, MaybePartial, PartialCurve, PartialCycle},
|
||||
objects::{HalfEdge, Surface, SurfaceVertex},
|
||||
partial::{
|
||||
HasPartial, MaybePartial, PartialCurve, PartialCycle,
|
||||
PartialSurfaceVertex, PartialVertex,
|
||||
},
|
||||
storage::Handle,
|
||||
};
|
||||
|
||||
|
@ -72,11 +75,10 @@ impl CycleBuilder for PartialCycle {
|
|||
.update_as_line_from_points([position_prev, position_next]);
|
||||
|
||||
let vertices = [(0., vertex_prev), (1., vertex_next)].map(
|
||||
|(position, surface_form)| {
|
||||
Vertex::partial()
|
||||
.with_curve(curve.clone())
|
||||
.with_position(Some([position]))
|
||||
.with_surface_form(surface_form)
|
||||
|(position, surface_form)| PartialVertex {
|
||||
position: Some([position].into()),
|
||||
curve: curve.clone().into(),
|
||||
surface_form,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -101,9 +103,11 @@ impl CycleBuilder for PartialCycle {
|
|||
points: impl IntoIterator<Item = impl Into<Point<2>>>,
|
||||
) -> Self {
|
||||
self.with_poly_chain(points.into_iter().map(|position| {
|
||||
SurfaceVertex::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.with_position(Some(position))
|
||||
PartialSurfaceVertex {
|
||||
position: Some(position.into()),
|
||||
surface: Some(surface.clone()),
|
||||
..Default::default()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,10 @@ use iter_fixed::IntoIteratorFixed;
|
|||
|
||||
use crate::{
|
||||
insert::Insert,
|
||||
objects::{
|
||||
Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex,
|
||||
VerticesInNormalizedOrder,
|
||||
},
|
||||
objects::{Curve, Objects, Surface, Vertex, VerticesInNormalizedOrder},
|
||||
partial::{
|
||||
HasPartial, MaybePartial, PartialCurve, PartialGlobalEdge,
|
||||
PartialHalfEdge,
|
||||
MaybePartial, PartialCurve, PartialGlobalEdge, PartialGlobalVertex,
|
||||
PartialHalfEdge, PartialSurfaceVertex, PartialVertex,
|
||||
},
|
||||
storage::Handle,
|
||||
validate::ValidationError,
|
||||
|
@ -82,24 +79,27 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
|||
.vertices()
|
||||
.map(|[global_form, _]| global_form)
|
||||
.unwrap_or_else(|| {
|
||||
GlobalVertex::partial()
|
||||
.update_from_curve_and_position(curve.clone(), a_curve)
|
||||
.into()
|
||||
PartialGlobalVertex::from_curve_and_position(
|
||||
curve.clone(),
|
||||
a_curve,
|
||||
)
|
||||
.into()
|
||||
});
|
||||
|
||||
let surface_vertex = SurfaceVertex::partial()
|
||||
.with_position(Some(path.point_from_path_coords(a_curve)))
|
||||
.with_surface(curve.surface.clone())
|
||||
.with_global_form(Some(global_vertex))
|
||||
.build(objects)?
|
||||
.insert(objects)?;
|
||||
let surface_vertex = PartialSurfaceVertex {
|
||||
position: Some(path.point_from_path_coords(a_curve)),
|
||||
surface: curve.surface.clone(),
|
||||
global_form: global_vertex,
|
||||
}
|
||||
.build(objects)?
|
||||
.insert(objects)?;
|
||||
|
||||
let [back, front] = [a_curve, b_curve].map(|point_curve| {
|
||||
Vertex::partial()
|
||||
.with_position(Some(point_curve))
|
||||
.with_curve(curve.clone())
|
||||
.with_surface_form(surface_vertex.clone())
|
||||
});
|
||||
let [back, front] =
|
||||
[a_curve, b_curve].map(|point_curve| PartialVertex {
|
||||
position: Some(point_curve),
|
||||
curve: curve.clone().into(),
|
||||
surface_form: surface_vertex.clone().into(),
|
||||
});
|
||||
|
||||
Ok(self.with_curve(curve).with_vertices([back, front]))
|
||||
}
|
||||
|
@ -110,11 +110,16 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
|||
points: [impl Into<Point<2>>; 2],
|
||||
) -> Self {
|
||||
let vertices = points.map(|point| {
|
||||
let surface_form = SurfaceVertex::partial()
|
||||
.with_surface(Some(surface.clone()))
|
||||
.with_position(Some(point));
|
||||
let surface_form = PartialSurfaceVertex {
|
||||
position: Some(point.into()),
|
||||
surface: Some(surface.clone()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Vertex::partial().with_surface_form(surface_form)
|
||||
PartialVertex {
|
||||
surface_form: surface_form.into(),
|
||||
..Default::default()
|
||||
}
|
||||
});
|
||||
|
||||
self.with_surface(surface)
|
||||
|
@ -148,10 +153,10 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
|||
|
||||
let [back, front] = {
|
||||
let vertices = [(from, 0.), (to, 1.)].map(|(vertex, position)| {
|
||||
vertex.update_partial(|vertex| {
|
||||
vertex.update_partial(|mut vertex| {
|
||||
vertex.position = Some([position].into());
|
||||
vertex.curve = curve.clone().into();
|
||||
vertex
|
||||
.with_position(Some([position]))
|
||||
.with_curve(curve.clone())
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -195,14 +200,16 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
|||
.zip(global_forms)
|
||||
.collect::<[_; 2]>()
|
||||
.map(|(vertex, global_form)| {
|
||||
vertex.update_partial(|vertex| {
|
||||
vertex.clone().with_surface_form(
|
||||
vertex.surface_form().update_partial(
|
||||
|surface_vertex| {
|
||||
surface_vertex.with_global_form(global_form)
|
||||
},
|
||||
),
|
||||
)
|
||||
vertex.update_partial(|mut vertex| {
|
||||
vertex.surface_form = vertex
|
||||
.surface_form
|
||||
.update_partial(|mut surface_vertex| {
|
||||
if let Some(global_form) = global_form {
|
||||
surface_vertex.global_form = global_form;
|
||||
}
|
||||
surface_vertex
|
||||
});
|
||||
vertex
|
||||
})
|
||||
})
|
||||
};
|
||||
|
|
|
@ -8,11 +8,8 @@ use crate::{
|
|||
algorithms::transform::TransformObject,
|
||||
builder::{FaceBuilder, HalfEdgeBuilder},
|
||||
insert::Insert,
|
||||
objects::{
|
||||
Cycle, Face, FaceSet, HalfEdge, Objects, Shell, Surface, SurfaceVertex,
|
||||
Vertex,
|
||||
},
|
||||
partial::{HasPartial, PartialCurve},
|
||||
objects::{Cycle, Face, FaceSet, HalfEdge, Objects, Shell, Surface},
|
||||
partial::{HasPartial, PartialCurve, PartialSurfaceVertex, PartialVertex},
|
||||
storage::Handle,
|
||||
};
|
||||
|
||||
|
@ -114,14 +111,22 @@ impl<'a> ShellBuilder<'a> {
|
|||
let [_, from] = bottom.vertices();
|
||||
|
||||
let from = from.surface_form().clone();
|
||||
let to = SurfaceVertex::partial()
|
||||
.with_position(Some(from.position() + [Z, edge_length]))
|
||||
.with_surface(Some(surface.clone()));
|
||||
let to = PartialSurfaceVertex {
|
||||
position: Some(from.position() + [Z, edge_length]),
|
||||
surface: Some(surface.clone()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
HalfEdge::partial()
|
||||
.with_vertices([
|
||||
Vertex::partial().with_surface_form(from),
|
||||
Vertex::partial().with_surface_form(to),
|
||||
PartialVertex {
|
||||
surface_form: from.into(),
|
||||
..Default::default()
|
||||
},
|
||||
PartialVertex {
|
||||
surface_form: to.into(),
|
||||
..Default::default()
|
||||
},
|
||||
])
|
||||
.update_as_line_segment()
|
||||
.build(self.objects)
|
||||
|
@ -145,12 +150,11 @@ impl<'a> ShellBuilder<'a> {
|
|||
let [to, _] = bottom.vertices();
|
||||
|
||||
let to = to.surface_form().clone();
|
||||
let from = SurfaceVertex::partial()
|
||||
.with_position(Some(
|
||||
to.position() + [Z, edge_length],
|
||||
))
|
||||
.with_surface(Some(surface.clone()))
|
||||
.with_global_form(Some(from.global_form().clone()));
|
||||
let from = PartialSurfaceVertex {
|
||||
position: Some(to.position() + [Z, edge_length]),
|
||||
surface: Some(surface.clone()),
|
||||
global_form: from.global_form().clone().into(),
|
||||
};
|
||||
|
||||
let curve = PartialCurve {
|
||||
global_form: Some(
|
||||
|
@ -166,8 +170,14 @@ impl<'a> ShellBuilder<'a> {
|
|||
HalfEdge::partial()
|
||||
.with_curve(curve)
|
||||
.with_vertices([
|
||||
Vertex::partial().with_surface_form(from),
|
||||
Vertex::partial().with_surface_form(to),
|
||||
PartialVertex {
|
||||
surface_form: from.into(),
|
||||
..Default::default()
|
||||
},
|
||||
PartialVertex {
|
||||
surface_form: to.into(),
|
||||
..Default::default()
|
||||
},
|
||||
])
|
||||
.update_as_line_segment()
|
||||
.build(self.objects)
|
||||
|
@ -189,8 +199,14 @@ impl<'a> ShellBuilder<'a> {
|
|||
let from = from.surface_form().clone();
|
||||
let to = to.surface_form().clone();
|
||||
|
||||
let from = Vertex::partial().with_surface_form(from);
|
||||
let to = Vertex::partial().with_surface_form(to);
|
||||
let from = PartialVertex {
|
||||
surface_form: from.into(),
|
||||
..Default::default()
|
||||
};
|
||||
let to = PartialVertex {
|
||||
surface_form: to.into(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
HalfEdge::partial()
|
||||
.with_vertices([from, to])
|
||||
|
@ -250,16 +266,15 @@ impl<'a> ShellBuilder<'a> {
|
|||
.map(|(point, edge)| {
|
||||
let vertex = edge.back();
|
||||
|
||||
SurfaceVertex::partial()
|
||||
.with_position(Some(point))
|
||||
.with_surface(Some(surface.clone()))
|
||||
.with_global_form(Some(
|
||||
vertex.global_form().clone(),
|
||||
))
|
||||
.build(self.objects)
|
||||
.unwrap()
|
||||
.insert(self.objects)
|
||||
.unwrap()
|
||||
PartialSurfaceVertex {
|
||||
position: Some(point.into()),
|
||||
surface: Some(surface.clone()),
|
||||
global_form: vertex.global_form().clone().into(),
|
||||
}
|
||||
.build(self.objects)
|
||||
.unwrap()
|
||||
.insert(self.objects)
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
[a.clone(), b, c, d, a]
|
||||
|
@ -277,10 +292,10 @@ impl<'a> ShellBuilder<'a> {
|
|||
.into_iter_fixed()
|
||||
.zip(surface_vertices.clone())
|
||||
.collect::<[_; 2]>()
|
||||
.map(|(vertex, surface_form)| {
|
||||
Vertex::partial()
|
||||
.with_position(Some(vertex.position()))
|
||||
.with_surface_form(surface_form)
|
||||
.map(|(vertex, surface_form)| PartialVertex {
|
||||
position: Some(vertex.position()),
|
||||
surface_form: surface_form.into(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
edges.push(
|
||||
|
|
|
@ -11,47 +11,46 @@ use crate::{
|
|||
/// 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;
|
||||
fn infer_surface_form(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl VertexBuilder for PartialVertex {
|
||||
fn infer_surface_form(self) -> Self {
|
||||
self.with_surface_form(PartialSurfaceVertex::default())
|
||||
fn infer_surface_form(&mut self) -> &mut Self {
|
||||
self.surface_form = PartialSurfaceVertex::default().into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder API for [`PartialSurfaceVertex`]
|
||||
pub trait SurfaceVertexBuilder {
|
||||
/// Infer the global form of the partial vertex
|
||||
fn infer_global_form(self) -> Self;
|
||||
fn infer_global_form(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl SurfaceVertexBuilder for PartialSurfaceVertex {
|
||||
fn infer_global_form(self) -> Self {
|
||||
self.with_global_form(Some(GlobalVertex::partial()))
|
||||
fn infer_global_form(&mut self) -> &mut Self {
|
||||
self.global_form = GlobalVertex::partial().into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,
|
||||
fn from_curve_and_position(
|
||||
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,
|
||||
fn from_surface_and_position(
|
||||
surface: &Surface,
|
||||
position: impl Into<Point<2>>,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
impl GlobalVertexBuilder for PartialGlobalVertex {
|
||||
fn update_from_curve_and_position(
|
||||
self,
|
||||
fn from_curve_and_position(
|
||||
curve: impl Into<MaybePartial<Curve>>,
|
||||
position: impl Into<Point<1>>,
|
||||
) -> Self {
|
||||
|
@ -65,14 +64,16 @@ impl GlobalVertexBuilder for PartialGlobalVertex {
|
|||
);
|
||||
|
||||
let position_surface = path.point_from_path_coords(position);
|
||||
self.update_from_surface_and_position(&surface, position_surface)
|
||||
|
||||
Self::from_surface_and_position(&surface, position_surface)
|
||||
}
|
||||
|
||||
fn update_from_surface_and_position(
|
||||
self,
|
||||
fn from_surface_and_position(
|
||||
surface: &Surface,
|
||||
position: impl Into<Point<2>>,
|
||||
) -> Self {
|
||||
self.with_position(Some(surface.point_from_surface_coords(position)))
|
||||
PartialGlobalVertex {
|
||||
position: Some(surface.point_from_surface_coords(position)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ 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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,7 @@ impl MaybePartial<SurfaceVertex> {
|
|||
pub fn surface(&self) -> Option<Handle<Surface>> {
|
||||
match self {
|
||||
Self::Full(full) => Some(full.surface().clone()),
|
||||
Self::Partial(partial) => partial.surface(),
|
||||
Self::Partial(partial) => partial.surface.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ impl MaybePartial<SurfaceVertex> {
|
|||
pub fn global_form(&self) -> MaybePartial<GlobalVertex> {
|
||||
match self {
|
||||
Self::Full(full) => full.global_form().clone().into(),
|
||||
Self::Partial(partial) => partial.global_form(),
|
||||
Self::Partial(partial) => partial.global_form.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,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(),
|
||||
Self::Partial(partial) => partial.surface_form.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,9 +96,14 @@ impl PartialCycle {
|
|||
|
||||
*half_edge = half_edge.clone().merge_with(
|
||||
PartialHalfEdge::default().with_vertices([
|
||||
PartialVertex::default().with_surface_form(back_vertex),
|
||||
PartialVertex::default()
|
||||
.with_surface_form(front_vertex.clone()),
|
||||
PartialVertex {
|
||||
surface_form: back_vertex,
|
||||
..Default::default()
|
||||
},
|
||||
PartialVertex {
|
||||
surface_form: front_vertex.clone().into(),
|
||||
..Default::default()
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
|
@ -111,9 +116,10 @@ impl PartialCycle {
|
|||
let back_vertex = previous_vertex.unwrap_or_default();
|
||||
|
||||
*half_edge = half_edge.clone().merge_with(
|
||||
PartialHalfEdge::default().with_back_vertex(
|
||||
PartialVertex::default().with_surface_form(back_vertex),
|
||||
),
|
||||
PartialHalfEdge::default().with_back_vertex(PartialVertex {
|
||||
surface_form: back_vertex,
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,13 +54,16 @@ impl PartialHalfEdge {
|
|||
});
|
||||
|
||||
self.vertices = self.vertices.map(|vertex| {
|
||||
vertex.update_partial(|vertex| {
|
||||
let surface_form =
|
||||
vertex.surface_form().update_partial(|surface_vertex| {
|
||||
surface_vertex.with_surface(Some(surface.clone()))
|
||||
});
|
||||
vertex.update_partial(|mut vertex| {
|
||||
let surface_form = vertex.surface_form.clone().update_partial(
|
||||
|mut surface_vertex| {
|
||||
surface_vertex.surface = Some(surface.clone());
|
||||
surface_vertex
|
||||
},
|
||||
);
|
||||
|
||||
vertex.with_surface_form(surface_form)
|
||||
vertex.surface_form = surface_form;
|
||||
vertex
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -98,7 +101,10 @@ impl PartialHalfEdge {
|
|||
let curve = self.curve.into_full(objects)?;
|
||||
let vertices = self.vertices.try_map_ext(|vertex| {
|
||||
vertex
|
||||
.update_partial(|vertex| vertex.with_curve(curve.clone()))
|
||||
.update_partial(|mut vertex| {
|
||||
vertex.curve = curve.clone().into();
|
||||
vertex
|
||||
})
|
||||
.into_full(objects)
|
||||
})?;
|
||||
|
||||
|
|
|
@ -13,53 +13,17 @@ use crate::{
|
|||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PartialVertex {
|
||||
position: Option<Point<1>>,
|
||||
curve: MaybePartial<Curve>,
|
||||
surface_form: MaybePartial<SurfaceVertex>,
|
||||
/// The position of the [`Vertex`]
|
||||
pub position: Option<Point<1>>,
|
||||
|
||||
/// The curve that the [`Vertex`] is defined in
|
||||
pub curve: MaybePartial<Curve>,
|
||||
|
||||
/// The surface form of the [`Vertex`]
|
||||
pub 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,
|
||||
position: Option<impl Into<Point<1>>>,
|
||||
) -> Self {
|
||||
if let Some(position) = position {
|
||||
self.position = Some(position.into());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Provide a curve for the partial vertex
|
||||
pub fn with_curve(mut self, curve: impl Into<MaybePartial<Curve>>) -> Self {
|
||||
self.curve = curve.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Provide a surface form for the partial vertex
|
||||
pub fn with_surface_form(
|
||||
mut self,
|
||||
surface_form: impl Into<MaybePartial<SurfaceVertex>>,
|
||||
) -> Self {
|
||||
self.surface_form = surface_form.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a full [`Vertex`] from the partial vertex
|
||||
///
|
||||
/// # Panics
|
||||
|
@ -75,14 +39,15 @@ impl PartialVertex {
|
|||
|
||||
let surface_form = self
|
||||
.surface_form
|
||||
.update_partial(|partial| {
|
||||
.update_partial(|mut partial| {
|
||||
let position = partial.position.unwrap_or_else(|| {
|
||||
curve.path().point_from_path_coords(position)
|
||||
});
|
||||
|
||||
partial.position = Some(position);
|
||||
partial.surface = Some(curve.surface().clone());
|
||||
|
||||
partial
|
||||
.with_position(Some(position))
|
||||
.with_surface(Some(curve.surface().clone()))
|
||||
})
|
||||
.into_full(objects)?;
|
||||
|
||||
|
@ -117,57 +82,17 @@ impl From<&Vertex> for PartialVertex {
|
|||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct PartialSurfaceVertex {
|
||||
position: Option<Point<2>>,
|
||||
surface: Option<Handle<Surface>>,
|
||||
global_form: MaybePartial<GlobalVertex>,
|
||||
/// The position of the [`SurfaceVertex`]
|
||||
pub position: Option<Point<2>>,
|
||||
|
||||
/// The surface that the [`SurfaceVertex`] is defined in
|
||||
pub surface: Option<Handle<Surface>>,
|
||||
|
||||
/// The global form of the [`SurfaceVertex`]
|
||||
pub 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,
|
||||
position: Option<impl Into<Point<2>>>,
|
||||
) -> Self {
|
||||
if let Some(position) = position {
|
||||
self.position = Some(position.into());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Provide a surface for the partial surface vertex
|
||||
pub fn with_surface(mut self, surface: Option<Handle<Surface>>) -> Self {
|
||||
if let Some(surface) = surface {
|
||||
self.surface = Some(surface);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Provide a global form for the partial surface vertex
|
||||
pub fn with_global_form(
|
||||
mut self,
|
||||
global_form: Option<impl Into<MaybePartial<GlobalVertex>>>,
|
||||
) -> Self {
|
||||
if let Some(global_form) = global_form {
|
||||
self.global_form = global_form.into();
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a full [`SurfaceVertex`] from the partial surface vertex
|
||||
pub fn build(
|
||||
self,
|
||||
|
@ -182,9 +107,9 @@ impl PartialSurfaceVertex {
|
|||
|
||||
let global_form = self
|
||||
.global_form
|
||||
.update_partial(|global_form| {
|
||||
global_form.update_from_surface_and_position(&surface, position)
|
||||
})
|
||||
.merge_with(PartialGlobalVertex::from_surface_and_position(
|
||||
&surface, position,
|
||||
))
|
||||
.into_full(objects)?;
|
||||
|
||||
Ok(SurfaceVertex::new(position, surface, global_form))
|
||||
|
@ -218,26 +143,11 @@ impl From<&SurfaceVertex> for PartialSurfaceVertex {
|
|||
/// See [`crate::partial`] for more information.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct PartialGlobalVertex {
|
||||
position: Option<Point<3>>,
|
||||
/// The position of the [`GlobalVertex`]
|
||||
pub 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,
|
||||
position: Option<impl Into<Point<3>>>,
|
||||
) -> Self {
|
||||
if let Some(position) = position {
|
||||
self.position = Some(position.into());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a full [`GlobalVertex`] from the partial global vertex
|
||||
pub fn build(self, _: &Objects) -> Result<GlobalVertex, ValidationError> {
|
||||
let position = self
|
||||
|
|
|
@ -95,7 +95,8 @@ mod tests {
|
|||
|
||||
// Sever connection between the last and first half-edge in the
|
||||
// cycle.
|
||||
let first_vertex = first_vertex.into_partial().infer_surface_form();
|
||||
let mut first_vertex = first_vertex.into_partial();
|
||||
first_vertex.infer_surface_form();
|
||||
*first_half_edge = first_half_edge
|
||||
.clone()
|
||||
.with_back_vertex(first_vertex)
|
||||
|
|
|
@ -220,12 +220,10 @@ mod tests {
|
|||
.build(&objects)?;
|
||||
let invalid = {
|
||||
let mut vertices = valid.vertices().clone();
|
||||
vertices[1] = vertices[1]
|
||||
.to_partial()
|
||||
// Arranging for an equal but not identical curve here.
|
||||
.with_curve(valid.curve().to_partial())
|
||||
.build(&objects)?
|
||||
.insert(&objects)?;
|
||||
let mut vertex = vertices[1].to_partial();
|
||||
// Arranging for an equal but not identical curve here.
|
||||
vertex.curve = valid.curve().to_partial().into();
|
||||
vertices[1] = vertex.build(&objects)?.insert(&objects)?;
|
||||
|
||||
HalfEdge::new(vertices, valid.global_form().clone())
|
||||
};
|
||||
|
@ -308,12 +306,10 @@ mod tests {
|
|||
let invalid = HalfEdge::new(
|
||||
valid.vertices().clone().try_map_ext(
|
||||
|vertex| -> anyhow::Result<_, ValidationError> {
|
||||
Ok(vertex
|
||||
.to_partial()
|
||||
.with_position(Some([0.]))
|
||||
.infer_surface_form()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?)
|
||||
let mut vertex = vertex.to_partial();
|
||||
vertex.position = Some([0.].into());
|
||||
vertex.infer_surface_form();
|
||||
Ok(vertex.build(&objects)?.insert(&objects)?)
|
||||
},
|
||||
)?,
|
||||
valid.global_form().clone(),
|
||||
|
|
|
@ -182,7 +182,9 @@ mod tests {
|
|||
builder::{CurveBuilder, SurfaceVertexBuilder},
|
||||
insert::Insert,
|
||||
objects::{GlobalVertex, Objects, SurfaceVertex, Vertex},
|
||||
partial::{HasPartial, PartialCurve},
|
||||
partial::{
|
||||
HasPartial, PartialCurve, PartialSurfaceVertex, PartialVertex,
|
||||
},
|
||||
validate::Validate,
|
||||
};
|
||||
|
||||
|
@ -196,20 +198,17 @@ mod tests {
|
|||
};
|
||||
curve.update_as_u_axis();
|
||||
|
||||
let valid = Vertex::partial()
|
||||
.with_position(Some([0.]))
|
||||
.with_curve(curve)
|
||||
.build(&objects)?;
|
||||
let invalid = Vertex::new(
|
||||
valid.position(),
|
||||
valid.curve().clone(),
|
||||
valid
|
||||
.surface_form()
|
||||
.to_partial()
|
||||
.with_surface(Some(objects.surfaces.xz_plane()))
|
||||
.build(&objects)?
|
||||
.insert(&objects)?,
|
||||
);
|
||||
let valid = PartialVertex {
|
||||
position: Some([0.].into()),
|
||||
curve: curve.into(),
|
||||
..Default::default()
|
||||
}
|
||||
.build(&objects)?;
|
||||
let invalid = Vertex::new(valid.position(), valid.curve().clone(), {
|
||||
let mut tmp = valid.surface_form().to_partial();
|
||||
tmp.surface = Some(objects.surfaces.xz_plane());
|
||||
tmp.build(&objects)?.insert(&objects)?
|
||||
});
|
||||
|
||||
assert!(valid.validate().is_ok());
|
||||
assert!(invalid.validate().is_err());
|
||||
|
@ -228,22 +227,19 @@ mod tests {
|
|||
};
|
||||
curve.update_as_u_axis();
|
||||
|
||||
Vertex::partial()
|
||||
.with_position(Some([0.]))
|
||||
.with_curve(curve)
|
||||
.build(&objects)?
|
||||
PartialVertex {
|
||||
position: Some([0.].into()),
|
||||
curve: curve.into(),
|
||||
..Default::default()
|
||||
}
|
||||
.build(&objects)?
|
||||
};
|
||||
let invalid = Vertex::new(
|
||||
valid.position(),
|
||||
valid.curve().clone(),
|
||||
valid
|
||||
.surface_form()
|
||||
.to_partial()
|
||||
.with_position(Some([1., 0.]))
|
||||
.infer_global_form()
|
||||
.build(&objects)?
|
||||
.insert(&objects)?,
|
||||
);
|
||||
let invalid = Vertex::new(valid.position(), valid.curve().clone(), {
|
||||
let mut tmp = valid.surface_form().to_partial();
|
||||
tmp.position = Some([1., 0.].into());
|
||||
tmp.infer_global_form();
|
||||
tmp.build(&objects)?.insert(&objects)?
|
||||
});
|
||||
|
||||
assert!(valid.validate().is_ok());
|
||||
assert!(invalid.validate().is_err());
|
||||
|
@ -255,10 +251,12 @@ mod tests {
|
|||
fn surface_vertex_position_mismatch() -> anyhow::Result<()> {
|
||||
let objects = Objects::new();
|
||||
|
||||
let valid = SurfaceVertex::partial()
|
||||
.with_position(Some([0., 0.]))
|
||||
.with_surface(Some(objects.surfaces.xy_plane()))
|
||||
.build(&objects)?;
|
||||
let valid = PartialSurfaceVertex {
|
||||
position: Some([0., 0.].into()),
|
||||
surface: Some(objects.surfaces.xy_plane()),
|
||||
..Default::default()
|
||||
}
|
||||
.build(&objects)?;
|
||||
let invalid = SurfaceVertex::new(
|
||||
valid.position(),
|
||||
valid.surface().clone(),
|
||||
|
|
Loading…
Reference in New Issue