refactor(layout,geometry): Layout::node_bbox(...) → AccessShape::bbox(Layout::node_shape(...), 0.0)

This commit is contained in:
Alain Emilia Anna Zscheile 2025-01-03 19:16:58 +01:00 committed by mikolaj
parent 740019e2e5
commit fae1f4d7bc
5 changed files with 42 additions and 74 deletions

View File

@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use crate::{
board::{mesadata::AccessMesadata, BandName, Board, ResolvedSelector},
drawing::graph::{GetLayer, MakePrimitive, PrimitiveIndex},
geometry::GenericNode,
geometry::{shape::AccessShape, GenericNode},
graph::{GenericIndex, GetPetgraphIndex},
layout::{poly::PolyWeight, CompoundWeight, NodeIndex},
};
@ -209,7 +209,7 @@ impl Selection {
if let Some(rsel) = ResolvedSelector::try_from_node(board, node) {
let rseli = selectors.entry(rsel).or_default();
rseli.0.insert(node);
if kind.matches(aabb, &layout.node_bbox(node)) {
if kind.matches(aabb, &layout.node_shape(node).bbox(0.0)) {
rseli.1.insert(node);
}
}
@ -234,7 +234,7 @@ impl Selection {
) {
let node = geom.data;
if layout.is_node_in_layer(node, active_layer)
&& kind.matches(aabb, &layout.node_bbox(node))
&& kind.matches(aabb, &layout.node_shape(node).bbox(0.0))
{
if let Some(rsel) = ResolvedSelector::try_from_node(board, node) {
selectors.insert(rsel);

View File

@ -4,6 +4,7 @@
use geo::algorithm::line_measures::{Euclidean, Length};
use geo::{Centroid, Contains, Point, Polygon};
use rstar::AABB;
use crate::geometry::shape::{AccessShape, MeasureLength};
@ -32,4 +33,16 @@ impl AccessShape for PolyShape {
fn contains_point(&self, p: Point) -> bool {
self.polygon.contains(&p)
}
fn bbox_without_margin(&self) -> AABB<[f64; 2]> {
AABB::from_points(
self.polygon
.exterior()
.0
.iter()
.map(|coord| [coord.x, coord.y])
.collect::<Vec<_>>()
.iter(),
)
}
}

View File

@ -19,7 +19,6 @@ pub trait AccessPrimitiveShape: AccessShape {
fn priority(&self) -> usize;
fn inflate(&self, margin: f64) -> PrimitiveShape;
fn intersects(&self, other: &PrimitiveShape) -> bool;
fn bbox(&self, margin: f64) -> AABB<[f64; 2]>;
fn width(&self) -> f64;
fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> {
@ -71,6 +70,10 @@ impl AccessShape for DotShape {
fn contains_point(&self, p: Point) -> bool {
Euclidean::distance(&p, &self.circle.pos) <= self.circle.r
}
fn bbox_without_margin(&self) -> AABB<[f64; 2]> {
self.circle.bbox(0.0)
}
}
impl AccessPrimitiveShape for DotShape {
@ -118,19 +121,6 @@ impl AccessPrimitiveShape for DotShape {
}
}
fn bbox(&self, margin: f64) -> AABB<[f64; 2]> {
AABB::from_corners(
[
self.circle.pos.x() - self.circle.r - margin,
self.circle.pos.y() - self.circle.r - margin,
],
[
self.circle.pos.x() + self.circle.r + margin,
self.circle.pos.y() + self.circle.r + margin,
],
)
}
fn width(&self) -> f64 {
self.circle.r * 2.0
}
@ -174,6 +164,13 @@ impl AccessShape for SegShape {
fn contains_point(&self, p: Point) -> bool {
self.polygon().contains(&p)
}
fn bbox_without_margin(&self) -> AABB<[f64; 2]> {
super::poly::PolyShape {
polygon: self.polygon(),
}
.bbox_without_margin()
}
}
impl AccessPrimitiveShape for SegShape {
@ -220,22 +217,6 @@ impl AccessPrimitiveShape for SegShape {
}
}
fn bbox(&self, margin: f64) -> AABB<[f64; 2]> {
let points: Vec<[f64; 2]> = self
.polygon()
.exterior()
.points()
.map(|p| [p.x(), p.y()])
.collect();
let aabb = AABB::<[f64; 2]>::from_points(points.iter());
// Inflate.
let lower = [aabb.lower()[0] - margin, aabb.lower()[1] - margin];
let upper = [aabb.upper()[0] + margin, aabb.upper()[1] + margin];
AABB::<[f64; 2]>::from_corners(lower, upper)
}
fn width(&self) -> f64 {
self.width
}
@ -331,6 +312,10 @@ impl AccessShape for BendShape {
let d = Euclidean::distance(&p, &self.inner_circle.pos);
self.between_ends(p) && d >= self.inner_circle().r && d <= self.outer_circle().r
}
fn bbox_without_margin(&self) -> AABB<[f64; 2]> {
self.inner_circle.bbox(self.width)
}
}
impl AccessPrimitiveShape for BendShape {
@ -387,20 +372,6 @@ impl AccessPrimitiveShape for BendShape {
}
}
fn bbox(&self, _margin: f64) -> AABB<[f64; 2]> {
let halfwidth = self.inner_circle.r + self.width;
AABB::from_corners(
[
self.inner_circle.pos.x() - halfwidth,
self.inner_circle.pos.y() - halfwidth,
],
[
self.inner_circle.pos.x() + halfwidth,
self.inner_circle.pos.y() + halfwidth,
],
)
}
fn width(&self) -> f64 {
self.width
}
@ -409,6 +380,6 @@ impl AccessPrimitiveShape for BendShape {
impl RTreeObject for PrimitiveShape {
type Envelope = AABB<[f64; 2]>;
fn envelope(&self) -> Self::Envelope {
AccessPrimitiveShape::bbox(self, 0.0)
AccessShape::bbox(self, 0.0)
}
}

View File

@ -4,6 +4,7 @@
use enum_dispatch::enum_dispatch;
use geo::Point;
use rstar::AABB;
use crate::geometry::{
poly::PolyShape,
@ -19,6 +20,15 @@ pub trait MeasureLength {
pub trait AccessShape: MeasureLength {
fn center(&self) -> Point;
fn contains_point(&self, p: Point) -> bool;
fn bbox_without_margin(&self) -> AABB<[f64; 2]>;
fn bbox(&self, margin: f64) -> AABB<[f64; 2]> {
let aabb = self.bbox_without_margin();
AABB::<[f64; 2]>::from_corners(
[aabb.lower()[0] - margin, aabb.lower()[1] - margin],
[aabb.upper()[0] + margin, aabb.upper()[1] + margin],
)
}
}
#[enum_dispatch(MeasureLength, AccessShape)]

View File

@ -353,32 +353,6 @@ impl<R: AccessRules> Layout<R> {
}
}
pub fn node_bbox(&self, index: NodeIndex) -> AABB<[f64; 2]> {
use crate::geometry::primitive::AccessPrimitiveShape;
match index {
NodeIndex::Primitive(primitive) => primitive.primitive(&self.drawing).shape().bbox(0.0),
NodeIndex::Compound(compound) => match self.drawing.compound_weight(compound) {
CompoundWeight::Poly(_) => {
let coord_string = self
.poly(GenericIndex::<PolyWeight>::new(compound.petgraph_index()))
.shape()
.polygon
.exterior()
.0
.iter()
.map(|coord| [coord.x, coord.y])
.collect::<Vec<_>>();
AABB::from_points(&coord_string[..])
}
CompoundWeight::Via(_) => self
.via(GenericIndex::<ViaWeight>::new(compound.petgraph_index()))
.shape()
.bbox(0.0),
},
}
}
pub fn rules(&self) -> &R {
self.drawing.rules()
}