geometry,primitive: move first rail, core, inner, outer to `Geometry`

This commit is contained in:
Mikolaj Wielgus 2024-01-28 18:25:02 +00:00
parent 4bb513ee08
commit 4c3d0062b0
4 changed files with 142 additions and 106 deletions

View File

@ -44,6 +44,7 @@ use crate::shape::{Shape, ShapeTrait};
use crate::wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex}; use crate::wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex};
use self::bend::BendWeight; use self::bend::BendWeight;
use self::seg::SegWeight;
pub type RTreeWrapper = GeomWithData<Shape, GeometryIndex>; pub type RTreeWrapper = GeomWithData<Shape, GeometryIndex>;
@ -77,7 +78,16 @@ pub struct AlreadyConnected(pub i64, pub GeometryIndex);
pub struct Layout { pub struct Layout {
rtree: RTree<RTreeWrapper>, rtree: RTree<RTreeWrapper>,
connectivity: ConnectivityGraph, connectivity: ConnectivityGraph,
geometry: Geometry<GeometryWeight, DotWeight, BendWeight, DotIndex, SegIndex, BendIndex>, geometry: Geometry<
GeometryWeight,
DotWeight,
SegWeight,
BendWeight,
GeometryIndex,
DotIndex,
SegIndex,
BendIndex,
>,
} }
#[debug_invariant(self.geometry.graph().node_count() == self.rtree.size())] #[debug_invariant(self.geometry.graph().node_count() == self.rtree.size())]
@ -957,7 +967,16 @@ impl Layout {
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))] #[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
pub fn geometry( pub fn geometry(
&self, &self,
) -> &Geometry<GeometryWeight, DotWeight, BendWeight, DotIndex, SegIndex, BendIndex> { ) -> &Geometry<
GeometryWeight,
DotWeight,
SegWeight,
BendWeight,
GeometryIndex,
DotIndex,
SegIndex,
BendIndex,
> {
&self.geometry &self.geometry
} }

View File

@ -4,7 +4,7 @@ use enum_dispatch::enum_dispatch;
use geo::Point; use geo::Point;
use petgraph::{ use petgraph::{
stable_graph::{NodeIndex, StableDiGraph}, stable_graph::{NodeIndex, StableDiGraph},
Direction::Incoming, Direction::{Incoming, Outgoing},
}; };
use crate::{ use crate::{
@ -26,7 +26,7 @@ use super::{
}; };
#[enum_dispatch] #[enum_dispatch]
pub trait Retag { pub trait Retag<GeometryIndex> {
fn retag(&self, index: NodeIndex<usize>) -> GeometryIndex; fn retag(&self, index: NodeIndex<usize>) -> GeometryIndex;
} }
@ -60,7 +60,7 @@ pub trait GetOffset {
macro_rules! impl_weight { macro_rules! impl_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl Retag for $weight_struct { impl Retag<GeometryIndex> for $weight_struct {
fn retag(&self, index: NodeIndex<usize>) -> GeometryIndex { fn retag(&self, index: NodeIndex<usize>) -> GeometryIndex {
GeometryIndex::$weight_variant($index_struct::new(index)) GeometryIndex::$weight_variant($index_struct::new(index))
} }
@ -106,7 +106,7 @@ macro_rules! impl_loose_weight {
}; };
} }
#[enum_dispatch(GetWidth, Retag)] #[enum_dispatch(GetWidth, Retag<GeometryIndex>)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum GeometryWeight { pub enum GeometryWeight {
FixedDot(FixedDotWeight), FixedDot(FixedDotWeight),
@ -148,37 +148,45 @@ pub trait BendWeightTrait<GW>: GetOffset + GetWidth + Into<GW> + Copy {}
#[derive(Debug)] #[derive(Debug)]
pub struct Geometry< pub struct Geometry<
GW: GetWidth + TryInto<DW> + TryInto<BW> + Copy, GW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<GI> + Copy,
DW: DotWeightTrait<GW>, DW: DotWeightTrait<GW> + Copy,
BW: BendWeightTrait<GW>, SW: SegWeightTrait<GW> + Copy,
DI: GetNodeIndex, BW: BendWeightTrait<GW> + Copy,
SI: GetNodeIndex, GI: GetNodeIndex + Copy,
BI: GetNodeIndex, DI: GetNodeIndex + Copy,
SI: GetNodeIndex + Copy,
BI: GetNodeIndex + Copy,
> { > {
pub graph: StableDiGraph<GW, GeometryLabel, usize>, pub graph: StableDiGraph<GW, GeometryLabel, usize>,
weight_marker: PhantomData<GW>, weight_marker: PhantomData<GW>,
dot_weight_marker: PhantomData<DW>, dot_weight_marker: PhantomData<DW>,
seg_weight_marker: PhantomData<SW>,
bend_weight_marker: PhantomData<BW>, bend_weight_marker: PhantomData<BW>,
index_marker: PhantomData<GI>,
dot_index_marker: PhantomData<DI>, dot_index_marker: PhantomData<DI>,
seg_index_marker: PhantomData<SI>, seg_index_marker: PhantomData<SI>,
bend_index_marker: PhantomData<BI>, bend_index_marker: PhantomData<BI>,
} }
impl< impl<
GW: GetWidth + TryInto<DW> + TryInto<BW> + Copy, GW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<GI> + Copy,
DW: DotWeightTrait<GW>, DW: DotWeightTrait<GW> + Copy,
BW: BendWeightTrait<GW>, SW: SegWeightTrait<GW> + Copy,
BW: BendWeightTrait<GW> + Copy,
GI: GetNodeIndex + Copy,
DI: GetNodeIndex + Copy, DI: GetNodeIndex + Copy,
SI: GetNodeIndex + Copy, SI: GetNodeIndex + Copy,
BI: GetNodeIndex + Copy, BI: GetNodeIndex + Copy,
> Geometry<GW, DW, BW, DI, SI, BI> > Geometry<GW, DW, SW, BW, GI, DI, SI, BI>
{ {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
graph: StableDiGraph::default(), graph: StableDiGraph::default(),
weight_marker: PhantomData, weight_marker: PhantomData,
dot_weight_marker: PhantomData, dot_weight_marker: PhantomData,
seg_weight_marker: PhantomData,
bend_weight_marker: PhantomData, bend_weight_marker: PhantomData,
index_marker: PhantomData,
dot_index_marker: PhantomData, dot_index_marker: PhantomData,
seg_index_marker: PhantomData, seg_index_marker: PhantomData,
bend_index_marker: PhantomData, bend_index_marker: PhantomData,
@ -273,20 +281,6 @@ impl<
self.core_weight(bend).width() / 2.0 + r self.core_weight(bend).width() / 2.0 + r
} }
fn inner(&self, index: NodeIndex<usize>) -> Option<NodeIndex<usize>> {
self.graph
.neighbors_directed(index, Incoming)
.filter(|node| {
matches!(
self.graph
.edge_weight(self.graph.find_edge(*node, index).unwrap())
.unwrap(),
GeometryLabel::Outer
)
})
.next()
}
fn weight(&self, index: NodeIndex<usize>) -> GW { fn weight(&self, index: NodeIndex<usize>) -> GW {
*self.graph.node_weight(index).unwrap() *self.graph.node_weight(index).unwrap()
} }
@ -297,6 +291,12 @@ impl<
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
} }
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 { fn bend_weight(&self, bend: BI) -> BW {
self.weight(bend.node_index()) self.weight(bend.node_index())
.try_into() .try_into()
@ -342,6 +342,62 @@ impl<
.unwrap() .unwrap()
} }
pub fn first_rail(&self, index: NodeIndex<usize>) -> Option<NodeIndex<usize>> {
self.graph
.neighbors_directed(index, Incoming)
.filter(|node| {
matches!(
self.graph
.edge_weight(self.graph.find_edge(*node, index).unwrap())
.unwrap(),
GeometryLabel::Core
)
})
.next()
}
pub fn core(&self, index: NodeIndex<usize>) -> Option<NodeIndex<usize>> {
self.graph
.neighbors(index)
.filter(|node| {
matches!(
self.graph
.edge_weight(self.graph.find_edge(index, *node).unwrap())
.unwrap(),
GeometryLabel::Core
)
})
.next()
}
pub fn inner(&self, index: NodeIndex<usize>) -> Option<NodeIndex<usize>> {
self.graph
.neighbors_directed(index, Incoming)
.filter(|node| {
matches!(
self.graph
.edge_weight(self.graph.find_edge(*node, index).unwrap())
.unwrap(),
GeometryLabel::Outer
)
})
.next()
}
pub fn outer(&self, index: NodeIndex<usize>) -> Option<NodeIndex<usize>> {
self.graph
.neighbors_directed(index, Outgoing)
.filter(|node| {
matches!(
self.graph
.edge_weight(self.graph.find_edge(index, *node).unwrap())
.unwrap(),
GeometryLabel::Outer
)
})
.next()
}
pub fn graph(&self) -> &StableDiGraph<GW, GeometryLabel, usize> { pub fn graph(&self) -> &StableDiGraph<GW, GeometryLabel, usize> {
&self.graph &self.graph
} }

View File

@ -31,6 +31,39 @@ impl From<SegIndex> for GeometryIndex {
} }
} }
#[enum_dispatch(GetWidth)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum SegWeight {
Fixed(FixedSegWeight),
LoneLoose(LoneLooseSegWeight),
SeqLoose(SeqLooseSegWeight),
}
impl From<SegWeight> for GeometryWeight {
fn from(seg: SegWeight) -> Self {
match seg {
SegWeight::Fixed(weight) => GeometryWeight::FixedSeg(weight),
SegWeight::LoneLoose(weight) => GeometryWeight::LoneLooseSeg(weight),
SegWeight::SeqLoose(weight) => GeometryWeight::SeqLooseSeg(weight),
}
}
}
impl TryFrom<GeometryWeight> for SegWeight {
type Error = (); // TODO.
fn try_from(weight: GeometryWeight) -> Result<SegWeight, ()> {
match weight {
GeometryWeight::FixedSeg(weight) => Ok(SegWeight::Fixed(weight)),
GeometryWeight::LoneLooseSeg(weight) => Ok(SegWeight::LoneLoose(weight)),
GeometryWeight::SeqLooseSeg(weight) => Ok(SegWeight::SeqLoose(weight)),
_ => unreachable!(),
}
}
}
impl SegWeightTrait<GeometryWeight> for SegWeight {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedSegWeight { pub struct FixedSegWeight {
pub component: ComponentIndex, pub component: ComponentIndex,

View File

@ -87,26 +87,8 @@ pub trait GetFirstRail: GetLayout + GetNodeIndex {
fn first_rail(&self) -> Option<LooseBendIndex> { fn first_rail(&self) -> Option<LooseBendIndex> {
self.layout() self.layout()
.geometry() .geometry()
.graph() .first_rail(self.node_index())
.neighbors_directed(self.node_index(), Incoming)
.filter(|node| {
matches!(
self.layout()
.geometry()
.graph()
.edge_weight(
self.layout()
.geometry()
.graph()
.find_edge(*node, self.node_index())
.unwrap()
)
.unwrap(),
GeometryLabel::Core
)
})
.map(|node| LooseBendIndex::new(node)) .map(|node| LooseBendIndex::new(node))
.next()
} }
} }
@ -114,26 +96,8 @@ pub trait GetCore: GetLayout + GetNodeIndex {
fn core(&self) -> FixedDotIndex { fn core(&self) -> FixedDotIndex {
self.layout() self.layout()
.geometry() .geometry()
.graph() .core(self.node_index())
.neighbors(self.node_index())
.filter(|node| {
matches!(
self.layout()
.geometry()
.graph()
.edge_weight(
self.layout()
.geometry()
.graph()
.find_edge(self.node_index(), *node)
.unwrap()
)
.unwrap(),
GeometryLabel::Core
)
})
.map(|node| FixedDotIndex::new(node)) .map(|node| FixedDotIndex::new(node))
.next()
.unwrap() .unwrap()
} }
} }
@ -142,51 +106,15 @@ pub trait GetInnerOuter: GetLayout + GetNodeIndex {
fn inner(&self) -> Option<LooseBendIndex> { fn inner(&self) -> Option<LooseBendIndex> {
self.layout() self.layout()
.geometry() .geometry()
.graph() .inner(self.node_index())
.neighbors_directed(self.node_index(), Incoming)
.filter(|node| {
matches!(
self.layout()
.geometry()
.graph()
.edge_weight(
self.layout()
.geometry()
.graph()
.find_edge(*node, self.node_index())
.unwrap()
)
.unwrap(),
GeometryLabel::Outer
)
})
.map(|node| LooseBendIndex::new(node)) .map(|node| LooseBendIndex::new(node))
.next()
} }
fn outer(&self) -> Option<LooseBendIndex> { fn outer(&self) -> Option<LooseBendIndex> {
self.layout() self.layout()
.geometry() .geometry()
.graph() .outer(self.node_index())
.neighbors_directed(self.node_index(), Outgoing)
.filter(|node| {
matches!(
self.layout()
.geometry()
.graph()
.edge_weight(
self.layout()
.geometry()
.graph()
.find_edge(self.node_index(), *node)
.unwrap()
)
.unwrap(),
GeometryLabel::Outer
)
})
.map(|node| LooseBendIndex::new(node)) .map(|node| LooseBendIndex::new(node))
.next()
} }
} }