mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 11:18:11 +08:00
Fix box selection regression where only intersected, not contained, objects get selected (#3093)
* fix insideness checking * fix selection insideness checking * Revert changes to comments * Revert unneed rename --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
a744499f4f
commit
57853f755b
@@ -608,8 +608,9 @@ pub fn round_line_join(bezpath1: &BezPath, bezpath2: &BezPath, center: DVec2) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the `bezpath1` is completely inside the `bezpath2`.
|
/// Returns `true` if the `bezpath1` is completely inside the `bezpath2`.
|
||||||
|
/// NOTE: `bezpath2` must be a closed path to get correct results.
|
||||||
pub fn bezpath_is_inside_bezpath(bezpath1: &BezPath, bezpath2: &BezPath, accuracy: Option<f64>, minimum_separation: Option<f64>) -> bool {
|
pub fn bezpath_is_inside_bezpath(bezpath1: &BezPath, bezpath2: &BezPath, accuracy: Option<f64>, minimum_separation: Option<f64>) -> bool {
|
||||||
// Eliminate any possibility of one being inside the other, if either of them is empty
|
// Eliminate any possibility of one being inside the other, if either of them are empty
|
||||||
if bezpath1.is_empty() || bezpath2.is_empty() {
|
if bezpath1.is_empty() || bezpath2.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -621,7 +622,7 @@ pub fn bezpath_is_inside_bezpath(bezpath1: &BezPath, bezpath2: &BezPath, accurac
|
|||||||
// Reasoning:
|
// Reasoning:
|
||||||
// If the inner bezpath bounding box is larger than the outer bezpath bounding box in any direction
|
// If the inner bezpath bounding box is larger than the outer bezpath bounding box in any direction
|
||||||
// then the inner bezpath is intersecting with or outside the outer bezpath.
|
// then the inner bezpath is intersecting with or outside the outer bezpath.
|
||||||
if !outer_bbox.contains_rect(inner_bbox) {
|
if !outer_bbox.contains_rect(inner_bbox) && outer_bbox.intersect(inner_bbox).is_zero_area() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use super::algorithms::intersection::filtered_segment_intersections;
|
use super::algorithms::{bezpath_algorithms::bezpath_is_inside_bezpath, intersection::filtered_segment_intersections};
|
||||||
use super::misc::dvec2_to_point;
|
use super::misc::dvec2_to_point;
|
||||||
use crate::math::math_ext::QuadExt;
|
use crate::math::math_ext::QuadExt;
|
||||||
use crate::math::quad::Quad;
|
use crate::math::quad::Quad;
|
||||||
@@ -6,7 +6,7 @@ use crate::subpath::Subpath;
|
|||||||
use crate::vector::PointId;
|
use crate::vector::PointId;
|
||||||
use crate::vector::misc::point_to_dvec2;
|
use crate::vector::misc::point_to_dvec2;
|
||||||
use glam::{DAffine2, DMat2, DVec2};
|
use glam::{DAffine2, DMat2, DVec2};
|
||||||
use kurbo::{Affine, ParamCurve, PathSeg, Point, Shape};
|
use kurbo::{Affine, BezPath, ParamCurve, PathSeg, Shape};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct FreePoint {
|
pub struct FreePoint {
|
||||||
@@ -125,9 +125,11 @@ impl ClickTarget {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut selection = BezPath::from_path_segments(bezier_iter());
|
||||||
|
selection.close_path();
|
||||||
|
|
||||||
// Check if shape is entirely within selection
|
// Check if shape is entirely within selection
|
||||||
let any_point_from_subpath = subpath.manipulator_groups().first().map(|manipulators| manipulators.anchor);
|
bezpath_is_inside_bezpath(&subpath.to_bezpath(), &selection, None, None)
|
||||||
any_point_from_subpath.is_some_and(|shape_point| bezier_iter().map(|bezier| bezier.winding(Point::new(shape_point.x, shape_point.y))).sum::<i32>() != 0)
|
|
||||||
}
|
}
|
||||||
ClickTargetType::FreePoint(point) => bezier_iter().map(|bezier: PathSeg| bezier.winding(dvec2_to_point(point.position))).sum::<i32>() != 0,
|
ClickTargetType::FreePoint(point) => bezier_iter().map(|bezier: PathSeg| bezier.winding(dvec2_to_point(point.position))).sum::<i32>() != 0,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user