mirror of https://codeberg.org/topola/topola.git
tracer: Implement rudimentary wrapping around loose bends
Temporarily disabled bend-seg intersection to make it rudimentarily work.
This commit is contained in:
parent
60c494a171
commit
36710b7a51
30
src/draw.rs
30
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)
|
||||
}
|
||||
|
|
|
|||
20
src/guide.rs
20
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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ pub trait GetFirstLayer: GetGraph + GetNodeIndex {
|
|||
fn first_layer(&self) -> Option<LooseBendIndex> {
|
||||
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<LooseBendIndex> {
|
||||
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<LooseBendIndex> {
|
||||
self.graph()
|
||||
.neighbors_directed(self.node_index(), Outgoing)
|
||||
|
|
@ -340,45 +354,8 @@ impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> 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<FixedBendIndex> {
|
||||
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<FixedDotIndex, FixedDotIndex> 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<LooseBendIndex> {
|
||||
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<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {
|
|||
|
||||
impl<'a> GetOtherEnd<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {}
|
||||
impl<'a> GetCore for LooseBend<'a> {}
|
||||
impl<'a> GetOuter for LooseBend<'a> {}
|
||||
impl<'a> GetInnerOuter for LooseBend<'a> {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<SegbendHead, ()> {
|
||||
/*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<SegbendHead, ()> {
|
||||
self.draw().segbend_around_dot(head, around.into(), width)
|
||||
let head = self.draw().segbend_around_dot(head, around.into(), width)?;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*fn is_under(
|
||||
&mut self,
|
||||
_head: Head,
|
||||
around: FixedDotIndex,
|
||||
_layer: FixedBendIndex,
|
||||
) -> Option<bool> {
|
||||
let _around_pos = self.layout.primitive(around).weight().circle.pos;
|
||||
|
||||
/*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<SegbendHead, ()> {
|
||||
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<SegbendHead, ()> {
|
||||
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<Bow> = vec![];
|
||||
|
||||
let mut cur_bend = bend;
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue