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>2022-09-16 16:58:51 +0300
committersupermerill <merill@free.fr>2022-09-16 17:32:00 +0300
commitcc59dbd07125ec8c5e36c89b62b8a1ca85db0477 (patch)
tree15caee4eca4509adadd1a0e9224a130973094244
parentceec9d753e97709f44f0db31057c3d23cfc5a430 (diff)
Fix thinwall-merge to keep a real loop
-rw-r--r--src/libslic3r/PerimeterGenerator.cpp55
1 files changed, 52 insertions, 3 deletions
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index 8df16a5cd..4602e84ce 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -24,7 +24,18 @@
#include <boost/log/trivial.hpp>
namespace Slic3r {
-
+#if _DEBUG
+struct LoopAssertVisitor : public ExtrusionVisitorRecursiveConst {
+ virtual void default_use(const ExtrusionEntity& entity) override {};
+ virtual void use(const ExtrusionLoop& loop) override {
+ for (auto it = std::next(loop.paths.begin()); it != loop.paths.end(); ++it) {
+ assert(it->polyline.points.size() >= 2);
+ assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
+ }
+ assert(loop.paths.front().first_point() == loop.paths.back().last_point());
+ }
+};
+#endif
PerimeterGeneratorLoops get_all_Childs(PerimeterGeneratorLoop loop) {
PerimeterGeneratorLoops ret;
for (PerimeterGeneratorLoop &child : loop.children) {
@@ -946,7 +957,7 @@ void PerimeterGenerator::process()
contours.emplace_back();
holes.emplace_back();
}
- //Add the new periemter
+ //Add the new perimeter
contours[contours_size].emplace_back(contour_expolygon.front().contour, contours_size, true, has_steep_overhang, fuzzify_gapfill);
//create the new gapfills
ExPolygons gapfill_area = offset_ex(Polygons{ expoly.contour }, -(float)(perimeter_spacing));
@@ -1051,6 +1062,9 @@ void PerimeterGenerator::process()
peri_entities = this->_traverse_loops(contours.front(), thin_walls_thickpolys);
}
}
+#if _DEBUG
+ peri_entities.visit(LoopAssertVisitor{});
+#endif
//{
// static int aodfjiaqsdz = 0;
// std::stringstream stri;
@@ -1135,6 +1149,9 @@ void PerimeterGenerator::process()
this->loops->append(peri_entities);
}
} // for each loop of an island
+#if _DEBUG
+ this->loops->visit(LoopAssertVisitor{});
+#endif
// fill gaps
ExPolygons gaps_ex;
@@ -1783,7 +1800,27 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
public:
float percent_extrusion;
std::vector<ExtrusionPath> paths;
+ Point* first_point = nullptr;
+ coordf_t resolution_sqr;
virtual void use(ExtrusionPath &path) override {
+ //ensure the loop is continue.
+ if (first_point != nullptr) {
+ if (*first_point != path.first_point()) {
+ if (first_point->distance_to_square(path.first_point()) < resolution_sqr) {
+ path.polyline.points[0] = *first_point;
+ } else {
+ //add travel
+ ExtrusionPath travel(path.role());
+ travel.width = path.width;
+ travel.height = path.height;
+ travel.mm3_per_mm = 0;
+ travel.polyline.points.push_back(*first_point);
+ travel.polyline.points.push_back(path.first_point());
+ paths.push_back(travel);
+ }
+ }
+ first_point = nullptr;
+ }
path.mm3_per_mm *= percent_extrusion;
path.width *= percent_extrusion;
paths.push_back(path);
@@ -1884,6 +1921,9 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
//now insert thin wall if it has a point
//it found a segment
if (searcher.search_result.path != nullptr) {
+#if _DEBUG
+ searcher.search_result.loop->visit(LoopAssertVisitor{});
+#endif
if (!searcher.search_result.from_start)
tw.reverse();
//get the point
@@ -1904,20 +1944,25 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
//create thin wall path exttrusion
ExtrusionEntityCollection tws;
tws.append(Geometry::thin_variable_width({ tw }, erThinWall, this->ext_perimeter_flow, std::max(ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution))));
+ assert(!tws.entities().empty());
ChangeFlow change_flow;
if (tws.entities().size() == 1 && tws.entities()[0]->is_loop()) {
//loop, just add it
+ change_flow.first_point = &point;
change_flow.percent_extrusion = 1;
change_flow.use(tws);
//add move back
-
searcher.search_result.loop->paths.insert(searcher.search_result.loop->paths.begin() + 1 + searcher.search_result.idx_path,
change_flow.paths.begin(), change_flow.paths.end());
//add move to
+#if _DEBUG
+ searcher.search_result.loop->visit(LoopAssertVisitor{});
+#endif
} else {
//first add the return path
//ExtrusionEntityCollection tws_second = tws; // this does a deep copy
+ change_flow.first_point = &point;
change_flow.percent_extrusion = 0.1f;
change_flow.use(tws); // tws_second); //does not need the deep copy if the change_flow copy the content instead of re-using it.
//force reverse
@@ -1928,11 +1973,15 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
searcher.search_result.loop->paths.insert(searcher.search_result.loop->paths.begin() + 1 + searcher.search_result.idx_path,
change_flow.paths.begin(), change_flow.paths.end());
//add the real extrusion path
+ change_flow.first_point = &point;
change_flow.percent_extrusion = 9.f; // 0.9 but as we modified it by 0.1 just before, has to multiply by 10
change_flow.paths = std::vector<ExtrusionPath>();
change_flow.use(tws);
searcher.search_result.loop->paths.insert(searcher.search_result.loop->paths.begin() + 1 + searcher.search_result.idx_path,
change_flow.paths.begin(), change_flow.paths.end());
+#if _DEBUG
+ searcher.search_result.loop->visit(LoopAssertVisitor{});
+#endif
}
} else {
not_added.push_back(tw);