From 86170e6a66b115ab6fa4def988e8154f729c0900 Mon Sep 17 00:00:00 2001
From: Robert Mendon <gibben@gmail.com>
Date: Mon, 11 Jun 2018 20:51:48 -0600
Subject: [PATCH] [2.0.x] Add O (optional) flag to G28/G29 (#10913)

---
 Marlin/src/gcode/bedlevel/abl/G29.cpp | 11 +++++++++++
 Marlin/src/gcode/calibrate/G28.cpp    | 12 ++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp
index 552c5d36ef..ff46574bd5 100644
--- a/Marlin/src/gcode/bedlevel/abl/G29.cpp
+++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp
@@ -68,6 +68,8 @@
  *
  * Enhanced G29 Auto Bed Leveling Probe Routine
  *
+ *  O  Auto-level only if needed
+ *
  *  D  Dry-Run mode. Just evaluate the bed Topology - Don't apply
  *     or alter the bed level data. Useful to check the topology
  *     after a first run of G29.
@@ -174,6 +176,15 @@ void GcodeSuite::G29() {
   // Don't allow auto-leveling without homing first
   if (axis_unhomed_error()) return;
 
+  if (!no_action && planner.leveling_active && parser.boolval('O')) { // Auto-level only if needed
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
+      if (DEBUGGING(LEVELING)) {
+        SERIAL_ECHOLNPGM("> Auto-level not needed, skip");
+        SERIAL_ECHOLNPGM("<<< G29");
+      }
+    #endif
+    return;
+  }
   // Define local vars 'static' for manual probing, 'auto' otherwise
   #if ENABLED(PROBE_MANUALLY)
     #define ABL_VAR static
diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp
index c80d106d76..4535621688 100644
--- a/Marlin/src/gcode/calibrate/G28.cpp
+++ b/Marlin/src/gcode/calibrate/G28.cpp
@@ -152,6 +152,8 @@
  *  None  Home to all axes with no parameters.
  *        With QUICK_HOME enabled XY will home together, then Z.
  *
+ *  O   Home only if position is unknown
+ *
  *  Rn  Raise by n mm/inches before homing
  *
  * Cartesian/SCARA parameters
@@ -170,6 +172,16 @@ void GcodeSuite::G28(const bool always_home_all) {
     }
   #endif
 
+  if ((axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS]) && parser.boolval('O')) { // home only if needed
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
+      if (DEBUGGING(LEVELING)) {
+        SERIAL_ECHOLNPGM("> homing not needed, skip");
+        SERIAL_ECHOLNPGM("<<< G28");
+      }
+    #endif
+    return;
+  }
+  
   // Wait for planner moves to finish!
   planner.synchronize();