mirror of https://codeberg.org/topola/topola.git
geometry: make shape bboxes occupy only one layer instead of all
This commit is contained in:
parent
cf01cdaea5
commit
5a0ea94a87
|
|
@ -14,7 +14,15 @@ pub trait ShapeTrait {
|
||||||
fn width(&self) -> f64;
|
fn width(&self) -> f64;
|
||||||
fn length(&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);
|
let envelope = self.envelope(margin);
|
||||||
AABB::from_corners(
|
AABB::from_corners(
|
||||||
[envelope.lower()[0], envelope.lower()[1], 0.0],
|
[envelope.lower()[0], envelope.lower()[1], 0.0],
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ pub struct Bbox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bbox {
|
impl Bbox {
|
||||||
pub fn new(shape: &Shape) -> Bbox {
|
pub fn new(shape: &Shape, layer: u64) -> Bbox {
|
||||||
Self {
|
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<W: DotWeightTrait<GW>>(&mut self, weight: W) -> GenericIndex<W>
|
pub fn add_dot<W: DotWeightTrait<GW> + GetLayer>(&mut self, weight: W) -> GenericIndex<W>
|
||||||
where
|
where
|
||||||
GenericIndex<W>: Into<GI>,
|
GenericIndex<W>: Into<GI>,
|
||||||
{
|
{
|
||||||
|
|
@ -100,13 +100,19 @@ impl<
|
||||||
&self
|
&self
|
||||||
.geometry
|
.geometry
|
||||||
.dot_shape(dot.into().try_into().unwrap_or_else(|_| unreachable!())),
|
.dot_shape(dot.into().try_into().unwrap_or_else(|_| unreachable!())),
|
||||||
|
weight.layer(),
|
||||||
),
|
),
|
||||||
dot.into(),
|
dot.into(),
|
||||||
));
|
));
|
||||||
dot
|
dot
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_seg<W: SegWeightTrait<GW>>(&mut self, from: DI, to: DI, weight: W) -> GenericIndex<W>
|
pub fn add_seg<W: SegWeightTrait<GW> + GetLayer>(
|
||||||
|
&mut self,
|
||||||
|
from: DI,
|
||||||
|
to: DI,
|
||||||
|
weight: W,
|
||||||
|
) -> GenericIndex<W>
|
||||||
where
|
where
|
||||||
GenericIndex<W>: Into<GI>,
|
GenericIndex<W>: Into<GI>,
|
||||||
{
|
{
|
||||||
|
|
@ -116,13 +122,14 @@ impl<
|
||||||
&self
|
&self
|
||||||
.geometry
|
.geometry
|
||||||
.seg_shape(seg.into().try_into().unwrap_or_else(|_| unreachable!())),
|
.seg_shape(seg.into().try_into().unwrap_or_else(|_| unreachable!())),
|
||||||
|
weight.layer(),
|
||||||
),
|
),
|
||||||
seg.into(),
|
seg.into(),
|
||||||
));
|
));
|
||||||
seg
|
seg
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_bend<W: BendWeightTrait<GW>>(
|
pub fn add_bend<W: BendWeightTrait<GW> + GetLayer>(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DI,
|
from: DI,
|
||||||
to: DI,
|
to: DI,
|
||||||
|
|
@ -138,6 +145,7 @@ impl<
|
||||||
&self
|
&self
|
||||||
.geometry
|
.geometry
|
||||||
.bend_shape(bend.into().try_into().unwrap_or_else(|_| unreachable!())),
|
.bend_shape(bend.into().try_into().unwrap_or_else(|_| unreachable!())),
|
||||||
|
weight.layer(),
|
||||||
),
|
),
|
||||||
bend.into(),
|
bend.into(),
|
||||||
));
|
));
|
||||||
|
|
@ -248,15 +256,24 @@ impl<
|
||||||
> GeometryWithRtree<GW, DW, SW, BW, GI, DI, SI, BI>
|
> GeometryWithRtree<GW, DW, SW, BW, GI, DI, SI, BI>
|
||||||
{
|
{
|
||||||
fn make_dot_bbox(&self, dot: DI) -> BboxedIndex<GI> {
|
fn make_dot_bbox(&self, dot: DI) -> BboxedIndex<GI> {
|
||||||
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<GI> {
|
fn make_seg_bbox(&self, seg: SI) -> BboxedIndex<GI> {
|
||||||
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<GI> {
|
fn make_bend_bbox(&self, bend: BI) -> BboxedIndex<GI> {
|
||||||
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 {
|
fn shape(&self, index: GI) -> Shape {
|
||||||
|
|
@ -271,6 +288,18 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layer(&self, index: GI) -> u64 {
|
||||||
|
if let Ok(dot) = <GI as TryInto<DI>>::try_into(index) {
|
||||||
|
self.geometry.dot_weight(dot).layer()
|
||||||
|
} else if let Ok(seg) = <GI as TryInto<SI>>::try_into(index) {
|
||||||
|
self.geometry.seg_weight(seg).layer()
|
||||||
|
} else if let Ok(bend) = <GI as TryInto<BI>>::try_into(index) {
|
||||||
|
self.geometry.bend_weight(bend).layer()
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn geometry(&self) -> &Geometry<GW, DW, SW, BW, GI, DI, SI, BI> {
|
pub fn geometry(&self) -> &Geometry<GW, DW, SW, BW, GI, DI, SI, BI> {
|
||||||
&self.geometry
|
&self.geometry
|
||||||
}
|
}
|
||||||
|
|
@ -287,10 +316,11 @@ impl<
|
||||||
!self.rtree.iter().any(|wrapper| {
|
!self.rtree.iter().any(|wrapper| {
|
||||||
let node = wrapper.data;
|
let node = wrapper.data;
|
||||||
let shape = self.shape(node);
|
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
|
!self
|
||||||
.rtree
|
.rtree
|
||||||
.locate_in_envelope(&shape.flat_envelope_3d(0.0, 2))
|
.locate_in_envelope(&shape.envelope_3d(0.0, layer))
|
||||||
.any(|w| *w == wrapper)
|
.any(|w| *w == wrapper)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use geo::Point;
|
||||||
use rstar::RTreeObject;
|
use rstar::RTreeObject;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use super::graph::GetLayer;
|
||||||
use super::loose::{GetNextLoose, Loose, LooseIndex};
|
use super::loose::{GetNextLoose, Loose, LooseIndex};
|
||||||
use super::rules::RulesTrait;
|
use super::rules::RulesTrait;
|
||||||
use super::segbend::Segbend;
|
use super::segbend::Segbend;
|
||||||
|
|
@ -175,7 +176,7 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
|
|
||||||
#[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_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()))]
|
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
fn add_dot_infringably<W: DotWeightTrait<GeometryWeight>>(
|
fn add_dot_infringably<W: DotWeightTrait<GeometryWeight> + GetLayer>(
|
||||||
&mut self,
|
&mut self,
|
||||||
weight: W,
|
weight: W,
|
||||||
infringables: &[GeometryIndex],
|
infringables: &[GeometryIndex],
|
||||||
|
|
@ -469,7 +470,7 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
#[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_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().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()))]
|
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
fn add_seg_infringably<W: SegWeightTrait<GeometryWeight>>(
|
fn add_seg_infringably<W: SegWeightTrait<GeometryWeight> + GetLayer>(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: DotIndex,
|
||||||
to: DotIndex,
|
to: DotIndex,
|
||||||
|
|
@ -527,7 +528,7 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
#[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().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_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()))]
|
#[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<W: BendWeightTrait<GeometryWeight>>(
|
fn add_core_bend_infringably<W: BendWeightTrait<GeometryWeight> + GetLayer>(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: DotIndex,
|
||||||
to: DotIndex,
|
to: DotIndex,
|
||||||
|
|
@ -723,7 +724,7 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
|
|
||||||
self.geometry_with_rtree
|
self.geometry_with_rtree
|
||||||
.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| !self.are_connectable(node, wrapper.data))
|
||||||
.filter(|wrapper| !except.contains(&wrapper.data))
|
.filter(|wrapper| !except.contains(&wrapper.data))
|
||||||
.filter(|wrapper| {
|
.filter(|wrapper| {
|
||||||
|
|
@ -749,7 +750,7 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
|
|
||||||
self.geometry_with_rtree
|
self.geometry_with_rtree
|
||||||
.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| !self.are_connectable(node, wrapper.data))
|
||||||
.filter(|wrapper| shape.intersects(&wrapper.data.primitive(self).shape()))
|
.filter(|wrapper| shape.intersects(&wrapper.data.primitive(self).shape()))
|
||||||
.map(|wrapper| wrapper.data)
|
.map(|wrapper| wrapper.data)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue