diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 18e03e0058..7b7a21f0ae 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -532,6 +532,7 @@ void Layer::make_ironing() } } if (ironing_params.extruder != -1) { + //TODO just_infill is currently not used. ironing_params.just_infill = false; ironing_params.line_spacing = config.ironing_spacing; ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate; @@ -562,17 +563,54 @@ void Layer::make_ironing() ExPolygons ironing_areas; double nozzle_dmr = this->object()->print()->config().nozzle_diameter.values[ironing_params.extruder - 1]; if (ironing_params.just_infill) { + //TODO just_infill is currently not used. // Just infill. } else { // Infill and perimeter. // Merge top surfaces with the same ironing parameters. Polygons polys; - for (size_t k = i; k < j; ++ k) - for (const Surface &surface : by_extruder[k].layerm->slices.surfaces) - if (surface.surface_type == stTop) + Polygons infills; + for (size_t k = i; k < j; ++ k) { + const IroningParams &ironing_params = by_extruder[k]; + const PrintRegionConfig ®ion_config = ironing_params.layerm->region()->config(); + bool iron_everything = region_config.ironing_type == IroningType::AllSolid; + bool iron_completely = iron_everything; + if (iron_everything) { + // Check whether there is any non-solid hole in the regions. + bool internal_infill_solid = region_config.fill_density.value > 95.; + for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces) + if ((! internal_infill_solid && surface.surface_type == stInternal) || surface.surface_type == stInternalBridge || surface.surface_type == stInternalVoid) { + // Some fill region is not quite solid. Don't iron over the whole surface. + iron_completely = false; + break; + } + } + if (iron_completely) { + // Iron everything. This is likely only good for solid transparent objects. + for (const Surface &surface : ironing_params.layerm->slices.surfaces) polygons_append(polys, surface.expolygon); + } else { + for (const Surface &surface : ironing_params.layerm->slices.surfaces) + if (surface.surface_type == stTop || (iron_everything && surface.surface_type == stBottom)) + // stBottomBridge is not being ironed on purpose, as it would likely destroy the bridges. + polygons_append(polys, surface.expolygon); + } + if (iron_everything && ! iron_completely) { + // Add solid fill surfaces. This may not be ideal, as one will not iron perimeters touching these + // solid fill surfaces, but it is likely better than nothing. + for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces) + if (surface.surface_type == stInternalSolid) + polygons_append(infills, surface.expolygon); + } + } // Trim the top surfaces with half the nozzle diameter. ironing_areas = intersection_ex(polys, offset(this->lslices, - float(scale_(0.5 * nozzle_dmr)))); + if (! infills.empty()) { + // For IroningType::AllSolid only: + // Add solid infill areas for layers, that contain some non-ironable infil (sparse infill, bridge infill). + append(infills, to_polygons(std::move(ironing_areas))); + ironing_areas = union_ex(infills, true); + } } // Create the filler object. diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index ee2e645695..233f693e3c 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -399,7 +399,8 @@ void PrintObject::ironing() if (this->set_started(posIroning)) { BOOST_LOG_TRIVIAL(debug) << "Ironing in parallel - start"; tbb::parallel_for( - tbb::blocked_range(1, m_layers.size()), + // Ironing starting with layer 0 to support ironing all surfaces. + tbb::blocked_range(0, m_layers.size()), [this](const tbb::blocked_range& range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { m_print->throw_if_canceled(); @@ -605,7 +606,11 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector