diff options
author | supermerill <merill@free.fr> | 2022-09-16 16:58:51 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2022-09-16 17:32:00 +0300 |
commit | cc59dbd07125ec8c5e36c89b62b8a1ca85db0477 (patch) | |
tree | 15caee4eca4509adadd1a0e9224a130973094244 | |
parent | ceec9d753e97709f44f0db31057c3d23cfc5a430 (diff) |
Fix thinwall-merge to keep a real loop
-rw-r--r-- | src/libslic3r/PerimeterGenerator.cpp | 55 |
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); |