mirror of https://github.com/hannobraun/Fornjot
commit
74d745c644
|
@ -37,20 +37,18 @@ mod test {
|
|||
use crate::{
|
||||
geometry,
|
||||
objects::{Vertex, VerticesOfEdge},
|
||||
shape::{LocalForm, Shape},
|
||||
shape::LocalForm,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn approx_edge() {
|
||||
let mut shape = Shape::new();
|
||||
|
||||
let a = Point::from([1., 2., 3.]);
|
||||
let b = Point::from([2., 3., 5.]);
|
||||
let c = Point::from([3., 5., 8.]);
|
||||
let d = Point::from([5., 8., 13.]);
|
||||
|
||||
let v1 = Vertex::builder(&mut shape).build_from_point(a).get();
|
||||
let v2 = Vertex::builder(&mut shape).build_from_point(d).get();
|
||||
let v1 = Vertex::from_point(a);
|
||||
let v2 = Vertex::from_point(d);
|
||||
|
||||
let vertices = VerticesOfEdge::from_vertices([
|
||||
LocalForm::new(Point::from([0.]), v1),
|
||||
|
|
|
@ -84,7 +84,6 @@ mod tests {
|
|||
use crate::{
|
||||
geometry,
|
||||
objects::{Face, Surface},
|
||||
shape::Shape,
|
||||
};
|
||||
|
||||
use super::{CycleApprox, FaceApprox, Tolerance};
|
||||
|
@ -95,8 +94,6 @@ mod tests {
|
|||
|
||||
let tolerance = Tolerance::from_scalar(Scalar::ONE)?;
|
||||
|
||||
let mut shape = Shape::new();
|
||||
|
||||
let a = Point::from([0., 0.]);
|
||||
let b = Point::from([3., 0.]);
|
||||
let c = Point::from([3., 3.]);
|
||||
|
@ -107,7 +104,7 @@ mod tests {
|
|||
let g = Point::from([2., 2.]);
|
||||
let h = Point::from([1., 2.]);
|
||||
|
||||
let face = Face::builder(Surface::xy_plane(), &mut shape)
|
||||
let face = Face::builder(Surface::xy_plane())
|
||||
.with_exterior_polygon([a, b, c, d])
|
||||
.with_interior_polygon([e, f, g, h])
|
||||
.build();
|
||||
|
@ -130,7 +127,7 @@ mod tests {
|
|||
let g = geometry::Point::new(g, g);
|
||||
let h = geometry::Point::new(h, h);
|
||||
|
||||
let approx = FaceApprox::new(&face.get(), tolerance);
|
||||
let approx = FaceApprox::new(&face, tolerance);
|
||||
let expected = FaceApprox {
|
||||
points: set![a, b, c, d, e, f, g, h],
|
||||
exterior: CycleApprox {
|
||||
|
|
|
@ -273,7 +273,6 @@ mod tests {
|
|||
algorithms::Tolerance,
|
||||
iter::ObjectIters,
|
||||
objects::{Face, Surface},
|
||||
shape::Shape,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -362,12 +361,9 @@ mod tests {
|
|||
) -> anyhow::Result<()> {
|
||||
let tolerance = Tolerance::from_scalar(Scalar::ONE)?;
|
||||
|
||||
let mut shape = Shape::new();
|
||||
|
||||
let sketch = Face::builder(Surface::xy_plane(), &mut shape)
|
||||
let sketch = Face::builder(Surface::xy_plane())
|
||||
.with_exterior_polygon([[0., 0.], [1., 0.], [0., 1.]])
|
||||
.build()
|
||||
.get();
|
||||
.build();
|
||||
|
||||
let solid =
|
||||
super::sweep(vec![sketch], direction, tolerance, [255, 0, 0, 255]);
|
||||
|
@ -377,14 +373,12 @@ mod tests {
|
|||
.map(|vertex| vertex.into())
|
||||
.collect();
|
||||
|
||||
let mut shape = Shape::new();
|
||||
let faces = expected_surfaces.into_iter().map(|surface| {
|
||||
let surface = Surface::plane_from_points(surface);
|
||||
|
||||
Face::builder(surface, &mut shape)
|
||||
Face::builder(surface)
|
||||
.with_exterior_polygon(expected_vertices.clone())
|
||||
.build()
|
||||
.get()
|
||||
});
|
||||
|
||||
for face in faces {
|
||||
|
|
|
@ -89,22 +89,18 @@ mod tests {
|
|||
use crate::{
|
||||
algorithms::Tolerance,
|
||||
objects::{Face, Surface},
|
||||
shape::Shape,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn simple() -> anyhow::Result<()> {
|
||||
let mut shape = Shape::new();
|
||||
|
||||
let a = [0., 0.];
|
||||
let b = [2., 0.];
|
||||
let c = [2., 2.];
|
||||
let d = [0., 1.];
|
||||
|
||||
let face = Face::builder(Surface::xy_plane(), &mut shape)
|
||||
let face = Face::builder(Surface::xy_plane())
|
||||
.with_exterior_polygon([a, b, c, d])
|
||||
.build()
|
||||
.get();
|
||||
.build();
|
||||
|
||||
let a = Point::from(a).to_xyz();
|
||||
let b = Point::from(b).to_xyz();
|
||||
|
@ -123,8 +119,6 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn simple_hole() -> anyhow::Result<()> {
|
||||
let mut shape = Shape::new();
|
||||
|
||||
let a = [0., 0.];
|
||||
let b = [4., 0.];
|
||||
let c = [4., 4.];
|
||||
|
@ -135,11 +129,10 @@ mod tests {
|
|||
let g = [3., 3.];
|
||||
let h = [1., 2.];
|
||||
|
||||
let face = Face::builder(Surface::xy_plane(), &mut shape)
|
||||
let face = Face::builder(Surface::xy_plane())
|
||||
.with_exterior_polygon([a, b, c, d])
|
||||
.with_interior_polygon([e, f, g, h])
|
||||
.build()
|
||||
.get();
|
||||
.build();
|
||||
|
||||
let triangles = triangulate(face)?;
|
||||
|
||||
|
|
|
@ -1,191 +1,26 @@
|
|||
//! Convenient API to build objects
|
||||
|
||||
use fj_math::{Circle, Line, Point, Scalar, Vector};
|
||||
use fj_math::Point;
|
||||
|
||||
use crate::{
|
||||
objects::{Curve, Cycle, Edge, Face, Surface, Vertex, VerticesOfEdge},
|
||||
shape::{Handle, LocalForm, Shape},
|
||||
};
|
||||
|
||||
/// API for building a [`Vertex`]
|
||||
#[must_use]
|
||||
pub struct VertexBuilder<'r> {
|
||||
shape: &'r mut Shape,
|
||||
}
|
||||
|
||||
impl<'r> VertexBuilder<'r> {
|
||||
/// Construct a new instance of `VertexBuilder`
|
||||
pub fn new(shape: &'r mut Shape) -> Self {
|
||||
Self { shape }
|
||||
}
|
||||
|
||||
/// 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 build_from_point(
|
||||
self,
|
||||
point: impl Into<Point<3>>,
|
||||
) -> Handle<Vertex> {
|
||||
let point = point.into();
|
||||
self.shape.get_handle_or_insert(Vertex { point })
|
||||
}
|
||||
}
|
||||
|
||||
/// API for building an [`Edge`]
|
||||
#[must_use]
|
||||
pub struct EdgeBuilder<'r> {
|
||||
shape: &'r mut Shape,
|
||||
}
|
||||
|
||||
impl<'r> EdgeBuilder<'r> {
|
||||
/// Construct a new instance of `EdgeBuilder`
|
||||
pub fn new(shape: &'r mut Shape) -> Self {
|
||||
Self { shape }
|
||||
}
|
||||
|
||||
/// Build a circle from a radius
|
||||
pub fn build_circle(self, radius: Scalar) -> LocalForm<Edge<2>, Edge<3>> {
|
||||
let curve_local = Curve::Circle(Circle {
|
||||
center: Point::origin(),
|
||||
a: Vector::from([radius, Scalar::ZERO]),
|
||||
b: Vector::from([Scalar::ZERO, radius]),
|
||||
});
|
||||
let curve_canonical = Curve::Circle(Circle {
|
||||
center: Point::origin(),
|
||||
a: Vector::from([radius, Scalar::ZERO, Scalar::ZERO]),
|
||||
b: Vector::from([Scalar::ZERO, radius, Scalar::ZERO]),
|
||||
});
|
||||
|
||||
let edge_local = Edge {
|
||||
curve: LocalForm::new(curve_local, curve_canonical),
|
||||
vertices: VerticesOfEdge::none(),
|
||||
};
|
||||
let edge_canonical = Edge {
|
||||
curve: LocalForm::canonical_only(curve_canonical),
|
||||
vertices: VerticesOfEdge::none(),
|
||||
};
|
||||
|
||||
LocalForm::new(edge_local, edge_canonical)
|
||||
}
|
||||
|
||||
/// Build a line segment from two points
|
||||
pub fn build_line_segment_from_points(
|
||||
self,
|
||||
vertices: [impl Into<Point<3>>; 2],
|
||||
) -> Handle<Edge<3>> {
|
||||
let vertices = vertices.map(|point| {
|
||||
let point = point.into();
|
||||
Vertex { point }
|
||||
});
|
||||
|
||||
self.build_line_segment_from_vertices(vertices)
|
||||
}
|
||||
|
||||
/// Build a line segment from two vertices
|
||||
pub fn build_line_segment_from_vertices(
|
||||
self,
|
||||
[a, b]: [Vertex; 2],
|
||||
) -> Handle<Edge<3>> {
|
||||
let curve = {
|
||||
let points = [a, b].map(|vertex| vertex.point);
|
||||
Curve::Line(Line::from_points(points))
|
||||
};
|
||||
|
||||
let vertices = [
|
||||
LocalForm::new(Point::from([0.]), a),
|
||||
LocalForm::new(Point::from([1.]), b),
|
||||
];
|
||||
|
||||
self.shape.get_handle_or_insert(Edge {
|
||||
curve: LocalForm::canonical_only(curve),
|
||||
vertices: VerticesOfEdge::from_vertices(vertices),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// API for building a [`Cycle`]
|
||||
#[must_use]
|
||||
pub struct CycleBuilder<'r> {
|
||||
surface: Surface,
|
||||
shape: &'r mut Shape,
|
||||
}
|
||||
|
||||
impl<'r> CycleBuilder<'r> {
|
||||
/// Construct a new instance of `CycleBuilder`
|
||||
pub fn new(surface: Surface, shape: &'r mut Shape) -> Self {
|
||||
Self { surface, shape }
|
||||
}
|
||||
|
||||
/// Build a polygon from a list of points
|
||||
pub fn build_polygon(
|
||||
self,
|
||||
points: impl IntoIterator<Item = impl Into<Point<2>>>,
|
||||
) -> LocalForm<Cycle<2>, Cycle<3>> {
|
||||
let mut points: Vec<_> = points.into_iter().map(Into::into).collect();
|
||||
|
||||
// A polygon is closed, so we need to add the first point at the end
|
||||
// again, for the next step.
|
||||
if let Some(point) = points.first().cloned() {
|
||||
points.push(point);
|
||||
}
|
||||
|
||||
let mut edges = Vec::new();
|
||||
for points in points.windows(2) {
|
||||
// Can't panic, as we passed `2` to `windows`.
|
||||
//
|
||||
// Can be cleaned up, once `array_windows` is stable.
|
||||
let points = [points[0], points[1]];
|
||||
|
||||
let points_canonical = points
|
||||
.map(|point| self.surface.point_from_surface_coords(point));
|
||||
let edge_canonical = Edge::builder(self.shape)
|
||||
.build_line_segment_from_points(points_canonical)
|
||||
.get();
|
||||
|
||||
let edge_local = Edge {
|
||||
curve: LocalForm::new(
|
||||
Curve::Line(Line::from_points(points)),
|
||||
edge_canonical.curve.canonical(),
|
||||
),
|
||||
vertices: edge_canonical.vertices.clone(),
|
||||
};
|
||||
|
||||
edges.push(LocalForm::new(edge_local, edge_canonical));
|
||||
}
|
||||
|
||||
let local = Cycle {
|
||||
edges: edges.clone(),
|
||||
};
|
||||
|
||||
let edges_canonical = edges.into_iter().map(|edge| edge.canonical());
|
||||
let canonical = Cycle::new(edges_canonical);
|
||||
|
||||
LocalForm::new(local, canonical)
|
||||
}
|
||||
}
|
||||
use crate::objects::{Cycle, Face, Surface};
|
||||
|
||||
/// API for building a [`Face`]
|
||||
#[must_use]
|
||||
pub struct FaceBuilder<'r> {
|
||||
pub struct FaceBuilder {
|
||||
surface: Surface,
|
||||
exterior: Option<Vec<Point<2>>>,
|
||||
interiors: Vec<Vec<Point<2>>>,
|
||||
color: Option<[u8; 4]>,
|
||||
|
||||
shape: &'r mut Shape,
|
||||
}
|
||||
|
||||
impl<'r> FaceBuilder<'r> {
|
||||
impl FaceBuilder {
|
||||
/// Construct a new instance of `FaceBuilder`
|
||||
pub fn new(surface: Surface, shape: &'r mut Shape) -> Self {
|
||||
pub fn new(surface: Surface) -> Self {
|
||||
Self {
|
||||
surface,
|
||||
exterior: None,
|
||||
interiors: Vec::new(),
|
||||
color: None,
|
||||
|
||||
shape,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,27 +57,23 @@ impl<'r> FaceBuilder<'r> {
|
|||
}
|
||||
|
||||
/// Build the face
|
||||
pub fn build(self) -> Handle<Face> {
|
||||
pub fn build(self) -> Face {
|
||||
let surface = self.surface;
|
||||
|
||||
let mut exteriors = Vec::new();
|
||||
if let Some(points) = self.exterior {
|
||||
let cycle =
|
||||
Cycle::builder(self.surface, self.shape).build_polygon(points);
|
||||
let cycle = Cycle::polygon_from_points(&self.surface, points);
|
||||
exteriors.push(cycle);
|
||||
}
|
||||
|
||||
let mut interiors = Vec::new();
|
||||
for points in self.interiors {
|
||||
let cycle =
|
||||
Cycle::builder(self.surface, self.shape).build_polygon(points);
|
||||
let cycle = Cycle::polygon_from_points(&self.surface, points);
|
||||
interiors.push(cycle);
|
||||
}
|
||||
|
||||
let color = self.color.unwrap_or([255, 0, 0, 255]);
|
||||
|
||||
self.shape.get_handle_or_insert(Face::new(
|
||||
surface, exteriors, interiors, color,
|
||||
))
|
||||
Face::new(surface, exteriors, interiors, color)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -439,10 +439,7 @@ impl<T> Iterator for Iter<T> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
objects::{Curve, Cycle, Edge, Face, Surface, Vertex},
|
||||
shape::Shape,
|
||||
};
|
||||
use crate::objects::{Curve, Cycle, Edge, Face, Surface, Vertex};
|
||||
|
||||
use super::ObjectIters as _;
|
||||
|
||||
|
@ -460,10 +457,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn cycle() {
|
||||
let mut shape = Shape::new();
|
||||
let cycle = Cycle::builder(Surface::xy_plane(), &mut shape)
|
||||
.build_polygon([[0., 0.], [1., 0.], [0., 1.]])
|
||||
.canonical();
|
||||
let cycle = Cycle::polygon_from_points(
|
||||
&Surface::xy_plane(),
|
||||
[[0., 0.], [1., 0.], [0., 1.]],
|
||||
)
|
||||
.canonical();
|
||||
|
||||
assert_eq!(3, cycle.curve_iter().count());
|
||||
assert_eq!(1, cycle.cycle_iter().count());
|
||||
|
@ -475,10 +473,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn edge() {
|
||||
let mut shape = Shape::new();
|
||||
let edge = Edge::builder(&mut shape)
|
||||
.build_line_segment_from_points([[0., 0., 0.], [1., 0., 0.]])
|
||||
.get();
|
||||
let edge = Edge::line_segment_from_points([[0., 0., 0.], [1., 0., 0.]]);
|
||||
|
||||
assert_eq!(1, edge.curve_iter().count());
|
||||
assert_eq!(0, edge.cycle_iter().count());
|
||||
|
@ -490,11 +485,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn face() {
|
||||
let mut shape = Shape::new();
|
||||
let face = Face::builder(Surface::xy_plane(), &mut shape)
|
||||
let face = Face::builder(Surface::xy_plane())
|
||||
.with_exterior_polygon([[0., 0.], [1., 0.], [0., 1.]])
|
||||
.build()
|
||||
.get();
|
||||
.build();
|
||||
|
||||
assert_eq!(3, face.curve_iter().count());
|
||||
assert_eq!(1, face.cycle_iter().count());
|
||||
|
@ -518,10 +511,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn vertex() {
|
||||
let mut shape = Shape::new();
|
||||
let vertex = Vertex::builder(&mut shape)
|
||||
.build_from_point([0., 0., 0.])
|
||||
.get();
|
||||
let vertex = Vertex::from_point([0., 0., 0.]);
|
||||
|
||||
assert_eq!(0, vertex.curve_iter().count());
|
||||
assert_eq!(0, vertex.cycle_iter().count());
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::{
|
||||
builder::CycleBuilder,
|
||||
shape::{LocalForm, Shape},
|
||||
};
|
||||
use fj_math::{Line, Point};
|
||||
|
||||
use super::{Edge, Surface};
|
||||
use crate::shape::LocalForm;
|
||||
|
||||
use super::{Curve, Edge, Surface};
|
||||
|
||||
/// A cycle of connected edges
|
||||
///
|
||||
|
@ -29,9 +28,50 @@ impl Cycle<3> {
|
|||
Self { edges }
|
||||
}
|
||||
|
||||
/// Build a cycle using the [`CycleBuilder`] API
|
||||
pub fn builder(surface: Surface, shape: &mut Shape) -> CycleBuilder {
|
||||
CycleBuilder::new(surface, shape)
|
||||
/// Create a polygon from a list of points
|
||||
pub fn polygon_from_points(
|
||||
surface: &Surface,
|
||||
points: impl IntoIterator<Item = impl Into<Point<2>>>,
|
||||
) -> LocalForm<Cycle<2>, Cycle<3>> {
|
||||
let mut points: Vec<_> = points.into_iter().map(Into::into).collect();
|
||||
|
||||
// A polygon is closed, so we need to add the first point at the end
|
||||
// again, for the next step.
|
||||
if let Some(point) = points.first().cloned() {
|
||||
points.push(point);
|
||||
}
|
||||
|
||||
let mut edges = Vec::new();
|
||||
for points in points.windows(2) {
|
||||
// Can't panic, as we passed `2` to `windows`.
|
||||
//
|
||||
// Can be cleaned up, once `array_windows` is stable.
|
||||
let points = [points[0], points[1]];
|
||||
|
||||
let points_canonical =
|
||||
points.map(|point| surface.point_from_surface_coords(point));
|
||||
let edge_canonical =
|
||||
Edge::line_segment_from_points(points_canonical);
|
||||
|
||||
let edge_local = Edge {
|
||||
curve: LocalForm::new(
|
||||
Curve::Line(Line::from_points(points)),
|
||||
edge_canonical.curve.canonical(),
|
||||
),
|
||||
vertices: edge_canonical.vertices.clone(),
|
||||
};
|
||||
|
||||
edges.push(LocalForm::new(edge_local, edge_canonical));
|
||||
}
|
||||
|
||||
let local = Cycle {
|
||||
edges: edges.clone(),
|
||||
};
|
||||
|
||||
let edges_canonical = edges.into_iter().map(|edge| edge.canonical());
|
||||
let canonical = Cycle::new(edges_canonical);
|
||||
|
||||
LocalForm::new(local, canonical)
|
||||
}
|
||||
|
||||
/// Access the edges that this cycle refers to
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use std::fmt;
|
||||
|
||||
use fj_math::Point;
|
||||
use fj_math::{Circle, Line, Point, Scalar, Vector};
|
||||
|
||||
use crate::{
|
||||
builder::EdgeBuilder,
|
||||
shape::{LocalForm, Shape},
|
||||
};
|
||||
use crate::shape::LocalForm;
|
||||
|
||||
use super::{Curve, Vertex};
|
||||
|
||||
|
@ -53,10 +50,62 @@ impl<const D: usize> Edge<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Edge<2> {
|
||||
/// Create a circle from the given radius
|
||||
pub fn circle_from_radius(radius: Scalar) -> LocalForm<Edge<2>, Edge<3>> {
|
||||
let curve_local = Curve::Circle(Circle {
|
||||
center: Point::origin(),
|
||||
a: Vector::from([radius, Scalar::ZERO]),
|
||||
b: Vector::from([Scalar::ZERO, radius]),
|
||||
});
|
||||
let curve_canonical = Curve::Circle(Circle {
|
||||
center: Point::origin(),
|
||||
a: Vector::from([radius, Scalar::ZERO, Scalar::ZERO]),
|
||||
b: Vector::from([Scalar::ZERO, radius, Scalar::ZERO]),
|
||||
});
|
||||
|
||||
let edge_local = Edge {
|
||||
curve: LocalForm::new(curve_local, curve_canonical),
|
||||
vertices: VerticesOfEdge::none(),
|
||||
};
|
||||
let edge_canonical = Edge {
|
||||
curve: LocalForm::canonical_only(curve_canonical),
|
||||
vertices: VerticesOfEdge::none(),
|
||||
};
|
||||
|
||||
LocalForm::new(edge_local, edge_canonical)
|
||||
}
|
||||
}
|
||||
|
||||
impl Edge<3> {
|
||||
/// Build an edge using the [`EdgeBuilder`] API
|
||||
pub fn builder(shape: &mut Shape) -> EdgeBuilder {
|
||||
EdgeBuilder::new(shape)
|
||||
/// Create a line segment from two points
|
||||
pub fn line_segment_from_points(
|
||||
vertices: [impl Into<Point<3>>; 2],
|
||||
) -> Self {
|
||||
let vertices = vertices.map(|point| {
|
||||
let point = point.into();
|
||||
Vertex { point }
|
||||
});
|
||||
|
||||
Self::line_segment_from_vertices(vertices)
|
||||
}
|
||||
|
||||
/// Create a line segment from two vertices
|
||||
pub fn line_segment_from_vertices([a, b]: [Vertex; 2]) -> Self {
|
||||
let curve = {
|
||||
let points = [a, b].map(|vertex| vertex.point);
|
||||
Curve::Line(Line::from_points(points))
|
||||
};
|
||||
|
||||
let vertices = [
|
||||
LocalForm::new(Point::from([0.]), a),
|
||||
LocalForm::new(Point::from([1.]), b),
|
||||
];
|
||||
|
||||
Self {
|
||||
curve: LocalForm::canonical_only(curve),
|
||||
vertices: VerticesOfEdge::from_vertices(vertices),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,7 @@ use std::hash::{Hash, Hasher};
|
|||
use fj_interop::mesh::Color;
|
||||
use fj_math::Triangle;
|
||||
|
||||
use crate::{
|
||||
builder::FaceBuilder,
|
||||
shape::{LocalForm, Shape},
|
||||
};
|
||||
use crate::{builder::FaceBuilder, shape::LocalForm};
|
||||
|
||||
use super::{Cycle, Surface};
|
||||
|
||||
|
@ -57,8 +54,8 @@ impl Face {
|
|||
})
|
||||
}
|
||||
/// Build a face using the [`FaceBuilder`] API
|
||||
pub fn builder(surface: Surface, shape: &mut Shape) -> FaceBuilder {
|
||||
FaceBuilder::new(surface, shape)
|
||||
pub fn builder(surface: Surface) -> FaceBuilder {
|
||||
FaceBuilder::new(surface)
|
||||
}
|
||||
|
||||
/// Access the boundary representation of the face
|
||||
|
|
|
@ -2,8 +2,6 @@ use std::hash::Hash;
|
|||
|
||||
use fj_math::Point;
|
||||
|
||||
use crate::{builder::VertexBuilder, shape::Shape};
|
||||
|
||||
/// A vertex
|
||||
///
|
||||
/// This struct exists to distinguish between vertices and points at the type
|
||||
|
@ -27,8 +25,9 @@ pub struct Vertex {
|
|||
}
|
||||
|
||||
impl Vertex {
|
||||
/// Build a vertex using the [`VertexBuilder`] API
|
||||
pub fn builder(shape: &mut Shape) -> VertexBuilder {
|
||||
VertexBuilder::new(shape)
|
||||
/// Construct a `Vertex` from a point
|
||||
pub fn from_point(point: impl Into<Point<3>>) -> Self {
|
||||
let point = point.into();
|
||||
Self { point }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,36 +273,26 @@ mod tests {
|
|||
#[test]
|
||||
fn structural_cycle() {
|
||||
let mut shape = Shape::new();
|
||||
let mut other = Shape::new();
|
||||
|
||||
// Trying to refer to edge that is not from the same shape. Should fail.
|
||||
let edge = Edge::builder(&mut other)
|
||||
.build_line_segment_from_points([[0., 0., 0.], [1., 0., 0.]])
|
||||
.get();
|
||||
let edge = Edge::line_segment_from_points([[0., 0., 0.], [1., 0., 0.]]);
|
||||
shape.insert(Cycle::new(vec![edge.clone()]));
|
||||
let err =
|
||||
validate(shape.clone(), &ValidationConfig::default()).unwrap_err();
|
||||
assert!(err.missing_edge(&edge));
|
||||
|
||||
// Referring to edge that *is* from the same shape. Should work.
|
||||
let edge = Edge::builder(&mut shape)
|
||||
.build_line_segment_from_points([[0., 0., 0.], [1., 0., 0.]])
|
||||
.get();
|
||||
let edge = Edge::line_segment_from_points([[0., 0., 0.], [1., 0., 0.]]);
|
||||
shape.insert(Cycle::new(vec![edge]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn structural_edge() {
|
||||
let mut shape = Shape::new();
|
||||
let mut other = Shape::new();
|
||||
|
||||
let curve = Curve::x_axis();
|
||||
let a = Vertex::builder(&mut other)
|
||||
.build_from_point([1., 0., 0.])
|
||||
.get();
|
||||
let b = Vertex::builder(&mut other)
|
||||
.build_from_point([2., 0., 0.])
|
||||
.get();
|
||||
let a = Vertex::from_point([1., 0., 0.]);
|
||||
let b = Vertex::from_point([2., 0., 0.]);
|
||||
|
||||
let a = LocalForm::new(Point::from([1.]), a);
|
||||
let b = LocalForm::new(Point::from([2.]), b);
|
||||
|
@ -319,12 +309,8 @@ mod tests {
|
|||
assert!(err.missing_vertex(&b.canonical()));
|
||||
|
||||
let curve = Curve::x_axis();
|
||||
let a = Vertex::builder(&mut shape)
|
||||
.build_from_point([1., 0., 0.])
|
||||
.get();
|
||||
let b = Vertex::builder(&mut shape)
|
||||
.build_from_point([2., 0., 0.])
|
||||
.get();
|
||||
let a = Vertex::from_point([1., 0., 0.]);
|
||||
let b = Vertex::from_point([2., 0., 0.]);
|
||||
|
||||
let a = LocalForm::new(Point::from([1.]), a);
|
||||
let b = LocalForm::new(Point::from([2.]), b);
|
||||
|
@ -339,12 +325,11 @@ mod tests {
|
|||
#[test]
|
||||
fn structural_face() {
|
||||
let mut shape = Shape::new();
|
||||
let mut other = Shape::new();
|
||||
|
||||
let triangle = [[0., 0.], [1., 0.], [0., 1.]];
|
||||
|
||||
let surface = Surface::xy_plane();
|
||||
let cycle = Cycle::builder(surface, &mut other).build_polygon(triangle);
|
||||
let cycle = Cycle::polygon_from_points(&surface, triangle);
|
||||
|
||||
// Nothing has been added to `shape`. Should fail.
|
||||
shape.insert(Face::new(
|
||||
|
@ -359,7 +344,7 @@ mod tests {
|
|||
assert!(err.missing_cycle(&cycle.canonical()));
|
||||
|
||||
let surface = Surface::xy_plane();
|
||||
let cycle = Cycle::builder(surface, &mut shape).build_polygon(triangle);
|
||||
let cycle = Cycle::polygon_from_points(&surface, triangle);
|
||||
|
||||
// Everything has been added to `shape` now. Should work!
|
||||
shape.insert(Face::new(
|
||||
|
|
|
@ -21,8 +21,7 @@ impl ToShape for fj::Circle {
|
|||
// Circles have just a single round edge with no vertices. So none need
|
||||
// to be added here.
|
||||
|
||||
let edge = Edge::builder(&mut tmp)
|
||||
.build_circle(Scalar::from_f64(self.radius()));
|
||||
let edge = Edge::circle_from_radius(Scalar::from_f64(self.radius()));
|
||||
|
||||
let cycle_local = Cycle {
|
||||
edges: vec![edge.clone()],
|
||||
|
|
|
@ -2,7 +2,6 @@ use fj_interop::debug::DebugInfo;
|
|||
use fj_kernel::{
|
||||
algorithms::Tolerance,
|
||||
objects::{Face, Surface},
|
||||
shape::Shape,
|
||||
validation::{validate, Validated, ValidationConfig, ValidationError},
|
||||
};
|
||||
use fj_math::{Aabb, Point};
|
||||
|
@ -16,16 +15,13 @@ impl ToShape for fj::Sketch {
|
|||
_: Tolerance,
|
||||
_: &mut DebugInfo,
|
||||
) -> Result<Validated<Vec<Face>>, ValidationError> {
|
||||
let mut tmp = Shape::new();
|
||||
|
||||
let surface = Surface::xy_plane();
|
||||
let points = self.to_points().into_iter().map(Point::from);
|
||||
|
||||
let sketch = Face::builder(surface, &mut tmp)
|
||||
let sketch = Face::builder(surface)
|
||||
.with_exterior_polygon(points)
|
||||
.with_color(self.color())
|
||||
.build()
|
||||
.get();
|
||||
.build();
|
||||
|
||||
validate(vec![sketch], config)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue