diff --git a/Marlin/src/feature/bedlevel/bedlevel.cpp b/Marlin/src/feature/bedlevel/bedlevel.cpp index 1ce89d1e0..e6bc47a62 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.cpp +++ b/Marlin/src/feature/bedlevel/bedlevel.cpp @@ -100,6 +100,10 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) { } } +TemporaryBedLevelingState::TemporaryBedLevelingState(const bool enable) : saved(planner.leveling_active) { + set_bed_leveling_enabled(enable); +} + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) void set_z_fade_height(const float zfh, const bool do_report/*=true*/) { diff --git a/Marlin/src/feature/bedlevel/bedlevel.h b/Marlin/src/feature/bedlevel/bedlevel.h index 82957c488..e5f0db47f 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.h +++ b/Marlin/src/feature/bedlevel/bedlevel.h @@ -46,6 +46,18 @@ void reset_bed_level(); void _manual_goto_xy(const float &x, const float &y); #endif +/** + * A class to save and change the bed leveling state, + * then restore it when it goes out of scope. + */ +class TemporaryBedLevelingState { + bool saved; + public: + TemporaryBedLevelingState(const bool enable); + ~TemporaryBedLevelingState() { set_bed_leveling_enabled(saved); } +}; +#define TEMPORARY_BED_LEVELING_STATE(enable) TemporaryBedLevelingState tbls(enable) + #if HAS_MESH typedef float (&bed_mesh_t)[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 74009c9f3..fddf42d7b 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -436,7 +436,7 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u // Park the nozzle by moving up by z_lift and then moving to (x_pos, y_pos) if (!axis_unhomed_error()) - Nozzle::park(2, park_point); + nozzle.park(2, park_point); #if ENABLED(DUAL_X_CARRIAGE) const int8_t saved_ext = active_extruder; diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.cpp b/Marlin/src/feature/prusa_MMU2/mmu2.cpp index 8453afc60..3450e98b3 100644 --- a/Marlin/src/feature/prusa_MMU2/mmu2.cpp +++ b/Marlin/src/feature/prusa_MMU2/mmu2.cpp @@ -573,7 +573,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { COPY(resume_position, current_position); if (move_axes && all_axes_homed()) - Nozzle::park(2, park_point /*= NOZZLE_PARK_POINT*/); + nozzle.park(2, park_point /*= NOZZLE_PARK_POINT*/); if (turn_off_nozzle) thermalManager.setTargetHotend(0, active_extruder); diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp index c3356f078..996b1515b 100644 --- a/Marlin/src/gcode/calibrate/G425.cpp +++ b/Marlin/src/gcode/calibrate/G425.cpp @@ -74,7 +74,6 @@ struct measurements_t { float nozzle_outer_dimension[2] = {CALIBRATION_NOZZLE_OUTER_DIAMETER, CALIBRATION_NOZZLE_OUTER_DIAMETER}; }; -#define TEMPORARY_BED_LEVELING_STATE(enable) TemporaryBedLevelingState tbls(enable) #define TEMPORARY_SOFT_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable); #if ENABLED(BACKLASH_GCODE) @@ -89,20 +88,6 @@ struct measurements_t { #define TEMPORARY_BACKLASH_SMOOTHING(value) #endif -/** - * A class to save and change the bed leveling state, - * then restore it when it goes out of scope. - */ -class TemporaryBedLevelingState { - bool saved; - - public: - TemporaryBedLevelingState(const bool enable) : saved(planner.leveling_active) { - set_bed_leveling_enabled(enable); - } - ~TemporaryBedLevelingState() { set_bed_leveling_enabled(saved); } -}; - /** * Move to a particular location. Up to three individual axes * and their destinations can be specified, in any order. diff --git a/Marlin/src/gcode/feature/clean/G12.cpp b/Marlin/src/gcode/feature/clean/G12.cpp index c831f1fbf..30c71264e 100644 --- a/Marlin/src/gcode/feature/clean/G12.cpp +++ b/Marlin/src/gcode/feature/clean/G12.cpp @@ -42,32 +42,25 @@ void GcodeSuite::G12() { // Don't allow nozzle cleaning without homing first if (axis_unhomed_error()) return; - const bool seenxyz = parser.seen("XYZ"), - clean_x = !seenxyz || parser.boolval('X'), - clean_y = !seenxyz || parser.boolval('Y'); - - #if ENABLED(NOZZLE_CLEAN_NO_Z) - static constexpr bool clean_z = false; - #else - const bool clean_z = !seenxyz || parser.boolval('Z'); - #endif - const uint8_t pattern = parser.ushortval('P', 0), strokes = parser.ushortval('S', NOZZLE_CLEAN_STROKES), objects = parser.ushortval('T', NOZZLE_CLEAN_TRIANGLES); const float radius = parser.floatval('R', NOZZLE_CLEAN_CIRCLE_RADIUS); + const bool seenxyz = parser.seen("XYZ"); + const uint8_t cleans = (!seenxyz || parser.boolval('X') ? _BV(X_AXIS) : 0) + | (!seenxyz || parser.boolval('Y') ? _BV(Y_AXIS) : 0) + #if DISABLED(NOZZLE_CLEAN_NO_Z) + | (!seenxyz || parser.boolval('Z') ? _BV(Z_AXIS) : 0) + #endif + ; + #if HAS_LEVELING - const bool was_enabled = planner.leveling_active; - if (clean_z) set_bed_leveling_enabled(false); + // Disable bed leveling if cleaning Z + TEMPORARY_BED_LEVELING_STATE(!TEST(cleans, Z_AXIS) && planner.leveling_active); #endif - Nozzle::clean(pattern, strokes, radius, objects, clean_x, clean_y, clean_z); - - // Re-enable bed level correction if it had been on - #if HAS_LEVELING - if (clean_z) set_bed_leveling_enabled(was_enabled); - #endif + nozzle.clean(pattern, strokes, radius, objects, cleans); } #endif // NOZZLE_CLEAN_FEATURE diff --git a/Marlin/src/gcode/feature/pause/G27.cpp b/Marlin/src/gcode/feature/pause/G27.cpp index 3b49ae283..4f4c9e469 100644 --- a/Marlin/src/gcode/feature/pause/G27.cpp +++ b/Marlin/src/gcode/feature/pause/G27.cpp @@ -35,7 +35,7 @@ void GcodeSuite::G27() { // Don't allow nozzle parking without homing first if (axis_unhomed_error()) return; - Nozzle::park(parser.ushortval('P')); + nozzle.park(parser.ushortval('P')); } #endif // NOZZLE_PARK_FEATURE diff --git a/Marlin/src/libs/nozzle.cpp b/Marlin/src/libs/nozzle.cpp index 27c214b87..3926bfc93 100644 --- a/Marlin/src/libs/nozzle.cpp +++ b/Marlin/src/libs/nozzle.cpp @@ -26,6 +26,8 @@ #include "nozzle.h" +Nozzle nozzle; + #include "../Marlin.h" #include "../module/motion.h" #include "point_t.h" @@ -155,24 +157,34 @@ * @param pattern one of the available patterns * @param argument depends on the cleaning pattern */ - void Nozzle::clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects, const bool clean_x, const bool clean_y, const bool clean_z) { + void Nozzle::clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects, const uint8_t cleans) { point_t start = NOZZLE_CLEAN_START_POINT; point_t end = NOZZLE_CLEAN_END_POINT; - if (!clean_x) start.x = end.x = current_position[X_AXIS]; - if (!clean_y) start.y = end.y = current_position[Y_AXIS]; - if (!clean_z) start.z = end.z = current_position[Z_AXIS]; + + if (pattern == 2) { + if (!(cleans & (_BV(X_AXIS) | _BV(Y_AXIS)))) { + SERIAL_ECHOLNPGM("Warning : Clean Circle requires XY"); + return; + } + end = NOZZLE_CLEAN_CIRCLE_MIDDLE; + } + else { + if (!TEST(cleans, X_AXIS)) start.x = end.x = current_position[X_AXIS]; + if (!TEST(cleans, Y_AXIS)) start.y = end.y = current_position[Y_AXIS]; + } + if (!TEST(cleans, Z_AXIS)) start.z = end.z = current_position[Z_AXIS]; switch (pattern) { case 1: - zigzag(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes, objects); + zigzag(start, end, strokes, objects); break; case 2: - circle(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius); + circle(start, end, strokes, radius); break; default: - stroke(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes); + stroke(start, end, strokes); } } diff --git a/Marlin/src/libs/nozzle.h b/Marlin/src/libs/nozzle.h index dc8513f28..d20b41de9 100644 --- a/Marlin/src/libs/nozzle.h +++ b/Marlin/src/libs/nozzle.h @@ -78,7 +78,7 @@ class Nozzle { * @param pattern one of the available patterns * @param argument depends on the cleaning pattern */ - static void clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects, const bool clean_x, const bool clean_y, const bool clean_z) _Os; + static void clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects, const uint8_t cleans) _Os; #endif // NOZZLE_CLEAN_FEATURE @@ -88,3 +88,5 @@ class Nozzle { #endif }; + +extern Nozzle nozzle; diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 73f371696..7f1f6aab2 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -822,12 +822,6 @@ void tool_change(const uint8_t tmp_extruder, bool no_move/*=false*/) { return invalid_extruder_error(tmp_extruder); #endif - #if HAS_LEVELING - // Set current position to the physical position - const bool leveling_was_active = planner.leveling_active; - set_bed_leveling_enabled(false); - #endif - if (tmp_extruder >= EXTRUDERS) return invalid_extruder_error(tmp_extruder); @@ -875,6 +869,11 @@ void tool_change(const uint8_t tmp_extruder, bool no_move/*=false*/) { } #endif // TOOLCHANGE_FILAMENT_SWAP + #if HAS_LEVELING + // Set current position to the physical position + TEMPORARY_BED_LEVELING_STATE(false); + #endif + if (tmp_extruder != active_extruder) { #if SWITCHING_NOZZLE_TWO_SERVOS @@ -1071,11 +1070,6 @@ void tool_change(const uint8_t tmp_extruder, bool no_move/*=false*/) { fanmux_switch(active_extruder); #endif - #if HAS_LEVELING - // Restore leveling to re-establish the logical position - set_bed_leveling_enabled(leveling_was_active); - #endif - SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(MSG_ACTIVE_EXTRUDER, int(active_extruder));