mirror of https://codeberg.org/topola/topola.git
geometry,primitive: move first rail, core, inner, outer to `Geometry`
This commit is contained in:
parent
4bb513ee08
commit
4c3d0062b0
|
|
@ -44,6 +44,7 @@ use crate::shape::{Shape, ShapeTrait};
|
|||
use crate::wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex};
|
||||
|
||||
use self::bend::BendWeight;
|
||||
use self::seg::SegWeight;
|
||||
|
||||
pub type RTreeWrapper = GeomWithData<Shape, GeometryIndex>;
|
||||
|
||||
|
|
@ -77,7 +78,16 @@ pub struct AlreadyConnected(pub i64, pub GeometryIndex);
|
|||
pub struct Layout {
|
||||
rtree: RTree<RTreeWrapper>,
|
||||
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())]
|
||||
|
|
@ -957,7 +967,16 @@ impl Layout {
|
|||
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
|
||||
pub fn geometry(
|
||||
&self,
|
||||
) -> &Geometry<GeometryWeight, DotWeight, BendWeight, DotIndex, SegIndex, BendIndex> {
|
||||
) -> &Geometry<
|
||||
GeometryWeight,
|
||||
DotWeight,
|
||||
SegWeight,
|
||||
BendWeight,
|
||||
GeometryIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
BendIndex,
|
||||
> {
|
||||
&self.geometry
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use enum_dispatch::enum_dispatch;
|
|||
use geo::Point;
|
||||
use petgraph::{
|
||||
stable_graph::{NodeIndex, StableDiGraph},
|
||||
Direction::Incoming,
|
||||
Direction::{Incoming, Outgoing},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -26,7 +26,7 @@ use super::{
|
|||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait Retag {
|
||||
pub trait Retag<GeometryIndex> {
|
||||
fn retag(&self, index: NodeIndex<usize>) -> GeometryIndex;
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ pub trait GetOffset {
|
|||
|
||||
macro_rules! impl_weight {
|
||||
($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 {
|
||||
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)]
|
||||
pub enum GeometryWeight {
|
||||
FixedDot(FixedDotWeight),
|
||||
|
|
@ -148,37 +148,45 @@ pub trait BendWeightTrait<GW>: GetOffset + GetWidth + Into<GW> + Copy {}
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Geometry<
|
||||
GW: GetWidth + TryInto<DW> + TryInto<BW> + Copy,
|
||||
DW: DotWeightTrait<GW>,
|
||||
BW: BendWeightTrait<GW>,
|
||||
DI: GetNodeIndex,
|
||||
SI: GetNodeIndex,
|
||||
BI: GetNodeIndex,
|
||||
GW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<GI> + Copy,
|
||||
DW: DotWeightTrait<GW> + Copy,
|
||||
SW: SegWeightTrait<GW> + Copy,
|
||||
BW: BendWeightTrait<GW> + Copy,
|
||||
GI: GetNodeIndex + Copy,
|
||||
DI: GetNodeIndex + Copy,
|
||||
SI: GetNodeIndex + Copy,
|
||||
BI: GetNodeIndex + Copy,
|
||||
> {
|
||||
pub graph: StableDiGraph<GW, GeometryLabel, usize>,
|
||||
weight_marker: PhantomData<GW>,
|
||||
dot_weight_marker: PhantomData<DW>,
|
||||
seg_weight_marker: PhantomData<SW>,
|
||||
bend_weight_marker: PhantomData<BW>,
|
||||
index_marker: PhantomData<GI>,
|
||||
dot_index_marker: PhantomData<DI>,
|
||||
seg_index_marker: PhantomData<SI>,
|
||||
bend_index_marker: PhantomData<BI>,
|
||||
}
|
||||
|
||||
impl<
|
||||
GW: GetWidth + TryInto<DW> + TryInto<BW> + Copy,
|
||||
DW: DotWeightTrait<GW>,
|
||||
BW: BendWeightTrait<GW>,
|
||||
GW: GetWidth + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<GI> + Copy,
|
||||
DW: DotWeightTrait<GW> + Copy,
|
||||
SW: SegWeightTrait<GW> + Copy,
|
||||
BW: BendWeightTrait<GW> + Copy,
|
||||
GI: GetNodeIndex + Copy,
|
||||
DI: GetNodeIndex + Copy,
|
||||
SI: 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 {
|
||||
Self {
|
||||
graph: StableDiGraph::default(),
|
||||
weight_marker: PhantomData,
|
||||
dot_weight_marker: PhantomData,
|
||||
seg_weight_marker: PhantomData,
|
||||
bend_weight_marker: PhantomData,
|
||||
index_marker: PhantomData,
|
||||
dot_index_marker: PhantomData,
|
||||
seg_index_marker: PhantomData,
|
||||
bend_index_marker: PhantomData,
|
||||
|
|
@ -273,20 +281,6 @@ impl<
|
|||
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 {
|
||||
*self.graph.node_weight(index).unwrap()
|
||||
}
|
||||
|
|
@ -297,6 +291,12 @@ impl<
|
|||
.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 {
|
||||
self.weight(bend.node_index())
|
||||
.try_into()
|
||||
|
|
@ -342,6 +342,62 @@ impl<
|
|||
.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> {
|
||||
&self.graph
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
pub struct FixedSegWeight {
|
||||
pub component: ComponentIndex,
|
||||
|
|
|
|||
|
|
@ -87,26 +87,8 @@ pub trait GetFirstRail: GetLayout + GetNodeIndex {
|
|||
fn first_rail(&self) -> Option<LooseBendIndex> {
|
||||
self.layout()
|
||||
.geometry()
|
||||
.graph()
|
||||
.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
|
||||
)
|
||||
})
|
||||
.first_rail(self.node_index())
|
||||
.map(|node| LooseBendIndex::new(node))
|
||||
.next()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,26 +96,8 @@ pub trait GetCore: GetLayout + GetNodeIndex {
|
|||
fn core(&self) -> FixedDotIndex {
|
||||
self.layout()
|
||||
.geometry()
|
||||
.graph()
|
||||
.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
|
||||
)
|
||||
})
|
||||
.core(self.node_index())
|
||||
.map(|node| FixedDotIndex::new(node))
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
|
@ -142,51 +106,15 @@ pub trait GetInnerOuter: GetLayout + GetNodeIndex {
|
|||
fn inner(&self) -> Option<LooseBendIndex> {
|
||||
self.layout()
|
||||
.geometry()
|
||||
.graph()
|
||||
.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
|
||||
)
|
||||
})
|
||||
.inner(self.node_index())
|
||||
.map(|node| LooseBendIndex::new(node))
|
||||
.next()
|
||||
}
|
||||
|
||||
fn outer(&self) -> Option<LooseBendIndex> {
|
||||
self.layout()
|
||||
.geometry()
|
||||
.graph()
|
||||
.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
|
||||
)
|
||||
})
|
||||
.outer(self.node_index())
|
||||
.map(|node| LooseBendIndex::new(node))
|
||||
.next()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue