Browse Source

Merge pull request #6827 from thinkyhead/bf_day_ending_in_y

Make UBL a complete singleton
Scott Lahteine 8 years ago
parent
commit
62d8e35adc

+ 137
- 160
Marlin/G26_Mesh_Validation_Tool.cpp View File

@@ -135,64 +135,78 @@
135 135
   float code_value_axis_units(const AxisEnum axis);
136 136
   bool code_value_bool();
137 137
   bool code_has_value();
138
-  void lcd_init();
139
-  void lcd_setstatuspgm(const char* const message, const uint8_t level);
140 138
   void sync_plan_position_e();
141 139
   void chirp_at_user();
142 140
 
143 141
   // Private functions
144 142
 
145
-  void un_retract_filament(float where[XYZE]);
146
-  void retract_filament(float where[XYZE]);
147
-  bool look_for_lines_to_connect();
148
-  bool parse_G26_parameters();
149
-  void move_to(const float&, const float&, const float&, const float&) ;
150
-  void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&);
151
-  bool turn_on_heaters();
152
-  bool prime_nozzle();
153
-
154 143
   static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
155 144
   float g26_e_axis_feedrate = 0.020,
156
-        random_deviation = 0.0,
157
-        layer_height = LAYER_HEIGHT;
145
+        random_deviation = 0.0;
158 146
 
159 147
   static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
160 148
                                      // retracts/recovers won't result in a bad state.
161 149
 
162 150
   float valid_trig_angle(float);
163
-  mesh_index_pair find_closest_circle_to_print(const float&, const float&);
164 151
 
165
-  static float extrusion_multiplier = EXTRUSION_MULTIPLIER,
166
-               retraction_multiplier = RETRACTION_MULTIPLIER,
167
-               nozzle = NOZZLE,
168
-               filament_diameter = FILAMENT,
169
-               prime_length = PRIME_LENGTH,
170
-               x_pos, y_pos,
171
-               ooze_amount = OOZE_AMOUNT;
152
+  float unified_bed_leveling::g26_extrusion_multiplier,
153
+        unified_bed_leveling::g26_retraction_multiplier,
154
+        unified_bed_leveling::g26_nozzle,
155
+        unified_bed_leveling::g26_filament_diameter,
156
+        unified_bed_leveling::g26_layer_height,
157
+        unified_bed_leveling::g26_prime_length,
158
+        unified_bed_leveling::g26_x_pos,
159
+        unified_bed_leveling::g26_y_pos,
160
+        unified_bed_leveling::g26_ooze_amount;
172 161
 
173
-  static int16_t bed_temp = BED_TEMP,
174
-                 hotend_temp = HOTEND_TEMP;
162
+  int16_t unified_bed_leveling::g26_bed_temp,
163
+          unified_bed_leveling::g26_hotend_temp;
175 164
 
176
-  static int8_t prime_flag = 0;
165
+  int8_t unified_bed_leveling::g26_prime_flag;
177 166
 
178
-  static bool continue_with_closest, keep_heaters_on;
167
+  bool unified_bed_leveling::g26_continue_with_closest,
168
+       unified_bed_leveling::g26_keep_heaters_on;
179 169
 
180
-  static int16_t g26_repeats;
170
+  int16_t unified_bed_leveling::g26_repeats;
181 171
 
182
-  void G26_line_to_destination(const float &feed_rate) {
172
+  void unified_bed_leveling::G26_line_to_destination(const float &feed_rate) {
183 173
     const float save_feedrate = feedrate_mm_s;
184 174
     feedrate_mm_s = feed_rate;      // use specified feed rate
185
-    prepare_move_to_destination();  // will ultimately call ubl_line_to_destination_cartesian or ubl_prepare_linear_move_to for UBL_DELTA
175
+    prepare_move_to_destination();  // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_DELTA
186 176
     feedrate_mm_s = save_feedrate;  // restore global feed rate
187 177
   }
188 178
 
189 179
   /**
180
+   * Detect ubl_lcd_clicked, debounce it, and return true for cancel
181
+   */
182
+  bool user_canceled() {
183
+    if (!ubl_lcd_clicked()) return false;
184
+    safe_delay(10);                       // Wait for click to settle
185
+
186
+    #if ENABLED(ULTRA_LCD)
187
+      lcd_setstatuspgm(PSTR("Mesh Validation Stopped."), 99);
188
+      lcd_quick_feedback();
189
+    #endif
190
+    lcd_reset_alert_level();
191
+
192
+    while (!ubl_lcd_clicked()) idle();    // Wait for button release
193
+
194
+    // If the button is suddenly pressed again,
195
+    // ask the user to resolve the issue
196
+    lcd_setstatuspgm(PSTR("Release button"), 99); // will never appear...
197
+    while (ubl_lcd_clicked()) idle();             // unless this loop happens
198
+    lcd_setstatuspgm(PSTR(""));
199
+
200
+    return true;
201
+  }
202
+
203
+  /**
190 204
    * G26: Mesh Validation Pattern generation.
191 205
    *
192 206
    * Used to interactively edit UBL's Mesh by placing the
193 207
    * nozzle in a problem area and doing a G29 P4 R command.
194 208
    */
195
-  void gcode_G26() {
209
+  void unified_bed_leveling::G26() {
196 210
     SERIAL_ECHOLNPGM("G26 command started.  Waiting for heater(s).");
197 211
     float tmp, start_angle, end_angle;
198 212
     int   i, xi, yi;
@@ -213,7 +227,7 @@
213 227
     current_position[E_AXIS] = 0.0;
214 228
     sync_plan_position_e();
215 229
 
216
-    if (prime_flag && prime_nozzle()) goto LEAVE;
230
+    if (g26_prime_flag && prime_nozzle()) goto LEAVE;
217 231
 
218 232
     /**
219 233
      *  Bed is preheated
@@ -231,11 +245,11 @@
231 245
 
232 246
     // Move nozzle to the specified height for the first layer
233 247
     set_destination_to_current();
234
-    destination[Z_AXIS] = layer_height;
248
+    destination[Z_AXIS] = g26_layer_height;
235 249
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
236
-    move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], ooze_amount);
250
+    move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], g26_ooze_amount);
237 251
 
238
-    ubl.has_control_of_lcd_panel = true;
252
+    has_control_of_lcd_panel = true;
239 253
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
240 254
 
241 255
     /**
@@ -249,13 +263,13 @@
249 263
     }
250 264
 
251 265
     do {
252
-      location = continue_with_closest
266
+      location = g26_continue_with_closest
253 267
         ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
254
-        : find_closest_circle_to_print(x_pos, y_pos); // Find the closest Mesh Intersection to where we are now.
268
+        : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now.
255 269
 
256 270
       if (location.x_index >= 0 && location.y_index >= 0) {
257
-        const float circle_x = pgm_read_float(&ubl.mesh_index_to_xpos[location.x_index]),
258
-                    circle_y = pgm_read_float(&ubl.mesh_index_to_ypos[location.y_index]);
271
+        const float circle_x = mesh_index_to_xpos(location.x_index),
272
+                    circle_y = mesh_index_to_ypos(location.y_index);
259 273
 
260 274
         // If this mesh location is outside the printable_radius, skip it.
261 275
 
@@ -264,7 +278,7 @@
264 278
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
265 279
         yi = location.y_index;
266 280
 
267
-        if (ubl.g26_debug_flag) {
281
+        if (g26_debug_flag) {
268 282
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
269 283
           SERIAL_ECHOPAIR(", yi=", yi);
270 284
           SERIAL_CHAR(')');
@@ -300,25 +314,7 @@
300 314
 
301 315
         for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) {
302 316
 
303
-          // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is
304
-          // a Press and Hold is repeated in a lot of places (including ubl_G29.cpp).   This
305
-          // should be redone and compressed.
306
-          if (ubl_lcd_clicked()) {              // Check if the user wants to stop the Mesh Validation
307
-            #if ENABLED(ULTRA_LCD)
308
-              lcd_setstatuspgm(PSTR("Mesh Validation Stopped."), 99);
309
-              lcd_quick_feedback();
310
-            #endif
311
-            while (!ubl_lcd_clicked()) {         // Wait until the user is done pressing the
312
-              idle();                            // Encoder Wheel if that is why we are leaving
313
-              lcd_reset_alert_level();
314
-              lcd_setstatuspgm(PSTR(""));
315
-            }
316
-            while (ubl_lcd_clicked()) {          // Wait until the user is done pressing the
317
-              idle();                            // Encoder Wheel if that is why we are leaving
318
-              lcd_setstatuspgm(PSTR("Unpress Wheel"), 99);
319
-            }
320
-            goto LEAVE;
321
-          }
317
+          if (user_canceled()) goto LEAVE;              // Check if the user wants to stop the Mesh Validation
322 318
 
323 319
           int tmp_div_30 = tmp / 30.0;
324 320
           if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
@@ -338,7 +334,7 @@
338 334
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
339 335
           #endif
340 336
 
341
-          //if (ubl.g26_debug_flag) {
337
+          //if (g26_debug_flag) {
342 338
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
343 339
           //  strcpy(seg_msg, "   segment: ");
344 340
           //  strcpy(seg_num, "    \n");
@@ -349,7 +345,7 @@
349 345
           //  debug_current_and_destination(seg_msg);
350 346
           //}
351 347
 
352
-          print_line_from_here_to_there(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), layer_height, LOGICAL_X_POSITION(xe), LOGICAL_Y_POSITION(ye), layer_height);
348
+          print_line_from_here_to_there(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), g26_layer_height, LOGICAL_X_POSITION(xe), LOGICAL_Y_POSITION(ye), g26_layer_height);
353 349
 
354 350
         }
355 351
         if (look_for_lines_to_connect())
@@ -368,16 +364,16 @@
368 364
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Raise the nozzle
369 365
     //debug_current_and_destination(PSTR("done doing Z-Raise."));
370 366
 
371
-    destination[X_AXIS] = x_pos;                                               // Move back to the starting position
372
-    destination[Y_AXIS] = y_pos;
367
+    destination[X_AXIS] = g26_x_pos;                                               // Move back to the starting position
368
+    destination[Y_AXIS] = g26_y_pos;
373 369
     //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;                        // Keep the nozzle where it is
374 370
 
375 371
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
376 372
     //debug_current_and_destination(PSTR("done doing X/Y move."));
377 373
 
378
-    ubl.has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
374
+    has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
379 375
 
380
-    if (!keep_heaters_on) {
376
+    if (!g26_keep_heaters_on) {
381 377
       #if HAS_TEMP_BED
382 378
         thermalManager.setTargetBed(0);
383 379
       #endif
@@ -385,14 +381,13 @@
385 381
     }
386 382
   }
387 383
 
388
-
389 384
   float valid_trig_angle(float d) {
390 385
     while (d > 360.0) d -= 360.0;
391 386
     while (d < 0.0) d += 360.0;
392 387
     return d;
393 388
   }
394 389
 
395
-  mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
390
+  mesh_index_pair unified_bed_leveling::find_closest_circle_to_print(const float &X, const float &Y) {
396 391
     float closest = 99999.99;
397 392
     mesh_index_pair return_val;
398 393
 
@@ -401,8 +396,8 @@
401 396
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
402 397
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
403 398
         if (!is_bit_set(circle_flags, i, j)) {
404
-          const float mx = pgm_read_float(&ubl.mesh_index_to_xpos[i]),  // We found a circle that needs to be printed
405
-                      my = pgm_read_float(&ubl.mesh_index_to_ypos[j]);
399
+          const float mx = mesh_index_to_xpos(i),  // We found a circle that needs to be printed
400
+                      my = mesh_index_to_ypos(j);
406 401
 
407 402
           // Get the distance to this intersection
408 403
           float f = HYPOT(X - mx, Y - my);
@@ -411,7 +406,7 @@
411 406
           // to let us find the closest circle to the start position.
412 407
           // But if this is not the case, add a small weighting to the
413 408
           // distance calculation to help it choose a better place to continue.
414
-          f += HYPOT(x_pos - mx, y_pos - my) / 15.0;
409
+          f += HYPOT(g26_x_pos - mx, g26_y_pos - my) / 15.0;
415 410
 
416 411
           // Add in the specified amount of Random Noise to our search
417 412
           if (random_deviation > 1.0)
@@ -430,34 +425,16 @@
430 425
     return return_val;
431 426
   }
432 427
 
433
-  bool look_for_lines_to_connect() {
428
+  bool unified_bed_leveling::look_for_lines_to_connect() {
434 429
     float sx, sy, ex, ey;
435 430
 
436 431
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
437 432
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
438 433
 
439
-        // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is
440
-        // a Press and Hold is repeated in a lot of places (including ubl_G29.cpp).   This
441
-        // should be redone and compressed.
442
-        if (ubl_lcd_clicked()) {              // Check if the user wants to stop the Mesh Validation
443
-          #if ENABLED(ULTRA_LCD)
444
-            lcd_setstatuspgm(PSTR("Mesh Validation Stopped."), 99);
445
-            lcd_quick_feedback();
446
-          #endif
447
-          while (!ubl_lcd_clicked()) {         // Wait until the user is done pressing the
448
-            idle();                            // Encoder Wheel if that is why we are leaving
449
-            lcd_reset_alert_level();
450
-            lcd_setstatuspgm(PSTR(""));
451
-          }
452
-          while (ubl_lcd_clicked()) {          // Wait until the user is done pressing the
453
-            idle();                            // Encoder Wheel if that is why we are leaving
454
-            lcd_setstatuspgm(PSTR("Unpress Wheel"), 99);
455
-          }
456
-          return true;
457
-        }
434
+        if (user_canceled()) return true;     // Check if the user wants to stop the Mesh Validation
458 435
 
459 436
         if (i < GRID_MAX_POINTS_X) { // We can't connect to anything to the right than GRID_MAX_POINTS_X.
460
-                                         // This is already a half circle because we are at the edge of the bed.
437
+                                     // This is already a half circle because we are at the edge of the bed.
461 438
 
462 439
           if (is_bit_set(circle_flags, i, j) && is_bit_set(circle_flags, i + 1, j)) { // check if we can do a line to the left
463 440
             if (!is_bit_set(horizontal_mesh_line_flags, i, j)) {
@@ -466,16 +443,16 @@
466 443
               // We found two circles that need a horizontal line to connect them
467 444
               // Print it!
468 445
               //
469
-              sx = pgm_read_float(&ubl.mesh_index_to_xpos[  i  ]) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
470
-              ex = pgm_read_float(&ubl.mesh_index_to_xpos[i + 1]) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge
446
+              sx = mesh_index_to_xpos(  i  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
447
+              ex = mesh_index_to_xpos(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge
471 448
 
472 449
               sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
473
-              sy = ey = constrain(pgm_read_float(&ubl.mesh_index_to_ypos[j]), Y_MIN_POS + 1, Y_MAX_POS - 1);
450
+              sy = ey = constrain(mesh_index_to_ypos(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
474 451
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
475 452
 
476 453
               if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
477 454
 
478
-                if (ubl.g26_debug_flag) {
455
+                if (g26_debug_flag) {
479 456
                   SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
480 457
                   SERIAL_ECHOPAIR(", sy=", sy);
481 458
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
@@ -485,7 +462,7 @@
485 462
                   //debug_current_and_destination(PSTR("Connecting horizontal line."));
486 463
                 }
487 464
 
488
-                print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), layer_height);
465
+                print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height);
489 466
               }
490 467
               bit_set(horizontal_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if we skipped it
491 468
             }
@@ -500,16 +477,16 @@
500 477
                 // We found two circles that need a vertical line to connect them
501 478
                 // Print it!
502 479
                 //
503
-                sy = pgm_read_float(&ubl.mesh_index_to_ypos[  j  ]) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
504
-                ey = pgm_read_float(&ubl.mesh_index_to_ypos[j + 1]) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge
480
+                sy = mesh_index_to_ypos(  j  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
481
+                ey = mesh_index_to_ypos(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge
505 482
 
506
-                sx = ex = constrain(pgm_read_float(&ubl.mesh_index_to_xpos[i]), X_MIN_POS + 1, X_MAX_POS - 1);
483
+                sx = ex = constrain(mesh_index_to_xpos(i), X_MIN_POS + 1, X_MAX_POS - 1);
507 484
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
508 485
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
509 486
 
510 487
                 if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
511 488
 
512
-                  if (ubl.g26_debug_flag) {
489
+                  if (g26_debug_flag) {
513 490
                     SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
514 491
                     SERIAL_ECHOPAIR(", sy=", sy);
515 492
                     SERIAL_ECHOPAIR(") -> (ex=", ex);
@@ -518,7 +495,7 @@
518 495
                     SERIAL_EOL;
519 496
                     debug_current_and_destination(PSTR("Connecting vertical line."));
520 497
                   }
521
-                  print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), layer_height);
498
+                  print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height);
522 499
                 }
523 500
                 bit_set(vertical_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if skipped
524 501
               }
@@ -530,7 +507,7 @@
530 507
     return false;
531 508
   }
532 509
 
533
-  void move_to(const float &x, const float &y, const float &z, const float &e_delta) {
510
+  void unified_bed_leveling::move_to(const float &x, const float &y, const float &z, const float &e_delta) {
534 511
     float feed_value;
535 512
     static float last_z = -999.99;
536 513
 
@@ -552,10 +529,10 @@
552 529
     }
553 530
 
554 531
     // Check if X or Y is involved in the movement.
555
-    // Yes: a 'normal' movement. No: a retract() or un_retract()
532
+    // Yes: a 'normal' movement. No: a retract() or recover()
556 533
     feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
557 534
 
558
-    if (ubl.g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
535
+    if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
559 536
 
560 537
     destination[X_AXIS] = x;
561 538
     destination[Y_AXIS] = y;
@@ -568,16 +545,16 @@
568 545
 
569 546
   }
570 547
 
571
-  void retract_filament(float where[XYZE]) {
548
+  void unified_bed_leveling::retract_filament(float where[XYZE]) {
572 549
     if (!g26_retracted) { // Only retract if we are not already retracted!
573 550
       g26_retracted = true;
574
-      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], -1.0 * retraction_multiplier);
551
+      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], -1.0 * g26_retraction_multiplier);
575 552
     }
576 553
   }
577 554
 
578
-  void un_retract_filament(float where[XYZE]) {
555
+  void unified_bed_leveling::recover_filament(float where[XYZE]) {
579 556
     if (g26_retracted) { // Only un-retract if we are retracted.
580
-      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], 1.2 * retraction_multiplier);
557
+      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], 1.2 * g26_retraction_multiplier);
581 558
       g26_retracted = false;
582 559
     }
583 560
   }
@@ -597,7 +574,7 @@
597 574
    * segment of a 'circle'.   The time this requires is very short and is easily saved by the other
598 575
    * cases where the optimization comes into play.
599 576
    */
600
-  void print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) {
577
+  void unified_bed_leveling::print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) {
601 578
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
602 579
                 dy_s = current_position[Y_AXIS] - sy,
603 580
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
@@ -625,9 +602,9 @@
625 602
 
626 603
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump
627 604
 
628
-    const float e_pos_delta = line_length * g26_e_axis_feedrate * extrusion_multiplier;
605
+    const float e_pos_delta = line_length * g26_e_axis_feedrate * g26_extrusion_multiplier;
629 606
 
630
-    un_retract_filament(destination);
607
+    recover_filament(destination);
631 608
     move_to(ex, ey, ez, e_pos_delta);  // Get to the ending point with an appropriate amount of extrusion
632 609
   }
633 610
 
@@ -636,33 +613,33 @@
636 613
    * parameters it made sense to turn them into static globals and get
637 614
    * this code out of sight of the main routine.
638 615
    */
639
-  bool parse_G26_parameters() {
640
-
641
-    extrusion_multiplier  = EXTRUSION_MULTIPLIER;
642
-    retraction_multiplier = RETRACTION_MULTIPLIER;
643
-    nozzle                = NOZZLE;
644
-    filament_diameter     = FILAMENT;
645
-    layer_height          = LAYER_HEIGHT;
646
-    prime_length          = PRIME_LENGTH;
647
-    bed_temp              = BED_TEMP;
648
-    hotend_temp           = HOTEND_TEMP;
649
-    prime_flag            = 0;
650
-
651
-    ooze_amount           = code_seen('O') && code_has_value() ? code_value_linear_units() : OOZE_AMOUNT;
652
-    keep_heaters_on       = code_seen('K') && code_value_bool();
653
-    continue_with_closest = code_seen('C') && code_value_bool();
616
+  bool unified_bed_leveling::parse_G26_parameters() {
617
+
618
+    g26_extrusion_multiplier  = EXTRUSION_MULTIPLIER;
619
+    g26_retraction_multiplier = RETRACTION_MULTIPLIER;
620
+    g26_nozzle                = NOZZLE;
621
+    g26_filament_diameter     = FILAMENT;
622
+    g26_layer_height          = LAYER_HEIGHT;
623
+    g26_prime_length          = PRIME_LENGTH;
624
+    g26_bed_temp              = BED_TEMP;
625
+    g26_hotend_temp           = HOTEND_TEMP;
626
+    g26_prime_flag            = 0;
627
+
628
+    g26_ooze_amount           = code_seen('O') && code_has_value() ? code_value_linear_units() : OOZE_AMOUNT;
629
+    g26_keep_heaters_on       = code_seen('K') && code_value_bool();
630
+    g26_continue_with_closest = code_seen('C') && code_value_bool();
654 631
 
655 632
     if (code_seen('B')) {
656
-      bed_temp = code_value_temp_abs();
657
-      if (!WITHIN(bed_temp, 15, 140)) {
633
+      g26_bed_temp = code_value_temp_abs();
634
+      if (!WITHIN(g26_bed_temp, 15, 140)) {
658 635
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
659 636
         return UBL_ERR;
660 637
       }
661 638
     }
662 639
 
663 640
     if (code_seen('L')) {
664
-      layer_height = code_value_linear_units();
665
-      if (!WITHIN(layer_height, 0.0, 2.0)) {
641
+      g26_layer_height = code_value_linear_units();
642
+      if (!WITHIN(g26_layer_height, 0.0, 2.0)) {
666 643
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
667 644
         return UBL_ERR;
668 645
       }
@@ -670,8 +647,8 @@
670 647
 
671 648
     if (code_seen('Q')) {
672 649
       if (code_has_value()) {
673
-        retraction_multiplier = code_value_float();
674
-        if (!WITHIN(retraction_multiplier, 0.05, 15.0)) {
650
+        g26_retraction_multiplier = code_value_float();
651
+        if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) {
675 652
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
676 653
           return UBL_ERR;
677 654
         }
@@ -683,8 +660,8 @@
683 660
     }
684 661
 
685 662
     if (code_seen('S')) {
686
-      nozzle = code_value_float();
687
-      if (!WITHIN(nozzle, 0.1, 1.0)) {
663
+      g26_nozzle = code_value_float();
664
+      if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
688 665
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
689 666
         return UBL_ERR;
690 667
       }
@@ -692,11 +669,11 @@
692 669
 
693 670
     if (code_seen('P')) {
694 671
       if (!code_has_value())
695
-        prime_flag = -1;
672
+        g26_prime_flag = -1;
696 673
       else {
697
-        prime_flag++;
698
-        prime_length = code_value_linear_units();
699
-        if (!WITHIN(prime_length, 0.0, 25.0)) {
674
+        g26_prime_flag++;
675
+        g26_prime_length = code_value_linear_units();
676
+        if (!WITHIN(g26_prime_length, 0.0, 25.0)) {
700 677
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
701 678
           return UBL_ERR;
702 679
         }
@@ -704,21 +681,21 @@
704 681
     }
705 682
 
706 683
     if (code_seen('F')) {
707
-      filament_diameter = code_value_linear_units();
708
-      if (!WITHIN(filament_diameter, 1.0, 4.0)) {
684
+      g26_filament_diameter = code_value_linear_units();
685
+      if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) {
709 686
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
710 687
         return UBL_ERR;
711 688
       }
712 689
     }
713
-    extrusion_multiplier *= sq(1.75) / sq(filament_diameter);         // If we aren't using 1.75mm filament, we need to
690
+    g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter);         // If we aren't using 1.75mm filament, we need to
714 691
                                                                       // scale up or down the length needed to get the
715 692
                                                                       // same volume of filament
716 693
 
717
-    extrusion_multiplier *= filament_diameter * sq(nozzle) / sq(0.3); // Scale up by nozzle size
694
+    g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size
718 695
 
719 696
     if (code_seen('H')) {
720
-      hotend_temp = code_value_temp_abs();
721
-      if (!WITHIN(hotend_temp, 165, 280)) {
697
+      g26_hotend_temp = code_value_temp_abs();
698
+      if (!WITHIN(g26_hotend_temp, 165, 280)) {
722 699
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
723 700
         return UBL_ERR;
724 701
       }
@@ -735,9 +712,9 @@
735 712
       return UBL_ERR;
736 713
     }
737 714
 
738
-    x_pos = code_seen('X') ? code_value_linear_units() : current_position[X_AXIS];
739
-    y_pos = code_seen('Y') ? code_value_linear_units() : current_position[Y_AXIS];
740
-    if (!position_is_reachable_xy(x_pos, y_pos)) {
715
+    g26_x_pos = code_seen('X') ? code_value_linear_units() : current_position[X_AXIS];
716
+    g26_y_pos = code_seen('Y') ? code_value_linear_units() : current_position[Y_AXIS];
717
+    if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) {
741 718
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
742 719
       return UBL_ERR;
743 720
     }
@@ -745,12 +722,12 @@
745 722
     /**
746 723
      * Wait until all parameters are verified before altering the state!
747 724
      */
748
-    ubl.state.active = !code_seen('D');
725
+    state.active = !code_seen('D');
749 726
 
750 727
     return UBL_OK;
751 728
   }
752 729
 
753
-  bool exit_from_g26() {
730
+  bool unified_bed_leveling::exit_from_g26() {
754 731
     lcd_reset_alert_level();
755 732
     lcd_setstatuspgm(PSTR("Leaving G26"));
756 733
     while (ubl_lcd_clicked()) idle();
@@ -761,18 +738,18 @@
761 738
    * Turn on the bed and nozzle heat and
762 739
    * wait for them to get up to temperature.
763 740
    */
764
-  bool turn_on_heaters() {
741
+  bool unified_bed_leveling::turn_on_heaters() {
765 742
     millis_t next;
766 743
     #if HAS_TEMP_BED
767 744
       #if ENABLED(ULTRA_LCD)
768
-        if (bed_temp > 25) {
745
+        if (g26_bed_temp > 25) {
769 746
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
770 747
           lcd_quick_feedback();
771 748
       #endif
772
-          ubl.has_control_of_lcd_panel = true;
773
-          thermalManager.setTargetBed(bed_temp);
749
+          has_control_of_lcd_panel = true;
750
+          thermalManager.setTargetBed(g26_bed_temp);
774 751
           next = millis() + 5000UL;
775
-          while (abs(thermalManager.degBed() - bed_temp) > 3) {
752
+          while (abs(thermalManager.degBed() - g26_bed_temp) > 3) {
776 753
             if (ubl_lcd_clicked()) return exit_from_g26();
777 754
             if (PENDING(millis(), next)) {
778 755
               next = millis() + 5000UL;
@@ -788,8 +765,8 @@
788 765
     #endif
789 766
 
790 767
     // Start heating the nozzle and wait for it to reach temperature.
791
-    thermalManager.setTargetHotend(hotend_temp, 0);
792
-    while (abs(thermalManager.degHotend(0) - hotend_temp) > 3) {
768
+    thermalManager.setTargetHotend(g26_hotend_temp, 0);
769
+    while (abs(thermalManager.degHotend(0) - g26_hotend_temp) > 3) {
793 770
       if (ubl_lcd_clicked()) return exit_from_g26();
794 771
       if (PENDING(millis(), next)) {
795 772
         next = millis() + 5000UL;
@@ -810,19 +787,19 @@
810 787
   /**
811 788
    * Prime the nozzle if needed. Return true on error.
812 789
    */
813
-  bool prime_nozzle() {
790
+  bool unified_bed_leveling::prime_nozzle() {
814 791
     float Total_Prime = 0.0;
815 792
 
816
-    if (prime_flag == -1) {  // The user wants to control how much filament gets purged
793
+    if (g26_prime_flag == -1) {  // The user wants to control how much filament gets purged
817 794
 
818
-      ubl.has_control_of_lcd_panel = true;
795
+      has_control_of_lcd_panel = true;
819 796
 
820 797
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
821 798
       chirp_at_user();
822 799
 
823 800
       set_destination_to_current();
824 801
 
825
-      un_retract_filament(destination); // Make sure G26 doesn't think the filament is retracted().
802
+      recover_filament(destination); // Make sure G26 doesn't think the filament is retracted().
826 803
 
827 804
       while (!ubl_lcd_clicked()) {
828 805
         chirp_at_user();
@@ -850,7 +827,7 @@
850 827
         lcd_quick_feedback();
851 828
       #endif
852 829
 
853
-      ubl.has_control_of_lcd_panel = false;
830
+      has_control_of_lcd_panel = false;
854 831
 
855 832
     }
856 833
     else {
@@ -859,7 +836,7 @@
859 836
         lcd_quick_feedback();
860 837
       #endif
861 838
       set_destination_to_current();
862
-      destination[E_AXIS] += prime_length;
839
+      destination[E_AXIS] += g26_prime_length;
863 840
       G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
864 841
       stepper.synchronize();
865 842
       set_destination_to_current();

+ 14
- 14
Marlin/Marlin_main.cpp View File

@@ -2355,7 +2355,7 @@ static void clean_up_after_endstop_or_probe_move() {
2355 2355
    *   - Raise to the BETWEEN height
2356 2356
    * - Return the probed Z position
2357 2357
    */
2358
-  float probe_pt(const float x, const float y, const bool stow/*=true*/, const int verbose_level/*=1*/) {
2358
+  float probe_pt(const float &x, const float &y, const bool stow/*=true*/, const int verbose_level/*=1*/) {
2359 2359
     #if ENABLED(DEBUG_LEVELING_FEATURE)
2360 2360
       if (DEBUGGING(LEVELING)) {
2361 2361
         SERIAL_ECHOPAIR(">>> probe_pt(", x);
@@ -3416,8 +3416,8 @@ inline void gcode_G7(
3416 3416
       return;
3417 3417
     }
3418 3418
 
3419
-    destination[X_AXIS] = hasI ? pgm_read_float(&ubl.mesh_index_to_xpos[ix]) : current_position[X_AXIS];
3420
-    destination[Y_AXIS] = hasJ ? pgm_read_float(&ubl.mesh_index_to_ypos[iy]) : current_position[Y_AXIS];
3419
+    destination[X_AXIS] = hasI ? ubl.mesh_index_to_xpos(ix) : current_position[X_AXIS];
3420
+    destination[Y_AXIS] = hasJ ? ubl.mesh_index_to_ypos(iy) : current_position[Y_AXIS];
3421 3421
     destination[Z_AXIS] = current_position[Z_AXIS]; //todo: perhaps add Z-move support?
3422 3422
     destination[E_AXIS] = current_position[E_AXIS];
3423 3423
 
@@ -5107,9 +5107,9 @@ void home_all_axes() { gcode_G28(true); }
5107 5107
      *      P4-P7  Probe all positions at different locations and average them.
5108 5108
      *
5109 5109
      *   T   Don't calibrate tower angle corrections
5110
-     *   
5110
+     *
5111 5111
      *   Cn.nn Calibration precision; when omitted calibrates to maximum precision
5112
-     *   
5112
+     *
5113 5113
      *   Vn  Verbose level:
5114 5114
      *
5115 5115
      *      V0  Dry-run mode. Report settings and probe results. No calibration.
@@ -5229,7 +5229,7 @@ void home_all_axes() { gcode_G28(true); }
5229 5229
       #endif
5230 5230
 
5231 5231
       int8_t iterations = 0;
5232
-      
5232
+
5233 5233
       home_offset[Z_AXIS] -= probe_pt(0.0, 0.0 , true, 1); // 1st probe to set height
5234 5234
       do_probe_raise(Z_CLEARANCE_BETWEEN_PROBES);
5235 5235
 
@@ -5239,7 +5239,7 @@ void home_all_axes() { gcode_G28(true); }
5239 5239
         int16_t N = 0;
5240 5240
 
5241 5241
         test_precision = zero_std_dev_old != 999.0 ? (zero_std_dev + zero_std_dev_old) / 2 : zero_std_dev;
5242
-        
5242
+
5243 5243
         iterations++;
5244 5244
 
5245 5245
         // Probe the points
@@ -5286,7 +5286,7 @@ void home_all_axes() { gcode_G28(true); }
5286 5286
           }
5287 5287
         zero_std_dev_old = zero_std_dev;
5288 5288
         zero_std_dev = round(sqrt(S2 / N) * 1000.0) / 1000.0 + 0.00001;
5289
-        
5289
+
5290 5290
         if (iterations == 1) home_offset[Z_AXIS] = zh_old; // reset height after 1st probe change
5291 5291
 
5292 5292
         // Solve matrices
@@ -5416,7 +5416,7 @@ void home_all_axes() { gcode_G28(true); }
5416 5416
             else {
5417 5417
               SERIAL_PROTOCOLPGM("std dev:");
5418 5418
               SERIAL_PROTOCOL_F(zero_std_dev, 3);
5419
-            }            
5419
+            }
5420 5420
             SERIAL_EOL;
5421 5421
             LCD_MESSAGEPGM("Calibration OK"); // TODO: Make translatable string
5422 5422
           }
@@ -5481,7 +5481,7 @@ void home_all_axes() { gcode_G28(true); }
5481 5481
         home_delta();
5482 5482
         endstops.not_homing();
5483 5483
 
5484
-      } 
5484
+      }
5485 5485
       while (zero_std_dev < test_precision && zero_std_dev > calibration_precision && iterations < 31);
5486 5486
 
5487 5487
       #if ENABLED(DELTA_HOME_TO_SAFE_ZONE)
@@ -8704,7 +8704,7 @@ void quickstop_stepper() {
8704 8704
     const bool hasZ = code_seen('Z'), hasQ = !hasZ && code_seen('Q');
8705 8705
 
8706 8706
     if (hasC) {
8707
-      const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false);
8707
+      const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false);
8708 8708
       ix = location.x_index;
8709 8709
       iy = location.y_index;
8710 8710
     }
@@ -11467,7 +11467,7 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
11467 11467
     #if ENABLED(AUTO_BED_LEVELING_UBL)
11468 11468
       const float fr_scaled = MMS_SCALED(feedrate_mm_s);
11469 11469
       if (ubl.state.active) {
11470
-        ubl_line_to_destination_cartesian(fr_scaled, active_extruder);
11470
+        ubl.line_to_destination_cartesian(fr_scaled, active_extruder);
11471 11471
         return true;
11472 11472
       }
11473 11473
       else
@@ -11612,14 +11612,14 @@ void prepare_move_to_destination() {
11612 11612
   if (
11613 11613
     #if IS_KINEMATIC
11614 11614
       #if UBL_DELTA
11615
-        ubl_prepare_linear_move_to(destination, feedrate_mm_s)
11615
+        ubl.prepare_linear_move_to(destination, feedrate_mm_s)
11616 11616
       #else
11617 11617
         prepare_kinematic_move_to(destination)
11618 11618
       #endif
11619 11619
     #elif ENABLED(DUAL_X_CARRIAGE)
11620 11620
       prepare_move_to_destination_dualx()
11621 11621
     #elif UBL_DELTA // will work for CARTESIAN too (smaller segments follow mesh more closely)
11622
-      ubl_prepare_linear_move_to(destination, feedrate_mm_s)
11622
+      ubl.prepare_linear_move_to(destination, feedrate_mm_s)
11623 11623
     #else
11624 11624
       prepare_move_to_destination_cartesian()
11625 11625
     #endif

+ 1
- 1
Marlin/example_configurations/SCARA/Configuration.h View File

@@ -903,7 +903,7 @@
903 903
   #define UBL_PROBE_PT_3_Y 20
904 904
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
905 905
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
906
- 
906
+
907 907
 #elif ENABLED(MESH_BED_LEVELING)
908 908
 
909 909
   //===========================================================================

+ 1
- 1
Marlin/example_configurations/TAZ4/Configuration.h View File

@@ -907,7 +907,7 @@
907 907
   #define UBL_PROBE_PT_3_Y 20
908 908
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
909 909
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
910
- 
910
+
911 911
 #elif ENABLED(MESH_BED_LEVELING)
912 912
 
913 913
   //===========================================================================

+ 1
- 1
Marlin/example_configurations/TinyBoy2/Configuration.h View File

@@ -943,7 +943,7 @@
943 943
   #define UBL_PROBE_PT_3_Y 20
944 944
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
945 945
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
946
- 
946
+
947 947
 #elif ENABLED(MESH_BED_LEVELING)
948 948
 
949 949
   //===========================================================================

+ 1
- 1
Marlin/example_configurations/WITBOX/Configuration.h View File

@@ -878,7 +878,7 @@
878 878
   #define UBL_PROBE_PT_3_Y 20
879 879
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
880 880
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
881
- 
881
+
882 882
 #elif ENABLED(MESH_BED_LEVELING)
883 883
 
884 884
   //===========================================================================

+ 1
- 1
Marlin/example_configurations/tvrrug/Round2/Configuration.h View File

@@ -883,7 +883,7 @@
883 883
   #define UBL_PROBE_PT_3_Y 20
884 884
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
885 885
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
886
- 
886
+
887 887
 #elif ENABLED(MESH_BED_LEVELING)
888 888
 
889 889
   //===========================================================================

+ 10
- 8
Marlin/fastio.h View File

@@ -21,24 +21,24 @@
21 21
  */
22 22
 
23 23
 /**
24
- * Contributed by Triffid_Hunter, modified by Kliment, extended by the Marlin team
25
- * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
24
+ * Fast I/O Routines
25
+ * Use direct port manipulation to save scads of processor time.
26
+ * Contributed by Triffid_Hunter. Modified by Kliment and the Marlin team.
26 27
  */
27 28
 
28
-#ifndef _FASTIO_ARDUINO_H
29
+#ifndef _FASTIO_ARDUINO_H 
29 30
 #define _FASTIO_ARDUINO_H
30 31
 
31 32
 #include <avr/io.h>
32 33
 
33 34
 /**
34
- * Include Ports and Functions
35
- */
36
-
37
-/**
38 35
  * Enable this option to use Teensy++ 2.0 assignments for AT90USB processors.
39 36
  */
40 37
 //#define AT90USBxx_TEENSYPP_ASSIGNMENTS
41 38
 
39
+/**
40
+ * Include Ports and Functions
41
+ */
42 42
 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
43 43
   #include "fastio_168.h"
44 44
 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
@@ -58,13 +58,15 @@
58 58
 #endif
59 59
 
60 60
 #ifndef _BV
61
-  #define _BV(PIN) (1 << PIN)
61
+  #define _BV(PIN) (1UL << PIN)
62 62
 #endif
63 63
 
64 64
 /**
65 65
  * Magic I/O routines
66 66
  *
67 67
  * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
68
+ *
69
+ * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
68 70
  */
69 71
 
70 72
 #define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN)))

+ 0
- 1
Marlin/fastio_AT90USB-Teensy.h View File

@@ -679,5 +679,4 @@
679 679
 #define PF7_PWM     NULL
680 680
 #define PF7_DDR     DDRF
681 681
 
682
-#endif // AT90USBxx_TEENSYPP_ASSIGNMENTS Teensyduino assignments
683 682
 #endif // _FASTIO_AT90USB

+ 4
- 4
Marlin/least_squares_fit.h View File

@@ -52,7 +52,7 @@ void inline incremental_LSF_reset(struct linear_fit_data *lsf) {
52 52
   memset(lsf, 0, sizeof(linear_fit_data));
53 53
 }
54 54
 
55
-void inline incremental_WLSF(struct linear_fit_data *lsf, float x, float y, float z, float w) {
55
+void inline incremental_WLSF(struct linear_fit_data *lsf, const float &x, const float &y, const float &z, const float &w) {
56 56
   // weight each accumulator by factor w, including the "number" of samples
57 57
   // (analagous to calling inc_LSF twice with same values to weight it by 2X)
58 58
   lsf->xbar  += w * x;
@@ -65,11 +65,11 @@ void inline incremental_WLSF(struct linear_fit_data *lsf, float x, float y, floa
65 65
   lsf->xzbar += w * x * z;
66 66
   lsf->yzbar += w * y * z;
67 67
   lsf->N     += w;
68
-  lsf->max_absx = max(fabs( w * x ), lsf->max_absx);
69
-  lsf->max_absy = max(fabs( w * y ), lsf->max_absy);
68
+  lsf->max_absx = max(fabs(w * x), lsf->max_absx);
69
+  lsf->max_absy = max(fabs(w * y), lsf->max_absy);
70 70
 }
71 71
 
72
-void inline incremental_LSF(struct linear_fit_data *lsf, float x, float y, float z) {
72
+void inline incremental_LSF(struct linear_fit_data *lsf, const float &x, const float &y, const float &z) {
73 73
   lsf->xbar += x;
74 74
   lsf->ybar += y;
75 75
   lsf->zbar += z;

+ 6
- 6
Marlin/macros.h View File

@@ -29,12 +29,12 @@
29 29
 #define XYZ  3
30 30
 
31 31
 #define FORCE_INLINE __attribute__((always_inline)) inline
32
-
33
-#define _O0 __attribute__((optimize("O0")))
34
-#define _Os __attribute__((optimize("Os")))
35
-#define _O1 __attribute__((optimize("O1")))
36
-#define _O2 __attribute__((optimize("O2")))
37
-#define _O3 __attribute__((optimize("O3")))
32
+#define _UNUSED      __attribute__((unused))
33
+#define _O0          __attribute__((optimize("O0")))
34
+#define _Os          __attribute__((optimize("Os")))
35
+#define _O1          __attribute__((optimize("O1")))
36
+#define _O2          __attribute__((optimize("O2")))
37
+#define _O3          __attribute__((optimize("O3")))
38 38
 
39 39
 // Bracket code that shouldn't be interrupted
40 40
 #ifndef CRITICAL_SECTION_START

+ 16
- 16
Marlin/nozzle.cpp View File

@@ -12,9 +12,9 @@
12 12
   * @param strokes number of strokes to execute
13 13
   */
14 14
 void Nozzle::stroke(
15
-  __attribute__((unused)) point_t const &start,
16
-  __attribute__((unused)) point_t const &end,
17
-  __attribute__((unused)) uint8_t const &strokes
15
+  _UNUSED point_t const &start,
16
+  _UNUSED point_t const &end,
17
+  _UNUSED uint8_t const &strokes
18 18
 ) {
19 19
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
20 20
 
@@ -56,10 +56,10 @@ void Nozzle::stroke(
56 56
   * @param objects number of objects to create
57 57
   */
58 58
 void Nozzle::zigzag(
59
-  __attribute__((unused)) point_t const &start,
60
-  __attribute__((unused)) point_t const &end,
61
-  __attribute__((unused)) uint8_t const &strokes,
62
-  __attribute__((unused)) uint8_t const &objects
59
+  _UNUSED point_t const &start,
60
+  _UNUSED point_t const &end,
61
+  _UNUSED uint8_t const &strokes,
62
+  _UNUSED uint8_t const &objects
63 63
 ) {
64 64
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
65 65
     const float A = nozzle_clean_horizontal ? nozzle_clean_height : nozzle_clean_length, // [twice the] Amplitude
@@ -114,10 +114,10 @@ void Nozzle::zigzag(
114 114
   * @param radius radius of circle
115 115
   */
116 116
 void Nozzle::circle(
117
-  __attribute__((unused)) point_t const &start,
118
-  __attribute__((unused)) point_t const &middle,
119
-  __attribute__((unused)) uint8_t const &strokes,
120
-  __attribute__((unused)) float const &radius
117
+  _UNUSED point_t const &start,
118
+  _UNUSED point_t const &middle,
119
+  _UNUSED uint8_t const &strokes,
120
+  _UNUSED float const &radius
121 121
 ) {
122 122
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
123 123
     if (strokes == 0) return;
@@ -177,10 +177,10 @@ void Nozzle::circle(
177 177
   * @param argument depends on the cleaning pattern
178 178
   */
179 179
 void Nozzle::clean(
180
-  __attribute__((unused)) uint8_t const &pattern,
181
-  __attribute__((unused)) uint8_t const &strokes,
182
-  __attribute__((unused)) float const &radius,
183
-  __attribute__((unused)) uint8_t const &objects
180
+  _UNUSED uint8_t const &pattern,
181
+  _UNUSED uint8_t const &strokes,
182
+  _UNUSED float const &radius,
183
+  _UNUSED uint8_t const &objects
184 184
 ) {
185 185
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
186 186
     #if ENABLED(DELTA)
@@ -209,7 +209,7 @@ void Nozzle::clean(
209 209
 }
210 210
 
211 211
 void Nozzle::park(
212
-  __attribute__((unused)) uint8_t const &z_action
212
+  _UNUSED uint8_t const &z_action
213 213
 ) {
214 214
   #if ENABLED(NOZZLE_PARK_FEATURE)
215 215
     float const z = current_position[Z_AXIS];

+ 21
- 21
Marlin/nozzle.h View File

@@ -50,10 +50,10 @@ class Nozzle {
50 50
      * @param strokes number of strokes to execute
51 51
      */
52 52
     static void stroke(
53
-      __attribute__((unused)) point_t const &start,
54
-      __attribute__((unused)) point_t const &end,
55
-      __attribute__((unused)) uint8_t const &strokes
56
-    ) __attribute__((optimize ("Os")));
53
+      _UNUSED point_t const &start,
54
+      _UNUSED point_t const &end,
55
+      _UNUSED uint8_t const &strokes
56
+    ) _Os;
57 57
 
58 58
     /**
59 59
      * @brief Zig-zag clean pattern
@@ -65,11 +65,11 @@ class Nozzle {
65 65
      * @param objects number of objects to create
66 66
      */
67 67
     static void zigzag(
68
-      __attribute__((unused)) point_t const &start,
69
-      __attribute__((unused)) point_t const &end,
70
-      __attribute__((unused)) uint8_t const &strokes,
71
-      __attribute__((unused)) uint8_t const &objects
72
-    ) __attribute__((optimize ("Os")));
68
+      _UNUSED point_t const &start,
69
+      _UNUSED point_t const &end,
70
+      _UNUSED uint8_t const &strokes,
71
+      _UNUSED uint8_t const &objects
72
+    ) _Os;
73 73
 
74 74
     /**
75 75
      * @brief Circular clean pattern
@@ -80,11 +80,11 @@ class Nozzle {
80 80
      * @param radius radius of circle
81 81
      */
82 82
     static void circle(
83
-      __attribute__((unused)) point_t const &start,
84
-      __attribute__((unused)) point_t const &middle,
85
-      __attribute__((unused)) uint8_t const &strokes,
86
-      __attribute__((unused)) float const &radius
87
-    ) __attribute__((optimize ("Os")));
83
+      _UNUSED point_t const &start,
84
+      _UNUSED point_t const &middle,
85
+      _UNUSED uint8_t const &strokes,
86
+      _UNUSED float const &radius
87
+    ) _Os;
88 88
 
89 89
   public:
90 90
     /**
@@ -95,15 +95,15 @@ class Nozzle {
95 95
      * @param argument depends on the cleaning pattern
96 96
      */
97 97
     static void clean(
98
-      __attribute__((unused)) uint8_t const &pattern,
99
-      __attribute__((unused)) uint8_t const &strokes,
100
-      __attribute__((unused)) float const &radius,
101
-      __attribute__((unused)) uint8_t const &objects = 0
102
-    ) __attribute__((optimize ("Os")));
98
+      _UNUSED uint8_t const &pattern,
99
+      _UNUSED uint8_t const &strokes,
100
+      _UNUSED float const &radius,
101
+      _UNUSED uint8_t const &objects = 0
102
+    ) _Os;
103 103
 
104 104
     static void park(
105
-      __attribute__((unused)) uint8_t const &z_action
106
-    ) __attribute__((optimize ("Os")));
105
+      _UNUSED uint8_t const &z_action
106
+    ) _Os;
107 107
 };
108 108
 
109 109
 #endif

+ 10
- 21
Marlin/spi.h View File

@@ -27,37 +27,26 @@
27 27
 #include "softspi.h"
28 28
 
29 29
 template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
30
-class Spi {
31
-  static SoftSPI<MisoPin, MosiPin, SckPin> softSpi;
30
+class SPI {
31
+  static SoftSPI<MisoPin, MosiPin, SckPin> softSPI;
32 32
   public:
33
-    inline __attribute__((always_inline))
34
-    static void init() {
35
-        softSpi.begin();
36
-    }
37
-    inline __attribute__((always_inline))
38
-    static void send(uint8_t data) {
39
-        softSpi.send(data);
40
-    }
41
-    inline __attribute__((always_inline))
42
-    static uint8_t receive() {
43
-        return softSpi.receive();
44
-    }
33
+    FORCE_INLINE static void init() { softSPI.begin(); }
34
+    FORCE_INLINE static void send(uint8_t data) { softSPI.send(data); }
35
+    FORCE_INLINE static uint8_t receive() { return softSPI.receive(); }
45 36
 };
46 37
 
47 38
 
48
-//hardware spi
39
+// Hardware SPI
49 40
 template<>
50
-class Spi<MISO_PIN, MOSI_PIN, SCK_PIN> {
41
+class SPI<MISO_PIN, MOSI_PIN, SCK_PIN> {
51 42
   public:
52
-    inline __attribute__((always_inline))
53
-    static void init() {
43
+    FORCE_INLINE static void init() {
54 44
         OUT_WRITE(SCK_PIN, LOW);
55 45
         OUT_WRITE(MOSI_PIN, HIGH);
56 46
         SET_INPUT(MISO_PIN);
57 47
         WRITE(MISO_PIN, HIGH);
58 48
     }
59
-    inline __attribute__((always_inline))
60
-    static uint8_t receive() {
49
+    FORCE_INLINE static uint8_t receive() {
61 50
       SPDR = 0;
62 51
       for (;!TEST(SPSR, SPIF););
63 52
       return SPDR;
@@ -65,4 +54,4 @@ class Spi<MISO_PIN, MOSI_PIN, SCK_PIN> {
65 54
 
66 55
 };
67 56
 
68
-#endif
57
+#endif // __SPI_H__

+ 1
- 1
Marlin/temperature.cpp View File

@@ -935,7 +935,7 @@ void Temperature::updateTemperaturesFromRawValues() {
935 935
   #ifndef MAX6675_DO_PIN
936 936
     #define MAX6675_DO_PIN MISO_PIN
937 937
   #endif
938
-  Spi<MAX6675_DO_PIN, MOSI_PIN, MAX6675_SCK_PIN> max6675_spi;
938
+  SPI<MAX6675_DO_PIN, MOSI_PIN, MAX6675_SCK_PIN> max6675_spi;
939 939
 #endif
940 940
 
941 941
 /**

+ 1
- 2
Marlin/temperature.h View File

@@ -288,8 +288,7 @@ class Temperature {
288 288
     /**
289 289
      * Call periodically to manage heaters
290 290
      */
291
-    //static void manage_heater(); // changed to address compiler error
292
-    static void manage_heater()  __attribute__((__optimize__("O2")));
291
+    static void manage_heater() _O2; // Added _O2 to work around a compiler error
293 292
 
294 293
     /**
295 294
      * Preheating hotends

+ 4
- 4
Marlin/ubl.cpp View File

@@ -69,8 +69,8 @@
69 69
 
70 70
   // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
71 71
   // until determinism prevails
72
-  constexpr float unified_bed_leveling::mesh_index_to_xpos[16],
73
-                  unified_bed_leveling::mesh_index_to_ypos[16];
72
+  constexpr float unified_bed_leveling::_mesh_index_to_xpos[16],
73
+                  unified_bed_leveling::_mesh_index_to_ypos[16];
74 74
 
75 75
   bool unified_bed_leveling::g26_debug_flag = false,
76 76
        unified_bed_leveling::has_control_of_lcd_panel = false;
@@ -117,8 +117,8 @@
117 117
       SERIAL_EOL;
118 118
     }
119 119
 
120
-    const float current_xi = ubl.get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0),
121
-                current_yi = ubl.get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0);
120
+    const float current_xi = get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0),
121
+                current_yi = get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0);
122 122
 
123 123
     for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
124 124
       for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {

+ 106
- 55
Marlin/ubl.h View File

@@ -53,30 +53,16 @@
53 53
   // ubl_motion.cpp
54 54
 
55 55
   void debug_current_and_destination(const char * const title);
56
-  void ubl_line_to_destination_cartesian(const float&, uint8_t);
57
-  bool ubl_prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate );
58 56
 
59 57
   // ubl_G29.cpp
60 58
 
61 59
   enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
62 60
 
63
-  void dump(char * const str, const float &f);
64
-  void probe_entire_mesh(const float&, const float&, const bool, const bool, const bool);
65
-  float measure_business_card_thickness(float&);
66
-  mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, unsigned int[16], bool);
67
-  void shift_mesh_height();
68
-  void fine_tune_mesh(const float&, const float&, const bool);
69
-  bool g29_parameter_parsing();
70
-  void g29_eeprom_dump();
71
-  void g29_compare_current_mesh_to_stored_mesh();
72
-
73 61
   // External references
74 62
 
75 63
   char *ftostr43sign(const float&, char);
76 64
   bool ubl_lcd_clicked();
77 65
   void home_all_axes();
78
-  void gcode_G26();
79
-  void gcode_G29();
80 66
 
81 67
   extern uint8_t ubl_cnt;
82 68
 
@@ -101,26 +87,81 @@
101 87
 
102 88
       static float last_specified_z;
103 89
 
90
+      static int    g29_verbose_level,
91
+                    g29_phase_value,
92
+                    g29_repetition_cnt,
93
+                    g29_storage_slot,
94
+                    g29_map_type,
95
+                    g29_grid_size;
96
+      static bool   g29_c_flag, g29_x_flag, g29_y_flag;
97
+      static float  g29_x_pos, g29_y_pos,
98
+                    g29_card_thickness,
99
+                    g29_constant;
100
+
101
+      #if ENABLED(UBL_G26_MESH_VALIDATION)
102
+        static float   g26_extrusion_multiplier,
103
+                       g26_retraction_multiplier,
104
+                       g26_nozzle,
105
+                       g26_filament_diameter,
106
+                       g26_prime_length,
107
+                       g26_x_pos, g26_y_pos,
108
+                       g26_ooze_amount,
109
+                       g26_layer_height;
110
+        static int16_t g26_bed_temp,
111
+                       g26_hotend_temp,
112
+                       g26_repeats;
113
+        static int8_t  g26_prime_flag;
114
+        static bool    g26_continue_with_closest, g26_keep_heaters_on;
115
+      #endif
116
+
117
+      static float measure_point_with_encoder();
118
+      static float measure_business_card_thickness(float&);
119
+      static bool g29_parameter_parsing();
120
+      static void find_mean_mesh_height();
121
+      static void shift_mesh_height();
122
+      static void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
123
+      static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool);
124
+      static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
125
+      static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
126
+      static void g29_what_command();
127
+      static void g29_eeprom_dump();
128
+      static void g29_compare_current_mesh_to_stored_mesh();
129
+      static void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map);
130
+      static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
131
+      static void smart_fill_mesh();
132
+
133
+      #if ENABLED(UBL_G26_MESH_VALIDATION)
134
+        static bool exit_from_g26();
135
+        static bool parse_G26_parameters();
136
+        static void G26_line_to_destination(const float &feed_rate);
137
+        static mesh_index_pair find_closest_circle_to_print(const float&, const float&);
138
+        static bool look_for_lines_to_connect();
139
+        static bool turn_on_heaters();
140
+        static bool prime_nozzle();
141
+        static void retract_filament(float where[XYZE]);
142
+        static void recover_filament(float where[XYZE]);
143
+        static void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&);
144
+        static void move_to(const float&, const float&, const float&, const float&);
145
+      #endif
146
+
104 147
     public:
105 148
 
106
-      void echo_name();
107
-      void report_state();
108
-      void find_mean_mesh_height();
109
-      void shift_mesh_height();
110
-      void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
111
-      void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
112
-      void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
113
-      void save_ubl_active_state_and_disable();
114
-      void restore_ubl_active_state_and_leave();
115
-      void g29_what_command();
116
-      void g29_eeprom_dump();
117
-      void g29_compare_current_mesh_to_stored_mesh();
118
-      void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map);
119
-      void smart_fill_mesh();
120
-      void display_map(const int);
121
-      void reset();
122
-      void invalidate();
123
-      bool sanity_check();
149
+      static void echo_name();
150
+      static void report_state();
151
+      static void save_ubl_active_state_and_disable();
152
+      static void restore_ubl_active_state_and_leave();
153
+      static void display_map(const int);
154
+      static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, unsigned int[16], bool);
155
+      static void reset();
156
+      static void invalidate();
157
+      static bool sanity_check();
158
+
159
+      static void G29() _O0;                          // O0 for no optimization
160
+      static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560
161
+
162
+      #if ENABLED(UBL_G26_MESH_VALIDATION)
163
+        static void G26();
164
+      #endif
124 165
 
125 166
       static ubl_state state;
126 167
 
@@ -128,7 +169,7 @@
128 169
 
129 170
       // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
130 171
       // until determinism prevails
131
-      constexpr static float mesh_index_to_xpos[16] PROGMEM = {
172
+      constexpr static float _mesh_index_to_xpos[16] PROGMEM = {
132 173
                                 UBL_MESH_MIN_X +  0 * (MESH_X_DIST), UBL_MESH_MIN_X +  1 * (MESH_X_DIST),
133 174
                                 UBL_MESH_MIN_X +  2 * (MESH_X_DIST), UBL_MESH_MIN_X +  3 * (MESH_X_DIST),
134 175
                                 UBL_MESH_MIN_X +  4 * (MESH_X_DIST), UBL_MESH_MIN_X +  5 * (MESH_X_DIST),
@@ -139,7 +180,7 @@
139 180
                                 UBL_MESH_MIN_X + 14 * (MESH_X_DIST), UBL_MESH_MIN_X + 15 * (MESH_X_DIST)
140 181
                               };
141 182
 
142
-      constexpr static float mesh_index_to_ypos[16] PROGMEM = {
183
+      constexpr static float _mesh_index_to_ypos[16] PROGMEM = {
143 184
                                 UBL_MESH_MIN_Y +  0 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  1 * (MESH_Y_DIST),
144 185
                                 UBL_MESH_MIN_Y +  2 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  3 * (MESH_Y_DIST),
145 186
                                 UBL_MESH_MIN_Y +  4 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  5 * (MESH_Y_DIST),
@@ -156,16 +197,16 @@
156 197
 
157 198
       unified_bed_leveling();
158 199
 
159
-      FORCE_INLINE void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
200
+      FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
160 201
 
161
-      int8_t get_cell_index_x(const float &x) {
202
+      static int8_t get_cell_index_x(const float &x) {
162 203
         const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
163 204
         return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1);   // -1 is appropriate if we want all movement to the X_MAX
164 205
       }                                                     // position. But with this defined this way, it is possible
165 206
                                                             // to extrapolate off of this point even further out. Probably
166 207
                                                             // that is OK because something else should be keeping that from
167 208
                                                             // happening and should not be worried about at this level.
168
-      int8_t get_cell_index_y(const float &y) {
209
+      static int8_t get_cell_index_y(const float &y) {
169 210
         const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
170 211
         return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
171 212
       }                                                     // position. But with this defined this way, it is possible
@@ -173,12 +214,12 @@
173 214
                                                             // that is OK because something else should be keeping that from
174 215
                                                             // happening and should not be worried about at this level.
175 216
 
176
-      int8_t find_closest_x_index(const float &x) {
217
+      static int8_t find_closest_x_index(const float &x) {
177 218
         const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
178 219
         return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
179 220
       }
180 221
 
181
-      int8_t find_closest_y_index(const float &y) {
222
+      static int8_t find_closest_y_index(const float &y) {
182 223
         const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
183 224
         return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
184 225
       }
@@ -198,7 +239,7 @@
198 239
        *  It is fairly expensive with its 4 floating point additions and 2 floating point
199 240
        *  multiplications.
200 241
        */
201
-      FORCE_INLINE float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
242
+      FORCE_INLINE static float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
202 243
         return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
203 244
       }
204 245
 
@@ -206,7 +247,7 @@
206 247
        * z_correction_for_x_on_horizontal_mesh_line is an optimization for
207 248
        * the rare occasion when a point lies exactly on a Mesh line (denoted by index yi).
208 249
        */
209
-      inline float z_correction_for_x_on_horizontal_mesh_line(const float &lx0, const int x1_i, const int yi) {
250
+      inline static float z_correction_for_x_on_horizontal_mesh_line(const float &lx0, const int x1_i, const int yi) {
210 251
         if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
211 252
           serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") );
212 253
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0);
@@ -217,7 +258,7 @@
217 258
           return NAN;
218 259
         }
219 260
 
220
-        const float xratio = (RAW_X_POSITION(lx0) - pgm_read_float(&mesh_index_to_xpos[x1_i])) * (1.0 / (MESH_X_DIST)),
261
+        const float xratio = (RAW_X_POSITION(lx0) - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)),
221 262
                     z1 = z_values[x1_i][yi];
222 263
 
223 264
         return z1 + xratio * (z_values[x1_i + 1][yi] - z1);
@@ -226,7 +267,7 @@
226 267
       //
227 268
       // See comments above for z_correction_for_x_on_horizontal_mesh_line
228 269
       //
229
-      inline float z_correction_for_y_on_vertical_mesh_line(const float &ly0, const int xi, const int y1_i) {
270
+      inline static float z_correction_for_y_on_vertical_mesh_line(const float &ly0, const int xi, const int y1_i) {
230 271
         if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) {
231 272
           serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") );
232 273
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0);
@@ -237,7 +278,7 @@
237 278
           return NAN;
238 279
         }
239 280
 
240
-        const float yratio = (RAW_Y_POSITION(ly0) - pgm_read_float(&mesh_index_to_ypos[y1_i])) * (1.0 / (MESH_Y_DIST)),
281
+        const float yratio = (RAW_Y_POSITION(ly0) - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)),
241 282
                     z1 = z_values[xi][y1_i];
242 283
 
243 284
         return z1 + yratio * (z_values[xi][y1_i + 1] - z1);
@@ -249,7 +290,7 @@
249 290
        * Z-Height at both ends. Then it does a linear interpolation of these heights based
250 291
        * on the Y position within the cell.
251 292
        */
252
-      float get_z_correction(const float &lx0, const float &ly0) {
293
+      static float get_z_correction(const float &lx0, const float &ly0) {
253 294
         const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)),
254 295
                      cy = get_cell_index_y(RAW_Y_POSITION(ly0));
255 296
 
@@ -268,16 +309,16 @@
268 309
         }
269 310
 
270 311
         const float z1 = calc_z0(RAW_X_POSITION(lx0),
271
-                                 pgm_read_float(&mesh_index_to_xpos[cx]), z_values[cx][cy],
272
-                                 pgm_read_float(&mesh_index_to_xpos[cx + 1]), z_values[cx + 1][cy]);
312
+                                 mesh_index_to_xpos(cx), z_values[cx][cy],
313
+                                 mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy]);
273 314
 
274 315
         const float z2 = calc_z0(RAW_X_POSITION(lx0),
275
-                                 pgm_read_float(&mesh_index_to_xpos[cx]), z_values[cx][cy + 1],
276
-                                 pgm_read_float(&mesh_index_to_xpos[cx + 1]), z_values[cx + 1][cy + 1]);
316
+                                 mesh_index_to_xpos(cx), z_values[cx][cy + 1],
317
+                                 mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy + 1]);
277 318
 
278 319
         float z0 = calc_z0(RAW_Y_POSITION(ly0),
279
-                           pgm_read_float(&mesh_index_to_ypos[cy]), z1,
280
-                           pgm_read_float(&mesh_index_to_ypos[cy + 1]), z2);
320
+                           mesh_index_to_ypos(cy), z1,
321
+                           mesh_index_to_ypos(cy + 1), z2);
281 322
 
282 323
         #if ENABLED(DEBUG_LEVELING_FEATURE)
283 324
           if (DEBUGGING(MESH_ADJUST)) {
@@ -324,7 +365,7 @@
324 365
        *  Returns 0.0 if Z is past the specified 'Fade Height'.
325 366
        */
326 367
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
327
-        inline float fade_scaling_factor_for_z(const float &lz) {
368
+        static inline float fade_scaling_factor_for_z(const float &lz) {
328 369
           if (planner.z_fade_height == 0.0) return 1.0;
329 370
           static float fade_scaling_factor = 1.0;
330 371
           const float rz = RAW_Z_POSITION(lz);
@@ -338,14 +379,24 @@
338 379
           return fade_scaling_factor;
339 380
         }
340 381
       #else
341
-        inline float fade_scaling_factor_for_z(const float &lz) {
342
-          return 1.0;
343
-        }
382
+        FORCE_INLINE static float fade_scaling_factor_for_z(const float &lz) { return 1.0; }
344 383
       #endif
345 384
 
385
+      FORCE_INLINE static float mesh_index_to_xpos(const uint8_t i) { return pgm_read_float(&_mesh_index_to_xpos[i]); }
386
+      FORCE_INLINE static float mesh_index_to_ypos(const uint8_t i) { return pgm_read_float(&_mesh_index_to_ypos[i]); }
387
+
388
+      static bool prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate);
389
+      static void line_to_destination_cartesian(const float &fr, uint8_t e);
390
+
346 391
   }; // class unified_bed_leveling
347 392
 
348 393
   extern unified_bed_leveling ubl;
349 394
 
395
+  #if ENABLED(UBL_G26_MESH_VALIDATION)
396
+    FORCE_INLINE void gcode_G26() { ubl.G26(); }
397
+  #endif
398
+
399
+  FORCE_INLINE void gcode_G29() { ubl.G29(); }
400
+
350 401
 #endif // AUTO_BED_LEVELING_UBL
351 402
 #endif // UNIFIED_BED_LEVELING_H

+ 235
- 246
Marlin/ubl_G29.cpp
File diff suppressed because it is too large
View File


+ 64
- 64
Marlin/ubl_motion.cpp View File

@@ -85,7 +85,7 @@
85 85
 
86 86
   }
87 87
 
88
-  void ubl_line_to_destination_cartesian(const float &feed_rate, uint8_t extruder) {
88
+  void unified_bed_leveling::line_to_destination_cartesian(const float &feed_rate, uint8_t extruder) {
89 89
     /**
90 90
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
91 91
      * as possible to determine if this is the case. If this move is within the same cell, we will
@@ -104,19 +104,19 @@
104 104
                   destination[E_AXIS]
105 105
                 };
106 106
 
107
-    const int cell_start_xi = ubl.get_cell_index_x(RAW_X_POSITION(start[X_AXIS])),
108
-              cell_start_yi = ubl.get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])),
109
-              cell_dest_xi  = ubl.get_cell_index_x(RAW_X_POSITION(end[X_AXIS])),
110
-              cell_dest_yi  = ubl.get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS]));
107
+    const int cell_start_xi = get_cell_index_x(RAW_X_POSITION(start[X_AXIS])),
108
+              cell_start_yi = get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])),
109
+              cell_dest_xi  = get_cell_index_x(RAW_X_POSITION(end[X_AXIS])),
110
+              cell_dest_yi  = get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS]));
111 111
 
112
-    if (ubl.g26_debug_flag) {
113
-      SERIAL_ECHOPAIR(" ubl_line_to_destination(xe=", end[X_AXIS]);
112
+    if (g26_debug_flag) {
113
+      SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]);
114 114
       SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]);
115 115
       SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]);
116 116
       SERIAL_ECHOPAIR(", ee=", end[E_AXIS]);
117 117
       SERIAL_CHAR(')');
118 118
       SERIAL_EOL;
119
-      debug_current_and_destination(PSTR("Start of ubl_line_to_destination()"));
119
+      debug_current_and_destination(PSTR("Start of ubl.line_to_destination()"));
120 120
     }
121 121
 
122 122
     if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell,
@@ -132,11 +132,11 @@
132 132
         // Note: There is no Z Correction in this case. We are off the grid and don't know what
133 133
         // a reasonable correction would be.
134 134
 
135
-        planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + ubl.state.z_offset, end[E_AXIS], feed_rate, extruder);
135
+        planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + state.z_offset, end[E_AXIS], feed_rate, extruder);
136 136
         set_current_to_destination();
137 137
 
138
-        if (ubl.g26_debug_flag)
139
-          debug_current_and_destination(PSTR("out of bounds in ubl_line_to_destination()"));
138
+        if (g26_debug_flag)
139
+          debug_current_and_destination(PSTR("out of bounds in ubl.line_to_destination()"));
140 140
 
141 141
         return;
142 142
       }
@@ -152,20 +152,20 @@
152 152
        * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
153 153
        */
154 154
 
155
-      const float xratio = (RAW_X_POSITION(end[X_AXIS]) - pgm_read_float(&ubl.mesh_index_to_xpos[cell_dest_xi])) * (1.0 / (MESH_X_DIST)),
156
-                  z1 = ubl.z_values[cell_dest_xi    ][cell_dest_yi    ] + xratio *
157
-                      (ubl.z_values[cell_dest_xi + 1][cell_dest_yi    ] - ubl.z_values[cell_dest_xi][cell_dest_yi    ]),
158
-                  z2 = ubl.z_values[cell_dest_xi    ][cell_dest_yi + 1] + xratio *
159
-                      (ubl.z_values[cell_dest_xi + 1][cell_dest_yi + 1] - ubl.z_values[cell_dest_xi][cell_dest_yi + 1]);
155
+      const float xratio = (RAW_X_POSITION(end[X_AXIS]) - mesh_index_to_xpos(cell_dest_xi)) * (1.0 / (MESH_X_DIST)),
156
+                  z1 = z_values[cell_dest_xi    ][cell_dest_yi    ] + xratio *
157
+                      (z_values[cell_dest_xi + 1][cell_dest_yi    ] - z_values[cell_dest_xi][cell_dest_yi    ]),
158
+                  z2 = z_values[cell_dest_xi    ][cell_dest_yi + 1] + xratio *
159
+                      (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]);
160 160
 
161 161
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
162 162
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
163 163
 
164
-      const float yratio = (RAW_Y_POSITION(end[Y_AXIS]) - pgm_read_float(&ubl.mesh_index_to_ypos[cell_dest_yi])) * (1.0 / (MESH_Y_DIST));
164
+      const float yratio = (RAW_Y_POSITION(end[Y_AXIS]) - mesh_index_to_ypos(cell_dest_yi)) * (1.0 / (MESH_Y_DIST));
165 165
 
166 166
       float z0 = z1 + (z2 - z1) * yratio;
167 167
 
168
-      z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
168
+      z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
169 169
 
170 170
       /**
171 171
        * If part of the Mesh is undefined, it will show up as NAN
@@ -176,10 +176,10 @@
176 176
        */
177 177
       if (isnan(z0)) z0 = 0.0;
178 178
 
179
-      planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0 + ubl.state.z_offset, end[E_AXIS], feed_rate, extruder);
179
+      planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0 + state.z_offset, end[E_AXIS], feed_rate, extruder);
180 180
 
181
-      if (ubl.g26_debug_flag)
182
-        debug_current_and_destination(PSTR("FINAL_MOVE in ubl_line_to_destination()"));
181
+      if (g26_debug_flag)
182
+        debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination()"));
183 183
 
184 184
       set_current_to_destination();
185 185
       return;
@@ -240,7 +240,7 @@
240 240
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
241 241
       while (current_yi != cell_dest_yi + down_flag) {
242 242
         current_yi += dyi;
243
-        const float next_mesh_line_y = LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[current_yi]));
243
+        const float next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi));
244 244
 
245 245
         /**
246 246
          * if the slope of the line is infinite, we won't do the calculations
@@ -249,9 +249,9 @@
249 249
          */
250 250
         const float x = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m;
251 251
 
252
-        float z0 = ubl.z_correction_for_x_on_horizontal_mesh_line(x, current_xi, current_yi);
252
+        float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi, current_yi);
253 253
 
254
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
254
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
255 255
 
256 256
         /**
257 257
          * If part of the Mesh is undefined, it will show up as NAN
@@ -262,7 +262,7 @@
262 262
          */
263 263
         if (isnan(z0)) z0 = 0.0;
264 264
 
265
-        const float y = LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[current_yi]));
265
+        const float y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi));
266 266
 
267 267
         /**
268 268
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
@@ -281,12 +281,12 @@
281 281
             z_position = end[Z_AXIS];
282 282
           }
283 283
 
284
-          planner._buffer_line(x, y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
284
+          planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
285 285
         } //else printf("FIRST MOVE PRUNED  ");
286 286
       }
287 287
 
288
-      if (ubl.g26_debug_flag)
289
-        debug_current_and_destination(PSTR("vertical move done in ubl_line_to_destination()"));
288
+      if (g26_debug_flag)
289
+        debug_current_and_destination(PSTR("vertical move done in ubl.line_to_destination()"));
290 290
 
291 291
       //
292 292
       // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done.
@@ -311,12 +311,12 @@
311 311
                                 // edge of this cell for the first move.
312 312
       while (current_xi != cell_dest_xi + left_flag) {
313 313
         current_xi += dxi;
314
-        const float next_mesh_line_x = LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[current_xi])),
314
+        const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)),
315 315
                     y = m * next_mesh_line_x + c;   // Calculate Y at the next X mesh line
316 316
 
317
-        float z0 = ubl.z_correction_for_y_on_vertical_mesh_line(y, current_xi, current_yi);
317
+        float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi, current_yi);
318 318
 
319
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
319
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
320 320
 
321 321
         /**
322 322
          * If part of the Mesh is undefined, it will show up as NAN
@@ -327,7 +327,7 @@
327 327
          */
328 328
         if (isnan(z0)) z0 = 0.0;
329 329
 
330
-        const float x = LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[current_xi]));
330
+        const float x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi));
331 331
 
332 332
         /**
333 333
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
@@ -346,12 +346,12 @@
346 346
             z_position = end[Z_AXIS];
347 347
           }
348 348
 
349
-          planner._buffer_line(x, y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
349
+          planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
350 350
         } //else printf("FIRST MOVE PRUNED  ");
351 351
       }
352 352
 
353
-      if (ubl.g26_debug_flag)
354
-        debug_current_and_destination(PSTR("horizontal move done in ubl_line_to_destination()"));
353
+      if (g26_debug_flag)
354
+        debug_current_and_destination(PSTR("horizontal move done in ubl.line_to_destination()"));
355 355
 
356 356
       if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
357 357
         goto FINAL_MOVE;
@@ -377,8 +377,8 @@
377 377
 
378 378
     while (xi_cnt > 0 || yi_cnt > 0) {
379 379
 
380
-      const float next_mesh_line_x = LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[current_xi + dxi])),
381
-                  next_mesh_line_y = LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[current_yi + dyi])),
380
+      const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi + dxi)),
381
+                  next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi + dyi)),
382 382
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
383 383
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
384 384
                                                   // (No need to worry about m being zero.
@@ -387,9 +387,9 @@
387 387
 
388 388
       if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
389 389
         // Yes!  Crossing a Y Mesh Line next
390
-        float z0 = ubl.z_correction_for_x_on_horizontal_mesh_line(x, current_xi - left_flag, current_yi + dyi);
390
+        float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi - left_flag, current_yi + dyi);
391 391
 
392
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
392
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
393 393
 
394 394
         /**
395 395
          * If part of the Mesh is undefined, it will show up as NAN
@@ -409,15 +409,15 @@
409 409
           e_position = end[E_AXIS];
410 410
           z_position = end[Z_AXIS];
411 411
         }
412
-        planner._buffer_line(x, next_mesh_line_y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
412
+        planner._buffer_line(x, next_mesh_line_y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
413 413
         current_yi += dyi;
414 414
         yi_cnt--;
415 415
       }
416 416
       else {
417 417
         // Yes!  Crossing a X Mesh Line next
418
-        float z0 = ubl.z_correction_for_y_on_vertical_mesh_line(y, current_xi + dxi, current_yi - down_flag);
418
+        float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi + dxi, current_yi - down_flag);
419 419
 
420
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
420
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
421 421
 
422 422
         /**
423 423
          * If part of the Mesh is undefined, it will show up as NAN
@@ -438,7 +438,7 @@
438 438
           z_position = end[Z_AXIS];
439 439
         }
440 440
 
441
-        planner._buffer_line(next_mesh_line_x, y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
441
+        planner._buffer_line(next_mesh_line_x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
442 442
         current_xi += dxi;
443 443
         xi_cnt--;
444 444
       }
@@ -446,8 +446,8 @@
446 446
       if (xi_cnt < 0 || yi_cnt < 0) break; // we've gone too far, so exit the loop and move on to FINAL_MOVE
447 447
     }
448 448
 
449
-    if (ubl.g26_debug_flag)
450
-      debug_current_and_destination(PSTR("generic move done in ubl_line_to_destination()"));
449
+    if (g26_debug_flag)
450
+      debug_current_and_destination(PSTR("generic move done in ubl.line_to_destination()"));
451 451
 
452 452
     if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
453 453
       goto FINAL_MOVE;
@@ -502,7 +502,7 @@
502 502
      * Returns true if the caller did NOT update current_position, otherwise false.
503 503
      */
504 504
 
505
-    static bool ubl_prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate) {
505
+    static bool unified_bed_leveling::prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate) {
506 506
 
507 507
       if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS]))  // fail if moving outside reachable boundary
508 508
         return true; // did not move, so current_position still accurate
@@ -554,9 +554,9 @@
554 554
 
555 555
       // Only compute leveling per segment if ubl active and target below z_fade_height.
556 556
 
557
-      if (!ubl.state.active || above_fade_height) {   // no mesh leveling
557
+      if (!state.active || above_fade_height) {   // no mesh leveling
558 558
 
559
-        const float z_offset = ubl.state.active ? ubl.state.z_offset : 0.0;
559
+        const float z_offset = state.active ? state.z_offset : 0.0;
560 560
 
561 561
         float seg_dest[XYZE];                   // per-segment destination,
562 562
         COPY_XYZE(seg_dest, current_position);  // starting from current position
@@ -579,7 +579,7 @@
579 579
       // Otherwise perform per-segment leveling
580 580
 
581 581
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
582
-        const float fade_scaling_factor = ubl.fade_scaling_factor_for_z(ltarget[Z_AXIS]);
582
+        const float fade_scaling_factor = fade_scaling_factor_for_z(ltarget[Z_AXIS]);
583 583
       #endif
584 584
 
585 585
       float seg_dest[XYZE];  // per-segment destination, initialize to first segment
@@ -591,7 +591,7 @@
591 591
       float rx = RAW_X_POSITION(seg_dest[X_AXIS]),  // assume raw vs logical coordinates shifted but not scaled.
592 592
             ry = RAW_Y_POSITION(seg_dest[Y_AXIS]);
593 593
 
594
-      do {  // for each mesh cell encountered during the move
594
+      for(;;) {  // for each mesh cell encountered during the move
595 595
 
596 596
         // Compute mesh cell invariants that remain constant for all segments within cell.
597 597
         // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter)
@@ -606,19 +606,19 @@
606 606
         cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
607 607
         cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
608 608
 
609
-        const float x0 = pgm_read_float(&(ubl.mesh_index_to_xpos[cell_xi  ])),  // 64 byte table lookup avoids mul+add
610
-                    y0 = pgm_read_float(&(ubl.mesh_index_to_ypos[cell_yi  ])),  // 64 byte table lookup avoids mul+add
611
-                    x1 = pgm_read_float(&(ubl.mesh_index_to_xpos[cell_xi+1])),  // 64 byte table lookup avoids mul+add
612
-                    y1 = pgm_read_float(&(ubl.mesh_index_to_ypos[cell_yi+1]));  // 64 byte table lookup avoids mul+add
609
+        const float x0 = pgm_read_float(&(mesh_index_to_xpos[cell_xi  ])),  // 64 byte table lookup avoids mul+add
610
+                    y0 = pgm_read_float(&(mesh_index_to_ypos[cell_yi  ])),  // 64 byte table lookup avoids mul+add
611
+                    x1 = pgm_read_float(&(mesh_index_to_xpos[cell_xi+1])),  // 64 byte table lookup avoids mul+add
612
+                    y1 = pgm_read_float(&(mesh_index_to_ypos[cell_yi+1]));  // 64 byte table lookup avoids mul+add
613 613
 
614 614
         float cx = rx - x0,   // cell-relative x
615 615
               cy = ry - y0,   // cell-relative y
616
-              z_x0y0 = ubl.z_values[cell_xi  ][cell_yi  ],  // z at lower left corner
617
-              z_x1y0 = ubl.z_values[cell_xi+1][cell_yi  ],  // z at upper left corner
618
-              z_x0y1 = ubl.z_values[cell_xi  ][cell_yi+1],  // z at lower right corner
619
-              z_x1y1 = ubl.z_values[cell_xi+1][cell_yi+1];  // z at upper right corner
616
+              z_x0y0 = z_values[cell_xi  ][cell_yi  ],  // z at lower left corner
617
+              z_x1y0 = z_values[cell_xi+1][cell_yi  ],  // z at upper left corner
618
+              z_x0y1 = z_values[cell_xi  ][cell_yi+1],  // z at lower right corner
619
+              z_x1y1 = z_values[cell_xi+1][cell_yi+1];  // z at upper right corner
620 620
 
621
-        if (isnan(z_x0y0)) z_x0y0 = 0;              // ideally activating ubl.state.active (G29 A)
621
+        if (isnan(z_x0y0)) z_x0y0 = 0;              // ideally activating state.active (G29 A)
622 622
         if (isnan(z_x1y0)) z_x1y0 = 0;              //   should refuse if any invalid mesh points
623 623
         if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
624 624
         if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
@@ -642,7 +642,7 @@
642 642
         const float z_sxy0 = z_xmy0 * dx_seg,                                     // per-segment adjustment to z_cxy0
643 643
                     z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * dx_seg;  // per-segment adjustment to z_cxym
644 644
 
645
-        do {  // for all segments within this mesh cell
645
+        for(;;) {  // for all segments within this mesh cell
646 646
 
647 647
           float z_cxcy = z_cxy0 + z_cxym * cy;      // interpolated mesh z height along cx at cy
648 648
 
@@ -650,7 +650,7 @@
650 650
             z_cxcy *= fade_scaling_factor;          // apply fade factor to interpolated mesh height
651 651
           #endif
652 652
 
653
-          z_cxcy += ubl.state.z_offset;             // add fixed mesh offset from G29 Z
653
+          z_cxcy += state.z_offset;             // add fixed mesh offset from G29 Z
654 654
 
655 655
           if (--segments == 0) {                    // if this is last segment, use ltarget for exact
656 656
             COPY_XYZE(seg_dest, ltarget);
@@ -681,9 +681,9 @@
681 681
           z_cxy0 += z_sxy0;   // adjust z_cxy0 by per-segment z_sxy0
682 682
           z_cxym += z_sxym;   // adjust z_cxym by per-segment z_sxym
683 683
 
684
-        } while (true);   // per-segment loop exits by break after last segment within cell, or by return on final segment
685
-      } while (true);   // per-cell loop
686
-    }                 // end of function
684
+        } // segment loop
685
+      } // cell loop
686
+    }
687 687
 
688 688
   #endif // UBL_DELTA
689 689
 

+ 3
- 3
Marlin/ultralcd.cpp View File

@@ -1480,7 +1480,7 @@ void kill_screen(const char* lcd_msg) {
1480 1480
     void _lcd_level_bed_get_z() {
1481 1481
       ENCODER_DIRECTION_NORMAL();
1482 1482
 
1483
-      // Encoder wheel adjusts the Z position
1483
+      // Encoder knob or keypad buttons adjust the Z position
1484 1484
       if (encoderPosition) {
1485 1485
         refresh_cmd_timeout();
1486 1486
         current_position[Z_AXIS] += float((int32_t)encoderPosition) * (MBL_Z_STEP);
@@ -4202,9 +4202,9 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; }
4202 4202
       }
4203 4203
       #if ENABLED(AUTO_BED_LEVELING_UBL)
4204 4204
         if (ubl.has_control_of_lcd_panel) {
4205
-          ubl.encoder_diff = encoderDiff;    // Make the encoder's rotation available to G29's Mesh Editor
4205
+          ubl.encoder_diff = encoderDiff;   // Make the encoder's rotation available to G29's Mesh Editor
4206 4206
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
4207
-                                            // wheel has not turned.
4207
+                                            // knob has not turned.
4208 4208
         }
4209 4209
       #endif
4210 4210
       lastEncoderBits = enc;

Loading…
Cancel
Save