diff --git a/build.rs b/build.rs index ca3046c..254a664 100644 --- a/build.rs +++ b/build.rs @@ -1,7 +1,7 @@ include!("src/bin/topola/cli.rs"); -use clap_mangen::Man; use clap::CommandFactory; -use std::fs::{File, create_dir_all}; +use clap_mangen::Man; +use std::fs::{create_dir_all, File}; // https://rust-cli.github.io/book/in-depth/docs.html fn main() -> Result<(), Box> { let cmd = Cli::command(); diff --git a/src/bin/topola/cli.rs b/src/bin/topola/cli.rs index 1455631..19418b2 100644 --- a/src/bin/topola/cli.rs +++ b/src/bin/topola/cli.rs @@ -1,17 +1,26 @@ use clap::Parser; use std::path::PathBuf; - #[derive(Parser, Debug, Default)] #[command(about, version)] pub struct Cli { - #[arg(value_name = "SPECCTRA DESIGN FILE", - help = "Specify the Specctra Design (*.dsn) input file for the Topola autorouter")] + #[arg( + value_name = "SPECCTRA DESIGN FILE", + help = "Specify the Specctra Design (*.dsn) input file for the Topola autorouter" + )] pub input: PathBuf, - #[arg(short, long, value_name = "SPECCTRA SESSION FILE", - help = "Specify the output session file in Specctra-compatible format (*.ses). The input filename is used by default, with the extension changed to Specctra Session File extension") - ] + #[arg( + short, + long, + value_name = "SPECCTRA SESSION FILE", + help = "Specify the output session file in Specctra-compatible format (*.ses). The input filename is used by default, with the extension changed to Specctra Session File extension" + )] pub output: Option, - #[arg(short, long, value_name = "COMMAND FILE", help = "JSON-like file with .cmd extension, containing sequence of available commands ")] + #[arg( + short, + long, + value_name = "COMMAND FILE", + help = "JSON-like file with .cmd extension, containing sequence of available commands " + )] pub commands: Option, } diff --git a/src/drawing/collect.rs b/src/drawing/collect.rs index 4581a8e..cc20fee 100644 --- a/src/drawing/collect.rs +++ b/src/drawing/collect.rs @@ -1,13 +1,13 @@ -use crate::graph::{GenericIndex, GetPetgraphIndex}; +use crate::graph::{GenericIndex, GetPetgraphIndex, MakeRef}; use super::{ band::{BandTermsegIndex, BandUid}, bend::LooseBendIndex, + gear::{GearIndex, GetNextGear}, graph::PrimitiveIndex, loose::{GetPrevNextLoose, LooseIndex}, primitive::{GetInnerOuter, GetJoints}, rules::AccessRules, - wraparoundable::{GetWraparound, WraparoundableIndex}, Drawing, }; @@ -85,21 +85,21 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> { pub fn bend_outer_bows(&self, bend: LooseBendIndex) -> Vec { let mut v = vec![]; - let mut rail = bend; + let mut gear = bend; - while let Some(outer) = self.drawing.primitive(rail).outer() { + while let Some(outer) = self.drawing.primitive(gear).outer() { v.append(&mut self.bend_bow(outer.into())); - rail = outer; + gear = outer; } v } - pub fn wraparounded_bows(&self, around: WraparoundableIndex) -> Vec { + pub fn wraparounded_bows(&self, around: GearIndex) -> Vec { let mut v = vec![]; - let mut rail = around.into(); + let mut gear = around; - while let Some(outer) = self.drawing.wraparoundable(rail).wraparound() { + while let Some(outer) = gear.ref_(self.drawing).next_gear() { let primitive = self.drawing.primitive(outer); v.push(outer.into()); @@ -111,7 +111,7 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> { v.push(self.drawing.primitive(joints.0).seg().unwrap().into()); v.push(self.drawing.primitive(joints.1).seg().unwrap().into()); - rail = outer.into(); + gear = outer.into(); } v diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index 9835065..f2317a9 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -5,26 +5,6 @@ use geo::Point; use rstar::{RTree, AABB}; use thiserror::Error; -use crate::drawing::{ - band::BandTermsegIndex, - 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::{GetPrevNextLoose, Loose, LooseIndex}, - primitive::{ - GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetLimbs, GetOtherJoint, - MakePrimitiveShape, - }, - rules::{AccessRules, GetConditions}, - seg::{ - FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, SegWeight, - SeqLooseSegIndex, SeqLooseSegWeight, - }, - wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex}, -}; use crate::geometry::{ compound::ManageCompounds, primitive::{AccessPrimitiveShape, PrimitiveShape}, @@ -34,6 +14,29 @@ use crate::geometry::{ }; use crate::graph::{GenericIndex, GetPetgraphIndex}; use crate::math::NoTangents; +use crate::{ + drawing::{ + band::BandTermsegIndex, + bend::{BendIndex, BendWeight, FixedBendIndex, LooseBendIndex, LooseBendWeight}, + cane::Cane, + collect::Collect, + dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, + gear::{GearIndex, GearRef, GetNextGear}, + graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight}, + guide::Guide, + loose::{GetPrevNextLoose, Loose, LooseIndex}, + primitive::{ + GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetLimbs, GetOtherJoint, + MakePrimitiveShape, + }, + rules::{AccessRules, GetConditions}, + seg::{ + FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, + SegWeight, SeqLooseSegIndex, SeqLooseSegWeight, + }, + }, + graph::MakeRef, +}; use super::head::{Head, HeadRef}; @@ -266,7 +269,7 @@ impl Drawing { &mut self, from: LooseDotIndex, to: LooseDotIndex, - around: WraparoundableIndex, + around: GearIndex, weight: LooseBendWeight, infringables: Option<&[PrimitiveIndex]>, ) -> Result { @@ -279,23 +282,23 @@ impl Drawing { } } // - if let Some(wraparound) = self.wraparoundable(around).wraparound() { - if let Some(wraparound_net) = wraparound.primitive(self).maybe_net() { + if let Some(next_gear) = around.ref_(self).next_gear() { + if let Some(wraparound_net) = next_gear.primitive(self).maybe_net() { if net == wraparound_net { - return Err(AlreadyConnected(net, wraparound.into()).into()); + return Err(AlreadyConnected(net, next_gear.into()).into()); } } } } match around { - WraparoundableIndex::FixedDot(core) => self + GearIndex::FixedDot(core) => self .add_core_bend_with_infringables(from.into(), to.into(), core, weight, infringables) .map_err(Into::into), - WraparoundableIndex::FixedBend(around) => self + GearIndex::FixedBend(around) => self .add_outer_bend_with_infringables(from, to, around.into(), weight, infringables) .map_err(Into::into), - WraparoundableIndex::LooseBend(around) => self + GearIndex::LooseBend(around) => self .add_outer_bend_with_infringables(from, to, around.into(), weight, infringables) .map_err(Into::into), } @@ -391,13 +394,13 @@ impl Drawing { pub fn insert_cane( &mut self, from: DotIndex, - around: WraparoundableIndex, + around: GearIndex, dot_weight: LooseDotWeight, seg_weight: SeqLooseSegWeight, bend_weight: LooseBendWeight, cw: bool, ) -> Result { - let maybe_wraparound = self.wraparoundable(around).wraparound(); + let maybe_next_gear = around.ref_(self).next_gear(); let cane = self.add_cane_with_infringables( from, around, @@ -408,8 +411,8 @@ impl Drawing { Some(&[]), )?; - if let Some(wraparound) = maybe_wraparound { - self.reattach_bend(wraparound, Some(cane.bend)); + if let Some(next_gear) = maybe_next_gear { + self.reattach_bend(next_gear, Some(cane.bend)); } if let Some(outer) = self.primitive(cane.bend).outer() { @@ -543,7 +546,7 @@ impl Drawing { pub fn add_cane( &mut self, from: DotIndex, - around: WraparoundableIndex, + around: GearIndex, dot_weight: LooseDotWeight, seg_weight: SeqLooseSegWeight, bend_weight: LooseBendWeight, @@ -567,7 +570,7 @@ impl Drawing { fn add_cane_with_infringables( &mut self, from: DotIndex, - around: WraparoundableIndex, + around: GearIndex, dot_weight: LooseDotWeight, seg_weight: SeqLooseSegWeight, bend_weight: LooseBendWeight, @@ -911,18 +914,10 @@ impl Drawing { GenericPrimitive::new(index, self) } - pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable { - Wraparoundable::new(index, self) - } - pub fn loose(&self, index: LooseIndex) -> Loose { Loose::new(index, self) } - pub fn head_ref(&self, head: Head) -> HeadRef<'_, CW, R> { - HeadRef::new(head, self) - } - pub fn layer_count(&self) -> usize { self.geometry_with_rtree.layer_count() } diff --git a/src/drawing/gear.rs b/src/drawing/gear.rs new file mode 100644 index 0000000..4871c2c --- /dev/null +++ b/src/drawing/gear.rs @@ -0,0 +1,87 @@ +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::NodeIndex; + +use crate::{ + drawing::{ + bend::{BendIndex, FixedBendIndex, LooseBendIndex}, + dot::FixedDotIndex, + graph::{MakePrimitive, PrimitiveIndex}, + primitive::{FixedBend, FixedDot, GetFirstGear, GetInnerOuter, LooseBend, Primitive}, + rules::AccessRules, + Drawing, + }, + graph::{GetPetgraphIndex, MakeRef}, +}; + +#[enum_dispatch] +pub trait GetNextGear: GetPetgraphIndex { + fn next_gear(&self) -> Option; +} + +#[enum_dispatch(GetPetgraphIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum GearIndex { + FixedDot(FixedDotIndex), + FixedBend(FixedBendIndex), + LooseBend(LooseBendIndex), +} + +impl<'a, CW: Copy, R: AccessRules> MakeRef<'a, GearRef<'a, CW, R>, Drawing> for GearIndex { + fn ref_(&self, drawing: &'a Drawing) -> GearRef<'a, CW, R> { + GearRef::new(*self, drawing) + } +} + +impl From for PrimitiveIndex { + fn from(wraparoundable: GearIndex) -> Self { + match wraparoundable { + GearIndex::FixedDot(dot) => PrimitiveIndex::FixedDot(dot), + GearIndex::FixedBend(bend) => PrimitiveIndex::FixedBend(bend), + GearIndex::LooseBend(bend) => PrimitiveIndex::LooseBend(bend), + } + } +} + +impl From for GearIndex { + fn from(bend: BendIndex) -> Self { + match bend { + BendIndex::Fixed(bend) => GearIndex::FixedBend(bend), + BendIndex::Loose(bend) => GearIndex::LooseBend(bend), + } + } +} + +#[enum_dispatch(GetNextGear, GetDrawing, GetPetgraphIndex)] +pub enum GearRef<'a, CW: Copy, R: AccessRules> { + FixedDot(FixedDot<'a, CW, R>), + FixedBend(FixedBend<'a, CW, R>), + LooseBend(LooseBend<'a, CW, R>), +} + +impl<'a, CW: Copy, R: AccessRules> GearRef<'a, CW, R> { + pub fn new(index: GearIndex, drawing: &'a Drawing) -> Self { + match index { + GearIndex::FixedDot(dot) => drawing.primitive(dot).into(), + GearIndex::FixedBend(bend) => drawing.primitive(bend).into(), + GearIndex::LooseBend(bend) => drawing.primitive(bend).into(), + } + } +} + +impl<'a, CW: Copy, R: AccessRules> GetNextGear for FixedDot<'a, CW, R> { + fn next_gear(&self) -> Option { + self.first_gear() + } +} + +impl<'a, CW: Copy, R: AccessRules> GetNextGear for LooseBend<'a, CW, R> { + fn next_gear(&self) -> Option { + self.outer() + } +} + +impl<'a, CW: Copy, R: AccessRules> GetNextGear for FixedBend<'a, CW, R> { + fn next_gear(&self) -> Option { + self.first_gear() + } +} diff --git a/src/drawing/mod.rs b/src/drawing/mod.rs index 62d0699..585da9b 100644 --- a/src/drawing/mod.rs +++ b/src/drawing/mod.rs @@ -6,12 +6,12 @@ pub mod cane; pub mod collect; pub mod dot; mod drawing; +pub mod gear; pub mod guide; pub mod head; pub mod loose; pub mod primitive; pub mod rules; pub mod seg; -pub mod wraparoundable; pub use drawing::*; diff --git a/src/drawing/primitive.rs b/src/drawing/primitive.rs index a80c5a5..25c7a1d 100644 --- a/src/drawing/primitive.rs +++ b/src/drawing/primitive.rs @@ -72,8 +72,8 @@ pub trait GetJoints { fn joints(&self) -> (F, T); } -pub trait GetFirstRail<'a, R: AccessRules>: GetDrawing<'a, R> + GetPetgraphIndex { - fn first_rail(&self) -> Option { +pub trait GetFirstGear<'a, R: AccessRules>: GetDrawing<'a, R> + GetPetgraphIndex { + fn first_gear(&self) -> Option { self.drawing() .geometry() .first_rail(self.petgraph_index()) @@ -268,7 +268,7 @@ impl<'a, CW: Copy, R: AccessRules> GetLimbs for FixedDot<'a, CW, R> { } } -impl<'a, CW: Copy, R: AccessRules> GetFirstRail<'a, R> for FixedDot<'a, CW, R> {} +impl<'a, CW: Copy, R: AccessRules> GetFirstGear<'a, R> for FixedDot<'a, CW, R> {} pub type LooseDot<'a, CW, R> = GenericPrimitive<'a, LooseDotWeight, CW, R>; impl_loose_primitive!(LooseDot, LooseDotWeight); @@ -437,7 +437,7 @@ impl<'a, CW: Copy, R: AccessRules> GetOtherJoint for FixedBend<'a, CW, R> { } -impl<'a, CW: Copy, R: AccessRules> GetFirstRail<'a, R> for FixedBend<'a, CW, R> {} +impl<'a, CW: Copy, R: AccessRules> GetFirstGear<'a, R> for FixedBend<'a, CW, R> {} impl<'a, CW: Copy, R: AccessRules> GetCore<'a, R> for FixedBend<'a, CW, R> {} // TODO: Fixed bends don't have cores actually. //impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, CW, R> {} diff --git a/src/drawing/wraparoundable.rs b/src/drawing/wraparoundable.rs deleted file mode 100644 index 06f8224..0000000 --- a/src/drawing/wraparoundable.rs +++ /dev/null @@ -1,81 +0,0 @@ -use enum_dispatch::enum_dispatch; -use petgraph::stable_graph::NodeIndex; - -use crate::{ - drawing::{ - bend::{BendIndex, FixedBendIndex, LooseBendIndex}, - dot::FixedDotIndex, - graph::{MakePrimitive, PrimitiveIndex}, - primitive::{FixedBend, FixedDot, GetFirstRail, GetInnerOuter, LooseBend, Primitive}, - rules::AccessRules, - Drawing, - }, - graph::GetPetgraphIndex, -}; - -#[enum_dispatch] -pub trait GetWraparound: GetPetgraphIndex { - fn wraparound(&self) -> Option; -} - -#[enum_dispatch(GetPetgraphIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum WraparoundableIndex { - FixedDot(FixedDotIndex), - FixedBend(FixedBendIndex), - LooseBend(LooseBendIndex), -} - -impl From for PrimitiveIndex { - fn from(wraparoundable: WraparoundableIndex) -> Self { - match wraparoundable { - WraparoundableIndex::FixedDot(dot) => PrimitiveIndex::FixedDot(dot), - WraparoundableIndex::FixedBend(bend) => PrimitiveIndex::FixedBend(bend), - WraparoundableIndex::LooseBend(bend) => PrimitiveIndex::LooseBend(bend), - } - } -} - -impl From for WraparoundableIndex { - fn from(bend: BendIndex) -> Self { - match bend { - BendIndex::Fixed(bend) => WraparoundableIndex::FixedBend(bend), - BendIndex::Loose(bend) => WraparoundableIndex::LooseBend(bend), - } - } -} - -#[enum_dispatch(GetWraparound, GetDrawing, GetPetgraphIndex)] -pub enum Wraparoundable<'a, CW: Copy, R: AccessRules> { - FixedDot(FixedDot<'a, CW, R>), - FixedBend(FixedBend<'a, CW, R>), - LooseBend(LooseBend<'a, CW, R>), -} - -impl<'a, CW: Copy, R: AccessRules> Wraparoundable<'a, CW, R> { - pub fn new(index: WraparoundableIndex, drawing: &'a Drawing) -> Self { - match index { - WraparoundableIndex::FixedDot(dot) => drawing.primitive(dot).into(), - WraparoundableIndex::FixedBend(bend) => drawing.primitive(bend).into(), - WraparoundableIndex::LooseBend(bend) => drawing.primitive(bend).into(), - } - } -} - -impl<'a, CW: Copy, R: AccessRules> GetWraparound for FixedDot<'a, CW, R> { - fn wraparound(&self) -> Option { - self.first_rail() - } -} - -impl<'a, CW: Copy, R: AccessRules> GetWraparound for LooseBend<'a, CW, R> { - fn wraparound(&self) -> Option { - self.outer() - } -} - -impl<'a, CW: Copy, R: AccessRules> GetWraparound for FixedBend<'a, CW, R> { - fn wraparound(&self) -> Option { - self.first_rail() - } -} diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 9c499d4..b76b063 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -9,6 +9,7 @@ use crate::{ bend::LooseBendWeight, cane::Cane, dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, + gear::GearIndex, graph::{GetMaybeNet, PrimitiveIndex}, primitive::{GetJoints, GetOtherJoint}, rules::AccessRules, @@ -16,7 +17,6 @@ use crate::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }, - wraparoundable::WraparoundableIndex, Drawing, Infringement, LayoutException, }, geometry::{compound::ManageCompounds, shape::MeasureLength, GenericNode}, @@ -49,7 +49,7 @@ impl Layout { pub fn insert_cane( &mut self, from: DotIndex, - around: WraparoundableIndex, + around: GearIndex, dot_weight: LooseDotWeight, seg_weight: SeqLooseSegWeight, bend_weight: LooseBendWeight, diff --git a/src/router/draw.rs b/src/router/draw.rs index a5cfc3a..c0a8cbc 100644 --- a/src/router/draw.rs +++ b/src/router/draw.rs @@ -7,13 +7,13 @@ use crate::{ band::BandTermsegIndex, bend::{BendIndex, LooseBendWeight}, dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, + gear::GearIndex, graph::{GetLayer, GetMaybeNet, MakePrimitive}, guide::Guide, head::{CaneHead, GetFace, Head}, primitive::GetOtherJoint, rules::AccessRules, seg::{LoneLooseSegWeight, SeqLooseSegWeight}, - wraparoundable::WraparoundableIndex, Infringement, LayoutException, }, layout::Layout, @@ -28,7 +28,7 @@ pub enum DrawException { #[error("cannot finish in {0:?}")] CannotFinishIn(FixedDotIndex, #[source] LayoutException), #[error("cannot wrap around {0:?}")] - CannotWrapAround(WraparoundableIndex, #[source] LayoutException), + CannotWrapAround(GearIndex, #[source] LayoutException), } pub struct Draw<'a, R: AccessRules> { @@ -152,7 +152,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { fn cane_around( &mut self, head: Head, - around: WraparoundableIndex, + around: GearIndex, from: Point, to: Point, cw: bool, @@ -178,7 +178,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { fn cane( &mut self, head: Head, - around: WraparoundableIndex, + around: GearIndex, to: Point, cw: bool, width: f64,