Give `Face` ownership of its surface

This commit is contained in:
Hanno Braun 2022-06-28 17:59:18 +02:00
parent 62de46b5e2
commit 8438f8a3c7
11 changed files with 27 additions and 37 deletions

View File

@ -5,7 +5,7 @@ use crate::{
objects::{ objects::{
Curve, Cycle, CyclesInFace, Edge, Face, Surface, Vertex, VerticesOfEdge, Curve, Cycle, CyclesInFace, Edge, Face, Surface, Vertex, VerticesOfEdge,
}, },
shape::{LocalForm, Shape}, shape::LocalForm,
}; };
use super::{transform::transform_cycles, CycleApprox, Tolerance}; use super::{transform::transform_cycles, CycleApprox, Tolerance};
@ -61,8 +61,6 @@ fn create_bottom_faces(
is_sweep_along_negative_direction: bool, is_sweep_along_negative_direction: bool,
target: &mut Vec<Face>, target: &mut Vec<Face>,
) { ) {
let mut tmp = Shape::new();
let mut surface = face.surface(); let mut surface = face.surface();
let mut exteriors = face.brep().exteriors.clone(); let mut exteriors = face.brep().exteriors.clone();
@ -75,8 +73,6 @@ fn create_bottom_faces(
interiors = reverse_local_coordinates_in_cycle(&interiors); interiors = reverse_local_coordinates_in_cycle(&interiors);
}; };
let surface = tmp.insert(surface);
let face = Face::new( let face = Face::new(
surface, surface,
exteriors.as_local_form().cloned(), exteriors.as_local_form().cloned(),
@ -111,9 +107,6 @@ fn create_top_face(
interiors = reverse_local_coordinates_in_cycle(&interiors); interiors = reverse_local_coordinates_in_cycle(&interiors);
}; };
let mut tmp = Shape::new();
let surface = tmp.insert(surface);
let face = Face::new( let face = Face::new(
surface, surface,
exteriors.as_local_form().cloned(), exteriors.as_local_form().cloned(),
@ -156,8 +149,6 @@ fn create_non_continuous_side_face(
color: [u8; 4], color: [u8; 4],
target: &mut Vec<Face>, target: &mut Vec<Face>,
) { ) {
let mut tmp = Shape::new();
let vertices = { let vertices = {
let vertices_top = vertices_bottom.map(|vertex| { let vertices_top = vertices_bottom.map(|vertex| {
let point = vertex.point + path; let point = vertex.point + path;
@ -177,7 +168,6 @@ fn create_non_continuous_side_face(
let [a, b, _, c] = vertices.map(|vertex| vertex.point); let [a, b, _, c] = vertices.map(|vertex| vertex.point);
Surface::plane_from_points([a, b, c]) Surface::plane_from_points([a, b, c])
}; };
let surface = tmp.get_handle_or_insert(surface);
let cycle = { let cycle = {
let [a, b, c, d] = vertices; let [a, b, c, d] = vertices;

View File

@ -2,7 +2,7 @@ use fj_math::Transform;
use crate::{ use crate::{
objects::{Cycle, CyclesInFace, Edge, Face, FaceBRep, Vertex}, objects::{Cycle, CyclesInFace, Edge, Face, FaceBRep, Vertex},
shape::{LocalForm, Shape}, shape::LocalForm,
}; };
/// Transform a shape /// Transform a shape
@ -12,9 +12,7 @@ pub fn transform(faces: &[Face], transform: &Transform) -> Vec<Face> {
for face in faces { for face in faces {
let face = match face { let face = match face {
Face::Face(face) => { Face::Face(face) => {
let mut tmp = Shape::new(); let surface = face.surface.transform(transform);
let surface = face.surface.get().transform(transform);
let surface = tmp.insert(surface);
let exteriors = transform_cycles(&face.exteriors, transform); let exteriors = transform_cycles(&face.exteriors, transform);
let interiors = transform_cycles(&face.interiors, transform); let interiors = transform_cycles(&face.interiors, transform);

View File

@ -22,7 +22,7 @@ pub fn triangulate(
for face in faces { for face in faces {
match &face { match &face {
Face::Face(brep) => { Face::Face(brep) => {
let surface = brep.surface.get(); let surface = brep.surface;
let approx = FaceApprox::new(&face, tolerance); let approx = FaceApprox::new(&face, tolerance);
let points: Vec<_> = approx let points: Vec<_> = approx

View File

@ -223,7 +223,7 @@ impl<'r> FaceBuilder<'r> {
/// Build the face /// Build the face
pub fn build(self) -> Handle<Face> { pub fn build(self) -> Handle<Face> {
let surface = self.shape.get_handle_or_insert(self.surface); let surface = self.surface;
let mut exteriors = Vec::new(); let mut exteriors = Vec::new();
if let Some(points) = self.exterior { if let Some(points) = self.exterior {

View File

@ -5,7 +5,7 @@ use fj_math::Triangle;
use crate::{ use crate::{
builder::FaceBuilder, builder::FaceBuilder,
shape::{Handle, LocalForm, Shape}, shape::{LocalForm, Shape},
}; };
use super::{Cycle, Surface}; use super::{Cycle, Surface};
@ -41,7 +41,7 @@ pub enum Face {
impl Face { impl Face {
/// Construct a new instance of `Face` /// Construct a new instance of `Face`
pub fn new( pub fn new(
surface: Handle<Surface>, surface: Surface,
exteriors: impl IntoIterator<Item = LocalForm<Cycle<2>, Cycle<3>>>, exteriors: impl IntoIterator<Item = LocalForm<Cycle<2>, Cycle<3>>>,
interiors: impl IntoIterator<Item = LocalForm<Cycle<2>, Cycle<3>>>, interiors: impl IntoIterator<Item = LocalForm<Cycle<2>, Cycle<3>>>,
color: [u8; 4], color: [u8; 4],
@ -119,7 +119,7 @@ impl Face {
#[derive(Clone, Debug, Eq, Ord, PartialOrd)] #[derive(Clone, Debug, Eq, Ord, PartialOrd)]
pub struct FaceBRep { pub struct FaceBRep {
/// The surface that defines this face /// The surface that defines this face
pub surface: Handle<Surface>, pub surface: Surface,
/// The cycles that bound the face on the outside /// The cycles that bound the face on the outside
/// ///
@ -152,7 +152,7 @@ impl FaceBRep {
/// 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
/// [`Handle`]. /// [`Handle`].
pub fn surface(&self) -> Surface { pub fn surface(&self) -> Surface {
self.surface.get() self.surface
} }
/// Access the exterior cycles that the face refers to /// Access the exterior cycles that the face refers to

View File

@ -196,7 +196,8 @@ mod tests {
let cycle = shape.insert(cycle); let cycle = shape.insert(cycle);
assert!(shape.get_handle(&cycle.get()).as_ref() == Some(&cycle)); assert!(shape.get_handle(&cycle.get()).as_ref() == Some(&cycle));
let face = Face::new(surface, Vec::new(), Vec::new(), [0, 0, 0, 0]); let face =
Face::new(surface.get(), Vec::new(), Vec::new(), [0, 0, 0, 0]);
assert!(shape.get_handle(&face).is_none()); assert!(shape.get_handle(&face).is_none());
let face = shape.insert(face); let face = shape.insert(face);

View File

@ -72,7 +72,7 @@ impl Object for Face {
fn merge_into(self, shape: &mut Shape) -> Handle<Self> { fn merge_into(self, shape: &mut Shape) -> Handle<Self> {
match self { match self {
Face::Face(face) => { Face::Face(face) => {
let surface = face.surface.get().merge_into(shape); let surface = face.surface.merge_into(shape);
let mut exts = Vec::new(); let mut exts = Vec::new();
for cycle in face.exteriors.as_local_form() { for cycle in face.exteriors.as_local_form() {
@ -93,7 +93,10 @@ impl Object for Face {
} }
shape.get_handle_or_insert(Face::new( shape.get_handle_or_insert(Face::new(
surface, exts, ints, face.color, surface.get(),
exts,
ints,
face.color,
)) ))
} }
Face::Triangles(_) => shape.get_handle_or_insert(self), Face::Triangles(_) => shape.get_handle_or_insert(self),

View File

@ -343,25 +343,23 @@ mod tests {
let triangle = [[0., 0.], [1., 0.], [0., 1.]]; let triangle = [[0., 0.], [1., 0.], [0., 1.]];
let surface = other.insert(Surface::xy_plane()); let surface = Surface::xy_plane();
let cycle = let cycle = Cycle::builder(surface, &mut other).build_polygon(triangle);
Cycle::builder(surface.get(), &mut other).build_polygon(triangle);
// Nothing has been added to `shape`. Should fail. // Nothing has been added to `shape`. Should fail.
shape.insert(Face::new( shape.insert(Face::new(
surface.clone(), surface,
vec![cycle.clone()], vec![cycle.clone()],
Vec::new(), Vec::new(),
[255, 0, 0, 255], [255, 0, 0, 255],
)); ));
let err = let err =
validate(shape.clone(), &ValidationConfig::default()).unwrap_err(); validate(shape.clone(), &ValidationConfig::default()).unwrap_err();
assert!(err.missing_surface(&surface.get())); assert!(err.missing_surface(&surface));
assert!(err.missing_cycle(&cycle.canonical())); assert!(err.missing_cycle(&cycle.canonical()));
let surface = shape.insert(Surface::xy_plane()); let surface = Surface::xy_plane();
let cycle = let cycle = Cycle::builder(surface, &mut shape).build_polygon(triangle);
Cycle::builder(surface.get(), &mut shape).build_polygon(triangle);
// Everything has been added to `shape` now. Should work! // Everything has been added to `shape` now. Should work!
shape.insert(Face::new( shape.insert(Face::new(

View File

@ -61,7 +61,7 @@ pub fn validate_face(
let mut missing_cycles = HashSet::new(); let mut missing_cycles = HashSet::new();
if !surfaces.contains(&face.surface()) { if !surfaces.contains(&face.surface()) {
missing_surface = Some(face.surface.get()); missing_surface = Some(face.surface);
} }
for cycle in face.all_cycles() { for cycle in face.all_cycles() {
if !cycles.contains(&cycle) { if !cycles.contains(&cycle) {

View File

@ -29,7 +29,7 @@ impl ToShape for fj::Circle {
}; };
let cycle_canonical = Cycle::new(vec![edge.canonical()]); let cycle_canonical = Cycle::new(vec![edge.canonical()]);
let surface = tmp.insert(Surface::xy_plane()); let surface = Surface::xy_plane();
let face = tmp let face = tmp
.insert(Face::new( .insert(Face::new(
surface, surface,

View File

@ -36,13 +36,13 @@ impl ToShape for fj::Difference2d {
if let Some(face) = a.face_iter().next() { if let Some(face) = a.face_iter().next() {
// If there's at least one face to subtract from, we can proceed. // If there's at least one face to subtract from, we can proceed.
let surface = face.brep().surface.clone(); let surface = face.brep().surface;
for face in a.face_iter() { for face in a.face_iter() {
let face = face.brep(); let face = face.brep();
assert_eq!( assert_eq!(
surface.get(), surface,
face.surface(), face.surface(),
"Trying to subtract faces with different surfaces.", "Trying to subtract faces with different surfaces.",
); );
@ -61,7 +61,7 @@ impl ToShape for fj::Difference2d {
let face = face.brep(); let face = face.brep();
assert_eq!( assert_eq!(
surface.get(), surface,
face.surface(), face.surface(),
"Trying to subtract faces with different surfaces.", "Trying to subtract faces with different surfaces.",
); );