From 684d0be641d25e3dca451dd6f24fd89e99ca3e79 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 28 Jan 2024 22:48:54 +0000 Subject: [PATCH] geometry,primitive: move more code and narrow typing further We replace all instances of `NodeIndex` 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". --- src/band.rs | 6 +- src/draw.rs | 6 +- src/guide.rs | 4 +- src/layout.rs | 28 ++--- src/layout/geometry.rs | 174 +++++++++++++++------------- src/loose.rs | 6 +- src/primitive.rs | 250 +++++++++++++++++++++++------------------ src/segbend.rs | 8 +- 8 files changed, 266 insertions(+), 216 deletions(-) diff --git a/src/band.rs b/src/band.rs index 2e4dffd..3878638 100644 --- a/src/band.rs +++ b/src/band.rs @@ -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 diff --git a/src/draw.rs b/src/draw.rs index 8a66cc6..a1ed5ef 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -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 { - 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); diff --git a/src/guide.rs b/src/guide.rs index 1cd8584..db4f468 100644 --- a/src/guide.rs +++ b/src/guide.rs @@ -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()) } } diff --git a/src/layout.rs b/src/layout.rs index d9ffcb1..b36c6b2 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -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 = 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); diff --git a/src/layout/geometry.rs b/src/layout/geometry.rs index fbf60b2..f16e739 100644 --- a/src/layout/geometry.rs +++ b/src/layout/geometry.rs @@ -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 + Copy, BW: BendWeightTrait + Copy, GI: GetNodeIndex + TryInto + TryInto + TryInto + Copy, - DI: GetNodeIndex + Copy, - SI: GetNodeIndex + Copy, - BI: GetNodeIndex + Copy, + DI: GetNodeIndex + Into + Copy, + SI: GetNodeIndex + Into + Copy, + BI: GetNodeIndex + Into + Copy, > { pub graph: StableDiGraph, weight_marker: PhantomData, @@ -174,9 +174,9 @@ impl< SW: SegWeightTrait + Copy, BW: BendWeightTrait + Copy, GI: GetNodeIndex + TryInto + TryInto + TryInto + Copy, - DI: GetNodeIndex + Copy, - SI: GetNodeIndex + Copy, - BI: GetNodeIndex + Copy, + DI: GetNodeIndex + Into + Copy, + SI: GetNodeIndex + Into + Copy, + BI: GetNodeIndex + Into + Copy, > Geometry { pub fn new() -> Self { @@ -205,10 +205,13 @@ impl< ) -> GenericIndex { let seg = GenericIndex::::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 { let bend = GenericIndex::::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) -> Vec { - 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) -> Option { + 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 + '_ { 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) -> Option { + 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 { 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 { 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!()) }) diff --git a/src/loose.rs b/src/loose.rs index 7f958a1..6df30ba 100644 --- a/src/loose.rs +++ b/src/loose.rs @@ -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) -> Option { - 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) -> Option { - let ends = self.ends(); + let ends = self.joints(); let Some(prev) = maybe_prev else { unreachable!(); }; diff --git a/src/primitive.rs b/src/primitive.rs index b078a9b..e52bccb 100644 --- a/src/primitive.rs +++ b/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 { +pub trait GetLimbs { + fn limbs(&self) -> Vec { let mut v = vec![]; v.extend(self.segs().into_iter().map(Into::::into)); v.extend(self.bends().into_iter().map(Into::::into)); @@ -68,9 +69,9 @@ pub trait GetInterior { fn interior(&self) -> Vec; } -pub trait GetOtherEnd>: GetEnds { - fn other_end(&self, end: F) -> F { - let ends = self.ends(); +pub trait GetOtherJoint>: GetJoints { + 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>: GetEnds } } -pub trait GetEnds { - fn ends(&self) -> (F, T); +pub trait GetJoints { + 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 { 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> { - 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(&self, index: GenericIndex) -> GenericPrimitive { 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 { - 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 { - 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 { - 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 { - 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 { 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 for FixedSeg<'a> { - fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { - let v = self.joints(); - (FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1])) +impl<'a> GetJoints 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 for FixedSeg<'a> {} +impl<'a> GetOtherJoint 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 for LoneLooseSeg<'a> { - fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { - let v = self.joints(); - (FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1])) +impl<'a> GetJoints 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 for LoneLooseSeg<'a> {} +impl<'a> GetOtherJoint 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 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 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 for SeqLooseSeg<'a> {} +impl<'a> GetOtherJoint 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 for FixedBend<'a> { - fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { - let v = self.joints(); - (FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1])) +impl<'a> GetJoints 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 for FixedBend<'a> {} +impl<'a> GetOtherJoint 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 for LooseBend<'a> { - fn ends(&self) -> (LooseDotIndex, LooseDotIndex) { - let v = self.joints(); - (LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1])) +impl<'a> GetJoints 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 for LooseBend<'a> {} +impl<'a> GetOtherJoint for LooseBend<'a> {} impl<'a> GetCore for LooseBend<'a> {} impl<'a> GetInnerOuter for LooseBend<'a> {} diff --git a/src/segbend.rs b/src/segbend.rs index 843375f..59e39e1 100644 --- a/src/segbend.rs +++ b/src/segbend.rs @@ -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 for Segbend { } } -impl GetEnds for Segbend { - fn ends(&self) -> (SeqLooseSegIndex, LooseBendIndex) { +impl GetJoints for Segbend { + fn joints(&self) -> (SeqLooseSegIndex, LooseBendIndex) { (self.seg, self.bend) } }