diff --git a/src/draw.rs b/src/draw.rs index cfbbbf3..a26de36 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -11,7 +11,7 @@ use crate::{ primitive::GetOtherJoint, seg::{LoneLooseSegWeight, SeqLooseSegWeight}, }, - layout::{Infringement, Layout, LayoutException}, + layout::{rules::RulesTrait, Infringement, Layout, LayoutException}, math::{Circle, NoTangents}, rules::{Conditions, Rules}, wraparoundable::WraparoundableIndex, @@ -29,13 +29,13 @@ pub enum DrawException { CannotWrapAround(WraparoundableIndex, LayoutException, LayoutException), } -pub struct Draw<'a> { - layout: &'a mut Layout, +pub struct Draw<'a, R: RulesTrait> { + layout: &'a mut Layout, rules: &'a Rules, } -impl<'a> Draw<'a> { - pub fn new(layout: &'a mut Layout, rules: &'a Rules) -> Self { +impl<'a, R: RulesTrait> Draw<'a, R> { + pub fn new(layout: &'a mut Layout, rules: &'a Rules) -> Self { Self { layout, rules } } @@ -95,6 +95,7 @@ impl<'a> Draw<'a> { head: Head, around: FixedDotIndex, width: f64, + offset: f64, ) -> Result { let mut tangents = self.guide(&Default::default()).head_around_dot_segments( &head, @@ -117,6 +118,7 @@ impl<'a> Draw<'a> { tangent.start_point(), tangent.end_point(), dirs[i], + offset, width, ) { Ok(ok) => return Ok(ok), @@ -138,6 +140,7 @@ impl<'a> Draw<'a> { head: Head, around: BendIndex, width: f64, + offset: f64, ) -> Result { let mut tangents = self.guide(&Default::default()).head_around_bend_segments( &head, @@ -160,6 +163,7 @@ impl<'a> Draw<'a> { tangent.start_point(), tangent.end_point(), dirs[i], + offset, width, ) { Ok(ok) => return Ok(ok), @@ -184,9 +188,10 @@ impl<'a> Draw<'a> { to: Point, cw: bool, width: f64, + offset: f64, ) -> Result { let head = self.extend_head(head, from)?; - self.segbend(head, around, to, cw, width) + self.segbend(head, around, to, cw, offset, width) } #[debug_ensures(self.layout.node_count() == old(self.layout.node_count()))] @@ -208,6 +213,7 @@ impl<'a> Draw<'a> { to: Point, cw: bool, width: f64, + offset: f64, ) -> Result { let segbend = self.layout.insert_segbend( head.face(), @@ -221,12 +227,12 @@ impl<'a> Draw<'a> { }, SeqLooseSegWeight { band: head.band(), - width: 3.0, + width, }, LooseBendWeight { band: head.band(), - width: 3.0, - offset: 3.0, + width, + offset, cw, }, )?; @@ -250,7 +256,7 @@ impl<'a> Draw<'a> { Some(self.guide(&Default::default()).head(prev_dot, band)) } - fn guide(&'a self, conditions: &'a Conditions) -> Guide { - Guide::new(self.layout, self.rules, conditions) + fn guide(&'a self, conditions: &'a Conditions) -> Guide { + Guide::new(self.layout, conditions) } } diff --git a/src/layout/band.rs b/src/layout/band.rs index bff0bca..fcabed9 100644 --- a/src/layout/band.rs +++ b/src/layout/band.rs @@ -11,13 +11,15 @@ use crate::{ }, }; -pub struct Band<'a> { +use super::rules::RulesTrait; + +pub struct Band<'a, R: RulesTrait> { pub index: BandIndex, - layout: &'a Layout, + layout: &'a Layout, } -impl<'a> Band<'a> { - pub fn new(index: BandIndex, layout: &'a Layout) -> Self { +impl<'a, R: RulesTrait> Band<'a, R> { + pub fn new(index: BandIndex, layout: &'a Layout) -> Self { Self { index, layout } } @@ -85,7 +87,7 @@ impl<'a> Band<'a> { } } -impl<'a> GetNet for Band<'a> { +impl<'a, R: RulesTrait> GetNet for Band<'a, R> { fn net(&self) -> i64 { self.weight().net } diff --git a/src/layout/bend.rs b/src/layout/bend.rs index 75b6c48..d0298e7 100644 --- a/src/layout/bend.rs +++ b/src/layout/bend.rs @@ -10,6 +10,7 @@ use crate::{ MakePrimitive, Retag, }, primitive::{GenericPrimitive, Primitive}, + rules::RulesTrait, Layout, }, }; diff --git a/src/layout/dot.rs b/src/layout/dot.rs index 27ef41b..c673c03 100644 --- a/src/layout/dot.rs +++ b/src/layout/dot.rs @@ -13,6 +13,7 @@ use crate::{ MakePrimitive, Retag, }, primitive::{GenericPrimitive, Primitive}, + rules::RulesTrait, Layout, }, math::Circle, diff --git a/src/layout/graph.rs b/src/layout/graph.rs index 9b63e70..b58439b 100644 --- a/src/layout/graph.rs +++ b/src/layout/graph.rs @@ -14,6 +14,7 @@ use super::{ bend::{FixedBendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight}, dot::{FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, primitive::Primitive, + rules::RulesTrait, seg::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight, @@ -40,7 +41,7 @@ pub trait GetBandIndex { #[enum_dispatch] pub trait MakePrimitive { - fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a>; + fn primitive<'a, R: RulesTrait>(&self, layout: &'a Layout) -> Primitive<'a, R>; } macro_rules! impl_weight { @@ -54,7 +55,7 @@ macro_rules! impl_weight { pub type $index_struct = GenericIndex<$weight_struct>; impl MakePrimitive for $index_struct { - fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a> { + fn primitive<'a, R: RulesTrait>(&self, layout: &'a Layout) -> Primitive<'a, R> { Primitive::$weight_variant(GenericPrimitive::new(*self, layout)) } } diff --git a/src/layout/guide.rs b/src/layout/guide.rs index 77168cd..b57708b 100644 --- a/src/layout/guide.rs +++ b/src/layout/guide.rs @@ -15,7 +15,7 @@ use crate::{ rules::{Conditions, Rules}, }; -use super::segbend::Segbend; +use super::{rules::RulesTrait, segbend::Segbend}; #[enum_dispatch] pub trait HeadTrait { @@ -63,19 +63,14 @@ impl HeadTrait for SegbendHead { } } -pub struct Guide<'a, 'b> { - layout: &'a Layout, - rules: &'a Rules, +pub struct Guide<'a, 'b, R: RulesTrait> { + layout: &'a Layout, conditions: &'b Conditions, } -impl<'a, 'b> Guide<'a, 'b> { - pub fn new(layout: &'a Layout, rules: &'a Rules, conditions: &'b Conditions) -> Self { - Self { - layout, - rules, - conditions, - } +impl<'a, 'b, R: RulesTrait> Guide<'a, 'b, R> { + pub fn new(layout: &'a Layout, conditions: &'b Conditions) -> Self { + Self { layout, conditions } } pub fn head_into_dot_segment( diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 65efe93..5b4d8e9 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -14,6 +14,7 @@ use super::connectivity::{ }; use super::geometry::with_rtree::GeometryWithRtree; use super::loose::{GetNextLoose, Loose, LooseIndex}; +use super::rules::RulesTrait; use super::segbend::Segbend; use crate::graph::{GenericIndex, GetNodeIndex}; use crate::layout::bend::BendIndex; @@ -28,8 +29,7 @@ use crate::layout::{ geometry::shape::{Shape, ShapeTrait}, graph::{GeometryIndex, GeometryWeight, GetComponentIndex, MakePrimitive}, primitive::{ - GenericPrimitive, GetConnectable, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, - GetWeight, MakeShape, + GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, GetWeight, MakeShape, }, seg::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, @@ -69,8 +69,7 @@ pub struct Collision(pub Shape, pub GeometryIndex); pub struct AlreadyConnected(pub i64, pub GeometryIndex); #[derive(Debug)] -pub struct Layout { - connectivity: ConnectivityGraph, +pub struct Layout { geometry_with_rtree: GeometryWithRtree< GeometryWeight, DotWeight, @@ -81,13 +80,16 @@ pub struct Layout { SegIndex, BendIndex, >, + connectivity: ConnectivityGraph, + rules: R, } -impl Layout { - pub fn new() -> Self { - Layout { - connectivity: StableDiGraph::default(), +impl Layout { + pub fn new(rules: R) -> Self { + Self { geometry_with_rtree: GeometryWithRtree::new(), + connectivity: StableDiGraph::default(), + rules, } } @@ -411,9 +413,8 @@ impl Layout { let cw = primitive.weight().cw; let ends = primitive.joints(); - let rules = Default::default(); let conditions = Default::default(); - let guide = Guide::new(self, &rules, &conditions); + let guide = Guide::new(self, &conditions); let from_head = guide.rear_head(ends.1); let to_head = guide.rear_head(ends.0); @@ -717,10 +718,6 @@ impl Layout { self.geometry_with_rtree.flip_bend(bend.into()); } - /*pub fn bow(&self, bend: LooseBendIndex) -> Bow { - Bow::from_bend(bend, &self.graph) - }*/ - pub fn segbend(&self, dot: LooseDotIndex) -> Segbend { Segbend::from_dot(dot, self) } @@ -769,7 +766,7 @@ impl Layout { } } -impl Layout { +impl Layout { #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), Infringement> { @@ -815,10 +812,7 @@ impl Layout { self.geometry_with_rtree .rtree() .locate_in_envelope_intersecting(&RTreeObject::envelope(&shape)) - .filter(|wrapper| { - let other_index = wrapper.data; - !node.primitive(self).connectable(other_index) - }) + .filter(|wrapper| !self.are_connectable(node, wrapper.data)) .filter(|wrapper| !except.contains(&wrapper.data)) .filter(|wrapper| shape.intersects(wrapper.geom())) .map(|wrapper| wrapper.data) @@ -835,18 +829,24 @@ impl Layout { self.geometry_with_rtree .rtree() .locate_in_envelope_intersecting(&RTreeObject::envelope(&shape)) - .filter(|wrapper| { - let other_index = wrapper.data; - !node.primitive(self).connectable(other_index) - }) + .filter(|wrapper| !self.are_connectable(node, wrapper.data)) .filter(|wrapper| shape.intersects(wrapper.geom())) .map(|wrapper| wrapper.data) .next() .and_then(|collidee| Some(Collision(shape, collidee))) } + + #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] + #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] + fn are_connectable(&self, node1: GeometryIndex, node2: GeometryIndex) -> bool { + let node1_net = node1.primitive(self).net(); + let node2_net = node2.primitive(self).net(); + + (node1_net == node2_net) || node1_net == -1 || node2_net == -2 + } } -impl Layout { +impl Layout { #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] pub fn connectivity(&self) -> &ConnectivityGraph { @@ -872,25 +872,31 @@ impl Layout { #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - pub fn primitive(&self, index: GenericIndex) -> GenericPrimitive { + pub fn rules(&self) -> &R { + &self.rules + } + + #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] + #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] + pub fn primitive(&self, index: GenericIndex) -> GenericPrimitive { GenericPrimitive::new(index, self) } #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable { + pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable { Wraparoundable::new(index, self) } #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - pub fn loose(&self, index: LooseIndex) -> Loose { + pub fn loose(&self, index: LooseIndex) -> Loose { Loose::new(index, self) } #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - pub fn band(&self, index: BandIndex) -> Band { + pub fn band(&self, index: BandIndex) -> Band { Band::new(index, self) } } diff --git a/src/layout/loose.rs b/src/layout/loose.rs index bd8f684..623adad 100644 --- a/src/layout/loose.rs +++ b/src/layout/loose.rs @@ -13,6 +13,8 @@ use crate::{ }, }; +use super::rules::RulesTrait; + #[enum_dispatch] pub trait GetNextLoose { fn next_loose(&self, maybe_prev: Option) -> Option; @@ -39,15 +41,15 @@ impl From for GeometryIndex { } #[enum_dispatch(GetNextLoose, GetLayout, GetNodeIndex)] -pub enum Loose<'a> { - Dot(LooseDot<'a>), - LoneSeg(LoneLooseSeg<'a>), - SeqSeg(SeqLooseSeg<'a>), - Bend(LooseBend<'a>), +pub enum Loose<'a, R: RulesTrait> { + Dot(LooseDot<'a, R>), + LoneSeg(LoneLooseSeg<'a, R>), + SeqSeg(SeqLooseSeg<'a, R>), + Bend(LooseBend<'a, R>), } -impl<'a> Loose<'a> { - pub fn new(index: LooseIndex, layout: &'a Layout) -> Self { +impl<'a, R: RulesTrait> Loose<'a, R> { + pub fn new(index: LooseIndex, layout: &'a Layout) -> Self { match index { LooseIndex::Dot(dot) => layout.primitive(dot).into(), LooseIndex::LoneSeg(seg) => layout.primitive(seg).into(), @@ -57,7 +59,7 @@ impl<'a> Loose<'a> { } } -impl<'a> GetNextLoose for LooseDot<'a> { +impl<'a, R: RulesTrait> GetNextLoose for LooseDot<'a, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let bend = self.bend(); let Some(prev) = maybe_prev else { @@ -72,13 +74,13 @@ impl<'a> GetNextLoose for LooseDot<'a> { } } -impl<'a> GetNextLoose for LoneLooseSeg<'a> { +impl<'a, R: RulesTrait> GetNextLoose for LoneLooseSeg<'a, R> { fn next_loose(&self, _maybe_prev: Option) -> Option { None } } -impl<'a> GetNextLoose for SeqLooseSeg<'a> { +impl<'a, R: RulesTrait> GetNextLoose for SeqLooseSeg<'a, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let ends = self.joints(); let Some(prev) = maybe_prev else { @@ -96,7 +98,7 @@ impl<'a> GetNextLoose for SeqLooseSeg<'a> { } } -impl<'a> GetNextLoose for LooseBend<'a> { +impl<'a, R: RulesTrait> GetNextLoose for LooseBend<'a, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let ends = self.joints(); let Some(prev) = maybe_prev else { diff --git a/src/layout/mod.rs b/src/layout/mod.rs index c960acc..f8d1766 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -9,6 +9,7 @@ pub mod guide; mod layout; pub mod loose; pub mod primitive; +pub mod rules; pub mod seg; pub mod segbend; diff --git a/src/layout/primitive.rs b/src/layout/primitive.rs index 4d6a319..347a70a 100644 --- a/src/layout/primitive.rs +++ b/src/layout/primitive.rs @@ -20,19 +20,11 @@ use crate::layout::{ Layout, }; -#[enum_dispatch] -pub trait GetLayout { - fn layout(&self) -> &Layout; -} +use super::rules::RulesTrait; #[enum_dispatch] -pub trait GetConnectable: GetNet + GetLayout { - fn connectable(&self, node: GeometryIndex) -> bool { - let this = self.net(); - let other = node.primitive(self.layout()).net(); - - (this == other) || this == -1 || other == -1 - } +pub trait GetLayout<'a, R: RulesTrait> { + fn layout(&self) -> &Layout; } #[enum_dispatch] @@ -82,7 +74,7 @@ pub trait GetJoints { fn joints(&self) -> (F, T); } -pub trait GetFirstRail: GetLayout + GetNodeIndex { +pub trait GetFirstRail<'a, R: RulesTrait>: GetLayout<'a, R> + GetNodeIndex { fn first_rail(&self) -> Option { self.layout() .geometry() @@ -95,7 +87,7 @@ pub trait GetBendIndex { fn bend_index(&self) -> BendIndex; } -pub trait GetCore: GetLayout + GetBendIndex { +pub trait GetCore<'a, R: RulesTrait>: GetLayout<'a, R> + GetBendIndex { fn core(&self) -> FixedDotIndex { FixedDotIndex::new( self.layout() @@ -106,7 +98,7 @@ pub trait GetCore: GetLayout + GetBendIndex { } } -pub trait GetInnerOuter: GetLayout + GetBendIndex { +pub trait GetInnerOuter<'a, R: RulesTrait>: GetLayout<'a, R> + GetBendIndex { fn inner(&self) -> Option { self.layout() .geometry() @@ -124,7 +116,7 @@ pub trait GetInnerOuter: GetLayout + GetBendIndex { macro_rules! impl_primitive { ($primitive_struct:ident, $weight_struct:ident) => { - impl<'a> GetWeight<$weight_struct> for $primitive_struct<'a> { + impl<'a, R: RulesTrait> GetWeight<$weight_struct> for $primitive_struct<'a, R> { fn weight(&self) -> $weight_struct { if let GeometryWeight::$primitive_struct(weight) = self.tagged_weight() { weight @@ -140,13 +132,13 @@ macro_rules! impl_fixed_primitive { ($primitive_struct:ident, $weight_struct:ident) => { impl_primitive!($primitive_struct, $weight_struct); - impl<'a> GetComponentIndex for $primitive_struct<'a> { + impl<'a, R: RulesTrait> GetComponentIndex for $primitive_struct<'a, R> { fn component(&self) -> ComponentIndex { self.weight().component() } } - impl<'a> GetNet for $primitive_struct<'a> { + impl<'a, R: RulesTrait> GetNet for $primitive_struct<'a, R> { fn net(&self) -> i64 { self.layout() .connectivity() @@ -162,7 +154,7 @@ macro_rules! impl_loose_primitive { ($primitive_struct:ident, $weight_struct:ident) => { impl_primitive!($primitive_struct, $weight_struct); - impl<'a> GetNet for $primitive_struct<'a> { + impl<'a, R: RulesTrait> GetNet for $primitive_struct<'a, R> { fn net(&self) -> i64 { self.layout() .connectivity() @@ -174,25 +166,25 @@ macro_rules! impl_loose_primitive { }; } -#[enum_dispatch(GetNet, GetWidth, GetLayout, GetConnectable, MakeShape, GetLimbs)] -pub enum Primitive<'a> { - FixedDot(FixedDot<'a>), - LooseDot(LooseDot<'a>), - FixedSeg(FixedSeg<'a>), - LoneLooseSeg(LoneLooseSeg<'a>), - SeqLooseSeg(SeqLooseSeg<'a>), - FixedBend(FixedBend<'a>), - LooseBend(LooseBend<'a>), +#[enum_dispatch(GetNet, GetWidth, GetLayout, MakeShape, GetLimbs)] +pub enum Primitive<'a, R: RulesTrait> { + FixedDot(FixedDot<'a, R>), + LooseDot(LooseDot<'a, R>), + FixedSeg(FixedSeg<'a, R>), + LoneLooseSeg(LoneLooseSeg<'a, R>), + SeqLooseSeg(SeqLooseSeg<'a, R>), + FixedBend(FixedBend<'a, R>), + LooseBend(LooseBend<'a, R>), } #[derive(Debug)] -pub struct GenericPrimitive<'a, W> { +pub struct GenericPrimitive<'a, W, R: RulesTrait> { pub index: GenericIndex, - layout: &'a Layout, + layout: &'a Layout, } -impl<'a, W> GenericPrimitive<'a, W> { - pub fn new(index: GenericIndex, layout: &'a Layout) -> Self { +impl<'a, W, R: RulesTrait> GenericPrimitive<'a, W, R> { + pub fn new(index: GenericIndex, layout: &'a Layout) -> Self { Self { index, layout } } @@ -205,44 +197,42 @@ impl<'a, W> GenericPrimitive<'a, W> { .unwrap() } - fn primitive(&self, index: GenericIndex) -> GenericPrimitive { + fn primitive(&self, index: GenericIndex) -> GenericPrimitive { GenericPrimitive::new(index, &self.layout) } } -impl<'a, W> GetInterior for GenericPrimitive<'a, W> { +impl<'a, W, R: RulesTrait> GetInterior for GenericPrimitive<'a, W, R> { fn interior(&self) -> Vec { vec![self.tagged_weight().retag(self.index.node_index())] } } -impl<'a, W> GetLayout for GenericPrimitive<'a, W> { - fn layout(&self) -> &Layout { +impl<'a, W, R: RulesTrait> GetLayout<'a, R> for GenericPrimitive<'a, W, R> { + fn layout(&self) -> &Layout { self.layout } } -impl<'a, W> GetNodeIndex for GenericPrimitive<'a, W> { +impl<'a, W, R: RulesTrait> GetNodeIndex for GenericPrimitive<'a, W, R> { fn node_index(&self) -> NodeIndex { self.index.node_index() } } -impl<'a, W> GetConnectable for GenericPrimitive<'a, W> where GenericPrimitive<'a, W>: GetNet {} - -impl<'a, W: GetWidth> GetWidth for GenericPrimitive<'a, W> +impl<'a, W: GetWidth, R: RulesTrait> GetWidth for GenericPrimitive<'a, W, R> where - GenericPrimitive<'a, W>: GetWeight, + GenericPrimitive<'a, W, R>: GetWeight, { fn width(&self) -> f64 { self.weight().width() } } -pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; +pub type FixedDot<'a, R> = GenericPrimitive<'a, FixedDotWeight, R>; impl_fixed_primitive!(FixedDot, FixedDotWeight); -impl<'a> FixedDot<'a> { +impl<'a, R: RulesTrait> FixedDot<'a, R> { pub fn first_loose(&self, _band: BandIndex) -> Option { self.layout .geometry() @@ -266,13 +256,13 @@ impl<'a> FixedDot<'a> { } } -impl<'a> MakeShape for FixedDot<'a> { +impl<'a, R: RulesTrait> MakeShape for FixedDot<'a, R> { fn shape(&self) -> Shape { self.layout.geometry().dot_shape(self.index.into()) } } -impl<'a> GetLimbs for FixedDot<'a> { +impl<'a, R: RulesTrait> GetLimbs for FixedDot<'a, R> { fn segs(&self) -> Vec { self.layout .geometry() @@ -288,12 +278,12 @@ impl<'a> GetLimbs for FixedDot<'a> { } } -impl<'a> GetFirstRail for FixedDot<'a> {} +impl<'a, R: RulesTrait> GetFirstRail<'a, R> for FixedDot<'a, R> {} -pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; +pub type LooseDot<'a, R> = GenericPrimitive<'a, LooseDotWeight, R>; impl_loose_primitive!(LooseDot, LooseDotWeight); -impl<'a> LooseDot<'a> { +impl<'a, R: RulesTrait> LooseDot<'a, R> { pub fn seg(&self) -> Option { self.layout .geometry() @@ -312,13 +302,13 @@ impl<'a> LooseDot<'a> { } } -impl<'a> MakeShape for LooseDot<'a> { +impl<'a, R: RulesTrait> MakeShape for LooseDot<'a, R> { fn shape(&self) -> Shape { self.layout.geometry().dot_shape(self.index.into()) } } -impl<'a> GetLimbs for LooseDot<'a> { +impl<'a, R: RulesTrait> GetLimbs for LooseDot<'a, R> { fn segs(&self) -> Vec { if let Some(seg) = self.seg() { vec![seg.into()] @@ -332,18 +322,18 @@ impl<'a> GetLimbs for LooseDot<'a> { } } -pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>; +pub type FixedSeg<'a, R> = GenericPrimitive<'a, FixedSegWeight, R>; impl_fixed_primitive!(FixedSeg, FixedSegWeight); -impl<'a> MakeShape for FixedSeg<'a> { +impl<'a, R: RulesTrait> MakeShape for FixedSeg<'a, R> { fn shape(&self) -> Shape { self.layout.geometry().seg_shape(self.index.into()) } } -impl<'a> GetLimbs for FixedSeg<'a> {} +impl<'a, R: RulesTrait> GetLimbs for FixedSeg<'a, R> {} -impl<'a> GetJoints for FixedSeg<'a> { +impl<'a, R: RulesTrait> GetJoints for FixedSeg<'a, R> { fn joints(&self) -> (FixedDotIndex, FixedDotIndex) { let (from, to) = self.layout.geometry().seg_joints(self.index.into()); ( @@ -353,20 +343,20 @@ impl<'a> GetJoints for FixedSeg<'a> { } } -impl<'a> GetOtherJoint for FixedSeg<'a> {} +impl<'a, R: RulesTrait> GetOtherJoint for FixedSeg<'a, R> {} -pub type LoneLooseSeg<'a> = GenericPrimitive<'a, LoneLooseSegWeight>; +pub type LoneLooseSeg<'a, R> = GenericPrimitive<'a, LoneLooseSegWeight, R>; impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight); -impl<'a> MakeShape for LoneLooseSeg<'a> { +impl<'a, R: RulesTrait> MakeShape for LoneLooseSeg<'a, R> { fn shape(&self) -> Shape { self.layout.geometry().seg_shape(self.index.into()) } } -impl<'a> GetLimbs for LoneLooseSeg<'a> {} +impl<'a, R: RulesTrait> GetLimbs for LoneLooseSeg<'a, R> {} -impl<'a> GetJoints for LoneLooseSeg<'a> { +impl<'a, R: RulesTrait> GetJoints for LoneLooseSeg<'a, R> { fn joints(&self) -> (FixedDotIndex, FixedDotIndex) { let (from, to) = self.layout.geometry().seg_joints(self.index.into()); ( @@ -376,20 +366,20 @@ impl<'a> GetJoints for LoneLooseSeg<'a> { } } -impl<'a> GetOtherJoint for LoneLooseSeg<'a> {} +impl<'a, R: RulesTrait> GetOtherJoint for LoneLooseSeg<'a, R> {} -pub type SeqLooseSeg<'a> = GenericPrimitive<'a, SeqLooseSegWeight>; +pub type SeqLooseSeg<'a, R> = GenericPrimitive<'a, SeqLooseSegWeight, R>; impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight); -impl<'a> MakeShape for SeqLooseSeg<'a> { +impl<'a, R: RulesTrait> MakeShape for SeqLooseSeg<'a, R> { fn shape(&self) -> Shape { self.layout.geometry().seg_shape(self.index.into()) } } -impl<'a> GetLimbs for SeqLooseSeg<'a> {} +impl<'a, R: RulesTrait> GetLimbs for SeqLooseSeg<'a, R> {} -impl<'a> GetJoints for SeqLooseSeg<'a> { +impl<'a, R: RulesTrait> GetJoints for SeqLooseSeg<'a, R> { fn joints(&self) -> (DotIndex, LooseDotIndex) { let joints = self.layout.geometry().seg_joints(self.index.into()); if let DotWeight::Fixed(..) = self.layout.geometry().dot_weight(joints.0) { @@ -411,26 +401,26 @@ impl<'a> GetJoints for SeqLooseSeg<'a> { } } -impl<'a> GetOtherJoint for SeqLooseSeg<'a> {} +impl<'a, R: RulesTrait> GetOtherJoint for SeqLooseSeg<'a, R> {} -pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; +pub type FixedBend<'a, R> = GenericPrimitive<'a, FixedBendWeight, R>; impl_fixed_primitive!(FixedBend, FixedBendWeight); -impl<'a> GetBendIndex for FixedBend<'a> { +impl<'a, R: RulesTrait> GetBendIndex for FixedBend<'a, R> { fn bend_index(&self) -> BendIndex { self.index.into() } } -impl<'a> MakeShape for FixedBend<'a> { +impl<'a, R: RulesTrait> MakeShape for FixedBend<'a, R> { fn shape(&self) -> Shape { self.layout.geometry().bend_shape(self.index.into()) } } -impl<'a> GetLimbs for FixedBend<'a> {} +impl<'a, R: RulesTrait> GetLimbs for FixedBend<'a, R> {} -impl<'a> GetJoints for FixedBend<'a> { +impl<'a, R: RulesTrait> GetJoints for FixedBend<'a, R> { fn joints(&self) -> (FixedDotIndex, FixedDotIndex) { let (from, to) = self.layout.geometry().bend_joints(self.index.into()); ( @@ -440,41 +430,41 @@ impl<'a> GetJoints for FixedBend<'a> { } } -impl<'a> GetOtherJoint for FixedBend<'a> {} -impl<'a> GetFirstRail for FixedBend<'a> {} -impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actually. - //impl<'a> GetInnerOuter for FixedBend<'a> {} +impl<'a, R: RulesTrait> GetOtherJoint for FixedBend<'a, R> {} +impl<'a, R: RulesTrait> GetFirstRail<'a, R> for FixedBend<'a, R> {} +impl<'a, R: RulesTrait> GetCore<'a, R> for FixedBend<'a, R> {} // TODO: Fixed bends don't have cores actually. + //impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, R> {} -pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; +pub type LooseBend<'a, R> = GenericPrimitive<'a, LooseBendWeight, R>; impl_loose_primitive!(LooseBend, LooseBendWeight); -impl<'a> GetBendIndex for LooseBend<'a> { +impl<'a, R: RulesTrait> GetBendIndex for LooseBend<'a, R> { fn bend_index(&self) -> BendIndex { self.index.into() } } -impl<'a> From> for BendIndex { - fn from(bend: LooseBend<'a>) -> BendIndex { +impl<'a, R: RulesTrait> From> for BendIndex { + fn from(bend: LooseBend<'a, R>) -> BendIndex { bend.index.into() } } -impl<'a> MakeShape for LooseBend<'a> { +impl<'a, R: RulesTrait> MakeShape for LooseBend<'a, R> { fn shape(&self) -> Shape { self.layout.geometry().bend_shape(self.index.into()) } } -impl<'a> GetLimbs for LooseBend<'a> {} +impl<'a, R: RulesTrait> GetLimbs for LooseBend<'a, R> {} -impl<'a> GetOffset for LooseBend<'a> { +impl<'a, R: RulesTrait> GetOffset for LooseBend<'a, R> { fn offset(&self) -> f64 { self.weight().offset } } -impl<'a> GetJoints for LooseBend<'a> { +impl<'a, R: RulesTrait> GetJoints for LooseBend<'a, R> { fn joints(&self) -> (LooseDotIndex, LooseDotIndex) { let (from, to) = self.layout.geometry().bend_joints(self.index.into()); ( @@ -484,6 +474,6 @@ impl<'a> GetJoints for LooseBend<'a> { } } -impl<'a> GetOtherJoint for LooseBend<'a> {} -impl<'a> GetCore for LooseBend<'a> {} -impl<'a> GetInnerOuter for LooseBend<'a> {} +impl<'a, R: RulesTrait> GetOtherJoint for LooseBend<'a, R> {} +impl<'a, R: RulesTrait> GetCore<'a, R> for LooseBend<'a, R> {} +impl<'a, R: RulesTrait> GetInnerOuter<'a, R> for LooseBend<'a, R> {} diff --git a/src/layout/rules.rs b/src/layout/rules.rs new file mode 100644 index 0000000..0f27f97 --- /dev/null +++ b/src/layout/rules.rs @@ -0,0 +1,18 @@ +pub struct Conditions { + layer: Option, + region: Option, + netclass: Option, +} + +pub struct LayerNetclassConditions { + region: Option, +} + +pub trait RulesTrait { + fn clearance(conditions1: &Conditions, conditions2: &Conditions) -> f64; + fn clearance_limit( + layer: String, + netclass: String, + conditions: &LayerNetclassConditions, + ) -> f64; +} diff --git a/src/layout/seg.rs b/src/layout/seg.rs index 5eccfac..afc1bd3 100644 --- a/src/layout/seg.rs +++ b/src/layout/seg.rs @@ -10,6 +10,7 @@ use crate::{ MakePrimitive, Retag, }, primitive::{GenericPrimitive, Primitive}, + rules::RulesTrait, Layout, }, }; diff --git a/src/layout/segbend.rs b/src/layout/segbend.rs index 817b297..9beda1c 100644 --- a/src/layout/segbend.rs +++ b/src/layout/segbend.rs @@ -7,6 +7,8 @@ use crate::layout::{ Layout, }; +use super::rules::RulesTrait; + #[derive(Debug, Clone, Copy)] pub struct Segbend { pub seg: SeqLooseSegIndex, @@ -15,7 +17,7 @@ pub struct Segbend { } impl Segbend { - pub fn from_dot(dot: LooseDotIndex, layout: &Layout) -> Self { + pub fn from_dot(dot: LooseDotIndex, layout: &Layout) -> Self { let bend = LooseDot::new(dot, layout).bend(); let dot = LooseBend::new(bend, layout).other_joint(dot); let seg = LooseDot::new(dot, layout).seg().unwrap(); diff --git a/src/main.rs b/src/main.rs index 8b4895c..69f3f1a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,11 +28,12 @@ use layout::dot::FixedDotWeight; use layout::geometry::shape::{Shape, ShapeTrait}; use layout::graph::{GeometryIndex, MakePrimitive}; use layout::primitive::MakeShape; +use layout::rules::{Conditions, LayerNetclassConditions, RulesTrait}; use layout::seg::FixedSegWeight; use layout::{Infringement, Layout, LayoutException}; use mesh::{Mesh, MeshEdgeReference, VertexIndex}; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; -use router::RouterObserver; +use router::RouterObserverTrait; use sdl2::event::Event; use sdl2::keyboard::Keycode; @@ -57,26 +58,42 @@ use tracer::{Trace, Tracer}; use crate::math::Circle; use crate::router::Router; +struct ConstantClearance {} + +impl RulesTrait for ConstantClearance { + fn clearance(conditions1: &Conditions, conditions2: &Conditions) -> f64 { + 3.0 + } + + fn clearance_limit( + layer: String, + netclass: String, + conditions: &LayerNetclassConditions, + ) -> f64 { + 3.0 + } +} + // Clunky enum to work around borrow checker. -enum RouterOrLayout<'a> { - Router(&'a mut Router), - Layout(&'a Layout), +enum RouterOrLayout<'a, R: RulesTrait> { + Router(&'a mut Router), + Layout(&'a Layout), } struct EmptyRouterObserver; -impl RouterObserver for EmptyRouterObserver { - fn on_rework(&mut self, _tracer: &Tracer, _trace: &Trace) {} - fn before_probe(&mut self, _tracer: &Tracer, _trace: &Trace, _edge: MeshEdgeReference) {} +impl RouterObserverTrait for EmptyRouterObserver { + fn on_rework(&mut self, _tracer: &Tracer, _trace: &Trace) {} + fn before_probe(&mut self, _tracer: &Tracer, _trace: &Trace, _edge: MeshEdgeReference) {} fn on_probe( &mut self, - _tracer: &Tracer, + _tracer: &Tracer, _trace: &Trace, _edge: MeshEdgeReference, _result: Result<(), DrawException>, ) { } - fn on_estimate(&mut self, _tracer: &Tracer, _vertex: VertexIndex) {} + fn on_estimate(&mut self, _tracer: &Tracer, _vertex: VertexIndex) {} } struct DebugRouterObserver<'a> { @@ -102,8 +119,8 @@ impl<'a> DebugRouterObserver<'a> { } } -impl<'a> RouterObserver for DebugRouterObserver<'a> { - fn on_rework(&mut self, tracer: &Tracer, trace: &Trace) { +impl<'a, R: RulesTrait> RouterObserverTrait for DebugRouterObserver<'a> { + fn on_rework(&mut self, tracer: &Tracer, trace: &Trace) { render_times( self.event_pump, self.window, @@ -119,7 +136,7 @@ impl<'a> RouterObserver for DebugRouterObserver<'a> { ); } - fn before_probe(&mut self, tracer: &Tracer, trace: &Trace, edge: MeshEdgeReference) { + fn before_probe(&mut self, tracer: &Tracer, trace: &Trace, edge: MeshEdgeReference) { let mut path = trace.path.clone(); path.push(edge.target()); render_times( @@ -139,7 +156,7 @@ impl<'a> RouterObserver for DebugRouterObserver<'a> { fn on_probe( &mut self, - tracer: &Tracer, + tracer: &Tracer, trace: &Trace, _edge: MeshEdgeReference, result: Result<(), DrawException>, @@ -168,7 +185,7 @@ impl<'a> RouterObserver for DebugRouterObserver<'a> { ); } - fn on_estimate(&mut self, _tracer: &Tracer, _vertex: VertexIndex) {} + fn on_estimate(&mut self, _tracer: &Tracer, _vertex: VertexIndex) {} } fn main() -> Result<(), anyhow::Error> { @@ -218,7 +235,7 @@ fn main() -> Result<(), anyhow::Error> { let mut event_pump = sdl_context.event_pump().unwrap(); let _i = 0; - let mut router = Router::new(); + let mut router = Router::new(ConstantClearance {}); let component1_1 = router.layout.add_component(1); let component1_2 = router.layout.add_component(1); @@ -321,7 +338,7 @@ fn main() -> Result<(), anyhow::Error> { dot2_1, FixedSegWeight { component: component2, - width: 16.0, + width: 3.0, }, ); @@ -341,7 +358,7 @@ fn main() -> Result<(), anyhow::Error> { dot2_2, FixedSegWeight { component: component2, - width: 16.0, + width: 3.0, }, ); @@ -372,7 +389,7 @@ fn main() -> Result<(), anyhow::Error> { dot4, FixedSegWeight { component: component2, - width: 16.0, + width: 3.0, }, ); @@ -392,7 +409,7 @@ fn main() -> Result<(), anyhow::Error> { dot5, FixedSegWeight { component: component2, - width: 16.0, + width: 3.0, }, ); @@ -412,7 +429,7 @@ fn main() -> Result<(), anyhow::Error> { dot1_2, FixedSegWeight { component: component2, - width: 16.0, + width: 3.0, }, ); @@ -421,7 +438,7 @@ fn main() -> Result<(), anyhow::Error> { dot2_2, FixedSegWeight { component: component2, - width: 16.0, + width: 3.0, }, ); @@ -441,7 +458,7 @@ fn main() -> Result<(), anyhow::Error> { dot6, FixedSegWeight { component: component2, - width: 16.0, + width: 3.0, }, ); @@ -461,7 +478,7 @@ fn main() -> Result<(), anyhow::Error> { dot7, FixedSegWeight { net: 20, - width: 16.0, + width: 3.0, }, );*/ @@ -613,7 +630,7 @@ fn render_times( window: &Window, renderer: &mut Renderer, font_context: &CanvasFontContext, - mut router_or_layout: RouterOrLayout, + mut router_or_layout: RouterOrLayout, maybe_band: Option, mut maybe_mesh: Option, path: &[VertexIndex], diff --git a/src/mesh.rs b/src/mesh.rs index acd5198..6383112 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -7,6 +7,7 @@ use petgraph::visit::{self, NodeIndexable}; use petgraph::{stable_graph::NodeIndex, visit::EdgeRef}; use spade::{HasPosition, InsertionError, Point2}; +use crate::layout::rules::RulesTrait; use crate::triangulation::TriangulationEdgeReference; use crate::{ graph::GetNodeIndex, @@ -82,7 +83,7 @@ pub struct Mesh { } impl Mesh { - pub fn new(layout: &Layout) -> Self { + pub fn new(layout: &Layout) -> Self { let mut this = Self { triangulation: Triangulation::new(layout), vertex_to_triangulation_vertex: Vec::new(), @@ -92,7 +93,7 @@ impl Mesh { this } - pub fn generate(&mut self, layout: &Layout) -> Result<(), InsertionError> { + pub fn generate(&mut self, layout: &Layout) -> Result<(), InsertionError> { for node in layout.nodes() { let center = node.primitive(layout).shape().center(); diff --git a/src/router.rs b/src/router.rs index 3efa4b4..42d901e 100644 --- a/src/router.rs +++ b/src/router.rs @@ -7,6 +7,7 @@ use thiserror::Error; use crate::astar::{astar, AstarStrategy, PathTracker}; use crate::draw::DrawException; use crate::layout::guide::HeadTrait; +use crate::layout::rules::RulesTrait; use crate::layout::Layout; use crate::layout::{ connectivity::BandIndex, @@ -39,33 +40,38 @@ pub enum RoutingErrorKind { AStar, } -pub trait RouterObserver { - fn on_rework(&mut self, tracer: &Tracer, trace: &Trace); - fn before_probe(&mut self, tracer: &Tracer, trace: &Trace, edge: MeshEdgeReference); +pub trait RouterObserverTrait { + fn on_rework(&mut self, tracer: &Tracer, trace: &Trace); + fn before_probe(&mut self, tracer: &Tracer, trace: &Trace, edge: MeshEdgeReference); fn on_probe( &mut self, - tracer: &Tracer, + tracer: &Tracer, trace: &Trace, edge: MeshEdgeReference, result: Result<(), DrawException>, ); - fn on_estimate(&mut self, tracer: &Tracer, vertex: VertexIndex); + fn on_estimate(&mut self, tracer: &Tracer, vertex: VertexIndex); } -pub struct Router { - pub layout: Layout, +pub struct Router { + pub layout: Layout, rules: Rules, } -struct RouterAstarStrategy<'a, RO: RouterObserver> { - tracer: Tracer<'a>, +struct RouterAstarStrategy<'a, RO: RouterObserverTrait, R: RulesTrait> { + tracer: Tracer<'a, R>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO, } -impl<'a, RO: RouterObserver> RouterAstarStrategy<'a, RO> { - pub fn new(tracer: Tracer<'a>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self { +impl<'a, RO: RouterObserverTrait, R: RulesTrait> RouterAstarStrategy<'a, RO, R> { + pub fn new( + tracer: Tracer<'a, R>, + trace: Trace, + to: FixedDotIndex, + observer: &'a mut RO, + ) -> Self { Self { tracer, trace, @@ -75,7 +81,9 @@ impl<'a, RO: RouterObserver> RouterAstarStrategy<'a, RO> { } } -impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, f64> for RouterAstarStrategy<'a, RO> { +impl<'a, RO: RouterObserverTrait, R: RulesTrait> AstarStrategy<&Mesh, f64> + for RouterAstarStrategy<'a, RO, R> +{ fn is_goal(&mut self, vertex: VertexIndex, tracker: &PathTracker<&Mesh>) -> bool { let new_path = tracker.reconstruct_path_to(vertex); @@ -120,10 +128,10 @@ impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, f64> for RouterAstarStrategy<' } } -impl Router { - pub fn new() -> Self { +impl Router { + pub fn new(rules: R) -> Self { Router { - layout: Layout::new(), + layout: Layout::new(rules), rules: Rules::new(), } } @@ -132,7 +140,7 @@ impl Router { &mut self, from: FixedDotIndex, to: FixedDotIndex, - observer: &mut impl RouterObserver, + observer: &mut impl RouterObserverTrait, ) -> Result { // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look // right. @@ -166,7 +174,7 @@ impl Router { &mut self, band: BandIndex, to: Point, - observer: &mut impl RouterObserver, + observer: &mut impl RouterObserverTrait, ) -> Result { let from_dot = self.layout.band(band).from(); let to_dot = self.layout.band(band).to().unwrap(); @@ -175,7 +183,7 @@ impl Router { self.route_band(from_dot, to_dot, observer) } - pub fn tracer<'a>(&'a mut self, mesh: &'a Mesh) -> Tracer { + pub fn tracer<'a>(&'a mut self, mesh: &'a Mesh) -> Tracer { Tracer::new(&mut self.layout, &self.rules, mesh) } } diff --git a/src/tracer.rs b/src/tracer.rs index f09007f..e0ba5d4 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -6,6 +6,7 @@ use crate::{ bend::LooseBendIndex, dot::FixedDotIndex, guide::{BareHead, Head, SegbendHead}, + rules::RulesTrait, Layout, }, mesh::{Mesh, VertexIndex}, @@ -18,14 +19,14 @@ pub struct Trace { pub head: Head, } -pub struct Tracer<'a> { - pub layout: &'a mut Layout, +pub struct Tracer<'a, R: RulesTrait> { + pub layout: &'a mut Layout, pub rules: &'a Rules, pub mesh: &'a Mesh, } -impl<'a> Tracer<'a> { - pub fn new(layout: &'a mut Layout, rules: &'a Rules, mesh: &'a Mesh) -> Self { +impl<'a, R: RulesTrait> Tracer<'a, R> { + pub fn new(layout: &'a mut Layout, rules: &'a Rules, mesh: &'a Mesh) -> Self { Tracer { layout, rules, @@ -128,7 +129,9 @@ impl<'a> Tracer<'a> { around: FixedDotIndex, width: f64, ) -> Result { - let head = self.draw().segbend_around_dot(head, around.into(), width)?; + let head = self + .draw() + .segbend_around_dot(head, around.into(), width, 3.0)?; Ok(head) } @@ -140,7 +143,7 @@ impl<'a> Tracer<'a> { ) -> Result { let head = self .draw() - .segbend_around_bend(head, around.into(), width)?; + .segbend_around_bend(head, around.into(), width, 3.0)?; Ok(head) } @@ -156,7 +159,7 @@ impl<'a> Tracer<'a> { trace.path.pop(); } - fn draw(&mut self) -> Draw { + fn draw(&mut self) -> Draw { Draw::new(&mut self.layout, &self.rules) } } diff --git a/src/triangulation.rs b/src/triangulation.rs index 5bd710b..79d7dba 100644 --- a/src/triangulation.rs +++ b/src/triangulation.rs @@ -4,7 +4,10 @@ use geo::{point, Point}; use petgraph::visit::{self, NodeIndexable}; use spade::{handles::FixedVertexHandle, DelaunayTriangulation, HasPosition, InsertionError}; -use crate::{graph::GetNodeIndex, layout::Layout}; +use crate::{ + graph::GetNodeIndex, + layout::{rules::RulesTrait, Layout}, +}; pub trait GetVertexIndex { fn vertex(&self) -> I; @@ -20,7 +23,7 @@ pub struct Triangulation + HasPosition> Triangulation { - pub fn new(layout: &Layout) -> Self { + pub fn new(layout: &Layout) -> Self { let mut this = Self { triangulation: as spade::Triangulation>::new(), vertex_to_handle: Vec::new(), diff --git a/src/wraparoundable.rs b/src/wraparoundable.rs index 5c5bdf2..0d8668a 100644 --- a/src/wraparoundable.rs +++ b/src/wraparoundable.rs @@ -10,12 +10,13 @@ use crate::{ primitive::{ FixedBend, FixedDot, GetFirstRail, GetInnerOuter, GetLayout, LooseBend, Primitive, }, + rules::RulesTrait, Layout, }, }; #[enum_dispatch] -pub trait GetWraparound: GetLayout + GetNodeIndex { +pub trait GetWraparound: GetNodeIndex { fn wraparound(&self) -> Option; } @@ -47,14 +48,14 @@ impl From for WraparoundableIndex { } #[enum_dispatch(GetWraparound, GetLayout, GetNodeIndex)] -pub enum Wraparoundable<'a> { - FixedDot(FixedDot<'a>), - FixedBend(FixedBend<'a>), - LooseBend(LooseBend<'a>), +pub enum Wraparoundable<'a, R: RulesTrait> { + FixedDot(FixedDot<'a, R>), + FixedBend(FixedBend<'a, R>), + LooseBend(LooseBend<'a, R>), } -impl<'a> Wraparoundable<'a> { - pub fn new(index: WraparoundableIndex, layout: &'a Layout) -> Self { +impl<'a, R: RulesTrait> Wraparoundable<'a, R> { + pub fn new(index: WraparoundableIndex, layout: &'a Layout) -> Self { match index { WraparoundableIndex::FixedDot(dot) => layout.primitive(dot).into(), WraparoundableIndex::FixedBend(bend) => layout.primitive(bend).into(), @@ -63,19 +64,19 @@ impl<'a> Wraparoundable<'a> { } } -impl<'a> GetWraparound for FixedDot<'a> { +impl<'a, R: RulesTrait> GetWraparound for FixedDot<'a, R> { fn wraparound(&self) -> Option { self.first_rail() } } -impl<'a> GetWraparound for LooseBend<'a> { +impl<'a, R: RulesTrait> GetWraparound for LooseBend<'a, R> { fn wraparound(&self) -> Option { self.outer() } } -impl<'a> GetWraparound for FixedBend<'a> { +impl<'a, R: RulesTrait> GetWraparound for FixedBend<'a, R> { fn wraparound(&self) -> Option { self.first_rail() }