From 925448802aa53b38fb0220f26c5c10ea1071dd1a Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 22 Jul 2023 20:55:25 +0200 Subject: [PATCH] Create a new `Set` trait for collections of node indices --- src/graph.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++ src/layout.rs | 28 ++---------- src/main.rs | 9 ++-- src/mesh.rs | 105 +++++++++++++------------------------------ src/primitive.rs | 24 +++++++++- src/shape.rs | 3 +- src/weight.rs | 32 ------------- 7 files changed, 177 insertions(+), 138 deletions(-) create mode 100644 src/graph.rs diff --git a/src/graph.rs b/src/graph.rs new file mode 100644 index 0000000..db6109e --- /dev/null +++ b/src/graph.rs @@ -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; + fn closure(&self) -> Vec; + fn boundary(&self) -> Vec; +} + +#[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 { + pub index: NodeIndex, + marker: PhantomData, +} + +impl Index { + pub fn new(index: NodeIndex) -> 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; + +impl Tag for DotIndex { + fn tag(&self) -> TaggedIndex { + TaggedIndex::Dot(*self) + } +} + +pub type SegIndex = Index; + +impl Tag for SegIndex { + fn tag(&self) -> TaggedIndex { + TaggedIndex::Seg(*self) + } +} + +pub type BendIndex = Index; + +impl Tag for BendIndex { + fn tag(&self) -> TaggedIndex { + TaggedIndex::Bend(*self) + } +} diff --git a/src/layout.rs b/src/layout.rs index 6366a8e..6f03b5c 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -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::>()[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 } diff --git a/src/main.rs b/src/main.rs index ff3d746..76ce854 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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() { diff --git a/src/mesh.rs b/src/mesh.rs index 9e5dea2..8d578ea 100644 --- a/src/mesh.rs +++ b/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 { - pub index: NodeIndex, - marker: PhantomData, -} - -impl Index { - pub fn new(index: NodeIndex) -> 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; - -impl Tag for DotIndex { - fn tag(&self) -> TaggedIndex { - TaggedIndex::Dot(*self) - } -} - -pub type SegIndex = Index; - -impl Tag for SegIndex { - fn tag(&self) -> TaggedIndex { - TaggedIndex::Seg(*self) - } -} - -pub type BendIndex = Index; - -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; @@ -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 + '_ { self.rtree.iter().map(|wrapper| wrapper.data) } @@ -165,7 +116,13 @@ impl Mesh { Primitive::new(index, &self.graph) } - /*fn insert_into_rtree(&mut self, index: Index) { - 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)); + } } diff --git a/src/primitive.rs b/src/primitive.rs index cbe1e86..8f21d6a 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -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 { + vec![self.tagged_index()] + } + + fn closure(&self) -> Vec { + let ends: Vec = self.ends() + .into_iter() + .map(|end| TaggedIndex::Dot(end)) + .collect(); + [[self.tagged_index()].as_slice(), ends.as_slice()].concat() + } + + fn boundary(&self) -> Vec { + self.ends() + } +} + type Dot<'a> = Primitive<'a, DotWeight>; type Seg<'a> = Primitive<'a, SegWeight>; type Bend<'a> = Primitive<'a, BendWeight>; diff --git a/src/shape.rs b/src/shape.rs index 5ab0ce5..85b3bf0 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -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 { diff --git a/src/weight.rs b/src/weight.rs index 4f99816..03380fd 100644 --- a/src/weight.rs +++ b/src/weight.rs @@ -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, -}