Skip to content

Commit

Permalink
Make 'nearest' seam position truly near
Browse files Browse the repository at this point in the history
Implement suggestions by @supermerill in issue prusa3d#1409.
This makes a lot more sense than the current implementation which is
very similar to 'aligned'.
  • Loading branch information
DrLex0 committed Mar 21, 2020
1 parent d5bcdde commit 677c931
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2623,6 +2623,9 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
last_pos.y() += coord_t(3. * m_layer->object()->bounding_box().radius());
last_pos_weight = 5.f;
}
else if (seam_position == spNearest) {
last_pos_weight = 5.f;
}

// Insert a projection of last_pos into the polygon.
size_t last_pos_proj_idx;
Expand All @@ -2633,6 +2636,14 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou

// Parametrize the polygon by its length.
std::vector<float> lengths = polygon_parameter_by_length(polygon);
float dist_max = 0.1f * lengths.back(); // 5.f * nozzle_dmr

std::vector<float> distances(polygon.points.size(), 0.f);
if (seam_position == spNearest) {
for (size_t i = 0; i < polygon.points.size(); ++ i)
distances[i] = last_pos_proj.distance_to_squared(polygon.points[i]);
dist_max = *std::max_element(distances.begin(), distances.end());
}

// For each polygon point, store a penalty.
// First calculate the angles, store them as penalties. The angles are caluculated over a minimum arm length of nozzle_r.
Expand Down Expand Up @@ -2663,13 +2674,16 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
// Interpolate penalty between maximum and the penalty for a convex vertex.
penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle * float(PI * 2. / 3.));
}
// Give a negative penalty for points close to the last point or the prefered seam location.
//float dist_to_last_pos_proj = last_pos_proj.distance_to(polygon.points[i]);
float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
float dist_max = 0.1f * lengths.back(); // 5.f * nozzle_dmr
penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
if (seam_position == spNearest) {
penalty += last_pos_weight * distances[i] / dist_max;
} else {
// Give a negative penalty for points close to the last point or the prefered seam location.
//float dist_to_last_pos_proj = last_pos_proj.distance_to(polygon.points[i]);
float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
}
penalties[i] = std::max(0.f, penalty);
}

Expand Down
5 changes: 5 additions & 0 deletions src/libslic3r/Point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ void Point::rotate(double angle, const Point &center)
(*this)(1) = (coord_t)round( (double)center(1) + c * dy + s * dx );
}

double Point::distance_to_squared(const Point &point) const
{
return sqr<double>((*this)(0) - point.x()) + sqr<double>((*this)(1) - point.y());
}

int Point::nearest_point_index(const Points &points) const
{
PointConstPtrs p;
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/Point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class Point : public Vec2crd
void rotate(double angle, const Point &center);
Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
Point rotated(double angle, const Point &center) const { Point res(*this); res.rotate(angle, center); return res; }
double distance_to_squared(const Point &point) const;
int nearest_point_index(const Points &points) const;
int nearest_point_index(const PointConstPtrs &points) const;
int nearest_point_index(const PointPtrs &points) const;
Expand Down

0 comments on commit 677c931

Please sign in to comment.