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