mirror of https://codeberg.org/topola/topola.git
Make bends nodes
This is necessary because bends may have more than two neighbors: apart from the ends, there's also the node around which the bend is wrapped (not yet made a neighbor, will be done in subsequent commits).
This commit is contained in:
parent
bedd7c744a
commit
26112724c7
|
|
@ -137,7 +137,7 @@ impl Layout {
|
|||
match self.mesh.weight(head_around) {
|
||||
Weight::Dot(..) => self.dot_guidecircle(*head_around.as_dot().unwrap(), width + 5.0, conditions),
|
||||
Weight::Bend(..) => self.bend_guidecircle(*head_around.as_bend().unwrap(), width, conditions),
|
||||
Weight::Seg(..) => unreachable!(),
|
||||
Weight::Seg(..) | Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
||||
}
|
||||
},
|
||||
None => Circle {
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ fn main() {
|
|||
let mut angle1 = delta1.y().atan2(delta1.x());
|
||||
let mut angle2 = delta2.y().atan2(delta2.x());
|
||||
|
||||
if !primitive.weight.as_bend().unwrap().cw {
|
||||
if primitive.weight.as_bend().unwrap().cw {
|
||||
swap(&mut angle1, &mut angle2);
|
||||
}
|
||||
|
||||
|
|
@ -151,6 +151,7 @@ fn main() {
|
|||
}
|
||||
|
||||
},
|
||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
49
src/mesh.rs
49
src/mesh.rs
|
|
@ -6,7 +6,7 @@ use rstar::{RTree, RTreeObject, AABB};
|
|||
use rstar::primitives::GeomWithData;
|
||||
|
||||
use crate::primitive::Primitive;
|
||||
use crate::weight::{Weight, DotWeight, SegWeight, BendWeight};
|
||||
use crate::weight::{Weight, DotWeight, SegWeight, BendWeight, EndRefWeight, AroundRefWeight};
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
|
|
@ -44,7 +44,7 @@ impl Tag for SegIndex {
|
|||
}
|
||||
}
|
||||
|
||||
pub type BendIndex = Index<EdgeIndex<usize>, BendWeight>;
|
||||
pub type BendIndex = Index<NodeIndex<usize>, BendWeight>;
|
||||
|
||||
impl Tag for BendIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
|
|
@ -52,11 +52,29 @@ impl Tag for BendIndex {
|
|||
}
|
||||
}
|
||||
|
||||
pub type EndRefIndex = Index<EdgeIndex<usize>, EndRefWeight>;
|
||||
|
||||
impl Tag for EndRefIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::EndRef(*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub type AroundRefIndex = Index<EdgeIndex<usize>, AroundRefWeight>;
|
||||
|
||||
impl Tag for AroundRefIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::AroundRef(*self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)]
|
||||
pub enum TaggedIndex {
|
||||
Dot(DotIndex),
|
||||
Seg(SegIndex),
|
||||
Bend(BendIndex),
|
||||
EndRef(EndRefIndex),
|
||||
AroundRef(AroundRefIndex),
|
||||
}
|
||||
|
||||
pub type RTreeWrapper = GeomWithData<Primitive, TaggedIndex>;
|
||||
|
|
@ -99,7 +117,10 @@ impl Mesh {
|
|||
}
|
||||
|
||||
pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, weight: BendWeight) -> BendIndex {
|
||||
let bend_index = BendIndex::new(self.graph.add_edge(from.index, to.index, Weight::Bend(weight)));
|
||||
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 {}));
|
||||
|
||||
let index = TaggedIndex::Bend(bend_index);
|
||||
self.rtree.insert(RTreeWrapper::new(self.primitive(index), index));
|
||||
bend_index
|
||||
|
|
@ -107,7 +128,7 @@ impl Mesh {
|
|||
|
||||
pub fn remove_bend(&mut self, bend: BendIndex) {
|
||||
self.rtree.remove(&RTreeWrapper::new(self.primitive(TaggedIndex::Bend(bend)), TaggedIndex::Bend(bend)));
|
||||
self.graph.remove_edge(bend.index);
|
||||
self.graph.remove_node(bend.index);
|
||||
}
|
||||
|
||||
pub fn primitives(&self) -> Box<dyn Iterator<Item=Primitive> + '_> {
|
||||
|
|
@ -143,15 +164,18 @@ impl Mesh {
|
|||
|
||||
pub fn neighboring_dots(&self, index: TaggedIndex) -> Vec<TaggedIndex> {
|
||||
match index {
|
||||
TaggedIndex::Dot(DotIndex {index: node_index, ..}) =>
|
||||
TaggedIndex::Dot(DotIndex {index: node_index, ..})
|
||||
| TaggedIndex::Bend(BendIndex {index: node_index, ..}) =>
|
||||
return self.graph.neighbors(node_index)
|
||||
.map(|ni| TaggedIndex::Dot(Index::new(ni))).collect(),
|
||||
TaggedIndex::Seg(SegIndex {index: edge_index, ..})
|
||||
| TaggedIndex::Bend(BendIndex {index: edge_index, ..}) => {
|
||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().as_dot().is_some())
|
||||
.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::EndRef(..) | TaggedIndex::AroundRef(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -169,11 +193,12 @@ impl Mesh {
|
|||
|
||||
pub fn weight(&self, index: TaggedIndex) -> Weight {
|
||||
match index {
|
||||
TaggedIndex::Dot(DotIndex {index: node_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, ..})
|
||||
| TaggedIndex::Bend(BendIndex {index: edge_index, ..}) =>
|
||||
TaggedIndex::Seg(SegIndex {index: edge_index, ..}) =>
|
||||
*self.graph.edge_weight(edge_index).unwrap(),
|
||||
TaggedIndex::EndRef(..) | TaggedIndex::AroundRef(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ impl Primitive {
|
|||
.collect();
|
||||
return AABB::<[f64; 2]>::from_points(&points);
|
||||
},
|
||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ impl Primitive {
|
|||
r,
|
||||
})
|
||||
}
|
||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +52,7 @@ impl Primitive {
|
|||
Weight::Dot(dot) => dot.circle.r * 2.0,
|
||||
Weight::Seg(seg) => seg.width,
|
||||
Weight::Bend(bend) => self.dot_neighbor_weights[0].circle.r * 2.0,
|
||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,19 @@ pub struct SegWeight {
|
|||
pub width: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct EndRefWeight {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct AroundRefWeight {
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum Weight {
|
||||
Dot(DotWeight),
|
||||
Seg(SegWeight),
|
||||
Bend(BendWeight),
|
||||
EndRef(EndRefWeight),
|
||||
AroundRef(AroundRefWeight),
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue