Separate building and inserting objects

This provides more flexibility, making it possible to use the partial
object and builder infrastructure, without automatically opting into
validation. This can be useful, especially in unit tests.
This commit is contained in:
Hanno Braun 2022-11-09 22:22:42 +01:00
parent 7758f81748
commit 3f2aa6e6f2
30 changed files with 220 additions and 139 deletions

View File

@ -198,6 +198,7 @@ mod tests {
use crate::{ use crate::{
algorithms::approx::{path::RangeOnPath, Approx, ApproxPoint}, algorithms::approx::{path::RangeOnPath, Approx, ApproxPoint},
builder::CurveBuilder, builder::CurveBuilder,
insert::Insert,
objects::{Curve, Objects, Surface}, objects::{Curve, Objects, Surface},
partial::HasPartial, partial::HasPartial,
path::GlobalPath, path::GlobalPath,
@ -215,7 +216,8 @@ mod tests {
let curve = Curve::partial() let curve = Curve::partial()
.with_surface(Some(surface)) .with_surface(Some(surface))
.update_as_line_from_points([[1., 1.], [2., 1.]]) .update_as_line_from_points([[1., 1.], [2., 1.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let range = RangeOnPath::from([[0.], [1.]]); let range = RangeOnPath::from([[0.], [1.]]);
let approx = (&curve, range).approx(1.); let approx = (&curve, range).approx(1.);
@ -236,7 +238,8 @@ mod tests {
let curve = Curve::partial() let curve = Curve::partial()
.with_surface(Some(surface)) .with_surface(Some(surface))
.update_as_line_from_points([[1., 1.], [1., 2.]]) .update_as_line_from_points([[1., 1.], [1., 2.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let range = RangeOnPath::from([[0.], [1.]]); let range = RangeOnPath::from([[0.], [1.]]);
let approx = (&curve, range).approx(1.); let approx = (&curve, range).approx(1.);
@ -255,7 +258,8 @@ mod tests {
let curve = Curve::partial() let curve = Curve::partial()
.with_surface(Some(surface.clone())) .with_surface(Some(surface.clone()))
.update_as_line_from_points([[0., 1.], [1., 1.]]) .update_as_line_from_points([[0., 1.], [1., 1.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let range = RangeOnPath::from([[0.], [TAU]]); let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.; let tolerance = 1.;
@ -287,7 +291,8 @@ mod tests {
let curve = Curve::partial() let curve = Curve::partial()
.with_surface(Some(surface)) .with_surface(Some(surface))
.update_as_circle_from_radius(1.) .update_as_circle_from_radius(1.)
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let range = RangeOnPath::from([[0.], [TAU]]); let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.; let tolerance = 1.;

View File

@ -68,8 +68,10 @@ mod tests {
use crate::{ use crate::{
algorithms::intersect::CurveFaceIntersection, algorithms::intersect::CurveFaceIntersection,
builder::{CurveBuilder, FaceBuilder}, builder::{CurveBuilder, FaceBuilder},
insert::Insert,
objects::{Curve, Face, Objects}, objects::{Curve, Face, Objects},
partial::HasPartial, partial::HasPartial,
validate::ValidationError,
}; };
use super::FaceFaceIntersection; use super::FaceFaceIntersection;
@ -122,12 +124,14 @@ mod tests {
let intersection = FaceFaceIntersection::compute([&a, &b], &objects)?; let intersection = FaceFaceIntersection::compute([&a, &b], &objects)?;
let expected_curves = surfaces.try_map_ext(|surface| { let expected_curves =
Curve::partial() surfaces.try_map_ext(|surface| -> Result<_, ValidationError> {
.with_surface(Some(surface)) Ok(Curve::partial()
.update_as_line_from_points([[0., 0.], [1., 0.]]) .with_surface(Some(surface))
.build(&objects) .update_as_line_from_points([[0., 0.], [1., 0.]])
})?; .build(&objects)?
.insert(&objects)?)
})?;
let expected_intervals = let expected_intervals =
CurveFaceIntersection::from_intervals([[[-1.], [1.]]]); CurveFaceIntersection::from_intervals([[[-1.], [1.]]]);
assert_eq!( assert_eq!(

View File

@ -137,6 +137,7 @@ mod tests {
use crate::{ use crate::{
algorithms::intersect::{face_point::FacePointIntersection, Intersect}, algorithms::intersect::{face_point::FacePointIntersection, Intersect},
builder::FaceBuilder, builder::FaceBuilder,
insert::Insert,
iter::ObjectIters, iter::ObjectIters,
objects::{Face, Objects}, objects::{Face, Objects},
partial::HasPartial, partial::HasPartial,
@ -150,7 +151,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 1.], [0., 2.]]) .with_exterior_polygon_from_points([[0., 0.], [1., 1.], [0., 2.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([2., 1.]); let point = Point::from([2., 1.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();
@ -167,7 +169,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([[0., 0.], [2., 1.], [0., 2.]]) .with_exterior_polygon_from_points([[0., 0.], [2., 1.], [0., 2.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([1., 1.]); let point = Point::from([1., 1.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();
@ -187,7 +190,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([[4., 2.], [0., 4.], [0., 0.]]) .with_exterior_polygon_from_points([[4., 2.], [0., 4.], [0., 0.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([1., 2.]); let point = Point::from([1., 2.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();
@ -212,7 +216,8 @@ mod tests {
[3., 0.], [3., 0.],
[3., 4.], [3., 4.],
]) ])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([1., 1.]); let point = Point::from([1., 1.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();
@ -238,7 +243,8 @@ mod tests {
[3., 1.], [3., 1.],
[0., 2.], [0., 2.],
]) ])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([1., 1.]); let point = Point::from([1., 1.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();
@ -265,7 +271,8 @@ mod tests {
[4., 0.], [4., 0.],
[4., 5.], [4., 5.],
]) ])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([1., 1.]); let point = Point::from([1., 1.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();
@ -285,7 +292,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([[0., 0.], [2., 0.], [0., 1.]]) .with_exterior_polygon_from_points([[0., 0.], [2., 0.], [0., 1.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([1., 0.]); let point = Point::from([1., 0.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();
@ -314,7 +322,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let point = Point::from([1., 0.]); let point = Point::from([1., 0.]);
let intersection = (&face, &point).intersect(); let intersection = (&face, &point).intersect();

View File

@ -153,6 +153,7 @@ mod tests {
transform::TransformObject, transform::TransformObject,
}, },
builder::FaceBuilder, builder::FaceBuilder,
insert::Insert,
iter::ObjectIters, iter::ObjectIters,
objects::{Face, Objects}, objects::{Face, Objects},
partial::HasPartial, partial::HasPartial,
@ -174,6 +175,7 @@ mod tests {
[-1., 1.], [-1., 1.],
]) ])
.build(&objects)? .build(&objects)?
.insert(&objects)?
.translate([-1., 0., 0.], &objects)?; .translate([-1., 0., 0.], &objects)?;
assert_eq!((&ray, &face).intersect(), None); assert_eq!((&ray, &face).intersect(), None);
@ -196,6 +198,7 @@ mod tests {
[-1., 1.], [-1., 1.],
]) ])
.build(&objects)? .build(&objects)?
.insert(&objects)?
.translate([1., 0., 0.], &objects)?; .translate([1., 0., 0.], &objects)?;
assert_eq!( assert_eq!(
@ -221,6 +224,7 @@ mod tests {
[-1., 1.], [-1., 1.],
]) ])
.build(&objects)? .build(&objects)?
.insert(&objects)?
.translate([0., 0., 2.], &objects)?; .translate([0., 0., 2.], &objects)?;
assert_eq!((&ray, &face).intersect(), None); assert_eq!((&ray, &face).intersect(), None);
@ -243,6 +247,7 @@ mod tests {
[-1., 1.], [-1., 1.],
]) ])
.build(&objects)? .build(&objects)?
.insert(&objects)?
.translate([1., 1., 0.], &objects)?; .translate([1., 1., 0.], &objects)?;
let edge = face let edge = face
@ -276,6 +281,7 @@ mod tests {
[-1., 1.], [-1., 1.],
]) ])
.build(&objects)? .build(&objects)?
.insert(&objects)?
.translate([1., 1., 1.], &objects)?; .translate([1., 1., 1.], &objects)?;
let vertex = face let vertex = face
@ -306,7 +312,8 @@ mod tests {
[1., 1.], [1., 1.],
[-1., 1.], [-1., 1.],
]) ])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert_eq!( assert_eq!(
(&ray, &face).intersect(), (&ray, &face).intersect(),
@ -332,6 +339,7 @@ mod tests {
[-1., 1.], [-1., 1.],
]) ])
.build(&objects)? .build(&objects)?
.insert(&objects)?
.translate([0., 0., 1.], &objects)?; .translate([0., 0., 1.], &objects)?;
assert_eq!((&ray, &face).intersect(), None); assert_eq!((&ray, &face).intersect(), None);

View File

@ -93,6 +93,7 @@ mod tests {
use crate::{ use crate::{
algorithms::transform::TransformObject, algorithms::transform::TransformObject,
builder::CurveBuilder, builder::CurveBuilder,
insert::Insert,
objects::{Curve, Objects}, objects::{Curve, Objects},
partial::HasPartial, partial::HasPartial,
}; };
@ -124,11 +125,13 @@ mod tests {
let expected_xy = Curve::partial() let expected_xy = Curve::partial()
.with_surface(Some(xy.clone())) .with_surface(Some(xy.clone()))
.update_as_u_axis() .update_as_u_axis()
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let expected_xz = Curve::partial() let expected_xz = Curve::partial()
.with_surface(Some(xz.clone())) .with_surface(Some(xz.clone()))
.update_as_u_axis() .update_as_u_axis()
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert_eq!( assert_eq!(
SurfaceSurfaceIntersection::compute([xy, xz], &objects)?, SurfaceSurfaceIntersection::compute([xy, xz], &objects)?,

View File

@ -1,4 +1,5 @@
use crate::{ use crate::{
insert::Insert,
objects::{Face, Objects}, objects::{Face, Objects},
partial::HasPartial, partial::HasPartial,
storage::Handle, storage::Handle,
@ -15,10 +16,11 @@ impl Reverse for Handle<Face> {
.map(|cycle| cycle.clone().reverse(objects)) .map(|cycle| cycle.clone().reverse(objects))
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
Face::partial() Ok(Face::partial()
.with_exterior(exterior) .with_exterior(exterior)
.with_interiors(interiors) .with_interiors(interiors)
.with_color(self.color()) .with_color(self.color())
.build(objects) .build(objects)?
.insert(objects)?)
} }
} }

View File

@ -3,6 +3,7 @@ use fj_math::{Line, Scalar, Vector};
use crate::{ use crate::{
algorithms::{reverse::Reverse, transform::TransformObject}, algorithms::{reverse::Reverse, transform::TransformObject},
insert::Insert,
objects::{ objects::{
Curve, Cycle, Face, GlobalEdge, HalfEdge, Objects, SurfaceVertex, Curve, Cycle, Face, GlobalEdge, HalfEdge, Objects, SurfaceVertex,
Vertex, Vertex,
@ -176,10 +177,11 @@ impl Sweep for (Handle<HalfEdge>, Color) {
objects.cycles.insert(Cycle::new(edges))? objects.cycles.insert(Cycle::new(edges))?
}; };
Face::partial() Ok(Face::partial()
.with_exterior(cycle) .with_exterior(cycle)
.with_color(color) .with_color(color)
.build(objects) .build(objects)?
.insert(objects)?)
} }
} }
@ -191,6 +193,7 @@ mod tests {
use crate::{ use crate::{
algorithms::{reverse::Reverse, sweep::Sweep}, algorithms::{reverse::Reverse, sweep::Sweep},
builder::HalfEdgeBuilder, builder::HalfEdgeBuilder,
insert::Insert,
objects::{Cycle, Face, HalfEdge, Objects, SurfaceVertex, Vertex}, objects::{Cycle, Face, HalfEdge, Objects, SurfaceVertex, Vertex},
partial::HasPartial, partial::HasPartial,
}; };
@ -204,7 +207,8 @@ mod tests {
objects.surfaces.xy_plane(), objects.surfaces.xy_plane(),
[[0., 0.], [1., 0.]], [[0., 0.], [1., 0.]],
) )
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let face = let face =
(half_edge, Color::default()).sweep([0., 0., 1.], &objects)?; (half_edge, Color::default()).sweep([0., 0., 1.], &objects)?;
@ -218,7 +222,8 @@ mod tests {
surface.clone(), surface.clone(),
[[0., 0.], [1., 0.]], [[0., 0.], [1., 0.]],
) )
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let side_up = HalfEdge::partial() let side_up = HalfEdge::partial()
.with_surface(surface.clone()) .with_surface(surface.clone())
.with_back_vertex(Vertex::partial().with_surface_form( .with_back_vertex(Vertex::partial().with_surface_form(
@ -228,7 +233,8 @@ mod tests {
SurfaceVertex::partial().with_position(Some([1., 1.])), SurfaceVertex::partial().with_position(Some([1., 1.])),
)) ))
.update_as_line_segment() .update_as_line_segment()
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let top = HalfEdge::partial() let top = HalfEdge::partial()
.with_surface(surface.clone()) .with_surface(surface.clone())
.with_back_vertex(Vertex::partial().with_surface_form( .with_back_vertex(Vertex::partial().with_surface_form(
@ -239,6 +245,7 @@ mod tests {
)) ))
.update_as_line_segment() .update_as_line_segment()
.build(&objects)? .build(&objects)?
.insert(&objects)?
.reverse(&objects)?; .reverse(&objects)?;
let side_down = let side_down =
HalfEdge::partial() HalfEdge::partial()
@ -251,13 +258,17 @@ mod tests {
)) ))
.update_as_line_segment() .update_as_line_segment()
.build(&objects)? .build(&objects)?
.insert(&objects)?
.reverse(&objects)?; .reverse(&objects)?;
let cycle = objects let cycle = objects
.cycles .cycles
.insert(Cycle::new([bottom, side_up, top, side_down]))?; .insert(Cycle::new([bottom, side_up, top, side_down]))?;
Face::partial().with_exterior(cycle).build(&objects)? Face::partial()
.with_exterior(cycle)
.build(&objects)?
.insert(&objects)?
}; };
assert_eq!(face, expected_face); assert_eq!(face, expected_face);

View File

@ -85,6 +85,7 @@ mod tests {
use crate::{ use crate::{
algorithms::{reverse::Reverse, transform::TransformObject}, algorithms::{reverse::Reverse, transform::TransformObject},
builder::{FaceBuilder, HalfEdgeBuilder}, builder::{FaceBuilder, HalfEdgeBuilder},
insert::Insert,
objects::{Face, HalfEdge, Objects, Sketch}, objects::{Face, HalfEdge, Objects, Sketch},
partial::HasPartial, partial::HasPartial,
}; };
@ -111,11 +112,13 @@ mod tests {
.with_surface(surface.clone()) .with_surface(surface.clone())
.with_exterior_polygon_from_points(TRIANGLE) .with_exterior_polygon_from_points(TRIANGLE)
.build(&objects)? .build(&objects)?
.insert(&objects)?
.reverse(&objects)?; .reverse(&objects)?;
let top = Face::partial() let top = Face::partial()
.with_surface(surface.translate(UP, &objects)?) .with_surface(surface.translate(UP, &objects)?)
.with_exterior_polygon_from_points(TRIANGLE) .with_exterior_polygon_from_points(TRIANGLE)
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert!(solid.find_face(&bottom).is_some()); assert!(solid.find_face(&bottom).is_some());
assert!(solid.find_face(&top).is_some()); assert!(solid.find_face(&top).is_some());
@ -129,7 +132,8 @@ mod tests {
objects.surfaces.xy_plane(), objects.surfaces.xy_plane(),
[a, b], [a, b],
) )
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
(half_edge, Color::default()).sweep(UP, &objects) (half_edge, Color::default()).sweep(UP, &objects)
}) })
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
@ -155,11 +159,13 @@ mod tests {
.with_surface(surface.clone().translate(DOWN, &objects)?) .with_surface(surface.clone().translate(DOWN, &objects)?)
.with_exterior_polygon_from_points(TRIANGLE) .with_exterior_polygon_from_points(TRIANGLE)
.build(&objects)? .build(&objects)?
.insert(&objects)?
.reverse(&objects)?; .reverse(&objects)?;
let top = Face::partial() let top = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points(TRIANGLE) .with_exterior_polygon_from_points(TRIANGLE)
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert!(solid.find_face(&bottom).is_some()); assert!(solid.find_face(&bottom).is_some());
assert!(solid.find_face(&top).is_some()); assert!(solid.find_face(&top).is_some());
@ -174,6 +180,7 @@ mod tests {
[a, b], [a, b],
) )
.build(&objects)? .build(&objects)?
.insert(&objects)?
.reverse(&objects)?; .reverse(&objects)?;
(half_edge, Color::default()).sweep(DOWN, &objects) (half_edge, Color::default()).sweep(DOWN, &objects)
}) })

View File

@ -169,6 +169,7 @@ mod tests {
use crate::{ use crate::{
algorithms::sweep::Sweep, algorithms::sweep::Sweep,
builder::{CurveBuilder, HalfEdgeBuilder}, builder::{CurveBuilder, HalfEdgeBuilder},
insert::Insert,
objects::{Curve, HalfEdge, Objects, Vertex}, objects::{Curve, HalfEdge, Objects, Vertex},
partial::HasPartial, partial::HasPartial,
}; };
@ -181,18 +182,21 @@ mod tests {
let curve = Curve::partial() let curve = Curve::partial()
.with_surface(Some(surface.clone())) .with_surface(Some(surface.clone()))
.update_as_u_axis() .update_as_u_axis()
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let vertex = Vertex::partial() let vertex = Vertex::partial()
.with_position(Some([0.])) .with_position(Some([0.]))
.with_curve(curve) .with_curve(curve)
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let half_edge = let half_edge =
(vertex, surface.clone()).sweep([0., 0., 1.], &objects)?; (vertex, surface.clone()).sweep([0., 0., 1.], &objects)?;
let expected_half_edge = HalfEdge::partial() let expected_half_edge = HalfEdge::partial()
.update_as_line_segment_from_points(surface, [[0., 0.], [0., 1.]]) .update_as_line_segment_from_points(surface, [[0., 0.], [0., 1.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert_eq!(half_edge, expected_half_edge); assert_eq!(half_edge, expected_half_edge);
Ok(()) Ok(())
} }

View File

@ -1,6 +1,7 @@
use fj_math::Transform; use fj_math::Transform;
use crate::{ use crate::{
insert::Insert,
objects::{Face, FaceSet, Objects}, objects::{Face, FaceSet, Objects},
partial::{HasPartial, PartialFace}, partial::{HasPartial, PartialFace},
validate::ValidationError, validate::ValidationError,
@ -26,11 +27,12 @@ impl TransformObject for PartialFace {
let interiors = self let interiors = self
.interiors() .interiors()
.map(|cycle| -> Result<_, ValidationError> { .map(|cycle| -> Result<_, ValidationError> {
cycle Ok(cycle
.into_partial() .into_partial()
.transform(transform, objects)? .transform(transform, objects)?
.with_surface(surface.clone()) .with_surface(surface.clone())
.build(objects) .build(objects)?
.insert(objects)?)
}) })
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;

View File

@ -13,10 +13,11 @@ mod vertex;
use fj_math::{Transform, Vector}; use fj_math::{Transform, Vector};
use crate::{ use crate::{
insert::Insert,
objects::Objects, objects::Objects,
partial::{HasPartial, MaybePartial, Partial}, partial::{HasPartial, MaybePartial, Partial},
storage::Handle, storage::Handle,
validate::ValidationError, validate::{Validate, ValidationError},
}; };
/// Transform an object /// Transform an object
@ -61,17 +62,20 @@ pub trait TransformObject: Sized {
impl<T> TransformObject for Handle<T> impl<T> TransformObject for Handle<T>
where where
T: HasPartial, T: HasPartial + Insert,
T::Partial: TransformObject, T::Partial: TransformObject,
ValidationError: From<<T as Validate>::Error>,
{ {
fn transform( fn transform(
self, self,
transform: &Transform, transform: &Transform,
objects: &Objects, objects: &Objects,
) -> Result<Self, ValidationError> { ) -> Result<Self, ValidationError> {
self.to_partial() Ok(self
.to_partial()
.transform(transform, objects)? .transform(transform, objects)?
.build(objects) .build(objects)?
.insert(objects)?)
} }
} }

View File

@ -85,6 +85,7 @@ mod tests {
use crate::{ use crate::{
algorithms::approx::{Approx, Tolerance}, algorithms::approx::{Approx, Tolerance},
builder::FaceBuilder, builder::FaceBuilder,
insert::Insert,
objects::{Face, Objects}, objects::{Face, Objects},
partial::HasPartial, partial::HasPartial,
storage::Handle, storage::Handle,
@ -105,7 +106,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([a, b, c, d]) .with_exterior_polygon_from_points([a, b, c, d])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let a = Point::from(a).to_xyz(); let a = Point::from(a).to_xyz();
let b = Point::from(b).to_xyz(); let b = Point::from(b).to_xyz();
@ -141,7 +143,8 @@ mod tests {
.with_surface(surface.clone()) .with_surface(surface.clone())
.with_exterior_polygon_from_points([a, b, c, d]) .with_exterior_polygon_from_points([a, b, c, d])
.with_interior_polygon_from_points([e, f, g, h]) .with_interior_polygon_from_points([e, f, g, h])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let triangles = triangulate(face)?; let triangles = triangulate(face)?;
@ -201,7 +204,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface.clone()) .with_surface(surface.clone())
.with_exterior_polygon_from_points([a, b, c, d, e]) .with_exterior_polygon_from_points([a, b, c, d, e])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let triangles = triangulate(face)?; let triangles = triangulate(face)?;

View File

@ -2,6 +2,7 @@ use fj_interop::ext::ArrayExt;
use fj_math::{Point, Scalar}; use fj_math::{Point, Scalar};
use crate::{ use crate::{
insert::Insert,
objects::{ objects::{
Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex, Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex,
VerticesInNormalizedOrder, VerticesInNormalizedOrder,
@ -89,7 +90,8 @@ impl HalfEdgeBuilder for PartialHalfEdge {
.with_position(Some(path.point_from_path_coords(a_curve))) .with_position(Some(path.point_from_path_coords(a_curve)))
.with_surface(curve.surface()) .with_surface(curve.surface())
.with_global_form(Some(global_vertex)) .with_global_form(Some(global_vertex))
.build(objects)?; .build(objects)?
.insert(objects)?;
let [back, front] = [a_curve, b_curve].map(|point_curve| { let [back, front] = [a_curve, b_curve].map(|point_curve| {
Vertex::partial() Vertex::partial()

View File

@ -6,6 +6,7 @@ use fj_math::Scalar;
use crate::{ use crate::{
algorithms::transform::TransformObject, algorithms::transform::TransformObject,
builder::{FaceBuilder, HalfEdgeBuilder}, builder::{FaceBuilder, HalfEdgeBuilder},
insert::Insert,
objects::{ objects::{
Curve, Cycle, Face, FaceSet, HalfEdge, Objects, Shell, Surface, Curve, Cycle, Face, FaceSet, HalfEdge, Objects, Shell, Surface,
SurfaceVertex, Vertex, SurfaceVertex, Vertex,
@ -64,6 +65,8 @@ impl<'a> ShellBuilder<'a> {
]) ])
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}; };
let (sides, top_edges) = { let (sides, top_edges) = {
@ -97,6 +100,8 @@ impl<'a> ShellBuilder<'a> {
) )
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -120,6 +125,8 @@ impl<'a> ShellBuilder<'a> {
.update_as_line_segment() .update_as_line_segment()
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -157,6 +164,8 @@ impl<'a> ShellBuilder<'a> {
.update_as_line_segment() .update_as_line_segment()
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
}; };
@ -180,6 +189,8 @@ impl<'a> ShellBuilder<'a> {
.update_as_line_segment() .update_as_line_segment()
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -192,12 +203,16 @@ impl<'a> ShellBuilder<'a> {
let cycle = Cycle::partial() let cycle = Cycle::partial()
.with_half_edges([bottom, side_up, top, side_down]) .with_half_edges([bottom, side_up, top, side_down])
.build(self.objects) .build(self.objects)
.unwrap()
.insert(self.objects)
.unwrap(); .unwrap();
Face::partial() Face::partial()
.with_exterior(cycle) .with_exterior(cycle)
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}); });
(sides, tops) (sides, tops)
@ -232,6 +247,8 @@ impl<'a> ShellBuilder<'a> {
)) ))
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}); });
[a.clone(), b, c, d, a] [a.clone(), b, c, d, a]
@ -259,6 +276,8 @@ impl<'a> ShellBuilder<'a> {
.with_global_form(edge.global_form().clone()) .with_global_form(edge.global_form().clone())
.update_as_line_segment() .update_as_line_segment()
.build(self.objects) .build(self.objects)
.unwrap()
.insert(self.objects)
.unwrap(), .unwrap(),
); );
} }
@ -269,6 +288,8 @@ impl<'a> ShellBuilder<'a> {
) )
.build(self.objects) .build(self.objects)
.unwrap() .unwrap()
.insert(self.objects)
.unwrap()
}; };
self.faces.extend([bottom]); self.faces.extend([bottom]);

View File

@ -1,6 +1,7 @@
use fj_math::Point; use fj_math::Point;
use crate::{ use crate::{
insert::Insert,
objects::{Face, FaceSet, Objects, Sketch, Surface}, objects::{Face, FaceSet, Objects, Sketch, Surface},
partial::HasPartial, partial::HasPartial,
storage::Handle, storage::Handle,
@ -51,6 +52,8 @@ impl<'a> SketchBuilder<'a> {
.with_surface(surface.clone()) .with_surface(surface.clone())
.with_exterior_polygon_from_points(points) .with_exterior_polygon_from_points(points)
.build(self.objects) .build(self.objects)
.unwrap()
.insert(self.objects)
.unwrap()]); .unwrap()]);
self self
} }

View File

@ -361,6 +361,7 @@ impl<T> Iterator for Iter<T> {
mod tests { mod tests {
use crate::{ use crate::{
builder::{CurveBuilder, CycleBuilder, FaceBuilder, HalfEdgeBuilder}, builder::{CurveBuilder, CycleBuilder, FaceBuilder, HalfEdgeBuilder},
insert::Insert,
objects::{ objects::{
Curve, Cycle, Face, GlobalCurve, GlobalVertex, HalfEdge, Objects, Curve, Cycle, Face, GlobalCurve, GlobalVertex, HalfEdge, Objects,
Shell, Sketch, Solid, SurfaceVertex, Vertex, Shell, Sketch, Solid, SurfaceVertex, Vertex,
@ -378,7 +379,8 @@ mod tests {
let object = Curve::partial() let object = Curve::partial()
.with_surface(Some(surface)) .with_surface(Some(surface))
.update_as_u_axis() .update_as_u_axis()
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert_eq!(1, object.curve_iter().count()); assert_eq!(1, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count()); assert_eq!(0, object.cycle_iter().count());
@ -406,7 +408,8 @@ mod tests {
[[0., 0.], [1., 0.], [0., 1.]], [[0., 0.], [1., 0.], [0., 1.]],
) )
.close_with_line_segment() .close_with_line_segment()
.build(&objects)?; .build(&objects)?
.insert(&objects);
assert_eq!(3, object.curve_iter().count()); assert_eq!(3, object.curve_iter().count());
assert_eq!(1, object.cycle_iter().count()); assert_eq!(1, object.cycle_iter().count());
@ -431,7 +434,8 @@ mod tests {
let object = Face::partial() let object = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert_eq!(3, object.curve_iter().count()); assert_eq!(3, object.curve_iter().count());
assert_eq!(1, object.cycle_iter().count()); assert_eq!(1, object.cycle_iter().count());
@ -501,7 +505,8 @@ mod tests {
objects.surfaces.xy_plane(), objects.surfaces.xy_plane(),
[[0., 0.], [1., 0.]], [[0., 0.], [1., 0.]],
) )
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
assert_eq!(1, object.curve_iter().count()); assert_eq!(1, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count()); assert_eq!(0, object.cycle_iter().count());
@ -547,7 +552,8 @@ mod tests {
let face = Face::partial() let face = Face::partial()
.with_surface(surface) .with_surface(surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]]) .with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]])
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let object = Sketch::builder(&objects).with_faces([face]).build(); let object = Sketch::builder(&objects).with_faces([face]).build();
assert_eq!(3, object.curve_iter().count()); assert_eq!(3, object.curve_iter().count());
@ -613,7 +619,8 @@ mod tests {
let curve = Curve::partial() let curve = Curve::partial()
.with_surface(Some(surface.clone())) .with_surface(Some(surface.clone()))
.update_as_u_axis() .update_as_u_axis()
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
let global_vertex = objects let global_vertex = objects
.global_vertices .global_vertices
.insert(GlobalVertex::from_position([0., 0., 0.]))?; .insert(GlobalVertex::from_position([0., 0., 0.]))?;

View File

@ -1,13 +1,14 @@
use fj_math::Point; use fj_math::Point;
use crate::{ use crate::{
insert::Insert,
objects::{ objects::{
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects, Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
Surface, SurfaceVertex, Vertex, Surface, SurfaceVertex, Vertex,
}, },
path::SurfacePath, path::SurfacePath,
storage::Handle, storage::Handle,
validate::ValidationError, validate::{Validate, ValidationError},
}; };
use super::{HasPartial, Partial}; use super::{HasPartial, Partial};
@ -91,9 +92,15 @@ impl<T: HasPartial> MaybePartial<T> {
pub fn into_full( pub fn into_full(
self, self,
objects: &Objects, objects: &Objects,
) -> Result<Handle<T>, ValidationError> { ) -> Result<Handle<T>, ValidationError>
where
T: Insert,
ValidationError: From<<T as Validate>::Error>,
{
match self { match self {
Self::Partial(partial) => partial.build(objects), Self::Partial(partial) => {
Ok(partial.build(objects)?.insert(objects)?)
}
Self::Full(full) => Ok(full), Self::Full(full) => Ok(full),
} }
} }

View File

@ -80,10 +80,7 @@ impl PartialCurve {
} }
/// Build a full [`Curve`] from the partial curve /// Build a full [`Curve`] from the partial curve
pub fn build( pub fn build(self, objects: &Objects) -> Result<Curve, ValidationError> {
self,
objects: &Objects,
) -> Result<Handle<Curve>, ValidationError> {
let path = self.path.expect("Can't build `Curve` without path"); let path = self.path.expect("Can't build `Curve` without path");
let surface = let surface =
self.surface.expect("Can't build `Curve` without surface"); self.surface.expect("Can't build `Curve` without surface");
@ -94,9 +91,7 @@ impl PartialCurve {
} }
.into_full(objects)?; .into_full(objects)?;
Ok(objects Ok(Curve::new(surface, path, global_form))
.curves
.insert(Curve::new(surface, path, global_form))?)
} }
} }
@ -128,12 +123,8 @@ impl PartialGlobalCurve {
} }
/// Build a full [`GlobalCurve`] from the partial global curve /// Build a full [`GlobalCurve`] from the partial global curve
pub fn build( pub fn build(self, _: &Objects) -> Result<GlobalCurve, ValidationError> {
self, Ok(GlobalCurve)
objects: &Objects,
) -> Result<Handle<GlobalCurve>, ValidationError> {
let global_curve = objects.global_curves.insert(GlobalCurve)?;
Ok(global_curve)
} }
} }

View File

@ -86,7 +86,7 @@ impl PartialCycle {
pub fn build( pub fn build(
mut self, mut self,
objects: &Objects, objects: &Objects,
) -> Result<Handle<Cycle>, ValidationError> { ) -> Result<Cycle, ValidationError> {
// Check that the cycle is closed. This will lead to a panic further // Check that the cycle is closed. This will lead to a panic further
// down anyway, but that panic would be super-confusing. This one should // down anyway, but that panic would be super-confusing. This one should
// be a bit more explicit on what is wrong. // be a bit more explicit on what is wrong.
@ -142,7 +142,7 @@ impl PartialCycle {
half_edges.push(half_edge); half_edges.push(half_edge);
} }
Ok(objects.cycles.insert(Cycle::new(half_edges))?) Ok(Cycle::new(half_edges))
} }
} }

View File

@ -102,10 +102,7 @@ impl PartialHalfEdge {
} }
/// Build a full [`HalfEdge`] from the partial half-edge /// Build a full [`HalfEdge`] from the partial half-edge
pub fn build( pub fn build(self, objects: &Objects) -> Result<HalfEdge, ValidationError> {
self,
objects: &Objects,
) -> Result<Handle<HalfEdge>, ValidationError> {
let curve = self.curve.into_full(objects)?; let curve = self.curve.into_full(objects)?;
let vertices = self.vertices.try_map_ext(|vertex| { let vertices = self.vertices.try_map_ext(|vertex| {
vertex vertex
@ -120,9 +117,7 @@ impl PartialHalfEdge {
}) })
.into_full(objects)?; .into_full(objects)?;
Ok(objects Ok(HalfEdge::new(vertices, global_form))
.half_edges
.insert(HalfEdge::new(vertices, global_form))?)
} }
} }
@ -202,16 +197,14 @@ impl PartialGlobalEdge {
pub fn build( pub fn build(
self, self,
objects: &Objects, objects: &Objects,
) -> Result<Handle<GlobalEdge>, ValidationError> { ) -> Result<GlobalEdge, ValidationError> {
let curve = self.curve.into_full(objects)?; let curve = self.curve.into_full(objects)?;
let vertices = self let vertices = self
.vertices .vertices
.expect("Can't build `GlobalEdge` without vertices") .expect("Can't build `GlobalEdge` without vertices")
.try_map_ext(|global_vertex| global_vertex.into_full(objects))?; .try_map_ext(|global_vertex| global_vertex.into_full(objects))?;
Ok(objects Ok(GlobalEdge::new(curve, vertices))
.global_edges
.insert(GlobalEdge::new(curve, vertices))?)
} }
} }

View File

@ -84,10 +84,7 @@ impl PartialFace {
} }
/// Construct a polygon from a list of points /// Construct a polygon from a list of points
pub fn build( pub fn build(self, objects: &Objects) -> Result<Face, ValidationError> {
self,
objects: &Objects,
) -> Result<Handle<Face>, ValidationError> {
let exterior = self.exterior.into_full(objects)?; let exterior = self.exterior.into_full(objects)?;
let interiors = self let interiors = self
.interiors .interiors
@ -96,9 +93,7 @@ impl PartialFace {
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
let color = self.color.unwrap_or_default(); let color = self.color.unwrap_or_default();
Ok(objects Ok(Face::new(exterior, interiors, color))
.faces
.insert(Face::new(exterior, interiors, color))?)
} }
} }

View File

@ -4,12 +4,9 @@ pub mod edge;
pub mod face; pub mod face;
pub mod vertex; pub mod vertex;
use crate::{ use crate::objects::{
objects::{ Curve, Cycle, Face, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge,
Curve, Cycle, Face, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects, SurfaceVertex, Vertex,
Objects, SurfaceVertex, Vertex,
},
storage::Handle,
}; };
use super::{ use super::{
@ -34,7 +31,7 @@ macro_rules! impl_traits {
fn build(self, objects: &Objects) fn build(self, objects: &Objects)
-> Result< -> Result<
Handle<Self::Full>, Self::Full,
crate::validate::ValidationError crate::validate::ValidationError
> >
{ {

View File

@ -76,10 +76,7 @@ impl PartialVertex {
/// Panics, if position has not been provided. /// Panics, if position has not been provided.
/// ///
/// Panics, if curve has not been provided. /// Panics, if curve has not been provided.
pub fn build( pub fn build(self, objects: &Objects) -> Result<Vertex, ValidationError> {
self,
objects: &Objects,
) -> Result<Handle<Vertex>, ValidationError> {
let position = self let position = self
.position .position
.expect("Cant' build `Vertex` without position"); .expect("Cant' build `Vertex` without position");
@ -98,11 +95,7 @@ impl PartialVertex {
}) })
.into_full(objects)?; .into_full(objects)?;
Ok(objects.vertices.insert(Vertex::new( Ok(Vertex::new(position, curve, surface_form))
position,
curve,
surface_form,
))?)
} }
} }
@ -185,7 +178,7 @@ impl PartialSurfaceVertex {
pub fn build( pub fn build(
self, self,
objects: &Objects, objects: &Objects,
) -> Result<Handle<SurfaceVertex>, ValidationError> { ) -> Result<SurfaceVertex, ValidationError> {
let position = self let position = self
.position .position
.expect("Can't build `SurfaceVertex` without position"); .expect("Can't build `SurfaceVertex` without position");
@ -200,11 +193,7 @@ impl PartialSurfaceVertex {
}) })
.into_full(objects)?; .into_full(objects)?;
Ok(objects.surface_vertices.insert(SurfaceVertex::new( Ok(SurfaceVertex::new(position, surface, global_form))
position,
surface,
global_form,
))?)
} }
} }
@ -251,17 +240,12 @@ impl PartialGlobalVertex {
} }
/// Build a full [`GlobalVertex`] from the partial global vertex /// Build a full [`GlobalVertex`] from the partial global vertex
pub fn build( pub fn build(self, _: &Objects) -> Result<GlobalVertex, ValidationError> {
self,
objects: &Objects,
) -> Result<Handle<GlobalVertex>, ValidationError> {
let position = self let position = self
.position .position
.expect("Can't build a `GlobalVertex` without a position"); .expect("Can't build a `GlobalVertex` without a position");
Ok(objects Ok(GlobalVertex::from_position(position))
.global_vertices
.insert(GlobalVertex::from_position(position))?)
} }
} }

View File

@ -1,4 +1,4 @@
use crate::{objects::Objects, storage::Handle, validate::ValidationError}; use crate::{objects::Objects, validate::ValidationError};
/// Implemented for objects that a partial object type exists for /// Implemented for objects that a partial object type exists for
/// ///
@ -80,8 +80,5 @@ pub trait Partial: Default + for<'a> From<&'a Self::Full> {
/// Calling `build` on a partial object that can't infer its missing parts /// Calling `build` on a partial object that can't infer its missing parts
/// is considered a programmer error, hence why this method doesn't return a /// is considered a programmer error, hence why this method doesn't return a
/// [`Result`]. /// [`Result`].
fn build( fn build(self, objects: &Objects) -> Result<Self::Full, ValidationError>;
self,
objects: &Objects,
) -> Result<Handle<Self::Full>, ValidationError>;
} }

View File

@ -67,9 +67,10 @@ impl CycleValidationError {
mod tests { mod tests {
use crate::{ use crate::{
builder::{CycleBuilder, HalfEdgeBuilder, VertexBuilder}, builder::{CycleBuilder, HalfEdgeBuilder, VertexBuilder},
insert::Insert,
objects::{Cycle, Objects}, objects::{Cycle, Objects},
partial::HasPartial, partial::HasPartial,
validate::Validate, validate::{Validate, ValidationError},
}; };
#[test] #[test]
@ -102,7 +103,9 @@ mod tests {
let half_edges = half_edges let half_edges = half_edges
.into_iter() .into_iter()
.map(|half_edge| half_edge.build(&objects)) .map(|half_edge| -> anyhow::Result<_, ValidationError> {
Ok(half_edge.build(&objects)?.insert(&objects)?)
})
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
Cycle::new(half_edges) Cycle::new(half_edges)

View File

@ -202,9 +202,10 @@ mod tests {
use crate::{ use crate::{
builder::{HalfEdgeBuilder, VertexBuilder}, builder::{HalfEdgeBuilder, VertexBuilder},
insert::Insert,
objects::{GlobalCurve, HalfEdge, Objects}, objects::{GlobalCurve, HalfEdge, Objects},
partial::HasPartial, partial::HasPartial,
validate::Validate, validate::{Validate, ValidationError},
}; };
#[test] #[test]
@ -223,7 +224,8 @@ mod tests {
.to_partial() .to_partial()
// Arranging for an equal but not identical curve here. // Arranging for an equal but not identical curve here.
.with_curve(valid.curve().to_partial()) .with_curve(valid.curve().to_partial())
.build(&objects)?; .build(&objects)?
.insert(&objects)?;
HalfEdge::new(vertices, valid.global_form().clone()) HalfEdge::new(vertices, valid.global_form().clone())
}; };
@ -250,7 +252,8 @@ mod tests {
.global_form() .global_form()
.to_partial() .to_partial()
.with_curve(Some(objects.global_curves.insert(GlobalCurve)?)) .with_curve(Some(objects.global_curves.insert(GlobalCurve)?))
.build(&objects)?, .build(&objects)?
.insert(&objects)?,
); );
assert!(valid.validate().is_ok()); assert!(valid.validate().is_ok());
@ -282,7 +285,8 @@ mod tests {
// Creating equal but not identical vertices here. // Creating equal but not identical vertices here.
.map(|vertex| vertex.to_partial()), .map(|vertex| vertex.to_partial()),
)) ))
.build(&objects)?, .build(&objects)?
.insert(&objects)?,
); );
assert!(valid.validate().is_ok()); assert!(valid.validate().is_ok());
@ -302,13 +306,16 @@ mod tests {
) )
.build(&objects)?; .build(&objects)?;
let invalid = HalfEdge::new( let invalid = HalfEdge::new(
valid.vertices().clone().try_map_ext(|vertex| { valid.vertices().clone().try_map_ext(
vertex |vertex| -> anyhow::Result<_, ValidationError> {
.to_partial() Ok(vertex
.with_position(Some([0.])) .to_partial()
.infer_surface_form() .with_position(Some([0.]))
.build(&objects) .infer_surface_form()
})?, .build(&objects)?
.insert(&objects)?)
},
)?,
valid.global_form().clone(), valid.global_form().clone(),
); );

View File

@ -106,6 +106,7 @@ mod tests {
use crate::{ use crate::{
algorithms::reverse::Reverse, algorithms::reverse::Reverse,
builder::{CycleBuilder, FaceBuilder}, builder::{CycleBuilder, FaceBuilder},
insert::Insert,
objects::{Cycle, Face, Objects}, objects::{Cycle, Face, Objects},
partial::HasPartial, partial::HasPartial,
validate::Validate, validate::Validate,
@ -127,7 +128,8 @@ mod tests {
[[1., 1.], [1., 2.], [2., 1.]], [[1., 1.], [1., 2.], [2., 1.]],
) )
.close_with_line_segment() .close_with_line_segment()
.build(&objects)?]; .build(&objects)?
.insert(&objects)?];
Face::new(valid.exterior().clone(), interiors, valid.color()) Face::new(valid.exterior().clone(), interiors, valid.color())
}; };

View File

@ -180,6 +180,7 @@ impl SurfaceVertexValidationError {
mod tests { mod tests {
use crate::{ use crate::{
builder::{CurveBuilder, SurfaceVertexBuilder}, builder::{CurveBuilder, SurfaceVertexBuilder},
insert::Insert,
objects::{Curve, GlobalVertex, Objects, SurfaceVertex, Vertex}, objects::{Curve, GlobalVertex, Objects, SurfaceVertex, Vertex},
partial::HasPartial, partial::HasPartial,
validate::Validate, validate::Validate,
@ -204,7 +205,8 @@ mod tests {
.surface_form() .surface_form()
.to_partial() .to_partial()
.with_surface(Some(objects.surfaces.xz_plane())) .with_surface(Some(objects.surfaces.xz_plane()))
.build(&objects)?, .build(&objects)?
.insert(&objects)?,
); );
assert!(valid.validate().is_ok()); assert!(valid.validate().is_ok());
@ -233,7 +235,8 @@ mod tests {
.to_partial() .to_partial()
.with_position(Some([1., 0.])) .with_position(Some([1., 0.]))
.infer_global_form() .infer_global_form()
.build(&objects)?, .build(&objects)?
.insert(&objects)?,
); );
assert!(valid.validate().is_ok()); assert!(valid.validate().is_ok());

View File

@ -3,6 +3,7 @@ use std::ops::Deref;
use fj_interop::{debug::DebugInfo, ext::ArrayExt, mesh::Color}; use fj_interop::{debug::DebugInfo, ext::ArrayExt, mesh::Color};
use fj_kernel::{ use fj_kernel::{
algorithms::reverse::Reverse, algorithms::reverse::Reverse,
insert::Insert,
iter::ObjectIters, iter::ObjectIters,
objects::{Face, Objects, Sketch}, objects::{Face, Objects, Sketch},
partial::HasPartial, partial::HasPartial,
@ -83,7 +84,8 @@ impl Shape for fj::Difference2d {
.with_exterior(exterior) .with_exterior(exterior)
.with_interiors(interiors) .with_interiors(interiors)
.with_color(Color(self.color())) .with_color(Color(self.color()))
.build(objects)?, .build(objects)?
.insert(objects)?,
); );
} }

View File

@ -3,6 +3,7 @@ use std::ops::Deref;
use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_interop::{debug::DebugInfo, mesh::Color};
use fj_kernel::{ use fj_kernel::{
builder::{FaceBuilder, HalfEdgeBuilder}, builder::{FaceBuilder, HalfEdgeBuilder},
insert::Insert,
objects::{Cycle, Face, HalfEdge, Objects, Sketch}, objects::{Cycle, Face, HalfEdge, Objects, Sketch},
partial::HasPartial, partial::HasPartial,
validate::ValidationError, validate::ValidationError,
@ -29,13 +30,15 @@ impl Shape for fj::Sketch {
let half_edge = HalfEdge::partial() let half_edge = HalfEdge::partial()
.with_surface(surface) .with_surface(surface)
.update_as_circle_from_radius(circle.radius(), objects)? .update_as_circle_from_radius(circle.radius(), objects)?
.build(objects)?; .build(objects)?
.insert(objects)?;
let cycle = objects.cycles.insert(Cycle::new([half_edge]))?; let cycle = objects.cycles.insert(Cycle::new([half_edge]))?;
Face::partial() Face::partial()
.with_exterior(cycle) .with_exterior(cycle)
.with_color(Color(self.color())) .with_color(Color(self.color()))
.build(objects)? .build(objects)?
.insert(objects)?
} }
fj::Chain::PolyChain(poly_chain) => { fj::Chain::PolyChain(poly_chain) => {
let points = let points =
@ -46,6 +49,7 @@ impl Shape for fj::Sketch {
.with_exterior_polygon_from_points(points) .with_exterior_polygon_from_points(points)
.with_color(Color(self.color())) .with_color(Color(self.color()))
.build(objects)? .build(objects)?
.insert(objects)?
} }
}; };