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

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2021-10-14 01:10:23 +0300
committersupermerill <merill@free.fr>2021-10-14 01:10:23 +0300
commit02faf4528685a9baeaaacdf136d5b41a81b1f0b6 (patch)
treeb853173c8092e98c8ac9c9cc78bd53cb54f9071d
parentf46c98c410f0f140d153f7b94e94b3619d162e14 (diff)
parent52e58ff357e64e0890c31a68a3ff9ddc73ce154c (diff)
Merge branch 'dev'2.3.57.2
-rw-r--r--src/libslic3r/ClipperUtils.cpp33
-rw-r--r--src/libslic3r/ExtrusionEntity.cpp22
-rw-r--r--src/libslic3r/ExtrusionEntity.hpp8
-rw-r--r--src/libslic3r/PerimeterGenerator.cpp15
-rw-r--r--src/libslic3r/PrintConfig.cpp13
-rw-r--r--src/libslic3r/PrintObject.cpp7
-rw-r--r--src/slic3r/GUI/ConfigManipulation.cpp2
-rw-r--r--src/slic3r/GUI/Field.cpp8
8 files changed, 92 insertions, 16 deletions
diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp
index 45bb08599..d529e08d7 100644
--- a/src/libslic3r/ClipperUtils.cpp
+++ b/src/libslic3r/ClipperUtils.cpp
@@ -598,7 +598,21 @@ ClipperLib::PolyTree _clipper_do_pl(const ClipperLib::ClipType clipType, const P
// read input
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
ClipperLib::Paths input_clip = Slic3rMultiPoints_to_ClipperPaths(clip);
-
+
+ //perform y safing : if a line is on the same Y, clipper may not pick the good point.
+ std::set<coord_t> bad_y;
+ for (ClipperLib::Paths* input : {&input_subject, &input_clip} )
+ for (ClipperLib::Path& path : *input) {
+ coord_t lasty = 0;
+ for (ClipperLib::IntPoint& pt : path) {
+ if (lasty == pt.Y) {
+ pt.Y+=1;
+ bad_y.insert(pt.Y);
+ }
+ lasty = pt.Y;
+ }
+ }
+
// perform safety offset
if (safety_offset_) safety_offset(&input_clip);
@@ -613,6 +627,23 @@ ClipperLib::PolyTree _clipper_do_pl(const ClipperLib::ClipType clipType, const P
// perform operation
ClipperLib::PolyTree retval;
clipper.Execute(clipType, retval, fillType, fillType);
+
+ //restore good y
+ if (!bad_y.empty()) {
+ std::vector<ClipperLib::PolyNode*> to_check;
+ to_check.push_back(&retval);
+ while (!to_check.empty()) {
+ ClipperLib::PolyNode* node = to_check.back();
+ to_check.pop_back();
+ for (ClipperLib::IntPoint& pt : node->Contour) {
+ if (bad_y.find(pt.Y) != bad_y.end()) {
+ pt.Y-=1;
+ }
+ }
+ to_check.insert(to_check.end(), node->Childs.begin(), node->Childs.end());
+ }
+ }
+
return retval;
}
diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp
index 3ec8800bb..6b0611cca 100644
--- a/src/libslic3r/ExtrusionEntity.cpp
+++ b/src/libslic3r/ExtrusionEntity.cpp
@@ -388,6 +388,28 @@ void ExtrusionLength::use(const ExtrusionEntityCollection& collection) {
}
}
+
+void ExtrusionVisitorRecursiveConst::use(const ExtrusionMultiPath& multipath) {
+ for (const ExtrusionPath& path: multipath.paths) {
+ path.visit(*this);
+ }
+}
+void ExtrusionVisitorRecursiveConst::use(const ExtrusionMultiPath3D& multipath3D) {
+ for (const ExtrusionPath3D& path3D : multipath3D.paths) {
+ path3D.visit(*this);
+ }
+}
+void ExtrusionVisitorRecursiveConst::use(const ExtrusionLoop& loop) {
+ for (const ExtrusionPath& path : loop.paths) {
+ path.visit(*this);
+ }
+}
+void ExtrusionVisitorRecursiveConst::use(const ExtrusionEntityCollection& collection) {
+ for (const ExtrusionEntity* entity : collection.entities) {
+ entity->visit(*this);
+ }
+}
+
//class ExtrusionTreeVisitor : ExtrusionVisitor {
//public:
// //virtual void use(ExtrusionEntity &entity) { assert(false); };
diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp
index 8ce95e910..5369998cf 100644
--- a/src/libslic3r/ExtrusionEntity.hpp
+++ b/src/libslic3r/ExtrusionEntity.hpp
@@ -606,6 +606,14 @@ public:
}
};
+class ExtrusionVisitorRecursiveConst : public ExtrusionVisitorConst {
+public:
+ virtual void use(const ExtrusionMultiPath& multipath) override;
+ virtual void use(const ExtrusionMultiPath3D& multipath) override;
+ virtual void use(const ExtrusionLoop& loop) override;
+ virtual void use(const ExtrusionEntityCollection& collection) override;
+};
+
}
#endif
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index a5bedcc33..ed6e34549 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -1852,6 +1852,8 @@ PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, co
for (ExtrusionPath &path : paths) {
direction_polyline.points.insert(direction_polyline.points.end(), path.polyline.points.begin(), path.polyline.points.end());
}
+ for (int i = 0; i < direction_polyline.points.size() - 1; i++)
+ assert(direction_polyline.points[i] != direction_polyline.points[i + 1]);
direction_polyline.clip_start(SCALED_RESOLUTION);
direction_polyline.clip_end(SCALED_RESOLUTION);
coord_t dot = direction.dot(Line(direction_polyline.points.back(), direction_polyline.points.front()));
@@ -1950,11 +1952,12 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
//create new node with recursive ask for the inner perimeter & COPY of the points, ready to be cut
my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, my_loop.paths[nearest.idx_polyline_outter]);
+ // outer_start == outer_end
ExtrusionPath *outer_start = &my_loop.paths[nearest.idx_polyline_outter];
ExtrusionPath *outer_end = &my_loop.paths[nearest.idx_polyline_outter + 1];
Line deletedSection;
- //cut our polyline
+ //cut our polyline, so outer_start has no common point with outer_end
//separate them
size_t nearest_idx_outter = outer_start->polyline.closest_point_index(nearest.outter_best);
if (outer_start->polyline.points[nearest_idx_outter].coincides_with_epsilon(nearest.outter_best)) {
@@ -2195,6 +2198,16 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, travel_path_begin[i]);
}
}
+ //remove one-point extrusion
+ //FIXME prevent this instead of patching here?
+ for (int i = 0; i < my_loop.paths.size(); i++) {
+ if (my_loop.paths[i].polyline.size() < 2) {
+ if (my_loop.paths[i].polyline.size() == 1)
+ std::cout << "erase one-point extrusion : layer " << this->layer->id() << " " << my_loop.paths[i].polyline.points.front().x() << ":" << my_loop.paths[i].polyline.points.front().y() << "\n";
+ my_loop.paths.erase(my_loop.paths.begin() + i);
+ i--;
+ }
+ }
//update for next loop
childs.erase(childs.begin() + nearest.idx_children);
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index c5ae79bd8..a4cc2f4d3 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -3849,7 +3849,10 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionBool(false));
def = this->add("solid_over_perimeters", coInt);
- def->label = L("Max perimeters layer for solid infill");
+ def->label = L("No solid infill over");
+ def->full_label = L("No solid infill over perimeters");
+ def->sidetext = L("perimeters");
+ def->sidetext_width = 20;
def->category = OptionCategory::perimeter;
def->tooltip = L("When you have a medium/hight number of top/bottom solid layers, and a low/medium of perimeters,"
" then it have to put some solid infill inside the part to have enough solid layers."
@@ -6482,6 +6485,7 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co
}
//FIXME localize this function.
+//note: seems only called for config export & command line. Most of the validation work for the gui is done elsewhere... So this function may be a bit out-of-sync
std::string FullPrintConfig::validate()
{
// --layer-height
@@ -6558,7 +6562,7 @@ std::string FullPrintConfig::validate()
// --fill-density
if (fabs(this->fill_density.value - 100.) < EPSILON &&
(! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
- || ! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
+ && ! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
))
return "The selected fill pattern is not supposed to work at 100% density";
@@ -6581,11 +6585,6 @@ std::string FullPrintConfig::validate()
if (em <= 0)
return "Invalid value for --extrusion-multiplier";
- // --default-acceleration
- if ((this->perimeter_acceleration.value != 0. || this->infill_acceleration.value != 0. || this->bridge_acceleration.value != 0. || this->first_layer_acceleration.value != 0.) &&
- this->default_acceleration.value == 0.)
- return "Invalid zero value for --default-acceleration when using other acceleration settings";
-
// --spiral-vase
if (this->spiral_vase) {
// Note that we might want to have more than one perimeter on the bottom
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index c9d48093f..126db9a2c 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -1672,7 +1672,7 @@ namespace Slic3r {
size_t grain_size = std::max(num_layers / 16, size_t(1));
//solid_over_perimeters value, to remove solid fill where there's only perimeters on multiple layers
- int nb_perimeter_layers_for_solid_fill = region.config().solid_over_perimeters.value;
+ const int nb_perimeter_layers_for_solid_fill = region.config().solid_over_perimeters.value;
if (!top_bottom_surfaces_all_regions) {
// This is either a single material print, or a multi-material print and interface_shells are enabled, meaning that the vertical shell thickness
@@ -1899,8 +1899,9 @@ namespace Slic3r {
//check if a polygon is only over perimeter, in this case evict it (depends from nb_perimeter_layers_for_solid_fill value)
if (nb_perimeter_layers_for_solid_fill != 0) {
for (int i = 0; i < shell.size(); i++) {
- if (nb_perimeter_layers_for_solid_fill < 2 || intersection({ shell[i] }, max_perimeter_shell, false).empty()) {
- toadd = intersection_ex({ shell[i] }, fill_shell);
+ if (nb_perimeter_layers_for_solid_fill < 2 || intersection_ex({ shell[i] }, max_perimeter_shell, false).empty()) {
+ ExPolygons expoly = intersection_ex({ shell[i] }, fill_shell);
+ toadd.insert(toadd.end(), expoly.begin(), expoly.end());
shell.erase(shell.begin() + i);
i--;
}
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index f70ac147a..76f0e0d33 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -400,7 +400,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field(el, have_infill_dense);
bool has_spiral_vase = have_perimeters && config->opt_bool("spiral_vase");
- bool has_top_solid_infill = config->opt_int("top_solid_layers") > 0;
+ bool has_top_solid_infill = config->opt_int("top_solid_layers") > 0 || has_spiral_vase;
bool has_bottom_solid_infill = config->opt_int("bottom_solid_layers") > 0;
bool has_solid_infill = has_top_solid_infill || has_bottom_solid_infill || (have_infill && (config->opt_int("solid_infill_every_layers") > 0 || config->opt_float("solid_infill_below_area") > 0));
// solid_infill_extruder uses the same logic as in Print::extruders()
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index cbc49c29e..a4cf9cd41 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -311,8 +311,10 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
str.Replace(" ", "", true);
str.Replace("m", "", true);
- if (!str.ToCDouble(&val))
- {
+ if (m_opt.nullable && str == na_value()) {
+ val = ConfigOptionFloatsNullable::nil_value();
+ str = "nan";
+ } else if (!str.ToCDouble(&val)) {
if (!check_value) {
m_value.clear();
break;
@@ -480,7 +482,6 @@ void TextCtrl::BUILD() {
m_opt.default_value->getFloat() :
m_opt.get_default_value<ConfigOptionPercents>()->get_at(m_opt_idx);
text_value = double_to_string(val, m_opt.precision);
- m_last_meaningful_value = text_value;
break;
}
case coFloatsOrPercents:
@@ -507,6 +508,7 @@ void TextCtrl::BUILD() {
default:
break;
}
+ m_last_meaningful_value = text_value;
const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/;
auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style);