geometry: create new module, "loose", for traversal of loose nodes

This commit is contained in:
Mikolaj Wielgus 2024-01-16 22:30:28 +00:00
parent 46b50439c8
commit 3978802512
5 changed files with 129 additions and 25 deletions

View File

@ -22,12 +22,12 @@ use crate::graph::{GenericIndex, GetNodeIndex};
use crate::guide::Guide; use crate::guide::Guide;
use crate::math::NoTangents; use crate::math::NoTangents;
use crate::primitive::{ use crate::primitive::{
GenericPrimitive, GetConnectable, GetCore, GetEnds, GetFirstRail, GetInnerOuter, GetOtherEnd, GenericPrimitive, GetConnectable, GetCore, GetEnds, GetInnerOuter, GetOtherEnd, GetWeight,
GetWeight, GetWraparound, MakeShape, MakeShape,
}; };
use crate::segbend::Segbend; use crate::segbend::Segbend;
use crate::shape::{Shape, ShapeTrait}; use crate::shape::{Shape, ShapeTrait};
use crate::wraparoundable::{Wraparoundable, WraparoundableIndex}; use crate::wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex};
pub type RTreeWrapper = GeomWithData<Shape, GeometryIndex>; pub type RTreeWrapper = GeomWithData<Shape, GeometryIndex>;

98
src/loose.rs Normal file
View File

@ -0,0 +1,98 @@
use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex;
use crate::{
geometry::{
DotIndex, GeometryIndex, LoneLooseSegIndex, LooseBendIndex, LooseDotIndex, MakePrimitive,
SeqLooseSegIndex,
},
graph::GetNodeIndex,
layout::Layout,
primitive::{GetEnds, LoneLooseSeg, LooseBend, LooseDot, Primitive, SeqLooseSeg},
};
pub trait GetNextLoose {
fn next(&self, prev: GeometryIndex) -> Option<LooseIndex>;
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LooseIndex {
Dot(LooseDotIndex),
LoneSeg(LoneLooseSegIndex),
SeqSeg(SeqLooseSegIndex),
Bend(LooseBendIndex),
}
impl From<LooseIndex> for GeometryIndex {
fn from(loose: LooseIndex) -> Self {
match loose {
LooseIndex::Dot(dot) => GeometryIndex::LooseDot(dot),
LooseIndex::LoneSeg(seg) => GeometryIndex::LoneLooseSeg(seg),
LooseIndex::SeqSeg(seg) => GeometryIndex::SeqLooseSeg(seg),
LooseIndex::Bend(bend) => GeometryIndex::LooseBend(bend),
}
}
}
#[enum_dispatch(GetNextLoose, GetLayout, GetNodeIndex)]
pub enum Loose<'a> {
Dot(LooseDot<'a>),
LoneSeg(LoneLooseSeg<'a>),
SeqSeg(SeqLooseSeg<'a>),
Bend(LooseBend<'a>),
}
impl<'a> Loose<'a> {
pub fn new(index: LooseIndex, layout: &'a Layout) -> Self {
match index {
LooseIndex::Dot(dot) => layout.primitive(dot).into(),
LooseIndex::LoneSeg(seg) => layout.primitive(seg).into(),
LooseIndex::SeqSeg(seg) => layout.primitive(seg).into(),
LooseIndex::Bend(bend) => layout.primitive(bend).into(),
}
}
}
impl<'a> GetNextLoose for LooseDot<'a> {
fn next(&self, prev: GeometryIndex) -> Option<LooseIndex> {
let bend = self.bend();
if bend.node_index() != prev.node_index() {
self.seg().map(Into::into)
} else {
Some(bend.into())
}
}
}
impl<'a> GetNextLoose for LoneLooseSeg<'a> {
fn next(&self, _prev: GeometryIndex) -> Option<LooseIndex> {
None
}
}
impl<'a> GetNextLoose for SeqLooseSeg<'a> {
fn next(&self, prev: GeometryIndex) -> Option<LooseIndex> {
let ends = self.ends();
if ends.0.node_index() != prev.node_index() {
match ends.0 {
DotIndex::Fixed(..) => None,
DotIndex::Loose(dot) => Some(dot.into()),
}
} else {
Some(ends.1.into())
}
}
}
impl<'a> GetNextLoose for LooseBend<'a> {
fn next(&self, prev: GeometryIndex) -> Option<LooseIndex> {
let ends = self.ends();
if ends.0.node_index() != prev.node_index() {
Some(ends.0.into())
} else {
Some(ends.1.into())
}
}
}

View File

@ -15,6 +15,7 @@ mod geometry;
mod graph; mod graph;
mod guide; mod guide;
mod layout; mod layout;
mod loose;
mod math; mod math;
mod mesh; mod mesh;
mod primitive; mod primitive;

View File

@ -13,6 +13,7 @@ use crate::geometry::{
}; };
use crate::graph::{GenericIndex, GetNodeIndex}; use crate::graph::{GenericIndex, GetNodeIndex};
use crate::layout::Layout; use crate::layout::Layout;
use crate::loose::Loose;
use crate::math::{self, Circle}; use crate::math::{self, Circle};
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
@ -60,11 +61,6 @@ pub trait GetEnds<F, T> {
fn ends(&self) -> (F, T); fn ends(&self) -> (F, T);
} }
#[enum_dispatch]
pub trait GetWraparound: GetLayout + GetNodeIndex {
fn wraparound(&self) -> Option<LooseBendIndex>;
}
pub trait GetFirstRail: GetLayout + GetNodeIndex { pub trait GetFirstRail: GetLayout + GetNodeIndex {
fn first_rail(&self) -> Option<LooseBendIndex> { fn first_rail(&self) -> Option<LooseBendIndex> {
self.layout() self.layout()
@ -303,11 +299,6 @@ impl<'a> MakeShape for FixedDot<'a> {
} }
} }
impl<'a> GetFirstRail for FixedDot<'a> {} impl<'a> GetFirstRail for FixedDot<'a> {}
impl<'a> GetWraparound for FixedDot<'a> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.first_rail()
}
}
pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>;
impl_loose_primitive!(LooseDot, LooseDotWeight); impl_loose_primitive!(LooseDot, LooseDotWeight);
@ -520,11 +511,6 @@ impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {} impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {}
impl<'a> GetFirstRail for FixedBend<'a> {} impl<'a> GetFirstRail for FixedBend<'a> {}
impl<'a> GetWraparound for FixedBend<'a> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.first_rail()
}
}
impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actually. impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actually.
//impl<'a> GetInnerOuter for FixedBend<'a> {} //impl<'a> GetInnerOuter for FixedBend<'a> {}
@ -595,11 +581,5 @@ impl<'a> GetEnds<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {
} }
impl<'a> GetOtherEnd<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {} impl<'a> GetOtherEnd<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {}
impl<'a> GetWraparound for LooseBend<'a> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.outer()
}
}
impl<'a> GetCore for LooseBend<'a> {} impl<'a> GetCore for LooseBend<'a> {}
impl<'a> GetInnerOuter for LooseBend<'a> {} impl<'a> GetInnerOuter for LooseBend<'a> {}

View File

@ -7,9 +7,16 @@ use crate::{
}, },
graph::GetNodeIndex, graph::GetNodeIndex,
layout::Layout, layout::Layout,
primitive::{FixedBend, FixedDot, GetLayout, GetWraparound, LooseBend, Primitive}, primitive::{
FixedBend, FixedDot, GetFirstRail, GetInnerOuter, GetLayout, LooseBend, Primitive,
},
}; };
#[enum_dispatch]
pub trait GetWraparound: GetLayout + GetNodeIndex {
fn wraparound(&self) -> Option<LooseBendIndex>;
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)] #[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum WraparoundableIndex { pub enum WraparoundableIndex {
@ -53,3 +60,21 @@ impl<'a> Wraparoundable<'a> {
} }
} }
} }
impl<'a> GetWraparound for FixedDot<'a> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.first_rail()
}
}
impl<'a> GetWraparound for LooseBend<'a> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.outer()
}
}
impl<'a> GetWraparound for FixedBend<'a> {
fn wraparound(&self) -> Option<LooseBendIndex> {
self.first_rail()
}
}