From 5da6ec44634f4309568e0be0c062bdc336fb73da Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 23 Jul 2024 01:59:55 +0200 Subject: [PATCH] drawing: create methods for obtaining UIDs for bands --- src/autorouter/ratsnest.rs | 10 +++++-- src/board/board.rs | 12 +++++--- src/drawing/band.rs | 43 ++++++++++++++++++++------- src/drawing/collect.rs | 61 +++++++++++++++++++++++++++++++------- src/drawing/drawing.rs | 10 +++---- src/drawing/loose.rs | 38 ++++++++++++++---------- src/drawing/primitive.rs | 8 ++--- src/layout/layout.rs | 4 +-- src/router/draw.rs | 10 +++---- src/router/router.rs | 10 +++---- src/router/tracer.rs | 4 +-- 11 files changed, 144 insertions(+), 66 deletions(-) diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index 5fd7727..1bedcff 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -12,7 +12,7 @@ use spade::{HasPosition, InsertionError, Point2}; use crate::{ drawing::{ - band::BandFirstSegIndex, + band::BandTerminatingSegIndex, dot::FixedDotIndex, graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex}, primitive::MakePrimitiveShape, @@ -64,7 +64,7 @@ impl HasPosition for RatvertexWeight { #[derive(Debug, Default, Clone, Copy)] pub struct RatlineWeight { - pub band: Option, + pub band: Option, } pub struct Ratsnest { @@ -165,7 +165,11 @@ impl Ratsnest { Ok(this) } - pub fn assign_band_to_ratline(&mut self, ratline: EdgeIndex, band: BandFirstSegIndex) { + pub fn assign_band_to_ratline( + &mut self, + ratline: EdgeIndex, + band: BandTerminatingSegIndex, + ) { self.graph.edge_weight_mut(ratline).unwrap().band = Some(band); } diff --git a/src/board/board.rs b/src/board/board.rs index 1158eb4..9134653 100644 --- a/src/board/board.rs +++ b/src/board/board.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use crate::{ board::mesadata::AccessMesadata, drawing::{ - band::BandFirstSegIndex, + band::BandTerminatingSegIndex, dot::{FixedDotIndex, FixedDotWeight}, graph::{GetLayer, GetMaybeNet}, seg::{FixedSegIndex, FixedSegWeight}, @@ -21,7 +21,7 @@ use crate::{ pub struct Board { layout: Layout, node_to_pinname: HashMap, - pinname_pair_to_band: HashMap<(String, String), BandFirstSegIndex>, + pinname_pair_to_band: HashMap<(String, String), BandTerminatingSegIndex>, } impl Board { @@ -140,7 +140,7 @@ impl Board { &mut self, source: FixedDotIndex, target: FixedDotIndex, - band: BandFirstSegIndex, + band: BandTerminatingSegIndex, ) { let source_pinname = self .node_pinname(GenericNode::Primitive(source.into())) @@ -154,7 +154,11 @@ impl Board { .insert((source_pinname, target_pinname), band); } - pub fn band_between_pins(&self, pinname1: &str, pinname2: &str) -> Option { + pub fn band_between_pins( + &self, + pinname1: &str, + pinname2: &str, + ) -> Option { if let Some(band) = self .pinname_pair_to_band .get(&(pinname1.to_string(), pinname2.to_string())) diff --git a/src/drawing/band.rs b/src/drawing/band.rs index 942f00d..a826dd6 100644 --- a/src/drawing/band.rs +++ b/src/drawing/band.rs @@ -1,22 +1,42 @@ -use crate::{geometry::shape::MeasureLength, graph::MakeRef}; +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::NodeIndex; + +use crate::{ + geometry::shape::MeasureLength, + graph::{GetPetgraphIndex, MakeRef}, +}; use super::{ graph::MakePrimitive, - loose::{GetNextLoose, LooseIndex}, - primitive::{GetJoints, GetOtherJoint, MakePrimitiveShape}, + loose::{GetPrevNextLoose, LooseIndex}, + primitive::MakePrimitiveShape, rules::AccessRules, seg::{LoneLooseSegIndex, SeqLooseSegIndex}, Drawing, }; -#[derive(Debug, Hash, Clone, Copy, Eq, PartialEq)] -pub enum BandFirstSegIndex { +#[derive(Debug, Hash, Clone, Copy)] +pub struct BandUid(BandTerminatingSegIndex, BandTerminatingSegIndex); + +impl BandUid { + pub fn new(first_seg1: BandTerminatingSegIndex, first_seg2: BandTerminatingSegIndex) -> Self { + if first_seg1.petgraph_index() <= first_seg2.petgraph_index() { + BandUid(first_seg1, first_seg2) + } else { + BandUid(first_seg2, first_seg1) + } + } +} + +#[enum_dispatch(GetPetgraphIndex)] +#[derive(Debug, Hash, Clone, Copy)] +pub enum BandTerminatingSegIndex { Straight(LoneLooseSegIndex), Bended(SeqLooseSegIndex), } impl<'a, CW: Copy, R: AccessRules> MakeRef<'a, BandRef<'a, CW, R>, Drawing> - for BandFirstSegIndex + for BandTerminatingSegIndex { fn ref_(&self, drawing: &'a Drawing) -> BandRef<'a, CW, R> { BandRef::new(*self, drawing) @@ -24,12 +44,15 @@ impl<'a, CW: Copy, R: AccessRules> MakeRef<'a, BandRef<'a, CW, R>, Drawing { - first_seg: BandFirstSegIndex, + first_seg: BandTerminatingSegIndex, drawing: &'a Drawing, } impl<'a, CW: Copy, R: AccessRules> BandRef<'a, CW, R> { - pub fn new(first_seg: BandFirstSegIndex, drawing: &'a Drawing) -> BandRef<'a, CW, R> { + pub fn new( + first_seg: BandTerminatingSegIndex, + drawing: &'a Drawing, + ) -> BandRef<'a, CW, R> { Self { first_seg, drawing } } } @@ -37,10 +60,10 @@ impl<'a, CW: Copy, R: AccessRules> BandRef<'a, CW, R> { impl<'a, CW: Copy, R: AccessRules> MeasureLength for BandRef<'a, CW, R> { fn length(&self) -> f64 { match self.first_seg { - BandFirstSegIndex::Straight(seg) => { + BandTerminatingSegIndex::Straight(seg) => { self.drawing.geometry().seg_shape(seg.into()).length() } - BandFirstSegIndex::Bended(first_loose_seg) => { + BandTerminatingSegIndex::Bended(first_loose_seg) => { let mut maybe_loose: Option = Some(first_loose_seg.into()); let mut prev = None; let mut length = 0.0; diff --git a/src/drawing/collect.rs b/src/drawing/collect.rs index cc217d2..8270d70 100644 --- a/src/drawing/collect.rs +++ b/src/drawing/collect.rs @@ -1,6 +1,10 @@ -use crate::drawing::{ +use crate::graph::{GenericIndex, GetPetgraphIndex}; + +use super::{ + band::{BandTerminatingSegIndex, BandUid}, bend::LooseBendIndex, graph::PrimitiveIndex, + loose::{GetPrevNextLoose, LooseIndex}, primitive::{GetInnerOuter, GetJoints}, rules::AccessRules, wraparoundable::{GetWraparound, WraparoundableIndex}, @@ -17,19 +21,54 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> { Self { drawing } } + pub fn loose_band_uid(&self, start_loose: LooseIndex) -> BandUid { + BandUid::new( + self.loose_band_first_seg(start_loose), + self.loose_band_last_seg(start_loose), + ) + } + + fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex { + let mut loose = start_loose; + let mut prev = None; + + loop { + if let Some(next_loose) = self.drawing.loose(loose).prev_loose(prev) { + prev = Some(loose); + loose = next_loose; + } else { + return BandTerminatingSegIndex::Bended(GenericIndex::new(loose.petgraph_index())); + } + } + } + + fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex { + let mut loose = start_loose; + let mut next = None; + + loop { + if let Some(prev_loose) = self.drawing.loose(loose).next_loose(next) { + next = Some(loose); + loose = prev_loose; + } else { + return BandTerminatingSegIndex::Bended(GenericIndex::new(loose.petgraph_index())); + } + } + } + pub fn bend_bow(&self, bend: LooseBendIndex) -> Vec { let mut v: Vec = vec![]; v.push(bend.into()); - let ends = self.drawing.primitive(bend).joints(); - v.push(ends.0.into()); - v.push(ends.1.into()); + let joints = self.drawing.primitive(bend).joints(); + v.push(joints.0.into()); + v.push(joints.1.into()); - if let Some(seg0) = self.drawing.primitive(ends.0).seg() { + if let Some(seg0) = self.drawing.primitive(joints.0).seg() { v.push(seg0.into()); } - if let Some(seg1) = self.drawing.primitive(ends.1).seg() { + if let Some(seg1) = self.drawing.primitive(joints.1).seg() { v.push(seg1.into()); } @@ -57,12 +96,12 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> { v.push(outer.into()); - let ends = primitive.joints(); - v.push(ends.0.into()); - v.push(ends.1.into()); + let joints = primitive.joints(); + v.push(joints.0.into()); + v.push(joints.1.into()); - v.push(self.drawing.primitive(ends.0).seg().unwrap().into()); - v.push(self.drawing.primitive(ends.1).seg().unwrap().into()); + v.push(self.drawing.primitive(joints.0).seg().unwrap().into()); + v.push(self.drawing.primitive(joints.1).seg().unwrap().into()); rail = outer.into(); } diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index 78028c4..d56d9e8 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -6,14 +6,14 @@ use rstar::{RTree, AABB}; use thiserror::Error; use crate::drawing::{ - band::BandFirstSegIndex, + band::BandTerminatingSegIndex, bend::{BendIndex, BendWeight, FixedBendIndex, LooseBendIndex, LooseBendWeight}, cane::Cane, collect::Collect, dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight}, guide::Guide, - loose::{GetNextLoose, Loose, LooseIndex}, + loose::{GetPrevNextLoose, Loose, LooseIndex}, primitive::{ GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetLimbs, GetOtherJoint, MakePrimitiveShape, @@ -88,12 +88,12 @@ impl Drawing { } } - pub fn remove_band(&mut self, band: BandFirstSegIndex) { + pub fn remove_band(&mut self, band: BandTerminatingSegIndex) { match band { - BandFirstSegIndex::Straight(seg) => { + BandTerminatingSegIndex::Straight(seg) => { self.geometry_with_rtree.remove_seg(seg.into()); } - BandFirstSegIndex::Bended(first_loose_seg) => { + BandTerminatingSegIndex::Bended(first_loose_seg) => { let mut dots = vec![]; let mut segs = vec![]; let mut bends = vec![]; diff --git a/src/drawing/loose.rs b/src/drawing/loose.rs index 1e2e04a..70b90c1 100644 --- a/src/drawing/loose.rs +++ b/src/drawing/loose.rs @@ -16,8 +16,16 @@ use crate::{ use super::rules::AccessRules; #[enum_dispatch] -pub trait GetNextLoose { +pub trait GetPrevNextLoose { fn next_loose(&self, maybe_prev: Option) -> Option; + + fn prev_loose(&self, maybe_next: Option) -> Option { + if maybe_next.is_some() { + self.next_loose(maybe_next) + } else { + self.next_loose(self.next_loose(None)) + } + } } #[enum_dispatch(GetPetgraphIndex, MakePrimitive)] @@ -40,7 +48,7 @@ impl From for PrimitiveIndex { } } -#[enum_dispatch(GetNextLoose, GetDrawing, GetPetgraphIndex)] +#[enum_dispatch(GetPrevNextLoose, GetDrawing, GetPetgraphIndex)] pub enum Loose<'a, CW: Copy, R: AccessRules> { Dot(LooseDot<'a, CW, R>), LoneSeg(LoneLooseSeg<'a, CW, R>), @@ -59,7 +67,7 @@ impl<'a, CW: Copy, R: AccessRules> Loose<'a, CW, R> { } } -impl<'a, CW: Copy, R: AccessRules> GetNextLoose for LooseDot<'a, CW, R> { +impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseDot<'a, CW, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let bend = self.bend(); let Some(prev) = maybe_prev else { @@ -74,41 +82,41 @@ impl<'a, CW: Copy, R: AccessRules> GetNextLoose for LooseDot<'a, CW, R> { } } -impl<'a, CW: Copy, R: AccessRules> GetNextLoose for LoneLooseSeg<'a, CW, R> { +impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LoneLooseSeg<'a, CW, R> { fn next_loose(&self, _maybe_prev: Option) -> Option { None } } -impl<'a, CW: Copy, R: AccessRules> GetNextLoose for SeqLooseSeg<'a, CW, R> { +impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for SeqLooseSeg<'a, CW, R> { fn next_loose(&self, maybe_prev: Option) -> Option { - let ends = self.joints(); + let joints = self.joints(); let Some(prev) = maybe_prev else { - return Some(ends.1.into()); + return Some(joints.1.into()); }; - if ends.0.petgraph_index() != prev.petgraph_index() { - match ends.0 { + if joints.0.petgraph_index() != prev.petgraph_index() { + match joints.0 { DotIndex::Fixed(..) => None, DotIndex::Loose(dot) => Some(dot.into()), } } else { - Some(ends.1.into()) + Some(joints.1.into()) } } } -impl<'a, CW: Copy, R: AccessRules> GetNextLoose for LooseBend<'a, CW, R> { +impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseBend<'a, CW, R> { fn next_loose(&self, maybe_prev: Option) -> Option { - let ends = self.joints(); + let joints = self.joints(); let Some(prev) = maybe_prev else { unreachable!(); }; - if ends.0.petgraph_index() != prev.petgraph_index() { - Some(ends.0.into()) + if joints.0.petgraph_index() != prev.petgraph_index() { + Some(joints.0.into()) } else { - Some(ends.1.into()) + Some(joints.1.into()) } } } diff --git a/src/drawing/primitive.rs b/src/drawing/primitive.rs index 953bc4b..a80c5a5 100644 --- a/src/drawing/primitive.rs +++ b/src/drawing/primitive.rs @@ -59,11 +59,11 @@ pub trait GetOtherJoint>: GetJoints { fn other_joint(&self, end: F) -> F { - let ends = self.joints(); - if ends.0.petgraph_index() != end.petgraph_index() { - ends.0 + let joints = self.joints(); + if joints.0.petgraph_index() != end.petgraph_index() { + joints.0 } else { - ends.1.into() + joints.1.into() } } } diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 14c3eff..76339a1 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -5,7 +5,7 @@ use rstar::AABB; use crate::{ drawing::{ - band::BandFirstSegIndex, + band::BandTerminatingSegIndex, bend::LooseBendWeight, cane::Cane, dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, @@ -204,7 +204,7 @@ impl Layout { ) } - pub fn remove_band(&mut self, band: BandFirstSegIndex) { + pub fn remove_band(&mut self, band: BandTerminatingSegIndex) { self.drawing.remove_band(band); } diff --git a/src/router/draw.rs b/src/router/draw.rs index a428b34..5fc1609 100644 --- a/src/router/draw.rs +++ b/src/router/draw.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::{ drawing::{ - band::BandFirstSegIndex, + band::BandTerminatingSegIndex, bend::{BendIndex, LooseBendWeight}, dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, graph::{GetLayer, GetMaybeNet, MakePrimitive}, @@ -51,7 +51,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { head: Head, into: FixedDotIndex, width: f64, - ) -> Result { + ) -> Result { let tangent = self .guide() .head_into_dot_segment(&head, into, width) @@ -62,8 +62,8 @@ impl<'a, R: AccessRules> Draw<'a, R> { let layer = head.face().primitive(self.layout.drawing()).layer(); let maybe_net = head.face().primitive(self.layout.drawing()).maybe_net(); - Ok::(match head.face() { - DotIndex::Fixed(dot) => BandFirstSegIndex::Straight( + Ok::(match head.face() { + DotIndex::Fixed(dot) => BandTerminatingSegIndex::Straight( self.layout .add_lone_loose_seg( dot, @@ -76,7 +76,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { ) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?, ), - DotIndex::Loose(dot) => BandFirstSegIndex::Bended( + DotIndex::Loose(dot) => BandTerminatingSegIndex::Bended( self.layout .add_seq_loose_seg( into.into(), diff --git a/src/router/router.rs b/src/router/router.rs index 8788078..3d313f6 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::{ drawing::{ - band::BandFirstSegIndex, + band::BandTerminatingSegIndex, dot::{DotIndex, FixedDotIndex}, graph::{MakePrimitive, PrimitiveIndex}, head::GetFace, @@ -39,7 +39,7 @@ pub enum RouterError { #[derive(Debug)] pub enum RouterStatus { Running, - Finished(BandFirstSegIndex), + Finished(BandTerminatingSegIndex), } #[derive(Debug)] @@ -78,7 +78,7 @@ impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> { } } -impl<'a, R: AccessRules> AstarStrategy +impl<'a, R: AccessRules> AstarStrategy for RouterAstarStrategy<'a, R> { fn is_goal( @@ -86,7 +86,7 @@ impl<'a, R: AccessRules> AstarStrategy navmesh: &Navmesh, vertex: NavvertexIndex, tracker: &PathTracker, - ) -> Option { + ) -> Option { let new_path = tracker.reconstruct_path_to(vertex); let width = self.trace.width; @@ -176,7 +176,7 @@ impl<'a, R: AccessRules> Router<'a, R> { from: FixedDotIndex, to: FixedDotIndex, width: f64, - ) -> Result { + ) -> Result { let mut route = self.route_walk(from, to, width)?; loop { diff --git a/src/router/tracer.rs b/src/router/tracer.rs index 7ff9c7d..abb89f5 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -2,7 +2,7 @@ use contracts::{debug_ensures, debug_requires}; use thiserror::Error; use crate::{ - drawing::{band::BandFirstSegIndex, dot::FixedDotIndex, rules::AccessRules}, + drawing::{band::BandTerminatingSegIndex, dot::FixedDotIndex, rules::AccessRules}, layout::Layout, router::{ draw::{Draw, DrawException}, @@ -44,7 +44,7 @@ impl<'a, R: AccessRules> Tracer<'a, R> { trace: &mut Trace, target: FixedDotIndex, width: f64, - ) -> Result { + ) -> Result { Ok(Draw::new(self.layout).finish_in_dot(trace.head, target, width)?) }