From 25152a8cefcdae546b7ab86d3a04e65facbbc495 Mon Sep 17 00:00:00 2001
From: Jason Smith <jason.inet@gmail.com>
Date: Fri, 1 Jan 2021 18:08:10 -0800
Subject: [PATCH] Fix UBL mesh edit delta moves (#20620)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
---
 Marlin/src/feature/fwretract.cpp  |  2 +-
 Marlin/src/lcd/marlinui.cpp       | 16 +++++++---------
 Marlin/src/lcd/marlinui.h         | 15 ++++++++-------
 Marlin/src/lcd/menu/menu_ubl.cpp  | 13 ++++++++-----
 Marlin/src/lcd/tft/ui_480x320.cpp |  9 ++++-----
 5 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/Marlin/src/feature/fwretract.cpp b/Marlin/src/feature/fwretract.cpp
index e5c52562a9a..2a71af11d67 100644
--- a/Marlin/src/feature/fwretract.cpp
+++ b/Marlin/src/feature/fwretract.cpp
@@ -139,7 +139,7 @@ void FWRetract::retract(const bool retracting
   if (retracting) {
     // Retract by moving from a faux E position back to the current E position
     current_retract[active_extruder] = base_retract;
-    prepare_internal_move_to_destination(                 // set current to destination
+    prepare_internal_move_to_destination(                 // set current from destination
       settings.retract_feedrate_mm_s * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS))
     );
 
diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp
index fb37643cd2c..3c2f930e68a 100644
--- a/Marlin/src/lcd/marlinui.cpp
+++ b/Marlin/src/lcd/marlinui.cpp
@@ -687,7 +687,7 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
   TERN_(IS_KINEMATIC, float ManualMove::offset = 0);
   TERN_(IS_KINEMATIC, bool ManualMove::processing = false);
   TERN_(MULTI_MANUAL, int8_t ManualMove::e_index = 0);
-  uint8_t ManualMove::axis = (uint8_t)NO_AXIS;
+  AxisEnum ManualMove::axis = NO_AXIS;
 
   /**
    * If a manual move has been posted and its time has arrived, and if the planner
@@ -713,14 +713,14 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
     if (processing) return;   // Prevent re-entry from idle() calls
 
     // Add a manual move to the queue?
-    if (axis != (uint8_t)NO_AXIS && ELAPSED(millis(), start_time) && !planner.is_full()) {
+    if (axis != NO_AXIS && ELAPSED(millis(), start_time) && !planner.is_full()) {
 
-      const feedRate_t fr_mm_s = (uint8_t(axis) <= E_AXIS) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S;
+      const feedRate_t fr_mm_s = (axis <= E_AXIS) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S;
 
       #if IS_KINEMATIC
 
         #if HAS_MULTI_EXTRUDER
-          const int8_t old_extruder = active_extruder;
+          REMEMBER(ae, active_extruder);
           if (axis == E_AXIS) active_extruder = e_index;
         #endif
 
@@ -730,7 +730,7 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
 
         // Reset for the next move
         offset = 0;
-        axis = (uint8_t)NO_AXIS;
+        axis = NO_AXIS;
 
         // DELTA and SCARA machines use segmented moves, which could fill the planner during the call to
         // move_to_destination. This will cause idle() to be called, which can then call this function while the
@@ -740,8 +740,6 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
         prepare_internal_move_to_destination(fr_mm_s);  // will set current_position from destination
         processing = false;
 
-        TERN_(HAS_MULTI_EXTRUDER, active_extruder = old_extruder);
-
       #else
 
         // For Cartesian / Core motion simply move to the current_position
@@ -749,7 +747,7 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
 
         //SERIAL_ECHOLNPAIR("Add planner.move with Axis ", int(axis), " at FR ", fr_mm_s);
 
-        axis = (uint8_t)NO_AXIS;
+        axis = NO_AXIS;
 
       #endif
     }
@@ -767,7 +765,7 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
       if (move_axis == E_AXIS) e_index = eindex >= 0 ? eindex : active_extruder;
     #endif
     start_time = millis() + (menu_scale < 0.99f ? 0UL : 250UL); // delay for bigger moves
-    axis = (uint8_t)move_axis;
+    axis = move_axis;
     //SERIAL_ECHOLNPAIR("Post Move with Axis ", int(axis), " soon.");
   }
 
diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h
index e162dbdd2e2..d7285927a30 100644
--- a/Marlin/src/lcd/marlinui.h
+++ b/Marlin/src/lcd/marlinui.h
@@ -262,8 +262,15 @@
 
   // Manual Movement class
   class ManualMove {
-  public:
+  private:
+    static AxisEnum axis;
+    #if MULTI_MANUAL
+      static int8_t e_index;
+    #else
+      static int8_t constexpr e_index = 0;
+    #endif
     static millis_t start_time;
+  public:
     static float menu_scale;
     TERN_(IS_KINEMATIC, static float offset);
     #if IS_KINEMATIC
@@ -271,12 +278,6 @@
     #else
       static bool constexpr processing = false;
     #endif
-    #if MULTI_MANUAL
-      static int8_t e_index;
-    #else
-      static int8_t constexpr e_index = 0;
-    #endif
-    static uint8_t axis;
     static void task();
     static void soon(AxisEnum axis
       #if MULTI_MANUAL
diff --git a/Marlin/src/lcd/menu/menu_ubl.cpp b/Marlin/src/lcd/menu/menu_ubl.cpp
index eb19e96626c..9b784167179 100644
--- a/Marlin/src/lcd/menu/menu_ubl.cpp
+++ b/Marlin/src/lcd/menu/menu_ubl.cpp
@@ -413,6 +413,10 @@ void _lcd_ubl_map_edit_cmd() {
  * UBL LCD Map Movement
  */
 void ubl_map_move_to_xy() {
+  const xy_pos_t xy = { ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot) };
+
+  // Some printers have unreachable areas in the mesh. Skip the move if unreachable.
+  if (!position_is_reachable(xy)) return;
 
   #if ENABLED(DELTA)
     if (current_position.z > delta_clip_start_height) { // Make sure the delta has fully free motion
@@ -422,11 +426,10 @@ void ubl_map_move_to_xy() {
     }
   #endif
 
-  // Set the nozzle position to the mesh point
-  current_position.set(ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot));
-
-  // Use the built-in manual move handler
-  ui.manual_move.soon(ALL_AXES);
+  // Do an internal move to the mesh point
+  destination.set(ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot));
+  constexpr feedRate_t fr_mm_s = MMM_TO_MMS(XY_PROBE_SPEED);
+  prepare_internal_move_to_destination(fr_mm_s); // Set current_position from destination
 }
 
 inline int32_t grid_index(const uint8_t x, const uint8_t y) {
diff --git a/Marlin/src/lcd/tft/ui_480x320.cpp b/Marlin/src/lcd/tft/ui_480x320.cpp
index f7955fb1bd5..b6ffb4592f6 100644
--- a/Marlin/src/lcd/tft/ui_480x320.cpp
+++ b/Marlin/src/lcd/tft/ui_480x320.cpp
@@ -867,17 +867,16 @@ static void moveAxis(AxisEnum axis, const int8_t direction) {
         NOMORE(ui.manual_move.offset, max - current_position[axis]);
     #else
       current_position[axis] += diff;
+      const char *msg = PSTR(""); // clear the error
       if (direction < 0 && current_position[axis] < min) {
         current_position[axis] = min;
-        drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS));
+        msg = GET_TEXT(MSG_LCD_SOFT_ENDSTOPS);
       }
       else if (direction > 0 && current_position[axis] > max) {
         current_position[axis] = max;
-        drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS));
-      }
-      else {
-        drawMessage(""); // clear the error
+        msg = GET_TEXT(MSG_LCD_SOFT_ENDSTOPS);
       }
+      drawMessage(msg);
     #endif
 
     ui.manual_move.soon(axis