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 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue