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
{
// Zero based extruder ID.
unsigned int extruder = 0;
// Infill pattern, adjusted for the density etc.
InfillPattern pattern = InfillPattern(0);

View File

@ -149,20 +149,23 @@ 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 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 &para
//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.

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.
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).");

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.
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;
// 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 &params_init, const double volume) const {
const FillParams &params_init) const {
FillParams params = params_init;
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(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())

View File

@ -56,9 +56,9 @@ protected:
InfillPattern fillPattern[3];
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,
const FillParams &params, const double volume) const;
const FillParams &params) const;
};