浏览代码

Embed G26/G29 in ubl class, with enhancements

Scott Lahteine 8 年前
父节点
当前提交
85b967657e
共有 7 个文件被更改,包括 515 次插入484 次删除
  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 查看文件

135
   float code_value_axis_units(const AxisEnum axis);
135
   float code_value_axis_units(const AxisEnum axis);
136
   bool code_value_bool();
136
   bool code_value_bool();
137
   bool code_has_value();
137
   bool code_has_value();
138
-  void lcd_init();
139
-  void lcd_setstatuspgm(const char* const message, const uint8_t level);
140
   void sync_plan_position_e();
138
   void sync_plan_position_e();
141
   void chirp_at_user();
139
   void chirp_at_user();
142
 
140
 
143
   // Private functions
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
   static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
143
   static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
155
   float g26_e_axis_feedrate = 0.020,
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
   static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
147
   static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
160
                                      // retracts/recovers won't result in a bad state.
148
                                      // retracts/recovers won't result in a bad state.
161
 
149
 
162
   float valid_trig_angle(float);
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
     const float save_feedrate = feedrate_mm_s;
173
     const float save_feedrate = feedrate_mm_s;
184
     feedrate_mm_s = feed_rate;      // use specified feed rate
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
     feedrate_mm_s = save_feedrate;  // restore global feed rate
176
     feedrate_mm_s = save_feedrate;  // restore global feed rate
187
   }
177
   }
188
 
178
 
216
    * Used to interactively edit UBL's Mesh by placing the
206
    * Used to interactively edit UBL's Mesh by placing the
217
    * nozzle in a problem area and doing a G29 P4 R command.
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
     SERIAL_ECHOLNPGM("G26 command started.  Waiting for heater(s).");
210
     SERIAL_ECHOLNPGM("G26 command started.  Waiting for heater(s).");
221
     float tmp, start_angle, end_angle;
211
     float tmp, start_angle, end_angle;
222
     int   i, xi, yi;
212
     int   i, xi, yi;
237
     current_position[E_AXIS] = 0.0;
227
     current_position[E_AXIS] = 0.0;
238
     sync_plan_position_e();
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
      *  Bed is preheated
233
      *  Bed is preheated
255
 
245
 
256
     // Move nozzle to the specified height for the first layer
246
     // Move nozzle to the specified height for the first layer
257
     set_destination_to_current();
247
     set_destination_to_current();
258
-    destination[Z_AXIS] = layer_height;
248
+    destination[Z_AXIS] = g26_layer_height;
259
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
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
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
253
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
264
 
254
 
265
     /**
255
     /**
273
     }
263
     }
274
 
264
 
275
     do {
265
     do {
276
-      location = continue_with_closest
266
+      location = g26_continue_with_closest
277
         ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
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
       if (location.x_index >= 0 && location.y_index >= 0) {
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
         // If this mesh location is outside the printable_radius, skip it.
274
         // If this mesh location is outside the printable_radius, skip it.
285
 
275
 
288
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
278
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
289
         yi = location.y_index;
279
         yi = location.y_index;
290
 
280
 
291
-        if (ubl.g26_debug_flag) {
281
+        if (g26_debug_flag) {
292
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
282
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
293
           SERIAL_ECHOPAIR(", yi=", yi);
283
           SERIAL_ECHOPAIR(", yi=", yi);
294
           SERIAL_CHAR(')');
284
           SERIAL_CHAR(')');
344
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
334
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
345
           #endif
335
           #endif
346
 
336
 
347
-          //if (ubl.g26_debug_flag) {
337
+          //if (g26_debug_flag) {
348
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
338
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
349
           //  strcpy(seg_msg, "   segment: ");
339
           //  strcpy(seg_msg, "   segment: ");
350
           //  strcpy(seg_num, "    \n");
340
           //  strcpy(seg_num, "    \n");
355
           //  debug_current_and_destination(seg_msg);
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
         if (look_for_lines_to_connect())
351
         if (look_for_lines_to_connect())
374
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Raise the nozzle
364
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Raise the nozzle
375
     //debug_current_and_destination(PSTR("done doing Z-Raise."));
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
     //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;                        // Keep the nozzle where it is
369
     //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;                        // Keep the nozzle where it is
380
 
370
 
381
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
371
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
382
     //debug_current_and_destination(PSTR("done doing X/Y move."));
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
       #if HAS_TEMP_BED
377
       #if HAS_TEMP_BED
388
         thermalManager.setTargetBed(0);
378
         thermalManager.setTargetBed(0);
389
       #endif
379
       #endif
391
     }
381
     }
392
   }
382
   }
393
 
383
 
394
-
395
   float valid_trig_angle(float d) {
384
   float valid_trig_angle(float d) {
396
     while (d > 360.0) d -= 360.0;
385
     while (d > 360.0) d -= 360.0;
397
     while (d < 0.0) d += 360.0;
386
     while (d < 0.0) d += 360.0;
398
     return d;
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
     float closest = 99999.99;
391
     float closest = 99999.99;
403
     mesh_index_pair return_val;
392
     mesh_index_pair return_val;
404
 
393
 
407
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
396
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
408
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
397
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
409
         if (!is_bit_set(circle_flags, i, j)) {
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
           // Get the distance to this intersection
402
           // Get the distance to this intersection
414
           float f = HYPOT(X - mx, Y - my);
403
           float f = HYPOT(X - mx, Y - my);
417
           // to let us find the closest circle to the start position.
406
           // to let us find the closest circle to the start position.
418
           // But if this is not the case, add a small weighting to the
407
           // But if this is not the case, add a small weighting to the
419
           // distance calculation to help it choose a better place to continue.
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
           // Add in the specified amount of Random Noise to our search
411
           // Add in the specified amount of Random Noise to our search
423
           if (random_deviation > 1.0)
412
           if (random_deviation > 1.0)
436
     return return_val;
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
     float sx, sy, ex, ey;
429
     float sx, sy, ex, ey;
441
 
430
 
442
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
431
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
454
               // We found two circles that need a horizontal line to connect them
443
               // We found two circles that need a horizontal line to connect them
455
               // Print it!
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
               sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
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
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
451
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
463
 
452
 
464
               if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
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
                   SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
456
                   SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
468
                   SERIAL_ECHOPAIR(", sy=", sy);
457
                   SERIAL_ECHOPAIR(", sy=", sy);
469
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
458
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
473
                   //debug_current_and_destination(PSTR("Connecting horizontal line."));
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
               bit_set(horizontal_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if we skipped it
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
                 // We found two circles that need a vertical line to connect them
477
                 // We found two circles that need a vertical line to connect them
489
                 // Print it!
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
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
484
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
496
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
485
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
497
 
486
 
498
                 if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
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
                     SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
490
                     SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
502
                     SERIAL_ECHOPAIR(", sy=", sy);
491
                     SERIAL_ECHOPAIR(", sy=", sy);
503
                     SERIAL_ECHOPAIR(") -> (ex=", ex);
492
                     SERIAL_ECHOPAIR(") -> (ex=", ex);
506
                     SERIAL_EOL;
495
                     SERIAL_EOL;
507
                     debug_current_and_destination(PSTR("Connecting vertical line."));
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
                 bit_set(vertical_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if skipped
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
     return false;
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
     float feed_value;
511
     float feed_value;
523
     static float last_z = -999.99;
512
     static float last_z = -999.99;
524
 
513
 
540
     }
529
     }
541
 
530
 
542
     // Check if X or Y is involved in the movement.
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
     feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
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
     destination[X_AXIS] = x;
537
     destination[X_AXIS] = x;
549
     destination[Y_AXIS] = y;
538
     destination[Y_AXIS] = y;
556
 
545
 
557
   }
546
   }
558
 
547
 
559
-  void retract_filament(float where[XYZE]) {
548
+  void unified_bed_leveling::retract_filament(float where[XYZE]) {
560
     if (!g26_retracted) { // Only retract if we are not already retracted!
549
     if (!g26_retracted) { // Only retract if we are not already retracted!
561
       g26_retracted = true;
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
     if (g26_retracted) { // Only un-retract if we are retracted.
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
       g26_retracted = false;
558
       g26_retracted = false;
570
     }
559
     }
571
   }
560
   }
585
    * segment of a 'circle'.   The time this requires is very short and is easily saved by the other
574
    * segment of a 'circle'.   The time this requires is very short and is easily saved by the other
586
    * cases where the optimization comes into play.
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
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
578
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
590
                 dy_s = current_position[Y_AXIS] - sy,
579
                 dy_s = current_position[Y_AXIS] - sy,
591
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
580
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
613
 
602
 
614
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump
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
     move_to(ex, ey, ez, e_pos_delta);  // Get to the ending point with an appropriate amount of extrusion
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
    * parameters it made sense to turn them into static globals and get
613
    * parameters it made sense to turn them into static globals and get
625
    * this code out of sight of the main routine.
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
     if (code_seen('B')) {
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
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
635
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
647
         return UBL_ERR;
636
         return UBL_ERR;
648
       }
637
       }
649
     }
638
     }
650
 
639
 
651
     if (code_seen('L')) {
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
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
643
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
655
         return UBL_ERR;
644
         return UBL_ERR;
656
       }
645
       }
658
 
647
 
659
     if (code_seen('Q')) {
648
     if (code_seen('Q')) {
660
       if (code_has_value()) {
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
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
652
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
664
           return UBL_ERR;
653
           return UBL_ERR;
665
         }
654
         }
671
     }
660
     }
672
 
661
 
673
     if (code_seen('S')) {
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
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
665
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
677
         return UBL_ERR;
666
         return UBL_ERR;
678
       }
667
       }
680
 
669
 
681
     if (code_seen('P')) {
670
     if (code_seen('P')) {
682
       if (!code_has_value())
671
       if (!code_has_value())
683
-        prime_flag = -1;
672
+        g26_prime_flag = -1;
684
       else {
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
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
677
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
689
           return UBL_ERR;
678
           return UBL_ERR;
690
         }
679
         }
692
     }
681
     }
693
 
682
 
694
     if (code_seen('F')) {
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
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
686
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
698
         return UBL_ERR;
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
                                                                       // scale up or down the length needed to get the
691
                                                                       // scale up or down the length needed to get the
703
                                                                       // same volume of filament
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
     if (code_seen('H')) {
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
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
699
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
711
         return UBL_ERR;
700
         return UBL_ERR;
712
       }
701
       }
723
       return UBL_ERR;
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
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
718
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
730
       return UBL_ERR;
719
       return UBL_ERR;
731
     }
720
     }
733
     /**
722
     /**
734
      * Wait until all parameters are verified before altering the state!
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
     return UBL_OK;
727
     return UBL_OK;
739
   }
728
   }
740
 
729
 
741
-  bool exit_from_g26() {
730
+  bool unified_bed_leveling::exit_from_g26() {
742
     lcd_reset_alert_level();
731
     lcd_reset_alert_level();
743
     lcd_setstatuspgm(PSTR("Leaving G26"));
732
     lcd_setstatuspgm(PSTR("Leaving G26"));
744
     while (ubl_lcd_clicked()) idle();
733
     while (ubl_lcd_clicked()) idle();
749
    * Turn on the bed and nozzle heat and
738
    * Turn on the bed and nozzle heat and
750
    * wait for them to get up to temperature.
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
     millis_t next;
742
     millis_t next;
754
     #if HAS_TEMP_BED
743
     #if HAS_TEMP_BED
755
       #if ENABLED(ULTRA_LCD)
744
       #if ENABLED(ULTRA_LCD)
756
-        if (bed_temp > 25) {
745
+        if (g26_bed_temp > 25) {
757
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
746
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
758
           lcd_quick_feedback();
747
           lcd_quick_feedback();
759
       #endif
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
           next = millis() + 5000UL;
751
           next = millis() + 5000UL;
763
-          while (abs(thermalManager.degBed() - bed_temp) > 3) {
752
+          while (abs(thermalManager.degBed() - g26_bed_temp) > 3) {
764
             if (ubl_lcd_clicked()) return exit_from_g26();
753
             if (ubl_lcd_clicked()) return exit_from_g26();
765
             if (PENDING(millis(), next)) {
754
             if (PENDING(millis(), next)) {
766
               next = millis() + 5000UL;
755
               next = millis() + 5000UL;
776
     #endif
765
     #endif
777
 
766
 
778
     // Start heating the nozzle and wait for it to reach temperature.
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
       if (ubl_lcd_clicked()) return exit_from_g26();
770
       if (ubl_lcd_clicked()) return exit_from_g26();
782
       if (PENDING(millis(), next)) {
771
       if (PENDING(millis(), next)) {
783
         next = millis() + 5000UL;
772
         next = millis() + 5000UL;
798
   /**
787
   /**
799
    * Prime the nozzle if needed. Return true on error.
788
    * Prime the nozzle if needed. Return true on error.
800
    */
789
    */
801
-  bool prime_nozzle() {
790
+  bool unified_bed_leveling::prime_nozzle() {
802
     float Total_Prime = 0.0;
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
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
797
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
809
       chirp_at_user();
798
       chirp_at_user();
810
 
799
 
811
       set_destination_to_current();
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
       while (!ubl_lcd_clicked()) {
804
       while (!ubl_lcd_clicked()) {
816
         chirp_at_user();
805
         chirp_at_user();
838
         lcd_quick_feedback();
827
         lcd_quick_feedback();
839
       #endif
828
       #endif
840
 
829
 
841
-      ubl.has_control_of_lcd_panel = false;
830
+      has_control_of_lcd_panel = false;
842
 
831
 
843
     }
832
     }
844
     else {
833
     else {
847
         lcd_quick_feedback();
836
         lcd_quick_feedback();
848
       #endif
837
       #endif
849
       set_destination_to_current();
838
       set_destination_to_current();
850
-      destination[E_AXIS] += prime_length;
839
+      destination[E_AXIS] += g26_prime_length;
851
       G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
840
       G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
852
       stepper.synchronize();
841
       stepper.synchronize();
853
       set_destination_to_current();
842
       set_destination_to_current();

+ 6
- 6
Marlin/Marlin_main.cpp 查看文件

3416
       return;
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
     destination[Z_AXIS] = current_position[Z_AXIS]; //todo: perhaps add Z-move support?
3421
     destination[Z_AXIS] = current_position[Z_AXIS]; //todo: perhaps add Z-move support?
3422
     destination[E_AXIS] = current_position[E_AXIS];
3422
     destination[E_AXIS] = current_position[E_AXIS];
3423
 
3423
 
8704
     const bool hasZ = code_seen('Z'), hasQ = !hasZ && code_seen('Q');
8704
     const bool hasZ = code_seen('Z'), hasQ = !hasZ && code_seen('Q');
8705
 
8705
 
8706
     if (hasC) {
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
       ix = location.x_index;
8708
       ix = location.x_index;
8709
       iy = location.y_index;
8709
       iy = location.y_index;
8710
     }
8710
     }
11467
     #if ENABLED(AUTO_BED_LEVELING_UBL)
11467
     #if ENABLED(AUTO_BED_LEVELING_UBL)
11468
       const float fr_scaled = MMS_SCALED(feedrate_mm_s);
11468
       const float fr_scaled = MMS_SCALED(feedrate_mm_s);
11469
       if (ubl.state.active) {
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
         return true;
11471
         return true;
11472
       }
11472
       }
11473
       else
11473
       else
11612
   if (
11612
   if (
11613
     #if IS_KINEMATIC
11613
     #if IS_KINEMATIC
11614
       #if UBL_DELTA
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
       #else
11616
       #else
11617
         prepare_kinematic_move_to(destination)
11617
         prepare_kinematic_move_to(destination)
11618
       #endif
11618
       #endif
11619
     #elif ENABLED(DUAL_X_CARRIAGE)
11619
     #elif ENABLED(DUAL_X_CARRIAGE)
11620
       prepare_move_to_destination_dualx()
11620
       prepare_move_to_destination_dualx()
11621
     #elif UBL_DELTA // will work for CARTESIAN too (smaller segments follow mesh more closely)
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
     #else
11623
     #else
11624
       prepare_move_to_destination_cartesian()
11624
       prepare_move_to_destination_cartesian()
11625
     #endif
11625
     #endif

+ 1
- 1
Marlin/fastio.h 查看文件

58
 #endif
58
 #endif
59
 
59
 
60
 #ifndef _BV
60
 #ifndef _BV
61
-  #define _BV(PIN) (1 << PIN)
61
+  #define _BV(PIN) (1UL << PIN)
62
 #endif
62
 #endif
63
 
63
 
64
 /**
64
 /**

+ 4
- 4
Marlin/ubl.cpp 查看文件

69
 
69
 
70
   // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
70
   // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
71
   // until determinism prevails
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
   bool unified_bed_leveling::g26_debug_flag = false,
75
   bool unified_bed_leveling::g26_debug_flag = false,
76
        unified_bed_leveling::has_control_of_lcd_panel = false;
76
        unified_bed_leveling::has_control_of_lcd_panel = false;
117
       SERIAL_EOL;
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
     for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
123
     for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
124
       for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
124
       for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {

+ 106
- 55
Marlin/ubl.h 查看文件

53
   // ubl_motion.cpp
53
   // ubl_motion.cpp
54
 
54
 
55
   void debug_current_and_destination(const char * const title);
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
   // ubl_G29.cpp
57
   // ubl_G29.cpp
60
 
58
 
61
   enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
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
   // External references
61
   // External references
74
 
62
 
75
   char *ftostr43sign(const float&, char);
63
   char *ftostr43sign(const float&, char);
76
   bool ubl_lcd_clicked();
64
   bool ubl_lcd_clicked();
77
   void home_all_axes();
65
   void home_all_axes();
78
-  void gcode_G26();
79
-  void gcode_G29();
80
 
66
 
81
   extern uint8_t ubl_cnt;
67
   extern uint8_t ubl_cnt;
82
 
68
 
101
 
87
 
102
       static float last_specified_z;
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
     public:
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
       static ubl_state state;
166
       static ubl_state state;
126
 
167
 
128
 
169
 
129
       // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
170
       // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
130
       // until determinism prevails
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
                                 UBL_MESH_MIN_X +  0 * (MESH_X_DIST), UBL_MESH_MIN_X +  1 * (MESH_X_DIST),
173
                                 UBL_MESH_MIN_X +  0 * (MESH_X_DIST), UBL_MESH_MIN_X +  1 * (MESH_X_DIST),
133
                                 UBL_MESH_MIN_X +  2 * (MESH_X_DIST), UBL_MESH_MIN_X +  3 * (MESH_X_DIST),
174
                                 UBL_MESH_MIN_X +  2 * (MESH_X_DIST), UBL_MESH_MIN_X +  3 * (MESH_X_DIST),
134
                                 UBL_MESH_MIN_X +  4 * (MESH_X_DIST), UBL_MESH_MIN_X +  5 * (MESH_X_DIST),
175
                                 UBL_MESH_MIN_X +  4 * (MESH_X_DIST), UBL_MESH_MIN_X +  5 * (MESH_X_DIST),
139
                                 UBL_MESH_MIN_X + 14 * (MESH_X_DIST), UBL_MESH_MIN_X + 15 * (MESH_X_DIST)
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
                                 UBL_MESH_MIN_Y +  0 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  1 * (MESH_Y_DIST),
184
                                 UBL_MESH_MIN_Y +  0 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  1 * (MESH_Y_DIST),
144
                                 UBL_MESH_MIN_Y +  2 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  3 * (MESH_Y_DIST),
185
                                 UBL_MESH_MIN_Y +  2 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  3 * (MESH_Y_DIST),
145
                                 UBL_MESH_MIN_Y +  4 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  5 * (MESH_Y_DIST),
186
                                 UBL_MESH_MIN_Y +  4 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  5 * (MESH_Y_DIST),
156
 
197
 
157
       unified_bed_leveling();
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
         const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
203
         const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
163
         return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1);   // -1 is appropriate if we want all movement to the X_MAX
204
         return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1);   // -1 is appropriate if we want all movement to the X_MAX
164
       }                                                     // position. But with this defined this way, it is possible
205
       }                                                     // position. But with this defined this way, it is possible
165
                                                             // to extrapolate off of this point even further out. Probably
206
                                                             // to extrapolate off of this point even further out. Probably
166
                                                             // that is OK because something else should be keeping that from
207
                                                             // that is OK because something else should be keeping that from
167
                                                             // happening and should not be worried about at this level.
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
         const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
210
         const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
170
         return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
211
         return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
171
       }                                                     // position. But with this defined this way, it is possible
212
       }                                                     // position. But with this defined this way, it is possible
173
                                                             // that is OK because something else should be keeping that from
214
                                                             // that is OK because something else should be keeping that from
174
                                                             // happening and should not be worried about at this level.
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
         const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
218
         const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
178
         return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
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
         const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
223
         const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
183
         return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
224
         return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
184
       }
225
       }
198
        *  It is fairly expensive with its 4 floating point additions and 2 floating point
239
        *  It is fairly expensive with its 4 floating point additions and 2 floating point
199
        *  multiplications.
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
         return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
243
         return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
203
       }
244
       }
204
 
245
 
206
        * z_correction_for_x_on_horizontal_mesh_line is an optimization for
247
        * z_correction_for_x_on_horizontal_mesh_line is an optimization for
207
        * the rare occasion when a point lies exactly on a Mesh line (denoted by index yi).
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
         if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
251
         if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
211
           serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") );
252
           serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") );
212
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0);
253
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0);
217
           return NAN;
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
                     z1 = z_values[x1_i][yi];
262
                     z1 = z_values[x1_i][yi];
222
 
263
 
223
         return z1 + xratio * (z_values[x1_i + 1][yi] - z1);
264
         return z1 + xratio * (z_values[x1_i + 1][yi] - z1);
226
       //
267
       //
227
       // See comments above for z_correction_for_x_on_horizontal_mesh_line
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
         if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) {
271
         if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) {
231
           serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") );
272
           serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") );
232
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0);
273
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0);
237
           return NAN;
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
                     z1 = z_values[xi][y1_i];
282
                     z1 = z_values[xi][y1_i];
242
 
283
 
243
         return z1 + yratio * (z_values[xi][y1_i + 1] - z1);
284
         return z1 + yratio * (z_values[xi][y1_i + 1] - z1);
249
        * Z-Height at both ends. Then it does a linear interpolation of these heights based
290
        * Z-Height at both ends. Then it does a linear interpolation of these heights based
250
        * on the Y position within the cell.
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
         const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)),
294
         const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)),
254
                      cy = get_cell_index_y(RAW_Y_POSITION(ly0));
295
                      cy = get_cell_index_y(RAW_Y_POSITION(ly0));
255
 
296
 
268
         }
309
         }
269
 
310
 
270
         const float z1 = calc_z0(RAW_X_POSITION(lx0),
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
         const float z2 = calc_z0(RAW_X_POSITION(lx0),
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
         float z0 = calc_z0(RAW_Y_POSITION(ly0),
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
         #if ENABLED(DEBUG_LEVELING_FEATURE)
323
         #if ENABLED(DEBUG_LEVELING_FEATURE)
283
           if (DEBUGGING(MESH_ADJUST)) {
324
           if (DEBUGGING(MESH_ADJUST)) {
324
        *  Returns 0.0 if Z is past the specified 'Fade Height'.
365
        *  Returns 0.0 if Z is past the specified 'Fade Height'.
325
        */
366
        */
326
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
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
           if (planner.z_fade_height == 0.0) return 1.0;
369
           if (planner.z_fade_height == 0.0) return 1.0;
329
           static float fade_scaling_factor = 1.0;
370
           static float fade_scaling_factor = 1.0;
330
           const float rz = RAW_Z_POSITION(lz);
371
           const float rz = RAW_Z_POSITION(lz);
338
           return fade_scaling_factor;
379
           return fade_scaling_factor;
339
         }
380
         }
340
       #else
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
       #endif
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
   }; // class unified_bed_leveling
391
   }; // class unified_bed_leveling
347
 
392
 
348
   extern unified_bed_leveling ubl;
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
 #endif // AUTO_BED_LEVELING_UBL
401
 #endif // AUTO_BED_LEVELING_UBL
351
 #endif // UNIFIED_BED_LEVELING_H
402
 #endif // UNIFIED_BED_LEVELING_H

+ 224
- 233
Marlin/ubl_G29.cpp
文件差异内容过多而无法显示
查看文件


+ 64
- 64
Marlin/ubl_motion.cpp 查看文件

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
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
90
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
91
      * as possible to determine if this is the case. If this move is within the same cell, we will
91
      * as possible to determine if this is the case. If this move is within the same cell, we will
104
                   destination[E_AXIS]
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
       SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]);
114
       SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]);
115
       SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]);
115
       SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]);
116
       SERIAL_ECHOPAIR(", ee=", end[E_AXIS]);
116
       SERIAL_ECHOPAIR(", ee=", end[E_AXIS]);
117
       SERIAL_CHAR(')');
117
       SERIAL_CHAR(')');
118
       SERIAL_EOL;
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
     if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell,
122
     if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell,
132
         // Note: There is no Z Correction in this case. We are off the grid and don't know what
132
         // Note: There is no Z Correction in this case. We are off the grid and don't know what
133
         // a reasonable correction would be.
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
         set_current_to_destination();
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
         return;
141
         return;
142
       }
142
       }
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.
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
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
161
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
162
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
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
       float z0 = z1 + (z2 - z1) * yratio;
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
        * If part of the Mesh is undefined, it will show up as NAN
171
        * If part of the Mesh is undefined, it will show up as NAN
176
        */
176
        */
177
       if (isnan(z0)) z0 = 0.0;
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
       set_current_to_destination();
184
       set_current_to_destination();
185
       return;
185
       return;
240
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
240
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
241
       while (current_yi != cell_dest_yi + down_flag) {
241
       while (current_yi != cell_dest_yi + down_flag) {
242
         current_yi += dyi;
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
          * if the slope of the line is infinite, we won't do the calculations
246
          * if the slope of the line is infinite, we won't do the calculations
249
          */
249
          */
250
         const float x = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m;
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
          * If part of the Mesh is undefined, it will show up as NAN
257
          * If part of the Mesh is undefined, it will show up as NAN
262
          */
262
          */
263
         if (isnan(z0)) z0 = 0.0;
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
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
268
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
281
             z_position = end[Z_AXIS];
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
         } //else printf("FIRST MOVE PRUNED  ");
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
       // 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.
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
                                 // edge of this cell for the first move.
311
                                 // edge of this cell for the first move.
312
       while (current_xi != cell_dest_xi + left_flag) {
312
       while (current_xi != cell_dest_xi + left_flag) {
313
         current_xi += dxi;
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
                     y = m * next_mesh_line_x + c;   // Calculate Y at the next X mesh line
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
          * If part of the Mesh is undefined, it will show up as NAN
322
          * If part of the Mesh is undefined, it will show up as NAN
327
          */
327
          */
328
         if (isnan(z0)) z0 = 0.0;
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
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
333
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
346
             z_position = end[Z_AXIS];
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
         } //else printf("FIRST MOVE PRUNED  ");
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
       if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
356
       if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
357
         goto FINAL_MOVE;
357
         goto FINAL_MOVE;
377
 
377
 
378
     while (xi_cnt > 0 || yi_cnt > 0) {
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
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
382
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
383
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
383
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
384
                                                   // (No need to worry about m being zero.
384
                                                   // (No need to worry about m being zero.
387
 
387
 
388
       if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
388
       if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
389
         // Yes!  Crossing a Y Mesh Line next
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
          * If part of the Mesh is undefined, it will show up as NAN
395
          * If part of the Mesh is undefined, it will show up as NAN
409
           e_position = end[E_AXIS];
409
           e_position = end[E_AXIS];
410
           z_position = end[Z_AXIS];
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
         current_yi += dyi;
413
         current_yi += dyi;
414
         yi_cnt--;
414
         yi_cnt--;
415
       }
415
       }
416
       else {
416
       else {
417
         // Yes!  Crossing a X Mesh Line next
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
          * If part of the Mesh is undefined, it will show up as NAN
423
          * If part of the Mesh is undefined, it will show up as NAN
438
           z_position = end[Z_AXIS];
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
         current_xi += dxi;
442
         current_xi += dxi;
443
         xi_cnt--;
443
         xi_cnt--;
444
       }
444
       }
446
       if (xi_cnt < 0 || yi_cnt < 0) break; // we've gone too far, so exit the loop and move on to FINAL_MOVE
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
     if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
452
     if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
453
       goto FINAL_MOVE;
453
       goto FINAL_MOVE;
502
      * Returns true if the caller did NOT update current_position, otherwise false.
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
       if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS]))  // fail if moving outside reachable boundary
507
       if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS]))  // fail if moving outside reachable boundary
508
         return true; // did not move, so current_position still accurate
508
         return true; // did not move, so current_position still accurate
554
 
554
 
555
       // Only compute leveling per segment if ubl active and target below z_fade_height.
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
         float seg_dest[XYZE];                   // per-segment destination,
561
         float seg_dest[XYZE];                   // per-segment destination,
562
         COPY_XYZE(seg_dest, current_position);  // starting from current position
562
         COPY_XYZE(seg_dest, current_position);  // starting from current position
579
       // Otherwise perform per-segment leveling
579
       // Otherwise perform per-segment leveling
580
 
580
 
581
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
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
       #endif
583
       #endif
584
 
584
 
585
       float seg_dest[XYZE];  // per-segment destination, initialize to first segment
585
       float seg_dest[XYZE];  // per-segment destination, initialize to first segment
591
       float rx = RAW_X_POSITION(seg_dest[X_AXIS]),  // assume raw vs logical coordinates shifted but not scaled.
591
       float rx = RAW_X_POSITION(seg_dest[X_AXIS]),  // assume raw vs logical coordinates shifted but not scaled.
592
             ry = RAW_Y_POSITION(seg_dest[Y_AXIS]);
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
         // Compute mesh cell invariants that remain constant for all segments within cell.
596
         // Compute mesh cell invariants that remain constant for all segments within cell.
597
         // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter)
597
         // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter)
606
         cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
606
         cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
607
         cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
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
         float cx = rx - x0,   // cell-relative x
614
         float cx = rx - x0,   // cell-relative x
615
               cy = ry - y0,   // cell-relative y
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
         if (isnan(z_x1y0)) z_x1y0 = 0;              //   should refuse if any invalid mesh points
622
         if (isnan(z_x1y0)) z_x1y0 = 0;              //   should refuse if any invalid mesh points
623
         if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
623
         if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
624
         if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
624
         if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
642
         const float z_sxy0 = z_xmy0 * dx_seg,                                     // per-segment adjustment to z_cxy0
642
         const float z_sxy0 = z_xmy0 * dx_seg,                                     // per-segment adjustment to z_cxy0
643
                     z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * dx_seg;  // per-segment adjustment to z_cxym
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
           float z_cxcy = z_cxy0 + z_cxym * cy;      // interpolated mesh z height along cx at cy
647
           float z_cxcy = z_cxy0 + z_cxym * cy;      // interpolated mesh z height along cx at cy
648
 
648
 
650
             z_cxcy *= fade_scaling_factor;          // apply fade factor to interpolated mesh height
650
             z_cxcy *= fade_scaling_factor;          // apply fade factor to interpolated mesh height
651
           #endif
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
           if (--segments == 0) {                    // if this is last segment, use ltarget for exact
655
           if (--segments == 0) {                    // if this is last segment, use ltarget for exact
656
             COPY_XYZE(seg_dest, ltarget);
656
             COPY_XYZE(seg_dest, ltarget);
681
           z_cxy0 += z_sxy0;   // adjust z_cxy0 by per-segment z_sxy0
681
           z_cxy0 += z_sxy0;   // adjust z_cxy0 by per-segment z_sxy0
682
           z_cxym += z_sxym;   // adjust z_cxym by per-segment z_sxym
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
   #endif // UBL_DELTA
688
   #endif // UBL_DELTA
689
 
689
 

正在加载...
取消
保存