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
This commit is contained in:
Lukas Matena 2019-08-07 10:54:36 +02:00
parent 5ee69842d0
commit f61c982111

View file

@ -442,6 +442,7 @@ std::vector<GCode::LayerToPrint> 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::LayerToPrint> 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)