mirror of https://codeberg.org/topola/topola.git
refactor(layout,geometry): Layout::node_bbox(...) → AccessShape::bbox(Layout::node_shape(...), 0.0)
This commit is contained in:
parent
740019e2e5
commit
fae1f4d7bc
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue