mirror of https://codeberg.org/topola/topola.git
primitive: Move `.shape()` to a new trait `MakeShape`
This commit is contained in:
parent
ae9dd23b7c
commit
4e21ff754d
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
graph::{BendIndex, DotIndex},
|
graph::{BendIndex, DotIndex},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
math::{self, Circle},
|
math::{self, Circle},
|
||||||
|
primitive::MakeShape,
|
||||||
rules::{Conditions, Rules},
|
rules::{Conditions, Rules},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::graph::{
|
||||||
BendIndex, BendWeight, DotIndex, DotWeight, Index, Interior, Label, Retag, SegIndex, SegWeight,
|
BendIndex, BendWeight, DotIndex, DotWeight, Index, Interior, Label, Retag, SegIndex, SegWeight,
|
||||||
Tag, TaggedIndex, Weight,
|
Tag, TaggedIndex, Weight,
|
||||||
};
|
};
|
||||||
use crate::primitive::Primitive;
|
use crate::primitive::{MakeShape, Primitive};
|
||||||
use crate::segbend::Segbend;
|
use crate::segbend::Segbend;
|
||||||
use crate::shape::{Shape, ShapeTrait};
|
use crate::shape::{Shape, ShapeTrait};
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 1))]
|
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 1))]
|
||||||
pub fn remove<Weight: std::marker::Copy>(&mut self, index: Index<Weight>) {
|
pub fn remove<W: std::marker::Copy>(&mut self, index: Index<W>) {
|
||||||
// Unnecessary retag. It should be possible to elide it.
|
// Unnecessary retag. It should be possible to elide it.
|
||||||
let weight = *self.graph.node_weight(index.index).unwrap();
|
let weight = *self.graph.node_weight(index.index).unwrap();
|
||||||
|
|
||||||
|
|
@ -236,11 +236,14 @@ impl Layout {
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count() - 1))]
|
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count() - 1))]
|
||||||
fn fail_and_remove_if_collides_except<Weight: std::marker::Copy>(
|
fn fail_and_remove_if_collides_except<W: std::marker::Copy>(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: Index<Weight>,
|
index: Index<W>,
|
||||||
except: &[TaggedIndex],
|
except: &[TaggedIndex],
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()>
|
||||||
|
where
|
||||||
|
for<'a> Primitive<'a, W>: MakeShape,
|
||||||
|
{
|
||||||
if let Some(..) = self.detect_collision_except(index, except) {
|
if let Some(..) = self.detect_collision_except(index, except) {
|
||||||
self.remove(index);
|
self.remove(index);
|
||||||
return Err(());
|
return Err(());
|
||||||
|
|
@ -310,15 +313,18 @@ impl Layout {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primitive<Weight>(&self, index: Index<Weight>) -> Primitive<Weight> {
|
pub fn primitive<W>(&self, index: Index<W>) -> Primitive<W> {
|
||||||
Primitive::new(index, &self.graph)
|
Primitive::new(index, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detect_collision_except<Weight: std::marker::Copy>(
|
fn detect_collision_except<W>(
|
||||||
&self,
|
&self,
|
||||||
index: Index<Weight>,
|
index: Index<W>,
|
||||||
except: &[TaggedIndex],
|
except: &[TaggedIndex],
|
||||||
) -> Option<TaggedIndex> {
|
) -> Option<TaggedIndex>
|
||||||
|
where
|
||||||
|
for<'a> Primitive<'a, W>: MakeShape,
|
||||||
|
{
|
||||||
let primitive = self.primitive(index);
|
let primitive = self.primitive(index);
|
||||||
let shape = primitive.shape();
|
let shape = primitive.shape();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ use spade::{
|
||||||
DelaunayTriangulation, HasPosition, InsertionError, Point2, Triangulation,
|
DelaunayTriangulation, HasPosition, InsertionError, Point2, Triangulation,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::shape::ShapeTrait;
|
|
||||||
use crate::{graph::DotIndex, layout::Layout};
|
use crate::{graph::DotIndex, layout::Layout};
|
||||||
|
use crate::{primitive::MakeShape, shape::ShapeTrait};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::mem::{self, swap};
|
use std::mem::{self, swap};
|
||||||
|
|
||||||
|
use enum_dispatch::enum_dispatch;
|
||||||
use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
||||||
use petgraph::Direction::{Incoming, Outgoing};
|
use petgraph::Direction::{Incoming, Outgoing};
|
||||||
|
|
||||||
|
|
@ -10,6 +11,10 @@ use crate::graph::{
|
||||||
use crate::math::{self, Circle};
|
use crate::math::{self, Circle};
|
||||||
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
||||||
|
|
||||||
|
pub trait MakeShape {
|
||||||
|
fn shape(&self) -> Shape;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Primitive<'a, W> {
|
pub struct Primitive<'a, W> {
|
||||||
pub index: Index<W>,
|
pub index: Index<W>,
|
||||||
|
|
@ -21,38 +26,6 @@ impl<'a, W> Primitive<'a, W> {
|
||||||
Self { index, graph }
|
Self { index, graph }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shape(&self) -> Shape {
|
|
||||||
match self.tagged_weight() {
|
|
||||||
Weight::Dot(dot) => Shape::Dot(DotShape { c: dot.circle }),
|
|
||||||
Weight::Seg(seg) => {
|
|
||||||
let ends = self.ends();
|
|
||||||
Shape::Seg(SegShape {
|
|
||||||
from: self.primitive(ends.0).weight().circle.pos,
|
|
||||||
to: self.primitive(ends.1).weight().circle.pos,
|
|
||||||
width: seg.width,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Weight::Bend(bend) => {
|
|
||||||
let ends = self.ends();
|
|
||||||
|
|
||||||
let mut bend_shape = BendShape {
|
|
||||||
from: self.primitive(ends.0).weight().circle.pos,
|
|
||||||
to: self.primitive(ends.1).weight().circle.pos,
|
|
||||||
c: Circle {
|
|
||||||
pos: self.primitive(self.core().unwrap()).weight().circle.pos,
|
|
||||||
r: self.inner_radius(),
|
|
||||||
},
|
|
||||||
width: self.primitive(ends.0).weight().circle.r * 2.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if bend.cw {
|
|
||||||
swap(&mut bend_shape.from, &mut bend_shape.to);
|
|
||||||
}
|
|
||||||
Shape::Bend(bend_shape)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inner_radius(&self) -> f64 {
|
fn inner_radius(&self) -> f64 {
|
||||||
let mut r = 0.0;
|
let mut r = 0.0;
|
||||||
let mut layer = BendIndex::new(self.index.index);
|
let mut layer = BendIndex::new(self.index.index);
|
||||||
|
|
@ -224,13 +197,13 @@ impl<'a, W> Primitive<'a, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Weight> Interior<TaggedIndex> for Primitive<'a, Weight> {
|
impl<'a, W> Interior<TaggedIndex> for Primitive<'a, W> {
|
||||||
fn interior(&self) -> Vec<TaggedIndex> {
|
fn interior(&self) -> Vec<TaggedIndex> {
|
||||||
vec![self.tagged_index()]
|
vec![self.tagged_index()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Weight> Ends<DotIndex, DotIndex> for Primitive<'a, Weight> {
|
impl<'a, W> Ends<DotIndex, DotIndex> for Primitive<'a, W> {
|
||||||
fn ends(&self) -> (DotIndex, DotIndex) {
|
fn ends(&self) -> (DotIndex, DotIndex) {
|
||||||
let v = self
|
let v = self
|
||||||
.graph
|
.graph
|
||||||
|
|
@ -254,8 +227,6 @@ impl<'a, Weight> Ends<DotIndex, DotIndex> for Primitive<'a, Weight> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Dot<'a> = Primitive<'a, DotWeight>;
|
pub type Dot<'a> = Primitive<'a, DotWeight>;
|
||||||
pub type Seg<'a> = Primitive<'a, SegWeight>;
|
|
||||||
pub type Bend<'a> = Primitive<'a, BendWeight>;
|
|
||||||
|
|
||||||
impl<'a> Dot<'a> {
|
impl<'a> Dot<'a> {
|
||||||
pub fn bend(&self) -> Option<BendIndex> {
|
pub fn bend(&self) -> Option<BendIndex> {
|
||||||
|
|
@ -296,6 +267,16 @@ impl<'a> Dot<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> MakeShape for Dot<'a> {
|
||||||
|
fn shape(&self) -> Shape {
|
||||||
|
Shape::Dot(DotShape {
|
||||||
|
c: self.weight().circle,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Seg<'a> = Primitive<'a, SegWeight>;
|
||||||
|
|
||||||
impl<'a> Seg<'a> {
|
impl<'a> Seg<'a> {
|
||||||
pub fn next(&self) -> Option<DotIndex> {
|
pub fn next(&self) -> Option<DotIndex> {
|
||||||
self.next_node().map(|ni| DotIndex::new(ni))
|
self.next_node().map(|ni| DotIndex::new(ni))
|
||||||
|
|
@ -310,6 +291,19 @@ impl<'a> Seg<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> MakeShape for Seg<'a> {
|
||||||
|
fn shape(&self) -> Shape {
|
||||||
|
let ends = self.ends();
|
||||||
|
Shape::Seg(SegShape {
|
||||||
|
from: self.primitive(ends.0).weight().circle.pos,
|
||||||
|
to: self.primitive(ends.1).weight().circle.pos,
|
||||||
|
width: self.weight().width,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Bend<'a> = Primitive<'a, BendWeight>;
|
||||||
|
|
||||||
impl<'a> Bend<'a> {
|
impl<'a> Bend<'a> {
|
||||||
pub fn around(&self) -> TaggedIndex {
|
pub fn around(&self) -> TaggedIndex {
|
||||||
if let Some(inner) = self.inner() {
|
if let Some(inner) = self.inner() {
|
||||||
|
|
@ -365,3 +359,24 @@ impl<'a> Bend<'a> {
|
||||||
math::cross_product(end1 - center, end2 - center)
|
math::cross_product(end1 - center, end2 - center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> MakeShape for Bend<'a> {
|
||||||
|
fn shape(&self) -> Shape {
|
||||||
|
let ends = self.ends();
|
||||||
|
|
||||||
|
let mut bend_shape = BendShape {
|
||||||
|
from: self.primitive(ends.0).weight().circle.pos,
|
||||||
|
to: self.primitive(ends.1).weight().circle.pos,
|
||||||
|
c: Circle {
|
||||||
|
pos: self.primitive(self.core().unwrap()).weight().circle.pos,
|
||||||
|
r: self.inner_radius(),
|
||||||
|
},
|
||||||
|
width: self.primitive(ends.0).weight().circle.r * 2.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.weight().cw {
|
||||||
|
swap(&mut bend_shape.from, &mut bend_shape.to);
|
||||||
|
}
|
||||||
|
Shape::Bend(bend_shape)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
graph::{BendIndex, DotIndex, Ends},
|
graph::{BendIndex, DotIndex, Ends},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
mesh::{Mesh, MeshEdgeReference, VertexIndex},
|
mesh::{Mesh, MeshEdgeReference, VertexIndex},
|
||||||
|
primitive::MakeShape,
|
||||||
rules::Rules,
|
rules::Rules,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue