|
@@ -8698,7 +8698,68 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
8698
|
8698
|
mesh_line_to_destination(fr_mm_s, x_splits, y_splits);
|
8699
|
8699
|
}
|
8700
|
8700
|
|
8701
|
|
-#endif // MESH_BED_LEVELING
|
|
8701
|
+#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
|
8702
|
+
|
|
8703
|
+ /**
|
|
8704
|
+ * Prepare a mesh-leveled linear move in a Cartesian setup,
|
|
8705
|
+ * splitting the move where it crosses mesh borders.
|
|
8706
|
+ */
|
|
8707
|
+ void bilinear_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xff, uint8_t y_splits = 0xff) {
|
|
8708
|
+ int cx1 = RAW_CURRENT_POSITION(X_AXIS) / bilinear_grid_spacing[X_AXIS],
|
|
8709
|
+ cy1 = RAW_CURRENT_POSITION(Y_AXIS) / bilinear_grid_spacing[Y_AXIS],
|
|
8710
|
+ cx2 = RAW_X_POSITION(destination[X_AXIS]) / bilinear_grid_spacing[X_AXIS],
|
|
8711
|
+ cy2 = RAW_Y_POSITION(destination[Y_AXIS]) / bilinear_grid_spacing[Y_AXIS];
|
|
8712
|
+ NOMORE(cx1, ABL_GRID_POINTS_X - 2);
|
|
8713
|
+ NOMORE(cy1, ABL_GRID_POINTS_Y - 2);
|
|
8714
|
+ NOMORE(cx2, ABL_GRID_POINTS_X - 2);
|
|
8715
|
+ NOMORE(cy2, ABL_GRID_POINTS_Y - 2);
|
|
8716
|
+
|
|
8717
|
+ if (cx1 == cx2 && cy1 == cy2) {
|
|
8718
|
+ // Start and end on same mesh square
|
|
8719
|
+ line_to_destination(fr_mm_s);
|
|
8720
|
+ set_current_to_destination();
|
|
8721
|
+ return;
|
|
8722
|
+ }
|
|
8723
|
+
|
|
8724
|
+ #define LINE_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist)
|
|
8725
|
+
|
|
8726
|
+ float normalized_dist, end[NUM_AXIS];
|
|
8727
|
+
|
|
8728
|
+ // Split at the left/front border of the right/top square
|
|
8729
|
+ int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
|
|
8730
|
+ if (cx2 != cx1 && TEST(x_splits, gcx)) {
|
|
8731
|
+ memcpy(end, destination, sizeof(end));
|
|
8732
|
+ destination[X_AXIS] = LOGICAL_X_POSITION(bilinear_start[X_AXIS] + bilinear_grid_spacing[X_AXIS] * gcx);
|
|
8733
|
+ normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
|
|
8734
|
+ destination[Y_AXIS] = LINE_SEGMENT_END(Y);
|
|
8735
|
+ CBI(x_splits, gcx);
|
|
8736
|
+ }
|
|
8737
|
+ else if (cy2 != cy1 && TEST(y_splits, gcy)) {
|
|
8738
|
+ memcpy(end, destination, sizeof(end));
|
|
8739
|
+ destination[Y_AXIS] = LOGICAL_Y_POSITION(bilinear_start[Y_AXIS] + bilinear_grid_spacing[Y_AXIS] * gcy);
|
|
8740
|
+ normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
|
|
8741
|
+ destination[X_AXIS] = LINE_SEGMENT_END(X);
|
|
8742
|
+ CBI(y_splits, gcy);
|
|
8743
|
+ }
|
|
8744
|
+ else {
|
|
8745
|
+ // Already split on a border
|
|
8746
|
+ line_to_destination(fr_mm_s);
|
|
8747
|
+ set_current_to_destination();
|
|
8748
|
+ return;
|
|
8749
|
+ }
|
|
8750
|
+
|
|
8751
|
+ destination[Z_AXIS] = LINE_SEGMENT_END(Z);
|
|
8752
|
+ destination[E_AXIS] = LINE_SEGMENT_END(E);
|
|
8753
|
+
|
|
8754
|
+ // Do the split and look for more borders
|
|
8755
|
+ bilinear_line_to_destination(fr_mm_s, x_splits, y_splits);
|
|
8756
|
+
|
|
8757
|
+ // Restore destination from stack
|
|
8758
|
+ memcpy(destination, end, sizeof(end));
|
|
8759
|
+ bilinear_line_to_destination(fr_mm_s, x_splits, y_splits);
|
|
8760
|
+ }
|
|
8761
|
+
|
|
8762
|
+#endif // AUTO_BED_LEVELING_BILINEAR
|
8702
|
8763
|
|
8703
|
8764
|
#if IS_KINEMATIC
|
8704
|
8765
|
|
|
@@ -8892,6 +8953,12 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
8892
|
8953
|
return false;
|
8893
|
8954
|
}
|
8894
|
8955
|
else
|
|
8956
|
+ #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
|
8957
|
+ if (planner.abl_enabled) {
|
|
8958
|
+ bilinear_line_to_destination(MMS_SCALED(feedrate_mm_s));
|
|
8959
|
+ return false;
|
|
8960
|
+ }
|
|
8961
|
+ else
|
8895
|
8962
|
#endif
|
8896
|
8963
|
line_to_destination(MMS_SCALED(feedrate_mm_s));
|
8897
|
8964
|
}
|