diff --git a/crates/fj-core/src/operations/build/shell.rs b/crates/fj-core/src/operations/build/shell.rs index 0c846fda6..80027a368 100644 --- a/crates/fj-core/src/operations/build/shell.rs +++ b/crates/fj-core/src/operations/build/shell.rs @@ -166,123 +166,141 @@ pub trait BuildShell { let [a, b, c, d] = points.map(Into::into); let abc = Face::triangle([a, b, c], core); - let bad = Face::triangle([b, a, d], core).update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge + let bad = { + let bad = Face::triangle([b, a, d], core); + bad.update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge.reverse_curve_coordinate_systems( + core, + )] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 0..=0, + bad.face.surface().clone(), + core, + ) + }, + core, + ) + }, + core, + ) + }; + let dac = + { + let dac = Face::triangle([d, a, c], core); + dac.update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 0..=0, - core, - ) + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 1..=1, + 2..=2, + dac.face.surface().clone(), + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + bad.face.region().exterior(), + 0..=0, + 1..=1, + dac.face.surface().clone(), + core, + ) + }, + core, + ) }, core, ) - }, - core, - ); - let dac = Face::triangle([d, a, c], core).update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge + }; + let cbd = + { + let cbd = Face::triangle([c, b, d], core); + cbd.update_region( + |region, core| { + region.update_exterior( + |cycle, core| { + cycle + .update_half_edge( + cycle.half_edges().nth_circular(0), + |edge, core| { + [edge .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(1), + |edge, core| { + [edge .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - bad.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) + }, + core, + ) + .update_half_edge( + cycle.half_edges().nth_circular(2), + |edge, core| { + [edge + .reverse_curve_coordinate_systems(core)] + }, + core, + ) + .join_to( + abc.face.region().exterior(), + 0..=0, + 1..=1, + cbd.face.surface().clone(), + core, + ) + .join_to( + bad.face.region().exterior(), + 1..=1, + 2..=2, + cbd.face.surface().clone(), + core, + ) + .join_to( + dac.face.region().exterior(), + 2..=2, + 2..=2, + cbd.face.surface().clone(), + core, + ) + }, + core, + ) }, core, ) - }, - core, - ); - let cbd = Face::triangle([c, b, d], core).update_region( - |region, core| { - region.update_exterior( - |cycle, core| { - cycle - .update_half_edge( - cycle.half_edges().nth_circular(0), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(1), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .update_half_edge( - cycle.half_edges().nth_circular(2), - |edge, core| { - [edge - .reverse_curve_coordinate_systems(core)] - }, - core, - ) - .join_to( - abc.face.region().exterior(), - 0..=0, - 1..=1, - core, - ) - .join_to( - bad.face.region().exterior(), - 1..=1, - 2..=2, - core, - ) - .join_to( - dac.face.region().exterior(), - 2..=2, - 2..=2, - core, - ) - }, - core, - ) - }, - core, - ); + }; let triangles = [abc, bad, dac, cbd].map(|triangle| triangle.insert(core)); diff --git a/crates/fj-core/src/operations/join/cycle.rs b/crates/fj-core/src/operations/join/cycle.rs index 45122513b..107b75a7f 100644 --- a/crates/fj-core/src/operations/join/cycle.rs +++ b/crates/fj-core/src/operations/join/cycle.rs @@ -84,6 +84,7 @@ pub trait JoinCycle { other: &Cycle, range: RangeInclusive, other_range: RangeInclusive, + surface_self: Handle, core: &mut Core, ) -> Self; } @@ -131,6 +132,7 @@ impl JoinCycle for Cycle { other: &Cycle, range: RangeInclusive, range_other: RangeInclusive, + surface_self: Handle, core: &mut Core, ) -> Self { assert_eq!( @@ -148,6 +150,30 @@ impl JoinCycle for Cycle { .update_half_edge( self.half_edges().nth_circular(index), |half_edge, core| { + // The curve of the other half-edge we're joining + // this one to already has a curve geometry, + // presumably. But it might not have a local + // definition for the surface that *this* half-edge + // is in. + // + // We need to make sure that any local definition + // that our current curve already has, moves over to + // the new one. + let curve_geom = core + .layers + .geometry + .of_curve(half_edge.curve()) + .and_then(|curve_geom| { + curve_geom.local_on(&surface_self) + }); + if let Some(curve_geom) = curve_geom { + core.layers.geometry.define_curve( + edge_other.curve().clone(), + surface_self.clone(), + curve_geom.clone(), + ); + } + [half_edge .update_curve( |_, _| edge_other.curve().clone(),