Fix of crash when using raft with modified Shape-Box with height 0.5mm

Reworked skirt generator to only generate skirt at non-empty layers
(layers that actually extruder object or support) and to respect minimum
layer height. Skirt generator stops at the first layer where those both
conditions cannot be met.
This commit is contained in:
Vojtech Bubnik 2021-02-25 12:18:00 +01:00
parent 1e33b95ed7
commit 43c05d35ea
4 changed files with 87 additions and 42 deletions
src/libslic3r

View file

@ -1803,7 +1803,6 @@ namespace Skirt {
static std::map<unsigned int, std::pair<size_t, size_t>> make_skirt_loops_per_extruder_1st_layer(
const Print &print,
const std::vector<GCode::LayerToPrint> & /*layers */,
const LayerTools &layer_tools,
// Heights (print_z) at which the skirt has already been extruded.
std::vector<coordf_t> &skirt_done)
@ -1811,7 +1810,8 @@ namespace Skirt {
// Extrude skirt at the print_z of the raft layers and normal object layers
// not at the print_z of the interlaced support material layers.
std::map<unsigned int, std::pair<size_t, size_t>> skirt_loops_per_extruder_out;
if (skirt_done.empty() && print.has_skirt() && ! print.skirt().entities.empty()) {
assert(skirt_done.empty());
if (skirt_done.empty() && print.has_skirt() && ! print.skirt().entities.empty() && layer_tools.has_skirt) {
skirt_loops_per_extruder_all_printing(print, layer_tools, skirt_loops_per_extruder_out);
skirt_done.emplace_back(layer_tools.print_z);
}
@ -1820,36 +1820,34 @@ namespace Skirt {
static std::map<unsigned int, std::pair<size_t, size_t>> make_skirt_loops_per_extruder_other_layers(
const Print &print,
const std::vector<GCode::LayerToPrint> &layers,
const LayerTools &layer_tools,
// First non-empty support layer.
const SupportLayer *support_layer,
// Heights (print_z) at which the skirt has already been extruded.
std::vector<coordf_t> &skirt_done)
{
// Extrude skirt at the print_z of the raft layers and normal object layers
// not at the print_z of the interlaced support material layers.
std::map<unsigned int, std::pair<size_t, size_t>> skirt_loops_per_extruder_out;
if (print.has_skirt() && ! print.skirt().entities.empty() &&
if (print.has_skirt() && ! print.skirt().entities.empty() && layer_tools.has_skirt &&
// Not enough skirt layers printed yet.
//FIXME infinite or high skirt does not make sense for sequential print!
(skirt_done.size() < (size_t)print.config().skirt_height.value || print.has_infinite_skirt()) &&
(skirt_done.size() < (size_t)print.config().skirt_height.value || print.has_infinite_skirt())) {
bool valid = ! skirt_done.empty() && skirt_done.back() < layer_tools.print_z - EPSILON;
assert(valid);
// This print_z has not been extruded yet (sequential print)
// FIXME: The skirt_done should not be empty at this point. The check is a workaround
// of https://github.com/prusa3d/PrusaSlicer/issues/5652, but it deserves a real fix.
(! skirt_done.empty() && skirt_done.back() < layer_tools.print_z - EPSILON) &&
// and this layer is an object layer, or it is a raft layer.
(layer_tools.has_object || support_layer->id() < (size_t)support_layer->object()->config().raft_layers.value)) {
if (valid) {
#if 0
// Prime just the first printing extruder. This is original Slic3r's implementation.
skirt_loops_per_extruder_out[layer_tools.extruders.front()] = std::pair<size_t, size_t>(0, print.config().skirts.value);
// Prime just the first printing extruder. This is original Slic3r's implementation.
skirt_loops_per_extruder_out[layer_tools.extruders.front()] = std::pair<size_t, size_t>(0, print.config().skirts.value);
#else
// Prime all extruders planned for this layer, see
// https://github.com/prusa3d/PrusaSlicer/issues/469#issuecomment-322450619
skirt_loops_per_extruder_all_printing(print, layer_tools, skirt_loops_per_extruder_out);
// Prime all extruders planned for this layer, see
// https://github.com/prusa3d/PrusaSlicer/issues/469#issuecomment-322450619
skirt_loops_per_extruder_all_printing(print, layer_tools, skirt_loops_per_extruder_out);
#endif
assert(!skirt_done.empty());
skirt_done.emplace_back(layer_tools.print_z);
assert(!skirt_done.empty());
skirt_done.emplace_back(layer_tools.print_z);
}
}
return skirt_loops_per_extruder_out;
}
@ -1992,8 +1990,8 @@ void GCode::process_layer(
// Extrude skirt at the print_z of the raft layers and normal object layers
// not at the print_z of the interlaced support material layers.
skirt_loops_per_extruder = first_layer ?
Skirt::make_skirt_loops_per_extruder_1st_layer(print, layers, layer_tools, m_skirt_done) :
Skirt::make_skirt_loops_per_extruder_other_layers(print, layers, layer_tools, support_layer, m_skirt_done);
Skirt::make_skirt_loops_per_extruder_1st_layer(print, layer_tools, m_skirt_done) :
Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done);
// Group extrusions by an extruder, then by an object, an island and a region.
std::map<unsigned int, std::vector<ObjectByExtruder>> by_extruder;