Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable number of G29 grid points (UBL, Bilinear) #26084

Open
wants to merge 56 commits into
base: bugfix-2.1.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
c8db766
Basic implementation
lukasradek Jul 15, 2023
aaf1e19
Extends G29 gcode parameters
lukasradek Jul 16, 2023
dd6f8d2
make optional, start on leveling changes
thinkyhead Jul 16, 2023
1f57ecc
'static' needed
thinkyhead Jul 16, 2023
e3f2100
extraneous parens
thinkyhead Jul 16, 2023
48fc2f6
GRID_MAX_CELLS…
thinkyhead Jul 16, 2023
d0610d1
oops, ANY
thinkyhead Jul 16, 2023
1d423b3
fix my typos
thinkyhead Jul 16, 2023
98ab0fa
just one more
thinkyhead Jul 16, 2023
e89a1fd
Unifies LINEAR and BILINEAR logic, Implements EEPROM
lukasradek Jul 16, 2023
3f50636
Determine GRID_MAX_POINTS based on spacing
lukasradek Jul 16, 2023
93db6d7
Fix constexpr and conditional compilations
lukasradek Jul 16, 2023
7cd5801
Fix issue with printing array
lukasradek Jul 16, 2023
2e35e87
Set unused bedlevel z values to NAN
lukasradek Jul 16, 2023
1adb186
ABL_SUBDIVISION - optimize and fix
lukasradek Jul 16, 2023
0c97c3b
Enable in tests
lukasradek Jul 16, 2023
600f835
Fix G29 W, add ToDo
lukasradek Jul 17, 2023
16396d1
G26, G42 supports VARIABLE_GRID_POINTS
lukasradek Jul 19, 2023
87e7a2c
M421 supports VARIABLE_GRID_POINTS
lukasradek Jul 19, 2023
e5e9672
M420 supports VARIABLE_GRID_POINTS
lukasradek Jul 19, 2023
31bc6be
Level Menu supports VARIABLE_GRID_POINTS + small enhancement
lukasradek Jul 19, 2023
c447115
Revert accidental platformio.ini change
lukasradek Jul 19, 2023
99e1613
Merge remote-tracking branch 'upstream/bugfix-2.1.x' into G29-Variabl…
lukasradek Jul 19, 2023
1c41d3f
Refactor
lukasradek Jul 19, 2023
862cbef
AUTO_BED_LEVELING_LINEAR uses VARIABLE_GRID_POINTS macro
lukasradek Aug 6, 2023
1aee9c1
Merge remote-tracking branch 'upstream/bugfix-2.1.x' into G29-Variabl…
lukasradek Aug 6, 2023
338184d
Merge 'bugfix-2.1.x' into pr/26084
thinkyhead Oct 3, 2023
20f296d
cleanup
thinkyhead Oct 3, 2023
abf2f80
No printf("%f") allowed
thinkyhead Oct 3, 2023
3ebf838
DISABLED
thinkyhead Oct 3, 2023
26a5034
misc.
thinkyhead Oct 3, 2023
d345f1f
unused strings
thinkyhead Oct 3, 2023
281e7f0
clarify index
thinkyhead Oct 3, 2023
387a7cd
use xy_uint8_t
thinkyhead Oct 3, 2023
8776070
ws
thinkyhead Oct 4, 2023
ce5a863
Ubl variable grid points
ThomasToka Nov 8, 2023
9db3f17
Pass CI checks update
ThomasToka Nov 8, 2023
6702dc4
fix to one MESH_Y_DIST conversion
ThomasToka Nov 9, 2023
8353715
Pre-calculate grid distance
thinkyhead Nov 10, 2023
c27fe42
Merge branch 'bugfix-2.1.x' into pr/26403
thinkyhead Nov 10, 2023
19a5214
tweaks
thinkyhead Nov 10, 2023
fa6623d
etc
thinkyhead Nov 10, 2023
72f8dc7
Init, load, store
thinkyhead Nov 10, 2023
ef389d8
fixes
thinkyhead Nov 10, 2023
d119e83
etc
thinkyhead Nov 10, 2023
68868b7
Merge branch 'MarlinFirmware:bugfix-2.1.x' into bugfix-2.1.x-ubl-grid…
ThomasToka Nov 10, 2023
d2812d4
set_grid_points
thinkyhead Nov 10, 2023
275659b
serial tweaks
thinkyhead Nov 10, 2023
036edd5
more serial tweaks
thinkyhead Nov 10, 2023
aff29c5
move to work branch
thinkyhead Nov 11, 2023
5e2d6e2
Merge branch 'bugfix-2.1.x' into pr/26084
thinkyhead Nov 14, 2023
a4800ff
Merge branch 'bugfix-2.1.x' into pr/26403
thinkyhead Nov 14, 2023
1493529
Merge branch 'pr/26403' into pr/26084
thinkyhead Nov 14, 2023
966b59d
merge followup
thinkyhead Nov 14, 2023
2ae625b
use var instead
thinkyhead Nov 14, 2023
da65a46
Merge branch 'bugfix-2.1.x' into pr/26084
thinkyhead Jan 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -2119,6 +2119,13 @@
#define GRID_MAX_POINTS_X 3
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X

#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
//#define VARIABLE_GRID_POINTS // Variable grid points at the cost of SRAM and more per-segment computation
#endif
#if ANY(AUTO_BED_LEVELING_LINEAR, VARIABLE_GRID_POINTS)
#define GRID_MIN_SPACING 25 // Prevent the probed area / probed points producing tiny cells
#endif

// Probe along the Y axis, advancing X after each column
//#define PROBE_Y_FIRST

Expand Down
12 changes: 12 additions & 0 deletions Marlin/src/core/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,18 @@ inline void print_xyze(const xyze_pos_t &xyze, FSTR_P const prefix=nullptr, FSTR
print_xyze(LOGICAL_AXIS_ELEM_(xyze) prefix, suffix);
}

template<typename T>
inline void SERIAL_ECHO_NUM(T num, int digits) {
switch (digits) {
case 6: if (num < 100000) SERIAL_CHAR(' ');
case 5: if (num < 10000) SERIAL_CHAR(' ');
case 4: if (num < 1000) SERIAL_CHAR(' ');
case 3: if (num < 100) SERIAL_CHAR(' ');
case 2: if (num < 10) SERIAL_CHAR(' ');
}
SERIAL_ECHO(num);
}

#define SERIAL_POS(SUFFIX,VAR) do { print_xyz(VAR, F(" " STRINGIFY(VAR) "="), F(" : " SUFFIX "\n")); }while(0)
#define SERIAL_XYZ(PREFIX,V...) do { print_xyz(V, F(PREFIX)); }while(0)

Expand Down
88 changes: 56 additions & 32 deletions Marlin/src/feature/bedlevel/abl/bbl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@

LevelingBilinear bedlevel;

#if ENABLED(VARIABLE_GRID_POINTS)
xy_uint8_t LevelingBilinear::nr_grid_points;
#else
constexpr xy_uint8_t LevelingBilinear::nr_grid_points;
#endif
xy_pos_t LevelingBilinear::grid_spacing,
LevelingBilinear::grid_start;
xy_float_t LevelingBilinear::grid_factor;
Expand Down Expand Up @@ -100,16 +105,18 @@ void LevelingBilinear::extrapolate_one_point(const uint8_t x, const uint8_t y, c
void LevelingBilinear::reset() {
grid_start.reset();
grid_spacing.reset();
TERN_(VARIABLE_GRID_POINTS, nr_grid_points.set(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y));
GRID_LOOP(x, y) {
z_values[x][y] = NAN;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, 0));
}
}

void LevelingBilinear::set_grid(const xy_pos_t& _grid_spacing, const xy_pos_t& _grid_start) {
void LevelingBilinear::set_grid(const xy_pos_t &_grid_spacing, const xy_pos_t &_grid_start OPTARG(VARIABLE_GRID_POINTS, const xy_uint8_t &_nr_grid_points)) {
grid_spacing = _grid_spacing;
grid_start = _grid_start;
grid_factor = grid_spacing.reciprocal();
TERN_(VARIABLE_GRID_POINTS, nr_grid_points = _nr_grid_points);
}

/**
Expand All @@ -118,19 +125,21 @@ void LevelingBilinear::set_grid(const xy_pos_t& _grid_spacing, const xy_pos_t& _
*/
void LevelingBilinear::extrapolate_unprobed_bed_level() {
#ifdef HALF_IN_X
constexpr uint8_t ctrx2 = 0, xend = GRID_MAX_POINTS_X - 1;
constexpr uint8_t ctrx2 = 0, xend = nr_grid_points.x - 1;
#else
constexpr uint8_t ctrx1 = (GRID_MAX_CELLS_X) / 2, // left-of-center
ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center
xend = ctrx1;
IF_DISABLED(VARIABLE_GRID_POINTS, constexpr) uint8_t
ctrx1 = (nr_grid_points.x - 1) / 2, // left-of-center
ctrx2 = nr_grid_points.x / 2, // right-of-center
xend = ctrx1;
#endif

#ifdef HALF_IN_Y
constexpr uint8_t ctry2 = 0, yend = GRID_MAX_POINTS_Y - 1;
constexpr uint8_t ctry2 = 0, yend = nr_grid_points.y - 1;
#else
constexpr uint8_t ctry1 = (GRID_MAX_CELLS_Y) / 2, // top-of-center
ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center
yend = ctry1;
IF_DISABLED(VARIABLE_GRID_POINTS, constexpr) uint8_t
ctry1 = (nr_grid_points.y - 1) / 2, // top-of-center
ctry2 = nr_grid_points.y / 2, // bottom-of-center
yend = ctry1;
#endif

for (uint8_t xo = 0; xo <= xend; ++xo)
Expand All @@ -153,44 +162,52 @@ void LevelingBilinear::extrapolate_unprobed_bed_level() {
}
}

void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr*/) {
// print internal grid(s) or just the one passed as a parameter
void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr*/ OPTARG(VARIABLE_GRID_POINTS, const xy_uint8_t *_grid_points/*=nullptr*/)) {
// Print the passed mesh grid(s) or the current mesh
SERIAL_ECHOLNPGM("Bilinear Leveling Grid:");
print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 3, _z_values ? *_z_values[0] : z_values[0]);
PRINT_2D_ARRAY(
GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 3, _z_values ? *_z_values[0] : z_values[0],
_grid_points ? _grid_points->x : nr_grid_points.x,
_grid_points ? _grid_points->y : nr_grid_points.y
);

#if ENABLED(ABL_BILINEAR_SUBDIVISION)
if (!_z_values) {
SERIAL_ECHOLNPGM("Subdivided with CATMULL ROM Leveling Grid:");
print_2d_array(ABL_GRID_POINTS_VIRT_X, ABL_GRID_POINTS_VIRT_Y, 5, z_values_virt[0]);
PRINT_2D_ARRAY(
ABL_MAX_POINTS_VIRT_X, ABL_MAX_POINTS_VIRT_Y, 5, z_values_virt[0],
nr_grid_points_virt.x, nr_grid_points_virt.y
);
}
#endif
}

#if ENABLED(ABL_BILINEAR_SUBDIVISION)

#define ABL_TEMP_POINTS_X (GRID_MAX_POINTS_X + 2)
#define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2)
float LevelingBilinear::z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
float LevelingBilinear::z_values_virt[ABL_MAX_POINTS_VIRT_X][ABL_MAX_POINTS_VIRT_Y];
xy_pos_t LevelingBilinear::grid_spacing_virt;
xy_float_t LevelingBilinear::grid_factor_virt;
#if ENABLED(VARIABLE_GRID_POINTS)
xy_uint_t LevelingBilinear::nr_grid_points_virt;
#endif

#define LINEAR_EXTRAPOLATION(E, I) ((E) * 2 - (I))
float LevelingBilinear::virt_coord(const uint8_t x, const uint8_t y) {
uint8_t ep = 0, ip = 1;
if (x > (GRID_MAX_POINTS_X) + 1 || y > (GRID_MAX_POINTS_Y) + 1) {
if (x > nr_grid_points.x + 1 || y > nr_grid_points.y + 1) {
// The requested point requires extrapolating two points beyond the mesh.
// These values are only requested for the edges of the mesh, which are always an actual mesh point,
// and do not require interpolation. When interpolation is not needed, this "Mesh + 2" point is
// cancelled out in virt_cmr and does not impact the result. Return 0.0 rather than
// making this function more complex by extrapolating two points.
return 0.0;
}
if (!x || x == ABL_TEMP_POINTS_X - 1) {
if (!x || x == (nr_grid_points.x + 2) - 1) {
if (x) {
ep = (GRID_MAX_POINTS_X) - 1;
ip = GRID_MAX_CELLS_X - 1;
ep = nr_grid_points.x - 1;
ip = (nr_grid_points.x - 1) - 1;
}
if (WITHIN(y, 1, ABL_TEMP_POINTS_Y - 2))
if (WITHIN(y, 1, (nr_grid_points.y + 2) - 2))
return LINEAR_EXTRAPOLATION(
z_values[ep][y - 1],
z_values[ip][y - 1]
Expand All @@ -201,12 +218,12 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
virt_coord(ip + 1, y)
);
}
if (!y || y == ABL_TEMP_POINTS_Y - 1) {
if (!y || y == (nr_grid_points.y + 2) - 1) {
if (y) {
ep = (GRID_MAX_POINTS_Y) - 1;
ip = GRID_MAX_CELLS_Y - 1;
ep = nr_grid_points.y - 1;
ip = (nr_grid_points.y - 1) - 1;
}
if (WITHIN(x, 1, ABL_TEMP_POINTS_X - 2))
if (WITHIN(x, 1, (nr_grid_points.x + 2) - 2))
return LINEAR_EXTRAPOLATION(
z_values[x - 1][ep],
z_values[x - 1][ip]
Expand Down Expand Up @@ -243,11 +260,14 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
void LevelingBilinear::subdivide_mesh() {
grid_spacing_virt = grid_spacing / (BILINEAR_SUBDIVISIONS);
grid_factor_virt = grid_spacing_virt.reciprocal();
for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; ++y)
for (uint8_t x = 0; x < GRID_MAX_POINTS_X; ++x)
#if ENABLED(VARIABLE_GRID_POINTS)
nr_grid_points_virt.set((nr_grid_points.x - 1) * (uint16_t)(BILINEAR_SUBDIVISIONS) + (uint16_t)1, (nr_grid_points.y - 1) * (uint16_t)(BILINEAR_SUBDIVISIONS) + (uint16_t)1);
#endif
for (uint8_t y = 0; y < nr_grid_points.y; ++y)
for (uint8_t x = 0; x < nr_grid_points.x; ++x)
for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ++ty)
for (uint8_t tx = 0; tx < BILINEAR_SUBDIVISIONS; ++tx) {
if ((ty && y == (GRID_MAX_POINTS_Y) - 1) || (tx && x == (GRID_MAX_POINTS_X) - 1))
if ((ty && y == nr_grid_points.y - 1) || (tx && x == nr_grid_points.x - 1))
continue;
z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] =
virt_2cmr(x + 1, y + 1, (float)tx / (BILINEAR_SUBDIVISIONS), (float)ty / (BILINEAR_SUBDIVISIONS));
Expand All @@ -258,6 +278,10 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr

// Refresh after other values have been updated
void LevelingBilinear::refresh_bed_level() {
#if ENABLED(VARIABLE_GRID_POINTS)
// Fill the unused grid area with NaN
GRID_LOOP(x, y) if (x >= nr_grid_points.x || y >= nr_grid_points.y) z_values[x][y] = NAN;
#endif
TERN_(ABL_BILINEAR_SUBDIVISION, subdivide_mesh());
cached_rel.x = cached_rel.y = -999.999;
cached_g.x = cached_g.y = -99;
Expand All @@ -266,14 +290,14 @@ void LevelingBilinear::refresh_bed_level() {
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
#define ABL_BG_SPACING(A) grid_spacing_virt.A
#define ABL_BG_FACTOR(A) grid_factor_virt.A
#define ABL_BG_POINTS_X ABL_GRID_POINTS_VIRT_X
#define ABL_BG_POINTS_Y ABL_GRID_POINTS_VIRT_Y
#define ABL_BG_POINTS_X nr_grid_points_virt.x
#define ABL_BG_POINTS_Y nr_grid_points_virt.y
#define ABL_BG_GRID(X,Y) z_values_virt[X][Y]
#else
#define ABL_BG_SPACING(A) grid_spacing.A
#define ABL_BG_FACTOR(A) grid_factor.A
#define ABL_BG_POINTS_X GRID_MAX_POINTS_X
#define ABL_BG_POINTS_Y GRID_MAX_POINTS_Y
#define ABL_BG_POINTS_X nr_grid_points.x
#define ABL_BG_POINTS_Y nr_grid_points.y
#define ABL_BG_GRID(X,Y) z_values[X][Y]
#endif

Expand Down
27 changes: 21 additions & 6 deletions Marlin/src/feature/bedlevel/abl/bbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,21 @@

#include "../../../inc/MarlinConfigPre.h"

#ifndef GRID_MIN_SPACING
#define GRID_MIN_SPACING 25
#endif

class LevelingBilinear {
public:
static bed_mesh_t z_values;
static xy_pos_t grid_spacing, grid_start;

#if ENABLED(VARIABLE_GRID_POINTS)
static xy_uint8_t nr_grid_points;
#else
static constexpr xy_uint8_t nr_grid_points { GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y };
#endif

private:
static xy_float_t grid_factor;
static xy_pos_t cached_rel;
Expand All @@ -36,12 +46,17 @@ class LevelingBilinear {
static void extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);

#if ENABLED(ABL_BILINEAR_SUBDIVISION)
#define ABL_GRID_POINTS_VIRT_X (GRID_MAX_CELLS_X * (BILINEAR_SUBDIVISIONS) + 1)
#define ABL_GRID_POINTS_VIRT_Y (GRID_MAX_CELLS_Y * (BILINEAR_SUBDIVISIONS) + 1)
#define ABL_MAX_POINTS_VIRT_X (GRID_MAX_CELLS_X * (BILINEAR_SUBDIVISIONS) + 1)
#define ABL_MAX_POINTS_VIRT_Y (GRID_MAX_CELLS_Y * (BILINEAR_SUBDIVISIONS) + 1)

static float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
static float z_values_virt[ABL_MAX_POINTS_VIRT_X][ABL_MAX_POINTS_VIRT_Y];
static xy_pos_t grid_spacing_virt;
static xy_float_t grid_factor_virt;
#if ENABLED(VARIABLE_GRID_POINTS)
static xy_uint_t nr_grid_points_virt;
#else
static constexpr xy_uint_t nr_grid_points_virt { ABL_MAX_POINTS_VIRT_X, ABL_MAX_POINTS_VIRT_Y };
#endif

static float virt_coord(const uint8_t x, const uint8_t y);
static float virt_cmr(const float p[4], const uint8_t i, const float t);
Expand All @@ -51,13 +66,13 @@ class LevelingBilinear {

public:
static void reset();
static void set_grid(const xy_pos_t& _grid_spacing, const xy_pos_t& _grid_start);
static void set_grid(const xy_pos_t &_grid_spacing, const xy_pos_t &_grid_start OPTARG(VARIABLE_GRID_POINTS, const xy_uint8_t &_nr_grid_points={ GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y }));
static void extrapolate_unprobed_bed_level();
static void print_leveling_grid(const bed_mesh_t *_z_values=nullptr);
static void print_leveling_grid(const bed_mesh_t *_z_values=nullptr OPTARG(VARIABLE_GRID_POINTS, const xy_uint8_t *_grid_points=nullptr));
static void refresh_bed_level();
static bool has_mesh() { return !!grid_spacing.x; }
static bool mesh_is_valid() { return has_mesh(); }
static float get_mesh_x(const uint8_t i) { return grid_start.x + i * grid_spacing.x; }
static float get_mesh_x(const uint8_t i) { return grid_start.x + i * grid_spacing.x; } // Caller beware. Don't go out of bounds.
static float get_mesh_y(const uint8_t j) { return grid_start.y + j * grid_spacing.y; }
static float get_z_correction(const xy_pos_t &raw);
static constexpr float get_z_offset() { return 0.0f; }
Expand Down
24 changes: 18 additions & 6 deletions Marlin/src/feature/bedlevel/bedlevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,21 @@ void reset_bed_level() {
/**
* Print calibration results for plotting or manual frame adjustment.
*/
void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const float *values) {
void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const float *values
#if ENABLED(VARIABLE_GRID_POINTS)
, uint8_t print_x/*=0*/, uint8_t print_y/*=0*/
#endif
) {

#if ENABLED(VARIABLE_GRID_POINTS)
if (!print_x) print_x = sx;
if (!print_y) print_y = sy;
#else
const uint8_t print_x = sx, print_y = sy;
#endif

#ifndef SCAD_MESH_OUTPUT
for (uint8_t x = 0; x < sx; ++x) {
for (uint8_t x = 0; x < print_x; ++x) {
SERIAL_ECHO_SP(precision + (x < 10 ? 3 : 2));
SERIAL_ECHO(x);
}
Expand All @@ -146,14 +158,14 @@ void reset_bed_level() {
#ifdef SCAD_MESH_OUTPUT
SERIAL_ECHOLNPGM("measured_z = ["); // open 2D array
#endif
for (uint8_t y = 0; y < sy; ++y) {
for (uint8_t y = 0; y < print_y; ++y) {
#ifdef SCAD_MESH_OUTPUT
SERIAL_ECHOPGM(" ["); // open sub-array
#else
if (y < 10) SERIAL_CHAR(' ');
SERIAL_ECHO(y);
#endif
for (uint8_t x = 0; x < sx; ++x) {
for (uint8_t x = 0; x < print_x; ++x) {
SERIAL_CHAR(' ');
const float offset = values[x * sy + y];
if (!isnan(offset)) {
Expand All @@ -171,12 +183,12 @@ void reset_bed_level() {
#endif
}
#ifdef SCAD_MESH_OUTPUT
if (x < sx - 1) SERIAL_CHAR(',');
if (x < print_x - 1) SERIAL_CHAR(',');
#endif
}
#ifdef SCAD_MESH_OUTPUT
SERIAL_ECHOPGM(" ]"); // close sub-array
if (y < sy - 1) SERIAL_CHAR(',');
if (y < print_y - 1) SERIAL_CHAR(',');
#endif
SERIAL_EOL();
}
Expand Down
12 changes: 11 additions & 1 deletion Marlin/src/feature/bedlevel/bedlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,17 @@ class TemporaryBedLevelingState {
/**
* Print calibration results for plotting or manual frame adjustment.
*/
void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const float *values);
void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const float *values
#if ENABLED(VARIABLE_GRID_POINTS)
, uint8_t print_x=0, uint8_t print_y=0
#endif
);

#if ENABLED(VARIABLE_GRID_POINTS)
#define PRINT_2D_ARRAY(X, Y, P, V, M...) print_2d_array(X, Y, P, V, M)
#else
#define PRINT_2D_ARRAY(X, Y, P, V, M...) print_2d_array(X, Y, P, V)
#endif

#endif

Expand Down
18 changes: 9 additions & 9 deletions Marlin/src/feature/bedlevel/hilbert_curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@
#include "bedlevel.h"
#include "hilbert_curve.h"

constexpr int8_t to_fix(int8_t v) { return v * 2; }
constexpr int8_t to_int(int8_t v) { return v / 2; }
constexpr uint8_t log2(uint8_t n) { return (n > 1) ? 1 + log2(uint8_t(n >> 1)) : 0; }
constexpr uint8_t order(uint8_t n) { return uint8_t(log2(uint8_t(n - 1))) + 1; }
constexpr uint8_t ord = order(_MAX(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y));
constexpr uint8_t dim = _BV(ord);
int8_t to_fix(const int8_t v) { return v * 2; }
int8_t to_int(const int8_t v) { return v / 2; }
uint8_t log2(const uint8_t n) { return (n > 1) ? 1 + log2(uint8_t(n >> 1)) : 0; }
uint8_t order(const uint8_t n) { return uint8_t(log2(uint8_t(n - 1))) + 1; }
#define ord order(_MAX(GRID_USED_POINTS_Y, GRID_USED_POINTS_Y))
#define dim _BV(ord)

static inline bool eval_candidate(int8_t x, int8_t y, hilbert_curve::callback_ptr func, void *data) {
// The print bed likely has fewer points than the full Hilbert
// curve, so cull unnecessary points
return x < (GRID_MAX_POINTS_X) && y < (GRID_MAX_POINTS_Y) ? func(x, y, data) : false;
return x < GRID_USED_POINTS_X && y < GRID_USED_POINTS_Y ? func(x, y, data) : false;
}

bool hilbert_curve::hilbert(int8_t x, int8_t y, int8_t xi, int8_t xj, int8_t yi, int8_t yj, uint8_t n, hilbert_curve::callback_ptr func, void *data) {
Expand Down Expand Up @@ -102,8 +102,8 @@ bool hilbert_curve::search_from(uint8_t x, uint8_t y, hilbert_curve::callback_pt
*/
bool hilbert_curve::search_from_closest(const xy_pos_t &pos, hilbert_curve::callback_ptr func, void *data) {
// Find closest grid intersection
const uint8_t grid_x = LROUND(constrain(float(pos.x - (MESH_MIN_X)) / (MESH_X_DIST), 0, (GRID_MAX_POINTS_X) - 1));
const uint8_t grid_y = LROUND(constrain(float(pos.y - (MESH_MIN_Y)) / (MESH_Y_DIST), 0, (GRID_MAX_POINTS_Y) - 1));
const uint8_t grid_x = LROUND(constrain(float(pos.x - (MESH_MIN_X)) / bedlevel.mesh_dist.x, 0, GRID_USED_POINTS_X - 1));
const uint8_t grid_y = LROUND(constrain(float(pos.y - (MESH_MIN_Y)) / bedlevel.mesh_dist.y, 0, GRID_USED_POINTS_Y - 1));
return search_from(grid_x, grid_y, func, data);
}

Expand Down
Loading