Fix enforce_full_fill_volume for smooth pattern, when it splits from the half-offset.

Changed the way the surface to fill is computed (more work) to ensure there isn't problem anymore anywhere.
FIXME: enforce_full_fill_volume isn't really compatible with filament_max_overlap right now
This commit is contained in:
supermerill 2021-11-20 21:52:51 +01:00
parent d1fa026479
commit 7c59e501f1
5 changed files with 37 additions and 31 deletions

View File

@ -16,8 +16,6 @@ namespace Slic3r {
struct SurfaceFillParams : FillParams struct SurfaceFillParams : FillParams
{ {
// Zero based extruder ID.
unsigned int extruder = 0;
// Infill pattern, adjusted for the density etc. // Infill pattern, adjusted for the density etc.
InfillPattern pattern = InfillPattern(0); InfillPattern pattern = InfillPattern(0);

View File

@ -149,10 +149,15 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
double Fill::compute_unscaled_volume_to_fill(const Surface* surface, const FillParams& params) const { double Fill::compute_unscaled_volume_to_fill(const Surface* surface, const FillParams& params) const {
double polyline_volume = 0; double polyline_volume = 0;
for (const ExPolygon& poly : this->no_overlap_expolygons) { 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())); polyline_volume += params.flow.height * unscaled(unscaled(poly.area()));
double perimeter_gap_usage = params.config->perimeter_overlap.get_abs_value(1); double perimeter_gap_usage = params.config->perimeter_overlap.get_abs_value(1);
// add external "perimeter gap" // 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; double perimeter_round_gap = unscaled(poly.contour.length()) * params.flow.height * (1 - 0.25 * PI) * 0.5;
// add holes "perimeter gaps" // add holes "perimeter gaps"
double holes_gaps = 0; double holes_gaps = 0;
@ -161,8 +166,6 @@ double Fill::compute_unscaled_volume_to_fill(const Surface* surface, const FillP
} }
polyline_volume += (perimeter_round_gap + holes_gaps) * perimeter_gap_usage; 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; return polyline_volume;
} }
@ -202,7 +205,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
//failsafe, it can happen //failsafe, it can happen
if (mult_flow > 1.3) mult_flow = 1.3; if (mult_flow > 1.3) mult_flow = 1.3;
if (mult_flow < 0.8) mult_flow = 0.8; 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. // Save into layer.

View File

@ -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. //full configuration for the region, to avoid copying every bit that is needed. Use this for process-specific parameters.
PrintRegionConfig const *config{ nullptr }; PrintRegionConfig const *config{ nullptr };
// Zero based extruder ID.
unsigned int extruder = 0;
}; };
static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor)."); static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");

View File

@ -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. /// @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, void FillSmooth::perform_single_fill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source,
const FillParams &params, const double volume) const { const FillParams &params) const {
if (srf_source.expolygon.empty()) return; if (srf_source.expolygon.empty()) return;
// Save into layer smoothing path. // Save into layer smoothing path.
@ -42,7 +42,7 @@ namespace Slic3r {
//choose if we are going to extrude with or without overlap //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()){ 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{ else{
Surface surfaceNoOverlap(srf_source); Surface surfaceNoOverlap(srf_source);
@ -52,7 +52,7 @@ namespace Slic3r {
for (const ExPolygon &poly : half_overlap) { for (const ExPolygon &poly : half_overlap) {
if (poly.empty()) continue; if (poly.empty()) continue;
surfaceNoOverlap.expolygon = poly; 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, void FillSmooth::fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
const FillParams &params_init, const double volume) const { const FillParams &params_init) const {
FillParams params = params_init; FillParams params = params_init;
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[idx])); std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[idx]));
@ -84,7 +84,11 @@ namespace Slic3r {
} }
//get the flow //get the flow
float mult_flow = 1; 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 //compute the path of the nozzle
double length_tot = 0; double length_tot = 0;
int nb_lines = 0; int nb_lines = 0;
@ -103,11 +107,12 @@ namespace Slic3r {
extruded_volume = test_flow.mm3_per_mm() * length_tot / params.density; extruded_volume = test_flow.mm3_per_mm() * length_tot / params.density;
} else } else
extruded_volume = params.flow.mm3_per_mm() * length_tot / params.density; 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 // print
mult_flow = (float)std::min(2., volume / extruded_volume); mult_flow = (float)std::min(2., volume_to_occupy / 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; 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( extrusion_entities_append_paths(
eec.entities, std::move(polylines_layer), eec.entities, std::move(polylines_layer),
@ -123,9 +128,6 @@ namespace Slic3r {
{ {
coordf_t init_spacing = this->get_spacing(); 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 //create root node
ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection(); ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
//you don't want to sort the extrusions: big infill first, small second //you don't want to sort the extrusions: big infill first, small second
@ -135,7 +137,7 @@ namespace Slic3r {
FillParams first_pass_params = params; FillParams first_pass_params = params;
//if(first_pass_params.role != ExtrusionRole::erSupportMaterial && first_pass_params.role != ExtrusionRole::erSupportMaterialInterface) //if(first_pass_params.role != ExtrusionRole::erSupportMaterial && first_pass_params.role != ExtrusionRole::erSupportMaterialInterface)
//s first_pass_params.role = ExtrusionRole::erSolidInfill; //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 //use monotonic for ironing pass
FillParams monotonic_params = params; FillParams monotonic_params = params;
@ -143,12 +145,12 @@ namespace Slic3r {
//second infill //second infill
if (nbPass > 1){ if (nbPass > 1){
perform_single_fill(1, *eecroot, *surface, monotonic_params, volume_to_occupy); perform_single_fill(1, *eecroot, *surface, monotonic_params);
} }
// third infill // third infill
if (nbPass > 2){ 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()) if (!eecroot->entities.empty())

View File

@ -56,9 +56,9 @@ protected:
InfillPattern fillPattern[3]; InfillPattern fillPattern[3];
void perform_single_fill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source, void perform_single_fill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source,
const FillParams &params, const double volume) const; const FillParams &params) const;
void fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill, void fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
const FillParams &params, const double volume) const; const FillParams &params) const;
}; };