diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index fbc88fcd2..d09a9b9b6 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -16,8 +16,6 @@ namespace Slic3r { struct SurfaceFillParams : FillParams { - // Zero based extruder ID. - unsigned int extruder = 0; // Infill pattern, adjusted for the density etc. InfillPattern pattern = InfillPattern(0); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index b2806c19d..26b73bd25 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -149,20 +149,23 @@ std::pair Fill::_infill_direction(const Surface *surface) const double Fill::compute_unscaled_volume_to_fill(const Surface* surface, const FillParams& params) const { double polyline_volume = 0; - for (const ExPolygon& poly : this->no_overlap_expolygons) { - 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; + } else { + for (const ExPolygon& poly : intersection_ex({ surface->expolygon }, this->no_overlap_expolygons)) { + 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" + //TODO: use filament_max_overlap to reduce it + //double filament_max_overlap = params.config->get_computed_value("filament_max_overlap", params.extruder - 1); + 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; + } } return polyline_volume; } @@ -202,7 +205,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ //failsafe, it can happen if (mult_flow > 1.3) mult_flow = 1.3; if (mult_flow < 0.8) mult_flow = 0.8; - BOOST_LOG_TRIVIAL(info) << "Infill process extrude " << extruded_volume << " mm3 for a volume of " << polyline_volume << " mm3 : we mult the flow by " << mult_flow; + BOOST_LOG_TRIVIAL(info) << "Layer " << layer_id << ": Fill process extrude " << extruded_volume << " mm3 for a volume of " << polyline_volume << " mm3 : we mult the flow by " << mult_flow; } // Save into layer. diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 5c5773b10..056b9eef0 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -83,6 +83,9 @@ struct FillParams //full configuration for the region, to avoid copying every bit that is needed. Use this for process-specific parameters. PrintRegionConfig const *config{ nullptr }; + + // Zero based extruder ID. + unsigned int extruder = 0; }; static_assert(IsTriviallyCopyable::value, "FillParams class is not POD (and it should be - see constructor)."); diff --git a/src/libslic3r/Fill/FillSmooth.cpp b/src/libslic3r/Fill/FillSmooth.cpp index 3fa43d673..444e61132 100644 --- a/src/libslic3r/Fill/FillSmooth.cpp +++ b/src/libslic3r/Fill/FillSmooth.cpp @@ -19,7 +19,7 @@ namespace Slic3r { /// @idx: the index of the step (0 = first step, 1 = second step, ...) The first lay down the volume and the others smoothen the surface. void FillSmooth::perform_single_fill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source, - const FillParams ¶ms, const double volume) const { + const FillParams ¶ms) const { if (srf_source.expolygon.empty()) return; // Save into layer smoothing path. @@ -42,7 +42,7 @@ namespace Slic3r { //choose if we are going to extrude with or without overlap if ((params.flow.bridge && idx == 0) || has_overlap[idx] || this->no_overlap_expolygons.empty()){ - this->fill_expolygon(idx, *eec, srf_source, params_modifided, volume); + this->fill_expolygon(idx, *eec, srf_source, params_modifided); } else{ Surface surfaceNoOverlap(srf_source); @@ -52,7 +52,7 @@ namespace Slic3r { for (const ExPolygon &poly : half_overlap) { if (poly.empty()) continue; surfaceNoOverlap.expolygon = poly; - this->fill_expolygon(idx, *eec, surfaceNoOverlap, params_modifided, volume); + this->fill_expolygon(idx, *eec, surfaceNoOverlap, params_modifided); } } @@ -61,7 +61,7 @@ namespace Slic3r { } void FillSmooth::fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill, - const FillParams ¶ms_init, const double volume) const { + const FillParams ¶ms_init) const { FillParams params = params_init; std::unique_ptr f2 = std::unique_ptr(Fill::new_from_type(fillPattern[idx])); @@ -84,7 +84,11 @@ namespace Slic3r { } //get the flow float mult_flow = 1; - if (params.fill_exactly) { + if (params.fill_exactly && idx == 0) { + + // compute the volume to extrude + double volume_to_occupy = compute_unscaled_volume_to_fill(&srf_to_fill, params); + //compute the path of the nozzle double length_tot = 0; int nb_lines = 0; @@ -103,11 +107,12 @@ namespace Slic3r { extruded_volume = test_flow.mm3_per_mm() * length_tot / params.density; } else extruded_volume = params.flow.mm3_per_mm() * length_tot / params.density; - if (extruded_volume == 0) extruded_volume = volume; + if (extruded_volume == 0) extruded_volume = volume_to_occupy; // print - mult_flow = (float)std::min(2., volume / extruded_volume); - BOOST_LOG_TRIVIAL(info) << "Ironing process extrude " << extruded_volume << " mm3 for a volume of " << volume << " mm3 : we mult the flow by " << mult_flow; + mult_flow = (float)std::min(2., volume_to_occupy / extruded_volume); + BOOST_LOG_TRIVIAL(info) << "Layer " << layer_id << " Ironing process " << idx << " extrude " << extruded_volume << " mm3 for a volume of " << volume_to_occupy << " mm3 : we mult the flow by " << mult_flow; + } extrusion_entities_append_paths( eec.entities, std::move(polylines_layer), @@ -123,9 +128,6 @@ namespace Slic3r { { coordf_t init_spacing = this->get_spacing(); - // compute the volume to extrude - double volume_to_occupy = compute_unscaled_volume_to_fill(surface, params); - //create root node ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection(); //you don't want to sort the extrusions: big infill first, small second @@ -135,7 +137,7 @@ namespace Slic3r { FillParams first_pass_params = params; //if(first_pass_params.role != ExtrusionRole::erSupportMaterial && first_pass_params.role != ExtrusionRole::erSupportMaterialInterface) //s first_pass_params.role = ExtrusionRole::erSolidInfill; - perform_single_fill(0, *eecroot, *surface, first_pass_params, volume_to_occupy); + perform_single_fill(0, *eecroot, *surface, first_pass_params); //use monotonic for ironing pass FillParams monotonic_params = params; @@ -143,12 +145,12 @@ namespace Slic3r { //second infill if (nbPass > 1){ - perform_single_fill(1, *eecroot, *surface, monotonic_params, volume_to_occupy); + perform_single_fill(1, *eecroot, *surface, monotonic_params); } // third infill if (nbPass > 2){ - perform_single_fill(2, *eecroot, *surface, monotonic_params, volume_to_occupy); + perform_single_fill(2, *eecroot, *surface, monotonic_params); } if (!eecroot->entities.empty()) diff --git a/src/libslic3r/Fill/FillSmooth.hpp b/src/libslic3r/Fill/FillSmooth.hpp index 1c8a8fae7..fb4533e5e 100644 --- a/src/libslic3r/Fill/FillSmooth.hpp +++ b/src/libslic3r/Fill/FillSmooth.hpp @@ -56,9 +56,9 @@ protected: InfillPattern fillPattern[3]; void perform_single_fill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source, - const FillParams ¶ms, const double volume) const; + const FillParams ¶ms) const; void fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill, - const FillParams ¶ms, const double volume) const; + const FillParams ¶ms) const; };