From 86650e61a2691794fb1d8ad68ba66f5d6ce2250f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 25 Jun 2024 20:36:49 +0200 Subject: [PATCH 01/17] Construct half-edge boundary from vertex geometry --- crates/fj-core/src/algorithms/approx/cycle.rs | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/cycle.rs b/crates/fj-core/src/algorithms/approx/cycle.rs index dfedcdf38..981fcb8f0 100644 --- a/crates/fj-core/src/algorithms/approx/cycle.rs +++ b/crates/fj-core/src/algorithms/approx/cycle.rs @@ -5,7 +5,7 @@ use fj_math::Segment; use crate::{ - geometry::Geometry, + geometry::{CurveBoundary, Geometry}, storage::Handle, topology::{Cycle, Surface}, }; @@ -28,9 +28,24 @@ pub fn approx_cycle( let half_edges = cycle .half_edges() - .iter() - .map(|half_edge| { - let boundary = geometry.of_half_edge(half_edge).boundary; + .pairs() + .map(|(half_edge, next_half_edge)| { + let boundary = CurveBoundary { + inner: [ + geometry + .of_vertex(half_edge.start_vertex()) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position, + geometry + .of_vertex(next_half_edge.start_vertex()) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position, + ], + }; let [start_position_curve, _] = boundary.inner; let start = approx_vertex( From b655fb6dbf857ed71c315b20ca55f79c250d3ac2 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 27 Jun 2024 20:54:03 +0200 Subject: [PATCH 02/17] Read vertex geometry in validation check --- .../fj-core/src/validation/checks/half_edge_connection.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 376cdf1e0..6dcabad65 100644 --- a/crates/fj-core/src/validation/checks/half_edge_connection.rs +++ b/crates/fj-core/src/validation/checks/half_edge_connection.rs @@ -99,7 +99,12 @@ fn check_cycle<'r>( ) -> impl Iterator + 'r { cycle.half_edges().pairs().filter_map(|(first, second)| { let end_pos_of_first_half_edge = { - let [_, end] = geometry.of_half_edge(first).boundary.inner; + let end = geometry + .of_vertex(second.start_vertex()) + .unwrap() + .local_on(first.curve()) + .unwrap() + .position; geometry .of_curve(first.curve()) .unwrap() From 8778855744ee4755b466a9ca12ae78bf2fc3ef10 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:50:27 +0200 Subject: [PATCH 03/17] Require end vertex for `HalfEdge` AABB calculation This is preparation for using the vertex geometry there. --- crates/fj-core/src/algorithms/bounding_volume/cycle.rs | 4 ++-- .../fj-core/src/algorithms/bounding_volume/half_edge.rs | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/algorithms/bounding_volume/cycle.rs b/crates/fj-core/src/algorithms/bounding_volume/cycle.rs index a934a38a1..1c19db6ae 100644 --- a/crates/fj-core/src/algorithms/bounding_volume/cycle.rs +++ b/crates/fj-core/src/algorithms/bounding_volume/cycle.rs @@ -12,8 +12,8 @@ impl super::BoundingVolume<2> for (&Cycle, &Handle) { let mut aabb: Option> = None; - for half_edge in cycle.half_edges() { - let new_aabb = (half_edge, surface) + for (half_edge, half_edge_next) in cycle.half_edges().pairs() { + let new_aabb = (half_edge, half_edge_next.start_vertex(), surface) .aabb(geometry) .expect("`HalfEdge` can always compute AABB"); aabb = Some(aabb.map_or(new_aabb, |aabb| aabb.merged(&new_aabb))); diff --git a/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs b/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs index 5f5322f62..0062404c3 100644 --- a/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs +++ b/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs @@ -3,12 +3,14 @@ use fj_math::{Aabb, Vector}; use crate::{ geometry::{Geometry, SurfacePath}, storage::Handle, - topology::{HalfEdge, Surface}, + topology::{HalfEdge, Surface, Vertex}, }; -impl super::BoundingVolume<2> for (&Handle, &Handle) { +impl super::BoundingVolume<2> + for (&Handle, &Handle, &Handle) +{ fn aabb(self, geometry: &Geometry) -> Option> { - let (half_edge, surface) = self; + let (half_edge, _end_vertex, surface) = self; let half_edge_geom = geometry.of_half_edge(half_edge); let path = geometry From bed86118debf3a8d201916f260e83dea5da6d6a0 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 18:55:32 +0200 Subject: [PATCH 04/17] Read vertex geometry in bounding box calculation --- .../src/algorithms/bounding_volume/half_edge.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs b/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs index 0062404c3..ba8ee4408 100644 --- a/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs +++ b/crates/fj-core/src/algorithms/bounding_volume/half_edge.rs @@ -10,9 +10,8 @@ impl super::BoundingVolume<2> for (&Handle, &Handle, &Handle) { fn aabb(self, geometry: &Geometry) -> Option> { - let (half_edge, _end_vertex, surface) = self; + let (half_edge, end_vertex, surface) = self; - let half_edge_geom = geometry.of_half_edge(half_edge); let path = geometry .of_curve(half_edge.curve()) .unwrap() @@ -34,9 +33,17 @@ impl super::BoundingVolume<2> }) } SurfacePath::Line(_) => { - let points = half_edge_geom.boundary.inner.map(|point_curve| { - path.point_from_path_coords(point_curve) - }); + let points = + [half_edge.start_vertex(), end_vertex].map(|vertex| { + let point_curve = geometry + .of_vertex(vertex) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position; + + path.point_from_path_coords(point_curve) + }); Some(Aabb::<2>::from_points(points)) } From 22b50e2f319189bf05899e4bc96bd667d742d029 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 19:15:23 +0200 Subject: [PATCH 05/17] Read vertex geometry in validation check --- .../src/validation/checks/half_edge_connection.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 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 6dcabad65..4a181b56f 100644 --- a/crates/fj-core/src/validation/checks/half_edge_connection.rs +++ b/crates/fj-core/src/validation/checks/half_edge_connection.rs @@ -122,9 +122,18 @@ fn check_cycle<'r>( return None; }; - let start_pos_of_second_half_edge = geometry - .of_half_edge(second) - .start_position(&local_curve_geometry.path); + let start_pos_of_second_half_edge = { + let point_curve = geometry + .of_vertex(second.start_vertex()) + .unwrap() + .local_on(second.curve()) + .unwrap() + .position; + + local_curve_geometry + .path + .point_from_path_coords(point_curve) + }; let distance_between_positions = (end_pos_of_first_half_edge - start_pos_of_second_half_edge) From 24e0b0cbcaacb9916e843ae6bbe517c40b849686 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 19:33:27 +0200 Subject: [PATCH 06/17] Add variable to increase clarity --- crates/fj-core/src/operations/split/face.rs | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 8b8b53e67..f55325246 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -104,18 +104,20 @@ impl SplitFace for Shell { // Build the edge that's going to divide the new faces. let dividing_half_edge_a_to_d = { + let start = core.layers.geometry.of_half_edge(&b).start_position( + &core + .layers + .geometry + .of_curve(b.curve()) + .unwrap() + .local_on(face.surface()) + .unwrap() + .path, + ); + let (half_edge, boundary) = HalfEdge::line_segment( [ - core.layers.geometry.of_half_edge(&b).start_position( - &core - .layers - .geometry - .of_curve(b.curve()) - .unwrap() - .local_on(face.surface()) - .unwrap() - .path, - ), + start, core.layers.geometry.of_half_edge(&d).start_position( &core .layers From aec37de69b86b5e985b1de422b6a2afddb67b61d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 19:33:49 +0200 Subject: [PATCH 07/17] Add variable to increase clarity --- crates/fj-core/src/operations/split/face.rs | 24 ++++++++++----------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index f55325246..261d588a2 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -114,21 +114,19 @@ impl SplitFace for Shell { .unwrap() .path, ); + let end = core.layers.geometry.of_half_edge(&d).start_position( + &core + .layers + .geometry + .of_curve(d.curve()) + .unwrap() + .local_on(face.surface()) + .unwrap() + .path, + ); let (half_edge, boundary) = HalfEdge::line_segment( - [ - start, - core.layers.geometry.of_half_edge(&d).start_position( - &core - .layers - .geometry - .of_curve(d.curve()) - .unwrap() - .local_on(face.surface()) - .unwrap() - .path, - ), - ], + [start, end], face.surface().clone(), core, ); From 8648590fa8c8777ec04c9e850a41b52f2f260607 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 28 Jun 2024 19:36:29 +0200 Subject: [PATCH 08/17] Read vertex geometry in `SplitFace::split_face` --- crates/fj-core/src/operations/split/face.rs | 54 +++++++++++++-------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index 261d588a2..c742ac478 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -104,26 +104,40 @@ impl SplitFace for Shell { // Build the edge that's going to divide the new faces. let dividing_half_edge_a_to_d = { - let start = core.layers.geometry.of_half_edge(&b).start_position( - &core - .layers - .geometry - .of_curve(b.curve()) - .unwrap() - .local_on(face.surface()) - .unwrap() - .path, - ); - let end = core.layers.geometry.of_half_edge(&d).start_position( - &core - .layers - .geometry - .of_curve(d.curve()) - .unwrap() - .local_on(face.surface()) - .unwrap() - .path, - ); + let start = core + .layers + .geometry + .of_curve(b.curve()) + .unwrap() + .local_on(face.surface()) + .unwrap() + .path + .point_from_path_coords( + core.layers + .geometry + .of_vertex(b.start_vertex()) + .unwrap() + .local_on(b.curve()) + .unwrap() + .position, + ); + let end = core + .layers + .geometry + .of_curve(d.curve()) + .unwrap() + .local_on(face.surface()) + .unwrap() + .path + .point_from_path_coords( + core.layers + .geometry + .of_vertex(d.start_vertex()) + .unwrap() + .local_on(d.curve()) + .unwrap() + .position, + ); let (half_edge, boundary) = HalfEdge::line_segment( [start, end], From 2ba09e1213845aa5335b131ff6cc5f94b3d1b496 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 20:18:21 +0200 Subject: [PATCH 09/17] Read vertex geometry in `Cycle::winding` --- crates/fj-core/src/topology/objects/cycle.rs | 22 +++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/fj-core/src/topology/objects/cycle.rs b/crates/fj-core/src/topology/objects/cycle.rs index 2ad742a51..f4c57fb99 100644 --- a/crates/fj-core/src/topology/objects/cycle.rs +++ b/crates/fj-core/src/topology/objects/cycle.rs @@ -80,14 +80,20 @@ impl Cycle { for (a, b) in self.half_edges().pairs() { let [a, b] = [a, b].map(|half_edge| { - geometry.of_half_edge(half_edge).start_position( - &geometry - .of_curve(half_edge.curve()) - .unwrap() - .local_on(surface) - .unwrap() - .path, - ) + geometry + .of_curve(half_edge.curve()) + .unwrap() + .local_on(surface) + .unwrap() + .path + .point_from_path_coords( + geometry + .of_vertex(half_edge.start_vertex()) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position, + ) }); sum += (b.u - a.u) * (b.v + a.v); From 04dc00988f83532ddd3168c802c88c5afc9edfc3 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 20:20:37 +0200 Subject: [PATCH 10/17] Read vertex geometry in solid validation check --- crates/fj-core/src/validate/solid.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/validate/solid.rs b/crates/fj-core/src/validate/solid.rs index f51191aa7..64d0ebae9 100644 --- a/crates/fj-core/src/validate/solid.rs +++ b/crates/fj-core/src/validate/solid.rs @@ -117,9 +117,14 @@ impl SolidValidationError { Some(( geometry.of_surface(s).point_from_surface_coords( - geometry - .of_half_edge(&h) - .start_position(&local_curve_geometry.path), + local_curve_geometry.path.point_from_path_coords( + geometry + .of_vertex(h.start_vertex()) + .unwrap() + .local_on(h.curve()) + .unwrap() + .position, + ), ), h.start_vertex().clone(), )) From e96f66c17e31cdb8fa4fddd1c97db3d2fd1bfcd5 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 20:30:23 +0200 Subject: [PATCH 11/17] Prepare for follow-on change --- crates/fj-core/src/operations/sweep/half_edge.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index d04dc5bdf..20710ed08 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -59,7 +59,7 @@ impl SweepHalfEdge for Handle { ) -> SweptHalfEdge { let path = path.into(); - let half_edge_geom = *core.layers.geometry.of_half_edge(self); + let boundary = core.layers.geometry.of_half_edge(self).boundary.inner; let curve_geom = core .layers .geometry @@ -94,7 +94,7 @@ impl SweepHalfEdge for Handle { // Let's figure out the surface coordinates of the edge vertices. let surface_points = { - let [a, b] = half_edge_geom.boundary.inner; + let [a, b] = boundary; [ [a.t, Scalar::ZERO], @@ -112,7 +112,7 @@ impl SweepHalfEdge for Handle { // Now, the boundaries of each edge. let boundaries = { - let [a, b] = half_edge_geom.boundary.inner; + let [a, b] = boundary; let [c, d] = [0., 1.].map(|coord| Point::from([coord])); [[a, b], [c, d], [b, a], [d, c]] From 972895707e675a514966c32a41fe62360a16388d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 20:35:08 +0200 Subject: [PATCH 12/17] Read vertex geometry in `SweepHalfEdge` --- .../fj-core/src/operations/sweep/half_edge.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/sweep/half_edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs index 20710ed08..522a33e23 100644 --- a/crates/fj-core/src/operations/sweep/half_edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -59,7 +59,22 @@ impl SweepHalfEdge for Handle { ) -> SweptHalfEdge { let path = path.into(); - let boundary = core.layers.geometry.of_half_edge(self).boundary.inner; + let boundary = [ + core.layers + .geometry + .of_vertex(self.start_vertex()) + .unwrap() + .local_on(self.curve()) + .unwrap() + .position, + core.layers + .geometry + .of_vertex(&end_vertex) + .unwrap() + .local_on(self.curve()) + .unwrap() + .position, + ]; let curve_geom = core .layers .geometry From d2d89fcec2b01b2d97cfffe955c4141ffc92339a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 21:06:32 +0200 Subject: [PATCH 13/17] Read vertex geometry in `SplitHalfEdge` --- .../fj-core/src/operations/split/half_edge.rs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/split/half_edge.rs b/crates/fj-core/src/operations/split/half_edge.rs index 3e304e933..ba9ee5d64 100644 --- a/crates/fj-core/src/operations/split/half_edge.rs +++ b/crates/fj-core/src/operations/split/half_edge.rs @@ -46,7 +46,27 @@ impl SplitHalfEdge for Cycle { let point = point.into(); let geometry = *core.layers.geometry.of_half_edge(half_edge); - let [start, end] = geometry.boundary.inner; + let [start, end] = [ + core.layers + .geometry + .of_vertex(half_edge.start_vertex()) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position, + core.layers + .geometry + .of_vertex( + self.half_edges() + .after(half_edge) + .expect("Expected half-edge to be in cycle") + .start_vertex(), + ) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position, + ]; let a = HalfEdge::new( half_edge.curve().clone(), From 104bbea1ed5629557350d43e2ba538baa89d394e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 21:20:31 +0200 Subject: [PATCH 14/17] Read vertex geometry in `Cycle::winding` --- crates/fj-core/src/topology/objects/cycle.rs | 25 ++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/topology/objects/cycle.rs b/crates/fj-core/src/topology/objects/cycle.rs index f4c57fb99..509072bee 100644 --- a/crates/fj-core/src/topology/objects/cycle.rs +++ b/crates/fj-core/src/topology/objects/cycle.rs @@ -46,7 +46,6 @@ impl Cycle { .next() .expect("Invalid cycle: expected at least one edge"); - let half_edge_geom = geometry.of_half_edge(first); let curve_geom = geometry .of_curve(first.curve()) .unwrap() @@ -54,7 +53,29 @@ impl Cycle { .unwrap() .clone(); - let [a, b] = half_edge_geom.boundary.inner; + let [a, b] = [ + curve_geom.path.point_from_path_coords( + geometry + .of_vertex(first.start_vertex()) + .unwrap() + .local_on(first.curve()) + .unwrap() + .position, + ), + curve_geom.path.point_from_path_coords( + geometry + .of_vertex( + self.half_edges() + .after(first) + .expect("Just got half-edge from this cycle") + .start_vertex(), + ) + .unwrap() + .local_on(first.curve()) + .unwrap() + .position, + ), + ]; let edge_direction_positive = a < b; let circle = match curve_geom.path { From 35edeaca761af5e9ecd128e3131f75d9a4a71246 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 21:26:37 +0200 Subject: [PATCH 15/17] Remove commented code --- .../validation/checks/coincident_half_edges_are_not_siblings.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs index cb1529dfe..7007ca95d 100644 --- a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs +++ b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs @@ -165,12 +165,10 @@ fn distances( ) -> Option> { let [start, end] = geometry.of_half_edge(half_edge).boundary.inner; let path_coords = start + (end - start) * percent; - // let path = geometry.of_half_edge(half_edge).path; let path = geometry .of_curve(half_edge.curve())? .local_on(surface)? .path; - // assert_eq!(path, path_from_curve); let surface_coords = path.point_from_path_coords(path_coords); Some( geometry From 22433ac8b86473a52b401cac12ffb87c65d91970 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 21:28:11 +0200 Subject: [PATCH 16/17] Read vertex geometry in validation check --- .../coincident_half_edges_are_not_siblings.rs | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs index 7007ca95d..ca13ffd2c 100644 --- a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs +++ b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs @@ -5,7 +5,8 @@ use fj_math::{Point, Scalar}; use crate::{ geometry::{CurveBoundary, Geometry}, queries::{ - AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge, SiblingOfHalfEdge, + AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge, CycleOfHalfEdge, + SiblingOfHalfEdge, }, storage::Handle, topology::{Curve, HalfEdge, Shell, Surface, Vertex}, @@ -109,8 +110,22 @@ impl ValidationCheck for CoincidentHalfEdgesAreNotSiblings { let Some(mut distances) = distances( half_edge_a.clone(), + object + .find_cycle_of_half_edge(half_edge_a) + .unwrap() + .half_edges() + .after(half_edge_a) + .unwrap() + .start_vertex(), surface_a, half_edge_b.clone(), + object + .find_cycle_of_half_edge(half_edge_b) + .unwrap() + .half_edges() + .after(half_edge_b) + .unwrap() + .start_vertex(), surface_b, geometry, ) else { @@ -152,18 +167,34 @@ impl ValidationCheck for CoincidentHalfEdgesAreNotSiblings { /// Returns an [`Iterator`] of the distance at each sample. fn distances( half_edge_a: Handle, + end_vertex_a: &Handle, surface_a: &Handle, half_edge_b: Handle, + end_vertex_b: &Handle, surface_b: &Handle, geometry: &Geometry, ) -> Option> { fn sample( percent: f64, half_edge: &Handle, + end_vertex: &Handle, surface: &Handle, geometry: &Geometry, ) -> Option> { - let [start, end] = geometry.of_half_edge(half_edge).boundary.inner; + let [start, end] = [ + geometry + .of_vertex(half_edge.start_vertex()) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position, + geometry + .of_vertex(end_vertex) + .unwrap() + .local_on(half_edge.curve()) + .unwrap() + .position, + ]; let path_coords = start + (end - start) * percent; let path = geometry .of_curve(half_edge.curve())? @@ -186,8 +217,15 @@ fn distances( let mut distances = Vec::new(); for i in 0..sample_count { let percent = i as f64 * step; - let sample1 = sample(percent, &half_edge_a, surface_a, geometry)?; - let sample2 = sample(1.0 - percent, &half_edge_b, surface_b, geometry)?; + let sample1 = + sample(percent, &half_edge_a, end_vertex_a, surface_a, geometry)?; + let sample2 = sample( + 1.0 - percent, + &half_edge_b, + end_vertex_b, + surface_b, + geometry, + )?; distances.push(sample1.distance_to(&sample2)) } Some(distances.into_iter()) From be89c2ea121e5b71c35eba3fe0274b0d03a2cd3e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 9 Jul 2024 21:32:33 +0200 Subject: [PATCH 17/17] Read vertex geometry in validation check --- .../checks/curve_geometry_mismatch.rs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs b/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs index bd8fb440b..adf1f8188 100644 --- a/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs +++ b/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use crate::{ geometry::Geometry, - queries::AllHalfEdgesWithSurface, + queries::{AllHalfEdgesWithSurface, CycleOfHalfEdge}, storage::Handle, topology::{HalfEdge, Shell}, validation::{ValidationCheck, ValidationConfig}, @@ -130,8 +130,28 @@ impl ValidationCheck for CurveGeometryMismatch { // we have right now are circles, 3 would be enough to check // for coincidence. But the first and last might be // identical, so let's add an extra one. - let [a, d] = - geometry.of_half_edge(&half_edge_a).boundary.inner; + let [a, d] = [ + geometry + .of_vertex(half_edge_a.start_vertex()) + .unwrap() + .local_on(half_edge_a.curve()) + .unwrap() + .position, + geometry + .of_vertex( + object + .find_cycle_of_half_edge(&half_edge_a) + .unwrap() + .half_edges() + .after(&half_edge_a) + .unwrap() + .start_vertex(), + ) + .unwrap() + .local_on(half_edge_a.curve()) + .unwrap() + .position, + ]; let b = a + (d - a) * 1. / 3.; let c = a + (d - a) * 2. / 3.;