diff --git a/src/graph.rs b/src/graph.rs index f38b5e3..9f0b4a3 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -63,7 +63,7 @@ impl Index { } } - pub fn retag(&self, weight: TaggedWeight) -> TaggedIndex { + pub fn retag(&self, weight: &TaggedWeight) -> TaggedIndex { match weight { TaggedWeight::Dot(..) => TaggedIndex::Dot(DotIndex { index: self.index, diff --git a/src/main.rs b/src/main.rs index e05a6d2..b0d448f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -177,11 +177,41 @@ fn main() { }) .unwrap(); + let dot5 = layout + .add_dot(DotWeight { + net: 0, + circle: Circle { + pos: (150.5, 100.5).into(), + r: 8.0, + }, + }) + .unwrap(); + + let dot6 = layout + .add_dot(DotWeight { + net: 0, + circle: Circle { + pos: (190.5, 100.5).into(), + r: 8.0, + }, + }) + .unwrap(); + + let dot7 = layout + .add_dot(DotWeight { + net: 0, + circle: Circle { + pos: (230.5, 70.5).into(), + r: 8.0, + }, + }) + .unwrap(); + let barrier1_dot1 = layout .add_dot(DotWeight { net: 0, circle: Circle { - pos: (250.5, 150.5).into(), + pos: (250.5, 250.5).into(), r: 8.0, }, }) @@ -217,16 +247,20 @@ fn main() { .unwrap(); let _ = layout.add_seg(barrier2_dot1, barrier2_dot2, 16.0); + let head = layout.route_start(dot5); + let head = layout.route_around_dot(head, dot6, true, 5.0).unwrap(); + let _ = layout.route_finish(head, dot7, 5.0); + /*render_times(&mut event_pump, &mut canvas, &mut layout, None, -1); let head = layout.route_start(dot1_1); let head = layout - .route_around_dot(head, barrier1_dot1, true, 5.) + .route_around_dot(head, barrier1_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); let head = layout - .route_around_dot(head, barrier2_dot1, true, 5.) + .route_around_dot(head, barrier2_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); @@ -236,12 +270,12 @@ fn main() { let head = layout.route_start(dot2_1); let head = layout - .shove_around_dot(head, barrier1_dot1, true, 5.) + .shove_around_dot(head, barrier1_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); let head = layout - .shove_around_dot(head, barrier2_dot1, true, 5.) + .shove_around_dot(head, barrier2_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); @@ -253,16 +287,16 @@ fn main() { render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); let head = layout - .shove_around_dot(head, barrier1_dot1, true, 5.) + .shove_around_dot(head, barrier1_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); let head = layout - .shove_around_dot(head, barrier2_dot1, true, 5.) + .shove_around_dot(head, barrier2_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); - let _ = layout.route_finish(head, dot3_2, 5.); + let _ = layout.route_finish(head, dot3_2, 5.0); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); @@ -270,16 +304,16 @@ fn main() { render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); let head = layout - .shove_around_dot(head, barrier1_dot1, true, 5.) + .shove_around_dot(head, barrier1_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); let head = layout - .shove_around_dot(head, barrier2_dot1, true, 5.) + .shove_around_dot(head, barrier2_dot1, true, 5.0) .unwrap(); render_times(&mut event_pump, &mut canvas, &mut layout, None, 50); - let _ = layout.route_finish(head, dot4_2, 5.);*/ + let _ = layout.route_finish(head, dot4_2, 5.0);*/ render_times(&mut event_pump, &mut canvas, &mut layout, None, -1); render_times( diff --git a/src/mesh.rs b/src/mesh.rs index e5d26aa..99ab0e1 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -45,14 +45,14 @@ impl Mesh { // Unnecessary retag. It should be possible to elide it. let weight = *self.graph.node_weight(index.index).unwrap(); - let wrapper = RTreeWrapper::new(self.primitive(index).shape(), index.retag(weight)); + let wrapper = RTreeWrapper::new(self.primitive(index).shape(), index.retag(&weight)); assert!(self.rtree.remove(&wrapper).is_some()); self.graph.remove_node(index.index); } pub fn add_dot(&mut self, weight: DotWeight) -> Result { let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight))); - self.fail_and_remove_if_collides(dot)?; + //self.fail_and_remove_if_collides_except(dot, &[])?; self.rtree.insert(RTreeWrapper::new( self.primitive(dot).shape(), @@ -68,11 +68,11 @@ impl Mesh { weight: SegWeight, ) -> Result { let seg = SegIndex::new(self.graph.add_node(TaggedWeight::Seg(weight))); - self.fail_and_remove_if_collides(seg)?; self.graph.add_edge(from.index, seg.index, Label::End); self.graph.add_edge(seg.index, to.index, Label::End); + //self.fail_and_remove_if_collides_except(seg, &[from.tag(), to.tag()])?; self.insert_into_rtree(seg.tag()); Ok(seg) } @@ -99,7 +99,7 @@ impl Mesh { weight: BendWeight, ) -> Result { let bend = BendIndex::new(self.graph.add_node(TaggedWeight::Bend(weight))); - self.fail_and_remove_if_collides(bend)?; + //self.fail_and_remove_if_collides_except(bend, &[from.tag(), to.tag(), core.tag()])?; self.graph.add_edge(from.index, bend.index, Label::End); self.graph.add_edge(bend.index, to.index, Label::End); @@ -173,7 +173,7 @@ impl Mesh { dot_weight.circle.pos = to; *self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(dot_weight); - if let Some(..) = self.detect_collision(&self.primitive(dot).shape()) { + if let Some(..) = self.detect_collision_except(dot, &[]) { // Restore original state. *self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(old_weight); self.insert_into_rtree(dot.tag()); @@ -209,20 +209,34 @@ impl Mesh { Bow::new(bend, &self.graph) } - fn fail_and_remove_if_collides( + fn fail_and_remove_if_collides_except( &mut self, index: Index, + except: &[TaggedIndex], ) -> Result<(), ()> { - /*if self.detect_collision(&self.primitive(index).shape()) { + if let Some(..) = self.detect_collision_except(index, except) { self.remove(index); return Err(()); - }*/ + } Ok(()) } - fn detect_collision(&self, shape: &Shape) -> Option { + fn detect_collision_except( + &self, + index: Index, + except: &[TaggedIndex], + ) -> Option { + let primitive = self.primitive(index); + let shape = primitive.shape(); + self.rtree .locate_in_envelope_intersecting(&shape.envelope()) + .filter(|wrapper| { + !primitive + .neighbors() + .any(|neighbor| neighbor == wrapper.data) + }) + .filter(|wrapper| !except.contains(&wrapper.data)) .filter(|wrapper| shape.intersects(wrapper.geom())) .map(|wrapper| wrapper.data) .next() diff --git a/src/primitive.rs b/src/primitive.rs index 9d3de27..c8eae18 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -49,6 +49,12 @@ impl<'a, Weight> Primitive<'a, Weight> { } } + pub fn neighbors(&self) -> impl Iterator + '_ { + self.graph + .neighbors_undirected(self.index.index) + .map(|index| Index::