Fix no_perimeter_unsupported_algo by detecting each bridged area independently.

Apply also the fix for extra overhang detection
bridge_angle now invalidate perimeters
supermerill/SuperSlicer#1595
This commit is contained in:
supermerill 2021-10-02 19:41:10 +02:00
parent 8790970bd6
commit a4caa5d1c3
2 changed files with 135 additions and 130 deletions

View File

@ -189,11 +189,15 @@ void PerimeterGenerator::process()
int numploy = 0; int numploy = 0;
//only consider the bottom layer that intersect unsupported, to be sure it's only on our island. //only consider the bottom layer that intersect unsupported, to be sure it's only on our island.
ExPolygonCollection lower_island(support); ExPolygonCollection lower_island(support);
BridgeDetector detector{ unsupported_filtered, //a detector per island
ExPolygons bridgeable;
for (ExPolygon unsupported : unsupported_filtered) {
BridgeDetector detector{ unsupported,
lower_island.expolygons, lower_island.expolygons,
perimeter_spacing }; perimeter_spacing };
if (detector.detect_angle(Geometry::deg2rad(this->config->bridge_angle.value))) { if (detector.detect_angle(Geometry::deg2rad(this->config->bridge_angle.value)))
ExPolygons bridgeable = union_ex(detector.coverage(-1, true)); expolygons_append(bridgeable, union_ex(detector.coverage(-1, true)));
}
if (!bridgeable.empty()) { if (!bridgeable.empty()) {
//check if we get everything or just the bridgeable area //check if we get everything or just the bridgeable area
if (this->config->no_perimeter_unsupported_algo.value == npuaNoPeri || this->config->no_perimeter_unsupported_algo.value == npuaFilled) { if (this->config->no_perimeter_unsupported_algo.value == npuaNoPeri || this->config->no_perimeter_unsupported_algo.value == npuaFilled) {
@ -313,7 +317,6 @@ void PerimeterGenerator::process()
// ) // )
// ); // );
} }
}
} else { } else {
unsupported_filtered.clear(); unsupported_filtered.clear();
} }
@ -406,11 +409,14 @@ void PerimeterGenerator::process()
//first, separate into islands (ie, each ExPlolygon) //first, separate into islands (ie, each ExPlolygon)
//only consider the bottom layer that intersect unsupported, to be sure it's only on our island. //only consider the bottom layer that intersect unsupported, to be sure it's only on our island.
const ExPolygonCollection lower_island(diff_ex(last, overhangs_unsupported)); const ExPolygonCollection lower_island(diff_ex(last, overhangs_unsupported));
BridgeDetector detector{ overhangs_unsupported, ExPolygons bridgeable;
for (ExPolygon unsupported : overhangs_unsupported) {
BridgeDetector detector{ unsupported,
lower_island.expolygons, lower_island.expolygons,
perimeter_spacing }; perimeter_spacing };
if (detector.detect_angle(Geometry::deg2rad(this->config->bridge_angle.value))) { if (detector.detect_angle(Geometry::deg2rad(this->config->bridge_angle.value)))
const ExPolygons bridgeable = union_ex(detector.coverage(-1, true)); expolygons_append(bridgeable, union_ex(detector.coverage(-1, true)));
}
if (!bridgeable.empty()) { if (!bridgeable.empty()) {
//simplify to avoid most of artefacts from printing lines. //simplify to avoid most of artefacts from printing lines.
ExPolygons bridgeable_simplified; ExPolygons bridgeable_simplified;
@ -418,16 +424,15 @@ void PerimeterGenerator::process()
poly.simplify(perimeter_spacing / 2, &bridgeable_simplified); poly.simplify(perimeter_spacing / 2, &bridgeable_simplified);
} }
//offset by perimeter spacing because the simplify may have reduced it a bit.
if (!bridgeable_simplified.empty()) if (!bridgeable_simplified.empty())
bridgeable_simplified = offset_ex(bridgeable_simplified, double(perimeter_spacing) / 1.9); bridgeable_simplified = offset_ex(bridgeable_simplified, double(perimeter_spacing) / 1.9);
if (!bridgeable_simplified.empty()) { if (!bridgeable_simplified.empty()) {
//offset by perimeter spacing because the simplify may have reduced it a bit.
overhangs_unsupported = diff_ex(overhangs_unsupported, bridgeable_simplified, true); overhangs_unsupported = diff_ex(overhangs_unsupported, bridgeable_simplified, true);
} }
} }
} }
} }
}
bool has_steep_overhang = false; bool has_steep_overhang = false;
if (this->layer->id() % 2 == 1 && this->config->overhangs_reverse //check if my option is set and good layer if (this->layer->id() % 2 == 1 && this->config->overhangs_reverse //check if my option is set and good layer
&& !last.empty() && !overhangs_unsupported.empty() //has something to work with && !last.empty() && !overhangs_unsupported.empty() //has something to work with

View File

@ -815,7 +815,6 @@ namespace Slic3r {
} else if ( } else if (
opt_key == "bottom_solid_min_thickness" opt_key == "bottom_solid_min_thickness"
|| opt_key == "bridged_infill_margin" || opt_key == "bridged_infill_margin"
|| opt_key == "bridge_angle"
|| opt_key == "ensure_vertical_shell_thickness" || opt_key == "ensure_vertical_shell_thickness"
|| opt_key == "fill_density" || opt_key == "fill_density"
|| opt_key == "interface_shells" || opt_key == "interface_shells"
@ -856,7 +855,8 @@ namespace Slic3r {
|| opt_key == "top_infill_extrusion_width") { || opt_key == "top_infill_extrusion_width") {
steps.emplace_back(posInfill); steps.emplace_back(posInfill);
} else if ( } else if (
opt_key == "extra_perimeters" opt_key == "bridge_angle"
|| opt_key == "extra_perimeters"
|| opt_key == "extra_perimeters_odd_layers" || opt_key == "extra_perimeters_odd_layers"
|| opt_key == "external_infill_margin" || opt_key == "external_infill_margin"
|| opt_key == "external_perimeter_overlap" || opt_key == "external_perimeter_overlap"