mirror of https://codeberg.org/topola/topola.git
Add `node_count == size` invariant for `Layout`
This commit is contained in:
parent
82081ef170
commit
1a271cd89c
|
|
@ -221,7 +221,7 @@ impl<'a> Draw<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(Head, SegIndex), ()> {
|
fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(Head, SegIndex), ()> {
|
||||||
assert!(width <= self.layout.primitive(head.dot).weight().circle.r * 2.0);
|
debug_assert!(width <= self.layout.primitive(head.dot).weight().circle.r * 2.0);
|
||||||
|
|
||||||
let net = self.layout.primitive(head.dot).weight().net;
|
let net = self.layout.primitive(head.dot).weight().net;
|
||||||
let to_index = self.layout.add_dot(DotWeight {
|
let to_index = self.layout.add_dot(DotWeight {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use contracts::debug_invariant;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
use petgraph::visit::EdgeRef;
|
use petgraph::visit::EdgeRef;
|
||||||
|
|
@ -22,6 +23,7 @@ pub struct Layout {
|
||||||
pub graph: StableDiGraph<TaggedWeight, Label, usize>,
|
pub graph: StableDiGraph<TaggedWeight, Label, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[debug_invariant(self.graph.node_count() == self.rtree.size())]
|
||||||
impl Layout {
|
impl Layout {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Layout {
|
Layout {
|
||||||
|
|
@ -54,8 +56,8 @@ impl Layout {
|
||||||
pub fn add_dot(&mut self, weight: DotWeight) -> Result<DotIndex, ()> {
|
pub fn add_dot(&mut self, weight: DotWeight) -> Result<DotIndex, ()> {
|
||||||
let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight)));
|
let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight)));
|
||||||
|
|
||||||
self.fail_and_remove_if_collides_except(dot, &[])?;
|
|
||||||
self.insert_into_rtree(dot.tag());
|
self.insert_into_rtree(dot.tag());
|
||||||
|
self.fail_and_remove_if_collides_except(dot, &[])?;
|
||||||
|
|
||||||
Ok(dot)
|
Ok(dot)
|
||||||
}
|
}
|
||||||
|
|
@ -71,8 +73,8 @@ impl Layout {
|
||||||
self.graph.add_edge(from.index, seg.index, Label::End);
|
self.graph.add_edge(from.index, seg.index, Label::End);
|
||||||
self.graph.add_edge(seg.index, to.index, Label::End);
|
self.graph.add_edge(seg.index, to.index, Label::End);
|
||||||
|
|
||||||
self.fail_and_remove_if_collides_except(seg, &[from.tag(), to.tag()])?;
|
|
||||||
self.insert_into_rtree(seg.tag());
|
self.insert_into_rtree(seg.tag());
|
||||||
|
self.fail_and_remove_if_collides_except(seg, &[from.tag(), to.tag()])?;
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight_mut(from.index)
|
.node_weight_mut(from.index)
|
||||||
|
|
@ -117,8 +119,8 @@ impl Layout {
|
||||||
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);
|
self.graph.add_edge(bend.index, core.index, Label::Core);
|
||||||
|
|
||||||
self.fail_and_remove_if_collides_except(bend, &[from.tag(), to.tag(), core.tag()])?;
|
|
||||||
self.insert_into_rtree(bend.tag());
|
self.insert_into_rtree(bend.tag());
|
||||||
|
self.fail_and_remove_if_collides_except(bend, &[from.tag(), to.tag(), core.tag()])?;
|
||||||
Ok(bend)
|
Ok(bend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,6 +168,45 @@ impl Layout {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bow(&self, bend: BendIndex) -> Bow {
|
||||||
|
Bow::from_bend(bend, &self.graph)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
||||||
|
Segbend::from_dot_prev(dot, &self.graph)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
||||||
|
Segbend::from_dot_next(dot, &self.graph)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fail_and_remove_if_collides_except<Weight: std::marker::Copy>(
|
||||||
|
&mut self,
|
||||||
|
index: Index<Weight>,
|
||||||
|
except: &[TaggedIndex],
|
||||||
|
) -> Result<(), ()> {
|
||||||
|
if let Some(..) = self.detect_collision_except(index, except) {
|
||||||
|
self.remove(index);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dots(&self) -> impl Iterator<Item = DotIndex> + '_ {
|
||||||
|
self.nodes().filter_map(|ni| ni.as_dot().map(|di| *di))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
||||||
|
self.nodes()
|
||||||
|
.map(|ni| untag!(ni, self.primitive(ni).shape()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nodes(&self) -> impl Iterator<Item = TaggedIndex> + '_ {
|
||||||
|
self.rtree.iter().map(|wrapper| wrapper.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Layout {
|
||||||
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), ()> {
|
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), ()> {
|
||||||
let mut cur_bend = self.primitive(dot).outer();
|
let mut cur_bend = self.primitive(dot).outer();
|
||||||
loop {
|
loop {
|
||||||
|
|
@ -212,30 +253,6 @@ impl Layout {
|
||||||
Primitive::new(index, &self.graph)
|
Primitive::new(index, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bow(&self, bend: BendIndex) -> Bow {
|
|
||||||
Bow::from_bend(bend, &self.graph)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
|
||||||
Segbend::from_dot_prev(dot, &self.graph)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
|
||||||
Segbend::from_dot_next(dot, &self.graph)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fail_and_remove_if_collides_except<Weight: std::marker::Copy>(
|
|
||||||
&mut self,
|
|
||||||
index: Index<Weight>,
|
|
||||||
except: &[TaggedIndex],
|
|
||||||
) -> Result<(), ()> {
|
|
||||||
if let Some(..) = self.detect_collision_except(index, except) {
|
|
||||||
self.graph.remove_node(index.index);
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn detect_collision_except<Weight: std::marker::Copy>(
|
fn detect_collision_except<Weight: std::marker::Copy>(
|
||||||
&self,
|
&self,
|
||||||
index: Index<Weight>,
|
index: Index<Weight>,
|
||||||
|
|
@ -263,22 +280,9 @@ impl Layout {
|
||||||
|
|
||||||
fn remove_from_rtree(&mut self, index: TaggedIndex) {
|
fn remove_from_rtree(&mut self, index: TaggedIndex) {
|
||||||
let shape = untag!(index, self.primitive(index).shape());
|
let shape = untag!(index, self.primitive(index).shape());
|
||||||
assert!(self
|
debug_assert!(self
|
||||||
.rtree
|
.rtree
|
||||||
.remove(&RTreeWrapper::new(shape, index))
|
.remove(&RTreeWrapper::new(shape, index))
|
||||||
.is_some());
|
.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dots(&self) -> impl Iterator<Item = DotIndex> + '_ {
|
|
||||||
self.nodes().filter_map(|ni| ni.as_dot().map(|di| *di))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
|
||||||
self.nodes()
|
|
||||||
.map(|ni| untag!(ni, self.primitive(ni).shape()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nodes(&self) -> impl Iterator<Item = TaggedIndex> + '_ {
|
|
||||||
self.rtree.iter().map(|wrapper| wrapper.data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
||||||
use petgraph::Direction::{Incoming, Outgoing};
|
use petgraph::Direction::{Incoming, Outgoing};
|
||||||
|
|
||||||
use crate::graph::{
|
use crate::graph::{
|
||||||
BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, Interior, Label, SegWeight, TaggedIndex, TaggedWeight,
|
BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, Interior, Label, SegWeight,
|
||||||
|
TaggedIndex, TaggedWeight,
|
||||||
};
|
};
|
||||||
use crate::math::{self, Circle};
|
use crate::math::{self, Circle};
|
||||||
use crate::shape::{BendShape, DotShape, SegShape, Shape};
|
use crate::shape::{BendShape, DotShape, SegShape, Shape};
|
||||||
|
|
@ -184,7 +185,9 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
||||||
let this = self.net(&self.index);
|
let this = self.net(&self.index);
|
||||||
let other = self.net(&index);
|
let other = self.net(&index);
|
||||||
|
|
||||||
if this == -1 || other == -1 {
|
if this == other {
|
||||||
|
true
|
||||||
|
} else if this == -1 || other == -1 {
|
||||||
true
|
true
|
||||||
} else if this == -2 || other == -2 {
|
} else if this == -2 || other == -2 {
|
||||||
false
|
false
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue