Separate dot and bend arounds. Keep an edge to the core from each bend

This commit is contained in:
Mikolaj Wielgus 2023-07-20 20:42:21 +02:00
parent 16990517b2
commit 69317384dd
4 changed files with 69 additions and 69 deletions

View File

@ -97,12 +97,6 @@ impl Layout {
let bend_to = self.add_dot(self.mesh.dot_weight(head.dot)); let bend_to = self.add_dot(self.mesh.dot_weight(head.dot));
let net = self.mesh.dot_weight(head.dot).net; let net = self.mesh.dot_weight(head.dot).net;
let mut layer = around;
while let TaggedIndex::Bend(layer_bend) = layer {
layer = self.mesh.around(layer_bend)
}
let center = *layer.as_dot().unwrap();
let bend = self.mesh.add_bend(head.dot, bend_to, around, BendWeight {net, cw}); let bend = self.mesh.add_bend(head.dot, bend_to, around, BendWeight {net, cw});
Head {dot: bend_to, bend: Some(bend)} Head {dot: bend_to, bend: Some(bend)}
} }
@ -132,12 +126,10 @@ impl Layout {
match maybe_bend { match maybe_bend {
Some(bend) => { Some(bend) => {
let head_around = self.mesh.around(bend); if let Some(inner) = self.mesh.inner(bend) {
self.bend_guidecircle(inner, width, conditions)
match self.mesh.weight(head_around) { } else {
Weight::Dot(..) => self.dot_guidecircle(*head_around.as_dot().unwrap(), width + 5.0, conditions), self.dot_guidecircle(self.mesh.core(bend), width + 5.0, conditions)
Weight::Seg(..) => unreachable!(),
Weight::Bend(..) => self.bend_guidecircle(*head_around.as_bend().unwrap(), width, conditions),
} }
}, },
None => Circle { None => Circle {
@ -163,18 +155,18 @@ impl Layout {
} }
fn bend_guidecircle(&self, bend: BendIndex, width: f64, conditions: Conditions) -> Circle { fn bend_guidecircle(&self, bend: BendIndex, width: f64, conditions: Conditions) -> Circle {
let mut layer = TaggedIndex::Bend(bend);
let mut r = width + self.rules.ruleset(conditions).clearance.min; let mut r = width + self.rules.ruleset(conditions).clearance.min;
let mut layer = bend;
while let TaggedIndex::Bend(layer_bend) = layer { while let Some(inner) = self.mesh.inner(layer) {
layer = self.mesh.around(layer_bend); r += 5.0 + self.mesh.primitive(inner.tag()).width();
r += 5.0 + self.mesh.primitive(layer).width(); layer = inner;
} }
let circle = self.mesh.weight(layer).as_dot().unwrap().circle; let core_circle = self.mesh.dot_weight(self.mesh.core(bend)).circle;
Circle { Circle {
pos: circle.pos, pos: core_circle.pos,
r: circle.r - 5.0 + r, r: core_circle.r + r + 15.0
} }
} }
@ -234,10 +226,6 @@ impl Layout {
} }
pub fn primitive(&self, index: TaggedIndex) -> Primitive { pub fn primitive(&self, index: TaggedIndex) -> Primitive {
return self.mesh.primitive(index); self.mesh.primitive(index)
} }
/*pub fn bend(&self, index: DotIndex) -> Option<BendIndex> {
return self.mesh.bend(index);
}*/
} }

View File

@ -1,5 +1,6 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use enum_as_inner::EnumAsInner; use enum_as_inner::EnumAsInner;
use petgraph::Direction::{Outgoing, Incoming};
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex}; use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
use petgraph::visit::EdgeRef; use petgraph::visit::EdgeRef;
use rstar::{RTree, RTreeObject, AABB}; use rstar::{RTree, RTreeObject, AABB};
@ -103,25 +104,38 @@ impl Mesh {
} }
pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, around: TaggedIndex, weight: BendWeight) -> BendIndex { pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, around: TaggedIndex, weight: BendWeight) -> BendIndex {
match around {
TaggedIndex::Dot(core) =>
self.add_core_bend(from, to, core, weight),
TaggedIndex::Bend(around) =>
self.add_noncore_bend(from, to, around, weight),
TaggedIndex::Seg(..) => unreachable!(),
}
}
pub fn add_core_bend(&mut self, from: DotIndex, to: DotIndex, core: DotIndex, weight: BendWeight) -> BendIndex {
let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight)));
self.graph.add_edge(bend.index, from.index, Label::End); self.graph.add_edge(bend.index, from.index, Label::End);
self.graph.add_edge(bend.index, to.index, Label::End); self.graph.add_edge(bend.index, to.index, Label::End);
self.graph.add_edge(bend.index, core.index, Label::Core);
match around {
TaggedIndex::Dot(DotIndex {index: around_index, ..}) => {
self.graph.add_edge(bend.index, around_index, Label::Around);
},
TaggedIndex::Seg(..) => unreachable!(),
TaggedIndex::Bend(BendIndex {index: around_index, ..}) => {
self.graph.add_edge(bend.index, around_index, Label::Around);
},
}
let index = TaggedIndex::Bend(bend); let index = TaggedIndex::Bend(bend);
self.rtree.insert(RTreeWrapper::new(self.primitive(index), index)); self.rtree.insert(RTreeWrapper::new(self.primitive(index), index));
bend bend
} }
pub fn add_noncore_bend(&mut self, from: DotIndex, to: DotIndex, inner: BendIndex, weight: BendWeight) -> BendIndex {
let core = *self.graph.neighbors(inner.index)
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(inner.index, *ni).unwrap()).unwrap().is_core())
.map(|ni| DotIndex::new(ni))
.collect::<Vec<DotIndex>>()
.first()
.unwrap();
let bend = self.add_core_bend(from, to, core, weight);
self.graph.add_edge(inner.index, bend.index, Label::Outer);
bend
}
pub fn remove_bend(&mut self, bend: BendIndex) { pub fn remove_bend(&mut self, bend: BendIndex) {
self.rtree.remove(&RTreeWrapper::new(self.primitive(TaggedIndex::Bend(bend)), TaggedIndex::Bend(bend))); self.rtree.remove(&RTreeWrapper::new(self.primitive(TaggedIndex::Bend(bend)), TaggedIndex::Bend(bend)));
self.graph.remove_node(bend.index); self.graph.remove_node(bend.index);
@ -139,45 +153,43 @@ impl Mesh {
.into_iter() .into_iter()
.map(|index| self.dot_weight(index)) .map(|index| self.dot_weight(index))
.collect(), .collect(),
around_weight: match index { core_pos: match index {
TaggedIndex::Bend(bend) => Some(self.weight(self.around(bend))),
_ => None,
},
focus: match index {
TaggedIndex::Bend(bend) => { TaggedIndex::Bend(bend) => {
let mut layer = index; Some(self.dot_weight(self.core(bend)).circle.pos)
while let TaggedIndex::Bend(layer_bend) = layer {
layer = self.around(layer_bend)
}
Some(self.weight(layer).as_dot().unwrap().circle.pos)
}, },
_ => None, _ => None,
}, },
} }
} }
/*pub fn focus(&self, bend: BendIndex) -> DotIndex {
let mut layer = bend.tag();
while let TaggedIndex::Bend(bend) = layer {
layer = self.around(layer).unwrap();
}
*layer.as_dot().unwrap()
}*/
pub fn around(&self, bend: BendIndex) -> TaggedIndex { pub fn around(&self, bend: BendIndex) -> TaggedIndex {
for neighbor in self.graph.neighbors(bend.index) { if let Some(inner) = self.inner(bend) {
let edge = self.graph.find_edge(bend.index, neighbor).unwrap(); TaggedIndex::Bend(inner)
} else {
TaggedIndex::Dot(self.core(bend))
}
}
if self.graph.edge_weight(edge).unwrap().is_around() { pub fn core(&self, bend: BendIndex) -> DotIndex {
return match self.graph.node_weight(neighbor).unwrap() { self.graph.neighbors(bend.index)
Weight::Dot(dot) => DotIndex::new(neighbor).tag(), .filter(|ni| self.graph.edge_weight(self.graph.find_edge(bend.index, *ni).unwrap()).unwrap().is_core())
Weight::Bend(bend) => BendIndex::new(neighbor).tag(), .map(|ni| DotIndex::new(ni))
Weight::Seg(seg) => SegIndex::new(neighbor).tag(), .next()
.unwrap()
} }
pub fn inner(&self, bend: BendIndex) -> Option<BendIndex> {
self.graph.neighbors_directed(bend.index, Incoming)
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(*ni, bend.index).unwrap()).unwrap().is_outer())
.map(|ni| BendIndex::new(ni))
.next()
} }
}
unreachable!(); pub fn outer(&self, bend: BendIndex) -> Option<BendIndex> {
self.graph.neighbors_directed(bend.index, Outgoing)
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(bend.index, *ni).unwrap()).unwrap().is_outer())
.map(|ni| BendIndex::new(ni))
.next()
} }
pub fn ends(&self, index: TaggedIndex) -> Vec<DotIndex> { pub fn ends(&self, index: TaggedIndex) -> Vec<DotIndex> {

View File

@ -7,8 +7,7 @@ use crate::{weight::{Weight, DotWeight}, math::Circle};
pub struct Primitive { pub struct Primitive {
pub weight: Weight, pub weight: Weight,
pub dot_neighbor_weights: Vec<DotWeight>, pub dot_neighbor_weights: Vec<DotWeight>,
pub around_weight: Option<Weight>, pub core_pos: Option<Point>,
pub focus: Option<Point>,
} }
impl Primitive { impl Primitive {
@ -36,9 +35,9 @@ impl Primitive {
Weight::Dot(dot) => Some(dot.circle), Weight::Dot(dot) => Some(dot.circle),
Weight::Seg(seg) => None, Weight::Seg(seg) => None,
Weight::Bend(bend) => { Weight::Bend(bend) => {
let r = self.dot_neighbor_weights[0].circle.pos.euclidean_distance(&self.focus.unwrap()); let r = self.dot_neighbor_weights[0].circle.pos.euclidean_distance(&self.core_pos.unwrap());
Some(Circle { Some(Circle {
pos: self.focus.unwrap(), pos: self.core_pos.unwrap(),
r, r,
}) })
} }

View File

@ -29,5 +29,6 @@ pub enum Weight {
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum Label { pub enum Label {
End, End,
Around, Outer,
Core,
} }