From 82aed45816b300dc3a8b391c866a573cd979fcbc Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 22 Feb 2017 16:35:07 +0100 Subject: [PATCH] Hopefully fixes the aligned seam: https://github.com/prusa3d/Slic3r/issues/74 The way it works now is following: Slic3r will add some negative penalty to all perimeter points near the last seam. Once the perimeter point with minimum penalty is found, its penalty is compared to a point closest to the last seam. If the penalty of the point closest to the last seam is nearly as good as the minimum penalty, the point closest to the last seam is picked instead. This heuristics will hide the seams into corners if possible, but if not possible, it will strive to align the seams precisely. --- xs/src/libslic3r/GCode.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index ae49f1d9ecf..bab8a56eb43 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -587,7 +587,7 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed) // Seam is aligned to the seam at the preceding layer. if (this->layer != NULL && this->_seam_position.count(this->layer->object()) > 0) { last_pos = this->_seam_position[this->layer->object()]; - last_pos_weight = 5.f; + last_pos_weight = 1.f; } break; case spRear: @@ -669,6 +669,25 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed) // Find a point with a minimum penalty. size_t idx_min = std::min_element(penalties.begin(), penalties.end()) - penalties.begin(); + // if (seam_position == spAligned) + // For all (aligned, nearest, rear) seams: + { + // Very likely the weight of idx_min is very close to the weight of last_pos_proj_idx. + // In that case use last_pos_proj_idx instead. + float penalty_aligned = penalties[last_pos_proj_idx]; + float penalty_min = penalties[idx_min]; + float penalty_diff_abs = std::abs(penalty_min - penalty_aligned); + float penalty_max = std::max(penalty_min, penalty_aligned); + float penalty_diff_rel = (penalty_max == 0.f) ? 0.f : penalty_diff_abs / penalty_max; + // printf("Align seams, penalty aligned: %f, min: %f, diff abs: %f, diff rel: %f\n", penalty_aligned, penalty_min, penalty_diff_abs, penalty_diff_rel); + if (penalty_diff_rel < 0.05) { + // Penalty of the aligned point is very close to the minimum penalty. + // Align the seams as accurately as possible. + idx_min = last_pos_proj_idx; + } + this->_seam_position[this->layer->object()] = polygon.points[idx_min]; + } + // Export the contour into a SVG file. #if 0 {