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::{
|
use crate::{
|
||||||
board::{mesadata::AccessMesadata, BandName, Board, ResolvedSelector},
|
board::{mesadata::AccessMesadata, BandName, Board, ResolvedSelector},
|
||||||
drawing::graph::{GetLayer, MakePrimitive, PrimitiveIndex},
|
drawing::graph::{GetLayer, MakePrimitive, PrimitiveIndex},
|
||||||
geometry::GenericNode,
|
geometry::{shape::AccessShape, GenericNode},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
layout::{poly::PolyWeight, CompoundWeight, NodeIndex},
|
layout::{poly::PolyWeight, CompoundWeight, NodeIndex},
|
||||||
};
|
};
|
||||||
|
|
@ -209,7 +209,7 @@ impl Selection {
|
||||||
if let Some(rsel) = ResolvedSelector::try_from_node(board, node) {
|
if let Some(rsel) = ResolvedSelector::try_from_node(board, node) {
|
||||||
let rseli = selectors.entry(rsel).or_default();
|
let rseli = selectors.entry(rsel).or_default();
|
||||||
rseli.0.insert(node);
|
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);
|
rseli.1.insert(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +234,7 @@ impl Selection {
|
||||||
) {
|
) {
|
||||||
let node = geom.data;
|
let node = geom.data;
|
||||||
if layout.is_node_in_layer(node, active_layer)
|
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) {
|
if let Some(rsel) = ResolvedSelector::try_from_node(board, node) {
|
||||||
selectors.insert(rsel);
|
selectors.insert(rsel);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use geo::algorithm::line_measures::{Euclidean, Length};
|
use geo::algorithm::line_measures::{Euclidean, Length};
|
||||||
use geo::{Centroid, Contains, Point, Polygon};
|
use geo::{Centroid, Contains, Point, Polygon};
|
||||||
|
use rstar::AABB;
|
||||||
|
|
||||||
use crate::geometry::shape::{AccessShape, MeasureLength};
|
use crate::geometry::shape::{AccessShape, MeasureLength};
|
||||||
|
|
||||||
|
|
@ -32,4 +33,16 @@ impl AccessShape for PolyShape {
|
||||||
fn contains_point(&self, p: Point) -> bool {
|
fn contains_point(&self, p: Point) -> bool {
|
||||||
self.polygon.contains(&p)
|
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 priority(&self) -> usize;
|
||||||
fn inflate(&self, margin: f64) -> PrimitiveShape;
|
fn inflate(&self, margin: f64) -> PrimitiveShape;
|
||||||
fn intersects(&self, other: &PrimitiveShape) -> bool;
|
fn intersects(&self, other: &PrimitiveShape) -> bool;
|
||||||
fn bbox(&self, margin: f64) -> AABB<[f64; 2]>;
|
|
||||||
fn width(&self) -> f64;
|
fn width(&self) -> f64;
|
||||||
|
|
||||||
fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> {
|
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 {
|
fn contains_point(&self, p: Point) -> bool {
|
||||||
Euclidean::distance(&p, &self.circle.pos) <= self.circle.r
|
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 {
|
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 {
|
fn width(&self) -> f64 {
|
||||||
self.circle.r * 2.0
|
self.circle.r * 2.0
|
||||||
}
|
}
|
||||||
|
|
@ -174,6 +164,13 @@ impl AccessShape for SegShape {
|
||||||
fn contains_point(&self, p: Point) -> bool {
|
fn contains_point(&self, p: Point) -> bool {
|
||||||
self.polygon().contains(&p)
|
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 {
|
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 {
|
fn width(&self) -> f64 {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
@ -331,6 +312,10 @@ impl AccessShape for BendShape {
|
||||||
let d = Euclidean::distance(&p, &self.inner_circle.pos);
|
let d = Euclidean::distance(&p, &self.inner_circle.pos);
|
||||||
self.between_ends(p) && d >= self.inner_circle().r && d <= self.outer_circle().r
|
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 {
|
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 {
|
fn width(&self) -> f64 {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
@ -409,6 +380,6 @@ impl AccessPrimitiveShape for BendShape {
|
||||||
impl RTreeObject for PrimitiveShape {
|
impl RTreeObject for PrimitiveShape {
|
||||||
type Envelope = AABB<[f64; 2]>;
|
type Envelope = AABB<[f64; 2]>;
|
||||||
fn envelope(&self) -> Self::Envelope {
|
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 enum_dispatch::enum_dispatch;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
|
use rstar::AABB;
|
||||||
|
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
poly::PolyShape,
|
poly::PolyShape,
|
||||||
|
|
@ -19,6 +20,15 @@ pub trait MeasureLength {
|
||||||
pub trait AccessShape: MeasureLength {
|
pub trait AccessShape: MeasureLength {
|
||||||
fn center(&self) -> Point;
|
fn center(&self) -> Point;
|
||||||
fn contains_point(&self, p: Point) -> bool;
|
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)]
|
#[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 {
|
pub fn rules(&self) -> &R {
|
||||||
self.drawing.rules()
|
self.drawing.rules()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue