mirror of
https://github.com/hannobraun/Fornjot
synced 2025-02-25 00:25:51 +00:00
Merge pull request #418 from hannobraun/builder
Extend builder API, use it to simplify approximation tests
This commit is contained in:
commit
a53c275ddd
@ -120,7 +120,7 @@ mod tests {
|
|||||||
use crate::{
|
use crate::{
|
||||||
geometry::Surface,
|
geometry::Surface,
|
||||||
shape::Shape,
|
shape::Shape,
|
||||||
topology::{Cycle, Edge, Face, Vertex},
|
topology::{Cycle, Face, Vertex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Approximation;
|
use super::Approximation;
|
||||||
@ -162,23 +162,7 @@ mod tests {
|
|||||||
let c = Point::from([3., 5., 8.]);
|
let c = Point::from([3., 5., 8.]);
|
||||||
let d = Point::from([5., 8., 13.]);
|
let d = Point::from([5., 8., 13.]);
|
||||||
|
|
||||||
let v1 = Vertex::build(&mut shape).from_point(a)?;
|
let abcd = Cycle::build(&mut shape).polygon([a, b, c, d])?;
|
||||||
let v2 = Vertex::build(&mut shape).from_point(b)?;
|
|
||||||
let v3 = Vertex::build(&mut shape).from_point(c)?;
|
|
||||||
let v4 = Vertex::build(&mut shape).from_point(d)?;
|
|
||||||
|
|
||||||
let ab = Edge::build(&mut shape)
|
|
||||||
.line_segment_from_vertices([v1.clone(), v2.clone()])?;
|
|
||||||
let bc = Edge::build(&mut shape)
|
|
||||||
.line_segment_from_vertices([v2, v3.clone()])?;
|
|
||||||
let cd = Edge::build(&mut shape)
|
|
||||||
.line_segment_from_vertices([v3, v4.clone()])?;
|
|
||||||
let da =
|
|
||||||
Edge::build(&mut shape).line_segment_from_vertices([v4, v1])?;
|
|
||||||
|
|
||||||
let abcd = shape.insert(Cycle {
|
|
||||||
edges: vec![ab, bc, cd, da],
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let surface = shape.insert(Surface::x_y_plane())?;
|
let surface = shape.insert(Surface::x_y_plane())?;
|
||||||
let face = Face::Face {
|
let face = Face::Face {
|
||||||
|
@ -326,7 +326,7 @@ mod tests {
|
|||||||
use crate::{
|
use crate::{
|
||||||
geometry::{Surface, SweptCurve},
|
geometry::{Surface, SweptCurve},
|
||||||
shape::{Handle, Shape},
|
shape::{Handle, Shape},
|
||||||
topology::{Cycle, Edge, Face, Vertex},
|
topology::{Cycle, Edge, Face},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::sweep_shape;
|
use super::sweep_shape;
|
||||||
@ -377,32 +377,24 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Triangle {
|
impl Triangle {
|
||||||
fn new([a, b, c]: [impl Into<Point<3>>; 3]) -> anyhow::Result<Self> {
|
fn new(points: [impl Into<Point<3>>; 3]) -> anyhow::Result<Self> {
|
||||||
let mut shape = Shape::new();
|
let mut shape = Shape::new();
|
||||||
|
|
||||||
let a = shape.insert(a.into())?;
|
let [a, b, c] = points.map(|point| point.into());
|
||||||
let b = shape.insert(b.into())?;
|
|
||||||
let c = shape.insert(c.into())?;
|
|
||||||
|
|
||||||
let a = shape.insert(Vertex { point: a })?;
|
let ab =
|
||||||
let b = shape.insert(Vertex { point: b })?;
|
Edge::build(&mut shape).line_segment_from_points([a, b])?;
|
||||||
let c = shape.insert(Vertex { point: c })?;
|
let bc =
|
||||||
|
Edge::build(&mut shape).line_segment_from_points([b, c])?;
|
||||||
let ab = Edge::build(&mut shape)
|
let ca =
|
||||||
.line_segment_from_vertices([a.clone(), b.clone()])?;
|
Edge::build(&mut shape).line_segment_from_points([c, a])?;
|
||||||
let bc = Edge::build(&mut shape)
|
|
||||||
.line_segment_from_vertices([b.clone(), c.clone()])?;
|
|
||||||
let ca = Edge::build(&mut shape)
|
|
||||||
.line_segment_from_vertices([c.clone(), a.clone()])?;
|
|
||||||
|
|
||||||
let cycles = shape.insert(Cycle {
|
let cycles = shape.insert(Cycle {
|
||||||
edges: vec![ab, bc, ca],
|
edges: vec![ab, bc, ca],
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let surface = shape.insert(Surface::SweptCurve(
|
let surface = shape.insert(Surface::SweptCurve(
|
||||||
SweptCurve::plane_from_points(
|
SweptCurve::plane_from_points([a, b, c]),
|
||||||
[a, b, c].map(|vertex| vertex.get().point()),
|
|
||||||
),
|
|
||||||
))?;
|
))?;
|
||||||
let abc = Face::Face {
|
let abc = Face::Face {
|
||||||
surface,
|
surface,
|
||||||
|
@ -191,15 +191,13 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_edge(&mut self) -> anyhow::Result<Handle<Edge>> {
|
fn add_edge(&mut self) -> anyhow::Result<Handle<Edge>> {
|
||||||
let vertices = [(); 2].map(|()| {
|
let points = [(); 2].map(|()| {
|
||||||
let point = self.next_point;
|
let point = self.next_point;
|
||||||
self.next_point.x += Scalar::ONE;
|
self.next_point.x += Scalar::ONE;
|
||||||
|
point
|
||||||
let point = self.insert(point).unwrap();
|
|
||||||
self.insert(Vertex { point }).unwrap()
|
|
||||||
});
|
});
|
||||||
let edge = Edge::build(&mut self.inner)
|
let edge = Edge::build(&mut self.inner)
|
||||||
.line_segment_from_vertices(vertices)?;
|
.line_segment_from_points(points)?;
|
||||||
|
|
||||||
Ok(edge)
|
Ok(edge)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
shape::{Handle, Shape, ValidationResult},
|
shape::{Handle, Shape, ValidationResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{Edge, Vertex};
|
use super::{Cycle, Edge, Vertex};
|
||||||
|
|
||||||
/// API for building a [`Vertex`]
|
/// API for building a [`Vertex`]
|
||||||
pub struct VertexBuilder<'r> {
|
pub struct VertexBuilder<'r> {
|
||||||
@ -19,12 +19,15 @@ impl<'r> VertexBuilder<'r> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Build a [`Vertex`] from a point
|
/// Build a [`Vertex`] from a point
|
||||||
|
///
|
||||||
|
/// If an identical point or vertex are already part of the shape, those
|
||||||
|
/// objects are re-used.
|
||||||
pub fn from_point(
|
pub fn from_point(
|
||||||
self,
|
self,
|
||||||
point: impl Into<Point<3>>,
|
point: impl Into<Point<3>>,
|
||||||
) -> ValidationResult<Vertex> {
|
) -> ValidationResult<Vertex> {
|
||||||
let point = self.shape.insert(point.into())?;
|
let point = self.shape.get_handle_or_insert(point.into())?;
|
||||||
let vertex = self.shape.insert(Vertex { point })?;
|
let vertex = self.shape.get_handle_or_insert(Vertex { point })?;
|
||||||
|
|
||||||
Ok(vertex)
|
Ok(vertex)
|
||||||
}
|
}
|
||||||
@ -55,6 +58,25 @@ impl<'r> EdgeBuilder<'r> {
|
|||||||
Ok(edge)
|
Ok(edge)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build a line segment from two points
|
||||||
|
pub fn line_segment_from_points(
|
||||||
|
self,
|
||||||
|
vertices: [impl Into<Point<3>>; 2],
|
||||||
|
) -> ValidationResult<Edge> {
|
||||||
|
// Can be cleaned up with `try_map`, once that is stable:
|
||||||
|
// https://doc.rust-lang.org/std/primitive.array.html#method.try_map
|
||||||
|
let vertices =
|
||||||
|
vertices.map(|point| Vertex::build(self.shape).from_point(point));
|
||||||
|
let vertices = match vertices {
|
||||||
|
[Ok(a), Ok(b)] => Ok([a, b]),
|
||||||
|
[Err(err), _] | [_, Err(err)] => Err(err),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let edge = self.line_segment_from_vertices(vertices)?;
|
||||||
|
|
||||||
|
Ok(edge)
|
||||||
|
}
|
||||||
|
|
||||||
/// Build a line segment from two vertices
|
/// Build a line segment from two vertices
|
||||||
pub fn line_segment_from_vertices(
|
pub fn line_segment_from_vertices(
|
||||||
self,
|
self,
|
||||||
@ -71,3 +93,42 @@ impl<'r> EdgeBuilder<'r> {
|
|||||||
Ok(edge)
|
Ok(edge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// API for building a [`Cycle`]
|
||||||
|
pub struct CycleBuilder<'r> {
|
||||||
|
shape: &'r mut Shape,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r> CycleBuilder<'r> {
|
||||||
|
/// Construct a new instance of `CycleBuilder`
|
||||||
|
pub fn new(shape: &'r mut Shape) -> Self {
|
||||||
|
Self { shape }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build a polygon from a list of points
|
||||||
|
pub fn polygon(
|
||||||
|
self,
|
||||||
|
points: impl IntoIterator<Item = impl Into<Point<3>>>,
|
||||||
|
) -> ValidationResult<Cycle> {
|
||||||
|
// A polygon is closed, so we need to add the first point at the end
|
||||||
|
// again, for the next step.
|
||||||
|
let mut points: Vec<_> = points.into_iter().map(Into::into).collect();
|
||||||
|
if let Some(point) = points.first().cloned() {
|
||||||
|
points.push(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut edges = Vec::new();
|
||||||
|
for ab in points.windows(2) {
|
||||||
|
// Can't panic, as we passed `2` to `windows`.
|
||||||
|
//
|
||||||
|
// Can be cleaned up, once `array_windows` is stable.
|
||||||
|
let points = [ab[0], ab[1]];
|
||||||
|
|
||||||
|
let edge =
|
||||||
|
Edge::build(self.shape).line_segment_from_points(points)?;
|
||||||
|
edges.push(edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.shape.insert(Cycle { edges })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
shape::{Handle, Shape},
|
shape::{Handle, Shape},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{vertices::Vertex, EdgeBuilder};
|
use super::{builder::CycleBuilder, vertices::Vertex, EdgeBuilder};
|
||||||
|
|
||||||
/// A cycle of connected edges
|
/// A cycle of connected edges
|
||||||
///
|
///
|
||||||
@ -29,6 +29,11 @@ pub struct Cycle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Cycle {
|
impl Cycle {
|
||||||
|
/// Build a cycle using the [`CycleBuilder`] API
|
||||||
|
pub fn build(shape: &mut Shape) -> CycleBuilder {
|
||||||
|
CycleBuilder::new(shape)
|
||||||
|
}
|
||||||
|
|
||||||
/// Access the edges that this cycle refers to
|
/// Access the edges that this cycle refers to
|
||||||
///
|
///
|
||||||
/// This is a convenience method that saves the caller from dealing with the
|
/// This is a convenience method that saves the caller from dealing with the
|
||||||
|
Loading…
Reference in New Issue
Block a user