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},
|
||||
layout::Layout,
|
||||
math::{self, Circle},
|
||||
primitive::MakeShape,
|
||||
rules::{Conditions, Rules},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use crate::graph::{
|
|||
BendIndex, BendWeight, DotIndex, DotWeight, Index, Interior, Label, Retag, SegIndex, SegWeight,
|
||||
Tag, TaggedIndex, Weight,
|
||||
};
|
||||
use crate::primitive::Primitive;
|
||||
use crate::primitive::{MakeShape, Primitive};
|
||||
use crate::segbend::Segbend;
|
||||
use crate::shape::{Shape, ShapeTrait};
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ impl Layout {
|
|||
}
|
||||
|
||||
#[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.
|
||||
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.edge_count() == old(self.graph.edge_count()))]
|
||||
#[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,
|
||||
index: Index<Weight>,
|
||||
index: Index<W>,
|
||||
except: &[TaggedIndex],
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
for<'a> Primitive<'a, W>: MakeShape,
|
||||
{
|
||||
if let Some(..) = self.detect_collision_except(index, except) {
|
||||
self.remove(index);
|
||||
return Err(());
|
||||
|
|
@ -310,15 +313,18 @@ impl Layout {
|
|||
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)
|
||||
}
|
||||
|
||||
fn detect_collision_except<Weight: std::marker::Copy>(
|
||||
fn detect_collision_except<W>(
|
||||
&self,
|
||||
index: Index<Weight>,
|
||||
index: Index<W>,
|
||||
except: &[TaggedIndex],
|
||||
) -> Option<TaggedIndex> {
|
||||
) -> Option<TaggedIndex>
|
||||
where
|
||||
for<'a> Primitive<'a, W>: MakeShape,
|
||||
{
|
||||
let primitive = self.primitive(index);
|
||||
let shape = primitive.shape();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use spade::{
|
|||
DelaunayTriangulation, HasPosition, InsertionError, Point2, Triangulation,
|
||||
};
|
||||
|
||||
use crate::shape::ShapeTrait;
|
||||
use crate::{graph::DotIndex, layout::Layout};
|
||||
use crate::{primitive::MakeShape, shape::ShapeTrait};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Vertex {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::mem::{self, swap};
|
||||
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
||||
use petgraph::Direction::{Incoming, Outgoing};
|
||||
|
||||
|
|
@ -10,6 +11,10 @@ use crate::graph::{
|
|||
use crate::math::{self, Circle};
|
||||
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
||||
|
||||
pub trait MakeShape {
|
||||
fn shape(&self) -> Shape;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Primitive<'a, W> {
|
||||
pub index: Index<W>,
|
||||
|
|
@ -21,38 +26,6 @@ impl<'a, W> Primitive<'a, W> {
|
|||
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 {
|
||||
let mut r = 0.0;
|
||||
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> {
|
||||
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) {
|
||||
let v = self
|
||||
.graph
|
||||
|
|
@ -254,8 +227,6 @@ impl<'a, Weight> Ends<DotIndex, DotIndex> for Primitive<'a, Weight> {
|
|||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
pub fn next(&self) -> Option<DotIndex> {
|
||||
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> {
|
||||
pub fn around(&self) -> TaggedIndex {
|
||||
if let Some(inner) = self.inner() {
|
||||
|
|
@ -365,3 +359,24 @@ impl<'a> Bend<'a> {
|
|||
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},
|
||||
layout::Layout,
|
||||
mesh::{Mesh, MeshEdgeReference, VertexIndex},
|
||||
primitive::MakeShape,
|
||||
rules::Rules,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue