Merge pull request #1198 from hannobraun/objects

Rename `Stores` to `Objects`, move it to `Objects`
This commit is contained in:
Hanno Braun 2022-10-10 20:08:26 +02:00 committed by GitHub
commit bbddc4bc2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 552 additions and 528 deletions

View File

@ -14,7 +14,7 @@ use std::collections::BTreeMap;
use crate::{
objects::{Curve, GlobalCurve},
path::{GlobalPath, SurfacePath},
stores::{Handle, ObjectId},
storage::{Handle, ObjectId},
};
use super::{path::RangeOnPath, Approx, ApproxPoint, Tolerance};
@ -197,25 +197,25 @@ mod tests {
use crate::{
algorithms::approx::{path::RangeOnPath, Approx, ApproxPoint},
objects::{Curve, Surface},
objects::{Curve, Objects, Surface},
partial::HasPartial,
path::GlobalPath,
stores::{Handle, Stores},
storage::Handle,
};
use super::CurveApprox;
#[test]
fn approx_line_on_flat_surface() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores
let surface = objects
.surfaces
.insert(Surface::new(GlobalPath::x_axis(), [0., 0., 1.]));
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface))
.as_line_from_points([[1., 1.], [2., 1.]])
.build(&stores);
.build(&objects);
let range = RangeOnPath::from([[0.], [1.]]);
let approx = (&curve, range).approx(1.);
@ -225,16 +225,16 @@ mod tests {
#[test]
fn approx_line_on_curved_surface_but_not_along_curve() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::new(
let surface = objects.surfaces.insert(Surface::new(
GlobalPath::circle_from_radius(1.),
[0., 0., 1.],
));
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface))
.as_line_from_points([[1., 1.], [1., 2.]])
.build(&stores);
.build(&objects);
let range = RangeOnPath::from([[0.], [1.]]);
let approx = (&curve, range).approx(1.);
@ -244,14 +244,14 @@ mod tests {
#[test]
fn approx_line_on_curved_surface_along_curve() {
let stores = Stores::new();
let objects = Objects::new();
let path = GlobalPath::circle_from_radius(1.);
let surface = stores.surfaces.insert(Surface::new(path, [0., 0., 1.]));
let surface = objects.surfaces.insert(Surface::new(path, [0., 0., 1.]));
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_line_from_points([[0., 1.], [1., 1.]])
.build(&stores);
.build(&objects);
let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.;
@ -274,15 +274,15 @@ mod tests {
#[test]
fn approx_circle_on_flat_surface() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores
let surface = objects
.surfaces
.insert(Surface::new(GlobalPath::x_axis(), [0., 0., 1.]));
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface))
.as_circle_from_radius(1.)
.build(&stores);
.build(&objects);
let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.;

View File

@ -20,7 +20,7 @@ use std::{
use fj_math::Point;
use crate::{objects::Curve, stores::Handle};
use crate::{objects::Curve, storage::Handle};
pub use self::tolerance::{InvalidTolerance, Tolerance};

View File

@ -75,26 +75,26 @@ mod tests {
use fj_math::Point;
use crate::{
objects::{Curve, HalfEdge, Surface},
objects::{Curve, HalfEdge, Objects, Surface},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
use super::CurveEdgeIntersection;
#[test]
fn compute_edge_in_front_of_curve_origin() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_u_axis()
.build(&stores);
.build(&objects);
let half_edge = HalfEdge::partial()
.with_surface(Some(surface))
.as_line_segment_from_points([[1., -1.], [1., 1.]])
.build(&stores);
.build(&objects);
let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);
@ -108,17 +108,17 @@ mod tests {
#[test]
fn compute_edge_behind_curve_origin() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_u_axis()
.build(&stores);
.build(&objects);
let half_edge = HalfEdge::partial()
.with_surface(Some(surface))
.as_line_segment_from_points([[-1., -1.], [-1., 1.]])
.build(&stores);
.build(&objects);
let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);
@ -132,17 +132,17 @@ mod tests {
#[test]
fn compute_edge_parallel_to_curve() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_u_axis()
.build(&stores);
.build(&objects);
let half_edge = HalfEdge::partial()
.with_surface(Some(surface))
.as_line_segment_from_points([[-1., -1.], [1., -1.]])
.build(&stores);
.build(&objects);
let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);
@ -151,17 +151,17 @@ mod tests {
#[test]
fn compute_edge_on_curve() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_u_axis()
.build(&stores);
.build(&objects);
let half_edge = HalfEdge::partial()
.with_surface(Some(surface))
.as_line_segment_from_points([[-1., 0.], [1., 0.]])
.build(&stores);
.build(&objects);
let intersection = CurveEdgeIntersection::compute(&curve, &half_edge);

View File

@ -156,23 +156,23 @@ where
#[cfg(test)]
mod tests {
use crate::{
objects::{Curve, Face, Surface},
objects::{Curve, Face, Objects, Surface},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
use super::CurveFaceIntersection;
#[test]
fn compute() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_line_from_points([[-3., 0.], [-2., 0.]])
.build(&stores);
.build(&objects);
#[rustfmt::skip]
let exterior = [
@ -189,7 +189,7 @@ mod tests {
[ 1., -1.],
];
let face = Face::builder(&stores, surface)
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points(exterior)
.with_interior_polygon_from_points(interior)
.build();

View File

@ -1,6 +1,6 @@
use crate::{
objects::{Curve, Face},
stores::{Handle, Stores},
objects::{Curve, Face, Objects},
storage::Handle,
};
use super::{CurveFaceIntersection, SurfaceSurfaceIntersection};
@ -24,11 +24,11 @@ pub struct FaceFaceIntersection {
impl FaceFaceIntersection {
/// Compute the intersections between two faces
pub fn compute(faces: [&Face; 2], stores: &Stores) -> Option<Self> {
pub fn compute(faces: [&Face; 2], objects: &Objects) -> Option<Self> {
let surfaces = faces.map(|face| face.surface().clone());
let intersection_curves =
SurfaceSurfaceIntersection::compute(surfaces, stores)?
SurfaceSurfaceIntersection::compute(surfaces, objects)?
.intersection_curves;
// Can be cleaned up, once `zip` is stable:
@ -64,16 +64,16 @@ mod tests {
use crate::{
algorithms::intersect::CurveFaceIntersection,
objects::{Curve, Face, Surface},
objects::{Curve, Face, Objects, Surface},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
use super::FaceFaceIntersection;
#[test]
fn compute_no_intersection() {
let stores = Stores::new();
let objects = Objects::new();
#[rustfmt::skip]
let points = [
@ -84,20 +84,20 @@ mod tests {
];
let [a, b] =
[Surface::xy_plane(), Surface::xz_plane()].map(|surface| {
let surface = stores.surfaces.insert(surface);
Face::builder(&stores, surface)
let surface = objects.surfaces.insert(surface);
Face::builder(&objects, surface)
.with_exterior_polygon_from_points(points)
.build()
});
let intersection = FaceFaceIntersection::compute([&a, &b], &stores);
let intersection = FaceFaceIntersection::compute([&a, &b], &objects);
assert!(intersection.is_none());
}
#[test]
fn compute_one_intersection() {
let stores = Stores::new();
let objects = Objects::new();
#[rustfmt::skip]
let points = [
@ -107,20 +107,20 @@ mod tests {
[-1., 1.],
];
let surfaces = [Surface::xy_plane(), Surface::xz_plane()]
.map(|surface| stores.surfaces.insert(surface));
.map(|surface| objects.surfaces.insert(surface));
let [a, b] = surfaces.clone().map(|surface| {
Face::builder(&stores, surface)
Face::builder(&objects, surface)
.with_exterior_polygon_from_points(points)
.build()
});
let intersection = FaceFaceIntersection::compute([&a, &b], &stores);
let intersection = FaceFaceIntersection::compute([&a, &b], &objects);
let expected_curves = surfaces.map(|surface| {
Handle::<Curve>::partial()
.with_surface(Some(surface))
.as_line_from_points([[0., 0.], [1., 0.]])
.build(&stores)
.build(&objects)
});
let expected_intervals =
CurveFaceIntersection::from_intervals([[[-1.], [1.]]]);

View File

@ -134,16 +134,15 @@ mod tests {
use crate::{
algorithms::intersect::{face_point::FacePointIntersection, Intersect},
iter::ObjectIters,
objects::{Face, Surface},
stores::Stores,
objects::{Face, Objects, Surface},
};
#[test]
fn point_is_outside_face() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 1.], [0., 2.]])
.build();
let point = Point::from([2., 1.]);
@ -154,10 +153,10 @@ mod tests {
#[test]
fn ray_hits_vertex_while_passing_outside() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([[0., 0.], [2., 1.], [0., 2.]])
.build();
let point = Point::from([1., 1.]);
@ -171,10 +170,10 @@ mod tests {
#[test]
fn ray_hits_vertex_at_cycle_seam() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([[4., 2.], [0., 4.], [0., 0.]])
.build();
let point = Point::from([1., 2.]);
@ -188,10 +187,10 @@ mod tests {
#[test]
fn ray_hits_vertex_while_staying_inside() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[0., 0.],
[2., 1.],
@ -210,10 +209,10 @@ mod tests {
#[test]
fn ray_hits_parallel_edge_and_leaves_face_at_vertex() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[0., 0.],
[2., 1.],
@ -232,10 +231,10 @@ mod tests {
#[test]
fn ray_hits_parallel_edge_and_does_not_leave_face_there() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[0., 0.],
[2., 1.],
@ -255,10 +254,10 @@ mod tests {
#[test]
fn point_is_coincident_with_edge() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([[0., 0.], [2., 0.], [0., 1.]])
.build();
let point = Point::from([1., 0.]);
@ -281,10 +280,10 @@ mod tests {
#[test]
fn point_is_coincident_with_vertex() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]])
.build();
let point = Point::from([1., 0.]);

View File

@ -152,18 +152,17 @@ mod tests {
transform::TransformObject,
},
iter::ObjectIters,
objects::{Face, Surface},
stores::Stores,
objects::{Face, Objects, Surface},
};
#[test]
fn ray_misses_whole_surface() {
let stores = Stores::new();
let objects = Objects::new();
let ray = HorizontalRayToTheRight::from([0., 0., 0.]);
let surface = stores.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[-1., -1.],
[1., -1.],
@ -171,19 +170,19 @@ mod tests {
[-1., 1.],
])
.build()
.translate([-1., 0., 0.], &stores);
.translate([-1., 0., 0.], &objects);
assert_eq!((&ray, &face).intersect(), None);
}
#[test]
fn ray_hits_face() {
let stores = Stores::new();
let objects = Objects::new();
let ray = HorizontalRayToTheRight::from([0., 0., 0.]);
let surface = stores.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[-1., -1.],
[1., -1.],
@ -191,7 +190,7 @@ mod tests {
[-1., 1.],
])
.build()
.translate([1., 0., 0.], &stores);
.translate([1., 0., 0.], &objects);
assert_eq!(
(&ray, &face).intersect(),
@ -201,12 +200,12 @@ mod tests {
#[test]
fn ray_hits_surface_but_misses_face() {
let stores = Stores::new();
let objects = Objects::new();
let ray = HorizontalRayToTheRight::from([0., 0., 0.]);
let surface = stores.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[-1., -1.],
[1., -1.],
@ -214,19 +213,19 @@ mod tests {
[-1., 1.],
])
.build()
.translate([0., 0., 2.], &stores);
.translate([0., 0., 2.], &objects);
assert_eq!((&ray, &face).intersect(), None);
}
#[test]
fn ray_hits_edge() {
let stores = Stores::new();
let objects = Objects::new();
let ray = HorizontalRayToTheRight::from([0., 0., 0.]);
let surface = stores.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[-1., -1.],
[1., -1.],
@ -234,7 +233,7 @@ mod tests {
[-1., 1.],
])
.build()
.translate([1., 1., 0.], &stores);
.translate([1., 1., 0.], &objects);
let edge = face
.half_edge_iter()
@ -252,12 +251,12 @@ mod tests {
#[test]
fn ray_hits_vertex() {
let stores = Stores::new();
let objects = Objects::new();
let ray = HorizontalRayToTheRight::from([0., 0., 0.]);
let surface = stores.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::yz_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[-1., -1.],
[1., -1.],
@ -265,7 +264,7 @@ mod tests {
[-1., 1.],
])
.build()
.translate([1., 1., 1.], &stores);
.translate([1., 1., 1.], &objects);
let vertex = face
.vertex_iter()
@ -281,12 +280,12 @@ mod tests {
#[test]
fn ray_is_parallel_to_surface_and_hits() {
let stores = Stores::new();
let objects = Objects::new();
let ray = HorizontalRayToTheRight::from([0., 0., 0.]);
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[-1., -1.],
[1., -1.],
@ -303,12 +302,12 @@ mod tests {
#[test]
fn ray_is_parallel_to_surface_and_misses() {
let stores = Stores::new();
let objects = Objects::new();
let ray = HorizontalRayToTheRight::from([0., 0., 0.]);
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([
[-1., -1.],
[1., -1.],
@ -316,7 +315,7 @@ mod tests {
[-1., 1.],
])
.build()
.translate([0., 0., 1.], &stores);
.translate([0., 0., 1.], &objects);
assert_eq!((&ray, &face).intersect(), None)
}

View File

@ -1,9 +1,9 @@
use fj_math::{Line, Plane, Point, Scalar};
use crate::{
objects::{Curve, GlobalCurve, Surface},
objects::{Curve, GlobalCurve, Objects, Surface},
path::{GlobalPath, SurfacePath},
stores::{Handle, Stores},
storage::Handle,
};
/// The intersection between two surfaces
@ -17,7 +17,7 @@ impl SurfaceSurfaceIntersection {
/// Compute the intersection between two surfaces
pub fn compute(
surfaces: [Handle<Surface>; 2],
stores: &Stores,
objects: &Objects,
) -> Option<Self> {
// Algorithm from Real-Time Collision Detection by Christer Ericson. See
// section 5.4.4, Intersection of Two Planes.
@ -57,9 +57,9 @@ impl SurfaceSurfaceIntersection {
let curves = surfaces_and_planes.map(|(surface, plane)| {
let path = SurfacePath::Line(plane.project_line(&line));
let global_form = GlobalCurve::new(stores);
let global_form = GlobalCurve::new(objects);
Curve::new(surface, path, global_form, stores)
Curve::new(surface, path, global_form, objects)
});
Some(Self {
@ -88,19 +88,19 @@ mod tests {
use crate::{
algorithms::transform::TransformObject,
objects::{Curve, Surface},
objects::{Curve, Objects, Surface},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
use super::SurfaceSurfaceIntersection;
#[test]
fn plane_plane() {
let stores = Stores::new();
let objects = Objects::new();
let xy = stores.surfaces.insert(Surface::xy_plane());
let xz = stores.surfaces.insert(Surface::xz_plane());
let xy = objects.surfaces.insert(Surface::xy_plane());
let xz = objects.surfaces.insert(Surface::xz_plane());
// Coincident and parallel planes don't have an intersection curve.
assert_eq!(
@ -109,10 +109,10 @@ mod tests {
xy.clone(),
xy.clone().transform(
&Transform::translation([0., 0., 1.],),
&stores
&objects
)
],
&stores
&objects
),
None,
);
@ -120,14 +120,14 @@ mod tests {
let expected_xy = Handle::<Curve>::partial()
.with_surface(Some(xy.clone()))
.as_u_axis()
.build(&stores);
.build(&objects);
let expected_xz = Handle::<Curve>::partial()
.with_surface(Some(xz.clone()))
.as_u_axis()
.build(&stores);
.build(&objects);
assert_eq!(
SurfaceSurfaceIntersection::compute([xy, xz], &stores),
SurfaceSurfaceIntersection::compute([xy, xz], &objects),
Some(SurfaceSurfaceIntersection {
intersection_curves: [expected_xy, expected_xz],
})

View File

@ -1,9 +1,9 @@
use fj_math::{Circle, Line, Vector};
use crate::{
objects::{Curve, Surface},
objects::{Curve, Objects, Surface},
path::{GlobalPath, SurfacePath},
stores::{Handle, Stores},
storage::Handle,
};
use super::Sweep;
@ -11,7 +11,11 @@ use super::Sweep;
impl Sweep for Handle<Curve> {
type Swept = Handle<Surface>;
fn sweep(self, path: impl Into<Vector<3>>, stores: &Stores) -> Self::Swept {
fn sweep(
self,
path: impl Into<Vector<3>>,
objects: &Objects,
) -> Self::Swept {
match self.surface().u() {
GlobalPath::Circle(_) => {
// Sweeping a `Curve` creates a `Surface`. The u-axis of that
@ -59,6 +63,6 @@ impl Sweep for Handle<Curve> {
}
};
stores.surfaces.insert(Surface::new(u, path))
objects.surfaces.insert(Surface::new(u, path))
}
}

View File

@ -4,10 +4,10 @@ use fj_math::{Line, Scalar, Vector};
use crate::{
algorithms::{reverse::Reverse, transform::TransformObject},
objects::{
Curve, Cycle, Face, GlobalEdge, HalfEdge, SurfaceVertex, Vertex,
Curve, Cycle, Face, GlobalEdge, HalfEdge, Objects, SurfaceVertex,
Vertex,
},
path::SurfacePath,
stores::Stores,
};
use super::Sweep;
@ -15,11 +15,15 @@ use super::Sweep;
impl Sweep for (HalfEdge, Color) {
type Swept = Face;
fn sweep(self, path: impl Into<Vector<3>>, stores: &Stores) -> Self::Swept {
fn sweep(
self,
path: impl Into<Vector<3>>,
objects: &Objects,
) -> Self::Swept {
let (edge, color) = self;
let path = path.into();
let surface = edge.curve().clone().sweep(path, stores);
let surface = edge.curve().clone().sweep(path, objects);
// We can't use the edge we're sweeping from as the bottom edge, as that
// is not defined in the right surface. Let's create a new bottom edge,
@ -44,7 +48,7 @@ impl Sweep for (HalfEdge, Color) {
surface.clone(),
path,
edge.curve().global_form().clone(),
stores,
objects,
)
};
@ -80,7 +84,7 @@ impl Sweep for (HalfEdge, Color) {
let side_edges = bottom_edge
.vertices()
.clone()
.map(|vertex| (vertex, surface.clone()).sweep(path, stores));
.map(|vertex| (vertex, surface.clone()).sweep(path, objects));
let top_edge = {
let bottom_vertices = bottom_edge.vertices();
@ -100,7 +104,7 @@ impl Sweep for (HalfEdge, Color) {
.curve()
.global_form()
.clone()
.translate(path, stores);
.translate(path, objects);
// Please note that creating a line here is correct, even if the
// global curve is a circle. Projected into the side surface, it
@ -110,7 +114,7 @@ impl Sweep for (HalfEdge, Color) {
points_curve_and_surface,
));
Curve::new(surface.clone(), path, global, stores)
Curve::new(surface.clone(), path, global, objects)
};
let global = GlobalEdge::new(
@ -184,43 +188,42 @@ mod tests {
use crate::{
algorithms::{reverse::Reverse, sweep::Sweep},
objects::{Cycle, Face, HalfEdge, Surface},
objects::{Cycle, Face, HalfEdge, Objects, Surface},
partial::HasPartial,
stores::Stores,
};
#[test]
fn sweep() {
let stores = Stores::new();
let objects = Objects::new();
let half_edge = HalfEdge::partial()
.with_surface(Some(stores.surfaces.insert(Surface::xy_plane())))
.with_surface(Some(objects.surfaces.insert(Surface::xy_plane())))
.as_line_segment_from_points([[0., 0.], [1., 0.]])
.build(&stores);
.build(&objects);
let face = (half_edge, Color::default()).sweep([0., 0., 1.], &stores);
let face = (half_edge, Color::default()).sweep([0., 0., 1.], &objects);
let expected_face = {
let surface = stores.surfaces.insert(Surface::xz_plane());
let surface = objects.surfaces.insert(Surface::xz_plane());
let bottom = HalfEdge::partial()
.with_surface(Some(surface.clone()))
.as_line_segment_from_points([[0., 0.], [1., 0.]])
.build(&stores);
.build(&objects);
let top = HalfEdge::partial()
.with_surface(Some(surface.clone()))
.as_line_segment_from_points([[0., 1.], [1., 1.]])
.build(&stores)
.build(&objects)
.reverse();
let left = HalfEdge::partial()
.with_surface(Some(surface.clone()))
.as_line_segment_from_points([[0., 0.], [0., 1.]])
.build(&stores)
.build(&objects)
.reverse();
let right = HalfEdge::partial()
.with_surface(Some(surface.clone()))
.as_line_segment_from_points([[1., 0.], [1., 1.]])
.build(&stores);
.build(&objects);
let cycle = Cycle::new(surface, [bottom, right, top, left]);

View File

@ -2,9 +2,8 @@ use fj_math::{Scalar, Vector};
use crate::{
algorithms::{reverse::Reverse, transform::TransformObject},
objects::{Face, Shell},
objects::{Face, Objects, Shell},
path::GlobalPath,
stores::Stores,
};
use super::Sweep;
@ -12,7 +11,11 @@ use super::Sweep;
impl Sweep for Face {
type Swept = Shell;
fn sweep(self, path: impl Into<Vector<3>>, stores: &Stores) -> Self::Swept {
fn sweep(
self,
path: impl Into<Vector<3>>,
objects: &Objects,
) -> Self::Swept {
let path = path.into();
let mut faces = Vec::new();
@ -42,7 +45,7 @@ impl Sweep for Face {
faces.push(bottom_face);
let top_face = {
let mut face = self.clone().translate(path, stores);
let mut face = self.clone().translate(path, objects);
if is_negative_sweep {
face = face.reverse();
@ -61,7 +64,7 @@ impl Sweep for Face {
half_edge.clone()
};
let face = (half_edge, self.color()).sweep(path, stores);
let face = (half_edge, self.color()).sweep(path, objects);
faces.push(face);
}
@ -77,9 +80,8 @@ mod tests {
use crate::{
algorithms::{reverse::Reverse, transform::TransformObject},
objects::{Face, HalfEdge, Sketch, Surface},
objects::{Face, HalfEdge, Objects, Sketch, Surface},
partial::HasPartial,
stores::Stores,
};
use super::Sweep;
@ -91,18 +93,18 @@ mod tests {
#[test]
fn sweep_up() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let solid = Sketch::builder(&stores, surface.clone())
let surface = objects.surfaces.insert(Surface::xy_plane());
let solid = Sketch::builder(&objects, surface.clone())
.build_polygon_from_points(TRIANGLE)
.sweep(UP, &stores);
.sweep(UP, &objects);
let bottom = Face::builder(&stores, surface.clone())
let bottom = Face::builder(&objects, surface.clone())
.with_exterior_polygon_from_points(TRIANGLE)
.build()
.reverse();
let top = Face::builder(&stores, surface.translate(UP, &stores))
let top = Face::builder(&objects, surface.translate(UP, &objects))
.with_exterior_polygon_from_points(TRIANGLE)
.build();
@ -117,10 +119,12 @@ mod tests {
let [a, b] = [window[0], window[1]];
let half_edge = HalfEdge::partial()
.with_surface(Some(stores.surfaces.insert(Surface::xy_plane())))
.with_surface(Some(
objects.surfaces.insert(Surface::xy_plane()),
))
.as_line_segment_from_points([a, b])
.build(&stores);
(half_edge, Color::default()).sweep(UP, &stores)
.build(&objects);
(half_edge, Color::default()).sweep(UP, &objects)
});
assert!(side_faces.all(|face| solid.find_face(&face).is_some()));
@ -128,19 +132,19 @@ mod tests {
#[test]
fn sweep_down() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let solid = Sketch::builder(&stores, surface.clone())
let surface = objects.surfaces.insert(Surface::xy_plane());
let solid = Sketch::builder(&objects, surface.clone())
.build_polygon_from_points(TRIANGLE)
.sweep(DOWN, &stores);
.sweep(DOWN, &objects);
let bottom =
Face::builder(&stores, surface.clone().translate(DOWN, &stores))
Face::builder(&objects, surface.clone().translate(DOWN, &objects))
.with_exterior_polygon_from_points(TRIANGLE)
.build()
.reverse();
let top = Face::builder(&stores, surface)
let top = Face::builder(&objects, surface)
.with_exterior_polygon_from_points(TRIANGLE)
.build();
@ -155,11 +159,13 @@ mod tests {
let [a, b] = [window[0], window[1]];
let half_edge = HalfEdge::partial()
.with_surface(Some(stores.surfaces.insert(Surface::xy_plane())))
.with_surface(Some(
objects.surfaces.insert(Surface::xy_plane()),
))
.as_line_segment_from_points([a, b])
.build(&stores)
.build(&objects)
.reverse();
(half_edge, Color::default()).sweep(DOWN, &stores)
(half_edge, Color::default()).sweep(DOWN, &objects)
});
assert!(side_faces.all(|face| solid.find_face(&face).is_some()));

View File

@ -8,7 +8,7 @@ mod vertex;
use fj_math::Vector;
use crate::stores::Stores;
use crate::objects::Objects;
/// Sweep an object along a path to create another object
pub trait Sweep {
@ -16,5 +16,9 @@ pub trait Sweep {
type Swept;
/// Sweep the object along the given path
fn sweep(self, path: impl Into<Vector<3>>, store: &Stores) -> Self::Swept;
fn sweep(
self,
path: impl Into<Vector<3>>,
objects: &Objects,
) -> Self::Swept;
}

View File

@ -1,21 +1,22 @@
use fj_math::Vector;
use crate::{
objects::{Sketch, Solid},
stores::Stores,
};
use crate::objects::{Objects, Sketch, Solid};
use super::Sweep;
impl Sweep for Sketch {
type Swept = Solid;
fn sweep(self, path: impl Into<Vector<3>>, stores: &Stores) -> Self::Swept {
fn sweep(
self,
path: impl Into<Vector<3>>,
objects: &Objects,
) -> Self::Swept {
let path = path.into();
let mut shells = Vec::new();
for face in self.into_faces() {
let shell = face.sweep(path, stores);
let shell = face.sweep(path, objects);
shells.push(shell);
}

View File

@ -2,11 +2,11 @@ use fj_math::{Line, Point, Scalar, Vector};
use crate::{
objects::{
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Surface,
SurfaceVertex, Vertex,
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
Surface, SurfaceVertex, Vertex,
},
path::SurfacePath,
stores::{Handle, Stores},
storage::Handle,
};
use super::Sweep;
@ -14,7 +14,11 @@ use super::Sweep;
impl Sweep for (Vertex, Handle<Surface>) {
type Swept = HalfEdge;
fn sweep(self, path: impl Into<Vector<3>>, stores: &Stores) -> Self::Swept {
fn sweep(
self,
path: impl Into<Vector<3>>,
objects: &Objects,
) -> Self::Swept {
let (vertex, surface) = self;
let path = path.into();
@ -54,7 +58,7 @@ impl Sweep for (Vertex, Handle<Surface>) {
// as that is the most straight-forward part of this operations, and
// we're going to need it soon anyway.
let (edge_global, vertices_global) =
vertex.global_form().clone().sweep(path, stores);
vertex.global_form().clone().sweep(path, objects);
// Next, let's compute the surface coordinates of the two vertices of
// the output `Edge`, as we're going to need these for the rest of this
@ -84,7 +88,7 @@ impl Sweep for (Vertex, Handle<Surface>) {
surface.clone(),
SurfacePath::Line(line),
edge_global.curve().clone(),
stores,
objects,
)
};
@ -123,12 +127,16 @@ impl Sweep for (Vertex, Handle<Surface>) {
impl Sweep for Handle<GlobalVertex> {
type Swept = (GlobalEdge, [Handle<GlobalVertex>; 2]);
fn sweep(self, path: impl Into<Vector<3>>, stores: &Stores) -> Self::Swept {
let curve = GlobalCurve::new(stores);
fn sweep(
self,
path: impl Into<Vector<3>>,
objects: &Objects,
) -> Self::Swept {
let curve = GlobalCurve::new(objects);
let a = self.clone();
let b =
GlobalVertex::from_position(self.position() + path.into(), stores);
GlobalVertex::from_position(self.position() + path.into(), objects);
let vertices = [a, b];
let global_edge = GlobalEdge::new(curve, vertices.clone());
@ -146,31 +154,31 @@ mod tests {
use crate::{
algorithms::sweep::Sweep,
objects::{Curve, HalfEdge, Surface, Vertex},
objects::{Curve, HalfEdge, Objects, Surface, Vertex},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
#[test]
fn vertex_surface() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xz_plane());
let surface = objects.surfaces.insert(Surface::xz_plane());
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_u_axis()
.build(&stores);
.build(&objects);
let vertex = Vertex::partial()
.with_position(Some([0.]))
.with_curve(Some(curve))
.build(&stores);
.build(&objects);
let half_edge = (vertex, surface.clone()).sweep([0., 0., 1.], &stores);
let half_edge = (vertex, surface.clone()).sweep([0., 0., 1.], &objects);
let expected_half_edge = HalfEdge::partial()
.with_surface(Some(surface))
.as_line_segment_from_points([[0., 0.], [0., 1.]])
.build(&stores);
.build(&objects);
assert_eq!(half_edge, expected_half_edge);
}
}

View File

@ -1,15 +1,15 @@
use fj_math::Transform;
use crate::{
objects::GlobalCurve,
objects::{GlobalCurve, Objects},
partial::PartialCurve,
stores::{Handle, Stores},
storage::Handle,
};
use super::TransformObject;
impl TransformObject for Handle<GlobalCurve> {
fn transform(self, _: &Transform, stores: &Stores) -> Self {
fn transform(self, _: &Transform, objects: &Objects) -> Self {
// `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
@ -18,18 +18,18 @@ impl TransformObject for Handle<GlobalCurve> {
// 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.
GlobalCurve::new(stores)
GlobalCurve::new(objects)
}
}
impl TransformObject for PartialCurve {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let surface = self
.surface
.map(|surface| surface.transform(transform, stores));
.map(|surface| surface.transform(transform, objects));
let global_form = self
.global_form
.map(|global_form| global_form.0.transform(transform, stores));
.map(|global_form| global_form.0.transform(transform, objects));
// Don't need to transform `self.path`, as that's defined in surface
// coordinates, and thus transforming `surface` takes care of it.

View File

@ -1,21 +1,21 @@
use fj_math::Transform;
use crate::{partial::PartialCycle, stores::Stores};
use crate::{objects::Objects, partial::PartialCycle};
use super::TransformObject;
impl TransformObject for PartialCycle {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let surface = self
.surface
.clone()
.map(|surface| surface.transform(transform, stores));
.map(|surface| surface.transform(transform, objects));
let half_edges = self
.half_edges
.into_iter()
.map(|edge| {
edge.into_partial()
.transform(transform, stores)
.transform(transform, objects)
.with_surface(surface.clone())
.into()
})

View File

@ -1,22 +1,22 @@
use fj_math::Transform;
use crate::{
objects::Curve,
objects::{Curve, Objects},
partial::{MaybePartial, PartialGlobalEdge, PartialHalfEdge},
stores::{Handle, Stores},
storage::Handle,
};
use super::TransformObject;
impl TransformObject for PartialHalfEdge {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let surface = self
.surface
.map(|surface| surface.transform(transform, stores));
.map(|surface| surface.transform(transform, objects));
let curve = self.curve.clone().map(|curve| {
curve
.into_partial()
.transform(transform, stores)
.transform(transform, objects)
.with_surface(surface.clone())
.into()
});
@ -24,7 +24,7 @@ impl TransformObject for PartialHalfEdge {
vertices.map(|vertex| {
vertex
.into_partial()
.transform(transform, stores)
.transform(transform, objects)
.with_curve(curve.clone())
.into()
})
@ -32,7 +32,7 @@ impl TransformObject for PartialHalfEdge {
let global_form = self.global_form.map(|global_form| {
global_form
.into_partial()
.transform(transform, stores)
.transform(transform, objects)
.with_curve(curve.as_ref().and_then(
|curve: &MaybePartial<Handle<Curve>>| curve.global_form(),
))
@ -49,11 +49,12 @@ impl TransformObject for PartialHalfEdge {
}
impl TransformObject for PartialGlobalEdge {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let curve =
self.curve.map(|curve| curve.0.transform(transform, stores));
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let curve = self
.curve
.map(|curve| curve.0.transform(transform, objects));
let vertices = self.vertices.map(|vertices| {
vertices.map(|vertex| vertex.transform(transform, stores))
vertices.map(|vertex| vertex.transform(transform, objects))
});
Self {

View File

@ -1,28 +1,27 @@
use fj_math::Transform;
use crate::{
objects::{Face, Faces},
objects::{Face, Faces, Objects},
partial::HasPartial,
stores::Stores,
};
use super::TransformObject;
impl TransformObject for Face {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let surface = self.surface().clone().transform(transform, stores);
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let surface = self.surface().clone().transform(transform, objects);
let exterior = self
.exterior()
.to_partial()
.transform(transform, stores)
.transform(transform, objects)
.with_surface(Some(surface.clone()))
.build(stores);
.build(objects);
let interiors = self.interiors().map(|cycle| {
cycle
.to_partial()
.transform(transform, stores)
.transform(transform, objects)
.with_surface(Some(surface.clone()))
.build(stores)
.build(objects)
});
let color = self.color();
@ -34,11 +33,11 @@ impl TransformObject for Face {
}
impl TransformObject for Faces {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let mut faces = Faces::new();
faces.extend(
self.into_iter()
.map(|face| face.transform(transform, stores)),
.map(|face| face.transform(transform, objects)),
);
faces
}

View File

@ -14,8 +14,8 @@ mod vertex;
use fj_math::{Transform, Vector};
use crate::{
objects::Objects,
partial::{HasPartial, MaybePartial, Partial},
stores::Stores,
};
/// Transform an object
@ -30,22 +30,30 @@ use crate::{
pub trait TransformObject: Sized {
/// Transform the object
#[must_use]
fn transform(self, transform: &Transform, stores: &Stores) -> Self;
fn transform(self, transform: &Transform, objects: &Objects) -> Self;
/// Translate the object
///
/// Convenience wrapper around [`TransformObject::transform`].
#[must_use]
fn translate(self, offset: impl Into<Vector<3>>, stores: &Stores) -> Self {
self.transform(&Transform::translation(offset), stores)
fn translate(
self,
offset: impl Into<Vector<3>>,
objects: &Objects,
) -> Self {
self.transform(&Transform::translation(offset), objects)
}
/// Rotate the object
///
/// Convenience wrapper around [`TransformObject::transform`].
#[must_use]
fn rotate(self, axis_angle: impl Into<Vector<3>>, stores: &Stores) -> Self {
self.transform(&Transform::rotation(axis_angle), stores)
fn rotate(
self,
axis_angle: impl Into<Vector<3>>,
objects: &Objects,
) -> Self {
self.transform(&Transform::rotation(axis_angle), objects)
}
}
@ -54,8 +62,10 @@ where
T: HasPartial,
T::Partial: TransformObject,
{
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
self.to_partial().transform(transform, stores).build(stores)
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
self.to_partial()
.transform(transform, objects)
.build(objects)
}
}
@ -64,11 +74,11 @@ where
T: HasPartial + TransformObject,
T::Partial: TransformObject,
{
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
match self {
Self::Full(full) => Self::Full(full.transform(transform, stores)),
Self::Full(full) => Self::Full(full.transform(transform, objects)),
Self::Partial(partial) => {
Self::Partial(partial.transform(transform, stores))
Self::Partial(partial.transform(transform, objects))
}
}
}

View File

@ -1,11 +1,11 @@
use fj_math::Transform;
use crate::{path::GlobalPath, stores::Stores};
use crate::{objects::Objects, path::GlobalPath};
use super::TransformObject;
impl TransformObject for GlobalPath {
fn transform(self, transform: &Transform, _: &Stores) -> Self {
fn transform(self, transform: &Transform, _: &Objects) -> Self {
match self {
Self::Circle(curve) => {
Self::Circle(transform.transform_circle(&curve))

View File

@ -1,15 +1,15 @@
use fj_math::Transform;
use crate::{objects::Shell, stores::Stores};
use crate::objects::{Objects, Shell};
use super::TransformObject;
impl TransformObject for Shell {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let faces = self
.into_faces()
.into_iter()
.map(|face| face.transform(transform, stores));
.map(|face| face.transform(transform, objects));
Self::new().with_faces(faces)
}
}

View File

@ -1,15 +1,15 @@
use fj_math::Transform;
use crate::{objects::Sketch, stores::Stores};
use crate::objects::{Objects, Sketch};
use super::TransformObject;
impl TransformObject for Sketch {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let faces = self
.into_faces()
.into_iter()
.map(|face| face.transform(transform, stores));
.map(|face| face.transform(transform, objects));
Self::new().with_faces(faces)
}
}

View File

@ -1,14 +1,14 @@
use fj_math::Transform;
use crate::{objects::Solid, stores::Stores};
use crate::objects::{Objects, Solid};
use super::TransformObject;
impl TransformObject for Solid {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let faces = self
.into_shells()
.map(|shell| shell.transform(transform, stores));
.map(|shell| shell.transform(transform, objects));
Self::new().with_shells(faces)
}
}

View File

@ -1,16 +1,16 @@
use fj_math::Transform;
use crate::{
objects::Surface,
stores::{Handle, Stores},
objects::{Objects, Surface},
storage::Handle,
};
use super::TransformObject;
impl TransformObject for Handle<Surface> {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
stores.surfaces.insert(Surface::new(
self.u().transform(transform, stores),
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
objects.surfaces.insert(Surface::new(
self.u().transform(transform, objects),
transform.transform_vector(&self.v()),
))
}

View File

@ -1,24 +1,24 @@
use fj_math::Transform;
use crate::{
objects::Objects,
partial::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex},
stores::Stores,
};
use super::TransformObject;
impl TransformObject for PartialVertex {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
let curve = self.curve.map(|curve| curve.transform(transform, stores));
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let curve = self.curve.map(|curve| curve.transform(transform, objects));
let surface_form = self.surface_form.map(|surface_form| {
surface_form
.into_partial()
.transform(transform, stores)
.transform(transform, objects)
.into()
});
let global_form = self
.global_form
.map(|global_form| global_form.transform(transform, stores));
.map(|global_form| global_form.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.
@ -32,13 +32,13 @@ impl TransformObject for PartialVertex {
}
impl TransformObject for PartialSurfaceVertex {
fn transform(self, transform: &Transform, stores: &Stores) -> Self {
fn transform(self, transform: &Transform, objects: &Objects) -> Self {
let surface = self
.surface
.map(|surface| surface.transform(transform, stores));
.map(|surface| surface.transform(transform, objects));
let global_form = self
.global_form
.map(|global_form| global_form.transform(transform, stores));
.map(|global_form| 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.
@ -51,7 +51,7 @@ impl TransformObject for PartialSurfaceVertex {
}
impl TransformObject for PartialGlobalVertex {
fn transform(self, transform: &Transform, _: &Stores) -> Self {
fn transform(self, transform: &Transform, _: &Objects) -> Self {
let position = self
.position
.map(|position| transform.transform_point(&position));

View File

@ -84,23 +84,22 @@ mod tests {
use crate::{
algorithms::approx::{Approx, Tolerance},
objects::{Face, Surface},
stores::Stores,
objects::{Face, Objects, Surface},
};
use super::Triangulate;
#[test]
fn simple() -> anyhow::Result<()> {
let stores = Stores::new();
let objects = Objects::new();
let a = [0., 0.];
let b = [2., 0.];
let c = [2., 2.];
let d = [0., 1.];
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([a, b, c, d])
.build();
@ -121,7 +120,7 @@ mod tests {
#[test]
fn simple_hole() -> anyhow::Result<()> {
let stores = Stores::new();
let objects = Objects::new();
let a = [0., 0.];
let b = [4., 0.];
@ -133,8 +132,8 @@ mod tests {
let g = [3., 3.];
let h = [3., 1.];
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface.clone())
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface.clone())
.with_exterior_polygon_from_points([a, b, c, d])
.with_interior_polygon_from_points([e, f, g, h])
.build();
@ -172,7 +171,7 @@ mod tests {
#[ignore]
#[test]
fn sharp_concave_shape() -> anyhow::Result<()> {
let stores = Stores::new();
let objects = Objects::new();
//
// c
@ -193,8 +192,8 @@ mod tests {
let d = [0.1, 0.1];
let e = [0., 0.8];
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface.clone())
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface.clone())
.with_exterior_polygon_from_points([a, b, c, d, e])
.build();

View File

@ -36,21 +36,19 @@ pub trait Validate: Sized {
/// ``` rust
/// # use fj_kernel::{
/// # algorithms::validate::{Validate, ValidationConfig},
/// # objects::GlobalVertex,
/// # stores::Stores,
/// # objects::{GlobalVertex, Objects},
/// # };
/// # let stores = Stores::new();
/// # let object = GlobalVertex::from_position([0., 0., 0.], &stores);
/// # let objects = Objects::new();
/// # let object = GlobalVertex::from_position([0., 0., 0.], &objects);
/// object.validate();
/// ```
/// ``` rust
/// # use fj_kernel::{
/// # algorithms::validate::{Validate, ValidationConfig},
/// # objects::GlobalVertex,
/// # stores::Stores,
/// # objects::{GlobalVertex, Objects},
/// # };
/// # let stores = Stores::new();
/// # let object = GlobalVertex::from_position([0., 0., 0.], &stores);
/// # let objects = Objects::new();
/// # let object = GlobalVertex::from_position([0., 0., 0.], &objects);
/// object.validate_with_config(&ValidationConfig::default());
/// ```
fn validate(self) -> Result<Validated<Self>, ValidationError> {
@ -168,32 +166,31 @@ mod tests {
use crate::{
algorithms::validate::{Validate, ValidationConfig, ValidationError},
objects::{
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Surface,
SurfaceVertex, Vertex,
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
Surface, SurfaceVertex, Vertex,
},
partial::HasPartial,
path::SurfacePath,
stores::Stores,
};
#[test]
fn coherence_edge() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let points_surface = [[0., 0.], [1., 0.]];
let points_global = [[0., 0., 0.], [1., 0., 0.]];
let curve = {
let path = SurfacePath::line_from_points(points_surface);
let global_form = GlobalCurve::new(&stores);
let global_form = GlobalCurve::new(&objects);
Curve::new(surface.clone(), path, global_form, &stores)
Curve::new(surface.clone(), path, global_form, &objects)
};
let [a_global, b_global] = points_global
.map(|point| GlobalVertex::from_position(point, &stores));
.map(|point| GlobalVertex::from_position(point, &objects));
let [a_surface, b_surface] = {
// Can be cleaned up, once `zip` is stable:
@ -223,7 +220,7 @@ mod tests {
let global_edge = GlobalEdge::partial()
.from_curve_and_vertices(&curve, &vertices)
.build(&stores);
.build(&objects);
let half_edge = HalfEdge::new(vertices, global_edge);
let result =
@ -242,7 +239,7 @@ mod tests {
#[test]
fn uniqueness_vertex() -> anyhow::Result<()> {
let stores = Stores::new();
let objects = Objects::new();
let mut shape = Vec::new();
let deviation = Scalar::from_f64(0.25);
@ -258,11 +255,11 @@ mod tests {
};
// Adding a vertex should work.
shape.push(GlobalVertex::from_position(a, &stores));
shape.push(GlobalVertex::from_position(a, &objects));
shape.clone().validate_with_config(&config)?;
// Adding a second vertex that is considered identical should fail.
shape.push(GlobalVertex::from_position(b, &stores));
shape.push(GlobalVertex::from_position(b, &objects));
let result = shape.validate_with_config(&config);
assert!(matches!(result, Err(ValidationError::Uniqueness(_))));

View File

@ -1,9 +1,9 @@
use fj_math::Point;
use crate::{
objects::{Cycle, Face, Surface},
objects::{Cycle, Face, Objects, Surface},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
/// API for building a [`Face`]
@ -11,7 +11,7 @@ use crate::{
/// Also see [`Face::builder`].
pub struct FaceBuilder<'a> {
/// The stores that the created objects are put in
pub stores: &'a Stores,
pub objects: &'a Objects,
/// The surface that the [`Face`] is defined in
pub surface: Handle<Surface>,
@ -37,7 +37,7 @@ impl<'a> FaceBuilder<'a> {
.with_surface(Some(self.surface.clone()))
.with_poly_chain_from_points(points)
.close_with_line_segment()
.build(self.stores),
.build(self.objects),
);
self
}
@ -52,7 +52,7 @@ impl<'a> FaceBuilder<'a> {
.with_surface(Some(self.surface.clone()))
.with_poly_chain_from_points(points)
.close_with_line_segment()
.build(self.stores),
.build(self.objects),
);
self
}

View File

@ -3,10 +3,11 @@ use fj_math::Scalar;
use crate::{
algorithms::transform::TransformObject,
objects::{
Curve, Cycle, Face, HalfEdge, Shell, Surface, SurfaceVertex, Vertex,
Curve, Cycle, Face, HalfEdge, Objects, Shell, Surface, SurfaceVertex,
Vertex,
},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
/// API for building a [`Shell`]
@ -14,7 +15,7 @@ use crate::{
/// Also see [`Shell::builder`].
pub struct ShellBuilder<'a> {
/// The stores that the created objects are put in
pub stores: &'a Stores,
pub objects: &'a Objects,
}
impl<'a> ShellBuilder<'a> {
@ -31,12 +32,12 @@ impl<'a> ShellBuilder<'a> {
let bottom = {
let surface = self
.stores
.objects
.surfaces
.insert(Surface::xy_plane())
.translate([Z, Z, -h], self.stores);
.translate([Z, Z, -h], self.objects);
Face::builder(self.stores, surface)
Face::builder(self.objects, surface)
.with_exterior_polygon_from_points([
[-h, -h],
[h, -h],
@ -57,7 +58,7 @@ impl<'a> ShellBuilder<'a> {
.map(|vertex| vertex.global_form().position());
let c = a + [Z, Z, edge_length];
self.stores
self.objects
.surfaces
.insert(Surface::plane_from_points([a, b, c]))
})
@ -72,7 +73,7 @@ impl<'a> ShellBuilder<'a> {
.with_surface(Some(surface.clone()))
.with_global_form(Some(half_edge.global_form().clone()))
.as_line_segment_from_points([[Z, Z], [edge_length, Z]])
.build(self.stores)
.build(self.objects)
})
.collect::<Vec<_>>();
@ -94,7 +95,7 @@ impl<'a> ShellBuilder<'a> {
Vertex::partial().with_surface_form(Some(to)),
]))
.as_line_segment()
.build(self.stores)
.build(self.objects)
})
.collect::<Vec<_>>();
@ -131,7 +132,7 @@ impl<'a> ShellBuilder<'a> {
Vertex::partial().with_surface_form(Some(to)),
]))
.as_line_segment()
.build(self.stores)
.build(self.objects)
})
.collect::<Vec<_>>()
};
@ -159,7 +160,7 @@ impl<'a> ShellBuilder<'a> {
HalfEdge::partial()
.with_vertices(Some([from, to]))
.as_line_segment()
.build(self.stores)
.build(self.objects)
})
.collect::<Vec<_>>();
@ -173,7 +174,7 @@ impl<'a> ShellBuilder<'a> {
let cycle = Cycle::partial()
.with_surface(Some(surface))
.with_half_edges([bottom, side_up, top, side_down])
.build(self.stores);
.build(self.objects);
Face::from_exterior(cycle)
});
@ -183,10 +184,10 @@ impl<'a> ShellBuilder<'a> {
let top = {
let surface = self
.stores
.objects
.surfaces
.insert(Surface::xy_plane())
.translate([Z, Z, h], self.stores);
.translate([Z, Z, h], self.objects);
let points = [[-h, -h], [-h, h], [h, h], [h, -h], [-h, -h]];
@ -211,7 +212,7 @@ impl<'a> ShellBuilder<'a> {
.with_global_form(Some(
vertex.global_form().clone(),
))
.build(self.stores);
.build(self.objects);
Vertex::partial()
.with_position(Some(vertex.position()))
.with_surface_form(Some(surface_form))
@ -223,7 +224,7 @@ impl<'a> ShellBuilder<'a> {
.with_vertices(Some(vertices))
.with_global_form(Some(edge.global_form().clone()))
.as_line_segment()
.build(self.stores),
.build(self.objects),
);
}

View File

@ -1,8 +1,8 @@
use fj_math::Point;
use crate::{
objects::{Face, Sketch, Surface},
stores::{Handle, Stores},
objects::{Face, Objects, Sketch, Surface},
storage::Handle,
};
/// API for building a [`Sketch`]
@ -10,7 +10,7 @@ use crate::{
/// Also see [`Sketch::builder`].
pub struct SketchBuilder<'a> {
/// The stores that the created objects are put in
pub stores: &'a Stores,
pub objects: &'a Objects,
/// The surface that the [`Sketch`] is defined in
pub surface: Handle<Surface>,
@ -22,7 +22,7 @@ impl<'a> SketchBuilder<'a> {
self,
points: impl IntoIterator<Item = impl Into<Point<2>>>,
) -> Sketch {
let face = Face::builder(self.stores, self.surface)
let face = Face::builder(self.objects, self.surface)
.with_exterior_polygon_from_points(points)
.build();
Sketch::new().with_faces([face])

View File

@ -1,16 +1,13 @@
use fj_math::Scalar;
use crate::{
objects::{Shell, Solid},
stores::Stores,
};
use crate::objects::{Objects, Shell, Solid};
/// API for building a [`Solid`]
///
/// Also see [`Solid::builder`].
pub struct SolidBuilder<'a> {
/// The stores that the created objects are put in
pub stores: &'a Stores,
pub objects: &'a Objects,
}
impl<'a> SolidBuilder<'a> {
@ -19,7 +16,7 @@ impl<'a> SolidBuilder<'a> {
self,
edge_length: impl Into<Scalar>,
) -> Solid {
let shell = Shell::builder(self.stores)
let shell = Shell::builder(self.objects)
.build_cube_from_edge_length(edge_length);
Solid::new().with_shells([shell])
}

View File

@ -7,7 +7,7 @@ use crate::{
Curve, Cycle, Face, GlobalCurve, GlobalVertex, HalfEdge, Shell, Sketch,
Solid, Surface, Vertex,
},
stores::Handle,
storage::Handle,
};
/// Access iterators over all objects of a shape, or part of it
@ -361,24 +361,24 @@ impl<T> Iterator for Iter<T> {
mod tests {
use crate::{
objects::{
Curve, Cycle, Face, GlobalCurve, GlobalVertex, HalfEdge, Shell,
Sketch, Solid, Surface, SurfaceVertex, Vertex,
Curve, Cycle, Face, GlobalCurve, GlobalVertex, HalfEdge, Objects,
Shell, Sketch, Solid, Surface, SurfaceVertex, Vertex,
},
partial::HasPartial,
stores::{Handle, Stores},
storage::Handle,
};
use super::ObjectIters as _;
#[test]
fn curve() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let object = Handle::<Curve>::partial()
.with_surface(Some(surface))
.as_u_axis()
.build(&stores);
.build(&objects);
assert_eq!(1, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count());
@ -395,14 +395,14 @@ mod tests {
#[test]
fn cycle() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let object = Cycle::partial()
.with_surface(Some(surface))
.with_poly_chain_from_points([[0., 0.], [1., 0.], [0., 1.]])
.close_with_line_segment()
.build(&stores);
.build(&objects);
assert_eq!(3, object.curve_iter().count());
assert_eq!(1, object.cycle_iter().count());
@ -419,10 +419,10 @@ mod tests {
#[test]
fn face() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let object = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let object = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]])
.build();
@ -441,9 +441,9 @@ mod tests {
#[test]
fn global_curve() {
let stores = Stores::new();
let objects = Objects::new();
let object = GlobalCurve::new(&stores);
let object = GlobalCurve::new(&objects);
assert_eq!(0, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count());
@ -460,9 +460,9 @@ mod tests {
#[test]
fn global_vertex() {
let stores = Stores::new();
let objects = Objects::new();
let object = GlobalVertex::from_position([0., 0., 0.], &stores);
let object = GlobalVertex::from_position([0., 0., 0.], &objects);
assert_eq!(0, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count());
@ -479,12 +479,12 @@ mod tests {
#[test]
fn half_edge() {
let stores = Stores::new();
let objects = Objects::new();
let object = HalfEdge::partial()
.with_surface(Some(stores.surfaces.insert(Surface::xy_plane())))
.with_surface(Some(objects.surfaces.insert(Surface::xy_plane())))
.as_line_segment_from_points([[0., 0.], [1., 0.]])
.build(&stores);
.build(&objects);
assert_eq!(1, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count());
@ -501,9 +501,9 @@ mod tests {
#[test]
fn shell() {
let stores = Stores::new();
let objects = Objects::new();
let object = Shell::builder(&stores).build_cube_from_edge_length(1.);
let object = Shell::builder(&objects).build_cube_from_edge_length(1.);
assert_eq!(24, object.curve_iter().count());
assert_eq!(6, object.cycle_iter().count());
@ -520,10 +520,10 @@ mod tests {
#[test]
fn sketch() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&stores, surface)
let surface = objects.surfaces.insert(Surface::xy_plane());
let face = Face::builder(&objects, surface)
.with_exterior_polygon_from_points([[0., 0.], [1., 0.], [0., 1.]])
.build();
let object = Sketch::new().with_faces([face]);
@ -543,9 +543,9 @@ mod tests {
#[test]
fn solid() {
let stores = Stores::new();
let objects = Objects::new();
let object = Solid::builder(&stores).build_cube_from_edge_length(1.);
let object = Solid::builder(&objects).build_cube_from_edge_length(1.);
assert_eq!(24, object.curve_iter().count());
assert_eq!(6, object.cycle_iter().count());
@ -562,9 +562,9 @@ mod tests {
#[test]
fn surface() {
let stores = Stores::new();
let objects = Objects::new();
let object = stores.surfaces.insert(Surface::xy_plane());
let object = objects.surfaces.insert(Surface::xy_plane());
assert_eq!(0, object.curve_iter().count());
assert_eq!(0, object.cycle_iter().count());
@ -581,14 +581,14 @@ mod tests {
#[test]
fn vertex() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let curve = Handle::<Curve>::partial()
.with_surface(Some(surface.clone()))
.as_u_axis()
.build(&stores);
let global_vertex = GlobalVertex::from_position([0., 0., 0.], &stores);
.build(&objects);
let global_vertex = GlobalVertex::from_position([0., 0., 0.], &objects);
let surface_vertex =
SurfaceVertex::new([0., 0.], surface, global_vertex);
let object = Vertex::new([0.], curve, surface_vertex);

View File

@ -93,4 +93,4 @@ pub mod iter;
pub mod objects;
pub mod partial;
pub mod path;
pub mod stores;
pub mod storage;

View File

@ -1,9 +1,9 @@
use crate::{
path::SurfacePath,
stores::{Handle, HandleWrapper, Stores},
storage::{Handle, HandleWrapper},
};
use super::Surface;
use super::{Objects, Surface};
/// A curve, defined in local surface coordinates
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
@ -19,9 +19,9 @@ impl Curve {
surface: Handle<Surface>,
path: SurfacePath,
global_form: impl Into<HandleWrapper<GlobalCurve>>,
stores: &Stores,
objects: &Objects,
) -> Handle<Self> {
stores.curves.insert(Self {
objects.curves.insert(Self {
surface,
path,
global_form: global_form.into(),
@ -50,7 +50,7 @@ pub struct GlobalCurve;
impl GlobalCurve {
/// Construct a new instance of `Handle` and add it to the store
pub fn new(stores: &Stores) -> Handle<Self> {
stores.global_curves.insert(GlobalCurve)
pub fn new(objects: &Objects) -> Handle<Self> {
objects.global_curves.insert(GlobalCurve)
}
}

View File

@ -1,7 +1,7 @@
use fj_math::{Scalar, Winding};
use pretty_assertions::assert_eq;
use crate::{path::SurfacePath, stores::Handle};
use crate::{path::SurfacePath, storage::Handle};
use super::{HalfEdge, Surface};

View File

@ -2,7 +2,7 @@ use std::fmt;
use pretty_assertions::{assert_eq, assert_ne};
use crate::stores::{Handle, HandleWrapper};
use crate::storage::{Handle, HandleWrapper};
use super::{Curve, GlobalCurve, GlobalVertex, Vertex};
@ -172,15 +172,18 @@ impl VerticesInNormalizedOrder {
mod tests {
use pretty_assertions::assert_eq;
use crate::{objects::Surface, partial::HasPartial, stores::Stores};
use crate::{
objects::{Objects, Surface},
partial::HasPartial,
};
use super::HalfEdge;
#[test]
fn global_edge_equality() {
let stores = Stores::new();
let objects = Objects::new();
let surface = stores.surfaces.insert(Surface::xy_plane());
let surface = objects.surfaces.insert(Surface::xy_plane());
let a = [0., 0.];
let b = [1., 0.];
@ -188,11 +191,11 @@ mod tests {
let a_to_b = HalfEdge::partial()
.with_surface(Some(surface.clone()))
.as_line_segment_from_points([a, b])
.build(&stores);
.build(&objects);
let b_to_a = HalfEdge::partial()
.with_surface(Some(surface))
.as_line_segment_from_points([b, a])
.build(&stores);
.build(&objects);
assert_eq!(a_to_b.global_form(), b_to_a.global_form());
}

View File

@ -3,12 +3,9 @@ use std::collections::{btree_set, BTreeSet};
use fj_interop::mesh::Color;
use fj_math::Winding;
use crate::{
builder::FaceBuilder,
stores::{Handle, Stores},
};
use crate::{builder::FaceBuilder, storage::Handle};
use super::{Cycle, Surface};
use super::{Cycle, Objects, Surface};
/// A face of a shape
///
@ -44,9 +41,9 @@ pub struct Face {
impl Face {
/// Build a `Face` using [`FaceBuilder`]
pub fn builder(stores: &Stores, surface: Handle<Surface>) -> FaceBuilder {
pub fn builder(objects: &Objects, surface: Handle<Surface>) -> FaceBuilder {
FaceBuilder {
stores,
objects,
surface,
exterior: None,
interiors: Vec::new(),

View File

@ -58,7 +58,7 @@
//! ## How Identity Works
//!
//! We can exactly determine the identity of an object, thanks to [centralized
//! object storage][`Stores`]. If objects are created at different times,
//! object storage][`Objects`]. If objects are created at different times,
//! potentially by different code, they end up being stored at different memory
//! locations, regardless of their (non-)equality.
//!
@ -70,8 +70,7 @@
//! As of this writing, most objects are not managed in the centralized object
//! storage. Changing this is an ongoing effort ([#1021]).
//!
//! [`Stores`]: crate::stores::Stores
//! [`Handle`]: crate::stores::Handle
//! [`Handle`]: crate::storage::Handle
//! [#1021]: https://github.com/hannobraun/Fornjot/issues/1021
mod curve;
@ -84,6 +83,8 @@ mod solid;
mod surface;
mod vertex;
use crate::storage::Store;
pub use self::{
curve::{Curve, GlobalCurve},
cycle::Cycle,
@ -95,3 +96,33 @@ pub use self::{
surface::Surface,
vertex::{GlobalVertex, SurfaceVertex, Vertex},
};
/// The available object stores
///
/// # Implementation Note
///
/// The intention is to eventually manage all objects in here. Making this
/// happen is simply a case of putting in the required work. See [#1021].
///
/// [#1021]: https://github.com/hannobraun/Fornjot/issues/1021
#[derive(Debug, Default)]
pub struct Objects {
/// Store for curves
pub curves: Store<Curve>,
/// Store for global curves
pub global_curves: Store<GlobalCurve>,
/// Store for global vertices
pub global_vertices: Store<GlobalVertex>,
/// Store for surfaces
pub surfaces: Store<Surface>,
}
impl Objects {
/// Construct a new instance of `Stores`
pub fn new() -> Self {
Self::default()
}
}

View File

@ -1,6 +1,6 @@
use crate::{builder::ShellBuilder, stores::Stores};
use crate::builder::ShellBuilder;
use super::{face::Faces, Face};
use super::{face::Faces, Face, Objects};
/// A 3-dimensional closed shell
///
@ -15,8 +15,8 @@ pub struct Shell {
impl Shell {
/// Build a `Shell` using [`ShellBuilder`]
pub fn builder(stores: &Stores) -> ShellBuilder {
ShellBuilder { stores }
pub fn builder(objects: &Objects) -> ShellBuilder {
ShellBuilder { objects }
}
/// Construct an empty instance of `Shell`

View File

@ -1,9 +1,6 @@
use crate::{
builder::SketchBuilder,
stores::{Handle, Stores},
};
use crate::{builder::SketchBuilder, storage::Handle};
use super::{face::Faces, Face, Surface};
use super::{face::Faces, Face, Objects, Surface};
/// A 2-dimensional shape
///
@ -18,8 +15,11 @@ pub struct Sketch {
impl Sketch {
/// Build a `Sketch` using [`SketchBuilder`]
pub fn builder(stores: &Stores, surface: Handle<Surface>) -> SketchBuilder {
SketchBuilder { stores, surface }
pub fn builder(
objects: &Objects,
surface: Handle<Surface>,
) -> SketchBuilder {
SketchBuilder { objects, surface }
}
/// Construct an empty instance of `Sketch`

View File

@ -1,8 +1,8 @@
use std::collections::BTreeSet;
use crate::{builder::SolidBuilder, stores::Stores};
use crate::builder::SolidBuilder;
use super::{Face, Shell};
use super::{Face, Objects, Shell};
/// A 3-dimensional shape
///
@ -17,8 +17,8 @@ pub struct Solid {
impl Solid {
/// Build a `Solid` using [`SolidBuilder`]
pub fn builder(stores: &Stores) -> SolidBuilder {
SolidBuilder { stores }
pub fn builder(objects: &Objects) -> SolidBuilder {
SolidBuilder { objects }
}
/// Construct an empty instance of `Solid`

View File

@ -1,9 +1,9 @@
use fj_math::Point;
use pretty_assertions::assert_eq;
use crate::stores::{Handle, Stores};
use crate::storage::Handle;
use super::{Curve, Surface};
use super::{Curve, Objects, Surface};
/// A vertex
///
@ -129,10 +129,10 @@ impl GlobalVertex {
/// Construct a `GlobalVertex` from a position
pub fn from_position(
position: impl Into<Point<3>>,
stores: &Stores,
objects: &Objects,
) -> Handle<Self> {
let position = position.into();
stores.global_vertices.insert(Self { position })
objects.global_vertices.insert(Self { position })
}
/// Access the position of the vertex

View File

@ -2,10 +2,10 @@ use fj_math::Point;
use crate::{
objects::{
Curve, GlobalCurve, GlobalEdge, HalfEdge, Surface, SurfaceVertex,
Vertex,
Curve, GlobalCurve, GlobalEdge, HalfEdge, Objects, Surface,
SurfaceVertex, Vertex,
},
stores::{Handle, Stores},
storage::Handle,
};
use super::{HasPartial, Partial};
@ -48,9 +48,9 @@ impl<T: HasPartial> MaybePartial<T> {
///
/// If this already is a full object, it is returned. If this is a partial
/// object, the full object is built from it, using [`Partial::build`].
pub fn into_full(self, stores: &Stores) -> T {
pub fn into_full(self, objects: &Objects) -> T {
match self {
Self::Partial(partial) => partial.build(stores),
Self::Partial(partial) => partial.build(objects),
Self::Full(full) => full,
}
}

View File

@ -1,9 +1,9 @@
use fj_math::{Point, Scalar, Vector};
use crate::{
objects::{Curve, GlobalCurve, Surface},
objects::{Curve, GlobalCurve, Objects, Surface},
path::SurfacePath,
stores::{Handle, HandleWrapper, Stores},
storage::{Handle, HandleWrapper},
};
/// A partial [`Curve`]
@ -83,16 +83,16 @@ impl PartialCurve {
}
/// Build a full [`Curve`] from the partial curve
pub fn build(self, stores: &Stores) -> Handle<Curve> {
pub fn build(self, objects: &Objects) -> Handle<Curve> {
let path = self.path.expect("Can't build `Curve` without path");
let surface =
self.surface.expect("Can't build `Curve` without surface");
let global_form = self
.global_form
.unwrap_or_else(|| GlobalCurve::new(stores).into());
.unwrap_or_else(|| GlobalCurve::new(objects).into());
Curve::new(surface, path, global_form, stores)
Curve::new(surface, path, global_form, objects)
}
}

View File

@ -1,9 +1,11 @@
use fj_math::Point;
use crate::{
objects::{Curve, Cycle, HalfEdge, Surface, SurfaceVertex, Vertex},
objects::{
Curve, Cycle, HalfEdge, Objects, Surface, SurfaceVertex, Vertex,
},
partial::{HasPartial, MaybePartial},
stores::{Handle, Stores},
storage::Handle,
};
/// A partial [`Cycle`]
@ -154,7 +156,7 @@ impl PartialCycle {
}
/// Build a full [`Cycle`] from the partial cycle
pub fn build(self, stores: &Stores) -> Cycle {
pub fn build(self, objects: &Objects) -> Cycle {
let surface = self.surface.expect("Need surface to build `Cycle`");
let surface_for_edges = surface.clone();
let half_edges = self.half_edges.into_iter().map(|half_edge| {
@ -162,7 +164,7 @@ impl PartialCycle {
.update_partial(|half_edge| {
half_edge.with_surface(Some(surface_for_edges.clone()))
})
.into_full(stores)
.into_full(objects)
});
Cycle::new(surface, half_edges)

View File

@ -2,11 +2,11 @@ use fj_math::{Point, Scalar};
use crate::{
objects::{
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Surface,
SurfaceVertex, Vertex,
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
Surface, SurfaceVertex, Vertex,
},
partial::{HasPartial, MaybePartial, PartialCurve},
stores::{Handle, HandleWrapper, Stores},
storage::{Handle, HandleWrapper},
};
/// A partial [`HalfEdge`]
@ -181,13 +181,13 @@ impl PartialHalfEdge {
}
/// Build a full [`HalfEdge`] from the partial half-edge
pub fn build(self, stores: &Stores) -> HalfEdge {
pub fn build(self, objects: &Objects) -> HalfEdge {
let surface = self.surface;
let curve = self
.curve
.expect("Can't build `HalfEdge` without curve")
.update_partial(|curve| curve.with_surface(surface))
.into_full(stores);
.into_full(objects);
let vertices = self
.vertices
.expect("Can't build `HalfEdge` without vertices")
@ -196,7 +196,7 @@ impl PartialHalfEdge {
.update_partial(|vertex| {
vertex.with_curve(Some(curve.clone()))
})
.into_full(stores)
.into_full(objects)
});
let global_form = self
@ -206,7 +206,7 @@ impl PartialHalfEdge {
.from_curve_and_vertices(&curve, &vertices)
.into()
})
.into_full(stores);
.into_full(objects);
HalfEdge::new(vertices, global_form)
}
@ -272,7 +272,7 @@ impl PartialGlobalEdge {
}
/// Build a full [`GlobalEdge`] from the partial global edge
pub fn build(self, _: &Stores) -> GlobalEdge {
pub fn build(self, _: &Objects) -> GlobalEdge {
let curve = self
.curve
.expect("Can't build `GlobalEdge` without `GlobalCurve`");

View File

@ -5,9 +5,10 @@ pub mod vertex;
use crate::{
objects::{
Curve, Cycle, GlobalEdge, GlobalVertex, HalfEdge, SurfaceVertex, Vertex,
Curve, Cycle, GlobalEdge, GlobalVertex, HalfEdge, Objects,
SurfaceVertex, Vertex,
},
stores::{Handle, Stores},
storage::Handle,
};
use super::{
@ -26,8 +27,8 @@ macro_rules! impl_traits {
impl Partial for $partial {
type Full = $full;
fn build(self, stores: &Stores) -> Self::Full {
self.build(stores)
fn build(self, objects: &Objects) -> Self::Full {
self.build(objects)
}
}

View File

@ -1,9 +1,9 @@
use fj_math::Point;
use crate::{
objects::{Curve, GlobalVertex, Surface, SurfaceVertex, Vertex},
objects::{Curve, GlobalVertex, Objects, Surface, SurfaceVertex, Vertex},
partial::{HasPartial, MaybePartial},
stores::{Handle, Stores},
storage::Handle,
};
/// A partial [`Vertex`]
@ -86,14 +86,14 @@ impl PartialVertex {
/// Panics, if no position has been provided.
///
/// Panics, if no curve has been provided.
pub fn build(self, stores: &Stores) -> Vertex {
pub fn build(self, objects: &Objects) -> Vertex {
let position = self
.position
.expect("Cant' build `Vertex` without position");
let curve = self
.curve
.expect("Can't build `Vertex` without `Curve`")
.into_full(stores);
.into_full(objects);
let surface_form = self
.surface_form
@ -108,7 +108,7 @@ impl PartialVertex {
.with_surface(Some(curve.surface().clone()))
.with_global_form(self.global_form)
})
.into_full(stores);
.into_full(objects);
Vertex::new(position, curve, surface_form)
}
@ -185,7 +185,7 @@ impl PartialSurfaceVertex {
/// Panics, if no position has been provided.
///
/// Panics, if no surface has been provided.
pub fn build(self, stores: &Stores) -> SurfaceVertex {
pub fn build(self, objects: &Objects) -> SurfaceVertex {
let position = self
.position
.expect("Can't build `SurfaceVertex` without position");
@ -200,7 +200,7 @@ impl PartialSurfaceVertex {
.from_surface_and_position(&surface, position)
.into()
})
.into_full(stores);
.into_full(objects);
SurfaceVertex::new(position, surface, global_form)
}
@ -269,12 +269,12 @@ impl PartialGlobalVertex {
}
/// Build a full [`GlobalVertex`] from the partial global vertex
pub fn build(self, stores: &Stores) -> Handle<GlobalVertex> {
pub fn build(self, objects: &Objects) -> Handle<GlobalVertex> {
let position = self
.position
.expect("Can't build a `GlobalVertex` without a position");
GlobalVertex::from_position(position, stores)
GlobalVertex::from_position(position, objects)
}
}

View File

@ -1,4 +1,4 @@
use crate::stores::Stores;
use crate::objects::Objects;
/// Implemented for objects that a partial object type exists for
///
@ -77,5 +77,5 @@ pub trait Partial: Default + for<'a> From<&'a Self::Full> {
/// 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
/// [`Result`].
fn build(self, stores: &Stores) -> Self::Full;
fn build(self, objects: &Objects) -> Self::Full;
}

View File

@ -0,0 +1,10 @@
//! Append-only object storage
mod blocks;
mod handle;
mod store;
pub use self::{
handle::{Handle, HandleWrapper, ObjectId},
store::{Iter, Reservation, Store},
};

View File

@ -1,42 +0,0 @@
//! Append-only object storage
mod blocks;
mod handle;
mod store;
use crate::objects::{Curve, GlobalCurve, GlobalVertex, Surface};
pub use self::{
handle::{Handle, HandleWrapper, ObjectId},
store::{Iter, Reservation, Store},
};
/// The available object stores
///
/// # Implementation Note
///
/// The intention is to eventually manage all objects in here. Making this
/// happen is simply a case of putting in the required work. See [#1021].
///
/// [#1021]: https://github.com/hannobraun/Fornjot/issues/1021
#[derive(Debug, Default)]
pub struct Stores {
/// Store for curves
pub curves: Store<Curve>,
/// Store for global curves
pub global_curves: Store<GlobalCurve>,
/// Store for global vertices
pub global_vertices: Store<GlobalVertex>,
/// Store for surfaces
pub surfaces: Store<Surface>,
}
impl Stores {
/// Construct a new instance of `Stores`
pub fn new() -> Self {
Self::default()
}
}

View File

@ -5,8 +5,7 @@ use fj_kernel::{
validate::{Validate, Validated, ValidationConfig, ValidationError},
},
iter::ObjectIters,
objects::{Face, Sketch},
stores::Stores,
objects::{Face, Objects, Sketch},
};
use fj_math::Aabb;
@ -20,7 +19,7 @@ impl Shape for fj::Difference2d {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
@ -37,7 +36,7 @@ impl Shape for fj::Difference2d {
// - https://doc.rust-lang.org/std/primitive.array.html#method.try_map
let [a, b] = self.shapes();
let [a, b] = [a, b].map(|shape| {
shape.compute_brep(config, stores, planes, debug_info)
shape.compute_brep(config, objects, planes, debug_info)
});
let [a, b] = [a?, b?];

View File

@ -3,8 +3,7 @@ use fj_kernel::{
algorithms::validate::{
Validate, Validated, ValidationConfig, ValidationError,
},
objects::Faces,
stores::Stores,
objects::{Faces, Objects},
};
use fj_math::Aabb;
@ -18,14 +17,14 @@ impl Shape for fj::Group {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
let mut faces = Faces::new();
let a = self.a.compute_brep(config, stores, planes, debug_info)?;
let b = self.b.compute_brep(config, stores, planes, debug_info)?;
let a = self.a.compute_brep(config, objects, planes, debug_info)?;
let b = self.b.compute_brep(config, objects, planes, debug_info)?;
faces.extend(a.into_inner());
faces.extend(b.into_inner());

View File

@ -32,8 +32,7 @@ use fj_kernel::{
algorithms::validate::{
Validate, Validated, ValidationConfig, ValidationError,
},
objects::{Faces, Sketch},
stores::Stores,
objects::{Faces, Objects, Sketch},
};
use fj_math::Aabb;
@ -46,7 +45,7 @@ pub trait Shape {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError>;
@ -64,21 +63,21 @@ impl Shape for fj::Shape {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
match self {
Self::Shape2d(shape) => shape
.compute_brep(config, stores, planes, debug_info)?
.compute_brep(config, objects, planes, debug_info)?
.into_inner()
.into_faces()
.validate_with_config(config),
Self::Group(shape) => {
shape.compute_brep(config, stores, planes, debug_info)
shape.compute_brep(config, objects, planes, debug_info)
}
Self::Sweep(shape) => shape
.compute_brep(config, stores, planes, debug_info)?
.compute_brep(config, objects, planes, debug_info)?
.into_inner()
.into_shells()
.map(|shell| shell.into_faces())
@ -89,7 +88,7 @@ impl Shape for fj::Shape {
.unwrap_or_default()
.validate_with_config(config),
Self::Transform(shape) => {
shape.compute_brep(config, stores, planes, debug_info)
shape.compute_brep(config, objects, planes, debug_info)
}
}
}
@ -110,16 +109,16 @@ impl Shape for fj::Shape2d {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
match self {
Self::Difference(shape) => {
shape.compute_brep(config, stores, planes, debug_info)
shape.compute_brep(config, objects, planes, debug_info)
}
Self::Sketch(shape) => {
shape.compute_brep(config, stores, planes, debug_info)
shape.compute_brep(config, objects, planes, debug_info)
}
}
}

View File

@ -1,6 +1,6 @@
use fj_kernel::{
objects::Surface,
stores::{Handle, Stores},
objects::{Objects, Surface},
storage::Handle,
};
/// The static planes
@ -25,10 +25,10 @@ impl Planes {
///
/// Create one instance of this struct, then share it everywhere it's
/// needed.
pub fn new(stores: &Stores) -> Self {
let xy = stores.surfaces.insert(Surface::xy_plane());
let xz = stores.surfaces.insert(Surface::xz_plane());
let yz = stores.surfaces.insert(Surface::yz_plane());
pub fn new(objects: &Objects) -> Self {
let xy = objects.surfaces.insert(Surface::xy_plane());
let xz = objects.surfaces.insert(Surface::xz_plane());
let yz = objects.surfaces.insert(Surface::yz_plane());
Self { xy, xz, yz }
}

View File

@ -7,7 +7,7 @@ use fj_kernel::{
triangulate::Triangulate,
validate::{ValidationConfig, ValidationError},
},
stores::Stores,
objects::Objects,
};
use fj_math::Scalar;
@ -43,11 +43,11 @@ impl ShapeProcessor {
};
let config = ValidationConfig::default();
let stores = Stores::new();
let planes = Planes::new(&stores);
let objects = Objects::new();
let planes = Planes::new(&objects);
let mut debug_info = DebugInfo::new();
let shape =
shape.compute_brep(&config, &stores, &planes, &mut debug_info)?;
shape.compute_brep(&config, &objects, &planes, &mut debug_info)?;
let mesh = (&shape.into_inner(), tolerance).triangulate();
Ok(ProcessedShape {

View File

@ -3,9 +3,8 @@ use fj_kernel::{
algorithms::validate::{
Validate, Validated, ValidationConfig, ValidationError,
},
objects::{Cycle, Face, HalfEdge, Sketch},
objects::{Cycle, Face, HalfEdge, Objects, Sketch},
partial::HasPartial,
stores::Stores,
};
use fj_math::{Aabb, Point};
@ -19,7 +18,7 @@ impl Shape for fj::Sketch {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
_: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
@ -33,7 +32,7 @@ impl Shape for fj::Sketch {
let half_edge = HalfEdge::partial()
.with_surface(Some(surface.clone()))
.as_circle_from_radius(circle.radius())
.build(stores);
.build(objects);
let cycle = Cycle::new(surface, [half_edge]);
Face::from_exterior(cycle).with_color(Color(self.color()))
@ -42,7 +41,7 @@ impl Shape for fj::Sketch {
let points =
poly_chain.to_points().into_iter().map(Point::from);
Face::builder(stores, surface)
Face::builder(objects, surface)
.with_exterior_polygon_from_points(points)
.build()
.with_color(Color(self.color()))

View File

@ -4,8 +4,7 @@ use fj_kernel::{
sweep::Sweep,
validate::{Validate, Validated, ValidationConfig, ValidationError},
},
objects::Solid,
stores::Stores,
objects::{Objects, Solid},
};
use fj_math::{Aabb, Vector};
@ -19,16 +18,16 @@ impl Shape for fj::Sweep {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
let sketch = self
.shape()
.compute_brep(config, stores, planes, debug_info)?;
.compute_brep(config, objects, planes, debug_info)?;
let path = Vector::from(self.path());
let solid = sketch.into_inner().sweep(path, stores);
let solid = sketch.into_inner().sweep(path, objects);
solid.validate_with_config(config)
}

View File

@ -4,8 +4,7 @@ use fj_kernel::{
transform::TransformObject,
validate::{Validate, Validated, ValidationConfig, ValidationError},
},
objects::Faces,
stores::Stores,
objects::{Faces, Objects},
};
use fj_math::{Aabb, Transform, Vector};
@ -19,15 +18,15 @@ impl Shape for fj::Transform {
fn compute_brep(
&self,
config: &ValidationConfig,
stores: &Stores,
objects: &Objects,
planes: &Planes,
debug_info: &mut DebugInfo,
) -> Result<Validated<Self::Brep>, ValidationError> {
let faces = self
.shape
.compute_brep(config, stores, planes, debug_info)?
.compute_brep(config, objects, planes, debug_info)?
.into_inner()
.transform(&make_transform(self), stores);
.transform(&make_transform(self), objects);
faces.validate_with_config(config)
}