From 5a0ea94a87ed72c8109fb2512dd1cc17a84ecd20 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Thu, 14 Mar 2024 19:17:38 +0000 Subject: [PATCH] geometry: make shape bboxes occupy only one layer instead of all --- src/geometry/shape.rs | 10 +++++++- src/geometry/with_rtree.rs | 50 ++++++++++++++++++++++++++++++-------- src/layout/layout.rs | 11 +++++---- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/geometry/shape.rs b/src/geometry/shape.rs index dbd0ae6..0fd9165 100644 --- a/src/geometry/shape.rs +++ b/src/geometry/shape.rs @@ -14,7 +14,15 @@ pub trait ShapeTrait { fn width(&self) -> f64; fn length(&self) -> f64; - fn flat_envelope_3d(&self, margin: f64, layer_count: u64) -> AABB<[f64; 3]> { + fn envelope_3d(&self, margin: f64, layer: u64) -> AABB<[f64; 3]> { + let envelope = self.envelope(margin); + AABB::from_corners( + [envelope.lower()[0], envelope.lower()[1], layer as f64], + [envelope.upper()[0], envelope.upper()[1], layer as f64], + ) + } + + fn full_height_envelope_3d(&self, margin: f64, layer_count: u64) -> AABB<[f64; 3]> { let envelope = self.envelope(margin); AABB::from_corners( [envelope.lower()[0], envelope.lower()[1], 0.0], diff --git a/src/geometry/with_rtree.rs b/src/geometry/with_rtree.rs index b08a1c7..f5be78d 100644 --- a/src/geometry/with_rtree.rs +++ b/src/geometry/with_rtree.rs @@ -21,9 +21,9 @@ pub struct Bbox { } impl Bbox { - pub fn new(shape: &Shape) -> Bbox { + pub fn new(shape: &Shape, layer: u64) -> Bbox { Self { - aabb: shape.flat_envelope_3d(0.0, 2), + aabb: shape.envelope_3d(0.0, layer), } } } @@ -90,7 +90,7 @@ impl< } } - pub fn add_dot>(&mut self, weight: W) -> GenericIndex + pub fn add_dot + GetLayer>(&mut self, weight: W) -> GenericIndex where GenericIndex: Into, { @@ -100,13 +100,19 @@ impl< &self .geometry .dot_shape(dot.into().try_into().unwrap_or_else(|_| unreachable!())), + weight.layer(), ), dot.into(), )); dot } - pub fn add_seg>(&mut self, from: DI, to: DI, weight: W) -> GenericIndex + pub fn add_seg + GetLayer>( + &mut self, + from: DI, + to: DI, + weight: W, + ) -> GenericIndex where GenericIndex: Into, { @@ -116,13 +122,14 @@ impl< &self .geometry .seg_shape(seg.into().try_into().unwrap_or_else(|_| unreachable!())), + weight.layer(), ), seg.into(), )); seg } - pub fn add_bend>( + pub fn add_bend + GetLayer>( &mut self, from: DI, to: DI, @@ -138,6 +145,7 @@ impl< &self .geometry .bend_shape(bend.into().try_into().unwrap_or_else(|_| unreachable!())), + weight.layer(), ), bend.into(), )); @@ -248,15 +256,24 @@ impl< > GeometryWithRtree { fn make_dot_bbox(&self, dot: DI) -> BboxedIndex { - BboxedIndex::new(Bbox::new(&self.geometry.dot_shape(dot)), dot.into()) + BboxedIndex::new( + Bbox::new(&self.geometry.dot_shape(dot), self.layer(dot.into())), + dot.into(), + ) } fn make_seg_bbox(&self, seg: SI) -> BboxedIndex { - BboxedIndex::new(Bbox::new(&self.geometry.seg_shape(seg)), seg.into()) + BboxedIndex::new( + Bbox::new(&self.geometry.seg_shape(seg), self.layer(seg.into())), + seg.into(), + ) } fn make_bend_bbox(&self, bend: BI) -> BboxedIndex { - BboxedIndex::new(Bbox::new(&self.geometry.bend_shape(bend)), bend.into()) + BboxedIndex::new( + Bbox::new(&self.geometry.bend_shape(bend), self.layer(bend.into())), + bend.into(), + ) } fn shape(&self, index: GI) -> Shape { @@ -271,6 +288,18 @@ impl< } } + fn layer(&self, index: GI) -> u64 { + if let Ok(dot) = >::try_into(index) { + self.geometry.dot_weight(dot).layer() + } else if let Ok(seg) = >::try_into(index) { + self.geometry.seg_weight(seg).layer() + } else if let Ok(bend) = >::try_into(index) { + self.geometry.bend_weight(bend).layer() + } else { + unreachable!(); + } + } + pub fn geometry(&self) -> &Geometry { &self.geometry } @@ -287,10 +316,11 @@ impl< !self.rtree.iter().any(|wrapper| { let node = wrapper.data; let shape = self.shape(node); - let wrapper = BboxedIndex::new(Bbox::new(&shape), node); + let layer = self.layer(node); + let wrapper = BboxedIndex::new(Bbox::new(&shape, layer), node); !self .rtree - .locate_in_envelope(&shape.flat_envelope_3d(0.0, 2)) + .locate_in_envelope(&shape.envelope_3d(0.0, layer)) .any(|w| *w == wrapper) }) } diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 0fc133a..289adde 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -5,6 +5,7 @@ use geo::Point; use rstar::RTreeObject; use thiserror::Error; +use super::graph::GetLayer; use super::loose::{GetNextLoose, Loose, LooseIndex}; use super::rules::RulesTrait; use super::segbend::Segbend; @@ -175,7 +176,7 @@ impl Layout { #[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))] #[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] - fn add_dot_infringably>( + fn add_dot_infringably + GetLayer>( &mut self, weight: W, infringables: &[GeometryIndex], @@ -469,7 +470,7 @@ impl Layout { #[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() + 2))] #[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn add_seg_infringably>( + fn add_seg_infringably + GetLayer>( &mut self, from: DotIndex, to: DotIndex, @@ -527,7 +528,7 @@ impl Layout { #[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() + 3))] #[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn add_core_bend_infringably>( + fn add_core_bend_infringably + GetLayer>( &mut self, from: DotIndex, to: DotIndex, @@ -723,7 +724,7 @@ impl Layout { self.geometry_with_rtree .rtree() - .locate_in_envelope_intersecting(&limiting_shape.flat_envelope_3d(0.0, 2)) + .locate_in_envelope_intersecting(&limiting_shape.full_height_envelope_3d(0.0, 2)) .filter(|wrapper| !self.are_connectable(node, wrapper.data)) .filter(|wrapper| !except.contains(&wrapper.data)) .filter(|wrapper| { @@ -749,7 +750,7 @@ impl Layout { self.geometry_with_rtree .rtree() - .locate_in_envelope_intersecting(&shape.flat_envelope_3d(0.0, 2)) + .locate_in_envelope_intersecting(&shape.full_height_envelope_3d(0.0, 2)) .filter(|wrapper| !self.are_connectable(node, wrapper.data)) .filter(|wrapper| shape.intersects(&wrapper.data.primitive(self).shape())) .map(|wrapper| wrapper.data)