diff --git a/geo/src/algorithm/relate/edge_end_builder.rs b/geo/src/algorithm/relate/edge_end_builder.rs index 4fcaf93c1d..597dbd5b47 100644 --- a/geo/src/algorithm/relate/edge_end_builder.rs +++ b/geo/src/algorithm/relate/edge_end_builder.rs @@ -1,9 +1,6 @@ use super::geomgraph::{Edge, EdgeEnd, EdgeIntersection}; use crate::GeoFloat; -use std::cell::RefCell; -use std::rc::Rc; - /// Computes the [`EdgeEnd`]s which arise from an [`Edge`] who has had its `edge_intersections` /// populated with self and proper [`EdgeIntersection`]s. /// @@ -19,10 +16,10 @@ impl EdgeEndBuilder { } } - pub fn compute_ends_for_edges(&self, edges: &[Rc>>]) -> Vec> { + pub fn compute_ends_for_edges(&self, edges: &mut [Edge]) -> Vec> { let mut list = vec![]; for edge in edges { - self.compute_ends_for_edge(&mut edge.borrow_mut(), &mut list); + self.compute_ends_for_edge(edge, &mut list); } list } diff --git a/geo/src/algorithm/relate/geomgraph/geometry_graph.rs b/geo/src/algorithm/relate/geomgraph/geometry_graph.rs index 6746dc8ac3..03250b48e6 100644 --- a/geo/src/algorithm/relate/geomgraph/geometry_graph.rs +++ b/geo/src/algorithm/relate/geomgraph/geometry_graph.rs @@ -10,8 +10,6 @@ use crate::HasDimensions; use crate::{Coord, GeoFloat, GeometryCow, Line, LineString, Point, Polygon}; use rstar::{RTree, RTreeNum}; -use std::cell::RefCell; -use std::rc::Rc; /// The computation of the [`IntersectionMatrix`](crate::algorithm::relate::IntersectionMatrix) relies on the use of a /// structure called a "topology graph". The topology graph contains nodes (CoordNode) and @@ -35,7 +33,7 @@ where { arg_index: usize, parent_geometry: GeometryCow<'a, F>, - tree: Option>>>, + tree: Option>>, use_boundary_determination_rule: bool, has_computed_self_nodes: bool, planar_graph: PlanarGraph, @@ -49,23 +47,33 @@ impl GeometryGraph<'_, F> where F: GeoFloat, { - pub(crate) fn set_tree(&mut self, tree: Rc>>) { - self.tree = Some(tree); + pub(crate) fn get_tree(&mut self) -> &RTree> { + self.update_tree(); + self.tree.as_ref().unwrap() } - pub(crate) fn get_or_build_tree(&self) -> Rc>> { - self.tree - .clone() - .unwrap_or_else(|| Rc::new(self.build_tree())) + pub(crate) fn tree_and_edges_mut(&mut self) -> (&RTree>, &mut [Edge]) { + self.update_tree(); + let edges = self.planar_graph.edges_mut(); + (self.tree.as_ref().unwrap(), edges) } - pub(crate) fn build_tree(&self) -> RTree> { + pub(crate) fn update_tree(&mut self) { + if self.tree.is_none() { + self.tree = Some(self.build_tree()); + } + } + + fn invalidate_tree(&mut self) { + self.tree = None; + } + + fn build_tree(&self) -> RTree> { let segments: Vec> = self .edges() .iter() .enumerate() .flat_map(|(edge_idx, edge)| { - let edge = RefCell::borrow(edge); let start_of_final_segment: usize = edge.coords().len() - 1; (0..start_of_final_segment).map(move |segment_idx| { let p1 = edge.coords()[segment_idx]; @@ -92,6 +100,7 @@ where self.has_computed_self_nodes, "should only be called after computing self nodes" ); + debug_assert!(self.tree.is_some()); let planar_graph = self .planar_graph .clone_for_arg_index(self.arg_index, arg_index); @@ -105,11 +114,16 @@ where } } - pub(crate) fn edges(&self) -> &[Rc>>] { + pub(crate) fn edges(&self) -> &[Edge] { self.planar_graph.edges() } + pub(crate) fn edges_mut(&mut self) -> &mut [Edge] { + self.planar_graph.edges_mut() + } + pub(crate) fn insert_edge(&mut self, edge: Edge) { + self.invalidate_tree(); self.planar_graph.insert_edge(edge) } @@ -159,7 +173,7 @@ where } } - fn boundary_nodes(&self) -> impl Iterator> { + pub(crate) fn boundary_nodes(&self) -> impl Iterator> { self.planar_graph.boundary_nodes(self.arg_index) } @@ -352,8 +366,8 @@ where } pub(crate) fn compute_edge_intersections( - &self, - other: &GeometryGraph, + &'a mut self, + other: &mut GeometryGraph<'a, F>, line_intersector: Box>, ) -> SegmentIntersector { let mut segment_intersector = SegmentIntersector::new(line_intersector, false); @@ -404,7 +418,6 @@ where let positions_and_intersections: Vec<(CoordPos, Vec>)> = self .edges() .iter() - .map(|cell| cell.borrow()) .map(|edge| { let position = edge .label() diff --git a/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs index a1f81af66b..f5c89db6dc 100644 --- a/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs @@ -14,7 +14,7 @@ pub(crate) trait EdgeSetIntersector { /// `segment_intersector`: the SegmentIntersector to use fn compute_intersections_within_set( &self, - graph: &GeometryGraph, + graph: &mut GeometryGraph, check_for_self_intersecting_edges: bool, segment_intersector: &mut SegmentIntersector, ); @@ -23,8 +23,8 @@ pub(crate) trait EdgeSetIntersector { /// the intersecting edges. fn compute_intersections_between_sets<'a>( &self, - graph_0: &GeometryGraph<'a, F>, - graph_1: &GeometryGraph<'a, F>, + graph_0: &mut GeometryGraph<'a, F>, + graph_1: &mut GeometryGraph<'a, F>, segment_intersector: &mut SegmentIntersector, ); } diff --git a/geo/src/algorithm/relate/geomgraph/index/prepared_geometry.rs b/geo/src/algorithm/relate/geomgraph/index/prepared_geometry.rs index 2fbc199e21..d03d6b7003 100644 --- a/geo/src/algorithm/relate/geomgraph/index/prepared_geometry.rs +++ b/geo/src/algorithm/relate/geomgraph/index/prepared_geometry.rs @@ -5,7 +5,6 @@ use crate::GeometryCow; use crate::{GeoFloat, Relate}; use std::cell::RefCell; -use std::rc::Rc; use rstar::{RTree, RTreeNum}; @@ -26,6 +25,7 @@ use rstar::{RTree, RTreeNum}; /// assert!(prepared_polygon.relate(&contained_line).is_contains()); /// /// ``` +#[derive(Clone)] pub struct PreparedGeometry<'a, F: GeoFloat + RTreeNum = f64> { geometry_graph: GeometryGraph<'a, F>, } @@ -38,7 +38,7 @@ mod conversions { Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; - use std::rc::Rc; + use std::sync::Arc; impl<'a, F: GeoFloat> From> for PreparedGeometry<'a, F> { fn from(point: Point) -> Self { @@ -156,7 +156,7 @@ mod conversions { impl<'a, F: GeoFloat> From> for PreparedGeometry<'a, F> { fn from(geometry: GeometryCow<'a, F>) -> Self { let mut geometry_graph = GeometryGraph::new(0, geometry); - geometry_graph.set_tree(Rc::new(geometry_graph.build_tree())); + geometry_graph.update_tree(); // TODO: maybe unecessary // TODO: don't pass in line intersector here - in theory we'll want pluggable line intersectors // and the type (Robust) shouldn't be hard coded here. diff --git a/geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs index 5c0190d33b..92f0c6028d 100644 --- a/geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs @@ -15,42 +15,64 @@ where { fn compute_intersections_within_set( &self, - graph: &GeometryGraph, + graph: &mut GeometryGraph, check_for_self_intersecting_edges: bool, segment_intersector: &mut SegmentIntersector, ) { - let edges = graph.edges(); - - let tree = graph.get_or_build_tree(); - for (segment_0, segment_1) in tree.intersection_candidates_with_other_tree(&tree) { + let (tree, edges) = graph.tree_and_edges_mut(); + for (segment_0, segment_1) in tree.intersection_candidates_with_other_tree(tree) { if check_for_self_intersecting_edges || segment_0.edge_idx != segment_1.edge_idx { - let edge_0 = &edges[segment_0.edge_idx]; - let edge_1 = &edges[segment_1.edge_idx]; - segment_intersector.add_intersections( - edge_0, - segment_0.segment_idx, - edge_1, - segment_1.segment_idx, - ); + if segment_1.edge_idx == segment_0.edge_idx { + let edge_0 = &mut edges[segment_0.edge_idx]; + segment_intersector.add_intersections_against_self( + edge_0, + segment_0.segment_idx, + segment_1.segment_idx, + ); + } else { + // TODO: use get_many_mut when available. + let mi = segment_0.edge_idx.min(segment_1.edge_idx); + let mx = segment_0.edge_idx.max(segment_1.edge_idx); + + assert!(mx > mi); + + let (e0, e1) = edges.split_at_mut(mi + 1); + + let edge_0 = &mut e0[mi]; + let edge_1 = &mut e1[mx - (mi + 1)]; + + if segment_0.edge_idx > segment_1.edge_idx { + segment_intersector.add_intersections( + edge_1, + segment_0.segment_idx, + edge_0, + segment_1.segment_idx, + ); + } else { + segment_intersector.add_intersections( + edge_0, + segment_0.segment_idx, + edge_1, + segment_1.segment_idx, + ); + } + } } } } fn compute_intersections_between_sets<'a>( &self, - graph_0: &GeometryGraph<'a, F>, - graph_1: &GeometryGraph<'a, F>, + graph_0: &mut GeometryGraph<'a, F>, + graph_1: &mut GeometryGraph<'a, F>, segment_intersector: &mut SegmentIntersector, ) { - let edges_0 = graph_0.edges(); - let edges_1 = graph_1.edges(); - - let tree_0 = graph_0.get_or_build_tree(); - let tree_1 = graph_1.get_or_build_tree(); + let (tree_0, edges_0) = graph_0.tree_and_edges_mut(); + let (tree_1, edges_1) = graph_1.tree_and_edges_mut(); - for (segment_0, segment_1) in tree_0.intersection_candidates_with_other_tree(&tree_1) { - let edge_0 = &edges_0[segment_0.edge_idx]; - let edge_1 = &edges_1[segment_1.edge_idx]; + for (segment_0, segment_1) in tree_0.intersection_candidates_with_other_tree(tree_1) { + let edge_0 = &mut edges_0[segment_0.edge_idx]; + let edge_1 = &mut edges_1[segment_1.edge_idx]; segment_intersector.add_intersections( edge_0, segment_0.segment_idx, diff --git a/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs index 933281d022..22fbc9b085 100644 --- a/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs @@ -64,12 +64,12 @@ where fn is_trivial_intersection( &self, intersection: LineIntersection, - edge0: &RefCell>, + edge0: &Edge, segment_index_0: usize, - edge1: &RefCell>, + edge1: &Edge, segment_index_1: usize, ) -> bool { - if edge0.as_ptr() != edge1.as_ptr() { + if !std::ptr::eq(edge0, edge1) { return false; } @@ -81,7 +81,6 @@ where return true; } - let edge0 = edge0.borrow(); if edge0.is_closed() { // first and last coords in a ring are adjacent let max_segment_index = edge0.coords().len() - 1; @@ -95,25 +94,85 @@ where false } + // Copy of `add_intersections` specialized for a single 'edge' against itself. + pub fn add_intersections_against_self( + &mut self, + edge0: &mut Edge, + segment_index_0: usize, + segment_index_1: usize, + ) { + // avoid a segment spuriously "intersecting" with itself + if segment_index_0 == segment_index_1 { + return; + } + + let line_0 = Line::new( + edge0.coords()[segment_index_0], + edge0.coords()[segment_index_0 + 1], + ); + let line_1 = Line::new( + edge0.coords()[segment_index_1], + edge0.coords()[segment_index_1 + 1], + ); + + let intersection = self.line_intersector.compute_intersection(line_0, line_1); + + if intersection.is_none() { + return; + } + let intersection = intersection.unwrap(); + + if !self.edges_are_from_same_geometry { + edge0.mark_as_unisolated(); + } + if !self.is_trivial_intersection( + intersection, + edge0, + segment_index_0, + edge0, + segment_index_1, + ) { + if self.edges_are_from_same_geometry || !intersection.is_proper() { + // In the case of self-noding, `edge0` might alias `edge1`, so it's imperative that + // the mutable borrows are short lived and do not overlap. + edge0.add_intersections(intersection, line_0, segment_index_0); + + // XXX: This may be a bug, but it matches the existing behavior. + edge0.add_intersections(intersection, line_1, segment_index_1); + } + if let LineIntersection::SinglePoint { + is_proper: true, + intersection: intersection_coord, + } = intersection + { + self.proper_intersection_point = Some(intersection_coord); + + if !self.is_boundary_point(&intersection_coord, &self.boundary_nodes) { + self.has_proper_interior_intersection = true + } + } + } + } + pub fn add_intersections( &mut self, - edge0: &RefCell>, + edge0: &mut Edge, segment_index_0: usize, - edge1: &RefCell>, + edge1: &mut Edge, segment_index_1: usize, ) { // avoid a segment spuriously "intersecting" with itself - if edge0.as_ptr() == edge1.as_ptr() && segment_index_0 == segment_index_1 { + if std::ptr::eq(edge0, edge1) && segment_index_0 == segment_index_1 { return; } let line_0 = Line::new( - edge0.borrow().coords()[segment_index_0], - edge0.borrow().coords()[segment_index_0 + 1], + edge0.coords()[segment_index_0], + edge0.coords()[segment_index_0 + 1], ); let line_1 = Line::new( - edge1.borrow().coords()[segment_index_1], - edge1.borrow().coords()[segment_index_1 + 1], + edge1.coords()[segment_index_1], + edge1.coords()[segment_index_1 + 1], ); let intersection = self.line_intersector.compute_intersection(line_0, line_1); @@ -124,8 +183,8 @@ where let intersection = intersection.unwrap(); if !self.edges_are_from_same_geometry { - edge0.borrow_mut().mark_as_unisolated(); - edge1.borrow_mut().mark_as_unisolated(); + edge0.mark_as_unisolated(); + edge1.mark_as_unisolated(); } if !self.is_trivial_intersection( intersection, @@ -137,13 +196,9 @@ where if self.edges_are_from_same_geometry || !intersection.is_proper() { // In the case of self-noding, `edge0` might alias `edge1`, so it's imperative that // the mutable borrows are short lived and do not overlap. - edge0 - .borrow_mut() - .add_intersections(intersection, line_0, segment_index_0); + edge0.add_intersections(intersection, line_0, segment_index_0); - edge1 - .borrow_mut() - .add_intersections(intersection, line_1, segment_index_1); + edge1.add_intersections(intersection, line_1, segment_index_1); } if let LineIntersection::SinglePoint { is_proper: true, diff --git a/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs index a735934465..9acf745f6e 100644 --- a/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs @@ -3,7 +3,6 @@ use super::{EdgeSetIntersector, SegmentIntersector}; use crate::GeoFloat; use std::cell::RefCell; -use std::rc::Rc; pub(crate) struct SimpleEdgeSetIntersector; @@ -14,48 +13,68 @@ impl SimpleEdgeSetIntersector { fn compute_intersects( &self, - edge0: &Rc>>, - edge1: &Rc>>, + edge0: &mut Edge, + edge1: &mut Edge, segment_intersector: &mut SegmentIntersector, ) { - let edge0_coords_len = edge0.borrow().coords().len() - 1; - let edge1_coords_len = edge1.borrow().coords().len() - 1; + let edge0_coords_len = edge0.coords().len() - 1; + let edge1_coords_len = edge1.coords().len() - 1; for i0 in 0..edge0_coords_len { for i1 in 0..edge1_coords_len { segment_intersector.add_intersections(edge0, i0, edge1, i1); } } } + + fn compute_intersects_against_self( + &self, + edge0: &mut Edge, + segment_intersector: &mut SegmentIntersector, + ) { + let edge0_coords_len = edge0.coords().len() - 1; + for i0 in 0..edge0_coords_len { + for i1 in 0..edge0_coords_len { + segment_intersector.add_intersections_against_self(edge0, i0, i1); + } + } + } } impl EdgeSetIntersector for SimpleEdgeSetIntersector { fn compute_intersections_within_set( &self, - graph: &GeometryGraph, + graph: &mut GeometryGraph, check_for_self_intersecting_edges: bool, segment_intersector: &mut SegmentIntersector, ) { - let edges = graph.edges(); - for edge0 in edges.iter() { - for edge1 in edges.iter() { - if check_for_self_intersecting_edges || edge0.as_ptr() != edge1.as_ptr() { - self.compute_intersects(edge0, edge1, segment_intersector); - } + let edges = graph.edges_mut(); + for i in 0..edges.len() { + let (e0, e1) = edges.split_at_mut(i + 1); + let (e0, edge0) = e0.split_at_mut(i); + debug_assert_eq!(edge0.len(), 1); + let edge0 = &mut edge0[0]; + + if check_for_self_intersecting_edges { + self.compute_intersects_against_self(edge0, segment_intersector); + } + + for edge1 in e0.iter_mut().chain(e1) { + self.compute_intersects(edge0, edge1, segment_intersector); } } } fn compute_intersections_between_sets<'a>( &self, - graph_0: &GeometryGraph<'a, F>, - graph_1: &GeometryGraph<'a, F>, + graph_0: &mut GeometryGraph<'a, F>, + graph_1: &mut GeometryGraph<'a, F>, segment_intersector: &mut SegmentIntersector, ) { - let edges_0 = graph_0.edges(); - let edges_1 = graph_1.edges(); + let edges_0 = graph_0.edges_mut(); + let edges_1 = graph_1.edges_mut(); for edge0 in edges_0 { - for edge1 in edges_1 { + for edge1 in &mut *edges_1 { self.compute_intersects(edge0, edge1, segment_intersector); } } diff --git a/geo/src/algorithm/relate/geomgraph/planar_graph.rs b/geo/src/algorithm/relate/geomgraph/planar_graph.rs index 454e410f19..f9b04ce475 100644 --- a/geo/src/algorithm/relate/geomgraph/planar_graph.rs +++ b/geo/src/algorithm/relate/geomgraph/planar_graph.rs @@ -4,9 +4,6 @@ use super::{ }; use crate::{Coord, GeoFloat}; -use std::cell::RefCell; -use std::rc::Rc; - #[derive(Clone, PartialEq)] pub(crate) struct PlanarGraphNode; @@ -24,7 +21,7 @@ where #[derive(Clone, PartialEq)] pub(crate) struct PlanarGraph { pub(crate) nodes: NodeMap, - edges: Vec>>>, + edges: Vec>, } impl PlanarGraph { @@ -32,11 +29,7 @@ impl PlanarGraph { let mut graph = Self { nodes: self.nodes.clone(), // deep copy edges - edges: self - .edges - .iter() - .map(|e| Rc::new(RefCell::new(e.borrow().clone()))) - .collect(), + edges: self.edges.to_vec(), }; assert_eq!(from_arg_index, 0); if from_arg_index != to_arg_index { @@ -50,7 +43,7 @@ impl PlanarGraph { node.swap_label_args(); } for edge in &mut self.edges { - edge.borrow_mut().swap_label_args(); + edge.swap_label_args(); } } @@ -59,10 +52,14 @@ impl PlanarGraph { assert_eq!(self.edges, other.edges); } - pub fn edges(&self) -> &[Rc>>] { + pub fn edges(&self) -> &[Edge] { &self.edges } + pub fn edges_mut(&mut self) -> &mut [Edge] { + &mut self.edges + } + pub fn new() -> Self { PlanarGraph { nodes: NodeMap::new(), @@ -79,7 +76,7 @@ impl PlanarGraph { } pub fn insert_edge(&mut self, edge: Edge) { - self.edges.push(Rc::new(RefCell::new(edge))); + self.edges.push(edge); } pub fn add_node_with_coordinate(&mut self, coord: Coord) -> &mut CoordNode { diff --git a/geo/src/algorithm/relate/relate_operation.rs b/geo/src/algorithm/relate/relate_operation.rs index 061bb29199..285a7cd4cb 100644 --- a/geo/src/algorithm/relate/relate_operation.rs +++ b/geo/src/algorithm/relate/relate_operation.rs @@ -9,9 +9,6 @@ use crate::relate::geomgraph::{ use crate::CoordinatePosition; use crate::{Coord, GeoFloat, GeometryCow}; -use std::cell::RefCell; -use std::rc::Rc; - /// Computes an [`IntersectionMatrix`] describing the topological relationship between two /// Geometries. /// @@ -29,7 +26,7 @@ where graph_b: GeometryGraph<'a, F>, nodes: NodeMap, line_intersector: RobustLineIntersector, - isolated_edges: Vec>>>, + isolated_edges: Vec>, } #[derive(PartialEq)] @@ -58,7 +55,7 @@ where } } - pub(crate) fn compute_intersection_matrix(&mut self) -> IntersectionMatrix { + pub(crate) fn compute_intersection_matrix(&'a mut self) -> IntersectionMatrix { let mut intersection_matrix = IntersectionMatrix::empty_disjoint(); use crate::BoundingRect; @@ -85,27 +82,48 @@ where .compute_self_nodes(Box::new(self.line_intersector.clone())); // compute intersections between edges of the two input geometries - let segment_intersector = self - .graph_a - .compute_edge_intersections(&self.graph_b, Box::new(self.line_intersector.clone())); + // let segment_intersector = self + // .graph_a + // .compute_edge_intersections(&mut self.graph_b, Box::new(self.line_intersector.clone())); + + // this is a copy of the above functionality to satisfy rust borrowing rules. + // from here [... + let mut segment_intersector = + SegmentIntersector::new(Box::new(self.line_intersector.clone()), false); + segment_intersector.set_boundary_nodes( + self.graph_a.boundary_nodes().cloned().collect(), + self.graph_b.boundary_nodes().cloned().collect(), + ); + + use crate::relate::geomgraph::index::{EdgeSetIntersector, RStarEdgeSetIntersector}; + + let edge_set_intersector = RStarEdgeSetIntersector; + edge_set_intersector.compute_intersections_between_sets( + &mut self.graph_a, + &mut self.graph_b, + &mut segment_intersector, + ); + // to here ..] self.compute_intersection_nodes(0); self.compute_intersection_nodes(1); + // Copy the labelling for the nodes in the parent Geometries. These override any labels // determined by intersections between the geometries. self.copy_nodes_and_labels(0); self.copy_nodes_and_labels(1); // complete the labelling for any nodes which only have a label for a single geometry self.label_isolated_nodes(); + // If a proper intersection was found, we can set a lower bound on the IM. self.compute_proper_intersection_im(&segment_intersector, &mut intersection_matrix); // Now process improper intersections // (eg where one or other of the geometries has a vertex at the intersection point) // We need to compute the edge graph at all nodes to determine the IM. let edge_end_builder = EdgeEndBuilder::new(); - let edge_ends_a: Vec<_> = edge_end_builder.compute_ends_for_edges(self.graph_a.edges()); + let edge_ends_a: Vec<_> = edge_end_builder.compute_ends_for_edges(self.graph_a.edges_mut()); self.insert_edge_ends(edge_ends_a); - let edge_ends_b: Vec<_> = edge_end_builder.compute_ends_for_edges(self.graph_b.edges()); + let edge_ends_b: Vec<_> = edge_end_builder.compute_ends_for_edges(self.graph_b.edges_mut()); self.insert_edge_ends(edge_ends_b); let mut nodes = NodeMap::new(); @@ -268,8 +286,6 @@ where }; for edge in graph.edges() { - let edge = edge.borrow(); - let edge_position = edge.label().on_position(geom_index); for edge_intersection in edge.edge_intersections() { let (new_node, _edges) = self @@ -294,8 +310,7 @@ where "before updated_intersection_matrix(isolated_edges): {:?}", intersection_matrix ); - for isolated_edge in &self.isolated_edges { - let edge = isolated_edge.borrow(); + for edge in &self.isolated_edges { Edge::::update_intersection_matrix(edge.label(), intersection_matrix); debug!( "after isolated_edge update_intersection_matrix: {:?}, (isolated_edge: {:?}, label: {:?})", @@ -319,15 +334,14 @@ where /// not be isolated). fn label_isolated_edges(&mut self, this_index: usize, target_index: usize) { let (this_graph, target_graph) = if this_index == 0 { - (&self.graph_a, &self.graph_b) + (&mut self.graph_a, &self.graph_b) } else { - (&self.graph_b, &self.graph_a) + (&mut self.graph_b, &self.graph_a) }; - for edge in this_graph.edges() { - let mut mut_edge = edge.borrow_mut(); - if mut_edge.is_isolated() { - Self::label_isolated_edge(&mut mut_edge, target_index, target_graph.geometry()); + for edge in this_graph.edges_mut() { + if edge.is_isolated() { + Self::label_isolated_edge(edge, target_index, target_graph.geometry()); self.isolated_edges.push(edge.clone()); } }