mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 21:57:12 -06:00
Curvature: deleting a point re-curves the path through the remaining points
Deleting a point of a finished path with the Curvature tool sent path.removeAnchor, which refits the two segments that met at the point so one curve follows them. The path kept the bend of the deleted point instead of curving through the points that remain. The tool now sends path.removeAnchor with curvature: true, which uses the new curvature_remove. Each smooth neighbor takes new handles from its new neighbors, and an end beside one of them takes its end handle again. A corner neighbor keeps its handle directions, and its handle on the new segment scales with the segment's chord. With two points left, the points that curve lose their handles. Object > Path > Remove Anchor Points and the Delete Anchor Point tool still refit the curve.
This commit is contained in:
@@ -109,13 +109,14 @@ pub(super) fn remove_anchor(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let id = id_param(p, "id").ok_or_else(|| bad(C, "missing id"))?;
|
||||
let si = usize_opt(p, "subpath", C)?.unwrap_or(0);
|
||||
let ai = usize_req(p, "anchor", C)?;
|
||||
let curvature = switch_or(p, "curvature", false, C)?;
|
||||
let removed = s.edit("Delete Anchor Point", |d, sel| {
|
||||
let sp = path_mut(d, id)?.subpaths.get(si).ok_or_else(|| EngineError::Other("no such subpath".into()))?;
|
||||
if ai >= sp.anchors.len() {
|
||||
return Err(EngineError::Other("no such anchor".into()));
|
||||
}
|
||||
let mut emptied = Beside::replacing(d, &[id]);
|
||||
let removed = remove_anchors_of(d, sel, &mut emptied, id, [(si, ai)])?;
|
||||
let removed = remove_anchors_of(d, sel, &mut emptied, id, [(si, ai)], curvature)?;
|
||||
emptied.finish(d)?;
|
||||
Ok(removed)
|
||||
})?;
|
||||
@@ -141,7 +142,7 @@ pub(super) fn remove_anchors(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
let shape: Vec<(usize, bool)> =
|
||||
d.node(id).and_then(Node::path_data).map(|p| p.subpaths.iter().map(|sp| (sp.anchors.len(), sp.closed)).collect()).unwrap_or_default();
|
||||
let next = following_anchors(&shape, &anchors);
|
||||
if remove_anchors_of(d, sel, &mut emptied, id, anchors)? {
|
||||
if remove_anchors_of(d, sel, &mut emptied, id, anchors, false)? {
|
||||
removed += 1;
|
||||
} else if !next.is_empty() {
|
||||
// The next anchor along is selected, so the next Remove Anchor Points goes on from
|
||||
@@ -180,14 +181,16 @@ fn following_anchors(shape: &[(usize, bool)], removed: &[(usize, usize)]) -> BTr
|
||||
}
|
||||
|
||||
/// Remove `anchors` (subpath, anchor) of path `id` without opening it, refitting the curve round
|
||||
/// each one. A subpath left with one anchor is removed, and a path left with no subpath is removed
|
||||
/// through `emptied`. True when the path went.
|
||||
/// each one, or with `curvature` re-curving it as the Curvature tool curves its points
|
||||
/// ([`vectorcraft_tools::draw2::curvature_remove`]). A subpath left with one anchor is removed,
|
||||
/// and a path left with no subpath is removed through `emptied`. True when the path went.
|
||||
fn remove_anchors_of(
|
||||
d: &mut Document,
|
||||
sel: &mut Selection,
|
||||
emptied: &mut Beside,
|
||||
id: NodeId,
|
||||
anchors: impl IntoIterator<Item = (usize, usize)>,
|
||||
curvature: bool,
|
||||
) -> Result<bool> {
|
||||
let mut anchors: Vec<(usize, usize)> = anchors.into_iter().collect();
|
||||
// The last first, so the indexes still to come stay valid.
|
||||
@@ -196,7 +199,11 @@ fn remove_anchors_of(
|
||||
let path = path_mut(d, id)?;
|
||||
for (si, ai) in anchors {
|
||||
if let Some(sp) = path.subpaths.get_mut(si) {
|
||||
po::remove_anchor(sp, ai);
|
||||
if curvature {
|
||||
vectorcraft_tools::draw2::curvature_remove(sp, ai);
|
||||
} else {
|
||||
po::remove_anchor(sp, ai);
|
||||
}
|
||||
}
|
||||
}
|
||||
path.subpaths.retain(|sp| sp.anchors.len() >= 2);
|
||||
|
||||
@@ -38,7 +38,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Delete Anchor Point",
|
||||
[],
|
||||
None,
|
||||
"{id, subpath?, anchor} remove one anchor, re-fitting the curve",
|
||||
"{id, subpath?, anchor, curvature?} remove one anchor, re-fitting the curve (with curvature: true, the curve where it was follows the remaining anchors, as the Curvature tool curves its points)",
|
||||
has_doc,
|
||||
remove_anchor
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user