Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@fr.fr>2019-01-03 19:42:10 +0300
committersupermerill <merill@fr.fr>2019-01-03 21:57:00 +0300
commita48e190137b3345a552bd1588c6bb145af55212a (patch)
tree3d52ee1b6145cb792d80d2f63b40cafd4db194c6
parent72d828cf7442fe242891e52bfed1cd47a38a06c9 (diff)
medial axis: now grows the extrusion to nozzle diameter if it's lower than that. Add a parameter to define the min width (default to 33% of nozzle diameter).
-rw-r--r--src/libslic3r/Layer.cpp1
-rw-r--r--src/libslic3r/MedialAxis.cpp30
-rw-r--r--src/libslic3r/MedialAxis.hpp11
-rw-r--r--src/libslic3r/PerimeterGenerator.cpp7
-rw-r--r--src/libslic3r/PrintConfig.cpp11
-rw-r--r--src/libslic3r/PrintConfig.hpp2
-rw-r--r--src/libslic3r/PrintObject.cpp1
-rw-r--r--src/slic3r/GUI/Preset.cpp1
-rw-r--r--src/slic3r/GUI/Tab.cpp8
9 files changed, 57 insertions, 15 deletions
diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp
index c587e81cf..40f3d9988 100644
--- a/src/libslic3r/Layer.cpp
+++ b/src/libslic3r/Layer.cpp
@@ -110,6 +110,7 @@ void Layer::make_perimeters()
&& config.overhangs == other_config.overhangs
&& config.serialize("perimeter_extrusion_width").compare(other_config.serialize("perimeter_extrusion_width")) == 0
&& config.thin_walls == other_config.thin_walls
+ && config.thin_walls_min_width == other_config.thin_walls_min_width
&& config.external_perimeters_first == other_config.external_perimeters_first
&& config.perimeter_loop == other_config.perimeter_loop) {
layerms.push_back(other_layerm);
diff --git a/src/libslic3r/MedialAxis.cpp b/src/libslic3r/MedialAxis.cpp
index baad42836..c869ef36a 100644
--- a/src/libslic3r/MedialAxis.cpp
+++ b/src/libslic3r/MedialAxis.cpp
@@ -578,7 +578,7 @@ MedialAxis::fusion_corners(ThickPolylines &pp)
//FIXME: also pull (a bit less) points that are near to this one.
// if true, pull it a bit, depends on my size, the dot?, and the coeff at my 0-end (~14% for a square, almost 0 for a gentle curve)
coord_t length_pull = polyline.length();
- length_pull *= 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, polyline.length() / 2));
+ length_pull *= 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2)));
//compute dir
Vec2d pull_direction(polyline.points[1].x() - polyline.points[0].x(), polyline.points[1].y() - polyline.points[0].y());
@@ -801,11 +801,11 @@ MedialAxis::main_fusion(ThickPolylines& pp)
//test if we don't merge with something too different and without any relevance.
double coeffSizePolyI = 1;
if (polyline.width.back() == 0) {
- coeffSizePolyI = 0.1 + 0.9*get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, polyline.length() / 2));
+ coeffSizePolyI = 0.1 + 0.9*get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2)));
}
double coeffSizeOtherJ = 1;
if (other.width.back() == 0) {
- coeffSizeOtherJ = 0.1 + 0.9*get_coeff_from_angle_countour(other.points.back(), this->expolygon, min(min_width, polyline.length() / 2));
+ coeffSizeOtherJ = 0.1 + 0.9*get_coeff_from_angle_countour(other.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2)));
}
//std::cout << " try2 : " << i << ":" << j << " : "
// << (abs(polyline.length()*coeffSizePolyI - other.length()*coeffSizeOtherJ) > max_width / 2)
@@ -904,10 +904,10 @@ MedialAxis::main_fusion(ThickPolylines& pp)
//TODO: try if we can achieve a better result if we use a different algo if the angle is <90°
const double coeff_angle_poly = (coeff_angle_cache.find(polyline.points.back()) != coeff_angle_cache.end())
? coeff_angle_cache[polyline.points.back()]
- : (get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, polyline.length() / 2)));
+ : (get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2))));
const double coeff_angle_candi = (coeff_angle_cache.find(best_candidate->points.back()) != coeff_angle_cache.end())
? coeff_angle_cache[best_candidate->points.back()]
- : (get_coeff_from_angle_countour(best_candidate->points.back(), this->expolygon, min(min_width, best_candidate->length() / 2)));
+ : (get_coeff_from_angle_countour(best_candidate->points.back(), this->expolygon, min(min_width, (coord_t)(best_candidate->length() / 2))));
//this will encourage to follow the curve, a little, because it's shorter near the center
//without that, it tends to go to the outter rim.
@@ -1488,11 +1488,31 @@ MedialAxis::build(ThickPolylines* polylines_out)
// svg.draw(pp);
// svg.Close();
//}
+ if (nozzle_diameter != min_width)
+ grow_to_nozzle_diameter(pp, diff_ex(this->bounds, this->expolygon));
polylines_out->insert(polylines_out->end(), pp.begin(), pp.end());
}
+
+void
+MedialAxis::grow_to_nozzle_diameter(ThickPolylines& pp, const ExPolygons& anchors) {
+ //ensure the width is not lower than 0.4.
+ for (ThickPolyline& polyline : pp) {
+ for (int i = 0; i < polyline.points.size(); ++i) {
+ bool is_anchored = false;
+ for (const ExPolygon &poly : anchors) {
+ if (poly.contains(polyline.points[i])) {
+ is_anchored = true;
+ break;
+ }
+ }
+ if (!is_anchored && polyline.width[i]<nozzle_diameter) polyline.width[i] = nozzle_diameter;
+ }
+ }
+}
+
ExtrusionEntityCollection thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) {
// this value determines granularity of adaptive width, as G-code does not allow
// variable extrusion within a single move; this value shall only affect the amount
diff --git a/src/libslic3r/MedialAxis.hpp b/src/libslic3r/MedialAxis.hpp
index 21fbe3895..85607b718 100644
--- a/src/libslic3r/MedialAxis.hpp
+++ b/src/libslic3r/MedialAxis.hpp
@@ -21,12 +21,14 @@ namespace Slic3r {
ExPolygon expolygon;
const ExPolygon& bounds;
const ExPolygon& surface;
- const double max_width;
- const double min_width;
- const double height;
+ const coord_t max_width;
+ const coord_t min_width;
+ const coord_t height;
+ coord_t nozzle_diameter;
bool stop_at_min_width = true;
- MedialAxis(const ExPolygon &_expolygon, const ExPolygon &_bounds, const double _max_width, const double _min_width, const double _height)
+ MedialAxis(const ExPolygon &_expolygon, const ExPolygon &_bounds, const coord_t _max_width, const coord_t _min_width, const coord_t _height)
: surface(_expolygon), bounds(_bounds), max_width(_max_width), min_width(_min_width), height(_height) {
+ nozzle_diameter = _min_width;
};
void build(ThickPolylines* polylines_out);
void build(Polylines* polylines);
@@ -60,6 +62,7 @@ namespace Slic3r {
void remove_too_thin_points(ThickPolylines& pp);
void remove_too_short_polylines(ThickPolylines& pp, const coord_t min_size);
void ensure_not_overextrude(ThickPolylines& pp);
+ void grow_to_nozzle_diameter(ThickPolylines& pp, const ExPolygons& anchors);
};
ExtrusionEntityCollection thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow);
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index 637d0eec6..13652f86a 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -265,7 +265,7 @@ void PerimeterGenerator::process()
// the following offset2 ensures almost nothing in @thin_walls is narrower than $min_width
// (actually, something larger than that still may exist due to mitering or other causes)
- coord_t min_width = (coord_t)scale_(this->ext_perimeter_flow.nozzle_diameter / 3);
+ coord_t min_width = (coord_t)scale_(this->config->thin_walls_min_width.get_abs_value(this->ext_perimeter_flow.nozzle_diameter));
ExPolygons no_thin_zone = offset_ex(next_onion, (float)(ext_perimeter_width / 2), jtSquare);
// medial axis requires non-overlapping geometry
@@ -297,8 +297,9 @@ void PerimeterGenerator::process()
if (thin[0].area() > min_width*(ext_perimeter_width + ext_perimeter_spacing2)) {
bound.remove_point_too_near(SCALED_RESOLUTION);
// the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
- thin[0].medial_axis(bound, ext_perimeter_width + ext_perimeter_spacing2, min_width,
- &thin_walls, this->layer_height);
+ Slic3r::MedialAxis ma(thin[0], bound, ext_perimeter_width + ext_perimeter_spacing2, min_width, this->layer_height);
+ ma.nozzle_diameter = (coord_t)scale_(this->ext_perimeter_flow.nozzle_diameter);
+ ma.build(&thin_walls);
thin_zones_extruded.emplace_back(thin[0]);
}
break;
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index fddfef0f1..637de22f3 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -2346,7 +2346,7 @@ void PrintConfigDef::init_fff_params()
def->default_value = new ConfigOptionInts { 200 };
def = this->add("thin_walls", coBool);
- def->label = L("Detect thin walls");
+ def->label = L("");
def->category = L("Layers and Perimeters");
def->tooltip = L("Detect single-width walls (parts where two extrusions don't fit and we need "
"to collapse them into a single trace).");
@@ -2354,6 +2354,15 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(true);
+ def = this->add("thin_walls_min_width", coFloatOrPercent);
+ def->label = L("min width");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("Minimum width for the extrusion to be extruded (widths lower than the nozzle diameter will be over-extruded at the nozzle diameter). Can be percent of the nozzle size.");
+ def->cli = "thin-walls-min-width=s";
+ def->mode = comExpert;
+ def->min = 0;
+ def->default_value = new ConfigOptionFloatOrPercent(33,true);
+
def = this->add("threads", coInt);
def->label = L("Threads");
def->tooltip = L("Threads are used to parallelize long-running tasks. Optimal threads number "
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 32629a64b..0cab33423 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -519,6 +519,7 @@ public:
ConfigOptionFloatOrPercent solid_infill_speed;
// Detect thin walls.
ConfigOptionBool thin_walls;
+ ConfigOptionFloatOrPercent thin_walls_min_width;
ConfigOptionFloatOrPercent top_infill_extrusion_width;
ConfigOptionInt top_solid_layers;
ConfigOptionFloatOrPercent top_solid_infill_speed;
@@ -574,6 +575,7 @@ protected:
OPT_PTR(solid_infill_every_layers);
OPT_PTR(solid_infill_speed);
OPT_PTR(thin_walls);
+ OPT_PTR(thin_walls_min_width);
OPT_PTR(top_infill_extrusion_width);
OPT_PTR(top_solid_infill_speed);
OPT_PTR(top_solid_layers);
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index a159d2020..aeee8750c 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -462,6 +462,7 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "perimeter_extrusion_width"
|| opt_key == "infill_overlap"
|| opt_key == "thin_walls"
+ || opt_key == "thin_walls_min_width"
|| opt_key == "external_perimeters_first"
|| opt_key == "perimeter_loop"
|| opt_key == "perimeter_loop_seam"
diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp
index e2abde519..23d632b0c 100644
--- a/src/slic3r/GUI/Preset.cpp
+++ b/src/slic3r/GUI/Preset.cpp
@@ -353,6 +353,7 @@ const std::vector<std::string>& Preset::print_options()
, "infill_not_connected"
, "first_layer_infill_speed"
, "label_printed_objects"
+ , "thin_walls_min_width"
};
return s_opts;
}
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 0f779984d..7c66b8cf1 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -923,7 +923,10 @@ void TabPrint::build()
optgroup->append_single_option_line("only_one_perimeter_top");
optgroup->append_single_option_line("ensure_vertical_shell_thickness");
optgroup->append_single_option_line("avoid_crossing_perimeters");
- optgroup->append_single_option_line("thin_walls");
+ line = { _(L("Thin walls")), "" };
+ line.append_option(optgroup->get_option("thin_walls"));
+ line.append_option(optgroup->get_option("thin_walls_min_width"));
+ optgroup->append_line(line);
optgroup->append_single_option_line("overhangs");
line = { _(L("Avoid unsupported perimeters")), "" };
line.append_option(optgroup->get_option("no_perimeter_unsupported"));
@@ -1322,10 +1325,11 @@ void TabPrint::update()
bool have_perimeters = m_config->opt_int("perimeters") > 0;
for (auto el : { "extra_perimeters", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
- "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
+ "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width", "thin_walls_min_width",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "perimeter_loop", "perimeter_loop_seam" })
get_field(el)->toggle(have_perimeters);
+ get_field("thin_walls_min_width")->toggle(m_config->opt_bool("thin_walls"));
get_field("perimeter_loop_seam")->toggle(m_config->opt_bool("perimeter_loop"));
bool have_no_perimeter_unsupported = have_perimeters && m_config->opt_bool("no_perimeter_unsupported");