diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index f3a9661a7..a0e969519 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -549,6 +549,7 @@ void Layer::make_ironing() // speed: 20 mm/sec }; + std::unordered_map fill_2_ironing_coll; std::vector by_extruder; bool extruder_dont_care = this->object()->config().wipe_into_objects; double default_layer_height = this->object()->config().layer_height; @@ -631,9 +632,33 @@ void Layer::make_ironing() } catch (InfillFailedException &) { } if (! polylines.empty()) { + //always extrude ironing after infill + ExtrusionEntityCollection* eec_ironing; + if (fill_2_ironing_coll.find(&ironing_params.layerm->fills) == fill_2_ironing_coll.end()) { + if (ironing_params.layerm->fills.empty()) { + eec_ironing = &ironing_params.layerm->fills; + fill_2_ironing_coll[&ironing_params.layerm->fills] = eec_ironing; + } else { + //create the "normal fill" collection + ExtrusionEntityCollection* eec_before_layer_ironing = new ExtrusionEntityCollection(ironing_params.layerm->fills); + eec_before_layer_ironing->no_sort = ironing_params.layerm->fills.no_sort; + //create the "ironing fill" collection + eec_ironing = new ExtrusionEntityCollection(); + eec_ironing->no_sort = false; + fill_2_ironing_coll[&ironing_params.layerm->fills] = eec_ironing; + //add them as fills in the right order (and we need an other ExtrusionEntityCollection, as the no_sort of fills isn't read anywhere) + ExtrusionEntityCollection* eec_root = new ExtrusionEntityCollection(); + ironing_params.layerm->fills.clear(); + ironing_params.layerm->fills.entities.push_back(eec_root); + eec_root->entities.push_back(eec_before_layer_ironing); + eec_root->entities.push_back(eec_ironing); + eec_root->no_sort = true; + } + } else + eec_ironing = fill_2_ironing_coll[&ironing_params.layerm->fills]; // Save into layer. - ExtrusionEntityCollection *eec = nullptr; - ironing_params.layerm->fills.entities.push_back(eec = new ExtrusionEntityCollection()); + ExtrusionEntityCollection *eec = new ExtrusionEntityCollection(); + eec_ironing->entities.push_back(eec); // Don't sort the ironing infill lines as they are monotonicly ordered. eec->no_sort = true; extrusion_entities_append_paths( diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 4aa392f19..8415e19bb 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -147,6 +147,26 @@ std::pair Fill::_infill_direction(const Surface *surface) const return std::pair(out_angle, out_shift); } +double Fill::compute_unscaled_volume_to_fill(const Surface* surface, const FillParams& params) const { + double polyline_volume = 0; + for (auto poly = this->no_overlap_expolygons.begin(); poly != this->no_overlap_expolygons.end(); ++poly) { + polyline_volume += params.flow.height * unscaled(unscaled(poly->area())); + double perimeter_gap_usage = params.config->perimeter_overlap.get_abs_value(1); + // add external "perimeter gap" + double perimeter_round_gap = unscaled(poly->contour.length()) * params.flow.height * (1 - 0.25 * PI) * 0.5; + // add holes "perimeter gaps" + double holes_gaps = 0; + for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole) { + holes_gaps += unscaled(hole->length()) * params.flow.height * (1 - 0.25 * PI) * 0.5; + } + polyline_volume += (perimeter_round_gap + holes_gaps) * perimeter_gap_usage; + } + if (this->no_overlap_expolygons.empty()) { + polyline_volume = unscaled(unscaled(surface->area())) * params.flow.height; + } + return polyline_volume; +} + void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) const { //add overlap & call fill_surface Polylines polylines; @@ -158,33 +178,28 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ return; // ensure it doesn't over or under-extrude - double multFlow = 1; + double mult_flow = 1; if (!params.dont_adjust && params.full_infill() && !params.flow.bridge && params.fill_exactly){ // compute the path of the nozzle -> extruded volume - double lengthTot = 0; - int nbLines = 0; + double length_tot = 0; for (auto pline = polylines.begin(); pline != polylines.end(); ++pline){ Lines lines = pline->lines(); for (auto line = lines.begin(); line != lines.end(); ++line){ - lengthTot += unscaled(line->length()); - nbLines++; + length_tot += unscaled(line->length()); } } - double extrudedVolume = params.flow.mm3_per_mm() * lengthTot; + double extruded_volume = params.flow.mm3_per_mm() * length_tot; // compute real volume - double poylineVolume = 0; - for (auto poly = this->no_overlap_expolygons.begin(); poly != this->no_overlap_expolygons.end(); ++poly) { - poylineVolume += params.flow.height*unscaled(unscaled(poly->area())); - } + double polyline_volume = compute_unscaled_volume_to_fill(surface, params); //printf("process want %f mm3 extruded for a volume of %f space : we mult by %f %i\n", // extrudedVolume, // (poylineVolume), // (poylineVolume) / extrudedVolume, // this->no_overlap_expolygons.size()); - if (extrudedVolume != 0 && poylineVolume != 0) multFlow = poylineVolume / extrudedVolume; + if (extruded_volume != 0 && polyline_volume != 0) mult_flow = polyline_volume / extruded_volume; //failsafe, it can happen - if (multFlow > 1.3) multFlow = 1.3; - if (multFlow < 0.8) multFlow = 0.8; + if (mult_flow > 1.3) mult_flow = 1.3; + if (mult_flow < 0.8) mult_flow = 0.8; } // Save into layer. @@ -199,8 +214,8 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ extrusion_entities_append_paths( eec->entities, std::move(polylines), good_role, - params.flow.mm3_per_mm() * params.flow_mult * multFlow, - (float)(params.flow.width * params.flow_mult * multFlow), + params.flow.mm3_per_mm() * params.flow_mult * mult_flow, + (float)(params.flow.width * params.flow_mult * mult_flow), (float)params.flow.height); } diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 190942a83..48c043b10 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -156,7 +156,9 @@ protected: virtual std::pair _infill_direction(const Surface *surface) const; - void do_gap_fill(const ExPolygons &gapfill_areas, const FillParams ¶ms, ExtrusionEntitiesPtr &coll_out) const; + void do_gap_fill(const ExPolygons& gapfill_areas, const FillParams& params, ExtrusionEntitiesPtr& coll_out) const; + + double compute_unscaled_volume_to_fill(const Surface* surface, const FillParams& params) const; ExtrusionRole getRoleFromSurfaceType(const FillParams ¶ms, const Surface *surface) const { if (params.role == erNone || params.role == erCustom) { diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index d9ac66539..3233eaaac 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -3287,19 +3287,7 @@ FillRectilinearWGapFill::fill_surface_extrusion(const Surface *surface, const Fi } double extrudedVolume = params.flow.mm3_per_mm() * lengthTot; // compute real volume - double poylineVolume = 0; - ExPolygons rectilinear_no_overlap_areas = intersection_ex(rectilinear_areas, this->no_overlap_expolygons); - for (const ExPolygon &poly : rectilinear_no_overlap_areas) { - poylineVolume += params.flow.height*unscaled(unscaled(poly.area())); - // add external "perimeter gap" - double perimeterRoundGap = unscaled(poly.contour.length()) * params.flow.height * (1 - 0.25*PI) * 0.5; - // add holes "perimeter gaps" - double holesGaps = 0; - for (auto hole = poly.holes.begin(); hole != poly.holes.end(); ++hole) { - holesGaps += unscaled(hole->length()) * params.flow.height * (1 - 0.25*PI) * 0.5; - } - poylineVolume += perimeterRoundGap + holesGaps; - } + double poylineVolume = compute_unscaled_volume_to_fill(surface, params); //printf("process want %f mm3 extruded for a volume of %f space : we mult by %f %i\n", // extrudedVolume, // (poylineVolume), diff --git a/src/libslic3r/Fill/FillSmooth.cpp b/src/libslic3r/Fill/FillSmooth.cpp index 7c21fc5b7..1591081b9 100644 --- a/src/libslic3r/Fill/FillSmooth.cpp +++ b/src/libslic3r/Fill/FillSmooth.cpp @@ -106,24 +106,7 @@ namespace Slic3r { coordf_t init_spacing = this->get_spacing(); // compute the volume to extrude - double volumeToOccupy = 0; - for (auto poly = this->no_overlap_expolygons.begin(); poly != this->no_overlap_expolygons.end(); ++poly) { - // add external "perimeter gap" - double poylineVolume = params.flow.height*unscaled(unscaled(poly->area())); - double perimeterRoundGap = unscaled(poly->contour.length()) * params.flow.height * (1 - 0.25*PI) * 0.5; - // add holes "perimeter gaps" - double holesGaps = 0; - for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole) { - holesGaps += unscaled(hole->length()) * params.flow.height * (1 - 0.25*PI) * 0.5; - } - poylineVolume += perimeterRoundGap + holesGaps; - - //extruded volume: see http://manual.slic3r.org/advanced/flow-math, and we need to remove a circle at an end (as the flow continue) - volumeToOccupy += poylineVolume; - } - if (this->no_overlap_expolygons.empty()) { - volumeToOccupy = unscaled(unscaled(surface->area())) * params.flow.height; - } + double volume_to_occupy = compute_unscaled_volume_to_fill(surface, params); //create root node ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection(); @@ -134,7 +117,7 @@ namespace Slic3r { FillParams first_pass_params = params; if(first_pass_params.role != ExtrusionRole::erSupportMaterial && first_pass_params.role != ExtrusionRole::erSupportMaterialInterface) first_pass_params.role = ExtrusionRole::erSolidInfill; - perform_single_fill(0, *eecroot, *surface, first_pass_params, volumeToOccupy); + perform_single_fill(0, *eecroot, *surface, first_pass_params, volume_to_occupy); //use monotonic for ironing pass FillParams monotonic_params = params; @@ -142,12 +125,12 @@ namespace Slic3r { //second infill if (nbPass > 1){ - perform_single_fill(1, *eecroot, *surface, monotonic_params, volumeToOccupy); + perform_single_fill(1, *eecroot, *surface, monotonic_params, volume_to_occupy); } // third infill if (nbPass > 2){ - perform_single_fill(2, *eecroot, *surface, monotonic_params, volumeToOccupy); + perform_single_fill(2, *eecroot, *surface, monotonic_params, volume_to_occupy); } if (!eecroot->entities.empty()) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 28023cff9..1558ef2a5 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2478,12 +2478,9 @@ void GCode::process_layer( extruder_id, print_wipe_extrusions != 0) : island.by_region; - gcode += this->extrude_infill(print, by_region_specific, true, false); + gcode += this->extrude_infill(print, by_region_specific, true); gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]); - gcode += this->extrude_infill(print, by_region_specific, false, false); - - // ironing - gcode += this->extrude_infill(print,by_region_specific, false, true); + gcode += this->extrude_infill(print, by_region_specific, false); } if (this->config().gcode_label_objects) gcode += std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name @@ -3329,32 +3326,24 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector &by_region, bool is_infill_first, bool ironing) +std::string GCode::extrude_infill(const Print &print, const std::vector &by_region, bool is_infill_first) { std::string gcode; - ExtrusionEntitiesPtr extrusions; for (const ObjectByExtruder::Island::Region ®ion : by_region) { if (!region.infills.empty() && - ( ironing || print.regions()[®ion - &by_region.front()]->config().infill_first == is_infill_first) ) { - extrusions.clear(); - extrusions.reserve(region.infills.size()); - for (ExtrusionEntity *ee : region.infills) - if ((ee->role() == erIroning) == ironing) - extrusions.emplace_back(ee); - if (! extrusions.empty()) { - m_config.apply(print.regions()[®ion - &by_region.front()]->config()); - m_writer.apply_print_region_config(print.regions()[®ion - &by_region.front()]->config()); - if (m_config.print_temperature > 0) - gcode += m_writer.set_temperature(m_config.print_temperature.value, false, m_writer.tool()->id()); + ( print.regions()[®ion - &by_region.front()]->config().infill_first == is_infill_first) ) { + m_config.apply(print.regions()[®ion - &by_region.front()]->config()); + m_writer.apply_print_region_config(print.regions()[®ion - &by_region.front()]->config()); + if (m_config.print_temperature > 0) + gcode += m_writer.set_temperature(m_config.print_temperature.value, false, m_writer.tool()->id()); else if(m_layer!=nullptr && m_layer->bottom_z() < EPSILON) gcode += m_writer.set_temperature(m_config.first_layer_temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id()); - else - gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id()); - ExtrusionEntitiesPtr extrusions { region.infills }; - chain_and_reorder_extrusion_entities(extrusions, &m_last_pos); - for (const ExtrusionEntity* fill : extrusions) { - gcode += extrude_entity(*fill, ""); - } + else + gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id()); + ExtrusionEntitiesPtr extrusions { region.infills }; + chain_and_reorder_extrusion_entities(extrusions, &m_last_pos); + for (const ExtrusionEntity* fill : extrusions) { + gcode += extrude_entity(*fill, ""); } } } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 8909e9ff8..29e3aa49c 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -328,7 +328,7 @@ private: const size_t single_object_instance_idx); std::string extrude_perimeters(const Print &print, const std::vector &by_region, std::unique_ptr &lower_layer_edge_grid); - std::string extrude_infill(const Print &print, const std::vector &by_region, bool is_infill_first, bool ironing); + std::string extrude_infill(const Print &print, const std::vector &by_region, bool is_infill_first); std::string extrude_support(const ExtrusionEntityCollection &support_fills); std::string travel_to(const Point &point, ExtrusionRole role, std::string comment); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 4dbac9aad..9393a7d72 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2513,7 +2513,7 @@ end: // Optimized version for a single region layer. if (layer->regions().size() == 1) { assert(!upscaled); - assert(!clipped); + //assert(!clipped); //can happen with z-range modifier // Single region, growing or shrinking. LayerRegion *layerm = layer->regions().front(); ExPolygons expolygons = to_expolygons(std::move(layerm->m_slices.surfaces));