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 geo::geometry::Point;
|
||||||
|
|
||||||
use crate::math::Circle;
|
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::rules::{Rules, Conditions};
|
||||||
use crate::shape::Shape;
|
use crate::shape::Shape;
|
||||||
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight};
|
use crate::graph::{TaggedWeight, DotWeight, SegWeight, BendWeight};
|
||||||
use crate::math;
|
use crate::math;
|
||||||
|
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
|
|
@ -182,28 +183,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_head_bend(&mut self, head: Head, to: Point) -> Head {
|
fn extend_head_bend(&mut self, head: Head, to: Point) -> Head {
|
||||||
let bend = head.bend.unwrap();
|
self.mesh.extend_bend(head.bend.unwrap(), head.dot, to);
|
||||||
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);
|
|
||||||
head
|
head
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,22 @@
|
||||||
extern crate sdl2;
|
extern crate sdl2;
|
||||||
|
|
||||||
#[macro_use] mod mesh;
|
#[macro_use] mod graph;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod rules;
|
mod rules;
|
||||||
|
mod mesh;
|
||||||
mod primitive;
|
mod primitive;
|
||||||
mod shape;
|
mod shape;
|
||||||
mod weight;
|
mod weight;
|
||||||
mod math;
|
mod math;
|
||||||
|
|
||||||
use std::mem::swap;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use geo::geometry::Point;
|
|
||||||
use mesh::Index;
|
|
||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
use sdl2::gfx::primitives::DrawRenderer;
|
use sdl2::gfx::primitives::DrawRenderer;
|
||||||
|
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
use crate::shape::Shape;
|
use crate::graph::DotWeight;
|
||||||
use crate::weight::{TaggedWeight, DotWeight};
|
|
||||||
use crate::math::Circle;
|
use crate::math::Circle;
|
||||||
|
|
||||||
fn main() {
|
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 geo::Point;
|
||||||
use petgraph::Direction::{Outgoing, Incoming};
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
|
use rstar::RTree;
|
||||||
use petgraph::visit::EdgeRef;
|
|
||||||
use rstar::{RTree, RTreeObject, AABB};
|
|
||||||
use rstar::primitives::GeomWithData;
|
use rstar::primitives::GeomWithData;
|
||||||
|
|
||||||
use crate::primitive::Primitive;
|
use crate::primitive::Primitive;
|
||||||
use crate::shape::Shape;
|
use crate::shape::Shape;
|
||||||
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight, Label};
|
use crate::graph::{Tag, TaggedIndex, DotIndex, SegIndex, BendIndex, Index, 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),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type RTreeWrapper = GeomWithData<Shape, TaggedIndex>;
|
pub type RTreeWrapper = GeomWithData<Shape, TaggedIndex>;
|
||||||
|
|
||||||
|
|
@ -149,14 +84,30 @@ impl Mesh {
|
||||||
self.graph.remove_node(bend.index);
|
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> + '_ {
|
pub fn nodes(&self) -> impl Iterator<Item=TaggedIndex> + '_ {
|
||||||
self.rtree.iter().map(|wrapper| wrapper.data)
|
self.rtree.iter().map(|wrapper| wrapper.data)
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +116,13 @@ impl Mesh {
|
||||||
Primitive::new(index, &self.graph)
|
Primitive::new(index, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fn insert_into_rtree<Weight>(&mut self, index: Index<Weight>) {
|
fn insert_into_rtree(&mut self, index: TaggedIndex) {
|
||||||
self.rtree.insert(RTreeWrapper::new(self.primitive(index).shape(), index.tag()));
|
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::Direction::{Outgoing, Incoming};
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
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;
|
use crate::shape::Shape;
|
||||||
|
|
||||||
pub struct Primitive<'a, Weight> {
|
pub struct Primitive<'a, Weight> {
|
||||||
|
|
@ -64,6 +64,10 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tagged_index(&self) -> TaggedIndex {
|
||||||
|
self.index.retag(*self.graph.node_weight(self.index.index).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tagged_weight(&self) -> TaggedWeight {
|
pub fn tagged_weight(&self) -> TaggedWeight {
|
||||||
*self.graph.node_weight(self.index.index).unwrap()
|
*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 Dot<'a> = Primitive<'a, DotWeight>;
|
||||||
type Seg<'a> = Primitive<'a, SegWeight>;
|
type Seg<'a> = Primitive<'a, SegWeight>;
|
||||||
type Bend<'a> = Primitive<'a, BendWeight>;
|
type Bend<'a> = Primitive<'a, BendWeight>;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use geo::{Point, EuclideanDistance};
|
use geo::{Point, EuclideanDistance};
|
||||||
use rstar::{RTreeObject, AABB};
|
use rstar::{RTreeObject, AABB};
|
||||||
|
|
||||||
use crate::{weight::{TaggedWeight, DotWeight}, math::Circle};
|
use crate::graph::{TaggedWeight, DotWeight};
|
||||||
|
use crate::math::Circle;
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct Shape {
|
pub struct Shape {
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,2 @@
|
||||||
use enum_as_inner::EnumAsInner;
|
use enum_as_inner::EnumAsInner;
|
||||||
use crate::math::Circle;
|
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