mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 18:55:59 +08:00
Fixed an issue that the wipe was shorter when it was located where extrusion width was changing.
This commit is contained in:
parent
0c22ca3ece
commit
952a6c882c
@ -268,13 +268,13 @@ void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extr
|
|||||||
{
|
{
|
||||||
for (const ClipperLib_Z::Path &extrusion_path : extrusion_paths) {
|
for (const ClipperLib_Z::Path &extrusion_path : extrusion_paths) {
|
||||||
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion_path);
|
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)
|
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow)
|
||||||
{
|
{
|
||||||
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion);
|
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
|
} // namespace Slic3r
|
@ -426,14 +426,13 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||||||
for (const ThickPolyline &thick_polyline : thick_polylines) {
|
for (const ThickPolyline &thick_polyline : thick_polylines) {
|
||||||
Flow new_flow = surface_fill.params.flow.with_spacing(float(f->spacing));
|
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.
|
// Append paths to collection.
|
||||||
if (!paths.empty()) {
|
if (!multi_path.empty()) {
|
||||||
if (paths.front().first_point() == paths.back().last_point())
|
if (multi_path.paths.front().first_point() == multi_path.paths.back().last_point())
|
||||||
eec->entities.emplace_back(new ExtrusionLoop(std::move(paths)));
|
eec->entities.emplace_back(new ExtrusionLoop(std::move(multi_path.paths)));
|
||||||
else
|
else
|
||||||
for (ExtrusionPath &path : paths)
|
eec->entities.emplace_back(new ExtrusionMultiPath(std::move(multi_path)));
|
||||||
eec->entities.emplace_back(new ExtrusionPath(std::move(path)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
// thus empty path segments will not be produced by G-code export.
|
||||||
loop.split_at(last_pos, false, scaled<double>(0.0015));
|
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;
|
// 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
|
// if polyline was shorter than the clipping distance we'd get a null polyline, so
|
||||||
// we discard it in that case
|
// we discard it in that case
|
||||||
@ -2670,8 +2676,21 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||||||
// reset acceleration
|
// reset acceleration
|
||||||
gcode += m_writer.set_acceleration((unsigned int)(m_config.default_acceleration.value + 0.5));
|
gcode += m_writer.set_acceleration((unsigned int)(m_config.default_acceleration.value + 0.5));
|
||||||
|
|
||||||
if (m_wipe.enable)
|
if (m_wipe.enable) {
|
||||||
m_wipe.path = paths.front().polyline; // TODO: don't limit wipe to last path
|
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
|
// 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) {
|
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)
|
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
|
// extrude along the path
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
for (ExtrusionPath path : multipath.paths) {
|
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);
|
gcode += this->_extrude(path, description, speed);
|
||||||
}
|
}
|
||||||
if (m_wipe.enable) {
|
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();
|
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
|
// reset acceleration
|
||||||
gcode += m_writer.set_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
|
gcode += m_writer.set_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
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;
|
ExtrusionMultiPath multi_path;
|
||||||
ExtrusionPath path(role);
|
ExtrusionPath path(role);
|
||||||
ThickLines lines = thick_polyline.thicklines();
|
ThickLines lines = thick_polyline.thicklines();
|
||||||
|
|
||||||
@ -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.
|
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.
|
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;
|
lines[i + 1].a = line.a;
|
||||||
else if (!paths.empty())
|
else if (!multi_path.paths.empty())
|
||||||
paths.back().polyline.points.back() = line.b; // Connect this tiny line to the last finished path.
|
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.
|
// If any of the above isn't satisfied, then remove this tiny line.
|
||||||
continue;
|
continue;
|
||||||
@ -103,38 +103,36 @@ ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_poly
|
|||||||
path.polyline.append(line.b);
|
path.polyline.append(line.b);
|
||||||
} else {
|
} else {
|
||||||
// we need to initialize a new line
|
// we need to initialize a new line
|
||||||
paths.emplace_back(std::move(path));
|
multi_path.paths.emplace_back(std::move(path));
|
||||||
path = ExtrusionPath(role);
|
path = ExtrusionPath(role);
|
||||||
-- i;
|
-- i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (path.polyline.is_valid())
|
if (path.polyline.is_valid())
|
||||||
paths.emplace_back(std::move(path));
|
multi_path.paths.emplace_back(std::move(path));
|
||||||
return paths;
|
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
|
// 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
|
// 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.
|
// of segments, and any pruning shall be performed before we apply this tolerance.
|
||||||
const auto tolerance = float(scale_(0.05));
|
const auto tolerance = float(scale_(0.05));
|
||||||
for (const ThickPolyline &p : polylines) {
|
for (const ThickPolyline &p : polylines) {
|
||||||
ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance, tolerance);
|
ExtrusionMultiPath multi_path = thick_polyline_to_multi_path(p, role, flow, tolerance, tolerance);
|
||||||
// Append paths to collection.
|
// Append paths to collection.
|
||||||
if (!paths.empty()) {
|
if (!multi_path.paths.empty()) {
|
||||||
for (auto it = std::next(paths.begin()); it != paths.end(); ++it) {
|
for (auto it = std::next(multi_path.paths.begin()); it != multi_path.paths.end(); ++it) {
|
||||||
assert(it->polyline.points.size() >= 2);
|
assert(it->polyline.points.size() >= 2);
|
||||||
assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
|
assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paths.front().first_point() == paths.back().last_point()) {
|
if (multi_path.paths.front().first_point() == multi_path.paths.back().last_point())
|
||||||
out.emplace_back(new ExtrusionLoop(std::move(paths)));
|
out.emplace_back(new ExtrusionLoop(std::move(multi_path.paths)));
|
||||||
} else {
|
else
|
||||||
for (ExtrusionPath &path : paths)
|
out.emplace_back(new ExtrusionMultiPath(std::move(multi_path)));
|
||||||
out.emplace_back(new ExtrusionPath(std::move(path)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,10 +532,35 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator &p
|
|||||||
else
|
else
|
||||||
extrusion_loop.make_clockwise();
|
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));
|
extrusion_coll.append(std::move(extrusion_loop));
|
||||||
} else
|
} else {
|
||||||
for (ExtrusionPath &path : paths)
|
// Because we are processing one ExtrusionLine all ExtrusionPaths should form one connected path.
|
||||||
extrusion_coll.append(ExtrusionPath(std::move(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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ private:
|
|||||||
Polygons m_lower_slices_polygons;
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user