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::{
|
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],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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) => {
|
||||||
|
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
|
/// 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),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
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::{
|
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
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user