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:
authorLukáš Hejl <hejl.lukas@gmail.com>2022-07-22 12:50:58 +0300
committerLukas Matena <lukasmatena@seznam.cz>2022-08-18 18:00:28 +0300
commit952a6c882c7553644aec74563e7e2be3716a2bfb (patch)
treed0b112cce639e2e37c8897d0fc5306cf0b362337
parent0c22ca3ece854d982faa6c5448f7320c85abcef6 (diff)
Fixed an issue that the wipe was shorter when it was located where extrusion width was changing.
-rw-r--r--src/libslic3r/Arachne/utils/ExtrusionLine.cpp4
-rw-r--r--src/libslic3r/Fill/Fill.cpp11
-rw-r--r--src/libslic3r/GCode.cpp41
-rw-r--r--src/libslic3r/PerimeterGenerator.cpp85
-rw-r--r--src/libslic3r/PerimeterGenerator.hpp2
5 files changed, 100 insertions, 43 deletions
diff --git a/src/libslic3r/Arachne/utils/ExtrusionLine.cpp b/src/libslic3r/Arachne/utils/ExtrusionLine.cpp
index a5734f478..75e4d5338 100644
--- a/src/libslic3r/Arachne/utils/ExtrusionLine.cpp
+++ b/src/libslic3r/Arachne/utils/ExtrusionLine.cpp
@@ -268,13 +268,13 @@ void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extr
{
for (const ClipperLib_Z::Path &extrusion_path : extrusion_paths) {
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion_path);
- Slic3r::append(dst, thick_polyline_to_extrusion_paths(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)));
+ Slic3r::append(dst, thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)).paths);
}
}
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow)
{
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion);
- Slic3r::append(dst, thick_polyline_to_extrusion_paths(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)));
+ Slic3r::append(dst, thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)).paths);
}
} // namespace Slic3r \ No newline at end of file
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index d6eaff03a..9d25143fb 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -426,14 +426,13 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
for (const ThickPolyline &thick_polyline : thick_polylines) {
Flow new_flow = surface_fill.params.flow.with_spacing(float(f->spacing));
- ExtrusionPaths paths = thick_polyline_to_extrusion_paths(thick_polyline, surface_fill.params.extrusion_role, new_flow, scaled<float>(0.05), 0);
+ ExtrusionMultiPath multi_path = thick_polyline_to_multi_path(thick_polyline, surface_fill.params.extrusion_role, new_flow, scaled<float>(0.05), float(SCALED_EPSILON));
// Append paths to collection.
- if (!paths.empty()) {
- if (paths.front().first_point() == paths.back().last_point())
- eec->entities.emplace_back(new ExtrusionLoop(std::move(paths)));
+ if (!multi_path.empty()) {
+ if (multi_path.paths.front().first_point() == multi_path.paths.back().last_point())
+ eec->entities.emplace_back(new ExtrusionLoop(std::move(multi_path.paths)));
else
- for (ExtrusionPath &path : paths)
- eec->entities.emplace_back(new ExtrusionPath(std::move(path)));
+ eec->entities.emplace_back(new ExtrusionMultiPath(std::move(multi_path)));
}
}
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index f2c435c4f..f8fc2e5a7 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -2642,6 +2642,12 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
// thus empty path segments will not be produced by G-code export.
loop.split_at(last_pos, false, scaled<double>(0.0015));
+ 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());
+
// clip the path to avoid the extruder to get exactly on the first point of the loop;
// if polyline was shorter than the clipping distance we'd get a null polyline, so
// we discard it in that case
@@ -2670,8 +2676,21 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
// reset acceleration
gcode += m_writer.set_acceleration((unsigned int)(m_config.default_acceleration.value + 0.5));
- if (m_wipe.enable)
- m_wipe.path = paths.front().polyline; // TODO: don't limit wipe to last path
+ if (m_wipe.enable) {
+ m_wipe.path = paths.front().polyline;
+
+ for (auto it = std::next(paths.begin()); it != paths.end(); ++it) {
+ if (is_bridge(it->role()))
+ break; // Don't perform a wipe on bridges.
+
+ assert(it->polyline.points.size() >= 2);
+ assert(m_wipe.path.points.back() == it->polyline.first_point());
+ if (m_wipe.path.points.back() != it->polyline.first_point())
+ break; // ExtrusionLoop is interrupted in some place.
+
+ m_wipe.path.points.insert(m_wipe.path.points.end(), it->polyline.points.begin() + 1, it->polyline.points.end());
+ }
+ }
// make a little move inwards before leaving loop
if (paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) {
@@ -2712,6 +2731,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string description, double speed)
{
+ for (auto it = std::next(multipath.paths.begin()); it != multipath.paths.end(); ++it) {
+ assert(it->polyline.points.size() >= 2);
+ assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
+ }
// extrude along the path
std::string gcode;
for (ExtrusionPath path : multipath.paths) {
@@ -2721,8 +2744,20 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string
gcode += this->_extrude(path, description, speed);
}
if (m_wipe.enable) {
- m_wipe.path = std::move(multipath.paths.back().polyline); // TODO: don't limit wipe to last path
+ m_wipe.path = std::move(multipath.paths.back().polyline);
m_wipe.path.reverse();
+
+ for (auto it = std::next(multipath.paths.rbegin()); it != multipath.paths.rend(); ++it) {
+ if (is_bridge(it->role()))
+ break; // Do not perform a wipe on bridges.
+
+ assert(it->polyline.points.size() >= 2);
+ assert(m_wipe.path.points.back() == it->polyline.last_point());
+ if (m_wipe.path.points.back() != it->polyline.last_point())
+ break; // ExtrusionMultiPath is interrupted in some place.
+
+ m_wipe.path.points.insert(m_wipe.path.points.end(), it->polyline.points.rbegin() + 1, it->polyline.points.rend());
+ }
}
// reset acceleration
gcode += m_writer.set_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index 830d48571..e61f9097d 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -21,12 +21,12 @@
namespace Slic3r {
-ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
+ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
{
- ExtrusionPaths paths;
- ExtrusionPath path(role);
- ThickLines lines = thick_polyline.thicklines();
-
+ ExtrusionMultiPath multi_path;
+ ExtrusionPath path(role);
+ ThickLines lines = thick_polyline.thicklines();
+
for (int i = 0; i < (int)lines.size(); ++i) {
const ThickLine& line = lines[i];
assert(line.a_width >= SCALED_EPSILON && line.b_width >= SCALED_EPSILON);
@@ -38,8 +38,8 @@ ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_poly
path.polyline.points.back() = line.b; // If the variable path is non-empty, connect this tiny line to it.
else if (i + 1 < (int)lines.size()) // If there is at least one following line, connect this tiny line to it.
lines[i + 1].a = line.a;
- else if (!paths.empty())
- paths.back().polyline.points.back() = line.b; // Connect this tiny line to the last finished path.
+ else if (!multi_path.paths.empty())
+ multi_path.paths.back().polyline.points.back() = line.b; // Connect this tiny line to the last finished path.
// If any of the above isn't satisfied, then remove this tiny line.
continue;
@@ -103,40 +103,38 @@ ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_poly
path.polyline.append(line.b);
} else {
// we need to initialize a new line
- paths.emplace_back(std::move(path));
+ multi_path.paths.emplace_back(std::move(path));
path = ExtrusionPath(role);
-- i;
}
}
}
if (path.polyline.is_valid())
- paths.emplace_back(std::move(path));
- return paths;
+ multi_path.paths.emplace_back(std::move(path));
+ return multi_path;
}
-static void variable_width(const ThickPolylines& polylines, ExtrusionRole role, const Flow &flow, std::vector<ExtrusionEntity*> &out)
+static void variable_width(const ThickPolylines &polylines, ExtrusionRole role, const Flow &flow, std::vector<ExtrusionEntity *> &out)
{
- // 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
- // of segments, and any pruning shall be performed before we apply this tolerance.
- const auto tolerance = float(scale_(0.05));
- for (const ThickPolyline &p : polylines) {
- ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance, tolerance);
- // Append paths to collection.
- if (!paths.empty()) {
- for (auto it = std::next(paths.begin()); it != paths.end(); ++it) {
+ // 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
+ // of segments, and any pruning shall be performed before we apply this tolerance.
+ const auto tolerance = float(scale_(0.05));
+ for (const ThickPolyline &p : polylines) {
+ ExtrusionMultiPath multi_path = thick_polyline_to_multi_path(p, role, flow, tolerance, tolerance);
+ // Append paths to collection.
+ if (!multi_path.paths.empty()) {
+ for (auto it = std::next(multi_path.paths.begin()); it != multi_path.paths.end(); ++it) {
assert(it->polyline.points.size() >= 2);
assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
}
- if (paths.front().first_point() == paths.back().last_point()) {
- out.emplace_back(new ExtrusionLoop(std::move(paths)));
- } else {
- for (ExtrusionPath &path : paths)
- out.emplace_back(new ExtrusionPath(std::move(path)));
- }
- }
- }
+ if (multi_path.paths.front().first_point() == multi_path.paths.back().last_point())
+ out.emplace_back(new ExtrusionLoop(std::move(multi_path.paths)));
+ else
+ out.emplace_back(new ExtrusionMultiPath(std::move(multi_path)));
+ }
+ }
}
// Hierarchy of perimeters.
@@ -534,10 +532,35 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator &p
else
extrusion_loop.make_clockwise();
+ for (auto it = std::next(extrusion_loop.paths.begin()); it != extrusion_loop.paths.end(); ++it) {
+ assert(it->polyline.points.size() >= 2);
+ assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
+ }
+ assert(extrusion_loop.paths.front().first_point() == extrusion_loop.paths.back().last_point());
+
extrusion_coll.append(std::move(extrusion_loop));
- } else
- for (ExtrusionPath &path : paths)
- extrusion_coll.append(ExtrusionPath(std::move(path)));
+ } else {
+ // Because we are processing one ExtrusionLine all ExtrusionPaths should form one connected path.
+ // But there is possibility that due to numerical issue there is poss
+ assert([&paths = std::as_const(paths)]() -> bool {
+ for (auto it = std::next(paths.begin()); it != paths.end(); ++it)
+ if (std::prev(it)->polyline.last_point() != it->polyline.first_point())
+ return false;
+ return true;
+ }());
+ ExtrusionMultiPath multi_path;
+ multi_path.paths.emplace_back(std::move(paths.front()));
+
+ for (auto it_path = std::next(paths.begin()); it_path != paths.end(); ++it_path) {
+ if (multi_path.paths.back().last_point() != it_path->first_point()) {
+ extrusion_coll.append(ExtrusionMultiPath(std::move(multi_path)));
+ multi_path = ExtrusionMultiPath();
+ }
+ multi_path.paths.emplace_back(std::move(*it_path));
+ }
+
+ extrusion_coll.append(ExtrusionMultiPath(std::move(multi_path)));
+ }
}
}
diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp
index 2e478e107..ecf09c593 100644
--- a/src/libslic3r/PerimeterGenerator.hpp
+++ b/src/libslic3r/PerimeterGenerator.hpp
@@ -72,7 +72,7 @@ private:
Polygons m_lower_slices_polygons;
};
-ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, float tolerance, float merge_tolerance);
+ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, float tolerance, float merge_tolerance);
}