From df3a7f586edc28536aee3dd0fd1b63148ce681e7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 25 Apr 2024 13:24:42 +0200 Subject: [PATCH 1/8] Refactor to reduce redundancy --- crates/fj-core/src/validate/sketch.rs | 34 ++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/crates/fj-core/src/validate/sketch.rs b/crates/fj-core/src/validate/sketch.rs index b8231bd09..47f560405 100644 --- a/crates/fj-core/src/validate/sketch.rs +++ b/crates/fj-core/src/validate/sketch.rs @@ -144,18 +144,17 @@ mod tests { fn should_find_cycle_multiple_references() -> anyhow::Result<()> { let mut core = Core::new(); + let surface = core.layers.topology.surfaces.space_2d(); + let region = ::circle([0., 0.], 1., &mut core) .insert(&mut core); - let valid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), - vec![region.clone()], - ) - .insert(&mut core); + let valid_sketch = Sketch::new(surface.clone(), vec![region.clone()]) + .insert(&mut core); valid_sketch.validate_and_return_first_error(&core.layers.geometry)?; let shared_cycle = region.exterior(); let invalid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), + surface, vec![ Region::new(shared_cycle.clone(), vec![]).insert(&mut core), Region::new(shared_cycle.clone(), vec![]).insert(&mut core), @@ -176,16 +175,15 @@ mod tests { fn should_find_half_edge_multiple_references() -> anyhow::Result<()> { let mut core = Core::new(); + let surface = core.layers.topology.surfaces.space_2d(); + let region = ::polygon( [[0., 0.], [1., 1.], [0., 1.]], &mut core, ) .insert(&mut core); - let valid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), - vec![region.clone()], - ) - .insert(&mut core); + let valid_sketch = Sketch::new(surface.clone(), vec![region.clone()]) + .insert(&mut core); valid_sketch.validate_and_return_first_error(&core.layers.geometry)?; let exterior = region.exterior(); @@ -194,7 +192,7 @@ mod tests { let interior = Cycle::new(cloned_edges).insert(&mut core); let invalid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), + surface, vec![ Region::new(exterior.clone(), vec![interior]).insert(&mut core) ], @@ -214,11 +212,13 @@ mod tests { fn should_find_clockwise_exterior_cycle() -> anyhow::Result<()> { let mut core = Core::new(); + let surface = core.layers.topology.surfaces.space_2d(); + let valid_outer_circle = HalfEdge::circle([0., 0.], 1., &mut core); let valid_exterior = Cycle::new(vec![valid_outer_circle.clone()]).insert(&mut core); let valid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), + surface.clone(), vec![Region::new(valid_exterior.clone(), vec![]).insert(&mut core)], ); valid_sketch.validate_and_return_first_error(&core.layers.geometry)?; @@ -231,7 +231,7 @@ mod tests { let invalid_exterior = Cycle::new(vec![invalid_outer_circle.clone()]).insert(&mut core); let invalid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), + surface, vec![ Region::new(invalid_exterior.clone(), vec![]).insert(&mut core) ], @@ -251,6 +251,8 @@ mod tests { fn should_find_counterclockwise_interior_cycle() -> anyhow::Result<()> { let mut core = Core::new(); + let surface = core.layers.topology.surfaces.space_2d(); + let outer_circle = HalfEdge::circle([0., 0.], 2., &mut core); let inner_circle = HalfEdge::circle([0., 0.], 1., &mut core); let cw_inner_circle = HalfEdge::from_sibling( @@ -263,7 +265,7 @@ mod tests { let valid_interior = Cycle::new(vec![cw_inner_circle.clone()]).insert(&mut core); let valid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), + surface.clone(), vec![Region::new(exterior.clone(), vec![valid_interior]) .insert(&mut core)], ); @@ -272,7 +274,7 @@ mod tests { let invalid_interior = Cycle::new(vec![inner_circle.clone()]).insert(&mut core); let invalid_sketch = Sketch::new( - core.layers.topology.surfaces.space_2d(), + surface, vec![Region::new(exterior.clone(), vec![invalid_interior]) .insert(&mut core)], ); From ddb6c10ebcf0b7ddf01dc5d406d8cd0df4e562c1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 26 Mar 2024 11:43:53 +0100 Subject: [PATCH 2/8] Provide surface to `BuildRegion` methods --- crates/fj-core/src/operations/build/face.rs | 6 ++++-- crates/fj-core/src/operations/build/region.rs | 6 ++++-- crates/fj-core/src/validate/sketch.rs | 10 ++++++++-- models/cuboid/src/lib.rs | 1 + models/spacer/src/lib.rs | 8 +++++++- models/star/src/lib.rs | 7 ++++++- 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/crates/fj-core/src/operations/build/face.rs b/crates/fj-core/src/operations/build/face.rs index d3b96e730..9b542921c 100644 --- a/crates/fj-core/src/operations/build/face.rs +++ b/crates/fj-core/src/operations/build/face.rs @@ -33,7 +33,8 @@ pub trait BuildFace { radius: impl Into, core: &mut Core, ) -> Face { - let region = Region::circle(center, radius, core).insert(core); + let region = + Region::circle(center, radius, surface.clone(), core).insert(core); Face::new(surface, region) } @@ -81,7 +82,8 @@ pub trait BuildFace { Ps: IntoIterator, Ps::IntoIter: Clone + ExactSizeIterator, { - let region = Region::polygon(points, core).insert(core); + let region = + Region::polygon(points, surface.clone(), core).insert(core); Face::new(surface, region) } } diff --git a/crates/fj-core/src/operations/build/region.rs b/crates/fj-core/src/operations/build/region.rs index 24ac8cafc..93b5840ba 100644 --- a/crates/fj-core/src/operations/build/region.rs +++ b/crates/fj-core/src/operations/build/region.rs @@ -2,7 +2,8 @@ use fj_math::{Point, Scalar}; use crate::{ operations::{build::BuildCycle, insert::Insert}, - topology::{Cycle, Region}, + storage::Handle, + topology::{Cycle, Region, Surface}, Core, }; @@ -24,6 +25,7 @@ pub trait BuildRegion { fn circle( center: impl Into>, radius: impl Into, + _: Handle, core: &mut Core, ) -> Region { let exterior = Cycle::circle(center, radius, core).insert(core); @@ -31,7 +33,7 @@ pub trait BuildRegion { } /// Build a polygon - fn polygon(points: Ps, core: &mut Core) -> Region + fn polygon(points: Ps, _: Handle, core: &mut Core) -> Region where P: Into>, Ps: IntoIterator, diff --git a/crates/fj-core/src/validate/sketch.rs b/crates/fj-core/src/validate/sketch.rs index 47f560405..9d5a4be38 100644 --- a/crates/fj-core/src/validate/sketch.rs +++ b/crates/fj-core/src/validate/sketch.rs @@ -146,8 +146,13 @@ mod tests { let surface = core.layers.topology.surfaces.space_2d(); - let region = ::circle([0., 0.], 1., &mut core) - .insert(&mut core); + let region = ::circle( + [0., 0.], + 1., + surface.clone(), + &mut core, + ) + .insert(&mut core); let valid_sketch = Sketch::new(surface.clone(), vec![region.clone()]) .insert(&mut core); valid_sketch.validate_and_return_first_error(&core.layers.geometry)?; @@ -179,6 +184,7 @@ mod tests { let region = ::polygon( [[0., 0.], [1., 1.], [0., 1.]], + surface.clone(), &mut core, ) .insert(&mut core); diff --git a/models/cuboid/src/lib.rs b/models/cuboid/src/lib.rs index e9df50729..8d98cb2d2 100644 --- a/models/cuboid/src/lib.rs +++ b/models/cuboid/src/lib.rs @@ -25,6 +25,7 @@ pub fn model(size: impl Into>, core: &mut fj::core::Core) -> Solid { [x / 2., y / 2.], [-x / 2., y / 2.], ], + core.layers.topology.surfaces.space_2d(), core, )], core, diff --git a/models/spacer/src/lib.rs b/models/spacer/src/lib.rs index e214fcc2b..3859145b3 100644 --- a/models/spacer/src/lib.rs +++ b/models/spacer/src/lib.rs @@ -22,7 +22,13 @@ pub fn model( Sketch::empty(&core.layers.topology) .add_regions( - [Region::circle(Point::origin(), outer, core).add_interiors( + [Region::circle( + Point::origin(), + outer, + core.layers.topology.surfaces.space_2d(), + core, + ) + .add_interiors( [Cycle::circle(Point::origin(), inner, core).reverse(core)], core, )], diff --git a/models/star/src/lib.rs b/models/star/src/lib.rs index 02b6ea537..aca8327f4 100644 --- a/models/star/src/lib.rs +++ b/models/star/src/lib.rs @@ -45,7 +45,12 @@ pub fn model( Sketch::empty(&core.layers.topology) .add_regions( - [Region::polygon(outer_points, core).add_interiors( + [Region::polygon( + outer_points, + core.layers.topology.surfaces.space_2d(), + core, + ) + .add_interiors( [Cycle::polygon(inner_points, core).reverse(core)], core, )], From 073e0d08d5fecd0a6f65c6786f0f1ea17ca0287e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 25 Apr 2024 13:33:59 +0200 Subject: [PATCH 3/8] Refactor to prepare for follow-on change --- .../fj-core/src/algorithms/triangulate/mod.rs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index 6c4953470..7c89499fa 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -102,18 +102,19 @@ mod tests { let c = [2., 2.]; let d = [0., 1.]; - let face = - Face::unbound(core.layers.topology.surfaces.xy_plane(), &mut core) - .update_region( - |region, core| { - region.update_exterior( - |_, core| Cycle::polygon([a, b, c, d], core), - core, - ) - }, - &mut core, - ) - .insert(&mut core); + let surface = core.layers.topology.surfaces.xy_plane(); + + let face = Face::unbound(surface, &mut core) + .update_region( + |region, core| { + region.update_exterior( + |_, core| Cycle::polygon([a, b, c, d], core), + core, + ) + }, + &mut core, + ) + .insert(&mut core); let a = Point::from(a).to_xyz(); let b = Point::from(b).to_xyz(); From feb45796c4a4fc7c10457de2e9eae8a7d79ba68d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 25 Apr 2024 13:36:01 +0200 Subject: [PATCH 4/8] Refactor to prepare for follow-on change --- .../src/validation/checks/face_winding.rs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/crates/fj-core/src/validation/checks/face_winding.rs b/crates/fj-core/src/validation/checks/face_winding.rs index fb2273bce..495147eb8 100644 --- a/crates/fj-core/src/validation/checks/face_winding.rs +++ b/crates/fj-core/src/validation/checks/face_winding.rs @@ -88,20 +88,21 @@ mod tests { fn interior_winding() -> anyhow::Result<()> { let mut core = Core::new(); - let valid = Face::polygon( - core.layers.topology.surfaces.xy_plane(), - [[0., 0.], [3., 0.], [0., 3.]], - &mut core, - ) - .update_region( - |region, core| { - region.add_interiors( - [Cycle::polygon([[1., 1.], [1., 2.], [2., 1.]], core)], - core, - ) - }, - &mut core, - ); + let surface = core.layers.topology.surfaces.xy_plane(); + let valid = + Face::polygon(surface, [[0., 0.], [3., 0.], [0., 3.]], &mut core) + .update_region( + |region, core| { + region.add_interiors( + [Cycle::polygon( + [[1., 1.], [1., 2.], [2., 1.]], + core, + )], + core, + ) + }, + &mut core, + ); InteriorCycleHasInvalidWinding::check_and_return_first_error( &valid, &core.layers.geometry, From fa2eea979e69d5ed9e6846b3437c93abc9a6e22d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 26 Mar 2024 11:46:30 +0100 Subject: [PATCH 5/8] Provide surface to `BuildCycle` methods --- .../fj-core/src/algorithms/triangulate/mod.rs | 26 ++++++++++++--- crates/fj-core/src/operations/build/cycle.rs | 6 ++-- crates/fj-core/src/operations/build/region.rs | 13 +++++--- .../src/validation/checks/face_winding.rs | 32 +++++++++++-------- models/spacer/src/lib.rs | 8 ++++- models/star/src/lib.rs | 7 +++- 6 files changed, 65 insertions(+), 27 deletions(-) diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index 7c89499fa..33fd922e0 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -104,11 +104,11 @@ mod tests { let surface = core.layers.topology.surfaces.xy_plane(); - let face = Face::unbound(surface, &mut core) + let face = Face::unbound(surface.clone(), &mut core) .update_region( |region, core| { region.update_exterior( - |_, core| Cycle::polygon([a, b, c, d], core), + |_, core| Cycle::polygon([a, b, c, d], surface, core), core, ) }, @@ -152,11 +152,21 @@ mod tests { |region, core| { region .update_exterior( - |_, core| Cycle::polygon([a, b, c, d], core), + |_, core| { + Cycle::polygon( + [a, b, c, d], + surface.clone(), + core, + ) + }, core, ) .add_interiors( - [Cycle::polygon([e, f, g, h], core)], + [Cycle::polygon( + [e, f, g, h], + surface.clone(), + core, + )], core, ) }, @@ -245,7 +255,13 @@ mod tests { .update_region( |region, core| { region.update_exterior( - |_, core| Cycle::polygon([a, b, c, d, e], core), + |_, core| { + Cycle::polygon( + [a, b, c, d, e], + surface.clone(), + core, + ) + }, core, ) }, diff --git a/crates/fj-core/src/operations/build/cycle.rs b/crates/fj-core/src/operations/build/cycle.rs index ace25c1b3..7e3ced9d4 100644 --- a/crates/fj-core/src/operations/build/cycle.rs +++ b/crates/fj-core/src/operations/build/cycle.rs @@ -3,7 +3,8 @@ use itertools::Itertools; use crate::{ operations::{build::BuildHalfEdge, update::UpdateCycle}, - topology::{Cycle, HalfEdge}, + storage::Handle, + topology::{Cycle, HalfEdge, Surface}, Core, }; @@ -22,6 +23,7 @@ pub trait BuildCycle { fn circle( center: impl Into>, radius: impl Into, + _: Handle, core: &mut Core, ) -> Cycle { let circle = HalfEdge::circle(center, radius, core); @@ -29,7 +31,7 @@ pub trait BuildCycle { } /// Build a polygon - fn polygon(points: Ps, core: &mut Core) -> Cycle + fn polygon(points: Ps, _: Handle, core: &mut Core) -> Cycle where P: Into>, Ps: IntoIterator, diff --git a/crates/fj-core/src/operations/build/region.rs b/crates/fj-core/src/operations/build/region.rs index 93b5840ba..e5ee97346 100644 --- a/crates/fj-core/src/operations/build/region.rs +++ b/crates/fj-core/src/operations/build/region.rs @@ -25,21 +25,26 @@ pub trait BuildRegion { fn circle( center: impl Into>, radius: impl Into, - _: Handle, + surface: Handle, core: &mut Core, ) -> Region { - let exterior = Cycle::circle(center, radius, core).insert(core); + let exterior = + Cycle::circle(center, radius, surface, core).insert(core); Region::new(exterior, []) } /// Build a polygon - fn polygon(points: Ps, _: Handle, core: &mut Core) -> Region + fn polygon( + points: Ps, + surface: Handle, + core: &mut Core, + ) -> Region where P: Into>, Ps: IntoIterator, Ps::IntoIter: Clone + ExactSizeIterator, { - let exterior = Cycle::polygon(points, core).insert(core); + let exterior = Cycle::polygon(points, surface, core).insert(core); Region::new(exterior, []) } } diff --git a/crates/fj-core/src/validation/checks/face_winding.rs b/crates/fj-core/src/validation/checks/face_winding.rs index 495147eb8..d60f4cbc6 100644 --- a/crates/fj-core/src/validation/checks/face_winding.rs +++ b/crates/fj-core/src/validation/checks/face_winding.rs @@ -89,20 +89,24 @@ mod tests { let mut core = Core::new(); let surface = core.layers.topology.surfaces.xy_plane(); - let valid = - Face::polygon(surface, [[0., 0.], [3., 0.], [0., 3.]], &mut core) - .update_region( - |region, core| { - region.add_interiors( - [Cycle::polygon( - [[1., 1.], [1., 2.], [2., 1.]], - core, - )], - core, - ) - }, - &mut core, - ); + let valid = Face::polygon( + surface.clone(), + [[0., 0.], [3., 0.], [0., 3.]], + &mut core, + ) + .update_region( + |region, core| { + region.add_interiors( + [Cycle::polygon( + [[1., 1.], [1., 2.], [2., 1.]], + surface, + core, + )], + core, + ) + }, + &mut core, + ); InteriorCycleHasInvalidWinding::check_and_return_first_error( &valid, &core.layers.geometry, diff --git a/models/spacer/src/lib.rs b/models/spacer/src/lib.rs index 3859145b3..b0a685db1 100644 --- a/models/spacer/src/lib.rs +++ b/models/spacer/src/lib.rs @@ -29,7 +29,13 @@ pub fn model( core, ) .add_interiors( - [Cycle::circle(Point::origin(), inner, core).reverse(core)], + [Cycle::circle( + Point::origin(), + inner, + core.layers.topology.surfaces.space_2d(), + core, + ) + .reverse(core)], core, )], core, diff --git a/models/star/src/lib.rs b/models/star/src/lib.rs index aca8327f4..bc41dac39 100644 --- a/models/star/src/lib.rs +++ b/models/star/src/lib.rs @@ -51,7 +51,12 @@ pub fn model( core, ) .add_interiors( - [Cycle::polygon(inner_points, core).reverse(core)], + [Cycle::polygon( + inner_points, + core.layers.topology.surfaces.space_2d(), + core, + ) + .reverse(core)], core, )], core, From 143e12b8f9799be6ab76ee420c254bc09c45b874 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 25 Apr 2024 13:43:38 +0200 Subject: [PATCH 6/8] Refactor to prepare for follow-on change --- .../src/validation/checks/half_edge_connection.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/validation/checks/half_edge_connection.rs b/crates/fj-core/src/validation/checks/half_edge_connection.rs index 489b42608..3cb14b3a5 100644 --- a/crates/fj-core/src/validation/checks/half_edge_connection.rs +++ b/crates/fj-core/src/validation/checks/half_edge_connection.rs @@ -143,13 +143,12 @@ mod tests { fn adjacent_half_edges_not_connected() -> anyhow::Result<()> { let mut core = Core::new(); + let surface = core.layers.topology.surfaces.space_2d(); + // We're only testing for `Face` here, not `Sketch`. Should be fine, as // most of the code is shared. - let valid = Face::polygon( - core.layers.topology.surfaces.space_2d(), - [[0., 0.], [1., 0.], [1., 1.]], - &mut core, - ); + let valid = + Face::polygon(surface, [[0., 0.], [1., 0.], [1., 1.]], &mut core); AdjacentHalfEdgesNotConnected::check_and_return_first_error( &valid, &core.layers.geometry, From 23684c21b51c7b9496195362da8a9eb46b6caba0 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 26 Mar 2024 11:57:48 +0100 Subject: [PATCH 7/8] Provide surface to `BuildHalfEdge` methods --- crates/fj-core/src/operations/build/cycle.rs | 17 ++++++--- .../fj-core/src/operations/build/half_edge.rs | 5 ++- crates/fj-core/src/operations/build/shell.rs | 1 + crates/fj-core/src/operations/holes.rs | 14 ++++++-- crates/fj-core/src/operations/split/face.rs | 1 + .../fj-core/src/operations/sweep/half_edge.rs | 1 + crates/fj-core/src/validate/sketch.rs | 9 +++-- crates/fj-core/src/validate/solid.rs | 35 ++++++++++++++----- .../validation/checks/half_edge_connection.rs | 8 +++-- 9 files changed, 71 insertions(+), 20 deletions(-) diff --git a/crates/fj-core/src/operations/build/cycle.rs b/crates/fj-core/src/operations/build/cycle.rs index 7e3ced9d4..ca5b47f61 100644 --- a/crates/fj-core/src/operations/build/cycle.rs +++ b/crates/fj-core/src/operations/build/cycle.rs @@ -23,15 +23,19 @@ pub trait BuildCycle { fn circle( center: impl Into>, radius: impl Into, - _: Handle, + surface: Handle, core: &mut Core, ) -> Cycle { - let circle = HalfEdge::circle(center, radius, core); + let circle = HalfEdge::circle(center, radius, surface, core); Cycle::empty().add_half_edges([circle], core) } /// Build a polygon - fn polygon(points: Ps, _: Handle, core: &mut Core) -> Cycle + fn polygon( + points: Ps, + surface: Handle, + core: &mut Core, + ) -> Cycle where P: Into>, Ps: IntoIterator, @@ -42,7 +46,12 @@ pub trait BuildCycle { .map(Into::into) .circular_tuple_windows() .map(|(start, end)| { - HalfEdge::line_segment([start, end], None, core) + HalfEdge::line_segment( + [start, end], + None, + surface.clone(), + core, + ) }); Cycle::new(edges) diff --git a/crates/fj-core/src/operations/build/half_edge.rs b/crates/fj-core/src/operations/build/half_edge.rs index 144bba46f..3d951f4d5 100644 --- a/crates/fj-core/src/operations/build/half_edge.rs +++ b/crates/fj-core/src/operations/build/half_edge.rs @@ -5,7 +5,7 @@ use crate::{ geometry::{HalfEdgeGeom, SurfacePath}, operations::{geometry::UpdateHalfEdgeGeometry, insert::Insert}, storage::Handle, - topology::{Curve, HalfEdge, Vertex}, + topology::{Curve, HalfEdge, Surface, Vertex}, Core, }; @@ -46,6 +46,7 @@ pub trait BuildHalfEdge { start: impl Into>, end: impl Into>, angle_rad: impl Into, + _: Handle, core: &mut Core, ) -> Handle { let angle_rad = angle_rad.into(); @@ -76,6 +77,7 @@ pub trait BuildHalfEdge { fn circle( center: impl Into>, radius: impl Into, + _: Handle, core: &mut Core, ) -> Handle { let path = SurfacePath::circle_from_center_and_radius(center, radius); @@ -98,6 +100,7 @@ pub trait BuildHalfEdge { fn line_segment( points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, + _: Handle, core: &mut Core, ) -> Handle { let boundary = diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 6f9e31ea6..c93427a47 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -95,6 +95,7 @@ pub trait BuildShell { let half_edge = HalfEdge::line_segment( positions, Some(boundary.reverse().inner), + surface.clone(), core, ); half_edge diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index 1e7b6f64a..519305263 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -43,7 +43,12 @@ impl AddHole for Shell { path: impl Into>, core: &mut Core, ) -> Self { - let entry = HalfEdge::circle(location.position, radius, core); + let entry = HalfEdge::circle( + location.position, + radius, + location.face.surface().clone(), + core, + ); let hole = Region::empty(core) .update_exterior( |_, core| Cycle::empty().add_half_edges([entry.clone()], core), @@ -91,7 +96,12 @@ impl AddHole for Shell { ) -> Self { let radius = radius.into(); - let entry = HalfEdge::circle(entry_location.position, radius, core); + let entry = HalfEdge::circle( + entry_location.position, + radius, + entry_location.face.surface().clone(), + core, + ); let path = { let point = |location: &HoleLocation| { diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 9f2b15e23..8cfd25d87 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -109,6 +109,7 @@ impl SplitFace for Shell { core.layers.geometry.of_half_edge(&d).start_position(), ], None, + face.surface().clone(), core, ); half_edge diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index bb2b37368..a92056f88 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -122,6 +122,7 @@ impl SweepHalfEdge for Handle { let line_segment = HalfEdge::line_segment( [start, end], Some(boundary), + surface.clone(), core, ); let half_edge = line_segment diff --git a/crates/fj-core/src/validate/sketch.rs b/crates/fj-core/src/validate/sketch.rs index 9d5a4be38..bbae1553c 100644 --- a/crates/fj-core/src/validate/sketch.rs +++ b/crates/fj-core/src/validate/sketch.rs @@ -220,7 +220,8 @@ mod tests { let surface = core.layers.topology.surfaces.space_2d(); - let valid_outer_circle = HalfEdge::circle([0., 0.], 1., &mut core); + let valid_outer_circle = + HalfEdge::circle([0., 0.], 1., surface.clone(), &mut core); let valid_exterior = Cycle::new(vec![valid_outer_circle.clone()]).insert(&mut core); let valid_sketch = Sketch::new( @@ -259,8 +260,10 @@ mod tests { let surface = core.layers.topology.surfaces.space_2d(); - let outer_circle = HalfEdge::circle([0., 0.], 2., &mut core); - let inner_circle = HalfEdge::circle([0., 0.], 1., &mut core); + let outer_circle = + HalfEdge::circle([0., 0.], 2., surface.clone(), &mut core); + let inner_circle = + HalfEdge::circle([0., 0.], 1., surface.clone(), &mut core); let cw_inner_circle = HalfEdge::from_sibling( &inner_circle, Vertex::new().insert(&mut core), diff --git a/crates/fj-core/src/validate/solid.rs b/crates/fj-core/src/validate/solid.rs index e1de52522..1f2a8a75c 100644 --- a/crates/fj-core/src/validate/solid.rs +++ b/crates/fj-core/src/validate/solid.rs @@ -204,8 +204,13 @@ mod tests { &mut core, ), Region::new( - Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)]) - .insert(&mut core), + Cycle::new(vec![HalfEdge::circle( + [0., 0.], + 1., + core.layers.topology.surfaces.space_2d(), + &mut core, + )]) + .insert(&mut core), vec![], ) .insert(&mut core), @@ -249,8 +254,13 @@ mod tests { let mut core = Core::new(); let shared_region = Region::new( - Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)]) - .insert(&mut core), + Cycle::new(vec![HalfEdge::circle( + [0., 0.], + 1., + core.layers.topology.surfaces.space_2d(), + &mut core, + )]) + .insert(&mut core), vec![], ) .insert(&mut core); @@ -299,9 +309,13 @@ mod tests { fn should_find_cycle_multiple_references() -> anyhow::Result<()> { let mut core = Core::new(); - let shared_cycle = - Cycle::new(vec![HalfEdge::circle([0., 0.], 1., &mut core)]) - .insert(&mut core); + let shared_cycle = Cycle::new(vec![HalfEdge::circle( + [0., 0.], + 1., + core.layers.topology.surfaces.space_2d(), + &mut core, + )]) + .insert(&mut core); let invalid_solid = Solid::new(vec![Shell::new(vec![ Face::new( @@ -347,7 +361,12 @@ mod tests { fn should_find_half_edge_multiple_references() -> anyhow::Result<()> { let mut core = Core::new(); - let shared_edge = HalfEdge::circle([0., 0.], 1., &mut core); + let shared_edge = HalfEdge::circle( + [0., 0.], + 1., + core.layers.topology.surfaces.space_2d(), + &mut core, + ); let invalid_solid = Solid::new(vec![Shell::new(vec![Face::new( Surface::from_uv( diff --git a/crates/fj-core/src/validation/checks/half_edge_connection.rs b/crates/fj-core/src/validation/checks/half_edge_connection.rs index 3cb14b3a5..f38fbcf37 100644 --- a/crates/fj-core/src/validation/checks/half_edge_connection.rs +++ b/crates/fj-core/src/validation/checks/half_edge_connection.rs @@ -147,8 +147,11 @@ mod tests { // We're only testing for `Face` here, not `Sketch`. Should be fine, as // most of the code is shared. - let valid = - Face::polygon(surface, [[0., 0.], [1., 0.], [1., 1.]], &mut core); + let valid = Face::polygon( + surface.clone(), + [[0., 0.], [1., 0.], [1., 1.]], + &mut core, + ); AdjacentHalfEdgesNotConnected::check_and_return_first_error( &valid, &core.layers.geometry, @@ -164,6 +167,7 @@ mod tests { [HalfEdge::line_segment( [[0., 0.], [2., 0.]], None, + surface, core, )] }, From d97582cc42efd6033803034ea9bc6481a7012dad Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 26 Mar 2024 12:06:04 +0100 Subject: [PATCH 8/8] Define curve geometry in `BuildHalfEdge` --- .../fj-core/src/operations/build/half_edge.rs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/operations/build/half_edge.rs b/crates/fj-core/src/operations/build/half_edge.rs index 3d951f4d5..7baa68e27 100644 --- a/crates/fj-core/src/operations/build/half_edge.rs +++ b/crates/fj-core/src/operations/build/half_edge.rs @@ -2,7 +2,7 @@ use fj_interop::ext::ArrayExt; use fj_math::{Arc, Point, Scalar}; use crate::{ - geometry::{HalfEdgeGeom, SurfacePath}, + geometry::{CurveGeom, HalfEdgeGeom, SurfacePath}, operations::{geometry::UpdateHalfEdgeGeometry, insert::Insert}, storage::Handle, topology::{Curve, HalfEdge, Surface, Vertex}, @@ -46,7 +46,7 @@ pub trait BuildHalfEdge { start: impl Into>, end: impl Into>, angle_rad: impl Into, - _: Handle, + surface: Handle, core: &mut Core, ) -> Handle { let angle_rad = angle_rad.into(); @@ -62,6 +62,11 @@ pub trait BuildHalfEdge { [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord])); let half_edge = HalfEdge::unjoined(core).insert(core); + + core.layers.geometry.define_curve( + half_edge.curve().clone(), + CurveGeom::from_path_and_surface(path, surface), + ); core.layers.geometry.define_half_edge( half_edge.clone(), HalfEdgeGeom { @@ -77,7 +82,7 @@ pub trait BuildHalfEdge { fn circle( center: impl Into>, radius: impl Into, - _: Handle, + surface: Handle, core: &mut Core, ) -> Handle { let path = SurfacePath::circle_from_center_and_radius(center, radius); @@ -85,6 +90,11 @@ pub trait BuildHalfEdge { [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord])); let half_edge = HalfEdge::unjoined(core).insert(core); + + core.layers.geometry.define_curve( + half_edge.curve().clone(), + CurveGeom::from_path_and_surface(path, surface), + ); core.layers.geometry.define_half_edge( half_edge.clone(), HalfEdgeGeom { @@ -100,7 +110,7 @@ pub trait BuildHalfEdge { fn line_segment( points_surface: [impl Into>; 2], boundary: Option<[Point<1>; 2]>, - _: Handle, + surface: Handle, core: &mut Core, ) -> Handle { let boundary = @@ -111,6 +121,10 @@ pub trait BuildHalfEdge { let half_edge = HalfEdge::unjoined(core).insert(core); + core.layers.geometry.define_curve( + half_edge.curve().clone(), + CurveGeom::from_path_and_surface(path, surface), + ); core.layers.geometry.define_half_edge( half_edge.clone(), HalfEdgeGeom {