#745 fix "only one perimeter on top" regression

some artifact can still be visible on some occasion when the min width isn't 0 but it's unavoidable (it's really inside the min width).
This commit is contained in:
supermerill 2020-12-10 00:50:09 +01:00
parent e215797af4
commit b14ed0b860

View File

@ -605,22 +605,43 @@ void PerimeterGenerator::process()
else offset_top_surface = 0;
//don't takes into account too thin areas
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), this->config->min_width_top_surface.get_abs_value(double(perimeter_width)));
//make thin upper surfaces disapear with -+offset_top_surface becasue it will be harder to do so later, as they can merge together to form big blob
const ExPolygons grown_upper_slices = offset2_ex(*this->upper_slices, -offset_top_surface, offset_top_surface+min_width_top_surface);
//make thin upper surfaces disapear with -+offset_top_surface
ExPolygons grown_upper_slices;
//do offset2 per island, to avoid big blob merging
//remove polygon too thin (but don't mess with holes)
for (const ExPolygon& expoly_to_grow : *this->upper_slices) {
//only offset the contour, as it can merge holes
Polygons contour = offset2({ expoly_to_grow.contour }, -offset_top_surface, offset_top_surface + min_width_top_surface + (have_to_grow_for_miller ? (double)mill_extra_size : 0));
if (!contour.empty()) {
if (expoly_to_grow.holes.empty()) {
for (Polygon& p : contour)
grown_upper_slices.push_back(ExPolygon{ p });
} else {
Polygons holes = expoly_to_grow.holes;
for (Polygon& h : holes)
h.reverse();
holes = offset(holes, -min_width_top_surface - (have_to_grow_for_miller ? (double)mill_extra_size : 0));
for (ExPolygon p : diff_ex(contour, holes))
grown_upper_slices.push_back(p);
}
}
}
grown_upper_slices = union_ex(grown_upper_slices);
//set the clip to a virtual "second perimeter"
fill_clip = offset_ex(last, -double(ext_perimeter_spacing));
auto fill_clip_old = fill_clip;
// get the real top surface
const ExPolygons top_grown_polygons = (!have_to_grow_for_miller)
? diff_ex(last, grown_upper_slices, true)
:(unmillable.empty())
? diff_ex(last, offset_ex(grown_upper_slices, (double)mill_extra_size), true)
: diff_ex(last, diff_ex(offset_ex(grown_upper_slices, (double)mill_extra_size), unmillable, true));
? diff_ex(last, grown_upper_slices, true)
: diff_ex(last, diff_ex(grown_upper_slices, unmillable, true));
//get the not-top surface, from the "real top" but enlarged by external_infill_margin (and the min_width_top_surface we removed a bit before)
const ExPolygons inner_polygons = diff_ex(last, offset_ex(top_grown_polygons, offset_top_surface + min_width_top_surface
//also remove the ext_perimeter_spacing/2 width because we are faking the external periemter, and we will remove ext_perimeter_spacing2
- double(ext_perimeter_spacing / 2)), true);
const ExPolygons inner_polygons = diff_ex(last,
offset_ex(top_grown_polygons, offset_top_surface + min_width_top_surface
//also remove the ext_perimeter_spacing/2 width because we are faking the external periemter, and we will remove ext_perimeter_spacing2
- double(ext_perimeter_spacing / 2)), true);
// get the enlarged top surface, by using inner_polygons instead of upper_slices, and clip it for it to be exactly the polygons to fill.
const ExPolygons top_polygons = diff_ex(fill_clip, inner_polygons, true);
// increase by half peri the inner space to fill the frontier between last and stored.
@ -629,17 +650,17 @@ void PerimeterGenerator::process()
double infill_spacing_unscaled = this->config->infill_extrusion_width.get_abs_value(nozzle_diameter);
if (infill_spacing_unscaled == 0) infill_spacing_unscaled = Flow::auto_extrusion_width(frInfill, nozzle_diameter);
fill_clip = offset_ex(last, double(ext_perimeter_spacing / 2) - scale_d(infill_spacing_unscaled / 2));
// ExPolygons oldLast = last;
last = intersection_ex(inner_polygons, last);
//{
// std::stringstream stri;
// stri << this->layer->id() << "_1_"<< i <<"_only_one_peri"<< ".svg";
// SVG svg(stri.str());
// svg.draw(to_polylines(top_fills), "green");
// svg.draw(to_polylines(oldLast), "orange");
// svg.draw(to_polylines(fill_clip), "purple");
// svg.draw(to_polylines(inner_polygons), "yellow");
// svg.draw(to_polylines(top_polygons), "cyan");
// svg.draw(to_polylines(oldLast), "orange");
// svg.draw(to_polylines(last), "red");
// svg.draw(to_polylines(fill_clip_old), "green");
// svg.Close();
//}
}