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},
geometry::{
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBandIndex, GetComponentIndex,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive,
WraparoundableIndex,
LoneLooseSegWeight, LooseBendWeight, LooseDotIndex, LooseDotWeight, MakePrimitive,
SeqLooseSegWeight, WraparoundableIndex,
},
guide::{Guide, Head, HeadTrait, SegbendHead},
layout::{Infringement, Layout, LayoutException},
@ -58,27 +58,15 @@ impl<'a> Draw<'a> {
.extend_head(head, tangent.start_point())
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
let net = head.face().primitive(self.layout).net();
match head.face() {
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
.add_fixed_seg(
into.into(),
dot,
FixedSegWeight {
component: self.layout.primitive(into).weight().component(),
width,
},
)
.add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { band: head.band() })
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
}
DotIndex::Loose(dot) => {
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()))?;
}
}
@ -216,7 +204,7 @@ impl<'a> Draw<'a> {
r: width / 2.0,
},
},
LooseSegWeight { band: head.band() },
SeqLooseSegWeight { band: head.band() },
LooseBendWeight {
band: head.band(),
offset: 3.0,

View File

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

View File

@ -15,8 +15,9 @@ use crate::connectivity::{
use crate::geometry::{
BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedDotIndex, FixedDotWeight, FixedSegIndex,
FixedSegWeight, GeometryGraph, GeometryLabel, GeometryWeight, GetComponentIndex, Index,
LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight,
MakePrimitive, Retag, SegWeight, WraparoundableIndex,
LoneLooseSegIndex, LoneLooseSegWeight, LooseBendIndex, LooseBendWeight, LooseDotIndex,
LooseDotWeight, MakePrimitive, Retag, SegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
WraparoundableIndex,
};
use crate::graph::{GenericIndex, GetNodeIndex};
use crate::guide::Guide;
@ -183,7 +184,7 @@ impl Layout {
from: DotIndex,
around: WraparoundableIndex,
dot_weight: LooseDotWeight,
seg_weight: LooseSegWeight,
seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight,
) -> Result<Segbend, LayoutException> {
let maybe_wraparound = match around {
@ -448,7 +449,7 @@ impl Layout {
from: DotIndex,
around: WraparoundableIndex,
dot_weight: LooseDotWeight,
seg_weight: LooseSegWeight,
seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight,
) -> Result<Segbend, LayoutException> {
self.add_segbend_infringably(
@ -470,7 +471,7 @@ impl Layout {
from: DotIndex,
around: WraparoundableIndex,
dot_weight: LooseDotWeight,
seg_weight: LooseSegWeight,
seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight,
infringables: &[Index],
) -> 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_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_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,
from: DotIndex,
to: LooseDotIndex,
weight: LooseSegWeight,
) -> Result<LooseSegIndex, Infringement> {
weight: SeqLooseSegWeight,
) -> Result<SeqLooseSegIndex, Infringement> {
self.add_seg_infringably(from, to, weight, &[])
}

View File

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

View File

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