#208 holes from thin walls because of the "chunks reduction" algo. It's now less extremist.

Also added a little routine to be able to print (overlapping) perimeters into small areas that are excluded from thin walls by their area size.
This commit is contained in:
supermerill 2020-04-30 17:13:53 +02:00
parent 7b0848be47
commit d812ae91d3

View File

@ -370,19 +370,20 @@ void PerimeterGenerator::process()
if (this->config->thin_walls) { if (this->config->thin_walls) {
// detect edge case where a curve can be split in multiple small chunks. // detect edge case where a curve can be split in multiple small chunks.
ExPolygons no_thin_onion = offset_ex(last, double( - ext_perimeter_width / 2)); ExPolygons no_thin_onion = offset_ex(last, double( - ext_perimeter_width / 2));
float div = 2; std::vector<float> divs = {2.2,1.75,1.5}; //don't go too far, it's not possible to print thinw wall after that
while (no_thin_onion.size() > 0 && next_onion.size() > no_thin_onion.size() && no_thin_onion.size() + next_onion.size() > 3) { size_t idx_div = 0;
div -= 0.3; while (no_thin_onion.size() > 0 && next_onion.size() > no_thin_onion.size() && next_onion.size() > 2
if (div == 2) div -= 0.3; && idx_div < divs.size() ) {
float div = divs[idx_div];
//use a sightly bigger spacing to try to drastically improve the split, that can lead to very thick gapfill //use a sightly bigger spacing to try to drastically improve the split, that can lead to very thick gapfill
ExPolygons next_onion_secondTry = offset2_ex( ExPolygons next_onion_secondTry = offset2_ex(
last, last,
-(float)(ext_perimeter_width / 2 + ext_min_spacing / div - 1), -(float)((ext_perimeter_width / 2) + (ext_min_spacing / div) - 1),
+(float)(ext_min_spacing / div - 1)); +(float)((ext_min_spacing / div) - 1));
if (next_onion.size() > next_onion_secondTry.size() * 1.1) { if (next_onion.size() > next_onion_secondTry.size() * 1.2 || next_onion.size() - next_onion_secondTry.size() > 3) {
next_onion = next_onion_secondTry; next_onion = next_onion_secondTry;
} }
if (div > 3 || div < 1.2) break; idx_div++;
} }
// the following offset2 ensures almost nothing in @thin_walls is narrower than $min_width // the following offset2 ensures almost nothing in @thin_walls is narrower than $min_width
@ -403,6 +404,7 @@ void PerimeterGenerator::process()
if (half_thins.size() > 0) { if (half_thins.size() > 0) {
no_thin_zone = diff_ex(last, offset_ex(half_thins, double(min_width / 2 - SCALED_EPSILON)), true); no_thin_zone = diff_ex(last, offset_ex(half_thins, double(min_width / 2 - SCALED_EPSILON)), true);
} }
ExPolygons thins;
// compute a bit of overlap to anchor thin walls inside the print. // compute a bit of overlap to anchor thin walls inside the print.
for (ExPolygon &half_thin : half_thins) { for (ExPolygon &half_thin : half_thins) {
//growing back the polygon //growing back the polygon
@ -418,9 +420,10 @@ void PerimeterGenerator::process()
//be sure it's not too small to extrude reliably //be sure it's not too small to extrude reliably
thin[0].remove_point_too_near((coord_t)SCALED_RESOLUTION); thin[0].remove_point_too_near((coord_t)SCALED_RESOLUTION);
if (thin[0].area() > min_width*(ext_perimeter_width + ext_perimeter_spacing2)) { if (thin[0].area() > min_width*(ext_perimeter_width + ext_perimeter_spacing2)) {
thins.push_back(thin[0]);
bound.remove_point_too_near((coord_t)SCALED_RESOLUTION); bound.remove_point_too_near((coord_t)SCALED_RESOLUTION);
// the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop (*1.1 because of circles approx.) // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop (*1.2 because of circles approx. and enlrgment from 'div')
Slic3r::MedialAxis ma{ thin[0], (coord_t)((ext_perimeter_width + ext_perimeter_spacing2)*1.1), Slic3r::MedialAxis ma{ thin[0], (coord_t)((ext_perimeter_width + ext_perimeter_spacing2)*1.2),
min_width, coord_t(this->layer_height) }; min_width, coord_t(this->layer_height) };
ma.use_bounds(bound) ma.use_bounds(bound)
.use_min_real_width((coord_t)scale_(this->ext_perimeter_flow.nozzle_diameter)) .use_min_real_width((coord_t)scale_(this->ext_perimeter_flow.nozzle_diameter))
@ -431,6 +434,14 @@ void PerimeterGenerator::process()
} }
} }
} }
// use perimeters to extrude area that can't be printed by thin walls
// it's a bit like re-add thin area in to perimeter area.
// it can over-extrude a bit, but it's for a better good.
{
next_onion = offset2_ex(diff_ex(last, thins, true),
-(float)((ext_perimeter_width / 2) + (ext_min_spacing / 4)),
(float)(ext_min_spacing / 4));
}
} }
} else { } else {
//FIXME Is this offset correct if the line width of the inner perimeters differs //FIXME Is this offset correct if the line width of the inner perimeters differs