Mesh: Create Gradient Mesh at a point outside the object keeps the path

object.mesh.create with `at` ignored a failed line placement and still replaced the
path with a bare 1x1 mesh. When the new mesh can't place its lines at the point, the
object is left as it is, and when nothing was converted the command fails with
"point is outside the object" and adds no undo step.
This commit is contained in:
dotCooCoo
2026-11-02 12:04:11 +07:00
committed by bflatastic
parent e4a066f12a
commit 76be75400e
2 changed files with 28 additions and 1 deletions
+8 -1
View File
@@ -59,7 +59,14 @@ pub(super) fn mesh_create(s: &mut Session, p: &Value) -> Result<Value> {
};
let Some(mut m) = m else { continue };
if let Some(q) = at {
index = m.add_lines_at(q, tol);
// A point the new mesh can't place its lines at leaves the object as it is.
match m.add_lines_at(q, tol) {
Some(i) => index = Some(i),
None => {
refused.get_or_insert("point is outside the object");
continue;
}
}
}
let mut mn = Node::new(n.id, NodeKind::Mesh(m));
mn.name = n.name.clone();
+20
View File
@@ -1040,6 +1040,26 @@ fn mesh_create_at_point_single_undo() {
assert!(b.x0 > -3.0 && b.x1 < 103.0, "{b:?}");
}
/// Create Gradient Mesh with an `at` the new mesh can't place its lines at (outside the object,
/// or past `tolerance`) is an error that leaves the path a path; within `tolerance` it adds them.
#[test]
fn mesh_create_at_a_point_outside_keeps_the_path() {
let mut s = session();
let a = rect(&mut s, 0.0, 0.0, 100.0, 100.0);
sel(&mut s, &[a]);
let n = undo_len(&s);
for p in [json!({"at": [300, 300]}), json!({"at": [50, 103]}), json!({"at": [50, 110], "tolerance": 3})] {
let r = s.execute("object.mesh.create", &p);
assert!(matches!(&r, Err(EngineError::BadParams { msg, .. }) if msg == "point is outside the object"), "{p}: {r:?}");
assert!(matches!(node(&s, a).kind, NodeKind::Path { .. }), "{p}: still a path");
}
assert_eq!(undo_len(&s), n, "nothing changed");
let r = s.execute("object.mesh.create", &json!({"at": [50, 102], "tolerance": 3})).unwrap();
let m = mesh_of(&s, a);
assert_eq!((m.rows, m.cols), (1, 2), "a column through the bottom edge");
assert!(m.points[r["index"].as_u64().unwrap() as usize].p.distance(Point::new(50.0, 100.0)) < 0.5);
}
#[test]
fn mesh_expand_to_flat_pieces() {
let mut s = session();