mirror of
https://github.com/hannobraun/Fornjot
synced 2025-02-25 16:45:52 +00:00
Merge pull request #310 from hannobraun/shape
Track curves and surfaces through `Shape`
This commit is contained in:
commit
bc863610d5
@ -150,10 +150,7 @@ mod tests {
|
||||
kernel::{
|
||||
geometry::Surface,
|
||||
shape::Shape,
|
||||
topology::{
|
||||
edges::{Cycle, Edge},
|
||||
faces::Face,
|
||||
},
|
||||
topology::{edges::Cycle, faces::Face},
|
||||
},
|
||||
math::{Point, Scalar, Segment},
|
||||
};
|
||||
@ -214,11 +211,9 @@ mod tests {
|
||||
let v2 = shape.vertices().add(b);
|
||||
let v3 = shape.vertices().add(c);
|
||||
|
||||
let ab = shape
|
||||
.edges()
|
||||
.add(Edge::line_segment([v1.clone(), v2.clone()]));
|
||||
let bc = shape.edges().add(Edge::line_segment([v2, v3.clone()]));
|
||||
let ca = shape.edges().add(Edge::line_segment([v3, v1]));
|
||||
let ab = shape.edges().add_line_segment([v1.clone(), v2.clone()]);
|
||||
let bc = shape.edges().add_line_segment([v2, v3.clone()]);
|
||||
let ca = shape.edges().add_line_segment([v3, v1]);
|
||||
|
||||
let cycle = Cycle {
|
||||
edges: vec![ab, bc, ca],
|
||||
@ -255,19 +250,18 @@ mod tests {
|
||||
let v3 = shape.vertices().add(c);
|
||||
let v4 = shape.vertices().add(d);
|
||||
|
||||
let ab = shape
|
||||
.edges()
|
||||
.add(Edge::line_segment([v1.clone(), v2.clone()]));
|
||||
let bc = shape.edges().add(Edge::line_segment([v2, v3.clone()]));
|
||||
let cd = shape.edges().add(Edge::line_segment([v3, v4.clone()]));
|
||||
let da = shape.edges().add(Edge::line_segment([v4, v1]));
|
||||
let ab = shape.edges().add_line_segment([v1.clone(), v2.clone()]);
|
||||
let bc = shape.edges().add_line_segment([v2, v3.clone()]);
|
||||
let cd = shape.edges().add_line_segment([v3, v4.clone()]);
|
||||
let da = shape.edges().add_line_segment([v4, v1]);
|
||||
|
||||
let abcd = shape.cycles().add(Cycle {
|
||||
edges: vec![ab, bc, cd, da],
|
||||
});
|
||||
|
||||
let surface = shape.surfaces().add(Surface::x_y_plane());
|
||||
let face = Face::Face {
|
||||
surface: Surface::x_y_plane(),
|
||||
surface,
|
||||
cycles: vec![abcd],
|
||||
};
|
||||
|
||||
|
@ -71,10 +71,7 @@ mod tests {
|
||||
kernel::{
|
||||
geometry::{surfaces::Swept, Surface},
|
||||
shape::{handle::Handle, Shape},
|
||||
topology::{
|
||||
edges::{Cycle, Edge},
|
||||
faces::Face,
|
||||
},
|
||||
topology::{edges::Cycle, faces::Face},
|
||||
},
|
||||
math::{Point, Scalar, Vector},
|
||||
};
|
||||
@ -115,24 +112,22 @@ mod tests {
|
||||
let b = shape.vertices().add(b.into());
|
||||
let c = shape.vertices().add(c.into());
|
||||
|
||||
let ab = shape
|
||||
.edges()
|
||||
.add(Edge::line_segment([a.clone(), b.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 ab = shape.edges().add_line_segment([a.clone(), b.clone()]);
|
||||
let bc = shape.edges().add_line_segment([b.clone(), c.clone()]);
|
||||
let ca = shape.edges().add_line_segment([c.clone(), a.clone()]);
|
||||
|
||||
let cycles = shape.cycles().add(Cycle {
|
||||
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 {
|
||||
surface: Surface::Swept(Swept::plane_from_points(
|
||||
[a, b, c].map(|vertex| vertex.point()),
|
||||
)),
|
||||
surface,
|
||||
cycles: vec![cycles],
|
||||
};
|
||||
|
||||
|
@ -44,6 +44,9 @@ pub fn transform_face(
|
||||
let mut edges = Vec::new();
|
||||
|
||||
for edge in &cycle.edges {
|
||||
let curve =
|
||||
shape.curves().add(edge.curve.transform(transform));
|
||||
|
||||
let vertices = edge.vertices.clone().map(|vertices| {
|
||||
vertices.map(|vertex| {
|
||||
let point =
|
||||
@ -53,10 +56,7 @@ pub fn transform_face(
|
||||
})
|
||||
});
|
||||
|
||||
let edge = Edge {
|
||||
curve: edge.curve.transform(transform),
|
||||
vertices,
|
||||
};
|
||||
let edge = Edge { curve, vertices };
|
||||
let edge = shape.edges().add(edge);
|
||||
|
||||
edges.push(edge);
|
||||
@ -65,9 +65,11 @@ pub fn transform_face(
|
||||
cycles_trans.push(shape.cycles().add(Cycle { edges }));
|
||||
}
|
||||
|
||||
let surface = shape.surfaces().add(surface.transform(transform));
|
||||
|
||||
Face::Face {
|
||||
cycles: cycles_trans,
|
||||
surface: surface.transform(transform),
|
||||
surface,
|
||||
}
|
||||
}
|
||||
Face::Triangles(mut triangles) => {
|
||||
|
13
src/kernel/shape/curves.rs
Normal file
13
src/kernel/shape/curves.rs
Normal 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()
|
||||
}
|
||||
}
|
@ -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
|
||||
pub struct Edges;
|
||||
pub struct Edges {
|
||||
pub(super) curves: Curves,
|
||||
}
|
||||
|
||||
impl Edges {
|
||||
/// Add an edge to the shape
|
||||
@ -23,4 +34,36 @@ impl Edges {
|
||||
pub fn add(&mut self, edge: Edge) -> Handle<Edge> {
|
||||
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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
pub mod curves;
|
||||
pub mod cycles;
|
||||
pub mod edges;
|
||||
pub mod faces;
|
||||
pub mod handle;
|
||||
pub mod surfaces;
|
||||
pub mod vertices;
|
||||
|
||||
use crate::math::Scalar;
|
||||
@ -9,8 +11,8 @@ use crate::math::Scalar;
|
||||
use super::topology::{edges::Cycle, faces::Face, vertices::Vertex};
|
||||
|
||||
use self::{
|
||||
cycles::Cycles, edges::Edges, faces::Faces, handle::Storage,
|
||||
vertices::Vertices,
|
||||
curves::Curves, cycles::Cycles, edges::Edges, faces::Faces,
|
||||
handle::Storage, surfaces::Surfaces, vertices::Vertices,
|
||||
};
|
||||
|
||||
/// The boundary representation of a shape
|
||||
@ -56,6 +58,16 @@ impl Shape {
|
||||
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
|
||||
pub fn vertices(&mut self) -> Vertices {
|
||||
Vertices {
|
||||
@ -66,7 +78,7 @@ impl Shape {
|
||||
|
||||
/// Access the shape's edges
|
||||
pub fn edges(&mut self) -> Edges {
|
||||
Edges
|
||||
Edges { curves: Curves }
|
||||
}
|
||||
|
||||
/// Access the shape's cycles
|
||||
|
13
src/kernel/shape/surfaces.rs
Normal file
13
src/kernel/shape/surfaces.rs
Normal 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()
|
||||
}
|
||||
}
|
@ -3,10 +3,7 @@ use crate::{
|
||||
kernel::{
|
||||
geometry::Surface,
|
||||
shape::Shape,
|
||||
topology::{
|
||||
edges::{Cycle, Edge},
|
||||
faces::Face,
|
||||
},
|
||||
topology::{edges::Cycle, faces::Face},
|
||||
},
|
||||
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
|
||||
// to be added here.
|
||||
|
||||
let edge = shape
|
||||
.edges()
|
||||
.add(Edge::circle(Scalar::from_f64(self.radius)));
|
||||
let edge = shape.edges().add_circle(Scalar::from_f64(self.radius));
|
||||
shape.cycles().add(Cycle { edges: vec![edge] });
|
||||
|
||||
let cycles = shape.cycles().all().collect();
|
||||
shape.faces().add(Face::Face {
|
||||
cycles,
|
||||
surface: Surface::x_y_plane(),
|
||||
});
|
||||
let surface = shape.surfaces().add(Surface::x_y_plane());
|
||||
shape.faces().add(Face::Face { cycles, surface });
|
||||
|
||||
shape
|
||||
}
|
||||
|
@ -3,10 +3,7 @@ use crate::{
|
||||
kernel::{
|
||||
geometry::Surface,
|
||||
shape::Shape,
|
||||
topology::{
|
||||
edges::{Cycle, Edge},
|
||||
faces::Face,
|
||||
},
|
||||
topology::{edges::Cycle, faces::Face},
|
||||
},
|
||||
math::{Aabb, Point, Scalar},
|
||||
};
|
||||
@ -40,16 +37,17 @@ impl ToShape for fj::Sketch {
|
||||
let a = window[0].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);
|
||||
}
|
||||
|
||||
shape.cycles().add(Cycle { edges });
|
||||
};
|
||||
|
||||
let surface = shape.surfaces().add(Surface::x_y_plane());
|
||||
let face = Face::Face {
|
||||
cycles: shape.cycles().all().collect(),
|
||||
surface: Surface::x_y_plane(),
|
||||
surface,
|
||||
};
|
||||
shape.faces().add(face);
|
||||
|
||||
|
@ -1,10 +1,4 @@
|
||||
use crate::{
|
||||
kernel::{
|
||||
geometry::{Circle, Curve, Line},
|
||||
shape::handle::Handle,
|
||||
},
|
||||
math::{Point, Scalar, Vector},
|
||||
};
|
||||
use crate::kernel::{geometry::Curve, shape::handle::Handle};
|
||||
|
||||
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,
|
||||
/// 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.
|
||||
pub curve: Curve,
|
||||
pub curve: Handle<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.
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ pub enum Face {
|
||||
/// surface.
|
||||
Face {
|
||||
/// The surface that defines this face
|
||||
surface: Surface,
|
||||
surface: Handle<Surface>,
|
||||
|
||||
/// The cycles that bound the face
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user