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},
|
selection::{BboxSelectionKind, Selection},
|
||||||
},
|
},
|
||||||
board::{AccessMesadata, Board},
|
board::{AccessMesadata, Board},
|
||||||
geometry::shape::AccessShape,
|
|
||||||
layout::NodeIndex,
|
layout::NodeIndex,
|
||||||
router::planar_incr_embed,
|
router::planar_incr_embed,
|
||||||
};
|
};
|
||||||
|
|
@ -191,29 +190,14 @@ impl Overlay {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let geoms: Vec<_> = board
|
let old_selection = self.take_selection();
|
||||||
.layout()
|
self.select_all_in_bbox(
|
||||||
.drawing()
|
board,
|
||||||
.rtree()
|
appearance_panel,
|
||||||
.locate_in_envelope_intersecting(&AABB::<[f64; 3]>::from_corners(
|
&AABB::from_point([at.x(), at.y()]),
|
||||||
[at.x(), at.y(), -f64::INFINITY],
|
BboxSelectionKind::MerelyIntersects,
|
||||||
[at.x(), at.y(), f64::INFINITY],
|
);
|
||||||
))
|
self.selection ^= &old_selection;
|
||||||
.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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_all_in_bbox(
|
pub fn select_all_in_bbox(
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,7 @@
|
||||||
use geo::Line;
|
use geo::Line;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::{
|
geometry::{primitive::PrimitiveShape, shape::AccessShape, GetWidth},
|
||||||
primitive::{AccessPrimitiveShape, PrimitiveShape},
|
|
||||||
shape::AccessShape,
|
|
||||||
},
|
|
||||||
math::{self, Circle, NoTangents, RotationSense},
|
math::{self, Circle, NoTangents, RotationSense},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,22 @@ use std::f64::consts::TAU;
|
||||||
|
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use geo::algorithm::line_measures::{Distance, Euclidean};
|
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 rstar::{RTreeObject, AABB};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::shape::{AccessShape, MeasureLength},
|
geometry::{
|
||||||
|
shape::{AccessShape, MeasureLength},
|
||||||
|
GetWidth,
|
||||||
|
},
|
||||||
math::{self, Circle},
|
math::{self, Circle},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait AccessPrimitiveShape: AccessShape {
|
pub trait AccessPrimitiveShape: AccessShape + GetWidth {
|
||||||
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 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]> {
|
||||||
let envelope = self.bbox(margin);
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum PrimitiveShape {
|
pub enum PrimitiveShape {
|
||||||
// Intentionally in different order to reorder `self.intersects(...)` properly.
|
// 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]> {
|
fn bbox_without_margin(&self) -> AABB<[f64; 2]> {
|
||||||
self.circle.bbox(0.0)
|
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 {
|
impl AccessPrimitiveShape for DotShape {
|
||||||
|
|
@ -120,7 +127,9 @@ impl AccessPrimitiveShape for DotShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetWidth for DotShape {
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.circle.r * 2.0
|
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 {
|
impl MeasureLength for SegShape {
|
||||||
fn length(&self) -> f64 {
|
fn length(&self) -> f64 {
|
||||||
Euclidean::distance(&self.to, &self.from)
|
Euclidean::distance(&self.to, &self.from)
|
||||||
|
|
@ -227,7 +243,9 @@ impl AccessPrimitiveShape for SegShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetWidth for SegShape {
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
@ -382,7 +400,9 @@ impl AccessPrimitiveShape for BendShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetWidth for BendShape {
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue