Revert "only one perimeter on top" to october algorithm.

added an hidden switch to get the buggy new one.
This commit is contained in:
remi durand 2021-03-19 12:37:21 +01:00
parent 519bcaf1a2
commit 7c0608f5be
6 changed files with 127 additions and 66 deletions

View File

@ -164,6 +164,7 @@ void Layer::make_perimeters()
&& config.infill_dense_algo == other_config.infill_dense_algo && config.infill_dense_algo == other_config.infill_dense_algo
&& config.no_perimeter_unsupported_algo == other_config.no_perimeter_unsupported_algo && config.no_perimeter_unsupported_algo == other_config.no_perimeter_unsupported_algo
&& config.only_one_perimeter_top == other_config.only_one_perimeter_top && config.only_one_perimeter_top == other_config.only_one_perimeter_top
&& config.only_one_perimeter_top_other_algo == other_config.only_one_perimeter_top_other_algo
&& config.overhangs_width_speed == other_config.overhangs_width_speed && config.overhangs_width_speed == other_config.overhangs_width_speed
&& config.overhangs_width == other_config.overhangs_width && config.overhangs_width == other_config.overhangs_width
&& config.overhangs_reverse == other_config.overhangs_reverse && config.overhangs_reverse == other_config.overhangs_reverse

View File

@ -599,74 +599,122 @@ void PerimeterGenerator::process()
//store surface for top infill if only_one_perimeter_top //store surface for top infill if only_one_perimeter_top
if(i==0 && config->only_one_perimeter_top && this->upper_slices != NULL){ if(i==0 && config->only_one_perimeter_top && this->upper_slices != NULL){
//split the polygons with top/not_top if (this->config->only_one_perimeter_top_other_algo) {
//get the offset from solid surface anchor //split the polygons with top/not_top
coord_t offset_top_surface = scale_(config->external_infill_margin.get_abs_value( //get the offset from solid surface anchor
config->perimeters.value == 0 ? 0. : unscaled(double(ext_perimeter_width + perimeter_spacing * int(int(config->perimeters.value) - int(1)))))); coord_t offset_top_surface = scale_(config->external_infill_margin.get_abs_value(
// if possible, try to not push the extra perimeters inside the sparse infill config->perimeters.value == 0 ? 0. : unscaled(double(ext_perimeter_width + perimeter_spacing * int(int(config->perimeters.value) - int(1))))));
if (offset_top_surface > 0.9 * (config->perimeters.value <= 1 ? 0. : (perimeter_spacing * (config->perimeters.value - 1)))) // if possible, try to not push the extra perimeters inside the sparse infill
offset_top_surface -= coord_t(0.9 * (config->perimeters.value <= 1 ? 0. : (perimeter_spacing * (config->perimeters.value - 1)))); if (offset_top_surface > 0.9 * (config->perimeters.value <= 1 ? 0. : (perimeter_spacing * (config->perimeters.value - 1))))
else offset_top_surface = 0; offset_top_surface -= coord_t(0.9 * (config->perimeters.value <= 1 ? 0. : (perimeter_spacing * (config->perimeters.value - 1))));
//don't takes into account too thin areas else offset_top_surface = 0;
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))); //don't takes into account too thin areas
//make thin upper surfaces disapear with -+offset_top_surface 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)));
ExPolygons grown_upper_slices; //make thin upper surfaces disapear with -+offset_top_surface
//do offset2 per island, to avoid big blob merging ExPolygons grown_upper_slices;
//remove polygon too thin (but don't mess with holes) //do offset2 per island, to avoid big blob merging
for (const ExPolygon& expoly_to_grow : *this->upper_slices) { //remove polygon too thin (but don't mess with holes)
//only offset the contour, as it can merge holes for (const ExPolygon& expoly_to_grow : *this->upper_slices) {
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)); //only offset the contour, as it can merge holes
if (!contour.empty()) { 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 (expoly_to_grow.holes.empty()) { if (!contour.empty()) {
for (Polygon& p : contour) if (expoly_to_grow.holes.empty()) {
grown_upper_slices.push_back(ExPolygon{ p }); for (Polygon& p : contour)
} else { grown_upper_slices.push_back(ExPolygon{ p });
Polygons holes = expoly_to_grow.holes; } else {
for (Polygon& h : holes) Polygons holes = expoly_to_grow.holes;
h.reverse(); for (Polygon& h : holes)
holes = offset(holes, -min_width_top_surface - (have_to_grow_for_miller ? (double)mill_extra_size : 0)); h.reverse();
for (ExPolygon p : diff_ex(contour, holes)) holes = offset(holes, -min_width_top_surface - (have_to_grow_for_miller ? (double)mill_extra_size : 0));
grown_upper_slices.push_back(p); for (ExPolygon p : diff_ex(contour, holes))
grown_upper_slices.push_back(p);
}
} }
} }
} grown_upper_slices = union_ex(grown_upper_slices);
grown_upper_slices = union_ex(grown_upper_slices); //set the clip to a virtual "second perimeter"
//set the clip to a virtual "second perimeter" fill_clip = offset_ex(last, -double(ext_perimeter_spacing));
fill_clip = offset_ex(last, -double(ext_perimeter_spacing)); auto fill_clip_old = fill_clip;
auto fill_clip_old = fill_clip; // get the real top surface
// get the real top surface const ExPolygons top_grown_polygons = (!have_to_grow_for_miller)
const ExPolygons top_grown_polygons = (!have_to_grow_for_miller) ? diff_ex(last, grown_upper_slices, true)
? diff_ex(last, grown_upper_slices, true) : (unmillable.empty())
:(unmillable.empty()) ? diff_ex(last, grown_upper_slices, true)
? diff_ex(last, grown_upper_slices, true) : diff_ex(last, diff_ex(grown_upper_slices, unmillable, 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) //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, const ExPolygons inner_polygons = diff_ex(last,
offset_ex(top_grown_polygons, offset_top_surface + min_width_top_surface 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.
top_fills = union_ex(top_fills, top_polygons);
//set the clip to the external wall but go back inside by infill_extrusion_width/2 to be sure the extrusion won't go outside even with a 100% overlap.
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));
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(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(last), "red");
// svg.draw(to_polylines(fill_clip_old), "green");
// svg.Close();
//}
} else {
//split the polygons with top/not_top
//get the offset from solid surface anchor
coord_t offset_top_surface = scale_(config->external_infill_margin.get_abs_value(
config->perimeters.value == 0 ? 0. : unscaled(double(ext_perimeter_width + perimeter_spacing * int(int(config->perimeters.value) - int(1))))));
// if possible, try to not push the extra perimeters inside the sparse infill
if (offset_top_surface > 0.9 * (config->perimeters.value <= 1 ? 0. : (perimeter_spacing * (config->perimeters.value - 1))))
offset_top_surface -= coord_t(0.9 * (config->perimeters.value <= 1 ? 0. : (perimeter_spacing * (config->perimeters.value - 1))));
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)));
ExPolygons grown_upper_slices = offset_ex(*this->upper_slices, min_width_top_surface);
//set the clip to a virtual "second perimeter"
fill_clip = offset_ex(last, -double(ext_perimeter_spacing));
// get the real top surface
ExPolygons top_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));
//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)
ExPolygons inner_polygons = diff_ex(last, offset_ex(top_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 //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); - 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. // 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); top_polygons = diff_ex(fill_clip, inner_polygons, true);
// increase by half peri the inner space to fill the frontier between last and stored. // increase by half peri the inner space to fill the frontier between last and stored.
top_fills = union_ex(top_fills, top_polygons); top_fills = union_ex(top_fills, top_polygons);
//set the clip to the external wall but go back inside by infill_extrusion_width/2 to be sure the extrusion won't go outside even with a 100% overlap. //set the clip to the external wall but go bacjk inside by infill_extrusion_width/2 to be sure the extrusion won't go outside even with a 100% overlap.
double infill_spacing_unscaled = this->config->infill_extrusion_width.get_abs_value(nozzle_diameter); fill_clip = offset_ex(last, double(ext_perimeter_spacing / 2) - this->config->infill_extrusion_width.get_abs_value(nozzle_diameter) / 2);
if (infill_spacing_unscaled == 0) infill_spacing_unscaled = Flow::auto_extrusion_width(frInfill, nozzle_diameter); ExPolygons oldLast = last;
fill_clip = offset_ex(last, double(ext_perimeter_spacing / 2) - scale_d(infill_spacing_unscaled / 2)); last = intersection_ex(inner_polygons, last);
last = intersection_ex(inner_polygons, last); //{
//{ // std::stringstream stri;
// std::stringstream stri; // stri << this->layer->id() << "_1_"<< i <<"_only_one_peri"<< ".svg";
// stri << this->layer->id() << "_1_"<< i <<"_only_one_peri"<< ".svg"; // SVG svg(stri.str());
// SVG svg(stri.str()); // svg.draw(to_polylines(top_fills), "green");
// svg.draw(to_polylines(oldLast), "orange"); // svg.draw(to_polylines(inner_polygons), "yellow");
// svg.draw(to_polylines(fill_clip), "purple"); // svg.draw(to_polylines(top_polygons), "cyan");
// svg.draw(to_polylines(inner_polygons), "yellow"); // svg.draw(to_polylines(oldLast), "orange");
// svg.draw(to_polylines(top_polygons), "cyan"); // svg.draw(to_polylines(last), "red");
// svg.draw(to_polylines(last), "red"); // svg.Close();
// svg.draw(to_polylines(fill_clip_old), "green"); //}
// svg.Close(); }
//}
} }
} }

View File

@ -449,7 +449,9 @@ const std::vector<std::string>& Preset::print_options()
"extra_perimeters", "extra_perimeters",
"extra_perimeters_odd_layers", "extra_perimeters_odd_layers",
"extra_perimeters_overhangs", "extra_perimeters_overhangs",
"only_one_perimeter_top", "ensure_vertical_shell_thickness", "only_one_perimeter_top",
"only_one_perimeter_top_other_algo",
"ensure_vertical_shell_thickness",
"allow_empty_layers", "allow_empty_layers",
"avoid_crossing_perimeters", "avoid_crossing_perimeters",
"avoid_crossing_not_first_layer", "avoid_crossing_not_first_layer",

View File

@ -1014,6 +1014,12 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Use only one perimeter on flat top surface, to let more space to the top infill pattern."); def->tooltip = L("Use only one perimeter on flat top surface, to let more space to the top infill pattern.");
def->set_default_value(new ConfigOptionBool(true)); def->set_default_value(new ConfigOptionBool(true));
def = this->add("only_one_perimeter_top_other_algo", coBool);
def->label = L("Only one peri - other algo");
def->category = OptionCategory::perimeter;
def->tooltip = L("If you have some problem with the 'Only one perimeter on Top surfaces' option, you can try to activate this on the problematic layer.");
def->set_default_value(new ConfigOptionBool(false));
def = this->add("extruder", coInt); def = this->add("extruder", coInt);
def->gui_type = "i_enum_open"; def->gui_type = "i_enum_open";
@ -5168,6 +5174,7 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
"extra_perimeters_overhangs", "extra_perimeters_overhangs",
"extra_perimeters_odd_layers", "extra_perimeters_odd_layers",
"only_one_perimeter_top", "only_one_perimeter_top",
"only_one_perimeter_top_other_algo",
"extruder_temperature_offset", "extruder_temperature_offset",
"extruder_fan_offset", "extruder_fan_offset",
"print_extrusion_multiplier", "print_extrusion_multiplier",
@ -5272,9 +5279,9 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
opt_key = ""; opt_key = "";
value = ""; value = "";
} else if (opt_key.find("_pattern") != std::string::npos) { } else if (opt_key.find("_pattern") != std::string::npos) {
if ("smooth" == value || "smoothtriple" == value || "smoothhilbert" == value || "rectiwithperimeter" == value || "scatteredrectilinear" == value || "rectilineargapfill" == value || "sawtooth" == value) { if ("smooth" == value || "smoothtriple" == value || "smoothhilbert" == value || "rectiwithperimeter" == value || "scatteredrectilinear" == value || "rectilineargapfill" == value || "monotonicgapfill" == value || "sawtooth" == value) {
value = "rectilinear"; value = "rectilinear";
} else if ( "concentricgapfill" == value) { } else if ("concentricgapfill" == value) {
value = "concentric"; value = "concentric";
} }
} else if ("seam_position" == opt_key) { } else if ("seam_position" == opt_key) {

View File

@ -750,6 +750,7 @@ public:
ConfigOptionBool extra_perimeters_odd_layers; ConfigOptionBool extra_perimeters_odd_layers;
ConfigOptionBool extra_perimeters_overhangs; ConfigOptionBool extra_perimeters_overhangs;
ConfigOptionBool only_one_perimeter_top; ConfigOptionBool only_one_perimeter_top;
ConfigOptionBool only_one_perimeter_top_other_algo;
ConfigOptionFloat fill_angle; ConfigOptionFloat fill_angle;
ConfigOptionFloat fill_angle_increment; ConfigOptionFloat fill_angle_increment;
ConfigOptionPercent fill_density; ConfigOptionPercent fill_density;
@ -861,6 +862,7 @@ protected:
OPT_PTR(extra_perimeters_odd_layers); OPT_PTR(extra_perimeters_odd_layers);
OPT_PTR(extra_perimeters_overhangs); OPT_PTR(extra_perimeters_overhangs);
OPT_PTR(only_one_perimeter_top); OPT_PTR(only_one_perimeter_top);
OPT_PTR(only_one_perimeter_top_other_algo);
OPT_PTR(fill_angle); OPT_PTR(fill_angle);
OPT_PTR(fill_angle_increment); OPT_PTR(fill_angle_increment);
OPT_PTR(fill_density); OPT_PTR(fill_density);

View File

@ -680,6 +680,7 @@ namespace Slic3r {
opt_key == "gap_fill" opt_key == "gap_fill"
|| opt_key == "gap_fill_min_area" || opt_key == "gap_fill_min_area"
|| opt_key == "only_one_perimeter_top" || opt_key == "only_one_perimeter_top"
|| opt_key == "only_one_perimeter_top_other_algo"
|| opt_key == "overhangs_width_speed" || opt_key == "overhangs_width_speed"
|| opt_key == "overhangs_width" || opt_key == "overhangs_width"
|| opt_key == "overhangs_reverse" || opt_key == "overhangs_reverse"