|
@@ -1545,84 +1545,54 @@
|
1545
|
1545
|
SERIAL_ECHOLNPGM("Done Editing Mesh");
|
1546
|
1546
|
}
|
1547
|
1547
|
|
1548
|
|
- //
|
1549
|
|
- // The routine provides the 'Smart Fill' capability. It scans from the
|
1550
|
|
- // outward edges of the mesh towards the center. If it finds an invalid
|
1551
|
|
- // location, it uses the next two points (assumming they are valid) to
|
1552
|
|
- // calculate a 'reasonable' value for the unprobed mesh point.
|
1553
|
|
- //
|
1554
|
|
- void smart_fill_mesh() {
|
1555
|
|
- float f, diff;
|
1556
|
|
- for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) { // Bottom of the mesh looking up
|
1557
|
|
- for (uint8_t y = 0; y < GRID_MAX_POINTS_Y-2; y++) {
|
1558
|
|
- if (isnan(ubl.z_values[x][y])) {
|
1559
|
|
- if (isnan(ubl.z_values[x][y+1])) // we only deal with the first NAN next to a block of
|
1560
|
|
- continue; // good numbers. we want 2 good numbers to extrapolate off of.
|
1561
|
|
- if (isnan(ubl.z_values[x][y+2]))
|
1562
|
|
- continue;
|
1563
|
|
- if (ubl.z_values[x][y+1] < ubl.z_values[x][y+2]) // The bed is angled down near this edge. So to be safe, we
|
1564
|
|
- ubl.z_values[x][y] = ubl.z_values[x][y+1]; // use the closest value, which is probably a little too high
|
1565
|
|
- else {
|
1566
|
|
- diff = ubl.z_values[x][y+1] - ubl.z_values[x][y+2]; // The bed is angled up near this edge. So we will use the closest
|
1567
|
|
- ubl.z_values[x][y] = ubl.z_values[x][y+1] + diff; // height and add in the difference between that and the next point
|
1568
|
|
- }
|
1569
|
|
- break;
|
1570
|
|
- }
|
1571
|
|
- }
|
1572
|
|
- }
|
1573
|
|
- for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) { // Top of the mesh looking down
|
1574
|
|
- for (uint8_t y=GRID_MAX_POINTS_Y-1; y>=1; y--) {
|
1575
|
|
- if (isnan(ubl.z_values[x][y])) {
|
1576
|
|
- if (isnan(ubl.z_values[x][y-1])) // we only deal with the first NAN next to a block of
|
1577
|
|
- continue; // good numbers. we want 2 good numbers to extrapolate off of.
|
1578
|
|
- if (isnan(ubl.z_values[x][y-2]))
|
1579
|
|
- continue;
|
1580
|
|
- if (ubl.z_values[x][y-1] < ubl.z_values[x][y-2]) // The bed is angled down near this edge. So to be safe, we
|
1581
|
|
- ubl.z_values[x][y] = ubl.z_values[x][y-1]; // use the closest value, which is probably a little too high
|
1582
|
|
- else {
|
1583
|
|
- diff = ubl.z_values[x][y-1] - ubl.z_values[x][y-2]; // The bed is angled up near this edge. So we will use the closest
|
1584
|
|
- ubl.z_values[x][y] = ubl.z_values[x][y-1] + diff; // height and add in the difference between that and the next point
|
1585
|
|
- }
|
1586
|
|
- break;
|
1587
|
|
- }
|
|
1548
|
+ /**
|
|
1549
|
+ * 'Smart Fill': Scan from the outward edges of the mesh towards the center.
|
|
1550
|
+ * If an invalid location is found, use the next two points (if valid) to
|
|
1551
|
+ * calculate a 'reasonable' value for the unprobed mesh point.
|
|
1552
|
+ */
|
|
1553
|
+
|
|
1554
|
+ bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir) {
|
|
1555
|
+ const int8_t x1 = x + xdir, x2 = x1 + xdir,
|
|
1556
|
+ y1 = y + ydir, y2 = y1 + ydir;
|
|
1557
|
+ // A NAN next to a pair of real values?
|
|
1558
|
+ if (isnan(ubl.z_values[x][y]) && !isnan(ubl.z_values[x1][y1]) && !isnan(ubl.z_values[x2][y2])) {
|
|
1559
|
+ if (ubl.z_values[x1][y1] < ubl.z_values[x2][y2]) // Angled downward?
|
|
1560
|
+ ubl.z_values[x][y] = ubl.z_values[x1][y1]; // Use nearest (maybe a little too high.)
|
|
1561
|
+ else {
|
|
1562
|
+ const float diff = ubl.z_values[x1][y1] - ubl.z_values[x2][y2]; // Angled upward
|
|
1563
|
+ ubl.z_values[x][y] = ubl.z_values[x1][y1] + diff; // Use closest plus difference
|
1588
|
1564
|
}
|
|
1565
|
+ return true;
|
1589
|
1566
|
}
|
1590
|
|
- for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) {
|
1591
|
|
- for (uint8_t x = 0; x < GRID_MAX_POINTS_X-2; x++) { // Left side of the mesh looking right
|
1592
|
|
- if (isnan(ubl.z_values[x][y])) {
|
1593
|
|
- if (isnan(ubl.z_values[x+1][y])) // we only deal with the first NAN next to a block of
|
1594
|
|
- continue; // good numbers. we want 2 good numbers to extrapolate off of.
|
1595
|
|
- if (isnan(ubl.z_values[x+2][y]))
|
1596
|
|
- continue;
|
1597
|
|
- if (ubl.z_values[x+1][y] < ubl.z_values[x+2][y]) // The bed is angled down near this edge. So to be safe, we
|
1598
|
|
- ubl.z_values[x][y] = ubl.z_values[x][y+1]; // use the closest value, which is probably a little too high
|
1599
|
|
- else {
|
1600
|
|
- diff = ubl.z_values[x+1][y] - ubl.z_values[x+2][y]; // The bed is angled up near this edge. So we will use the closest
|
1601
|
|
- ubl.z_values[x][y] = ubl.z_values[x+1][y] + diff; // height and add in the difference between that and the next point
|
1602
|
|
- }
|
1603
|
|
- break;
|
1604
|
|
- }
|
1605
|
|
- }
|
|
1567
|
+ return false;
|
|
1568
|
+ }
|
|
1569
|
+
|
|
1570
|
+ typedef struct { uint8_t sx, ex, sy, ey; bool yfirst; } smart_fill_info;
|
|
1571
|
+
|
|
1572
|
+ void smart_fill_loop(const smart_fill_info &f) {
|
|
1573
|
+ if (f.yfirst) {
|
|
1574
|
+ const int8_t dir = f.ex > f.sx ? 1 : -1;
|
|
1575
|
+ for (uint8_t y = f.sy; y != f.ey; ++y)
|
|
1576
|
+ for (uint8_t x = f.sx; x != f.ex; x += dir)
|
|
1577
|
+ if (smart_fill_one(x, y, dir, 0)) break;
|
1606
|
1578
|
}
|
1607
|
|
- for (uint8_t y=0; y < GRID_MAX_POINTS_Y; y++) {
|
1608
|
|
- for (uint8_t x=GRID_MAX_POINTS_X-1; x>=1; x--) { // Right side of the mesh looking left
|
1609
|
|
- if (isnan(ubl.z_values[x][y])) {
|
1610
|
|
- if (isnan(ubl.z_values[x-1][y])) // we only deal with the first NAN next to a block of
|
1611
|
|
- continue; // good numbers. we want 2 good numbers to extrapolate off of.
|
1612
|
|
- if (isnan(ubl.z_values[x-2][y]))
|
1613
|
|
- continue;
|
1614
|
|
- if (ubl.z_values[x-1][y] < ubl.z_values[x-2][y]) // The bed is angled down near this edge. So to be safe, we
|
1615
|
|
- ubl.z_values[x][y] = ubl.z_values[x-1][y]; // use the closest value, which is probably a little too high
|
1616
|
|
- else {
|
1617
|
|
- diff = ubl.z_values[x-1][y] - ubl.z_values[x-2][y]; // The bed is angled up near this edge. So we will use the closest
|
1618
|
|
- ubl.z_values[x][y] = ubl.z_values[x-1][y] + diff; // height and add in the difference between that and the next point
|
1619
|
|
- }
|
1620
|
|
- break;
|
1621
|
|
- }
|
1622
|
|
- }
|
|
1579
|
+ else {
|
|
1580
|
+ const int8_t dir = f.ey > f.sy ? 1 : -1;
|
|
1581
|
+ for (uint8_t x = f.sx; x != f.ex; ++x)
|
|
1582
|
+ for (uint8_t y = f.sy; y != f.ey; y += dir)
|
|
1583
|
+ if (smart_fill_one(x, y, 0, dir)) break;
|
1623
|
1584
|
}
|
1624
|
1585
|
}
|
1625
|
1586
|
|
|
1587
|
+ void smart_fill_mesh() {
|
|
1588
|
+ const smart_fill_info info[] = {
|
|
1589
|
+ { 0, GRID_MAX_POINTS_X, 0, GRID_MAX_POINTS_Y - 2, false }, // Bottom of the mesh looking up
|
|
1590
|
+ { 0, GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - 1, 0, false }, // Top of the mesh looking down
|
|
1591
|
+ { 0, GRID_MAX_POINTS_X - 2, 0, GRID_MAX_POINTS_Y, true }, // Left side of the mesh looking right
|
|
1592
|
+ { GRID_MAX_POINTS_X - 1, 0, 0, GRID_MAX_POINTS_Y, true } // Right side of the mesh looking left
|
|
1593
|
+ };
|
|
1594
|
+ for (uint8_t i = 0; i < COUNT(info); ++i) smart_fill_loop(info[i]);
|
|
1595
|
+ }
|
1626
|
1596
|
|
1627
|
1597
|
void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map) {
|
1628
|
1598
|
constexpr int16_t x_min = max(MIN_PROBE_X, UBL_MESH_MIN_X),
|