diff --git a/src/layout.rs b/src/layout.rs index a024b5d..e170911 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use geo::geometry::Point; use crate::math::Circle; -use crate::mesh::{Mesh, TaggedIndex, RTreeWrapper, DotIndex, SegIndex, BendIndex}; +use crate::mesh::{Mesh, TaggedIndex, RTreeWrapper, DotIndex, SegIndex, BendIndex, Tag}; use crate::rules::{Rules, Conditions}; use crate::primitive::Primitive; use crate::weight::{Weight, DotWeight, SegWeight, BendWeight}; @@ -98,12 +98,12 @@ impl Layout { let net = self.mesh.dot_weight(head.dot).net; let mut layer = around; - while let TaggedIndex::Bend(..) = layer { - layer = self.mesh.weight(layer).as_bend().unwrap().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, BendWeight {net, around, center, cw}); + let bend = self.mesh.add_bend(head.dot, bend_to, around, BendWeight {net, cw}); Head {dot: bend_to, bend: Some(bend)} } @@ -132,7 +132,7 @@ impl Layout { match maybe_bend { Some(bend) => { - let head_around = self.mesh.bend_weight(bend).around; + 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), @@ -166,8 +166,8 @@ impl Layout { let mut layer = TaggedIndex::Bend(bend); let mut r = width + self.rules.ruleset(conditions).clearance.min; - while let TaggedIndex::Bend(..) = layer { - layer = self.mesh.weight(layer).as_bend().unwrap().around; + while let TaggedIndex::Bend(layer_bend) = layer { + layer = self.mesh.around(layer_bend); r += 5.0 + self.mesh.primitive(layer).width(); } @@ -194,8 +194,9 @@ impl Layout { let bend = head.bend.unwrap(); let dot_weight = self.mesh.dot_weight(head.dot); let bend_weight = self.mesh.bend_weight(bend); + let around = self.mesh.around(bend); - let fixed_dot: TaggedIndex = self.mesh.neighboring_dots(TaggedIndex::Bend(bend)) + let fixed_dot: TaggedIndex = self.mesh.ends(TaggedIndex::Bend(bend)) .into_iter() .filter(|neighbor| *neighbor != TaggedIndex::Dot(head.dot)) .collect::>()[0]; @@ -210,7 +211,8 @@ impl Layout { r: dot_weight.circle.r, }, }); - self.mesh.add_bend(*fixed_dot.as_dot().unwrap(), new_dot, bend_weight); + + self.mesh.add_bend(*fixed_dot.as_dot().unwrap(), new_dot, around, bend_weight); head } diff --git a/src/mesh.rs b/src/mesh.rs index 673a229..0d22a23 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -116,14 +116,27 @@ impl Mesh { self.graph.remove_edge(seg.index); } - pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, weight: BendWeight) -> BendIndex { - let bend_index = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); - self.graph.add_edge(from.index, bend_index.index, Weight::EndRef(EndRefWeight {})); - self.graph.add_edge(bend_index.index, to.index, Weight::EndRef(EndRefWeight {})); + pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, around: TaggedIndex, weight: BendWeight) -> BendIndex { + let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); + self.graph.add_edge(from.index, bend.index, Weight::EndRef(EndRefWeight {})); + self.graph.add_edge(bend.index, to.index, Weight::EndRef(EndRefWeight {})); - let index = TaggedIndex::Bend(bend_index); + match around { + TaggedIndex::Dot(DotIndex {index: around_index, ..}) => { + self.graph.add_edge(bend.index, around_index, Weight::AroundRef(AroundRefWeight {})); + }, + TaggedIndex::Bend(BendIndex {index: around_index, ..}) => { + self.graph.add_edge(bend.index, around_index, Weight::AroundRef(AroundRefWeight {})); + }, + TaggedIndex::Seg(..) + | TaggedIndex::EndRef(..) + | TaggedIndex::AroundRef(..) => + unreachable!(), + } + + let index = TaggedIndex::Bend(bend); self.rtree.insert(RTreeWrapper::new(self.primitive(index), index)); - bend_index + bend } pub fn remove_bend(&mut self, bend: BendIndex) { @@ -139,43 +152,71 @@ impl Mesh { Primitive { weight: self.weight(index), dot_neighbor_weights: - self.neighboring_dots(index) + self.ends(index) .into_iter() .map(|index| *self.weight(index).as_dot().unwrap()) .collect(), around_weight: match index { - TaggedIndex::Bend(bend_index) => { - Some(self.weight((*self.weight(index).as_bend().unwrap()).around)) - }, + TaggedIndex::Bend(bend) => Some(self.weight(self.around(bend))), _ => None, }, focus: match index { - TaggedIndex::Bend(bend_index) => { + TaggedIndex::Bend(bend) => { let mut layer = index; - while let TaggedIndex::Bend(..) = layer { - layer = self.weight(layer).as_bend().unwrap().around; + while let TaggedIndex::Bend(layer_bend) = layer { + layer = self.around(layer_bend) } Some(self.weight(layer).as_dot().unwrap().circle.pos) }, _ => None, - } + }, } } - pub fn neighboring_dots(&self, index: TaggedIndex) -> Vec { + /*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 self.graph.edge_weight(edge).unwrap().is_around_ref() { + return match self.graph.node_weight(neighbor).unwrap() { + Weight::Dot(dot) => DotIndex::new(neighbor).tag(), + Weight::Bend(bend) => BendIndex::new(neighbor).tag(), + Weight::Seg(..) + | Weight::EndRef(..) + | Weight::AroundRef(..) => + unreachable!(), + } + } + } + unreachable!(); + } + + pub fn ends(&self, index: TaggedIndex) -> Vec { match index { - TaggedIndex::Dot(DotIndex {index: node_index, ..}) - | TaggedIndex::Bend(BendIndex {index: node_index, ..}) => - return self.graph.neighbors(node_index) - .filter(|ni| self.graph.node_weight(*ni).unwrap().as_dot().is_some()) + TaggedIndex::Dot(DotIndex {index: node, ..}) + | TaggedIndex::Bend(BendIndex {index: node, ..}) => + self.graph.neighbors(node) + .filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot()) + .filter(|ni| self.graph.edge_weight(self.graph.find_edge(node, *ni).unwrap()).unwrap().is_end_ref()) .map(|ni| TaggedIndex::Dot(Index::new(ni))) .collect(), - TaggedIndex::Seg(SegIndex {index: edge_index, ..}) => { - let endpoints = self.graph.edge_endpoints(edge_index).unwrap(); - return vec![TaggedIndex::Dot(DotIndex::new(endpoints.0)), - TaggedIndex::Dot(DotIndex::new(endpoints.1))] + TaggedIndex::Seg(SegIndex {index: edge, ..}) => { + let endpoints = self.graph.edge_endpoints(edge).unwrap(); + vec![TaggedIndex::Dot(DotIndex::new(endpoints.0)), + TaggedIndex::Dot(DotIndex::new(endpoints.1))] }, - TaggedIndex::EndRef(..) | TaggedIndex::AroundRef(..) => unreachable!(), + TaggedIndex::EndRef(..) + | TaggedIndex::AroundRef(..) => + unreachable!(), } } @@ -193,12 +234,14 @@ impl Mesh { pub fn weight(&self, index: TaggedIndex) -> Weight { match index { - TaggedIndex::Dot(DotIndex {index: node_index, ..}) - | TaggedIndex::Bend(BendIndex {index: node_index, ..}) => - *self.graph.node_weight(node_index).unwrap(), - TaggedIndex::Seg(SegIndex {index: edge_index, ..}) => - *self.graph.edge_weight(edge_index).unwrap(), - TaggedIndex::EndRef(..) | TaggedIndex::AroundRef(..) => unreachable!(), + TaggedIndex::Dot(DotIndex {index: node, ..}) + | TaggedIndex::Bend(BendIndex {index: node, ..}) => + *self.graph.node_weight(node).unwrap(), + TaggedIndex::Seg(SegIndex {index: edge, ..}) => + *self.graph.edge_weight(edge).unwrap(), + TaggedIndex::EndRef(..) + | TaggedIndex::AroundRef(..) => + unreachable!(), } } } diff --git a/src/weight.rs b/src/weight.rs index 9f2573c..ad0f6df 100644 --- a/src/weight.rs +++ b/src/weight.rs @@ -10,8 +10,6 @@ pub struct DotWeight { #[derive(Debug, Clone, Copy, PartialEq)] pub struct BendWeight { pub net: i32, - pub around: TaggedIndex, - pub center: DotIndex, pub cw: bool, }