Merge pull request #310 from hannobraun/shape

Track curves and surfaces through `Shape`
This commit is contained in:
Hanno Braun 2022-03-08 15:33:12 +01:00 committed by GitHub
commit bc863610d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 126 additions and 92 deletions

View File

@ -150,10 +150,7 @@ mod tests {
kernel::{ kernel::{
geometry::Surface, geometry::Surface,
shape::Shape, shape::Shape,
topology::{ topology::{edges::Cycle, faces::Face},
edges::{Cycle, Edge},
faces::Face,
},
}, },
math::{Point, Scalar, Segment}, math::{Point, Scalar, Segment},
}; };
@ -214,11 +211,9 @@ mod tests {
let v2 = shape.vertices().add(b); let v2 = shape.vertices().add(b);
let v3 = shape.vertices().add(c); let v3 = shape.vertices().add(c);
let ab = shape let ab = shape.edges().add_line_segment([v1.clone(), v2.clone()]);
.edges() let bc = shape.edges().add_line_segment([v2, v3.clone()]);
.add(Edge::line_segment([v1.clone(), v2.clone()])); let ca = shape.edges().add_line_segment([v3, v1]);
let bc = shape.edges().add(Edge::line_segment([v2, v3.clone()]));
let ca = shape.edges().add(Edge::line_segment([v3, v1]));
let cycle = Cycle { let cycle = Cycle {
edges: vec![ab, bc, ca], edges: vec![ab, bc, ca],
@ -255,19 +250,18 @@ mod tests {
let v3 = shape.vertices().add(c); let v3 = shape.vertices().add(c);
let v4 = shape.vertices().add(d); let v4 = shape.vertices().add(d);
let ab = shape let ab = shape.edges().add_line_segment([v1.clone(), v2.clone()]);
.edges() let bc = shape.edges().add_line_segment([v2, v3.clone()]);
.add(Edge::line_segment([v1.clone(), v2.clone()])); let cd = shape.edges().add_line_segment([v3, v4.clone()]);
let bc = shape.edges().add(Edge::line_segment([v2, v3.clone()])); let da = shape.edges().add_line_segment([v4, v1]);
let cd = shape.edges().add(Edge::line_segment([v3, v4.clone()]));
let da = shape.edges().add(Edge::line_segment([v4, v1]));
let abcd = shape.cycles().add(Cycle { let abcd = shape.cycles().add(Cycle {
edges: vec![ab, bc, cd, da], edges: vec![ab, bc, cd, da],
}); });
let surface = shape.surfaces().add(Surface::x_y_plane());
let face = Face::Face { let face = Face::Face {
surface: Surface::x_y_plane(), surface,
cycles: vec![abcd], cycles: vec![abcd],
}; };

View File

@ -71,10 +71,7 @@ mod tests {
kernel::{ kernel::{
geometry::{surfaces::Swept, Surface}, geometry::{surfaces::Swept, Surface},
shape::{handle::Handle, Shape}, shape::{handle::Handle, Shape},
topology::{ topology::{edges::Cycle, faces::Face},
edges::{Cycle, Edge},
faces::Face,
},
}, },
math::{Point, Scalar, Vector}, math::{Point, Scalar, Vector},
}; };
@ -115,24 +112,22 @@ mod tests {
let b = shape.vertices().add(b.into()); let b = shape.vertices().add(b.into());
let c = shape.vertices().add(c.into()); let c = shape.vertices().add(c.into());
let ab = shape let ab = shape.edges().add_line_segment([a.clone(), b.clone()]);
.edges() let bc = shape.edges().add_line_segment([b.clone(), c.clone()]);
.add(Edge::line_segment([a.clone(), b.clone()])); let ca = shape.edges().add_line_segment([c.clone(), a.clone()]);
let bc = shape
.edges()
.add(Edge::line_segment([b.clone(), c.clone()]));
let ca = shape
.edges()
.add(Edge::line_segment([c.clone(), a.clone()]));
let cycles = shape.cycles().add(Cycle { let cycles = shape.cycles().add(Cycle {
edges: vec![ab, bc, ca], edges: vec![ab, bc, ca],
}); });
let surface =
shape
.surfaces()
.add(Surface::Swept(Swept::plane_from_points(
[a, b, c].map(|vertex| vertex.point()),
)));
let abc = Face::Face { let abc = Face::Face {
surface: Surface::Swept(Swept::plane_from_points( surface,
[a, b, c].map(|vertex| vertex.point()),
)),
cycles: vec![cycles], cycles: vec![cycles],
}; };

View File

@ -44,6 +44,9 @@ pub fn transform_face(
let mut edges = Vec::new(); let mut edges = Vec::new();
for edge in &cycle.edges { for edge in &cycle.edges {
let curve =
shape.curves().add(edge.curve.transform(transform));
let vertices = edge.vertices.clone().map(|vertices| { let vertices = edge.vertices.clone().map(|vertices| {
vertices.map(|vertex| { vertices.map(|vertex| {
let point = let point =
@ -53,10 +56,7 @@ pub fn transform_face(
}) })
}); });
let edge = Edge { let edge = Edge { curve, vertices };
curve: edge.curve.transform(transform),
vertices,
};
let edge = shape.edges().add(edge); let edge = shape.edges().add(edge);
edges.push(edge); edges.push(edge);
@ -65,9 +65,11 @@ pub fn transform_face(
cycles_trans.push(shape.cycles().add(Cycle { edges })); cycles_trans.push(shape.cycles().add(Cycle { edges }));
} }
let surface = shape.surfaces().add(surface.transform(transform));
Face::Face { Face::Face {
cycles: cycles_trans, cycles: cycles_trans,
surface: surface.transform(transform), surface,
} }
} }
Face::Triangles(mut triangles) => { Face::Triangles(mut triangles) => {

View File

@ -0,0 +1,13 @@
use crate::kernel::geometry::Curve;
use super::handle::{Handle, Storage};
/// API to access the curves of a shape
pub struct Curves;
impl Curves {
/// Add a curve to the shape
pub fn add(&mut self, curve: Curve) -> Handle<Curve> {
Storage::new(curve).handle()
}
}

View File

@ -1,9 +1,20 @@
use crate::kernel::topology::edges::Edge; use crate::{
kernel::{
geometry::{Circle, Curve, Line},
topology::{edges::Edge, vertices::Vertex},
},
math::{Point, Scalar, Vector},
};
use super::handle::{Handle, Storage}; use super::{
curves::Curves,
handle::{Handle, Storage},
};
/// The edges of a shape /// The edges of a shape
pub struct Edges; pub struct Edges {
pub(super) curves: Curves,
}
impl Edges { impl Edges {
/// Add an edge to the shape /// Add an edge to the shape
@ -23,4 +34,36 @@ impl Edges {
pub fn add(&mut self, edge: Edge) -> Handle<Edge> { pub fn add(&mut self, edge: Edge) -> Handle<Edge> {
Storage::new(edge).handle() Storage::new(edge).handle()
} }
/// Add a circle to the shape
///
/// Calls [`Edges::add`] internally, and is subject to the same
/// restrictions.
pub fn add_circle(&mut self, radius: Scalar) -> Handle<Edge> {
let curve = self.curves.add(Curve::Circle(Circle {
center: Point::origin(),
radius: Vector::from([radius, Scalar::ZERO]),
}));
self.add(Edge {
curve,
vertices: None,
})
}
/// Add a line segment to the shape
///
/// Calls [`Edges::add`] internally, and is subject to the same
/// restrictions.
pub fn add_line_segment(
&mut self,
vertices: [Handle<Vertex>; 2],
) -> Handle<Edge> {
let curve = self.curves.add(Curve::Line(Line::from_points(
vertices.clone().map(|vertex| vertex.point()),
)));
self.add(Edge {
curve,
vertices: Some(vertices),
})
}
} }

View File

@ -1,7 +1,9 @@
pub mod curves;
pub mod cycles; pub mod cycles;
pub mod edges; pub mod edges;
pub mod faces; pub mod faces;
pub mod handle; pub mod handle;
pub mod surfaces;
pub mod vertices; pub mod vertices;
use crate::math::Scalar; use crate::math::Scalar;
@ -9,8 +11,8 @@ use crate::math::Scalar;
use super::topology::{edges::Cycle, faces::Face, vertices::Vertex}; use super::topology::{edges::Cycle, faces::Face, vertices::Vertex};
use self::{ use self::{
cycles::Cycles, edges::Edges, faces::Faces, handle::Storage, curves::Curves, cycles::Cycles, edges::Edges, faces::Faces,
vertices::Vertices, handle::Storage, surfaces::Surfaces, vertices::Vertices,
}; };
/// The boundary representation of a shape /// The boundary representation of a shape
@ -56,6 +58,16 @@ impl Shape {
self self
} }
/// Access the shape's curves
pub fn curves(&mut self) -> Curves {
Curves
}
/// Access the shape's surfaces
pub fn surfaces(&mut self) -> Surfaces {
Surfaces
}
/// Access the shape's vertices /// Access the shape's vertices
pub fn vertices(&mut self) -> Vertices { pub fn vertices(&mut self) -> Vertices {
Vertices { Vertices {
@ -66,7 +78,7 @@ impl Shape {
/// Access the shape's edges /// Access the shape's edges
pub fn edges(&mut self) -> Edges { pub fn edges(&mut self) -> Edges {
Edges Edges { curves: Curves }
} }
/// Access the shape's cycles /// Access the shape's cycles

View File

@ -0,0 +1,13 @@
use crate::kernel::geometry::Surface;
use super::handle::{Handle, Storage};
/// API to access the surfaces of a shape
pub struct Surfaces;
impl Surfaces {
/// Add a surface to the shape
pub fn add(&mut self, surface: Surface) -> Handle<Surface> {
Storage::new(surface).handle()
}
}

View File

@ -3,10 +3,7 @@ use crate::{
kernel::{ kernel::{
geometry::Surface, geometry::Surface,
shape::Shape, shape::Shape,
topology::{ topology::{edges::Cycle, faces::Face},
edges::{Cycle, Edge},
faces::Face,
},
}, },
math::{Aabb, Point, Scalar}, math::{Aabb, Point, Scalar},
}; };
@ -20,16 +17,12 @@ impl ToShape for fj::Circle {
// Circles have just a single round edge with no vertices. So none need // Circles have just a single round edge with no vertices. So none need
// to be added here. // to be added here.
let edge = shape let edge = shape.edges().add_circle(Scalar::from_f64(self.radius));
.edges()
.add(Edge::circle(Scalar::from_f64(self.radius)));
shape.cycles().add(Cycle { edges: vec![edge] }); shape.cycles().add(Cycle { edges: vec![edge] });
let cycles = shape.cycles().all().collect(); let cycles = shape.cycles().all().collect();
shape.faces().add(Face::Face { let surface = shape.surfaces().add(Surface::x_y_plane());
cycles, shape.faces().add(Face::Face { cycles, surface });
surface: Surface::x_y_plane(),
});
shape shape
} }

View File

@ -3,10 +3,7 @@ use crate::{
kernel::{ kernel::{
geometry::Surface, geometry::Surface,
shape::Shape, shape::Shape,
topology::{ topology::{edges::Cycle, faces::Face},
edges::{Cycle, Edge},
faces::Face,
},
}, },
math::{Aabb, Point, Scalar}, math::{Aabb, Point, Scalar},
}; };
@ -40,16 +37,17 @@ impl ToShape for fj::Sketch {
let a = window[0].clone(); let a = window[0].clone();
let b = window[1].clone(); let b = window[1].clone();
let edge = shape.edges().add(Edge::line_segment([a, b])); let edge = shape.edges().add_line_segment([a, b]);
edges.push(edge); edges.push(edge);
} }
shape.cycles().add(Cycle { edges }); shape.cycles().add(Cycle { edges });
}; };
let surface = shape.surfaces().add(Surface::x_y_plane());
let face = Face::Face { let face = Face::Face {
cycles: shape.cycles().all().collect(), cycles: shape.cycles().all().collect(),
surface: Surface::x_y_plane(), surface,
}; };
shape.faces().add(face); shape.faces().add(face);

View File

@ -1,10 +1,4 @@
use crate::{ use crate::kernel::{geometry::Curve, shape::handle::Handle};
kernel::{
geometry::{Circle, Curve, Line},
shape::handle::Handle,
},
math::{Point, Scalar, Vector},
};
use super::vertices::Vertex; use super::vertices::Vertex;
@ -26,7 +20,7 @@ pub struct Edge {
/// The edge can be a segment of the curve that is bounded by two vertices, /// The edge can be a segment of the curve that is bounded by two vertices,
/// or if the curve is continuous (i.e. connects to itself), the edge could /// or if the curve is continuous (i.e. connects to itself), the edge could
/// be defined by the whole curve, and have no bounding vertices. /// be defined by the whole curve, and have no bounding vertices.
pub curve: Curve, pub curve: Handle<Curve>,
/// Access the vertices that bound the edge on the curve /// Access the vertices that bound the edge on the curve
/// ///
@ -44,26 +38,3 @@ pub struct Edge {
/// and store 1D vertices again, at some point. /// and store 1D vertices again, at some point.
pub vertices: Option<[Handle<Vertex>; 2]>, pub vertices: Option<[Handle<Vertex>; 2]>,
} }
impl Edge {
/// Create a line segment
pub fn line_segment(vertices: [Handle<Vertex>; 2]) -> Self {
Edge {
curve: Curve::Line(Line::from_points(
vertices.clone().map(|vertex| vertex.point()),
)),
vertices: Some(vertices),
}
}
/// Create a circle
pub fn circle(radius: Scalar) -> Self {
Edge {
curve: Curve::Circle(Circle {
center: Point::origin(),
radius: Vector::from([radius, Scalar::ZERO]),
}),
vertices: None,
}
}
}

View File

@ -26,7 +26,7 @@ pub enum Face {
/// surface. /// surface.
Face { Face {
/// The surface that defines this face /// The surface that defines this face
surface: Surface, surface: Handle<Surface>,
/// The cycles that bound the face /// The cycles that bound the face
/// ///