|
@@ -757,9 +757,11 @@ void unified_bed_leveling::shift_mesh_height() {
|
757
|
757
|
}
|
758
|
758
|
#endif
|
759
|
759
|
|
760
|
|
- best = do_furthest
|
761
|
|
- ? find_furthest_invalid_mesh_point()
|
762
|
|
- : find_closest_mesh_point_of_type(INVALID, nearby, true);
|
|
760
|
+ best = do_furthest ? find_furthest_invalid_mesh_point()
|
|
761
|
+ : TERN(UBL_HILBERT_CURVE,
|
|
762
|
+ next_point_in_grid(),
|
|
763
|
+ find_closest_mesh_point_of_type(INVALID, nearby, true)
|
|
764
|
+ );
|
763
|
765
|
|
764
|
766
|
if (best.pos.x >= 0) { // mesh point found and is reachable by probe
|
765
|
767
|
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::PROBE_START));
|
|
@@ -1298,6 +1300,56 @@ mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const Mesh
|
1298
|
1300
|
return closest;
|
1299
|
1301
|
}
|
1300
|
1302
|
|
|
1303
|
+#if ENABLED(UBL_HILBERT_CURVE)
|
|
1304
|
+
|
|
1305
|
+ constexpr int8_t to_fix(int8_t v) { return v << 1; }
|
|
1306
|
+ constexpr int8_t to_int(int8_t v) { return v >> 1; }
|
|
1307
|
+ constexpr uint8_t log2(uint8_t n) { return (n > 1) ? 1 + log2(n >> 1) : 0; }
|
|
1308
|
+ constexpr uint8_t order(uint8_t n) { return uint8_t(log2(n - 1)) + 1; }
|
|
1309
|
+
|
|
1310
|
+ void unified_bed_leveling::hilbert(mesh_index_pair &pt, int8_t x, int8_t y, int8_t xi, int8_t xj, int8_t yi, int8_t yj, uint8_t n) {
|
|
1311
|
+ /* Hilbert space filling curve implementation
|
|
1312
|
+ *
|
|
1313
|
+ * x and y are the coordinates of the bottom left corner
|
|
1314
|
+ * xi & xj are the i & j components of the unit x vector of the frame
|
|
1315
|
+ * similarly yi and yj
|
|
1316
|
+ *
|
|
1317
|
+ * From: http://www.fundza.com/algorithmic/space_filling/hilbert/basics/index.html
|
|
1318
|
+ */
|
|
1319
|
+ if (n <= 0)
|
|
1320
|
+ check_if_missing(pt, to_int(x+(xi+yi)/2),to_int(y+(xj+yj)/2));
|
|
1321
|
+ else {
|
|
1322
|
+ hilbert(pt, x, y, yi/2, yj/2, xi/2, xj/2, n-1);
|
|
1323
|
+ hilbert(pt, x+xi/2, y+xj/2, xi/2, xj/2, yi/2, yj/2, n-1);
|
|
1324
|
+ hilbert(pt, x+xi/2+yi/2, y+xj/2+yj/2, xi/2, xj/2, yi/2, yj/2, n-1);
|
|
1325
|
+ hilbert(pt, x+xi/2+yi, y+xj/2+yj, -yi/2, -yj/2, -xi/2, -xj/2, n-1);
|
|
1326
|
+ }
|
|
1327
|
+ }
|
|
1328
|
+
|
|
1329
|
+ void unified_bed_leveling::check_if_missing(mesh_index_pair &pt, int x, int y) {
|
|
1330
|
+ if ( pt.distance < 0
|
|
1331
|
+ && x < GRID_MAX_POINTS_X
|
|
1332
|
+ && y < GRID_MAX_POINTS_Y
|
|
1333
|
+ && isnan(z_values[x][y])
|
|
1334
|
+ && probe.can_reach(mesh_index_to_xpos(x), mesh_index_to_ypos(y))
|
|
1335
|
+ ) {
|
|
1336
|
+ pt.pos.set(x, y);
|
|
1337
|
+ pt.distance = 1;
|
|
1338
|
+ }
|
|
1339
|
+ }
|
|
1340
|
+
|
|
1341
|
+ mesh_index_pair unified_bed_leveling::find_next_mesh_point() {
|
|
1342
|
+ mesh_index_pair pt;
|
|
1343
|
+ pt.invalidate();
|
|
1344
|
+ pt.distance = -99999.9f;
|
|
1345
|
+ constexpr uint8_t ord = order(_MAX(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y));
|
|
1346
|
+ constexpr uint8_t dim = _BV(ord);
|
|
1347
|
+ hilbert(pt, to_fix(0), to_fix(0), to_fix(dim), to_fix(0), to_fix(0), to_fix(dim), ord);
|
|
1348
|
+ return pt;
|
|
1349
|
+ }
|
|
1350
|
+
|
|
1351
|
+#endif // UBL_HILBERT_CURVE
|
|
1352
|
+
|
1301
|
1353
|
/**
|
1302
|
1354
|
* 'Smart Fill': Scan from the outward edges of the mesh towards the center.
|
1303
|
1355
|
* If an invalid location is found, use the next two points (if valid) to
|