mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-06 08:39:05 +00:00
Implement Support For Klippers Adaptive Bed Meshing
This commit is contained in:
@@ -196,6 +196,27 @@ public class PrinterConfigFragment extends ProfileListFragment {
|
|||||||
new OptionElement(def.options.get("elegoolink_bed_type"))
|
new OptionElement(def.options.get("elegoolink_bed_type"))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if ("moonraker".equalsIgnoreCase(hostType) || "klipper".equalsIgnoreCase(hostType)) {
|
||||||
|
int insertIndex = list.size();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
OptionElement el = list.get(i);
|
||||||
|
if (el != null && el.simpleItem instanceof SubHeader) {
|
||||||
|
String title = ((SubHeader) el.simpleItem).title;
|
||||||
|
if ("Advanced".equals(title)) {
|
||||||
|
insertIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.addAll(insertIndex, Arrays.asList(
|
||||||
|
new OptionElement(new SubHeader("Adaptive bed mesh")),
|
||||||
|
new OptionElement(def.options.get("bed_mesh_probe_distance")),
|
||||||
|
new OptionElement(def.options.get("bed_mesh_limit_min")),
|
||||||
|
new OptionElement(def.options.get("bed_mesh_limit_max")),
|
||||||
|
new OptionElement(def.options.get("adaptive_bed_mesh_margin")),
|
||||||
|
new OptionElement(new SpaceItem(0, ViewUtils.dp(4)))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ public class Slic3rConfigWrapper {
|
|||||||
"machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
|
"machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
|
||||||
"machine_min_extruding_rate", "machine_min_travel_rate",
|
"machine_min_extruding_rate", "machine_min_travel_rate",
|
||||||
"machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e",
|
"machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e",
|
||||||
"elegoolink_timelapse", "elegoolink_bed_leveling", "elegoolink_bed_type"
|
"elegoolink_timelapse", "elegoolink_bed_leveling", "elegoolink_bed_type",
|
||||||
|
"bed_mesh_probe_distance", "bed_mesh_limit_min", "bed_mesh_limit_max", "adaptive_bed_mesh_margin"
|
||||||
);
|
);
|
||||||
public final static List<String> PHYSICAL_PRINTER_CONFIG_KEYS = Arrays.asList(
|
public final static List<String> PHYSICAL_PRINTER_CONFIG_KEYS = Arrays.asList(
|
||||||
"preset_name", // temporary option to compatibility with older Slicer
|
"preset_name", // temporary option to compatibility with older Slicer
|
||||||
|
|||||||
@@ -1159,6 +1159,14 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
m_label_objects.init(print.objects(), print.config().gcode_label_objects, print.config().gcode_flavor);
|
m_label_objects.init(print.objects(), print.config().gcode_label_objects, print.config().gcode_flavor);
|
||||||
file.write(m_label_objects.all_objects_header());
|
file.write(m_label_objects.all_objects_header());
|
||||||
|
|
||||||
|
bool adaptive_bed_mesh_ready = false;
|
||||||
|
Vec2d adaptive_bed_mesh_min;
|
||||||
|
Vec2d adaptive_bed_mesh_max;
|
||||||
|
int adaptive_probe_count_x = 0;
|
||||||
|
int adaptive_probe_count_y = 0;
|
||||||
|
const char *adaptive_bed_mesh_algo = nullptr;
|
||||||
|
const bool host_is_klipper = (this->config().host_type.value == htMoonraker);
|
||||||
|
|
||||||
// Update output variables after the extruders were initialized.
|
// Update output variables after the extruders were initialized.
|
||||||
m_placeholder_parser_integration.init(m_writer);
|
m_placeholder_parser_integration.init(m_writer);
|
||||||
// Let the start-up script prime the 1st printing tool.
|
// Let the start-up script prime the 1st printing tool.
|
||||||
@@ -1206,7 +1214,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
this->placeholder_parser().set("print_bed_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
this->placeholder_parser().set("print_bed_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
||||||
this->placeholder_parser().set("print_bed_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
this->placeholder_parser().set("print_bed_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
||||||
}
|
}
|
||||||
{
|
if (host_is_klipper) {
|
||||||
// Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line.
|
// Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line.
|
||||||
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.
|
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.
|
||||||
// It does NOT encompass user extrusions generated by custom G-code,
|
// It does NOT encompass user extrusions generated by custom G-code,
|
||||||
@@ -1222,6 +1230,53 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
this->placeholder_parser().set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
this->placeholder_parser().set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
||||||
this->placeholder_parser().set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
this->placeholder_parser().set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
||||||
this->placeholder_parser().set("num_extruders", int(print.config().nozzle_diameter.values.size()));
|
this->placeholder_parser().set("num_extruders", int(print.config().nozzle_diameter.values.size()));
|
||||||
|
|
||||||
|
BoundingBoxf bed_bbox(print.config().bed_shape.values);
|
||||||
|
BoundingBoxf mesh_bbox = bbox;
|
||||||
|
if (bed_bbox.defined) {
|
||||||
|
const double margin = print.config().adaptive_bed_mesh_margin.value;
|
||||||
|
double min_x = bbox.min.x() - margin;
|
||||||
|
double min_y = bbox.min.y() - margin;
|
||||||
|
double max_x = bbox.max.x() + margin;
|
||||||
|
double max_y = bbox.max.y() + margin;
|
||||||
|
|
||||||
|
min_x = std::max(min_x, bed_bbox.min.x());
|
||||||
|
min_y = std::max(min_y, bed_bbox.min.y());
|
||||||
|
max_x = std::min(max_x, bed_bbox.max.x());
|
||||||
|
max_y = std::min(max_y, bed_bbox.max.y());
|
||||||
|
|
||||||
|
const Vec2d limit_min = print.config().bed_mesh_limit_min.value;
|
||||||
|
const Vec2d limit_max = print.config().bed_mesh_limit_max.value;
|
||||||
|
if (limit_min.x() > -99998 || limit_min.y() > -99998) {
|
||||||
|
min_x = std::max(min_x, limit_min.x());
|
||||||
|
min_y = std::max(min_y, limit_min.y());
|
||||||
|
}
|
||||||
|
if (limit_max.x() > -99998 || limit_max.y() > -99998) {
|
||||||
|
max_x = std::min(max_x, limit_max.x());
|
||||||
|
max_y = std::min(max_y, limit_max.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh_bbox.min = Vec2d(min_x, min_y);
|
||||||
|
mesh_bbox.max = Vec2d(max_x, max_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
adaptive_bed_mesh_min = mesh_bbox.min;
|
||||||
|
adaptive_bed_mesh_max = mesh_bbox.max;
|
||||||
|
adaptive_bed_mesh_ready = true;
|
||||||
|
|
||||||
|
this->placeholder_parser().set("adaptive_bed_mesh_min", new ConfigOptionFloats({ mesh_bbox.min.x(), mesh_bbox.min.y() }));
|
||||||
|
this->placeholder_parser().set("adaptive_bed_mesh_max", new ConfigOptionFloats({ mesh_bbox.max.x(), mesh_bbox.max.y() }));
|
||||||
|
|
||||||
|
const Vec2d probe_dist = print.config().bed_mesh_probe_distance.value;
|
||||||
|
const double probe_dist_x = std::max(1.0, probe_dist.x());
|
||||||
|
const double probe_dist_y = std::max(1.0, probe_dist.y());
|
||||||
|
const int probe_count_x = std::max(3, int(std::ceil(mesh_bbox.size().x() / probe_dist_x)) + 1);
|
||||||
|
const int probe_count_y = std::max(3, int(std::ceil(mesh_bbox.size().y() / probe_dist_y)) + 1);
|
||||||
|
adaptive_probe_count_x = probe_count_x;
|
||||||
|
adaptive_probe_count_y = probe_count_y;
|
||||||
|
this->placeholder_parser().set("bed_mesh_probe_count", new ConfigOptionInts({ probe_count_x, probe_count_y }));
|
||||||
|
adaptive_bed_mesh_algo = (probe_count_x < 4 || probe_count_y < 4) ? "lagrange" : "bicubic";
|
||||||
|
this->placeholder_parser().set("bed_mesh_algo", new ConfigOptionString(adaptive_bed_mesh_algo));
|
||||||
// PlaceholderParser currently substitues non-existent vector values with the zero'th value, which is harmful in the case of "is_extruder_used[]"
|
// PlaceholderParser currently substitues non-existent vector values with the zero'th value, which is harmful in the case of "is_extruder_used[]"
|
||||||
// as Slicer may lie about availability of such non-existent extruder.
|
// as Slicer may lie about availability of such non-existent extruder.
|
||||||
// We rather sacrifice 256B of memory before we change the behavior of the PlaceholderParser, which should really only fill in the non-existent
|
// We rather sacrifice 256B of memory before we change the behavior of the PlaceholderParser, which should really only fill in the non-existent
|
||||||
@@ -1235,7 +1290,14 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
// Enable ooze prevention if configured so.
|
// Enable ooze prevention if configured so.
|
||||||
DoExport::init_ooze_prevention(print, m_ooze_prevention);
|
DoExport::init_ooze_prevention(print, m_ooze_prevention);
|
||||||
|
|
||||||
std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id);
|
const std::string &start_gcode_template = print.config().start_gcode.value;
|
||||||
|
const bool uses_adaptive_bed_mesh_placeholders =
|
||||||
|
start_gcode_template.find("adaptive_bed_mesh_min") != std::string::npos ||
|
||||||
|
start_gcode_template.find("adaptive_bed_mesh_max") != std::string::npos ||
|
||||||
|
start_gcode_template.find("bed_mesh_probe_count") != std::string::npos ||
|
||||||
|
start_gcode_template.find("bed_mesh_algo") != std::string::npos;
|
||||||
|
|
||||||
|
std::string start_gcode = this->placeholder_parser_process("start_gcode", start_gcode_template, initial_extruder_id);
|
||||||
|
|
||||||
this->_print_first_layer_chamber_temperature(file, print, start_gcode, config().chamber_temperature.get_at(initial_extruder_id), false, false);
|
this->_print_first_layer_chamber_temperature(file, print, start_gcode, config().chamber_temperature.get_at(initial_extruder_id), false, false);
|
||||||
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);
|
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);
|
||||||
@@ -1245,6 +1307,13 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
|||||||
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), gcode_extrusion_role_to_string(GCodeExtrusionRole::Custom).c_str());
|
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), gcode_extrusion_role_to_string(GCodeExtrusionRole::Custom).c_str());
|
||||||
|
|
||||||
// Write the custom start G-code
|
// Write the custom start G-code
|
||||||
|
if (host_is_klipper && adaptive_bed_mesh_ready && uses_adaptive_bed_mesh_placeholders) {
|
||||||
|
file.write_format("; Adaptive bed mesh: min=%.3f,%.3f max=%.3f,%.3f probe_count=%d,%d algo=%s\n",
|
||||||
|
adaptive_bed_mesh_min.x(), adaptive_bed_mesh_min.y(),
|
||||||
|
adaptive_bed_mesh_max.x(), adaptive_bed_mesh_max.y(),
|
||||||
|
adaptive_probe_count_x, adaptive_probe_count_y,
|
||||||
|
adaptive_bed_mesh_algo ? adaptive_bed_mesh_algo : "");
|
||||||
|
}
|
||||||
file.writeln(start_gcode);
|
file.writeln(start_gcode);
|
||||||
|
|
||||||
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true);
|
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true);
|
||||||
|
|||||||
@@ -346,6 +346,35 @@ void PrintConfigDef::init_common_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) });
|
def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) });
|
||||||
|
|
||||||
|
def = this->add("bed_mesh_limit_min", coPoint);
|
||||||
|
def->label = L("Bed mesh min");
|
||||||
|
def->tooltip = L("Minimum point for allowed bed mesh area. Default is no limits.");
|
||||||
|
def->sidetext = L("mm");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionPoint(Vec2d(-99999, -99999)));
|
||||||
|
|
||||||
|
def = this->add("bed_mesh_limit_max", coPoint);
|
||||||
|
def->label = L("Bed mesh max");
|
||||||
|
def->tooltip = L("Maximum point for allowed bed mesh area. Default is no limits.");
|
||||||
|
def->sidetext = L("mm");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionPoint(Vec2d(-99999, -99999)));
|
||||||
|
|
||||||
|
def = this->add("bed_mesh_probe_distance", coPoint);
|
||||||
|
def->label = L("Probe point distance");
|
||||||
|
def->tooltip = L("Distance between probe points for bed mesh, as X,Y.");
|
||||||
|
def->sidetext = L("mm");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionPoint(Vec2d(25, 25)));
|
||||||
|
|
||||||
|
def = this->add("adaptive_bed_mesh_margin", coFloat);
|
||||||
|
def->label = L("Mesh margin");
|
||||||
|
def->tooltip = L("Extra margin around first-layer print area used for adaptive bed mesh.");
|
||||||
|
def->sidetext = L("mm");
|
||||||
|
def->min = 0;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionFloat(0.0));
|
||||||
|
|
||||||
def = this->add("auto_arrange_bed_clearance", coFloat);
|
def = this->add("auto_arrange_bed_clearance", coFloat);
|
||||||
def->label = L("Auto-arrange bed clearance");
|
def->label = L("Auto-arrange bed clearance");
|
||||||
def->tooltip = L("Minimum distance from the bed edge when auto arranging.");
|
def->tooltip = L("Minimum distance from the bed edge when auto arranging.");
|
||||||
@@ -2241,7 +2270,7 @@ void PrintConfigDef::init_fff_params()
|
|||||||
{ "prusalink", "PrusaLink" },
|
{ "prusalink", "PrusaLink" },
|
||||||
{ "prusaconnect", "PrusaConnect" },
|
{ "prusaconnect", "PrusaConnect" },
|
||||||
{ "octoprint", "OctoPrint" },
|
{ "octoprint", "OctoPrint" },
|
||||||
{ "moonraker", "Klipper (via Moonraker)" },
|
{ "moonraker", "Klipper (Moonraker)" },
|
||||||
{ "duet", "Duet" },
|
{ "duet", "Duet" },
|
||||||
{ "flashair", "FlashAir" },
|
{ "flashair", "FlashAir" },
|
||||||
{ "astrobox", "AstroBox" },
|
{ "astrobox", "AstroBox" },
|
||||||
|
|||||||
@@ -857,7 +857,11 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||||||
((ConfigOptionBool, avoid_crossing_perimeters))
|
((ConfigOptionBool, avoid_crossing_perimeters))
|
||||||
((ConfigOptionFloatOrPercent, avoid_crossing_perimeters_max_detour))
|
((ConfigOptionFloatOrPercent, avoid_crossing_perimeters_max_detour))
|
||||||
((ConfigOptionPoints, bed_shape))
|
((ConfigOptionPoints, bed_shape))
|
||||||
|
((ConfigOptionPoint, bed_mesh_probe_distance))
|
||||||
|
((ConfigOptionPoint, bed_mesh_limit_min))
|
||||||
|
((ConfigOptionPoint, bed_mesh_limit_max))
|
||||||
((ConfigOptionInts, bed_temperature))
|
((ConfigOptionInts, bed_temperature))
|
||||||
|
((ConfigOptionFloat, adaptive_bed_mesh_margin))
|
||||||
((ConfigOptionFloat, bridge_acceleration))
|
((ConfigOptionFloat, bridge_acceleration))
|
||||||
((ConfigOptionInts, bridge_fan_speed))
|
((ConfigOptionInts, bridge_fan_speed))
|
||||||
((ConfigOptionBools, enable_dynamic_fan_speeds))
|
((ConfigOptionBools, enable_dynamic_fan_speeds))
|
||||||
@@ -909,6 +913,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||||||
((ConfigOptionFloat, perimeter_acceleration))
|
((ConfigOptionFloat, perimeter_acceleration))
|
||||||
((ConfigOptionStrings, post_process))
|
((ConfigOptionStrings, post_process))
|
||||||
((ConfigOptionBool, prefer_clockwise_movements))
|
((ConfigOptionBool, prefer_clockwise_movements))
|
||||||
|
((ConfigOptionEnum<PrintHostType>, host_type))
|
||||||
((ConfigOptionString, printer_model))
|
((ConfigOptionString, printer_model))
|
||||||
((ConfigOptionString, printer_notes))
|
((ConfigOptionString, printer_notes))
|
||||||
((ConfigOptionFloat, resolution))
|
((ConfigOptionFloat, resolution))
|
||||||
|
|||||||
Reference in New Issue
Block a user