From f61c982111ec15567082fb46c985380ece2f6413 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 7 Aug 2019 10:54:36 +0200 Subject: [PATCH 1/3] 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) From 1c479ad6c5a9862ea214c63e31a0305ab1d591ea Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 7 Aug 2019 11:17:17 +0200 Subject: [PATCH 2/3] Fix build without PCH --- src/slic3r/GUI/GLTexture.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GLTexture.hpp b/src/slic3r/GUI/GLTexture.hpp index c4063b93d..c8fd01f41 100644 --- a/src/slic3r/GUI/GLTexture.hpp +++ b/src/slic3r/GUI/GLTexture.hpp @@ -5,6 +5,7 @@ #include #include #include +#include class wxImage; From 8e4f777bd33ee6708b7f2dc308de1ea223025d2f Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 7 Aug 2019 12:00:36 +0200 Subject: [PATCH 3/3] One more fix on the empty layers detection - support contact z distance is taken into account If it wasn't, anything with raft would be rejected unless contact z was zero. We do not want that. --- src/libslic3r/GCode.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f21baaab4..02fefceec 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -442,7 +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.; + const LayerToPrint* last_extrusion_layer = nullptr; 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; @@ -457,18 +457,25 @@ std::vector GCode::collect_layers_to_print(const PrintObjec } } + layers_to_print.emplace_back(layer_to_print); + // 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) + double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer) + ? object.config().support_material_contact_distance + : 0.; + double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) + + layer_to_print.layer()->height + + support_contact_z; + + if (layer_to_print.print_z() > maximal_print_z + EPSILON) 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(); + // Remember last layer with extrusions. + last_extrusion_layer = &layers_to_print.back(); } - - layers_to_print.emplace_back(layer_to_print); } return layers_to_print;