mirror of https://codeberg.org/topola/topola.git
geometry,primitive: move more code and narrow typing further
We replace all instances of `NodeIndex<usize>` in public interfaces of `Geometry` except for `.first_rail()`, for which we make a dirty exception. We also improve terminology a bit: - "joint" is renamed to "connection", - "end" is renamed to "joint", - "leg" is renamed to "limb".
This commit is contained in:
parent
87705653bd
commit
684d0be641
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
geometry::{GeometryIndex, MakePrimitive},
|
||||
},
|
||||
loose::{GetNextLoose, LooseIndex},
|
||||
primitive::{GetEnds, GetOtherEnd, MakeShape},
|
||||
primitive::{GetJoints, GetOtherJoint, MakeShape},
|
||||
shape::ShapeTrait,
|
||||
};
|
||||
|
||||
|
|
@ -52,10 +52,10 @@ impl<'a> Band<'a> {
|
|||
|
||||
match prev {
|
||||
Some(LooseIndex::LoneSeg(seg)) => {
|
||||
Some(self.layout.primitive(seg).other_end(self.from()))
|
||||
Some(self.layout.primitive(seg).other_joint(self.from()))
|
||||
}
|
||||
Some(LooseIndex::SeqSeg(seg)) => {
|
||||
if let DotIndex::Fixed(dot) = self.layout.primitive(seg).ends().0 {
|
||||
if let DotIndex::Fixed(dot) = self.layout.primitive(seg).joints().0 {
|
||||
Some(dot)
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
},
|
||||
layout::{Infringement, Layout, LayoutException},
|
||||
math::{Circle, NoTangents},
|
||||
primitive::GetOtherEnd,
|
||||
primitive::GetOtherJoint,
|
||||
rules::{Conditions, Rules},
|
||||
wraparoundable::WraparoundableIndex,
|
||||
};
|
||||
|
|
@ -231,7 +231,7 @@ impl<'a> Draw<'a> {
|
|||
},
|
||||
)?;
|
||||
Ok::<SegbendHead, LayoutException>(SegbendHead {
|
||||
face: self.layout.primitive(segbend.bend).other_end(segbend.dot),
|
||||
face: self.layout.primitive(segbend.bend).other_joint(segbend.dot),
|
||||
segbend,
|
||||
band: head.band(),
|
||||
})
|
||||
|
|
@ -243,7 +243,7 @@ impl<'a> Draw<'a> {
|
|||
let prev_dot = self
|
||||
.layout
|
||||
.primitive(head.segbend.seg)
|
||||
.other_end(head.segbend.dot.into());
|
||||
.other_joint(head.segbend.dot.into());
|
||||
let band = head.band;
|
||||
|
||||
self.layout.remove_segbend(&head.segbend, head.face);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
geometry::{GetBandIndex, MakePrimitive},
|
||||
},
|
||||
math::{self, Circle, NoTangents},
|
||||
primitive::{GetCore, GetInnerOuter, GetOtherEnd, GetWeight, MakeShape},
|
||||
primitive::{GetCore, GetInnerOuter, GetOtherJoint, GetWeight, MakeShape},
|
||||
rules::{Conditions, Rules},
|
||||
segbend::Segbend,
|
||||
shape::{Shape, ShapeTrait},
|
||||
|
|
@ -230,6 +230,6 @@ impl<'a, 'b> Guide<'a, 'b> {
|
|||
fn rear(&self, head: SegbendHead) -> DotIndex {
|
||||
self.layout
|
||||
.primitive(head.segbend.seg)
|
||||
.other_end(head.segbend.dot.into())
|
||||
.other_joint(head.segbend.dot.into())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ use crate::layout::{
|
|||
use crate::loose::{GetNextLoose, Loose, LooseIndex};
|
||||
use crate::math::NoTangents;
|
||||
use crate::primitive::{
|
||||
GenericPrimitive, GetConnectable, GetCore, GetEnds, GetInnerOuter, GetLegs, GetOtherEnd,
|
||||
GenericPrimitive, GetConnectable, GetCore, GetInnerOuter, GetJoints, GetLimbs, GetOtherJoint,
|
||||
GetWeight, MakeShape,
|
||||
};
|
||||
use crate::segbend::Segbend;
|
||||
|
|
@ -303,7 +303,7 @@ impl Layout {
|
|||
|
||||
// Segs must not cross.
|
||||
if let Some(collision) = self.detect_collision(segbend.seg.into()) {
|
||||
let end = self.primitive(segbend.bend).other_end(segbend.dot);
|
||||
let end = self.primitive(segbend.bend).other_joint(segbend.dot);
|
||||
self.remove_segbend(&segbend, end.into());
|
||||
return Err(collision.into());
|
||||
}
|
||||
|
|
@ -375,7 +375,7 @@ impl Layout {
|
|||
let mut bow: Vec<GeometryIndex> = vec![];
|
||||
bow.push(bend.into());
|
||||
|
||||
let ends = self.primitive(bend).ends();
|
||||
let ends = self.primitive(bend).joints();
|
||||
bow.push(ends.0.into());
|
||||
bow.push(ends.1.into());
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ impl Layout {
|
|||
|
||||
outer_bows.push(outer.into());
|
||||
|
||||
let ends = primitive.ends();
|
||||
let ends = primitive.joints();
|
||||
outer_bows.push(ends.0.into());
|
||||
outer_bows.push(ends.1.into());
|
||||
|
||||
|
|
@ -453,7 +453,7 @@ impl Layout {
|
|||
while let Some(rail) = maybe_rail {
|
||||
let primitive = self.primitive(rail);
|
||||
let cw = primitive.weight().cw;
|
||||
let ends = primitive.ends();
|
||||
let ends = primitive.joints();
|
||||
|
||||
let rules = Default::default();
|
||||
let conditions = Default::default();
|
||||
|
|
@ -843,7 +843,7 @@ impl Layout {
|
|||
to: Point,
|
||||
infringables: &[GeometryIndex],
|
||||
) -> Result<(), Infringement> {
|
||||
self.remove_from_rtree_with_legs(dot.into());
|
||||
self.remove_from_rtree_with_limbs(dot.into());
|
||||
|
||||
let mut weight = *self.geometry.graph.node_weight(dot.node_index()).unwrap();
|
||||
let old_weight = weight;
|
||||
|
|
@ -872,11 +872,11 @@ impl Layout {
|
|||
.node_weight_mut(dot.node_index())
|
||||
.unwrap() = old_weight;
|
||||
|
||||
self.insert_into_rtree_with_legs(dot.into());
|
||||
self.insert_into_rtree_with_limbs(dot.into());
|
||||
return Err(infringement);
|
||||
}
|
||||
|
||||
self.insert_into_rtree_with_legs(dot.into());
|
||||
self.insert_into_rtree_with_limbs(dot.into());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -922,11 +922,11 @@ impl Layout {
|
|||
|
||||
#[debug_ensures(self.geometry.graph().node_count() == old(self.geometry.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
|
||||
fn insert_into_rtree_with_legs(&mut self, node: GeometryIndex) {
|
||||
fn insert_into_rtree_with_limbs(&mut self, node: GeometryIndex) {
|
||||
self.insert_into_rtree(node);
|
||||
|
||||
for leg in node.primitive(self).legs() {
|
||||
self.insert_into_rtree(leg);
|
||||
for limb in node.primitive(self).limbs() {
|
||||
self.insert_into_rtree(limb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -939,9 +939,9 @@ impl Layout {
|
|||
|
||||
#[debug_ensures(self.geometry.graph().node_count() == old(self.geometry.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
|
||||
fn remove_from_rtree_with_legs(&mut self, node: GeometryIndex) {
|
||||
for leg in node.primitive(self).legs() {
|
||||
self.remove_from_rtree(leg);
|
||||
fn remove_from_rtree_with_limbs(&mut self, node: GeometryIndex) {
|
||||
for limb in node.primitive(self).limbs() {
|
||||
self.remove_from_rtree(limb);
|
||||
}
|
||||
|
||||
self.remove_from_rtree(node);
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ pub enum GeometryIndex {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum GeometryLabel {
|
||||
Joint,
|
||||
Connection,
|
||||
Outer,
|
||||
Core,
|
||||
}
|
||||
|
|
@ -153,9 +153,9 @@ pub struct Geometry<
|
|||
SW: SegWeightTrait<GW> + Copy,
|
||||
BW: BendWeightTrait<GW> + Copy,
|
||||
GI: GetNodeIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
|
||||
DI: GetNodeIndex + Copy,
|
||||
SI: GetNodeIndex + Copy,
|
||||
BI: GetNodeIndex + Copy,
|
||||
DI: GetNodeIndex + Into<GI> + Copy,
|
||||
SI: GetNodeIndex + Into<GI> + Copy,
|
||||
BI: GetNodeIndex + Into<GI> + Copy,
|
||||
> {
|
||||
pub graph: StableDiGraph<GW, GeometryLabel, usize>,
|
||||
weight_marker: PhantomData<GW>,
|
||||
|
|
@ -174,9 +174,9 @@ impl<
|
|||
SW: SegWeightTrait<GW> + Copy,
|
||||
BW: BendWeightTrait<GW> + Copy,
|
||||
GI: GetNodeIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
|
||||
DI: GetNodeIndex + Copy,
|
||||
SI: GetNodeIndex + Copy,
|
||||
BI: GetNodeIndex + Copy,
|
||||
DI: GetNodeIndex + Into<GI> + Copy,
|
||||
SI: GetNodeIndex + Into<GI> + Copy,
|
||||
BI: GetNodeIndex + Into<GI> + Copy,
|
||||
> Geometry<GW, DW, SW, BW, GI, DI, SI, BI>
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
|
|
@ -205,10 +205,13 @@ impl<
|
|||
) -> GenericIndex<W> {
|
||||
let seg = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph.update_edge(
|
||||
from.node_index(),
|
||||
seg.node_index(),
|
||||
GeometryLabel::Connection,
|
||||
);
|
||||
self.graph
|
||||
.update_edge(from.node_index(), seg.node_index(), GeometryLabel::Joint);
|
||||
self.graph
|
||||
.update_edge(seg.node_index(), to.node_index(), GeometryLabel::Joint);
|
||||
.update_edge(seg.node_index(), to.node_index(), GeometryLabel::Connection);
|
||||
|
||||
seg
|
||||
}
|
||||
|
|
@ -222,10 +225,16 @@ impl<
|
|||
) -> GenericIndex<W> {
|
||||
let bend = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph
|
||||
.update_edge(from.node_index(), bend.node_index(), GeometryLabel::Joint);
|
||||
self.graph
|
||||
.update_edge(bend.node_index(), to.node_index(), GeometryLabel::Joint);
|
||||
self.graph.update_edge(
|
||||
from.node_index(),
|
||||
bend.node_index(),
|
||||
GeometryLabel::Connection,
|
||||
);
|
||||
self.graph.update_edge(
|
||||
bend.node_index(),
|
||||
to.node_index(),
|
||||
GeometryLabel::Connection,
|
||||
);
|
||||
self.graph
|
||||
.update_edge(bend.node_index(), core.node_index(), GeometryLabel::Core);
|
||||
|
||||
|
|
@ -243,20 +252,20 @@ impl<
|
|||
}
|
||||
|
||||
pub fn seg_shape(&self, seg: SI) -> Shape {
|
||||
let joint_weights = self.joint_weights(seg.node_index());
|
||||
let (from, to) = self.seg_joints(seg);
|
||||
Shape::Seg(SegShape {
|
||||
from: joint_weights[0].pos(),
|
||||
to: joint_weights[1].pos(),
|
||||
from: self.dot_weight(from).pos(),
|
||||
to: self.dot_weight(to).pos(),
|
||||
width: self.weight(seg.node_index()).width(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bend_shape(&self, bend: BI) -> Shape {
|
||||
let joint_weights = self.joint_weights(bend.node_index());
|
||||
let (from, to) = self.bend_joints(bend);
|
||||
let core_weight = self.core_weight(bend);
|
||||
Shape::Bend(BendShape {
|
||||
from: joint_weights[0].pos(),
|
||||
to: joint_weights[1].pos(),
|
||||
from: self.dot_weight(from).pos(),
|
||||
to: self.dot_weight(to).pos(),
|
||||
c: Circle {
|
||||
pos: core_weight.pos(),
|
||||
r: self.inner_radius(bend),
|
||||
|
|
@ -285,56 +294,37 @@ impl<
|
|||
*self.graph.node_weight(index).unwrap()
|
||||
}
|
||||
|
||||
fn dot_weight(&self, dot: DI) -> DW {
|
||||
pub fn dot_weight(&self, dot: DI) -> DW {
|
||||
self.weight(dot.node_index())
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
}
|
||||
|
||||
fn seg_weight(&self, seg: SI) -> SW {
|
||||
pub fn seg_weight(&self, seg: SI) -> SW {
|
||||
self.weight(seg.node_index())
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
}
|
||||
|
||||
fn bend_weight(&self, bend: BI) -> BW {
|
||||
pub fn bend_weight(&self, bend: BI) -> BW {
|
||||
self.weight(bend.node_index())
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
}
|
||||
|
||||
fn joint_weights(&self, index: NodeIndex<usize>) -> Vec<DW> {
|
||||
self.graph
|
||||
.neighbors_undirected(index)
|
||||
.filter(|node| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge_undirected(index, *node).unwrap().0,)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joint
|
||||
)
|
||||
})
|
||||
.map(|node| {
|
||||
self.weight(node)
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn core_weight(&self, bend: BI) -> DW {
|
||||
self.graph
|
||||
.neighbors(bend.node_index())
|
||||
.filter(|node| {
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge(bend.node_index(), *node).unwrap())
|
||||
.edge_weight(self.graph.find_edge(bend.node_index(), *ni).unwrap())
|
||||
.unwrap(),
|
||||
GeometryLabel::Core
|
||||
)
|
||||
})
|
||||
.map(|node| {
|
||||
self.weight(node)
|
||||
.map(|ni| {
|
||||
self.weight(ni)
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
|
|
@ -342,22 +332,60 @@ impl<
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn first_rail(&self, index: NodeIndex<usize>) -> Option<BI> {
|
||||
pub fn seg_joints(&self, seg: SI) -> (DI, DI) {
|
||||
let v: Vec<_> = self.connections(seg.into()).collect();
|
||||
(
|
||||
v[0].try_into().unwrap_or_else(|_| unreachable!()),
|
||||
v[1].try_into().unwrap_or_else(|_| unreachable!()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn bend_joints(&self, bend: BI) -> (DI, DI) {
|
||||
let v: Vec<_> = self.connections(bend.into()).collect();
|
||||
(
|
||||
v[0].try_into().unwrap_or_else(|_| unreachable!()),
|
||||
v[1].try_into().unwrap_or_else(|_| unreachable!()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn connections(&self, node: GI) -> impl Iterator<Item = GI> + '_ {
|
||||
self.graph
|
||||
.neighbors_directed(index, Incoming)
|
||||
.filter(|node| {
|
||||
.neighbors_undirected(node.node_index())
|
||||
.filter(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge(*node, index).unwrap())
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(node.node_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Connection
|
||||
)
|
||||
})
|
||||
.map(|ni| {
|
||||
self.weight(ni)
|
||||
.retag(ni)
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn first_rail(&self, node: NodeIndex<usize>) -> Option<BI> {
|
||||
self.graph
|
||||
.neighbors_directed(node, Incoming)
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge(*ni, node).unwrap())
|
||||
.unwrap(),
|
||||
GeometryLabel::Core
|
||||
)
|
||||
})
|
||||
.map(|node| {
|
||||
self.graph
|
||||
.node_weight(node)
|
||||
.unwrap()
|
||||
.retag(node)
|
||||
.map(|ni| {
|
||||
self.weight(ni)
|
||||
.retag(ni)
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
|
|
@ -367,19 +395,17 @@ impl<
|
|||
pub fn core(&self, bend: BI) -> DI {
|
||||
self.graph
|
||||
.neighbors(bend.node_index())
|
||||
.filter(|node| {
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge(bend.node_index(), *node).unwrap())
|
||||
.edge_weight(self.graph.find_edge(bend.node_index(), *ni).unwrap())
|
||||
.unwrap(),
|
||||
GeometryLabel::Core
|
||||
)
|
||||
})
|
||||
.map(|node| {
|
||||
self.graph
|
||||
.node_weight(node)
|
||||
.unwrap()
|
||||
.retag(node)
|
||||
.map(|ni| {
|
||||
self.weight(ni)
|
||||
.retag(ni)
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
|
|
@ -390,19 +416,17 @@ impl<
|
|||
pub fn inner(&self, bend: BI) -> Option<BI> {
|
||||
self.graph
|
||||
.neighbors_directed(bend.node_index(), Incoming)
|
||||
.filter(|node| {
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge(*node, bend.node_index()).unwrap())
|
||||
.edge_weight(self.graph.find_edge(*ni, bend.node_index()).unwrap())
|
||||
.unwrap(),
|
||||
GeometryLabel::Outer
|
||||
)
|
||||
})
|
||||
.map(|node| {
|
||||
self.graph
|
||||
.node_weight(node)
|
||||
.unwrap()
|
||||
.retag(node)
|
||||
.map(|ni| {
|
||||
self.weight(ni)
|
||||
.retag(ni)
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
|
|
@ -412,19 +436,17 @@ impl<
|
|||
pub fn outer(&self, bend: BI) -> Option<BI> {
|
||||
self.graph
|
||||
.neighbors_directed(bend.node_index(), Outgoing)
|
||||
.filter(|node| {
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge(bend.node_index(), *node).unwrap())
|
||||
.edge_weight(self.graph.find_edge(bend.node_index(), *ni).unwrap())
|
||||
.unwrap(),
|
||||
GeometryLabel::Outer
|
||||
)
|
||||
})
|
||||
.map(|node| {
|
||||
self.graph
|
||||
.node_weight(node)
|
||||
.unwrap()
|
||||
.retag(node)
|
||||
.map(|ni| {
|
||||
self.weight(ni)
|
||||
.retag(ni)
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
geometry::{GeometryIndex, MakePrimitive},
|
||||
seg::{LoneLooseSegIndex, SeqLooseSegIndex},
|
||||
},
|
||||
primitive::{GetEnds, LoneLooseSeg, LooseBend, LooseDot, Primitive, SeqLooseSeg},
|
||||
primitive::{GetJoints, LoneLooseSeg, LooseBend, LooseDot, Primitive, SeqLooseSeg},
|
||||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
@ -80,7 +80,7 @@ impl<'a> GetNextLoose for LoneLooseSeg<'a> {
|
|||
|
||||
impl<'a> GetNextLoose for SeqLooseSeg<'a> {
|
||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||
let ends = self.ends();
|
||||
let ends = self.joints();
|
||||
let Some(prev) = maybe_prev else {
|
||||
return Some(ends.1.into());
|
||||
};
|
||||
|
|
@ -98,7 +98,7 @@ impl<'a> GetNextLoose for SeqLooseSeg<'a> {
|
|||
|
||||
impl<'a> GetNextLoose for LooseBend<'a> {
|
||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||
let ends = self.ends();
|
||||
let ends = self.joints();
|
||||
let Some(prev) = maybe_prev else {
|
||||
unreachable!();
|
||||
};
|
||||
|
|
|
|||
250
src/primitive.rs
250
src/primitive.rs
|
|
@ -4,6 +4,7 @@ use petgraph::Direction::{Incoming, Outgoing};
|
|||
|
||||
use crate::connectivity::{BandIndex, ComponentIndex, GetNet};
|
||||
use crate::graph::{GenericIndex, GetNodeIndex};
|
||||
use crate::layout::dot::DotWeight;
|
||||
use crate::layout::seg::{
|
||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
||||
SeqLooseSegIndex, SeqLooseSegWeight,
|
||||
|
|
@ -47,8 +48,8 @@ pub trait MakeShape {
|
|||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait GetLegs {
|
||||
fn legs(&self) -> Vec<GeometryIndex> {
|
||||
pub trait GetLimbs {
|
||||
fn limbs(&self) -> Vec<GeometryIndex> {
|
||||
let mut v = vec![];
|
||||
v.extend(self.segs().into_iter().map(Into::<GeometryIndex>::into));
|
||||
v.extend(self.bends().into_iter().map(Into::<GeometryIndex>::into));
|
||||
|
|
@ -68,9 +69,9 @@ pub trait GetInterior<T> {
|
|||
fn interior(&self) -> Vec<T>;
|
||||
}
|
||||
|
||||
pub trait GetOtherEnd<F: GetNodeIndex, T: GetNodeIndex + Into<F>>: GetEnds<F, T> {
|
||||
fn other_end(&self, end: F) -> F {
|
||||
let ends = self.ends();
|
||||
pub trait GetOtherJoint<F: GetNodeIndex, T: GetNodeIndex + Into<F>>: GetJoints<F, T> {
|
||||
fn other_joint(&self, end: F) -> F {
|
||||
let ends = self.joints();
|
||||
if ends.0.node_index() != end.node_index() {
|
||||
ends.0
|
||||
} else {
|
||||
|
|
@ -79,8 +80,8 @@ pub trait GetOtherEnd<F: GetNodeIndex, T: GetNodeIndex + Into<F>>: GetEnds<F, T>
|
|||
}
|
||||
}
|
||||
|
||||
pub trait GetEnds<F, T> {
|
||||
fn ends(&self) -> (F, T);
|
||||
pub trait GetJoints<F, T> {
|
||||
fn joints(&self) -> (F, T);
|
||||
}
|
||||
|
||||
pub trait GetFirstRail: GetLayout + GetNodeIndex {
|
||||
|
|
@ -88,7 +89,7 @@ pub trait GetFirstRail: GetLayout + GetNodeIndex {
|
|||
self.layout()
|
||||
.geometry()
|
||||
.first_rail(self.node_index())
|
||||
.map(|node| LooseBendIndex::new(node.node_index()))
|
||||
.map(|ni| LooseBendIndex::new(ni.node_index()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,14 +113,14 @@ pub trait GetInnerOuter: GetLayout + GetBendIndex {
|
|||
self.layout()
|
||||
.geometry()
|
||||
.inner(self.bend_index())
|
||||
.map(|node| LooseBendIndex::new(node.node_index()))
|
||||
.map(|ni| LooseBendIndex::new(ni.node_index()))
|
||||
}
|
||||
|
||||
fn outer(&self) -> Option<LooseBendIndex> {
|
||||
self.layout()
|
||||
.geometry()
|
||||
.outer(self.bend_index())
|
||||
.map(|node| LooseBendIndex::new(node.node_index()))
|
||||
.map(|ni| LooseBendIndex::new(ni.node_index()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +176,7 @@ macro_rules! impl_loose_primitive {
|
|||
};
|
||||
}
|
||||
|
||||
#[enum_dispatch(GetNet, GetWidth, GetLayout, GetConnectable, MakeShape, GetLegs)]
|
||||
#[enum_dispatch(GetNet, GetWidth, GetLayout, GetConnectable, MakeShape, GetLimbs)]
|
||||
pub enum Primitive<'a> {
|
||||
FixedDot(FixedDot<'a>),
|
||||
LooseDot(LooseDot<'a>),
|
||||
|
|
@ -206,31 +207,6 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
fn joints(&self) -> Vec<NodeIndex<usize>> {
|
||||
self.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.neighbors_undirected(self.index.node_index())
|
||||
.filter(|node| {
|
||||
matches!(
|
||||
self.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.edge_weight(
|
||||
self.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.find_edge_undirected(self.index.node_index(), *node)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joint
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn primitive<WW>(&self, index: GenericIndex<WW>) -> GenericPrimitive<WW> {
|
||||
GenericPrimitive::new(index, &self.layout)
|
||||
}
|
||||
|
|
@ -270,16 +246,25 @@ impl_fixed_primitive!(FixedDot, FixedDotWeight);
|
|||
|
||||
impl<'a> FixedDot<'a> {
|
||||
pub fn first_loose(&self, _band: BandIndex) -> Option<LooseIndex> {
|
||||
self.joints().into_iter().find_map(|node| {
|
||||
let weight = self.layout.geometry().graph().node_weight(node).unwrap();
|
||||
if matches!(weight, GeometryWeight::LoneLooseSeg(..)) {
|
||||
Some(LoneLooseSegIndex::new(node).into())
|
||||
} else if matches!(weight, GeometryWeight::SeqLooseSeg(..)) {
|
||||
Some(SeqLooseSegIndex::new(node).into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
self.layout
|
||||
.geometry()
|
||||
.connections(self.index.into())
|
||||
.into_iter()
|
||||
.find_map(|ni| {
|
||||
let weight = self
|
||||
.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.node_weight(ni.node_index())
|
||||
.unwrap();
|
||||
if matches!(weight, GeometryWeight::LoneLooseSeg(..)) {
|
||||
Some(LoneLooseSegIndex::new(ni.node_index()).into())
|
||||
} else if matches!(weight, GeometryWeight::SeqLooseSeg(..)) {
|
||||
Some(SeqLooseSegIndex::new(ni.node_index()).into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -289,37 +274,51 @@ impl<'a> MakeShape for FixedDot<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetLegs for FixedDot<'a> {
|
||||
impl<'a> GetLimbs for FixedDot<'a> {
|
||||
fn segs(&self) -> Vec<SegIndex> {
|
||||
self.joints()
|
||||
self.layout
|
||||
.geometry()
|
||||
.connections(self.index.into())
|
||||
.into_iter()
|
||||
.filter_map(
|
||||
|node| match self.layout.geometry().graph().node_weight(node).unwrap() {
|
||||
GeometryWeight::FixedSeg(_seg) => {
|
||||
Some(SegIndex::Fixed(FixedSegIndex::new(node)))
|
||||
}
|
||||
GeometryWeight::LoneLooseSeg(_seg) => {
|
||||
Some(SegIndex::LoneLoose(LoneLooseSegIndex::new(node).into()))
|
||||
}
|
||||
GeometryWeight::SeqLooseSeg(_seg) => {
|
||||
Some(SegIndex::SeqLoose(SeqLooseSegIndex::new(node).into()))
|
||||
.filter_map(|ni| {
|
||||
match self
|
||||
.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.node_weight(ni.node_index())
|
||||
.unwrap()
|
||||
{
|
||||
GeometryWeight::FixedSeg(..) => {
|
||||
Some(SegIndex::Fixed(FixedSegIndex::new(ni.node_index())))
|
||||
}
|
||||
GeometryWeight::LoneLooseSeg(..) => Some(SegIndex::LoneLoose(
|
||||
LoneLooseSegIndex::new(ni.node_index()).into(),
|
||||
)),
|
||||
GeometryWeight::SeqLooseSeg(..) => Some(SegIndex::SeqLoose(
|
||||
SeqLooseSegIndex::new(ni.node_index()).into(),
|
||||
)),
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn bends(&self) -> Vec<BendIndex> {
|
||||
self.joints()
|
||||
self.layout
|
||||
.geometry()
|
||||
.connections(self.index.into())
|
||||
.into_iter()
|
||||
.filter(|node| {
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.layout.geometry().graph().node_weight(*node).unwrap(),
|
||||
self.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.node_weight(ni.node_index())
|
||||
.unwrap(),
|
||||
GeometryWeight::FixedBend(..)
|
||||
)
|
||||
})
|
||||
.map(|node| FixedBendIndex::new(node).into())
|
||||
.map(|ni| FixedBendIndex::new(ni.node_index()).into())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
@ -331,28 +330,40 @@ impl_loose_primitive!(LooseDot, LooseDotWeight);
|
|||
|
||||
impl<'a> LooseDot<'a> {
|
||||
pub fn seg(&self) -> Option<SeqLooseSegIndex> {
|
||||
self.joints()
|
||||
self.layout
|
||||
.geometry()
|
||||
.connections(self.index.into())
|
||||
.into_iter()
|
||||
.filter(|node| {
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.layout.geometry().graph().node_weight(*node).unwrap(),
|
||||
self.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.node_weight(ni.node_index())
|
||||
.unwrap(),
|
||||
GeometryWeight::SeqLooseSeg(..)
|
||||
)
|
||||
})
|
||||
.map(|node| SeqLooseSegIndex::new(node))
|
||||
.map(|ni| SeqLooseSegIndex::new(ni.node_index()))
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn bend(&self) -> LooseBendIndex {
|
||||
self.joints()
|
||||
self.layout
|
||||
.geometry()
|
||||
.connections(self.index.into())
|
||||
.into_iter()
|
||||
.filter(|node| {
|
||||
.filter(|ni| {
|
||||
matches!(
|
||||
self.layout.geometry().graph().node_weight(*node).unwrap(),
|
||||
self.layout
|
||||
.geometry()
|
||||
.graph()
|
||||
.node_weight(ni.node_index())
|
||||
.unwrap(),
|
||||
GeometryWeight::LooseBend(..)
|
||||
)
|
||||
})
|
||||
.map(|node| LooseBendIndex::new(node))
|
||||
.map(|ni| LooseBendIndex::new(ni.node_index()))
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
|
|
@ -364,7 +375,7 @@ impl<'a> MakeShape for LooseDot<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetLegs for LooseDot<'a> {
|
||||
impl<'a> GetLimbs for LooseDot<'a> {
|
||||
fn segs(&self) -> Vec<SegIndex> {
|
||||
if let Some(seg) = self.seg() {
|
||||
vec![seg.into()]
|
||||
|
|
@ -387,16 +398,19 @@ impl<'a> MakeShape for FixedSeg<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetLegs for FixedSeg<'a> {}
|
||||
impl<'a> GetLimbs for FixedSeg<'a> {}
|
||||
|
||||
impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
|
||||
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let v = self.joints();
|
||||
(FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1]))
|
||||
impl<'a> GetJoints<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
|
||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let (from, to) = self.layout.geometry().seg_joints(self.index.into());
|
||||
(
|
||||
FixedDotIndex::new(from.node_index()),
|
||||
FixedDotIndex::new(to.node_index()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {}
|
||||
impl<'a> GetOtherJoint<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {}
|
||||
|
||||
pub type LoneLooseSeg<'a> = GenericPrimitive<'a, LoneLooseSegWeight>;
|
||||
impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight);
|
||||
|
|
@ -407,16 +421,19 @@ impl<'a> MakeShape for LoneLooseSeg<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetLegs for LoneLooseSeg<'a> {}
|
||||
impl<'a> GetLimbs for LoneLooseSeg<'a> {}
|
||||
|
||||
impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a> {
|
||||
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let v = self.joints();
|
||||
(FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1]))
|
||||
impl<'a> GetJoints<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a> {
|
||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let (from, to) = self.layout.geometry().seg_joints(self.index.into());
|
||||
(
|
||||
FixedDotIndex::new(from.node_index()),
|
||||
FixedDotIndex::new(to.node_index()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a> {}
|
||||
impl<'a> GetOtherJoint<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a> {}
|
||||
|
||||
pub type SeqLooseSeg<'a> = GenericPrimitive<'a, SeqLooseSegWeight>;
|
||||
impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight);
|
||||
|
|
@ -427,26 +444,31 @@ impl<'a> MakeShape for SeqLooseSeg<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetLegs for SeqLooseSeg<'a> {}
|
||||
impl<'a> GetLimbs for SeqLooseSeg<'a> {}
|
||||
|
||||
impl<'a> GetEnds<DotIndex, LooseDotIndex> for SeqLooseSeg<'a> {
|
||||
fn ends(&self) -> (DotIndex, LooseDotIndex) {
|
||||
let v = self.joints();
|
||||
if let GeometryWeight::FixedDot(..) =
|
||||
self.layout.geometry().graph().node_weight(v[0]).unwrap()
|
||||
{
|
||||
(FixedDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
|
||||
} else if let GeometryWeight::FixedDot(..) =
|
||||
self.layout.geometry().graph().node_weight(v[1]).unwrap()
|
||||
{
|
||||
(FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0]))
|
||||
impl<'a> GetJoints<DotIndex, LooseDotIndex> for SeqLooseSeg<'a> {
|
||||
fn joints(&self) -> (DotIndex, LooseDotIndex) {
|
||||
let joints = self.layout.geometry().seg_joints(self.index.into());
|
||||
if let DotWeight::Fixed(..) = self.layout.geometry().dot_weight(joints.0) {
|
||||
(
|
||||
FixedDotIndex::new(joints.0.node_index()).into(),
|
||||
LooseDotIndex::new(joints.1.node_index()).into(),
|
||||
)
|
||||
} else if let DotWeight::Fixed(..) = self.layout.geometry().dot_weight(joints.1) {
|
||||
(
|
||||
FixedDotIndex::new(joints.1.node_index()).into(),
|
||||
LooseDotIndex::new(joints.0.node_index()),
|
||||
)
|
||||
} else {
|
||||
(LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
|
||||
(
|
||||
LooseDotIndex::new(joints.0.node_index()).into(),
|
||||
LooseDotIndex::new(joints.1.node_index()).into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> for SeqLooseSeg<'a> {}
|
||||
impl<'a> GetOtherJoint<DotIndex, LooseDotIndex> for SeqLooseSeg<'a> {}
|
||||
|
||||
pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>;
|
||||
impl_fixed_primitive!(FixedBend, FixedBendWeight);
|
||||
|
|
@ -463,16 +485,19 @@ impl<'a> MakeShape for FixedBend<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetLegs for FixedBend<'a> {}
|
||||
impl<'a> GetLimbs for FixedBend<'a> {}
|
||||
|
||||
impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {
|
||||
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let v = self.joints();
|
||||
(FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1]))
|
||||
impl<'a> GetJoints<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {
|
||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let (from, to) = self.layout.geometry().bend_joints(self.index.into());
|
||||
(
|
||||
FixedDotIndex::new(from.node_index()),
|
||||
FixedDotIndex::new(to.node_index()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {}
|
||||
impl<'a> GetOtherJoint<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {}
|
||||
impl<'a> GetFirstRail for FixedBend<'a> {}
|
||||
impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actually.
|
||||
//impl<'a> GetInnerOuter for FixedBend<'a> {}
|
||||
|
|
@ -498,7 +523,7 @@ impl<'a> MakeShape for LooseBend<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetLegs for LooseBend<'a> {}
|
||||
impl<'a> GetLimbs for LooseBend<'a> {}
|
||||
|
||||
impl<'a> GetOffset for LooseBend<'a> {
|
||||
fn offset(&self) -> f64 {
|
||||
|
|
@ -506,13 +531,16 @@ impl<'a> GetOffset for LooseBend<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetEnds<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {
|
||||
fn ends(&self) -> (LooseDotIndex, LooseDotIndex) {
|
||||
let v = self.joints();
|
||||
(LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1]))
|
||||
impl<'a> GetJoints<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {
|
||||
fn joints(&self) -> (LooseDotIndex, LooseDotIndex) {
|
||||
let (from, to) = self.layout.geometry().bend_joints(self.index.into());
|
||||
(
|
||||
LooseDotIndex::new(from.node_index()),
|
||||
LooseDotIndex::new(to.node_index()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {}
|
||||
impl<'a> GetOtherJoint<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {}
|
||||
impl<'a> GetCore for LooseBend<'a> {}
|
||||
impl<'a> GetInnerOuter for LooseBend<'a> {}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
layout::{
|
||||
bend::LooseBendIndex, dot::LooseDotIndex, geometry::GeometryIndex, seg::SeqLooseSegIndex,
|
||||
},
|
||||
primitive::{GetEnds, GetInterior, GetOtherEnd, LooseBend, LooseDot},
|
||||
primitive::{GetInterior, GetJoints, GetOtherJoint, LooseBend, LooseDot},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
@ -16,7 +16,7 @@ pub struct Segbend {
|
|||
impl Segbend {
|
||||
pub fn from_dot(dot: LooseDotIndex, layout: &Layout) -> Self {
|
||||
let bend = LooseDot::new(dot, layout).bend();
|
||||
let dot = LooseBend::new(bend, layout).other_end(dot);
|
||||
let dot = LooseBend::new(bend, layout).other_joint(dot);
|
||||
let seg = LooseDot::new(dot, layout).seg().unwrap();
|
||||
Self { bend, dot, seg }
|
||||
}
|
||||
|
|
@ -28,8 +28,8 @@ impl GetInterior<GeometryIndex> for Segbend {
|
|||
}
|
||||
}
|
||||
|
||||
impl GetEnds<SeqLooseSegIndex, LooseBendIndex> for Segbend {
|
||||
fn ends(&self) -> (SeqLooseSegIndex, LooseBendIndex) {
|
||||
impl GetJoints<SeqLooseSegIndex, LooseBendIndex> for Segbend {
|
||||
fn joints(&self) -> (SeqLooseSegIndex, LooseBendIndex) {
|
||||
(self.seg, self.bend)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue