Skip to content

Commit c61d258

Browse files
committed
Simplify mesh connection algorithm
- Rather than checking entire mesh after each point, only check neighbors - Eliminate looping through entire mesh - Eliminate flags for horizontal and vertical lines
1 parent 75a6bb5 commit c61d258

1 file changed

Lines changed: 30 additions & 67 deletions

File tree

Marlin/src/gcode/bedlevel/G26.cpp

Lines changed: 30 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149

150150
constexpr float g26_e_axis_feedrate = 0.025;
151151

152-
static MeshFlags circle_flags, horizontal_mesh_line_flags, vertical_mesh_line_flags;
152+
static MeshFlags circle_flags;
153153
float g26_random_deviation = 0.0;
154154

155155
#if HAS_LCD_MENU
@@ -280,71 +280,32 @@ typedef struct {
280280
move_to(e, e_pos_delta); // Get to the ending point with an appropriate amount of extrusion
281281
}
282282

283-
inline bool look_for_lines_to_connect() {
284-
xyz_pos_t s, e;
285-
s.z = e.z = layer_height;
286-
287-
GRID_LOOP(i, j) {
288-
289-
if (TERN0(HAS_LCD_MENU, user_canceled())) return true;
290-
291-
if (
292-
// Can't connect to anything farther to the right than GRID_MAX_POINTS_X
293-
// Already a half circle at the edge of the bed.
294-
i < (GRID_MAX_POINTS_X - 1) &&
295-
296-
// Test whether a leftward line can be done
297-
circle_flags.marked(i, j) && circle_flags.marked(i + 1, j) &&
298-
299-
// Two circles need a horizontal line to connect them
300-
!horizontal_mesh_line_flags.marked(i, j)
301-
) {
302-
s.x = _GET_MESH_X( i ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // right edge
303-
e.x = _GET_MESH_X(i + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // left edge
304-
305-
#if HAS_ENDSTOPS
306-
LIMIT(s.x, X_MIN_POS + 1, X_MAX_POS - 1);
307-
s.y = e.y = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
308-
LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1);
309-
#else
310-
s.y = e.y = _GET_MESH_Y(j);
311-
#endif
312-
313-
if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y))
314-
print_line_from_here_to_there(s, e);
315-
316-
horizontal_mesh_line_flags.mark(i, j); // Mark done, even if skipped
317-
}
318-
319-
if (
320-
// Can't connect to anything further back than GRID_MAX_POINTS_Y
321-
// Already a half circle at the edge of the bed.
322-
j < (GRID_MAX_POINTS_Y - 1) &&
323-
324-
// Test whether a downward line can be done
325-
circle_flags.marked(i, j) && circle_flags.marked(i, j + 1) &&
326-
327-
// Two circles that need a vertical line to connect them
328-
!vertical_mesh_line_flags.marked(i, j)
329-
) {
330-
s.y = _GET_MESH_Y( j ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // top edge
331-
e.y = _GET_MESH_Y(j + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // bottom edge
332-
333-
#if HAS_ENDSTOPS
334-
s.x = e.x = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1);
335-
LIMIT(s.y, Y_MIN_POS + 1, Y_MAX_POS - 1);
336-
LIMIT(e.y, Y_MIN_POS + 1, Y_MAX_POS - 1);
337-
#else
338-
s.x = e.x = _GET_MESH_X(i);
339-
#endif
340-
341-
if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y))
342-
print_line_from_here_to_there(s, e);
283+
void connect_neighbor_with_line(const xy_int8_t &p1, int8_t dx, int8_t dy) {
284+
xy_int8_t p2;
285+
p2.x = p1.x + dx;
286+
p2.y = p1.y + dy;
287+
288+
if (p2.x < 0 || p2.x >= GRID_MAX_POINTS_X) return;
289+
if (p2.y < 0 || p2.y >= GRID_MAX_POINTS_Y) return;
290+
291+
if(circle_flags.marked(p1.x, p1.y) && circle_flags.marked(p2.x, p2.y)) {
292+
xyz_pos_t s, e;
293+
s.x = _GET_MESH_X(p1.x) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx;
294+
e.x = _GET_MESH_X(p2.x) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx;
295+
s.y = _GET_MESH_Y(p1.y) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dy;
296+
e.y = _GET_MESH_Y(p2.y) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dy;
297+
s.z = e.z = layer_height;
298+
299+
#if HAS_ENDSTOPS
300+
LIMIT(s.y, Y_MIN_POS + 1, Y_MAX_POS - 1);
301+
LIMIT(e.y, Y_MIN_POS + 1, Y_MAX_POS - 1);
302+
LIMIT(s.x, X_MIN_POS + 1, X_MAX_POS - 1);
303+
LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1);
304+
#endif
343305

344-
vertical_mesh_line_flags.mark(i, j); // Mark done, even if skipped
345-
}
306+
if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y))
307+
print_line_from_here_to_there(s, e);
346308
}
347-
return false;
348309
}
349310

350311
/**
@@ -735,8 +696,6 @@ void GcodeSuite::G26() {
735696
*/
736697

737698
circle_flags.reset();
738-
horizontal_mesh_line_flags.reset();
739-
vertical_mesh_line_flags.reset();
740699

741700
// Move nozzle to the specified height for the first layer
742701
destination = current_position;
@@ -883,7 +842,11 @@ void GcodeSuite::G26() {
883842

884843
#endif // !ARC_SUPPORT
885844

886-
if (g26.look_for_lines_to_connect()) goto LEAVE;
845+
g26.connect_neighbor_with_line(location.pos, -1, 0);
846+
g26.connect_neighbor_with_line(location.pos, 1, 0);
847+
g26.connect_neighbor_with_line(location.pos, 0, -1);
848+
g26.connect_neighbor_with_line(location.pos, 0, 1);
849+
if (TERN0(HAS_LCD_MENU, user_canceled())) goto LEAVE;
887850
}
888851

889852
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.

0 commit comments

Comments
 (0)