mirror of https://codeberg.org/topola/topola.git
Separate dot and bend arounds. Keep an edge to the core from each bend
This commit is contained in:
parent
16990517b2
commit
69317384dd
|
|
@ -97,12 +97,6 @@ impl Layout {
|
|||
let bend_to = self.add_dot(self.mesh.dot_weight(head.dot));
|
||||
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});
|
||||
Head {dot: bend_to, bend: Some(bend)}
|
||||
}
|
||||
|
|
@ -132,12 +126,10 @@ impl Layout {
|
|||
|
||||
match maybe_bend {
|
||||
Some(bend) => {
|
||||
let head_around = self.mesh.around(bend);
|
||||
|
||||
match self.mesh.weight(head_around) {
|
||||
Weight::Dot(..) => self.dot_guidecircle(*head_around.as_dot().unwrap(), width + 5.0, conditions),
|
||||
Weight::Seg(..) => unreachable!(),
|
||||
Weight::Bend(..) => self.bend_guidecircle(*head_around.as_bend().unwrap(), width, conditions),
|
||||
if let Some(inner) = self.mesh.inner(bend) {
|
||||
self.bend_guidecircle(inner, width, conditions)
|
||||
} else {
|
||||
self.dot_guidecircle(self.mesh.core(bend), width + 5.0, conditions)
|
||||
}
|
||||
},
|
||||
None => Circle {
|
||||
|
|
@ -163,18 +155,18 @@ impl Layout {
|
|||
}
|
||||
|
||||
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 layer = bend;
|
||||
|
||||
while let TaggedIndex::Bend(layer_bend) = layer {
|
||||
layer = self.mesh.around(layer_bend);
|
||||
r += 5.0 + self.mesh.primitive(layer).width();
|
||||
while let Some(inner) = self.mesh.inner(layer) {
|
||||
r += 5.0 + self.mesh.primitive(inner.tag()).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 {
|
||||
pos: circle.pos,
|
||||
r: circle.r - 5.0 + r,
|
||||
pos: core_circle.pos,
|
||||
r: core_circle.r + r + 15.0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,10 +226,6 @@ impl Layout {
|
|||
}
|
||||
|
||||
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);
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
88
src/mesh.rs
88
src/mesh.rs
|
|
@ -1,5 +1,6 @@
|
|||
use std::marker::PhantomData;
|
||||
use enum_as_inner::EnumAsInner;
|
||||
use petgraph::Direction::{Outgoing, Incoming};
|
||||
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
|
||||
use petgraph::visit::EdgeRef;
|
||||
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 {
|
||||
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)));
|
||||
self.graph.add_edge(bend.index, from.index, Label::End);
|
||||
self.graph.add_edge(bend.index, to.index, Label::End);
|
||||
|
||||
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);
|
||||
},
|
||||
}
|
||||
self.graph.add_edge(bend.index, core.index, Label::Core);
|
||||
|
||||
let index = TaggedIndex::Bend(bend);
|
||||
self.rtree.insert(RTreeWrapper::new(self.primitive(index), index));
|
||||
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) {
|
||||
self.rtree.remove(&RTreeWrapper::new(self.primitive(TaggedIndex::Bend(bend)), TaggedIndex::Bend(bend)));
|
||||
self.graph.remove_node(bend.index);
|
||||
|
|
@ -139,45 +153,43 @@ impl Mesh {
|
|||
.into_iter()
|
||||
.map(|index| self.dot_weight(index))
|
||||
.collect(),
|
||||
around_weight: match index {
|
||||
TaggedIndex::Bend(bend) => Some(self.weight(self.around(bend))),
|
||||
_ => None,
|
||||
},
|
||||
focus: match index {
|
||||
core_pos: match index {
|
||||
TaggedIndex::Bend(bend) => {
|
||||
let mut layer = index;
|
||||
while let TaggedIndex::Bend(layer_bend) = layer {
|
||||
layer = self.around(layer_bend)
|
||||
}
|
||||
Some(self.weight(layer).as_dot().unwrap().circle.pos)
|
||||
Some(self.dot_weight(self.core(bend)).circle.pos)
|
||||
},
|
||||
_ => 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 {
|
||||
for neighbor in self.graph.neighbors(bend.index) {
|
||||
let edge = self.graph.find_edge(bend.index, neighbor).unwrap();
|
||||
if let Some(inner) = self.inner(bend) {
|
||||
TaggedIndex::Bend(inner)
|
||||
} else {
|
||||
TaggedIndex::Dot(self.core(bend))
|
||||
}
|
||||
}
|
||||
|
||||
if self.graph.edge_weight(edge).unwrap().is_around() {
|
||||
return match self.graph.node_weight(neighbor).unwrap() {
|
||||
Weight::Dot(dot) => DotIndex::new(neighbor).tag(),
|
||||
Weight::Bend(bend) => BendIndex::new(neighbor).tag(),
|
||||
Weight::Seg(seg) => SegIndex::new(neighbor).tag(),
|
||||
pub fn core(&self, bend: BendIndex) -> DotIndex {
|
||||
self.graph.neighbors(bend.index)
|
||||
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(bend.index, *ni).unwrap()).unwrap().is_core())
|
||||
.map(|ni| DotIndex::new(ni))
|
||||
.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> {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ use crate::{weight::{Weight, DotWeight}, math::Circle};
|
|||
pub struct Primitive {
|
||||
pub weight: Weight,
|
||||
pub dot_neighbor_weights: Vec<DotWeight>,
|
||||
pub around_weight: Option<Weight>,
|
||||
pub focus: Option<Point>,
|
||||
pub core_pos: Option<Point>,
|
||||
}
|
||||
|
||||
impl Primitive {
|
||||
|
|
@ -36,9 +35,9 @@ impl Primitive {
|
|||
Weight::Dot(dot) => Some(dot.circle),
|
||||
Weight::Seg(seg) => None,
|
||||
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 {
|
||||
pos: self.focus.unwrap(),
|
||||
pos: self.core_pos.unwrap(),
|
||||
r,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,5 +29,6 @@ pub enum Weight {
|
|||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum Label {
|
||||
End,
|
||||
Around,
|
||||
Outer,
|
||||
Core,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue