diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 5b601f2b5..b77302b1d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2100,15 +2100,30 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(15, false)); - def = this->add("curve_smoothing_angle", coFloat); - def->label = L("Min angle"); - def->full_label = L("Curve smoothing minimum angle"); + def = this->add("curve_smoothing_angle_convex", coFloat); + def->label = L("Min convex angle"); + def->full_label = L("Curve smoothing minimum angle (convex)"); def->category = L("Slicing"); - def->tooltip = L("Minimum angle at a vertex to enable smoothing" + def->tooltip = L("Minimum (convex) angle at a vertex to enable smoothing" " (trying to create a curve around the vertex). " "180 : nothing will be smooth, 0 : all angles will be smoothen."); def->sidetext = L("°"); - def->cli = "curve-smoothing-angle=f"; + def->aliases = { "curve_smoothing_angle" }; + def->cli = "curve-smoothing-angle-convex=f"; + def->min = 0; + def->max = 180; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0)); + + def = this->add("curve_smoothing_angle_concave", coFloat); + def->label = L("Min concave angle"); + def->full_label = L("Curve smoothing minimum angle (concave)"); + def->category = L("Slicing"); + def->tooltip = L("Minimum (concave) angle at a vertex to enable smoothing" + " (trying to create a curve around the vertex). " + "180 : nothing will be smooth, 0 : all angles will be smoothen."); + def->sidetext = L("°"); + def->cli = "curve-smoothing-angle-concave=f"; def->min = 0; def->max = 180; def->mode = comAdvanced; @@ -2129,6 +2144,17 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); + def = this->add("curve_smoothing_cutoff_dist", coFloat); + def->label = L("cutoff"); + def->full_label = L("Curve smoothing cutoff dist"); + def->category = L("Slicing"); + def->tooltip = L("Maximum distance between two points to allow adding new ones. Allow to avoid distording long strait areas. 0 to disable."); + def->sidetext = L("mm"); + def->min = 0; + def->cli = "curve-smoothing-cutoff-dist=f"; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(2)); + def = this->add("solid_infill_below_area", coFloat); def->label = L("Solid infill threshold area"); def->category = L("Infill"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 68bd4af4c..9f407a1bd 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -558,7 +558,9 @@ public: ConfigOptionFloatOrPercent bridged_infill_margin; ConfigOptionFloat bridge_speed; ConfigOptionFloat curve_smoothing_precision; - ConfigOptionFloat curve_smoothing_angle; + ConfigOptionFloat curve_smoothing_cutoff_dist; + ConfigOptionFloat curve_smoothing_angle_convex; + ConfigOptionFloat curve_smoothing_angle_concave; ConfigOptionBool ensure_vertical_shell_thickness; ConfigOptionBool enforce_full_fill_volume; ConfigOptionFloatOrPercent external_infill_margin; @@ -619,7 +621,9 @@ protected: OPT_PTR(bridged_infill_margin); OPT_PTR(bridge_speed); OPT_PTR(curve_smoothing_precision); - OPT_PTR(curve_smoothing_angle); + OPT_PTR(curve_smoothing_cutoff_dist); + OPT_PTR(curve_smoothing_angle_convex); + OPT_PTR(curve_smoothing_angle_concave); OPT_PTR(ensure_vertical_shell_thickness); OPT_PTR(enforce_full_fill_volume); OPT_PTR(external_infill_margin); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index d78bf8043..18ce2bb4f 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2129,19 +2129,35 @@ void PrintObject::_offset_holes(double hole_delta, LayerRegion *layerm) { /// max angle: you ahve to be lwer than that to divide it. PI => all accepted /// min angle: don't smooth sharp angles! 0 => all accepted -Polygon _smooth_curve(Polygon &p, double max_angle, double min_angle, coord_t max_dist){ +/// cutoff_dist: maximum dist between two point to add new points +/// max dist : maximum distance between two pointsd, where we add new points +Polygon _smooth_curve(Polygon &p, double max_angle, double min_angle_convex, double min_angle_concave, coord_t cutoff_dist, coord_t max_dist){ if (p.size() < 4) return p; Polygon pout; //duplicate points to simplify the loop p.points.insert(p.points.end(), p.points.begin(), p.points.begin() + 3); for (size_t idx = 1; idx PI) angle1 = 2 * PI - angle1; + bool angle1_concave = true; + if (angle1 > PI) { + angle1 = 2 * PI - angle1; + angle1_concave = false; + } double angle2 = p[idx + 1].ccw_angle(p.points[idx], p.points[idx + 2]); - if (angle2 > PI) angle2 = 2 * PI - angle2; - if (angle1 < min_angle && angle2 < min_angle) continue; + bool angle2_concave = true; + if (angle2 > PI) { + angle2 = 2 * PI - angle2; + angle2_concave = false; + } + //filters + bool angle1_ok = angle1_concave ? angle1 >= min_angle_concave : angle1 >= min_angle_convex; + bool angle2_ok = angle2_concave ? angle2 >= min_angle_concave : angle2 >= min_angle_convex; + if (!angle1_ok && !angle2_ok) continue; if (angle1 > max_angle && angle2 > max_angle) continue; + if (cutoff_dist > 0 && p.points[idx].distance_to(p.points[idx+1]) > cutoff_dist) continue; // add points, but how many? coordf_t dist = p[idx].distance_to(p[idx + 1]); int nb_add = dist / max_dist; @@ -2168,9 +2184,9 @@ Polygon _smooth_curve(Polygon &p, double max_angle, double min_angle, coord_t ma vec_b_tang *= dist * (0.31 + 0.12 * (1-(angle1 / PI))); Vec2d vec_c_tang = vec_dc + vec_cb; vec_c_tang.normalize(); - vec_c_tang *= dist * (0.31 + 0.12 * (1 - (angle1 / PI))); - Point bp = p[idx] + ((angle1 < min_angle) ? vec_bc.cast() : vec_b_tang.cast()); - Point cp = p[idx + 1] + ((angle2 < min_angle) ? vec_cb.cast() : vec_c_tang.cast()); + vec_c_tang *= dist * (0.31 + 0.12 * (1 - (angle2 / PI))); + Point bp = p[idx] + ((!angle1_ok) ? vec_bc.cast() : vec_b_tang.cast()); + Point cp = p[idx + 1] + ((!angle2_ok) ? vec_cb.cast() : vec_c_tang.cast()); for (int idx_np = 0; idx_np < nb_add; idx_np++){ const float percent_np = (idx_np + 1) / (float)(nb_add + 1); const float inv_percent_np = 1 - percent_np; @@ -2201,13 +2217,17 @@ void PrintObject::_smooth_curves(LayerRegion *layerm) { for (const Surface &srf : layerm->slices.surfaces) { const ExPolygon &ex_poly = srf.expolygon; ExPolygon new_ex_poly(ex_poly); - new_ex_poly.contour = _smooth_curve(new_ex_poly.contour, PI, - layerm->region()->config().curve_smoothing_angle.value*PI / 180.0, + new_ex_poly.contour = _smooth_curve(new_ex_poly.contour, PI, + layerm->region()->config().curve_smoothing_angle_convex.value*PI / 180.0, + layerm->region()->config().curve_smoothing_angle_concave.value*PI / 180.0, + scale_(layerm->region()->config().curve_smoothing_cutoff_dist.value), scale_(layerm->region()->config().curve_smoothing_precision.value)); for (Polygon &phole : new_ex_poly.holes){ phole.reverse(); // make_counter_clockwise(); phole = _smooth_curve(phole, PI, - layerm->region()->config().curve_smoothing_angle.value*PI / 180.0, + layerm->region()->config().curve_smoothing_angle_convex.value*PI / 180.0, + layerm->region()->config().curve_smoothing_angle_concave.value*PI / 180.0, + scale_(layerm->region()->config().curve_smoothing_cutoff_dist.value), scale_(layerm->region()->config().curve_smoothing_precision.value)); phole.reverse(); // make_clockwise(); } diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 9e0f44fea..8b48a7174 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -428,7 +428,9 @@ const std::vector& Preset::print_options() , "thin_walls_overlap" , "model_precision" , "curve_smoothing_precision" - , "curve_smoothing_angle" + , "curve_smoothing_cutoff_dist" + , "curve_smoothing_angle_convex" + , "curve_smoothing_angle_concave" }; return s_opts; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index b5f5b9bae..a6add119a 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1062,7 +1062,9 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Modifying slices"))); line = { _(L("Curve smoothing")), "" }; line.append_option(optgroup->get_option("curve_smoothing_precision")); - line.append_option(optgroup->get_option("curve_smoothing_angle")); + line.append_option(optgroup->get_option("curve_smoothing_angle_convex")); + line.append_option(optgroup->get_option("curve_smoothing_angle_concave")); + line.append_option(optgroup->get_option("curve_smoothing_cutoff_dist")); optgroup->append_line(line); line = { _(L("XY compensation")), "" }; line.append_option(optgroup->get_option("xy_size_compensation"));