Fix of "Bridging and gap fill are parsed incorrectly when infill is set to 0"

The gap fill was disabled for zero infill.
Now the gap fill is enabled in between the perimeters, but disabled between
the inner-most perimeter and infill in case the infill is set to zero.

Also in case there are multiple infill regions inside a perimeter,
the mutliple infills are considered as non-zero if at least one infill
is non-zero, therefore the gap fill will be added inside the inner-most
perimeter.
This commit is contained in:
bubnikv 2019-09-10 19:03:37 +02:00
parent 84e8081413
commit 246dc64c99
3 changed files with 19 additions and 7 deletions

View file

@ -121,7 +121,6 @@ void Layer::make_perimeters()
for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it) { for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it) {
LayerRegion* other_layerm = *it; LayerRegion* other_layerm = *it;
const PrintRegionConfig &other_config = other_layerm->region()->config(); const PrintRegionConfig &other_config = other_layerm->region()->config();
if (config.perimeter_extruder == other_config.perimeter_extruder if (config.perimeter_extruder == other_config.perimeter_extruder
&& config.perimeters == other_config.perimeters && config.perimeters == other_config.perimeters
&& config.perimeter_speed == other_config.perimeter_speed && config.perimeter_speed == other_config.perimeter_speed
@ -130,7 +129,8 @@ void Layer::make_perimeters()
&& config.overhangs == other_config.overhangs && config.overhangs == other_config.overhangs
&& config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width") && config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width")
&& config.thin_walls == other_config.thin_walls && config.thin_walls == other_config.thin_walls
&& config.external_perimeters_first == other_config.external_perimeters_first) { && config.external_perimeters_first == other_config.external_perimeters_first
&& config.infill_overlap == other_config.infill_overlap) {
layerms.push_back(other_layerm); layerms.push_back(other_layerm);
done[it - m_regions.begin()] = true; done[it - m_regions.begin()] = true;
} }
@ -142,12 +142,17 @@ void Layer::make_perimeters()
(*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces); (*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
} else { } else {
SurfaceCollection new_slices; SurfaceCollection new_slices;
// Use the region with highest infill rate, as the make_perimeters() function below decides on the gap fill based on the infill existence.
LayerRegion *layerm_config = layerms.front();
{ {
// group slices (surfaces) according to number of extra perimeters // group slices (surfaces) according to number of extra perimeters
std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ] std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
for (LayerRegion *layerm : layerms) for (LayerRegion *layerm : layerms) {
for (Surface &surface : layerm->slices.surfaces) for (Surface &surface : layerm->slices.surfaces)
slices[surface.extra_perimeters].emplace_back(surface); slices[surface.extra_perimeters].emplace_back(surface);
if (layerm->region()->config().fill_density > layerm_config->region()->config().fill_density)
layerm_config = layerm;
}
// merge the surfaces assigned to each group // merge the surfaces assigned to each group
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices) for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front()); new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front());
@ -155,7 +160,7 @@ void Layer::make_perimeters()
// make perimeters // make perimeters
SurfaceCollection fill_surfaces; SurfaceCollection fill_surfaces;
(*layerm)->make_perimeters(new_slices, &fill_surfaces); layerm_config->make_perimeters(new_slices, &fill_surfaces);
// assign fill_surfaces to each layer // assign fill_surfaces to each layer
if (!fill_surfaces.surfaces.empty()) { if (!fill_surfaces.surfaces.empty()) {

View file

@ -37,7 +37,8 @@ void PerimeterGenerator::process()
// internal flow which is unrelated. // internal flow which is unrelated.
coord_t min_spacing = perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); coord_t min_spacing = perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE);
coord_t ext_min_spacing = ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); coord_t ext_min_spacing = ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE);
bool has_gap_fill = this->config->gap_fill_speed.value > 0;
// prepare grown lower layer slices for overhang detection // prepare grown lower layer slices for overhang detection
if (this->lower_slices != NULL && this->config->overhangs) { if (this->lower_slices != NULL && this->config->overhangs) {
// We consider overhang any part where the entire nozzle diameter is not supported by the // We consider overhang any part where the entire nozzle diameter is not supported by the
@ -105,7 +106,7 @@ void PerimeterGenerator::process()
// leads to overflows, as in prusa3d/Slic3r GH #32 // leads to overflows, as in prusa3d/Slic3r GH #32
offset_ex(last, - distance); offset_ex(last, - distance);
// look for gaps // look for gaps
if (this->config->gap_fill_speed.value > 0 && this->config->fill_density.value > 0) if (has_gap_fill)
// not using safety offset here would "detect" very narrow gaps // not using safety offset here would "detect" very narrow gaps
// (but still long enough to escape the area threshold) that gap fill // (but still long enough to escape the area threshold) that gap fill
// won't be able to fill but we'd still remove from infill area // won't be able to fill but we'd still remove from infill area
@ -132,6 +133,11 @@ void PerimeterGenerator::process()
} }
} }
last = std::move(offsets); last = std::move(offsets);
if (i == loop_number && (! has_gap_fill || this->config->fill_density.value == 0)) {
// The last run of this loop is executed to collect gaps for gap fill.
// As the gap fill is either disabled or not
break;
}
} }
// nest loops: holes first // nest loops: holes first

View file

@ -243,7 +243,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
"infill_speed", "bridge_speed" }) "infill_speed", "bridge_speed" })
toggle_field(el, have_infill || have_solid_infill); toggle_field(el, have_infill || have_solid_infill);
toggle_field("gap_fill_speed", have_perimeters && have_infill); // Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
toggle_field("gap_fill_speed", have_perimeters);
bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0; bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0;
for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" }) for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })