From ff99878755fd12e93664471aa4f01fe1a4e677ef Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Sat, 6 Jun 2026 14:43:24 +0300 Subject: [PATCH] Fixed eraser tool adding to mesh in rare cases --- src/CanvasComponents/MeshCanvasComponent.cpp | 15 ++++++++++----- src/DrawingProgram/Tools/EraserTool.cpp | 14 ++++++++++---- src/DrawingProgram/Tools/EraserTool.hpp | 1 + 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/CanvasComponents/MeshCanvasComponent.cpp b/src/CanvasComponents/MeshCanvasComponent.cpp index e3e9a49..e122422 100644 --- a/src/CanvasComponents/MeshCanvasComponent.cpp +++ b/src/CanvasComponents/MeshCanvasComponent.cpp @@ -374,13 +374,18 @@ CanvasComponentEraseDetailResult MeshCanvasComponent::erase_detail(const SkPath& bool intersectsAABB = d.meshPath.getBounds().intersects(eraseAgainst.getBounds()); if(!intersectsAABB) return CanvasComponentEraseDetailResult::NO_CHANGE; - std::optional newPath = Op(d.meshPath, eraseAgainst, SkPathOp::kDifference_SkPathOp); + std::optional newPath = Op(Simplify(d.meshPath).value(), Simplify(eraseAgainst).value(), SkPathOp::kDifference_SkPathOp); if(newPath.has_value()) { - auto oldPath = d.meshPath; - d.meshPath = newPath.value(); - if(d.meshPath.isEmpty()) + if(newPath.value().isEmpty()) { + d.meshPath = newPath.value(); return CanvasComponentEraseDetailResult::REMOVED; - return CanvasComponentEraseDetailResult::CHANGED; + } + else if(!d.meshPath.getBounds().contains(newPath.value().getBounds())) // If bounds of erased path is larger than bounds of original path (can happen when difference op bugs out with big eraser paths), dont change the path + return CanvasComponentEraseDetailResult::NO_CHANGE; + else { + d.meshPath = newPath.value(); + return CanvasComponentEraseDetailResult::CHANGED; + } } return CanvasComponentEraseDetailResult::NO_CHANGE; } diff --git a/src/DrawingProgram/Tools/EraserTool.cpp b/src/DrawingProgram/Tools/EraserTool.cpp index bf5864d..7488b67 100644 --- a/src/DrawingProgram/Tools/EraserTool.cpp +++ b/src/DrawingProgram/Tools/EraserTool.cpp @@ -89,17 +89,18 @@ void EraserTool::input_mouse_button_on_canvas_callback(const InputManager::Mouse BrushComponentCode::mouse_button(drawP, genData, drawP.world.drawData.cam.c, button, relativeWidthResult.first.value()); // NOTE: Must set erase path when isErasing is set to true to make sure that the Circle path from not erasing part doesn't reach the erase_on_path code erasePath = BrushComponentCode::brush_stroke_to_skpath(genData.brushPoints, drawP.world.main.toolConfig.brush.hasRoundCaps); - isErasing = true; + eraserChanged = isErasing = true; } else if(!button.down && isErasing) { // If not real time eraser, we can benefit from simplifying the path std::optional simplified = Simplify(erasePath); if(simplified.has_value()) erasePath = simplified.value(); - erase_on_path(); + if(eraserChanged) + erase_on_path(); reset_erasing_stroke(); commit_erase(); - isErasing = false; + eraserChanged = isErasing = false; } } } @@ -108,6 +109,7 @@ void EraserTool::input_mouse_motion_callback(const InputManager::MouseMotionCall if(isErasing) { auto& toolConfig = drawP.world.main.toolConfig; BrushComponentCode::mouse_motion(drawP, genData, motion.pos, toolConfig.get_relative_width_stroke_size(drawP, genData.coords.inverseScale).first.value()); + eraserChanged = true; } } @@ -118,6 +120,7 @@ void EraserTool::input_pen_axis_callback(const InputManager::PenAxisCallbackArgs auto& toolConfig = drawP.world.main.toolConfig; float width = toolConfig.get_relative_width_stroke_size(drawP, genData.coords.inverseScale).first.value(); BrushComponentCode::pen_pressure(drawP, genData, width); + eraserChanged = true; } } } @@ -281,7 +284,10 @@ void EraserTool::commit_data() { if(isErasing) { erasePath = BrushComponentCode::brush_stroke_to_skpath(genData.brushPoints, drawP.world.main.toolConfig.brush.hasRoundCaps); if(drawP.world.main.conf.realTimeEraser) { - erase_on_path(); + if(eraserChanged) { + erase_on_path(); + eraserChanged = false; + } reset_erasing_stroke(); } } diff --git a/src/DrawingProgram/Tools/EraserTool.hpp b/src/DrawingProgram/Tools/EraserTool.hpp index 1c14416..bec4a4d 100644 --- a/src/DrawingProgram/Tools/EraserTool.hpp +++ b/src/DrawingProgram/Tools/EraserTool.hpp @@ -56,4 +56,5 @@ class EraserTool : public DrawingProgramToolBase { void commit_erase(); void commit_data(); bool isErasing = false; + bool eraserChanged = false; };