mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-02 22:20:50 -06:00
Live Paint: the Live Paint tools skip hidden edges
An edge hidden on its own (for example with Object > Hide) while its Live Paint group stays visible could still be highlighted, selected or stroked, and a hidden edge nearer the pointer kept a visible one from being picked. lp_part_at now takes the nearest visible edge (visible_edge_near), inside and outside the faces, for the hover, the Live Paint Selection click and the Bucket's Shift-click. The Bucket's Shift-click sends nothing where no edge is highlighted, and livePaint.strokeEdge also skips hidden edges, so the Bucket strokes the edge it highlights.
This commit is contained in:
@@ -766,7 +766,7 @@ fn lp_stroke_edge(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let tol = f64_or(p, "tolerance", 4.0).clamp(0.0, 1000.0);
|
||||
let edge = s.edit("Live Paint Bucket", |d, _| {
|
||||
let n = d.node(g).filter(|n| is_live_paint(n)).ok_or_else(|| bad(C, format!("{g} is not a Live Paint group")))?;
|
||||
let eid = edge_near(n, pt, tol).map(|e| e.id).ok_or_else(|| EngineError::Other("no Live Paint edge near that point".into()))?;
|
||||
let eid = b::visible_edge_near(n, pt, tol).map(|e| e.id).ok_or_else(|| EngineError::Other("no Live Paint edge near that point".into()))?;
|
||||
let e = d.node_mut(eid).ok_or(EngineError::NoNode(eid))?;
|
||||
e.appearance.set_stroke(paint.clone());
|
||||
if let Some(st) = e.appearance.stroke_mut() {
|
||||
|
||||
@@ -531,6 +531,28 @@ fn live_paint_stroke_edge() {
|
||||
assert!(s.execute("livePaint.strokeEdge", &json!({"group": g.0, "point": [300, 300]})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn live_paint_stroke_edge_skips_hidden_edges() {
|
||||
let mut s = session();
|
||||
let g = live(&mut s);
|
||||
// The vertical edge at x=100 is hidden on its own; the group stays visible.
|
||||
let vertical_at = |s: &Session, x: f64| -> Vec<u64> {
|
||||
vectorcraft_tools::builder::edges(&node(s, g))
|
||||
.iter()
|
||||
.filter(|e| e.geometric_bounds().is_some_and(|bb| (bb.x0 - x).abs() < 1e-6 && (bb.x1 - x).abs() < 1e-6))
|
||||
.map(|e| e.id.0)
|
||||
.collect()
|
||||
};
|
||||
let hidden = vertical_at(&s, 100.0);
|
||||
assert!(!hidden.is_empty());
|
||||
s.execute("object.setProps", &json!({"ids": hidden, "visible": false})).unwrap();
|
||||
// 1 pt from the hidden edge, the nearest visible edge within the tolerance is the one at x=50.
|
||||
let r = s.execute("livePaint.strokeEdge", &json!({"group": g.0, "point": [99, 50], "tolerance": 60})).unwrap();
|
||||
assert!(vertical_at(&s, 50.0).contains(&r["edge"].as_u64().unwrap()), "{r}");
|
||||
// With only the hidden edge within the tolerance, no edge is stroked.
|
||||
assert!(s.execute("livePaint.strokeEdge", &json!({"group": g.0, "point": [99, 50]})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn live_paint_release_and_expand() {
|
||||
let mut s = session();
|
||||
|
||||
Reference in New Issue
Block a user