Don't use self.path in HalfEdgeGeom

This prepares for moving the path to `CurveGeom`.
This commit is contained in:
Hanno Braun 2024-04-25 14:07:05 +02:00 committed by Hanno Braun
parent 30549bc82e
commit f7513d0646
7 changed files with 73 additions and 14 deletions

View File

@ -30,7 +30,14 @@ impl Approx for (&Handle<HalfEdge>, &Handle<Surface>) {
let tolerance = tolerance.into(); let tolerance = tolerance.into();
let start_position_surface = let start_position_surface =
geometry.of_half_edge(half_edge).start_position(); geometry.of_half_edge(half_edge).start_position(
&geometry
.of_curve(half_edge.curve())
.unwrap()
.local_on(surface)
.unwrap()
.path,
);
let start_position = let start_position =
match cache.start_position.get(half_edge.start_vertex()) { match cache.start_position.get(half_edge.start_vertex()) {
Some(position) => position, Some(position) => position,

View File

@ -47,12 +47,12 @@ impl HalfEdgeGeom {
} }
/// Compute the surface position where the half-edge starts /// Compute the surface position where the half-edge starts
pub fn start_position(&self) -> Point<2> { pub fn start_position(&self, path: &SurfacePath) -> Point<2> {
// Computing the surface position from the curve position is fine. // Computing the surface position from the curve position is fine.
// `HalfEdge` "owns" its start position. There is no competing code that // `HalfEdge` "owns" its start position. There is no competing code that
// could compute the surface position from slightly different data. // could compute the surface position from slightly different data.
let [start, _] = self.boundary.inner; let [start, _] = self.boundary.inner;
self.path.point_from_path_coords(start) path.point_from_path_coords(start)
} }
} }

View File

@ -105,8 +105,26 @@ impl SplitFace for Shell {
let dividing_half_edge_a_to_d = { let dividing_half_edge_a_to_d = {
let half_edge = HalfEdge::line_segment( let half_edge = HalfEdge::line_segment(
[ [
core.layers.geometry.of_half_edge(&b).start_position(), core.layers.geometry.of_half_edge(&b).start_position(
core.layers.geometry.of_half_edge(&d).start_position(), &core
.layers
.geometry
.of_curve(b.curve())
.unwrap()
.local_on(face.surface())
.unwrap()
.path,
),
core.layers.geometry.of_half_edge(&d).start_position(
&core
.layers
.geometry
.of_curve(d.curve())
.unwrap()
.local_on(face.surface())
.unwrap()
.path,
),
], ],
None, None,
face.surface().clone(), face.surface().clone(),

View File

@ -31,7 +31,11 @@ impl Cycle {
/// Please note that this is not *the* winding of the cycle, only one of the /// Please note that this is not *the* winding of the cycle, only one of the
/// two possible windings, depending on the direction you look at the /// two possible windings, depending on the direction you look at the
/// surface that the cycle is defined on from. /// surface that the cycle is defined on from.
pub fn winding(&self, geometry: &Geometry, _: &Handle<Surface>) -> Winding { pub fn winding(
&self,
geometry: &Geometry,
surface: &Handle<Surface>,
) -> Winding {
// The cycle could be made up of one or two circles. If that is the // The cycle could be made up of one or two circles. If that is the
// case, the winding of the cycle is determined by the winding of the // case, the winding of the cycle is determined by the winding of the
// first circle. // first circle.
@ -70,7 +74,14 @@ impl Cycle {
for (a, b) in self.half_edges().pairs() { for (a, b) in self.half_edges().pairs() {
let [a, b] = [a, b].map(|half_edge| { let [a, b] = [a, b].map(|half_edge| {
geometry.of_half_edge(half_edge).start_position() geometry.of_half_edge(half_edge).start_position(
&geometry
.of_curve(half_edge.curve())
.unwrap()
.local_on(surface)
.unwrap()
.path,
)
}); });
sum += (b.u - a.u) * (b.v + a.v); sum += (b.u - a.u) * (b.v + a.v);

View File

@ -106,13 +106,23 @@ impl SolidValidationError {
.flat_map(|cycle| cycle.half_edges().iter().cloned()) .flat_map(|cycle| cycle.half_edges().iter().cloned())
.zip(repeat(face.surface())) .zip(repeat(face.surface()))
}) })
.map(|(h, s)| { .filter_map(|(h, s)| {
( let Some(local_curve_geometry) =
geometry.of_curve(h.curve()).unwrap().local_on(s)
else {
// If the curve geometry has no local definition,
// there's nothing we can check.
return None;
};
Some((
geometry.of_surface(s).point_from_surface_coords( geometry.of_surface(s).point_from_surface_coords(
geometry.of_half_edge(&h).start_position(), geometry
.of_half_edge(&h)
.start_position(&local_curve_geometry.path),
), ),
h.start_vertex().clone(), h.start_vertex().clone(),
) ))
}) })
.collect(); .collect();

View File

@ -201,6 +201,9 @@ mod tests {
) )
.is_err()); .is_err());
// Ignore remaining validation errors.
let _ = core.layers.validation.take_errors();
Ok(()) Ok(())
} }
} }

View File

@ -93,7 +93,7 @@ fn check_region<'r>(
fn check_cycle<'r>( fn check_cycle<'r>(
cycle: &'r Cycle, cycle: &'r Cycle,
_: &'r Handle<Surface>, surface: &'r Handle<Surface>,
geometry: &'r Geometry, geometry: &'r Geometry,
config: &'r ValidationConfig, config: &'r ValidationConfig,
) -> impl Iterator<Item = AdjacentHalfEdgesNotConnected> + 'r { ) -> impl Iterator<Item = AdjacentHalfEdgesNotConnected> + 'r {
@ -105,8 +105,18 @@ fn check_cycle<'r>(
.path .path
.point_from_path_coords(end) .point_from_path_coords(end)
}; };
let start_pos_of_second_half_edge =
geometry.of_half_edge(second).start_position(); let Some(local_curve_geometry) =
geometry.of_curve(second.curve()).unwrap().local_on(surface)
else {
// If the curve geometry is not defined for our local surface,
// there's nothing we can check.
return None;
};
let start_pos_of_second_half_edge = geometry
.of_half_edge(second)
.start_position(&local_curve_geometry.path);
let distance_between_positions = (end_pos_of_first_half_edge let distance_between_positions = (end_pos_of_first_half_edge
- start_pos_of_second_half_edge) - start_pos_of_second_half_edge)