From f61c982111ec15567082fb46c985380ece2f6413 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 7 Aug 2019 10:54:36 +0200 Subject: [PATCH] GCode.cpp: fixed detection of empty layers so it doesn't give false positives That could happen on empty support layers which do not necessarily matter, since their spacing is not generally synchronized with the object The new hopefully correct logic is "if there are extrusions on a layer, check that last layer with extrusions is at most the new layer height below This is a fixup of changes from 0de6e53 and 6ab1cec --- src/libslic3r/GCode.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index aa857e8e4..f21baaab4 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -442,6 +442,7 @@ std::vector GCode::collect_layers_to_print(const PrintObjec // Pair the object layers with the support layers by z. size_t idx_object_layer = 0; size_t idx_support_layer = 0; + double last_extrusion_z = 0.; while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) { LayerToPrint layer_to_print; layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer ++] : nullptr; @@ -456,15 +457,16 @@ std::vector GCode::collect_layers_to_print(const PrintObjec } } - // Let's make sure that the last layer is not empty, so we don't build on top of it. - if (! layers_to_print.empty() - && ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) - || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions())) - && (! layers_to_print.back().object_layer || ! layers_to_print.back().object_layer->has_extrusions()) - && (! layers_to_print.back().support_layer || ! layers_to_print.back().support_layer->has_extrusions())) - throw std::runtime_error(_(L("Empty layers detected, the output would not be printable.")) + "\n\n" + - _(L("Object name: ")) + object.model_object()->name + "\n" + _(L("Print z: ")) + - std::to_string(layers_to_print.back().print_z())); + // In case there are extrusions on this layer, check there is a layer to lay it on. + if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) + || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions())) { + if (layer_to_print.print_z() - layer_to_print.layer()->height - EPSILON > last_extrusion_z) + throw std::runtime_error(_(L("Empty layers detected, the output would not be printable.")) + "\n\n" + + _(L("Object name: ")) + object.model_object()->name + "\n" + _(L("Print z: ")) + + std::to_string(layers_to_print.back().print_z())); + // Stash last print_z with extrusions. + last_extrusion_z = layer_to_print.print_z(); + } layers_to_print.emplace_back(layer_to_print); } @@ -766,7 +768,7 @@ void GCode::_do_export(Print &print, FILE *file) mm3_per_mm.erase(std::remove_if(mm3_per_mm.begin(), mm3_per_mm.end(), [](double v) { return v < 0.000001; }), mm3_per_mm.end()); if (! mm3_per_mm.empty()) { // In order to honor max_print_speed we need to find a target volumetric - // speed that we can use throughout the print. So we define this target + // speed that we can use throughout the print. So we define this target // volumetric speed as the volumetric speed produced by printing the // smallest cross-section at the maximum speed: any larger cross-section // will need slower feedrates. @@ -833,7 +835,7 @@ void GCode::_do_export(Print &print, FILE *file) _writeln(file, GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag); } - // Prepare the helper object for replacing placeholders in custom G-code and output filename. + // Prepare the helper object for replacing placeholders in custom G-code and output filename. m_placeholder_parser = print.placeholder_parser(); m_placeholder_parser.update_timestamp(); print.update_object_placeholders(m_placeholder_parser.config_writable(), ".gcode"); @@ -2617,7 +2619,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, EXTRUDER_CONFIG(filament_max_volumetric_speed) / path.mm3_per_mm ); } - double F = speed * 60; // convert mm/sec to mm/min + double F = speed * 60; // convert mm/sec to mm/min // extrude arc or line if (m_enable_extrusion_role_markers)