diff --git a/crates/doc/src/vector_regions.rs b/crates/doc/src/vector_regions.rs index 1d1cd794..b1739160 100644 --- a/crates/doc/src/vector_regions.rs +++ b/crates/doc/src/vector_regions.rs @@ -102,10 +102,18 @@ impl VectorNetwork { (0..self.regions.len()).rev().find(|r| self.region_contains(*r, p)) } - /// Every point on region `r`'s loops (holes' too), each once, sorted. + /// Every point on region `r`'s loops (holes' too), each once, sorted (segments or points that + /// don't exist are left out). pub fn region_points(&self, r: usize) -> Vec { let Some(region) = self.regions.get(r) else { return Vec::new() }; - let mut out: Vec = region.loops.iter().flatten().filter_map(|i| self.segments.get(*i)).flat_map(|s| [s.a, s.b]).collect(); + let mut out: Vec = region + .loops + .iter() + .flatten() + .filter_map(|i| self.segments.get(*i)) + .flat_map(|s| [s.a, s.b]) + .filter(|v| *v < self.vertices.len()) + .collect(); out.sort_unstable(); out.dedup(); out diff --git a/crates/doc/src/vector_regions_tests.rs b/crates/doc/src/vector_regions_tests.rs index d1e3d0d8..c3e71163 100644 --- a/crates/doc/src/vector_regions_tests.rs +++ b/crates/doc/src/vector_regions_tests.rs @@ -186,6 +186,19 @@ fn empty_and_damaged_networks_have_no_regions_and_never_panic() { } } +#[test] +fn region_points_leave_out_segment_ends_that_do_not_exist() { + let mut n = VectorNetwork::default(); + let ring = square(&mut n, 0.0, 0.0, 100.0); + n.regions = vec![region(vec![ring], WindingRule::NonZero)]; + assert_eq!(n.region_points(0), vec![0, 1, 2, 3]); + n.segments[3] = Segment::line(3, 9); + assert_eq!(n.region_points(0), vec![0, 1, 2, 3]); + assert!(n.region_path(0).is_some()); + n.regions = vec![region(vec![vec![99]], WindingRule::NonZero)]; + assert!(n.region_points(0).is_empty()); +} + #[test] fn the_topology_key_ignores_moved_points_but_not_new_segments() { let mut n = nested();