From 5b2e42149379a5e0fe56c8c84333d08f0318b1d2 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 27 Oct 2023 09:30:08 +0000 Subject: [PATCH] graph,primitive: Implement new `GetWidth` trait --- src/graph.rs | 37 ++++++++++++++++++++++++++++---- src/primitive.rs | 56 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/src/graph.rs b/src/graph.rs index b91142d..228d0f4 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -5,15 +5,15 @@ use std::marker::PhantomData; use crate::{ math::Circle, - primitive::{GenericPrimitive, Primitive}, + primitive::{GenericPrimitive, GetWeight, Primitive}, }; pub trait Interior { fn interior(&self) -> Vec; } -pub trait GetEnds { - fn ends(&self) -> (Start, Stop); +pub trait GetEnds { + fn ends(&self) -> (F, T); } #[enum_dispatch] @@ -26,6 +26,11 @@ pub trait GetNet { fn net(&self) -> i64; } +#[enum_dispatch] +pub trait GetWidth { + fn width(&self) -> f64; +} + macro_rules! impl_type { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { impl Retag for $weight_struct { @@ -137,7 +142,7 @@ impl From for Index { } } -pub trait DotWeight: GetNet + Into + Copy {} +pub trait DotWeight: GetNet + GetWidth + Into + Copy {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedDotWeight { @@ -148,6 +153,12 @@ pub struct FixedDotWeight { impl_type!(FixedDotWeight, FixedDot, FixedDotIndex); impl DotWeight for FixedDotWeight {} +impl GetWidth for FixedDotWeight { + fn width(&self) -> f64 { + self.circle.r * 2.0 + } +} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct LooseDotWeight { pub net: i64, @@ -157,6 +168,12 @@ pub struct LooseDotWeight { impl_type!(LooseDotWeight, LooseDot, LooseDotIndex); impl DotWeight for LooseDotWeight {} +impl GetWidth for LooseDotWeight { + fn width(&self) -> f64 { + self.circle.r * 2.0 + } +} + pub trait SegWeight: GetNet + Into + Copy {} #[derive(Debug, Clone, Copy, PartialEq)] @@ -168,6 +185,12 @@ pub struct FixedSegWeight { impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex); impl SegWeight for FixedSegWeight {} +impl GetWidth for FixedSegWeight { + fn width(&self) -> f64 { + self.width + } +} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct HalfLooseSegWeight { pub net: i64, @@ -196,6 +219,12 @@ pub struct FixedBendWeight { impl_type!(FixedBendWeight, FixedBend, FixedBendIndex); impl BendWeight for FixedBendWeight {} +impl GetWidth for FixedBendWeight { + fn width(&self) -> f64 { + self.width + } +} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct LooseBendWeight { pub net: i64, diff --git a/src/primitive.rs b/src/primitive.rs index 9badf9c..3b97e26 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -6,9 +6,9 @@ use petgraph::Direction::{Incoming, Outgoing}; use crate::graph::{ FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight, - FullyLooseSegWeight, GenericIndex, GetEnds, GetNet, GetNodeIndex, HalfLooseSegWeight, Index, - Interior, Label, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, MakePrimitive, - Retag, Weight, + FullyLooseSegWeight, GenericIndex, GetEnds, GetNet, GetNodeIndex, GetWidth, HalfLooseSegWeight, + Index, Interior, Label, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, + MakePrimitive, Retag, Weight, }; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; @@ -38,7 +38,14 @@ pub trait MakeShape { fn shape(&self) -> Shape; } -#[enum_dispatch(GetNet, GetGraph, GetConnectable, TaggedPrevTaggedNext, MakeShape)] +#[enum_dispatch( + GetNet, + GetWidth, + GetGraph, + GetConnectable, + TaggedPrevTaggedNext, + MakeShape +)] pub enum Primitive<'a> { FixedDot(FixedDot<'a>), LooseDot(LooseDot<'a>), @@ -131,6 +138,15 @@ where } } +impl<'a, W: GetWidth> GetWidth for GenericPrimitive<'a, W> +where + GenericPrimitive<'a, W>: GetWeight, +{ + fn width(&self) -> f64 { + self.weight().width() + } +} + pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; impl<'a> FixedDot<'a> { @@ -241,7 +257,7 @@ impl<'a> MakeShape for FixedSeg<'a> { Shape::Seg(SegShape { from: self.primitive(ends.0).weight().circle.pos, to: self.primitive(ends.1).weight().circle.pos, - width: self.weight().width, + width: self.width(), }) } } @@ -267,11 +283,17 @@ impl<'a> MakeShape for HalfLooseSeg<'a> { Shape::Seg(SegShape { from: self.primitive(ends.0).weight().circle.pos, to: self.primitive(ends.1).weight().circle.pos, - width: self.primitive(ends.1).weight().circle.r * 2.0, + width: self.width(), }) } } +impl<'a> GetWidth for HalfLooseSeg<'a> { + fn width(&self) -> f64 { + self.primitive(self.ends().1).weight().width() + } +} + impl<'a> GetEnds for HalfLooseSeg<'a> { fn ends(&self) -> (FixedDotIndex, LooseDotIndex) { let v = self.adjacents(); @@ -293,11 +315,17 @@ impl<'a> MakeShape for FullyLooseSeg<'a> { Shape::Seg(SegShape { from: self.primitive(ends.0).weight().circle.pos, to: self.primitive(ends.1).weight().circle.pos, - width: self.primitive(ends.1).weight().circle.r * 2.0, + width: self.width(), }) } } +impl<'a> GetWidth for FullyLooseSeg<'a> { + fn width(&self) -> f64 { + self.primitive(self.ends().1).weight().width() + } +} + impl<'a> GetEnds for FullyLooseSeg<'a> { fn ends(&self) -> (LooseDotIndex, LooseDotIndex) { let v = self.adjacents(); @@ -355,7 +383,7 @@ impl<'a> FixedBend<'a> { let mut layer = FixedBendIndex::new(self.index.node_index()); while let Some(inner) = self.primitive(layer).inner() { - r += self.primitive(inner).shape().width(); + r += self.primitive(inner).width(); layer = inner; } @@ -397,7 +425,7 @@ impl<'a> MakeShape for FixedBend<'a> { pos: self.primitive(self.core().unwrap()).weight().circle.pos, r: self.inner_radius(), }, - width: self.primitive(ends.0).weight().circle.r * 2.0, + width: self.width(), }; if self.weight().cw { @@ -435,7 +463,7 @@ impl<'a> LooseBend<'a> { let mut layer = LooseBendIndex::new(self.index.node_index()); while let Some(inner) = self.primitive(layer).inner() { - r += self.primitive(inner).shape().width(); + r += self.primitive(inner).width(); layer = inner; } @@ -469,7 +497,7 @@ impl<'a> MakeShape for LooseBend<'a> { pos: self.primitive(self.core().unwrap()).weight().circle.pos, r: self.inner_radius(), }, - width: self.primitive(ends.0).weight().circle.r * 2.0, + width: self.width(), }; if self.weight().cw { @@ -479,6 +507,12 @@ impl<'a> MakeShape for LooseBend<'a> { } } +impl<'a> GetWidth for LooseBend<'a> { + fn width(&self) -> f64 { + self.primitive(self.ends().1).weight().width() + } +} + impl<'a> GetEnds for LooseBend<'a> { fn ends(&self) -> (LooseDotIndex, LooseDotIndex) { let v = self.adjacents();