From d9b94742e44c8ed31ec76d1179371a1f64d42952 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 15 Jan 2024 15:56:37 +0000 Subject: [PATCH] geometry: split loose segs into lone and sequential (seq) types --- src/draw.rs | 22 +++++-------------- src/geometry.rs | 26 ++++++++++++++++------ src/layout.rs | 30 +++++++++++++++++++------- src/primitive.rs | 56 +++++++++++++++++++++++++++++++++++++----------- src/segbend.rs | 8 +++---- 5 files changed, 93 insertions(+), 49 deletions(-) diff --git a/src/draw.rs b/src/draw.rs index 0a7df8c..f1b8672 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -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, diff --git a/src/geometry.rs b/src/geometry.rs index 15b71aa..1fde656 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -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 for Index { #[derive(Debug, Clone, Copy, PartialEq)] pub enum SegIndex { Fixed(FixedSegIndex), - Loose(LooseSegIndex), + LoneLoose(LoneLooseSegIndex), + SeqLoose(SeqLooseSegIndex), } impl From 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 + Copy {} diff --git a/src/layout.rs b/src/layout.rs index c8fc17f..318eed2 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -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 { 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 { 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 { @@ -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 { + 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 { + weight: SeqLooseSegWeight, + ) -> Result { self.add_seg_infringably(from, to, weight, &[]) } diff --git a/src/primitive.rs b/src/primitive.rs index 43552f3..06e37fd 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -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 { + pub fn seg(&self) -> Option { 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 for FixedSeg<'a> { impl<'a> GetOtherEnd 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 for LoneLooseSeg<'a> { + fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { + let v = self.adjacents(); + (FixedDotIndex::new(v[0]), FixedDotIndex::new(v[1])) + } +} + +impl<'a> GetOtherEnd 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 for LooseSeg<'a> { +impl<'a> GetEnds 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 for LooseSeg<'a> { } } -impl<'a> GetOtherEnd for LooseSeg<'a> {} +impl<'a> GetOtherEnd for SeqLooseSeg<'a> {} pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; impl_fixed_primitive!(FixedBend, FixedBendWeight); diff --git a/src/segbend.rs b/src/segbend.rs index fe05227..22253ba 100644 --- a/src/segbend.rs +++ b/src/segbend.rs @@ -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 for Segbend { } } -impl GetEnds for Segbend { - fn ends(&self) -> (LooseSegIndex, LooseBendIndex) { +impl GetEnds for Segbend { + fn ends(&self) -> (SeqLooseSegIndex, LooseBendIndex) { (self.seg, self.bend) } }