primitive: create trait for getting primitives with dependent bbox

I'm calling these "dependents" for now, but there may be a better word.
This commit is contained in:
Mikolaj Wielgus 2024-01-19 23:40:18 +00:00
parent 37fa62a4c2
commit 8bd0f20ee0
2 changed files with 109 additions and 23 deletions

View File

@ -24,8 +24,8 @@ use crate::guide::Guide;
use crate::loose::{GetNextLoose, Loose, LooseIndex};
use crate::math::NoTangents;
use crate::primitive::{
GenericPrimitive, GetConnectable, GetCore, GetEnds, GetInnerOuter, GetOtherEnd, GetWeight,
MakeShape,
GenericPrimitive, GetConnectable, GetCore, GetDependents, GetEnds, GetInnerOuter, GetOtherEnd,
GetWeight, MakeShape,
};
use crate::segbend::Segbend;
use crate::shape::{Shape, ShapeTrait};
@ -809,11 +809,7 @@ impl Layout {
to: Point,
infringables: &[GeometryIndex],
) -> Result<(), Infringement> {
self.primitive(dot)
.seg()
.map(|seg| self.remove_from_rtree(seg.into()));
self.remove_from_rtree(self.primitive(dot).bend().into());
self.remove_from_rtree(dot.into());
self.remove_from_rtree_with_dependents(dot.into());
let mut dot_weight = self.primitive(dot).weight();
let old_weight = dot_weight;
@ -827,20 +823,11 @@ impl Layout {
*self.geometry.node_weight_mut(dot.node_index()).unwrap() =
GeometryWeight::LooseDot(old_weight);
self.insert_into_rtree(dot.into());
self.insert_into_rtree(self.primitive(dot).bend().into());
self.primitive(dot)
.seg()
.map(|seg| self.insert_into_rtree(seg.into()));
self.insert_into_rtree_with_dependents(dot.into());
return Err(infringement);
}
self.insert_into_rtree(dot.into());
self.insert_into_rtree(self.primitive(dot).bend().into());
self.primitive(dot)
.seg()
.map(|seg| self.insert_into_rtree(seg.into()));
self.insert_into_rtree_with_dependents(dot.into());
Ok(())
}
@ -884,6 +871,16 @@ impl Layout {
.and_then(|collidee| Some(Collision(shape, collidee)))
}
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn insert_into_rtree_with_dependents(&mut self, node: GeometryIndex) {
self.insert_into_rtree(node);
for dependent in node.primitive(self).dependents() {
self.insert_into_rtree(dependent);
}
}
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn insert_into_rtree(&mut self, node: GeometryIndex) {
@ -891,6 +888,16 @@ impl Layout {
self.rtree.insert(RTreeWrapper::new(shape, node));
}
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn remove_from_rtree_with_dependents(&mut self, node: GeometryIndex) {
for dependent in node.primitive(self).dependents() {
self.remove_from_rtree(dependent);
}
self.remove_from_rtree(node);
}
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn remove_from_rtree(&mut self, node: GeometryIndex) {

View File

@ -6,10 +6,11 @@ use petgraph::Direction::{Incoming, Outgoing};
use crate::connectivity::{BandIndex, ComponentIndex, GetNet};
use crate::geometry::{
DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GeometryIndex,
GeometryLabel, GeometryWeight, GetBandIndex, GetComponentIndex, GetOffset, GetWidth,
LoneLooseSegIndex, LoneLooseSegWeight, LooseBendIndex, LooseBendWeight, LooseDotIndex,
LooseDotWeight, MakePrimitive, Retag, SeqLooseSegIndex, SeqLooseSegWeight,
BendIndex, DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight,
FixedSegIndex, FixedSegWeight, GeometryIndex, GeometryLabel, GeometryWeight, GetBandIndex,
GetComponentIndex, GetOffset, GetWidth, LoneLooseSegIndex, LoneLooseSegWeight, LooseBendIndex,
LooseBendWeight, LooseDotIndex, LooseDotWeight, MakePrimitive, Retag, SegIndex,
SeqLooseSegIndex, SeqLooseSegWeight,
};
use crate::graph::{GenericIndex, GetNodeIndex};
use crate::layout::Layout;
@ -42,6 +43,24 @@ pub trait MakeShape {
fn shape(&self) -> Shape;
}
#[enum_dispatch]
pub trait GetDependents {
fn dependents(&self) -> Vec<GeometryIndex> {
let mut v = vec![];
v.extend(self.segs().into_iter().map(Into::<GeometryIndex>::into));
v.extend(self.bends().into_iter().map(Into::<GeometryIndex>::into));
v
}
fn segs(&self) -> Vec<SegIndex> {
vec![]
}
fn bends(&self) -> Vec<BendIndex> {
vec![]
}
}
pub trait GetInterior<T> {
fn interior(&self) -> Vec<T>;
}
@ -208,7 +227,7 @@ macro_rules! impl_loose_primitive {
};
}
#[enum_dispatch(GetNet, GetWidth, GetLayout, GetConnectable, MakeShape)]
#[enum_dispatch(GetNet, GetWidth, GetLayout, GetConnectable, MakeShape, GetDependents)]
pub enum Primitive<'a> {
FixedDot(FixedDot<'a>),
LooseDot(LooseDot<'a>),
@ -319,6 +338,42 @@ impl<'a> MakeShape for FixedDot<'a> {
})
}
}
impl<'a> GetDependents for FixedDot<'a> {
fn segs(&self) -> Vec<SegIndex> {
self.adjacents()
.into_iter()
.filter_map(
|node| match self.layout.geometry().node_weight(node).unwrap() {
GeometryWeight::FixedSeg(seg) => {
Some(SegIndex::Fixed(FixedSegIndex::new(node)))
}
GeometryWeight::LoneLooseSeg(seg) => {
Some(SegIndex::LoneLoose(LoneLooseSegIndex::new(node).into()))
}
GeometryWeight::SeqLooseSeg(seg) => {
Some(SegIndex::SeqLoose(SeqLooseSegIndex::new(node).into()))
}
_ => None,
},
)
.collect()
}
fn bends(&self) -> Vec<BendIndex> {
self.adjacents()
.into_iter()
.filter(|node| {
matches!(
self.layout.geometry().node_weight(*node).unwrap(),
GeometryWeight::FixedBend(..)
)
})
.map(|node| FixedBendIndex::new(node).into())
.collect()
}
}
impl<'a> GetFirstRail for FixedDot<'a> {}
pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>;
@ -361,6 +416,20 @@ impl<'a> MakeShape for LooseDot<'a> {
}
}
impl<'a> GetDependents for LooseDot<'a> {
fn segs(&self) -> Vec<SegIndex> {
if let Some(seg) = self.seg() {
vec![seg.into()]
} else {
vec![]
}
}
fn bends(&self) -> Vec<BendIndex> {
vec![self.bend().into()]
}
}
pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>;
impl_fixed_primitive!(FixedSeg, FixedSegWeight);
@ -375,6 +444,8 @@ impl<'a> MakeShape for FixedSeg<'a> {
}
}
impl<'a> GetDependents for FixedSeg<'a> {}
impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
let v = self.adjacents();
@ -398,6 +469,8 @@ impl<'a> MakeShape for LoneLooseSeg<'a> {
}
}
impl<'a> GetDependents for LoneLooseSeg<'a> {}
impl<'a> GetWidth for LoneLooseSeg<'a> {
fn width(&self) -> f64 {
self.primitive(self.ends().1).weight().width()
@ -430,6 +503,8 @@ impl<'a> MakeShape for SeqLooseSeg<'a> {
}
}
impl<'a> GetDependents for SeqLooseSeg<'a> {}
impl<'a> GetWidth for SeqLooseSeg<'a> {
fn width(&self) -> f64 {
self.primitive(self.ends().1).weight().width()
@ -491,6 +566,8 @@ impl<'a> MakeShape for FixedBend<'a> {
}
}
impl<'a> GetDependents for FixedBend<'a> {}
impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
let v = self.adjacents();
@ -550,6 +627,8 @@ impl<'a> MakeShape for LooseBend<'a> {
}
}
impl<'a> GetDependents for LooseBend<'a> {}
impl<'a> GetWidth for LooseBend<'a> {
fn width(&self) -> f64 {
self.primitive(self.ends().1).weight().width()