mirror of https://codeberg.org/topola/topola.git
Create a new `Set` trait for collections of node indices
This commit is contained in:
parent
f1772ca0be
commit
925448802a
|
|
@ -0,0 +1,114 @@
|
|||
use std::marker::PhantomData;
|
||||
use enum_as_inner::EnumAsInner;
|
||||
use petgraph::stable_graph::NodeIndex;
|
||||
|
||||
use crate::math::Circle;
|
||||
|
||||
pub trait Set {
|
||||
fn interior(&self) -> Vec<TaggedIndex>;
|
||||
fn closure(&self) -> Vec<TaggedIndex>;
|
||||
fn boundary(&self) -> Vec<DotIndex>;
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum TaggedWeight {
|
||||
Dot(DotWeight),
|
||||
Seg(SegWeight),
|
||||
Bend(BendWeight),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct DotWeight {
|
||||
pub net: i32,
|
||||
pub circle: Circle,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct BendWeight {
|
||||
pub net: i32,
|
||||
pub cw: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct SegWeight {
|
||||
pub net: i32,
|
||||
pub width: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum Label {
|
||||
End,
|
||||
Outer,
|
||||
Core,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)]
|
||||
pub enum TaggedIndex {
|
||||
Dot(DotIndex),
|
||||
Seg(SegIndex),
|
||||
Bend(BendIndex),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Index<T> {
|
||||
pub index: NodeIndex<usize>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Index<T> {
|
||||
pub fn new(index: NodeIndex<usize>) -> Self {
|
||||
Self {
|
||||
index,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn retag(&self, weight: TaggedWeight) -> TaggedIndex {
|
||||
match weight {
|
||||
TaggedWeight::Dot(..) =>
|
||||
TaggedIndex::Dot(DotIndex {index: self.index, marker: PhantomData}),
|
||||
TaggedWeight::Seg(..) =>
|
||||
TaggedIndex::Seg(SegIndex {index: self.index, marker: PhantomData}),
|
||||
TaggedWeight::Bend(..) =>
|
||||
TaggedIndex::Bend(BendIndex {index: self.index, marker: PhantomData}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Tag {
|
||||
fn tag(&self) -> TaggedIndex;
|
||||
}
|
||||
|
||||
macro_rules! untag {
|
||||
($index:ident, $expr:expr) => {
|
||||
match $index {
|
||||
TaggedIndex::Dot($index) => $expr,
|
||||
TaggedIndex::Seg($index) => $expr,
|
||||
TaggedIndex::Bend($index) => $expr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type DotIndex = Index<DotWeight>;
|
||||
|
||||
impl Tag for DotIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::Dot(*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub type SegIndex = Index<SegWeight>;
|
||||
|
||||
impl Tag for SegIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::Seg(*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub type BendIndex = Index<BendWeight>;
|
||||
|
||||
impl Tag for BendIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::Bend(*self)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,11 @@ use std::rc::Rc;
|
|||
use geo::geometry::Point;
|
||||
|
||||
use crate::math::Circle;
|
||||
use crate::mesh::{Mesh, TaggedIndex, RTreeWrapper, DotIndex, SegIndex, BendIndex, Tag};
|
||||
use crate::mesh::Mesh;
|
||||
use crate::graph::{TaggedIndex, DotIndex, SegIndex, BendIndex};
|
||||
use crate::rules::{Rules, Conditions};
|
||||
use crate::shape::Shape;
|
||||
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight};
|
||||
use crate::graph::{TaggedWeight, DotWeight, SegWeight, BendWeight};
|
||||
use crate::math;
|
||||
|
||||
pub struct Layout {
|
||||
|
|
@ -182,28 +183,7 @@ impl Layout {
|
|||
}
|
||||
|
||||
fn extend_head_bend(&mut self, head: Head, to: Point) -> Head {
|
||||
let bend = head.bend.unwrap();
|
||||
let dot_weight = self.mesh.primitive(head.dot).weight();
|
||||
let bend_weight = self.mesh.primitive(bend).weight();
|
||||
let around = self.mesh.primitive(bend).around();
|
||||
|
||||
let fixed_dot: DotIndex = self.mesh.primitive(bend).ends()
|
||||
.into_iter()
|
||||
.filter(|neighbor| {*neighbor != head.dot})
|
||||
.collect::<Vec<DotIndex>>()[0];
|
||||
|
||||
self.mesh.remove_bend(bend);
|
||||
self.mesh.remove_dot(head.dot);
|
||||
|
||||
let new_dot = self.mesh.add_dot(DotWeight {
|
||||
net: dot_weight.net,
|
||||
circle: Circle {
|
||||
pos: to,
|
||||
r: dot_weight.circle.r,
|
||||
},
|
||||
});
|
||||
|
||||
self.mesh.add_bend(fixed_dot, new_dot, around, bend_weight);
|
||||
self.mesh.extend_bend(head.bend.unwrap(), head.dot, to);
|
||||
head
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,22 @@
|
|||
extern crate sdl2;
|
||||
|
||||
#[macro_use] mod mesh;
|
||||
#[macro_use] mod graph;
|
||||
mod layout;
|
||||
mod rules;
|
||||
mod mesh;
|
||||
mod primitive;
|
||||
mod shape;
|
||||
mod weight;
|
||||
mod math;
|
||||
|
||||
use std::mem::swap;
|
||||
use std::time::Duration;
|
||||
use geo::geometry::Point;
|
||||
use mesh::Index;
|
||||
use sdl2::pixels::Color;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::gfx::primitives::DrawRenderer;
|
||||
|
||||
use crate::layout::Layout;
|
||||
use crate::shape::Shape;
|
||||
use crate::weight::{TaggedWeight, DotWeight};
|
||||
use crate::graph::DotWeight;
|
||||
use crate::math::Circle;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
103
src/mesh.rs
103
src/mesh.rs
|
|
@ -1,76 +1,11 @@
|
|||
use std::marker::PhantomData;
|
||||
use enum_as_inner::EnumAsInner;
|
||||
use geo::Point;
|
||||
use petgraph::Direction::{Outgoing, Incoming};
|
||||
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
|
||||
use petgraph::visit::EdgeRef;
|
||||
use rstar::{RTree, RTreeObject, AABB};
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
use rstar::RTree;
|
||||
use rstar::primitives::GeomWithData;
|
||||
|
||||
use crate::primitive::Primitive;
|
||||
use crate::shape::Shape;
|
||||
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight, Label};
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Index<T> {
|
||||
pub index: NodeIndex<usize>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Index<T> {
|
||||
pub fn new(index: NodeIndex<usize>) -> Self {
|
||||
Self {
|
||||
index,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Tag {
|
||||
fn tag(&self) -> TaggedIndex;
|
||||
}
|
||||
|
||||
macro_rules! untag {
|
||||
($index:ident, $expr:expr) => {
|
||||
match $index {
|
||||
TaggedIndex::Dot($index) => $expr,
|
||||
TaggedIndex::Seg($index) => $expr,
|
||||
TaggedIndex::Bend($index) => $expr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type DotIndex = Index<DotWeight>;
|
||||
|
||||
impl Tag for DotIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::Dot(*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub type SegIndex = Index<SegWeight>;
|
||||
|
||||
impl Tag for SegIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::Seg(*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub type BendIndex = Index<BendWeight>;
|
||||
|
||||
impl Tag for BendIndex {
|
||||
fn tag(&self) -> TaggedIndex {
|
||||
TaggedIndex::Bend(*self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)]
|
||||
pub enum TaggedIndex {
|
||||
Dot(DotIndex),
|
||||
Seg(SegIndex),
|
||||
Bend(BendIndex),
|
||||
}
|
||||
use crate::graph::{Tag, TaggedIndex, DotIndex, SegIndex, BendIndex, Index, TaggedWeight, DotWeight, SegWeight, BendWeight, Label};
|
||||
|
||||
pub type RTreeWrapper = GeomWithData<Shape, TaggedIndex>;
|
||||
|
||||
|
|
@ -149,14 +84,30 @@ impl Mesh {
|
|||
self.graph.remove_node(bend.index);
|
||||
}
|
||||
|
||||
/*pub fn extend_bend(&mut self, bend: BendIndex, to: Point) -> DotIndex {
|
||||
pub fn extend_bend(&mut self, bend: BendIndex, dot: DotIndex, to: Point) {
|
||||
self.remove_from_rtree(bend.tag());
|
||||
self.remove_from_rtree(dot.tag());
|
||||
|
||||
let mut dot_weight = self.primitive(dot).weight();
|
||||
dot_weight.circle.pos = to;
|
||||
*self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(dot_weight);
|
||||
|
||||
self.insert_into_rtree(dot.tag());
|
||||
self.insert_into_rtree(bend.tag());
|
||||
}
|
||||
|
||||
pub fn shift_bend(&mut self, bend: BendIndex, offset: f64) {
|
||||
/*pub fn shift_bend(&mut self, bend: BendIndex, offset: f64) {
|
||||
|
||||
}*/
|
||||
|
||||
/*pub fn position_bend(&mut self, bend: BendIndex, uI*/
|
||||
|
||||
//pub fn reposition_bend
|
||||
|
||||
pub fn reoffset_bend(&mut self, bend: BendIndex, offset: f64) {
|
||||
|
||||
}
|
||||
|
||||
pub fn nodes(&self) -> impl Iterator<Item=TaggedIndex> + '_ {
|
||||
self.rtree.iter().map(|wrapper| wrapper.data)
|
||||
}
|
||||
|
|
@ -165,7 +116,13 @@ impl Mesh {
|
|||
Primitive::new(index, &self.graph)
|
||||
}
|
||||
|
||||
/*fn insert_into_rtree<Weight>(&mut self, index: Index<Weight>) {
|
||||
self.rtree.insert(RTreeWrapper::new(self.primitive(index).shape(), index.tag()));
|
||||
}*/
|
||||
fn insert_into_rtree(&mut self, index: TaggedIndex) {
|
||||
let shape = untag!(index, self.primitive(index).shape());
|
||||
self.rtree.insert(RTreeWrapper::new(shape, index));
|
||||
}
|
||||
|
||||
fn remove_from_rtree(&mut self, index: TaggedIndex) {
|
||||
let shape = untag!(index, self.primitive(index).shape());
|
||||
self.rtree.remove(&RTreeWrapper::new(shape, index));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::mem::swap;
|
|||
use petgraph::Direction::{Outgoing, Incoming};
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
|
||||
use crate::{mesh::{DotIndex, SegIndex, BendIndex, TaggedIndex, Mesh, Tag, Index}, weight::{DotWeight, SegWeight, BendWeight, TaggedWeight, Label}};
|
||||
use crate::graph::{Set, DotIndex, SegIndex, BendIndex, TaggedIndex, Tag, Index, DotWeight, SegWeight, BendWeight, TaggedWeight, Label};
|
||||
use crate::shape::Shape;
|
||||
|
||||
pub struct Primitive<'a, Weight> {
|
||||
|
|
@ -64,6 +64,10 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
.next()
|
||||
}
|
||||
|
||||
pub fn tagged_index(&self) -> TaggedIndex {
|
||||
self.index.retag(*self.graph.node_weight(self.index.index).unwrap())
|
||||
}
|
||||
|
||||
pub fn tagged_weight(&self) -> TaggedWeight {
|
||||
*self.graph.node_weight(self.index.index).unwrap()
|
||||
}
|
||||
|
|
@ -73,6 +77,24 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, Weight> Set for Primitive<'a, Weight> {
|
||||
fn interior(&self) -> Vec<TaggedIndex> {
|
||||
vec![self.tagged_index()]
|
||||
}
|
||||
|
||||
fn closure(&self) -> Vec<TaggedIndex> {
|
||||
let ends: Vec<TaggedIndex> = self.ends()
|
||||
.into_iter()
|
||||
.map(|end| TaggedIndex::Dot(end))
|
||||
.collect();
|
||||
[[self.tagged_index()].as_slice(), ends.as_slice()].concat()
|
||||
}
|
||||
|
||||
fn boundary(&self) -> Vec<DotIndex> {
|
||||
self.ends()
|
||||
}
|
||||
}
|
||||
|
||||
type Dot<'a> = Primitive<'a, DotWeight>;
|
||||
type Seg<'a> = Primitive<'a, SegWeight>;
|
||||
type Bend<'a> = Primitive<'a, BendWeight>;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use geo::{Point, EuclideanDistance};
|
||||
use rstar::{RTreeObject, AABB};
|
||||
|
||||
use crate::{weight::{TaggedWeight, DotWeight}, math::Circle};
|
||||
use crate::graph::{TaggedWeight, DotWeight};
|
||||
use crate::math::Circle;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct Shape {
|
||||
|
|
|
|||
|
|
@ -1,34 +1,2 @@
|
|||
use enum_as_inner::EnumAsInner;
|
||||
use crate::math::Circle;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct DotWeight {
|
||||
pub net: i32,
|
||||
pub circle: Circle,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct BendWeight {
|
||||
pub net: i32,
|
||||
pub cw: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct SegWeight {
|
||||
pub net: i32,
|
||||
pub width: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum TaggedWeight {
|
||||
Dot(DotWeight),
|
||||
Seg(SegWeight),
|
||||
Bend(BendWeight),
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum Label {
|
||||
End,
|
||||
Outer,
|
||||
Core,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue