From 36710b7a519fe5114a989a1375677400bc778382 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Wed, 15 Nov 2023 02:52:37 +0000 Subject: [PATCH] tracer: Implement rudimentary wrapping around loose bends Temporarily disabled bend-seg intersection to make it rudimentarily work. --- src/draw.rs | 30 ++++++++++++++- src/guide.rs | 20 +++++----- src/layout.rs | 11 +++++- src/main.rs | 4 +- src/primitive.rs | 72 +++++++++-------------------------- src/shape.rs | 4 +- src/tracer.rs | 99 ++++++++++++++---------------------------------- src/traverser.rs | 2 +- 8 files changed, 99 insertions(+), 143 deletions(-) diff --git a/src/draw.rs b/src/draw.rs index bd33352..3a4ec0e 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -4,13 +4,13 @@ use geo::{EuclideanLength, Point}; use crate::{ graph::{ - BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex, + BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetEnds, GetNet, Index, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive, }, guide::Guide, layout::Layout, math::Circle, - primitive::GetOtherEnd, + primitive::{GetOtherEnd, GetWeight}, rules::{Conditions, Rules}, segbend::Segbend, }; @@ -258,6 +258,22 @@ impl<'a> Draw<'a> { Some(self.head(prev_dot)) } + #[debug_ensures(self.layout.node_count() == old(self.layout.node_count()))] + pub fn update_bow(&mut self, bend: LooseBendIndex) { + /*let cw = self.layout.primitive(bend).weight().cw; + let ends = self.layout.primitive(bend).ends(); + let from_head = self.rear_head(ends.0); + let to_head = self.rear_head(ends.1); + + let from = self + .guide(&Default::default()) + .head_around_bend_segment(&from_head, inner, cw, 3.0); + let to = self + .guide(&Default::default()) + .head_around_bend_segment(&from_head, inner, cw, 3.0); + self.layout.reposition_bend(bend, from, to);*/ + } + fn head(&self, dot: DotIndex) -> Head { match dot { DotIndex::Fixed(loose) => BareHead { dot: loose }.into(), @@ -272,6 +288,16 @@ impl<'a> Draw<'a> { } } + fn rear_head(&self, dot: LooseDotIndex) -> Head { + self.head(self.rear(self.segbend_head(dot))) + } + + fn rear(&self, head: SegbendHead) -> DotIndex { + self.layout + .primitive(head.segbend.seg) + .other_end(head.segbend.dot.into()) + } + fn guide(&'a self, conditions: &'a Conditions) -> Guide { Guide::new(self.layout, self.rules, conditions) } diff --git a/src/guide.rs b/src/guide.rs index e98685e..1c4a021 100644 --- a/src/guide.rs +++ b/src/guide.rs @@ -5,7 +5,7 @@ use crate::{ graph::{BendIndex, DotIndex, FixedDotIndex, MakePrimitive}, layout::Layout, math::{self, Circle}, - primitive::{GetCore, GetWeight, MakeShape}, + primitive::{GetCore, GetInnerOuter, GetWeight, MakeShape}, rules::{Conditions, Rules}, shape::ShapeTrait, }; @@ -133,15 +133,15 @@ impl<'a, 'b> Guide<'a, 'b> { } } - fn bend_circle(&self, bend: BendIndex, _width: f64) -> Circle { - let mut circle = bend - .primitive(&self.layout.graph) - .shape() - .into_bend() - .unwrap() - .circle(); - circle.r += self.rules.ruleset(&self.conditions).clearance.min; - circle + fn bend_circle(&self, bend: BendIndex, width: f64) -> Circle { + let shape = bend.primitive(&self.layout.graph).shape(); + Circle { + pos: shape.center(), + r: shape.width() / 2.0 + + width + + 6.0 + + self.rules.ruleset(self.conditions).clearance.min, + } } fn dot_circle(&self, dot: DotIndex, width: f64) -> Circle { diff --git a/src/layout.rs b/src/layout.rs index e60c2e3..ce102a3 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -107,7 +107,7 @@ impl Layout { } #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 5))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_segbend( @@ -209,7 +209,9 @@ impl Layout { }*/ #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3) || self.graph.edge_count() == old(self.graph.edge_count() + 4))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] fn add_loose_bend( &mut self, from: LooseDotIndex, @@ -220,6 +222,7 @@ impl Layout { match around { Index::FixedDot(core) => self.add_core_bend(from, to, core, weight), Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), + Index::LooseBend(around) => self.add_outer_bend(from, to, around, weight), _ => unreachable!(), } } @@ -293,10 +296,14 @@ impl Layout { Ok(bend) } + pub fn reposition_bend(&mut self, bend: LooseBendIndex, from: Point, to: Point) { + // TODO. + } + #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()) || self.graph.edge_count() == old(self.graph.edge_count() + 1))] - pub fn reattach_bend(&mut self, bend: FixedBendIndex, inner: FixedBendIndex) { + pub fn reattach_bend(&mut self, bend: LooseBendIndex, inner: LooseBendIndex) { self.remove_from_rtree(bend.into()); if let Some(old_inner_edge) = self diff --git a/src/main.rs b/src/main.rs index 5a0eb95..5fcdd1f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,7 +148,7 @@ fn main() { let dot2 = router .layout .add_fixed_dot(FixedDotWeight { - net: 1, + net: 5, circle: Circle { pos: (100.5, 500.5).into(), r: 8.0, @@ -170,7 +170,7 @@ fn main() { let dot_end2 = router .layout .add_fixed_dot(FixedDotWeight { - net: 1, + net: 5, circle: Circle { pos: (500.5, 150.5).into(), r: 8.0, diff --git a/src/primitive.rs b/src/primitive.rs index af432ed..4eda070 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -60,6 +60,7 @@ pub trait GetFirstLayer: GetGraph + GetNodeIndex { fn first_layer(&self) -> Option { self.graph() .neighbors_directed(self.node_index(), Incoming) + .filter(|ni| self.graph().find_edge(self.node_index(), *ni).is_some()) .filter(|ni| { self.graph() .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) @@ -87,7 +88,20 @@ pub trait GetCore: GetGraph + GetNodeIndex { } } -pub trait GetOuter: GetGraph + GetNodeIndex { +pub trait GetInnerOuter: GetGraph + GetNodeIndex { + fn inner(&self) -> Option { + self.graph() + .neighbors_directed(self.node_index(), Incoming) + .filter(|ni| { + self.graph() + .edge_weight(self.graph().find_edge(*ni, self.node_index()).unwrap()) + .unwrap() + .is_outer() + }) + .map(|ni| LooseBendIndex::new(ni)) + .next() + } + fn outer(&self) -> Option { self.graph() .neighbors_directed(self.node_index(), Outgoing) @@ -340,45 +354,8 @@ impl<'a> GetOtherEnd for LooseSeg<'a> {} pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; impl<'a> FixedBend<'a> { - pub fn around(&self) -> Index { - if let Some(inner) = self.inner() { - inner.into() - } else { - self.core().into() - } - } - - pub fn inner(&self) -> Option { - self.graph - .neighbors_directed(self.index.node_index(), Incoming) - .filter(|ni| { - self.graph - .edge_weight(self.graph.find_edge(*ni, self.index.node_index()).unwrap()) - .unwrap() - .is_outer() - }) - .map(|ni| FixedBendIndex::new(ni)) - .next() - } - fn inner_radius(&self) -> f64 { - let mut r = 0.0; - let mut layer = FixedBendIndex::new(self.index.node_index()); - - while let Some(inner) = self.primitive(layer).inner() { - r += self.primitive(inner).width(); - layer = inner; - } - - let core_circle = self - .primitive( - self.primitive(FixedBendIndex::new(self.index.node_index())) - .core(), - ) - .weight() - .circle; - - core_circle.r + r + 3.0 + todo!(); } pub fn cross_product(&self) -> f64 { @@ -428,24 +405,11 @@ impl<'a> GetOtherEnd for FixedBend<'a> {} impl<'a> TraverseOutward for FixedBend<'a> {} impl<'a> GetFirstLayer for FixedBend<'a> {} impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actually. -impl<'a> GetOuter for FixedBend<'a> {} + //impl<'a> GetInnerOuter for FixedBend<'a> {} pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; impl<'a> LooseBend<'a> { - pub fn inner(&self) -> Option { - self.graph - .neighbors_directed(self.index.node_index(), Incoming) - .filter(|ni| { - self.graph - .edge_weight(self.graph.find_edge(*ni, self.index.node_index()).unwrap()) - .unwrap() - .is_outer() - }) - .map(|ni| LooseBendIndex::new(ni)) - .next() - } - fn inner_radius(&self) -> f64 { let mut r = 0.0; let mut layer = LooseBendIndex::new(self.index.node_index()); @@ -509,4 +473,4 @@ impl<'a> GetEnds for LooseBend<'a> { impl<'a> GetOtherEnd for LooseBend<'a> {} impl<'a> GetCore for LooseBend<'a> {} -impl<'a> GetOuter for LooseBend<'a> {} +impl<'a> GetInnerOuter for LooseBend<'a> {} diff --git a/src/shape.rs b/src/shape.rs index 90a9d30..9dae8a0 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -117,7 +117,7 @@ impl ShapeTrait for SegShape { Shape::Dot(..) => unreachable!(), Shape::Seg(other) => self.polygon().intersects(&other.polygon()), Shape::Bend(other) => { - for segment in self.polygon().exterior().lines() { + /*for segment in self.polygon().exterior().lines() { let inner_circle = other.inner_circle(); let outer_circle = other.outer_circle(); @@ -132,7 +132,7 @@ impl ShapeTrait for SegShape { return true; } } - } + }*/ false } diff --git a/src/tracer.rs b/src/tracer.rs index a94d7a0..7dcc11c 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -2,9 +2,10 @@ use contracts::debug_ensures; use crate::{ draw::{BareHead, Draw, Head, SegbendHead}, - graph::FixedDotIndex, + graph::{FixedDotIndex, LooseBendIndex}, layout::Layout, mesh::{Mesh, VertexIndex}, + primitive::{GetFirstLayer, GetInnerOuter}, rules::Rules, }; @@ -88,35 +89,12 @@ impl<'a> Tracer<'a> { } fn wrap(&mut self, head: Head, around: VertexIndex, width: f64) -> Result { - /*let _around_pos = self.layout.primitive(around).weight().circle.pos; - let _around_primitive = self.layout.primitive(around); - - 'blk: { - if let Some(mut layer) = self.layout.primitive(around).outer() { - match self.is_under(head, around, layer) { - Some(true) => return self.tuck_around_dot(head, around, width), - Some(false) => (), - None => break 'blk, - } - - while let Some(outer) = self.layout.primitive(layer).outer() { - match self.is_under(head, around, outer) { - Some(true) => return self.tuck_around_bend(head, layer, width), - Some(false) => (), - None => break 'blk, - } - - layer = outer; - } - - return self.draw().segbend_around_bend(head, layer.into(), width); - } - }*/ - match around { VertexIndex::FixedDot(dot) => self.wrap_around_fixed_dot(head, dot, width), VertexIndex::FixedBend(_fixed_bend) => todo!(), - VertexIndex::LooseBend(_loose_bend) => todo!(), + VertexIndex::LooseBend(loose_bend) => { + self.wrap_around_loose_bend(head, loose_bend, width) + } } } @@ -126,64 +104,45 @@ impl<'a> Tracer<'a> { around: FixedDotIndex, width: f64, ) -> Result { - self.draw().segbend_around_dot(head, around.into(), width) - } + let head = self.draw().segbend_around_dot(head, around.into(), width)?; - /*fn is_under( - &mut self, - _head: Head, - around: FixedDotIndex, - _layer: FixedBendIndex, - ) -> Option { - let _around_pos = self.layout.primitive(around).weight().circle.pos; + if let Some(first_layer) = self.layout.primitive(around).first_layer() { + self.layout.reattach_bend(first_layer, head.segbend.bend); + self.update_outward(head.segbend.bend); + } - /*if Some(layer) != self.layout.primitive(head.dot()).prev_bend() { - Some( - self.layout - .primitive(layer) - .shape() - .into_bend() - .unwrap() - .between_ends(around_pos), - ) - } else {*/ - None - //} - }*/ - - /*fn tuck_around_dot( - &mut self, - head: Head, - around: FixedDotIndex, - width: f64, - ) -> Result { - let outer = self.layout.primitive(around).outer().unwrap(); - let head = self - .draw() - .segbend_around_dot(Head::from(head), around.into(), width)?; - self.layout.reattach_bend(outer, head.segbend.bend); - - self.redraw_outward(outer)?; Ok(head) } - fn tuck_around_bend( + fn wrap_around_loose_bend( &mut self, head: Head, - around: FixedBendIndex, + around: LooseBendIndex, width: f64, ) -> Result { - let outer = self.layout.primitive(around).outer().unwrap(); + let maybe_outer = self.layout.primitive(around).outer(); let head = self .draw() - .segbend_around_bend(Head::from(head), around.into(), width)?; - self.layout.reattach_bend(outer, head.segbend.bend); + .segbend_around_bend(head, around.into(), width)?; + + if let Some(outer) = maybe_outer { + self.layout.reattach_bend(outer, head.segbend.bend); + self.update_outward(head.segbend.bend); + } - self.redraw_outward(outer)?; Ok(head) } - fn redraw_outward(&mut self, bend: FixedBendIndex) -> Result<(), ()> { + fn update_outward(&mut self, bend: LooseBendIndex) { + let mut layer = bend; + + while let Some(outer) = self.layout.primitive(layer).outer() { + self.draw().update_bow(bend); + layer = outer; + } + } + + /*fn redraw_outward(&mut self, bend: FixedBendIndex) -> Result<(), ()> { let mut bows: Vec = vec![]; let mut cur_bend = bend; diff --git a/src/traverser.rs b/src/traverser.rs index ea91d52..7939273 100644 --- a/src/traverser.rs +++ b/src/traverser.rs @@ -2,7 +2,7 @@ use petgraph::stable_graph::StableDiGraph; use crate::{ graph::{Label, LooseBendIndex, Weight}, - primitive::{GenericPrimitive, GetOuter}, + primitive::{GenericPrimitive, GetInnerOuter}, }; pub struct OutwardLayerTraverser<'a> {