drawing: rename "rails" and "wraparoundables" to "gears"

This commit is contained in:
Mikolaj Wielgus 2024-08-29 05:24:05 +02:00
parent 994b9e8e9b
commit 2105e8c7cf
10 changed files with 161 additions and 151 deletions

View File

@ -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<dyn std::error::Error>> {
let cmd = Cli::command();

View File

@ -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<PathBuf>,
#[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<PathBuf>,
}

View File

@ -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<PrimitiveIndex> {
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<PrimitiveIndex> {
pub fn wraparounded_bows(&self, around: GearIndex) -> Vec<PrimitiveIndex> {
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

View File

@ -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<CW: Copy, R: AccessRules> Drawing<CW, R> {
&mut self,
from: LooseDotIndex,
to: LooseDotIndex,
around: WraparoundableIndex,
around: GearIndex,
weight: LooseBendWeight,
infringables: Option<&[PrimitiveIndex]>,
) -> Result<LooseBendIndex, LayoutException> {
@ -279,23 +282,23 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
}
}
//
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<CW: Copy, R: AccessRules> Drawing<CW, R> {
pub fn insert_cane(
&mut self,
from: DotIndex,
around: WraparoundableIndex,
around: GearIndex,
dot_weight: LooseDotWeight,
seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight,
cw: bool,
) -> Result<Cane, LayoutException> {
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<CW: Copy, R: AccessRules> Drawing<CW, R> {
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<CW: Copy, R: AccessRules> Drawing<CW, R> {
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<CW: Copy, R: AccessRules> Drawing<CW, R> {
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<CW: Copy, R: AccessRules> Drawing<CW, R> {
GenericPrimitive::new(index, self)
}
pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable<CW, R> {
Wraparoundable::new(index, self)
}
pub fn loose(&self, index: LooseIndex) -> Loose<CW, R> {
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()
}

87
src/drawing/gear.rs Normal file
View File

@ -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<LooseBendIndex>;
}
#[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<CW, R>> for GearIndex {
fn ref_(&self, drawing: &'a Drawing<CW, R>) -> GearRef<'a, CW, R> {
GearRef::new(*self, drawing)
}
}
impl From<GearIndex> 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<BendIndex> 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<CW, R>) -> 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<LooseBendIndex> {
self.first_gear()
}
}
impl<'a, CW: Copy, R: AccessRules> GetNextGear for LooseBend<'a, CW, R> {
fn next_gear(&self) -> Option<LooseBendIndex> {
self.outer()
}
}
impl<'a, CW: Copy, R: AccessRules> GetNextGear for FixedBend<'a, CW, R> {
fn next_gear(&self) -> Option<LooseBendIndex> {
self.first_gear()
}
}

View File

@ -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::*;

View File

@ -72,8 +72,8 @@ pub trait GetJoints<F, T> {
fn joints(&self) -> (F, T);
}
pub trait GetFirstRail<'a, R: AccessRules>: GetDrawing<'a, R> + GetPetgraphIndex {
fn first_rail(&self) -> Option<LooseBendIndex> {
pub trait GetFirstGear<'a, R: AccessRules>: GetDrawing<'a, R> + GetPetgraphIndex {
fn first_gear(&self) -> Option<LooseBendIndex> {
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<FixedDotIndex, FixedDotIndex>
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> {}

View File

@ -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<LooseBendIndex>;
}
#[enum_dispatch(GetPetgraphIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum WraparoundableIndex {
FixedDot(FixedDotIndex),
FixedBend(FixedBendIndex),
LooseBend(LooseBendIndex),
}
impl From<WraparoundableIndex> 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<BendIndex> 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<CW, R>) -> 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<LooseBendIndex> {
self.first_rail()
}
}
impl<'a, CW: Copy, R: AccessRules> GetWraparound for LooseBend<'a, CW, R> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.outer()
}
}
impl<'a, CW: Copy, R: AccessRules> GetWraparound for FixedBend<'a, CW, R> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.first_rail()
}
}

View File

@ -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<R: AccessRules> Layout<R> {
pub fn insert_cane(
&mut self,
from: DotIndex,
around: WraparoundableIndex,
around: GearIndex,
dot_weight: LooseDotWeight,
seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight,

View File

@ -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,