Browse Source

Embed G26/G29 in ubl class, with enhancements

Scott Lahteine 7 years ago
parent
commit
85b967657e
7 changed files with 515 additions and 484 deletions
  1. 110
    121
      Marlin/G26_Mesh_Validation_Tool.cpp
  2. 6
    6
      Marlin/Marlin_main.cpp
  3. 1
    1
      Marlin/fastio.h
  4. 4
    4
      Marlin/ubl.cpp
  5. 106
    55
      Marlin/ubl.h
  6. 224
    233
      Marlin/ubl_G29.cpp
  7. 64
    64
      Marlin/ubl_motion.cpp

+ 110
- 121
Marlin/G26_Mesh_Validation_Tool.cpp View File

@@ -135,54 +135,44 @@
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
 
@@ -216,7 +206,7 @@
216 206
    * Used to interactively edit UBL's Mesh by placing the
217 207
    * nozzle in a problem area and doing a G29 P4 R command.
218 208
    */
219
-  void gcode_G26() {
209
+  void unified_bed_leveling::G26() {
220 210
     SERIAL_ECHOLNPGM("G26 command started.  Waiting for heater(s).");
221 211
     float tmp, start_angle, end_angle;
222 212
     int   i, xi, yi;
@@ -237,7 +227,7 @@
237 227
     current_position[E_AXIS] = 0.0;
238 228
     sync_plan_position_e();
239 229
 
240
-    if (prime_flag && prime_nozzle()) goto LEAVE;
230
+    if (g26_prime_flag && prime_nozzle()) goto LEAVE;
241 231
 
242 232
     /**
243 233
      *  Bed is preheated
@@ -255,11 +245,11 @@
255 245
 
256 246
     // Move nozzle to the specified height for the first layer
257 247
     set_destination_to_current();
258
-    destination[Z_AXIS] = layer_height;
248
+    destination[Z_AXIS] = g26_layer_height;
259 249
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
260
-    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);
261 251
 
262
-    ubl.has_control_of_lcd_panel = true;
252
+    has_control_of_lcd_panel = true;
263 253
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
264 254
 
265 255
     /**
@@ -273,13 +263,13 @@
273 263
     }
274 264
 
275 265
     do {
276
-      location = continue_with_closest
266
+      location = g26_continue_with_closest
277 267
         ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
278
-        : 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.
279 269
 
280 270
       if (location.x_index >= 0 && location.y_index >= 0) {
281
-        const float circle_x = pgm_read_float(&ubl.mesh_index_to_xpos[location.x_index]),
282
-                    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);
283 273
 
284 274
         // If this mesh location is outside the printable_radius, skip it.
285 275
 
@@ -288,7 +278,7 @@
288 278
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
289 279
         yi = location.y_index;
290 280
 
291
-        if (ubl.g26_debug_flag) {
281
+        if (g26_debug_flag) {
292 282
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
293 283
           SERIAL_ECHOPAIR(", yi=", yi);
294 284
           SERIAL_CHAR(')');
@@ -344,7 +334,7 @@
344 334
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
345 335
           #endif
346 336
 
347
-          //if (ubl.g26_debug_flag) {
337
+          //if (g26_debug_flag) {
348 338
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
349 339
           //  strcpy(seg_msg, "   segment: ");
350 340
           //  strcpy(seg_num, "    \n");
@@ -355,7 +345,7 @@
355 345
           //  debug_current_and_destination(seg_msg);
356 346
           //}
357 347
 
358
-          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);
359 349
 
360 350
         }
361 351
         if (look_for_lines_to_connect())
@@ -374,16 +364,16 @@
374 364
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Raise the nozzle
375 365
     //debug_current_and_destination(PSTR("done doing Z-Raise."));
376 366
 
377
-    destination[X_AXIS] = x_pos;                                               // Move back to the starting position
378
-    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;
379 369
     //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;                        // Keep the nozzle where it is
380 370
 
381 371
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
382 372
     //debug_current_and_destination(PSTR("done doing X/Y move."));
383 373
 
384
-    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!
385 375
 
386
-    if (!keep_heaters_on) {
376
+    if (!g26_keep_heaters_on) {
387 377
       #if HAS_TEMP_BED
388 378
         thermalManager.setTargetBed(0);
389 379
       #endif
@@ -391,14 +381,13 @@
391 381
     }
392 382
   }
393 383
 
394
-
395 384
   float valid_trig_angle(float d) {
396 385
     while (d > 360.0) d -= 360.0;
397 386
     while (d < 0.0) d += 360.0;
398 387
     return d;
399 388
   }
400 389
 
401
-  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) {
402 391
     float closest = 99999.99;
403 392
     mesh_index_pair return_val;
404 393
 
@@ -407,8 +396,8 @@
407 396
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
408 397
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
409 398
         if (!is_bit_set(circle_flags, i, j)) {
410
-          const float mx = pgm_read_float(&ubl.mesh_index_to_xpos[i]),  // We found a circle that needs to be printed
411
-                      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);
412 401
 
413 402
           // Get the distance to this intersection
414 403
           float f = HYPOT(X - mx, Y - my);
@@ -417,7 +406,7 @@
417 406
           // to let us find the closest circle to the start position.
418 407
           // But if this is not the case, add a small weighting to the
419 408
           // distance calculation to help it choose a better place to continue.
420
-          f += HYPOT(x_pos - mx, y_pos - my) / 15.0;
409
+          f += HYPOT(g26_x_pos - mx, g26_y_pos - my) / 15.0;
421 410
 
422 411
           // Add in the specified amount of Random Noise to our search
423 412
           if (random_deviation > 1.0)
@@ -436,7 +425,7 @@
436 425
     return return_val;
437 426
   }
438 427
 
439
-  bool look_for_lines_to_connect() {
428
+  bool unified_bed_leveling::look_for_lines_to_connect() {
440 429
     float sx, sy, ex, ey;
441 430
 
442 431
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
@@ -454,16 +443,16 @@
454 443
               // We found two circles that need a horizontal line to connect them
455 444
               // Print it!
456 445
               //
457
-              sx = pgm_read_float(&ubl.mesh_index_to_xpos[  i  ]) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
458
-              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
459 448
 
460 449
               sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
461
-              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);
462 451
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
463 452
 
464 453
               if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
465 454
 
466
-                if (ubl.g26_debug_flag) {
455
+                if (g26_debug_flag) {
467 456
                   SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
468 457
                   SERIAL_ECHOPAIR(", sy=", sy);
469 458
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
@@ -473,7 +462,7 @@
473 462
                   //debug_current_and_destination(PSTR("Connecting horizontal line."));
474 463
                 }
475 464
 
476
-                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);
477 466
               }
478 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
479 468
             }
@@ -488,16 +477,16 @@
488 477
                 // We found two circles that need a vertical line to connect them
489 478
                 // Print it!
490 479
                 //
491
-                sy = pgm_read_float(&ubl.mesh_index_to_ypos[  j  ]) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
492
-                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
493 482
 
494
-                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);
495 484
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
496 485
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
497 486
 
498 487
                 if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
499 488
 
500
-                  if (ubl.g26_debug_flag) {
489
+                  if (g26_debug_flag) {
501 490
                     SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
502 491
                     SERIAL_ECHOPAIR(", sy=", sy);
503 492
                     SERIAL_ECHOPAIR(") -> (ex=", ex);
@@ -506,7 +495,7 @@
506 495
                     SERIAL_EOL;
507 496
                     debug_current_and_destination(PSTR("Connecting vertical line."));
508 497
                   }
509
-                  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);
510 499
                 }
511 500
                 bit_set(vertical_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if skipped
512 501
               }
@@ -518,7 +507,7 @@
518 507
     return false;
519 508
   }
520 509
 
521
-  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) {
522 511
     float feed_value;
523 512
     static float last_z = -999.99;
524 513
 
@@ -540,10 +529,10 @@
540 529
     }
541 530
 
542 531
     // Check if X or Y is involved in the movement.
543
-    // Yes: a 'normal' movement. No: a retract() or un_retract()
532
+    // Yes: a 'normal' movement. No: a retract() or recover()
544 533
     feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
545 534
 
546
-    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);
547 536
 
548 537
     destination[X_AXIS] = x;
549 538
     destination[Y_AXIS] = y;
@@ -556,16 +545,16 @@
556 545
 
557 546
   }
558 547
 
559
-  void retract_filament(float where[XYZE]) {
548
+  void unified_bed_leveling::retract_filament(float where[XYZE]) {
560 549
     if (!g26_retracted) { // Only retract if we are not already retracted!
561 550
       g26_retracted = true;
562
-      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);
563 552
     }
564 553
   }
565 554
 
566
-  void un_retract_filament(float where[XYZE]) {
555
+  void unified_bed_leveling::recover_filament(float where[XYZE]) {
567 556
     if (g26_retracted) { // Only un-retract if we are retracted.
568
-      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);
569 558
       g26_retracted = false;
570 559
     }
571 560
   }
@@ -585,7 +574,7 @@
585 574
    * segment of a 'circle'.   The time this requires is very short and is easily saved by the other
586 575
    * cases where the optimization comes into play.
587 576
    */
588
-  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) {
589 578
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
590 579
                 dy_s = current_position[Y_AXIS] - sy,
591 580
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
@@ -613,9 +602,9 @@
613 602
 
614 603
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump
615 604
 
616
-    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;
617 606
 
618
-    un_retract_filament(destination);
607
+    recover_filament(destination);
619 608
     move_to(ex, ey, ez, e_pos_delta);  // Get to the ending point with an appropriate amount of extrusion
620 609
   }
621 610
 
@@ -624,33 +613,33 @@
624 613
    * parameters it made sense to turn them into static globals and get
625 614
    * this code out of sight of the main routine.
626 615
    */
627
-  bool parse_G26_parameters() {
628
-
629
-    extrusion_multiplier  = EXTRUSION_MULTIPLIER;
630
-    retraction_multiplier = RETRACTION_MULTIPLIER;
631
-    nozzle                = NOZZLE;
632
-    filament_diameter     = FILAMENT;
633
-    layer_height          = LAYER_HEIGHT;
634
-    prime_length          = PRIME_LENGTH;
635
-    bed_temp              = BED_TEMP;
636
-    hotend_temp           = HOTEND_TEMP;
637
-    prime_flag            = 0;
638
-
639
-    ooze_amount           = code_seen('O') && code_has_value() ? code_value_linear_units() : OOZE_AMOUNT;
640
-    keep_heaters_on       = code_seen('K') && code_value_bool();
641
-    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();
642 631
 
643 632
     if (code_seen('B')) {
644
-      bed_temp = code_value_temp_abs();
645
-      if (!WITHIN(bed_temp, 15, 140)) {
633
+      g26_bed_temp = code_value_temp_abs();
634
+      if (!WITHIN(g26_bed_temp, 15, 140)) {
646 635
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
647 636
         return UBL_ERR;
648 637
       }
649 638
     }
650 639
 
651 640
     if (code_seen('L')) {
652
-      layer_height = code_value_linear_units();
653
-      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)) {
654 643
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
655 644
         return UBL_ERR;
656 645
       }
@@ -658,8 +647,8 @@
658 647
 
659 648
     if (code_seen('Q')) {
660 649
       if (code_has_value()) {
661
-        retraction_multiplier = code_value_float();
662
-        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)) {
663 652
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
664 653
           return UBL_ERR;
665 654
         }
@@ -671,8 +660,8 @@
671 660
     }
672 661
 
673 662
     if (code_seen('S')) {
674
-      nozzle = code_value_float();
675
-      if (!WITHIN(nozzle, 0.1, 1.0)) {
663
+      g26_nozzle = code_value_float();
664
+      if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
676 665
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
677 666
         return UBL_ERR;
678 667
       }
@@ -680,11 +669,11 @@
680 669
 
681 670
     if (code_seen('P')) {
682 671
       if (!code_has_value())
683
-        prime_flag = -1;
672
+        g26_prime_flag = -1;
684 673
       else {
685
-        prime_flag++;
686
-        prime_length = code_value_linear_units();
687
-        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)) {
688 677
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
689 678
           return UBL_ERR;
690 679
         }
@@ -692,21 +681,21 @@
692 681
     }
693 682
 
694 683
     if (code_seen('F')) {
695
-      filament_diameter = code_value_linear_units();
696
-      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)) {
697 686
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
698 687
         return UBL_ERR;
699 688
       }
700 689
     }
701
-    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
702 691
                                                                       // scale up or down the length needed to get the
703 692
                                                                       // same volume of filament
704 693
 
705
-    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
706 695
 
707 696
     if (code_seen('H')) {
708
-      hotend_temp = code_value_temp_abs();
709
-      if (!WITHIN(hotend_temp, 165, 280)) {
697
+      g26_hotend_temp = code_value_temp_abs();
698
+      if (!WITHIN(g26_hotend_temp, 165, 280)) {
710 699
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
711 700
         return UBL_ERR;
712 701
       }
@@ -723,9 +712,9 @@
723 712
       return UBL_ERR;
724 713
     }
725 714
 
726
-    x_pos = code_seen('X') ? code_value_linear_units() : current_position[X_AXIS];
727
-    y_pos = code_seen('Y') ? code_value_linear_units() : current_position[Y_AXIS];
728
-    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)) {
729 718
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
730 719
       return UBL_ERR;
731 720
     }
@@ -733,12 +722,12 @@
733 722
     /**
734 723
      * Wait until all parameters are verified before altering the state!
735 724
      */
736
-    ubl.state.active = !code_seen('D');
725
+    state.active = !code_seen('D');
737 726
 
738 727
     return UBL_OK;
739 728
   }
740 729
 
741
-  bool exit_from_g26() {
730
+  bool unified_bed_leveling::exit_from_g26() {
742 731
     lcd_reset_alert_level();
743 732
     lcd_setstatuspgm(PSTR("Leaving G26"));
744 733
     while (ubl_lcd_clicked()) idle();
@@ -749,18 +738,18 @@
749 738
    * Turn on the bed and nozzle heat and
750 739
    * wait for them to get up to temperature.
751 740
    */
752
-  bool turn_on_heaters() {
741
+  bool unified_bed_leveling::turn_on_heaters() {
753 742
     millis_t next;
754 743
     #if HAS_TEMP_BED
755 744
       #if ENABLED(ULTRA_LCD)
756
-        if (bed_temp > 25) {
745
+        if (g26_bed_temp > 25) {
757 746
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
758 747
           lcd_quick_feedback();
759 748
       #endif
760
-          ubl.has_control_of_lcd_panel = true;
761
-          thermalManager.setTargetBed(bed_temp);
749
+          has_control_of_lcd_panel = true;
750
+          thermalManager.setTargetBed(g26_bed_temp);
762 751
           next = millis() + 5000UL;
763
-          while (abs(thermalManager.degBed() - bed_temp) > 3) {
752
+          while (abs(thermalManager.degBed() - g26_bed_temp) > 3) {
764 753
             if (ubl_lcd_clicked()) return exit_from_g26();
765 754
             if (PENDING(millis(), next)) {
766 755
               next = millis() + 5000UL;
@@ -776,8 +765,8 @@
776 765
     #endif
777 766
 
778 767
     // Start heating the nozzle and wait for it to reach temperature.
779
-    thermalManager.setTargetHotend(hotend_temp, 0);
780
-    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) {
781 770
       if (ubl_lcd_clicked()) return exit_from_g26();
782 771
       if (PENDING(millis(), next)) {
783 772
         next = millis() + 5000UL;
@@ -798,19 +787,19 @@
798 787
   /**
799 788
    * Prime the nozzle if needed. Return true on error.
800 789
    */
801
-  bool prime_nozzle() {
790
+  bool unified_bed_leveling::prime_nozzle() {
802 791
     float Total_Prime = 0.0;
803 792
 
804
-    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
805 794
 
806
-      ubl.has_control_of_lcd_panel = true;
795
+      has_control_of_lcd_panel = true;
807 796
 
808 797
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
809 798
       chirp_at_user();
810 799
 
811 800
       set_destination_to_current();
812 801
 
813
-      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().
814 803
 
815 804
       while (!ubl_lcd_clicked()) {
816 805
         chirp_at_user();
@@ -838,7 +827,7 @@
838 827
         lcd_quick_feedback();
839 828
       #endif
840 829
 
841
-      ubl.has_control_of_lcd_panel = false;
830
+      has_control_of_lcd_panel = false;
842 831
 
843 832
     }
844 833
     else {
@@ -847,7 +836,7 @@
847 836
         lcd_quick_feedback();
848 837
       #endif
849 838
       set_destination_to_current();
850
-      destination[E_AXIS] += prime_length;
839
+      destination[E_AXIS] += g26_prime_length;
851 840
       G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
852 841
       stepper.synchronize();
853 842
       set_destination_to_current();

+ 6
- 6
Marlin/Marlin_main.cpp View File

@@ -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
 
@@ -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/fastio.h View File

@@ -58,7 +58,7 @@
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
 /**

+ 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

+ 224
- 233
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
 

Loading…
Cancel
Save