geometry: split loose segs into lone and sequential (seq) types

This commit is contained in:
Mikolaj Wielgus 2024-01-15 15:56:37 +00:00
parent 8f8f47a41d
commit d9b94742e4
5 changed files with 93 additions and 49 deletions

View File

@ -6,8 +6,8 @@ use crate::{
connectivity::{ComponentIndex, GetNet}, connectivity::{ComponentIndex, GetNet},
geometry::{ geometry::{
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBandIndex, GetComponentIndex, BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBandIndex, GetComponentIndex,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive, LoneLooseSegWeight, LooseBendWeight, LooseDotIndex, LooseDotWeight, MakePrimitive,
WraparoundableIndex, SeqLooseSegWeight, WraparoundableIndex,
}, },
guide::{Guide, Head, HeadTrait, SegbendHead}, guide::{Guide, Head, HeadTrait, SegbendHead},
layout::{Infringement, Layout, LayoutException}, layout::{Infringement, Layout, LayoutException},
@ -58,27 +58,15 @@ impl<'a> Draw<'a> {
.extend_head(head, tangent.start_point()) .extend_head(head, tangent.start_point())
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
let net = head.face().primitive(self.layout).net();
match head.face() { match head.face() {
DotIndex::Fixed(dot) => { DotIndex::Fixed(dot) => {
// TODO: This code is temporary (component is wrong). Fix this by splitting loose
// segs into direct and indirect ones, the former ending with fixed dots on both
// sides and the latter not.
self.layout self.layout
.add_fixed_seg( .add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { band: head.band() })
into.into(),
dot,
FixedSegWeight {
component: self.layout.primitive(into).weight().component(),
width,
},
)
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
} }
DotIndex::Loose(dot) => { DotIndex::Loose(dot) => {
self.layout self.layout
.add_loose_seg(into.into(), dot, LooseSegWeight { band: head.band() }) .add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { band: head.band() })
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
} }
} }
@ -216,7 +204,7 @@ impl<'a> Draw<'a> {
r: width / 2.0, r: width / 2.0,
}, },
}, },
LooseSegWeight { band: head.band() }, SeqLooseSegWeight { band: head.band() },
LooseBendWeight { LooseBendWeight {
band: head.band(), band: head.band(),
offset: 3.0, offset: 3.0,

View File

@ -92,7 +92,8 @@ pub enum GeometryWeight {
FixedDot(FixedDotWeight), FixedDot(FixedDotWeight),
LooseDot(LooseDotWeight), LooseDot(LooseDotWeight),
FixedSeg(FixedSegWeight), FixedSeg(FixedSegWeight),
LooseSeg(LooseSegWeight), LoneLooseSeg(LoneLooseSegWeight),
SeqLooseSeg(SeqLooseSegWeight),
FixedBend(FixedBendWeight), FixedBend(FixedBendWeight),
LooseBend(LooseBendWeight), LooseBend(LooseBendWeight),
} }
@ -103,7 +104,8 @@ pub enum Index {
FixedDot(FixedDotIndex), FixedDot(FixedDotIndex),
LooseDot(LooseDotIndex), LooseDot(LooseDotIndex),
FixedSeg(FixedSegIndex), FixedSeg(FixedSegIndex),
LooseSeg(LooseSegIndex), LoneLooseSeg(LoneLooseSegIndex),
SeqLooseSeg(SeqLooseSegIndex),
FixedBend(FixedBendIndex), FixedBend(FixedBendIndex),
LooseBend(LooseBendIndex), LooseBend(LooseBendIndex),
} }
@ -128,14 +130,16 @@ impl From<DotIndex> for Index {
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum SegIndex { pub enum SegIndex {
Fixed(FixedSegIndex), Fixed(FixedSegIndex),
Loose(LooseSegIndex), LoneLoose(LoneLooseSegIndex),
SeqLoose(SeqLooseSegIndex),
} }
impl From<SegIndex> for Index { impl From<SegIndex> for Index {
fn from(seg: SegIndex) -> Self { fn from(seg: SegIndex) -> Self {
match seg { match seg {
SegIndex::Fixed(seg) => Index::FixedSeg(seg), SegIndex::Fixed(seg) => Index::FixedSeg(seg),
SegIndex::Loose(seg) => Index::LooseSeg(seg), SegIndex::LoneLoose(seg) => Index::LoneLooseSeg(seg),
SegIndex::SeqLoose(seg) => Index::SeqLooseSeg(seg),
} }
} }
} }
@ -232,12 +236,20 @@ impl GetWidth for FixedSegWeight {
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseSegWeight { pub struct LoneLooseSegWeight {
pub band: BandIndex, pub band: BandIndex,
} }
impl_loose_weight!(LooseSegWeight, LooseSeg, LooseSegIndex); impl_loose_weight!(LoneLooseSegWeight, LoneLooseSeg, LoneLooseSegIndex);
impl SegWeight for LooseSegWeight {} impl SegWeight for LoneLooseSegWeight {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SeqLooseSegWeight {
pub band: BandIndex,
}
impl_loose_weight!(SeqLooseSegWeight, SeqLooseSeg, SeqLooseSegIndex);
impl SegWeight for SeqLooseSegWeight {}
pub trait BendWeight: Into<GeometryWeight> + Copy {} pub trait BendWeight: Into<GeometryWeight> + Copy {}

View File

@ -15,8 +15,9 @@ use crate::connectivity::{
use crate::geometry::{ use crate::geometry::{
BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedDotIndex, FixedDotWeight, FixedSegIndex, BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedDotIndex, FixedDotWeight, FixedSegIndex,
FixedSegWeight, GeometryGraph, GeometryLabel, GeometryWeight, GetComponentIndex, Index, FixedSegWeight, GeometryGraph, GeometryLabel, GeometryWeight, GetComponentIndex, Index,
LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, LooseBendIndex, LooseBendWeight, LooseDotIndex,
MakePrimitive, Retag, SegWeight, WraparoundableIndex, LooseDotWeight, MakePrimitive, Retag, SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
WraparoundableIndex,
}; };
use crate::graph::{GenericIndex, GetNodeIndex}; use crate::graph::{GenericIndex, GetNodeIndex};
use crate::guide::Guide; use crate::guide::Guide;
@ -183,7 +184,7 @@ impl Layout {
from: DotIndex, from: DotIndex,
around: WraparoundableIndex, around: WraparoundableIndex,
dot_weight: LooseDotWeight, dot_weight: LooseDotWeight,
seg_weight: LooseSegWeight, seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight, bend_weight: LooseBendWeight,
) -> Result<Segbend, LayoutException> { ) -> Result<Segbend, LayoutException> {
let maybe_wraparound = match around { let maybe_wraparound = match around {
@ -448,7 +449,7 @@ impl Layout {
from: DotIndex, from: DotIndex,
around: WraparoundableIndex, around: WraparoundableIndex,
dot_weight: LooseDotWeight, dot_weight: LooseDotWeight,
seg_weight: LooseSegWeight, seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight, bend_weight: LooseBendWeight,
) -> Result<Segbend, LayoutException> { ) -> Result<Segbend, LayoutException> {
self.add_segbend_infringably( self.add_segbend_infringably(
@ -470,7 +471,7 @@ impl Layout {
from: DotIndex, from: DotIndex,
around: WraparoundableIndex, around: WraparoundableIndex,
dot_weight: LooseDotWeight, dot_weight: LooseDotWeight,
seg_weight: LooseSegWeight, seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight, bend_weight: LooseBendWeight,
infringables: &[Index], infringables: &[Index],
) -> Result<Segbend, LayoutException> { ) -> Result<Segbend, LayoutException> {
@ -509,12 +510,25 @@ impl Layout {
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))] #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn add_loose_seg( pub fn add_lone_loose_seg(
&mut self,
from: FixedDotIndex,
to: FixedDotIndex,
weight: LoneLooseSegWeight,
) -> Result<LoneLooseSegIndex, Infringement> {
self.add_seg_infringably(from, to, weight, &[])
}
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn add_seq_loose_seg(
&mut self, &mut self,
from: DotIndex, from: DotIndex,
to: LooseDotIndex, to: LooseDotIndex,
weight: LooseSegWeight, weight: SeqLooseSegWeight,
) -> Result<LooseSegIndex, Infringement> { ) -> Result<SeqLooseSegIndex, Infringement> {
self.add_seg_infringably(from, to, weight, &[]) self.add_seg_infringably(from, to, weight, &[])
} }

View File

@ -7,9 +7,9 @@ use petgraph::Direction::{Incoming, Outgoing};
use crate::connectivity::GetNet; use crate::connectivity::GetNet;
use crate::geometry::{ use crate::geometry::{
DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GeometryLabel, DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GeometryLabel,
GeometryWeight, GetBandIndex, GetComponentIndex, GetOffset, GetWidth, Index, LooseBendIndex, GeometryWeight, GetBandIndex, GetComponentIndex, GetOffset, GetWidth, Index,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive, LoneLooseSegWeight, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight,
Retag, MakePrimitive, Retag, SeqLooseSegIndex, SeqLooseSegWeight,
}; };
use crate::graph::{GenericIndex, GetNodeIndex}; use crate::graph::{GenericIndex, GetNodeIndex};
use crate::layout::Layout; use crate::layout::Layout;
@ -210,7 +210,8 @@ pub enum Primitive<'a> {
FixedDot(FixedDot<'a>), FixedDot(FixedDot<'a>),
LooseDot(LooseDot<'a>), LooseDot(LooseDot<'a>),
FixedSeg(FixedSeg<'a>), FixedSeg(FixedSeg<'a>),
LooseSeg(LooseSeg<'a>), LoneLooseSeg(LoneLooseSeg<'a>),
SeqLooseSeg(SeqLooseSeg<'a>),
FixedBend(FixedBend<'a>), FixedBend(FixedBend<'a>),
LooseBend(LooseBend<'a>), LooseBend(LooseBend<'a>),
} }
@ -311,7 +312,7 @@ pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>;
impl_loose_primitive!(LooseDot, LooseDotWeight); impl_loose_primitive!(LooseDot, LooseDotWeight);
impl<'a> LooseDot<'a> { impl<'a> LooseDot<'a> {
pub fn seg(&self) -> Option<LooseSegIndex> { pub fn seg(&self) -> Option<SeqLooseSegIndex> {
self.layout self.layout
.geometry() .geometry()
.neighbors_undirected(self.index.node_index()) .neighbors_undirected(self.index.node_index())
@ -333,10 +334,10 @@ impl<'a> LooseDot<'a> {
.filter(|ni| { .filter(|ni| {
matches!( matches!(
self.layout.geometry().node_weight(*ni).unwrap(), self.layout.geometry().node_weight(*ni).unwrap(),
GeometryWeight::LooseSeg(..) GeometryWeight::SeqLooseSeg(..)
) )
}) })
.map(|ni| LooseSegIndex::new(ni)) .map(|ni| SeqLooseSegIndex::new(ni))
.next() .next()
} }
@ -402,10 +403,39 @@ impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {} impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {}
pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>; pub type LoneLooseSeg<'a> = GenericPrimitive<'a, LoneLooseSegWeight>;
impl_loose_primitive!(LooseSeg, LooseSegWeight); impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight);
impl<'a> MakeShape for LooseSeg<'a> { impl<'a> MakeShape for LoneLooseSeg<'a> {
fn shape(&self) -> Shape {
let ends = self.ends();
Shape::Seg(SegShape {
from: self.primitive(ends.0).weight().circle.pos,
to: self.primitive(ends.1).weight().circle.pos,
width: self.width(),
})
}
}
impl<'a> GetWidth for LoneLooseSeg<'a> {
fn width(&self) -> f64 {
self.primitive(self.ends().1).weight().width()
}
}
impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a> {
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
let v = self.adjacents();
(FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1]))
}
}
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a> {}
pub type SeqLooseSeg<'a> = GenericPrimitive<'a, SeqLooseSegWeight>;
impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight);
impl<'a> MakeShape for SeqLooseSeg<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
let ends = self.ends(); let ends = self.ends();
Shape::Seg(SegShape { Shape::Seg(SegShape {
@ -419,13 +449,13 @@ impl<'a> MakeShape for LooseSeg<'a> {
} }
} }
impl<'a> GetWidth for LooseSeg<'a> { impl<'a> GetWidth for SeqLooseSeg<'a> {
fn width(&self) -> f64 { fn width(&self) -> f64 {
self.primitive(self.ends().1).weight().width() self.primitive(self.ends().1).weight().width()
} }
} }
impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> { impl<'a> GetEnds<DotIndex, LooseDotIndex> for SeqLooseSeg<'a> {
fn ends(&self) -> (DotIndex, LooseDotIndex) { fn ends(&self) -> (DotIndex, LooseDotIndex) {
let v = self.adjacents(); let v = self.adjacents();
if let GeometryWeight::FixedDot(..) = self.layout.geometry().node_weight(v[0]).unwrap() { if let GeometryWeight::FixedDot(..) = self.layout.geometry().node_weight(v[0]).unwrap() {
@ -440,7 +470,7 @@ impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
} }
} }
impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> for LooseSeg<'a> {} impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> for SeqLooseSeg<'a> {}
pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>;
impl_fixed_primitive!(FixedBend, FixedBendWeight); impl_fixed_primitive!(FixedBend, FixedBendWeight);

View File

@ -1,12 +1,12 @@
use crate::{ use crate::{
geometry::{Index, LooseBendIndex, LooseDotIndex, LooseSegIndex}, geometry::{Index, LooseBendIndex, LooseDotIndex, SeqLooseSegIndex},
layout::Layout, layout::Layout,
primitive::{GetEnds, GetInterior, GetOtherEnd, LooseBend, LooseDot}, primitive::{GetEnds, GetInterior, GetOtherEnd, LooseBend, LooseDot},
}; };
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Segbend { pub struct Segbend {
pub seg: LooseSegIndex, pub seg: SeqLooseSegIndex,
pub dot: LooseDotIndex, pub dot: LooseDotIndex,
pub bend: LooseBendIndex, pub bend: LooseBendIndex,
} }
@ -26,8 +26,8 @@ impl GetInterior<Index> for Segbend {
} }
} }
impl GetEnds<LooseSegIndex, LooseBendIndex> for Segbend { impl GetEnds<SeqLooseSegIndex, LooseBendIndex> for Segbend {
fn ends(&self) -> (LooseSegIndex, LooseBendIndex) { fn ends(&self) -> (SeqLooseSegIndex, LooseBendIndex) {
(self.seg, self.bend) (self.seg, self.bend)
} }
} }