Reintroduce improved logic for mesh interior region fill determination (#4464)

* Decide branching mesh fill insideness by winding, normalizing drawn direction at the Path node

* Fix dead connector click targets by explicitly closing the kurbo ellipse port paths

* Fix hole subtraction when a hole vertex is snapped exactly onto its covering contour

* Classify embedded negative space by its single surrounding face so fully enclosed mesh cells still fill
This commit is contained in:
Keavon Chambers
2026-08-19 00:59:40 -07:00
committed by GitHub
parent daa8b6a5a4
commit 2fa6b743fe
6 changed files with 652 additions and 61 deletions

View File

@@ -22,7 +22,11 @@ pub fn rounded_rectangle_path(corner1: DVec2, corner2: DVec2, radii: [f64; 4]) -
/// Ellipse inscribed in the box spanning the two opposite corners.
pub fn ellipse_path(corner1: DVec2, corner2: DVec2) -> BezPath {
let rect = kurbo::Rect::from_points(dvec2_to_point(corner1), dvec2_to_point(corner2));
kurbo::Ellipse::new(rect.center(), (rect.width() / 2., rect.height() / 2.), 0.).to_path(DEFAULT_ACCURACY)
let mut path = kurbo::Ellipse::new(rect.center(), (rect.width() / 2., rect.height() / 2.), 0.).to_path(DEFAULT_ACCURACY);
// Kurbo emits the ellipse as an unclosed 360 degree arc, but hit testing only fills explicitly closed contours
path.close_path();
path
}
#[derive(PartialEq)]
@@ -888,3 +892,23 @@ pub(crate) fn collect_input_resource(input: &NodeInput, out: &mut HashSet<Resour
out.insert(*id);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn port_click_targets_are_clickable_at_their_center() {
let center = DVec2::new(100., 50.);
let mut ports = Ports::new();
ports.insert_input_port_at_center(0, center);
ports.insert_output_port_at_center(0, center + DVec2::new(200., 0.));
assert_eq!(ports.clicked_input_port_from_point(center), Some(0));
assert_eq!(ports.clicked_input_port_from_point(center + DVec2::new(5., 5.)), Some(0));
assert_eq!(ports.clicked_input_port_from_point(center + DVec2::new(20., 0.)), None);
assert_eq!(ports.clicked_output_port_from_point(center + DVec2::new(200., 0.)), Some(0));
assert_eq!(ports.clicked_output_port_from_point(center), None);
}
}

View File

@@ -479,7 +479,7 @@ fn straight_wire_to_bezpath(locations: Vec<IVec2>) -> BezPath {
if locations.len() == 2 {
let p1 = to_point(locations[0]);
let p2 = to_point(locations[1]);
Line::new(p1, p2).to_path(DEFAULT_ACCURACY);
return Line::new(p1, p2).to_path(DEFAULT_ACCURACY);
}
let corner_radius = 10;