Dense infill: fix the full fill density bug & rework detection settings:

* AutoNotFull: now print the dense infill only if the area to cover doesn't fill the sparse area.
 * AutoOrEnlarged: now print the auto dense infill, unless the area to cover is wider than (nozzle diameter*2/infill ratio) and the enlarged version is smaller than the auto
 * New: AutoOrDisable: now print the auto dense infill, unless the area to cover is wider than (nozzle diameter*2/infill ratio) or the area to cover fill the sparse area.
This commit is contained in:
supermerill 2021-11-20 01:59:54 +01:00
parent a535725e5d
commit 56af116257
4 changed files with 85 additions and 33 deletions

View File

@ -146,6 +146,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
is_bridge = true;
params.pattern = ipRectiWithPerimeter;
params.priority = surface.priority;
params.dont_adjust = true; // keep the 42% density
params.connection = InfillConnection::icConnected;
}
if (params.density <= 0 && !is_denser)

View File

@ -2350,10 +2350,12 @@ void PrintConfigDef::init_fff_params()
" The Anchored option just slightly enlarges (by 'Default infill margin') the surfaces that need a better support.");
def->enum_keys_map = &ConfigOptionEnum<DenseInfillAlgo>::get_enum_values();
def->enum_values.push_back("automatic");
def->enum_values.push_back("autonotfull");
def->enum_values.push_back("autosmall");
def->enum_values.push_back("autoenlarged");
def->enum_values.push_back("enlarged");
def->enum_labels.push_back(L("Automatic"));
def->enum_labels.push_back(L("Automatic, unless full"));
def->enum_labels.push_back(L("Automatic, only for small areas"));
def->enum_labels.push_back(L("Automatic, or anchored if too big"));
def->enum_labels.push_back(L("Anchored"));

View File

@ -121,7 +121,12 @@ enum SLAMaterial {
slamHeatResistant,
};
enum DenseInfillAlgo {
dfaAutomatic, dfaAutoNotFull, dfaAutoOrEnlarged , dfaEnlarged,
dfaAutomatic,
dfaAutoNotFull,
dfaAutoOrEnlarged,
dfaAutoOrNothing,
dfaEnlarged,
dfaDisabled,
};
enum NoPerimeterUnsupportedAlgo {
@ -313,8 +318,9 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::ge
template<> inline const t_config_enum_values& ConfigOptionEnum<DenseInfillAlgo>::get_enum_values() {
static const t_config_enum_values keys_map = {
{ "automatic", dfaAutomatic },
{ "autosmall", dfaAutoNotFull },
{ "autonotfull", dfaAutoNotFull },
{ "autoenlarged", dfaAutoOrEnlarged },
{ "autosmall", dfaAutoOrNothing},
{ "enlarged", dfaEnlarged }
};
return keys_map;

View File

@ -1193,7 +1193,7 @@ namespace Slic3r {
ExPolygons dense_polys;
std::vector<uint16_t> dense_priority;
const ExPolygons surfs_with_overlap = { surface.expolygon };
////create a surface with overlap to allow the dense thing to bond to the infill
// create a surface with overlap to allow the dense thing to bond to the infill
coord_t scaled_width = layerm->flow(frInfill, true).scaled_width();
coord_t overlap = scaled_width / 4;
for (const ExPolygon& surf_with_overlap : surfs_with_overlap) {
@ -1209,24 +1209,54 @@ namespace Slic3r {
intersection_ex(sparse_polys, { upp.expolygon }, true)
, (float)-layerm->flow(frInfill).scaled_width(), (float)layerm->flow(frInfill).scaled_width());
if (!intersect.empty()) {
double area_intersect = 0;
// calculate area to decide if area is small enough for autofill
if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull || layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged)
for (ExPolygon poly_inter : intersect)
area_intersect += poly_inter.area();
DenseInfillAlgo algo = layerm->region()->config().infill_dense_algo.value;
double surf_with_overlap_area = surf_with_overlap.area();
if (layerm->region()->config().infill_dense_algo.value == dfaEnlarged
|| (layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged && surf_with_overlap_area <= area_intersect * COEFF_SPLIT)) {
//if no infill, don't bother, it's always yes
if (region->config().fill_density.value == 0) {
if (dfaAutoOrEnlarged == algo)
algo = dfaAutomatic;
else if (dfaAutomatic != algo)
algo = dfaAutoNotFull;
}
if ( dfaAutoOrNothing == algo
|| dfaAutoOrEnlarged == algo) {
//check if small enough
double max_nozzle_diam = 0;
for (uint16_t extruder_id : object_extruders()) {
max_nozzle_diam = std::max(max_nozzle_diam, print()->config().nozzle_diameter.values[extruder_id]);
}
coordf_t min_width = scale_d(max_nozzle_diam) / region->config().fill_density.get_abs_value(1.);
ExPolygons smalls = offset_ex(intersect, -min_width);
//small enough ?
if (smalls.empty()) {
if (dfaAutoOrNothing == algo)
algo = dfaAutoNotFull;
if (dfaAutoOrEnlarged == algo)
algo = dfaAutomatic;
} else if (dfaAutoOrNothing == algo) {
algo = dfaDisabled;
}
}
if (dfaEnlarged == algo) {
//expand the area a bit
intersect = offset_ex(intersect, (scaled(layerm->region()->config().external_infill_margin.get_abs_value(
region->config().perimeters == 0 ? 0 : (layerm->flow(frExternalPerimeter).width + layerm->flow(frPerimeter).spacing() * (region->config().perimeters - 1))))));
} else if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull
|| layerm->region()->config().infill_dense_algo.value == dfaAutomatic) {
intersect = intersection_ex(intersect, sparse_polys);
} else if (dfaDisabled == algo) {
intersect.clear();
} else {
double sparse_area = surf_with_overlap.area();
double area_to_cover = 0;
double min_area_to_cover = 0;
if (dfaAutoNotFull == algo) {
// calculate area to decide if area is small enough for autofill
for (ExPolygon poly_inter : intersect)
area_to_cover += poly_inter.area();
// if we have to fill everything, don't bother
if (area_to_cover * 1.1 > sparse_area)
intersect.clear();
}
//like intersect.empty() but more resilient
if (layerm->region()->config().infill_dense_algo.value == dfaAutomatic
|| surf_with_overlap_area > area_intersect * COEFF_SPLIT) {
ExPolygons cover_intersect;
// it will be a dense infill, split the surface if needed
@ -1239,10 +1269,23 @@ namespace Slic3r {
0.01f);
cover_intersect.insert(cover_intersect.end(), temp.begin(), temp.end());
}
// calculate area to decide if area is small enough for autofill
if (dfaAutoOrEnlarged == algo) {
double area_dense_covered = 0;
for (ExPolygon poly_inter : cover_intersect)
area_dense_covered += poly_inter.area();
// if enlarge is smaller, use enlarge
intersect = offset_ex(intersect, (scaled(layerm->region()->config().external_infill_margin.get_abs_value(
region->config().perimeters == 0 ? 0 : (layerm->flow(frExternalPerimeter).width + layerm->flow(frPerimeter).spacing() * (region->config().perimeters - 1))))));
intersect = intersection_ex(intersect, sparse_polys);
double area_enlarged_covered = 0;
for (ExPolygon poly_inter : intersect)
area_enlarged_covered += poly_inter.area();
if (area_dense_covered < area_enlarged_covered) {
intersect = cover_intersect;
} else {
intersect.clear();
}
}else
intersect = cover_intersect;
}
if (!intersect.empty()) {