mirror of https://codeberg.org/topola/topola.git
fix(topola-egui): Fix click-based selection of pins
- Do intersection calculation between DotShape and Rect=AABB properly
This commit is contained in:
parent
464e8abb89
commit
8d0681c07d
|
|
@ -12,7 +12,6 @@ use topola::{
|
|||
selection::{BboxSelectionKind, Selection},
|
||||
},
|
||||
board::{AccessMesadata, Board},
|
||||
geometry::shape::AccessShape,
|
||||
layout::NodeIndex,
|
||||
router::planar_incr_embed,
|
||||
};
|
||||
|
|
@ -191,29 +190,14 @@ impl Overlay {
|
|||
return;
|
||||
}
|
||||
|
||||
let geoms: Vec<_> = board
|
||||
.layout()
|
||||
.drawing()
|
||||
.rtree()
|
||||
.locate_in_envelope_intersecting(&AABB::<[f64; 3]>::from_corners(
|
||||
[at.x(), at.y(), -f64::INFINITY],
|
||||
[at.x(), at.y(), f64::INFINITY],
|
||||
))
|
||||
.collect();
|
||||
|
||||
if let Some(geom) = geoms.iter().find(|&&geom| {
|
||||
board.layout().node_shape(geom.data).contains_point(at)
|
||||
// TODO: fix which layers to query
|
||||
&& board
|
||||
.layout()
|
||||
.drawing()
|
||||
// This should use:
|
||||
// `.is_node_in_any_layer_of(geom.data, &appearance_panel.visible[..])`
|
||||
// instead, but that doesn't work reliably
|
||||
.is_node_in_layer(geom.data, 0)
|
||||
}) {
|
||||
self.selection.toggle_at_node(board, geom.data);
|
||||
}
|
||||
let old_selection = self.take_selection();
|
||||
self.select_all_in_bbox(
|
||||
board,
|
||||
appearance_panel,
|
||||
&AABB::from_point([at.x(), at.y()]),
|
||||
BboxSelectionKind::MerelyIntersects,
|
||||
);
|
||||
self.selection ^= &old_selection;
|
||||
}
|
||||
|
||||
pub fn select_all_in_bbox(
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@
|
|||
use geo::Line;
|
||||
|
||||
use crate::{
|
||||
geometry::{
|
||||
primitive::{AccessPrimitiveShape, PrimitiveShape},
|
||||
shape::AccessShape,
|
||||
},
|
||||
geometry::{primitive::PrimitiveShape, shape::AccessShape, GetWidth},
|
||||
math::{self, Circle, NoTangents, RotationSense},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,20 +6,22 @@ use std::f64::consts::TAU;
|
|||
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use geo::algorithm::line_measures::{Distance, Euclidean};
|
||||
use geo::{point, polygon, Contains, Intersects, Line, Point, Polygon, Rotate};
|
||||
use geo::{point, polygon, Contains, Intersects, Line, Point, Polygon, Rect, Rotate};
|
||||
use rstar::{RTreeObject, AABB};
|
||||
|
||||
use crate::{
|
||||
geometry::shape::{AccessShape, MeasureLength},
|
||||
geometry::{
|
||||
shape::{AccessShape, MeasureLength},
|
||||
GetWidth,
|
||||
},
|
||||
math::{self, Circle},
|
||||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait AccessPrimitiveShape: AccessShape {
|
||||
pub trait AccessPrimitiveShape: AccessShape + GetWidth {
|
||||
fn priority(&self) -> usize;
|
||||
fn inflate(&self, margin: f64) -> PrimitiveShape;
|
||||
fn intersects(&self, other: &PrimitiveShape) -> bool;
|
||||
fn width(&self) -> f64;
|
||||
|
||||
fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> {
|
||||
let envelope = self.bbox(margin);
|
||||
|
|
@ -42,7 +44,7 @@ pub trait AccessPrimitiveShape: AccessShape {
|
|||
}
|
||||
}
|
||||
|
||||
#[enum_dispatch(MeasureLength, AccessShape, AccessPrimitiveShape)]
|
||||
#[enum_dispatch(AccessShape, AccessPrimitiveShape, GetWidth, MeasureLength)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum PrimitiveShape {
|
||||
// Intentionally in different order to reorder `self.intersects(...)` properly.
|
||||
|
|
@ -74,6 +76,11 @@ impl AccessShape for DotShape {
|
|||
fn bbox_without_margin(&self) -> AABB<[f64; 2]> {
|
||||
self.circle.bbox(0.0)
|
||||
}
|
||||
|
||||
fn intersects_with_bbox(&self, bbox: &AABB<[f64; 2]>) -> bool {
|
||||
let bbox = Rect::new(bbox.lower(), bbox.upper());
|
||||
Euclidean::distance(&self.circle.pos, &bbox.to_polygon()) < self.circle.r
|
||||
}
|
||||
}
|
||||
|
||||
impl AccessPrimitiveShape for DotShape {
|
||||
|
|
@ -120,7 +127,9 @@ impl AccessPrimitiveShape for DotShape {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetWidth for DotShape {
|
||||
fn width(&self) -> f64 {
|
||||
self.circle.r * 2.0
|
||||
}
|
||||
|
|
@ -157,6 +166,13 @@ impl SegShape {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<SegShape> for Polygon {
|
||||
#[inline(always)]
|
||||
fn from(x: SegShape) -> Polygon {
|
||||
x.polygon()
|
||||
}
|
||||
}
|
||||
|
||||
impl MeasureLength for SegShape {
|
||||
fn length(&self) -> f64 {
|
||||
Euclidean::distance(&self.to, &self.from)
|
||||
|
|
@ -227,7 +243,9 @@ impl AccessPrimitiveShape for SegShape {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetWidth for SegShape {
|
||||
fn width(&self) -> f64 {
|
||||
self.width
|
||||
}
|
||||
|
|
@ -382,7 +400,9 @@ impl AccessPrimitiveShape for BendShape {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetWidth for BendShape {
|
||||
fn width(&self) -> f64 {
|
||||
self.width
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue