curling improvements
This commit is contained in:
parent
d5d1633e2b
commit
2e437d1761
@ -64,6 +64,16 @@ float gauss(float value, float mean_x_coord, float mean_value, float falloff_spe
|
|||||||
return mean_value * (std::exp(exponent) - 1.0f) / (std::exp(1.0f) - 1.0f);
|
return mean_value * (std::exp(exponent) - 1.0f) / (std::exp(1.0f) - 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float compute_angle_penalty(float ccw_angle) {
|
||||||
|
// This function is used:
|
||||||
|
// ((ℯ^(((1)/(x^(2)*3+1)))-1)/(ℯ-1))*1+((1)/(2+ℯ^(-x)))
|
||||||
|
// looks scary, but it is gaussian combined with sigmoid,
|
||||||
|
// so that concave points have much smaller penalty over convex ones
|
||||||
|
// https://github.com/prusa3d/PrusaSlicer/tree/master/doc/seam_placement/corner_penalty_function.png
|
||||||
|
return gauss(ccw_angle, 0.0f, 1.0f, 3.0f) +
|
||||||
|
1.0f / (2 + std::exp(-ccw_angle));
|
||||||
|
}
|
||||||
|
|
||||||
/// Coordinate frame
|
/// Coordinate frame
|
||||||
class Frame {
|
class Frame {
|
||||||
public:
|
public:
|
||||||
@ -474,7 +484,7 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const
|
|||||||
|
|
||||||
// resample smooth surfaces, so that alignment finds short path down, and does not create unnecesary curves
|
// resample smooth surfaces, so that alignment finds short path down, and does not create unnecesary curves
|
||||||
if (std::all_of(polygon_angles.begin(), polygon_angles.end(), [](float angle) {
|
if (std::all_of(polygon_angles.begin(), polygon_angles.end(), [](float angle) {
|
||||||
return fabs(angle) < SeamPlacer::sharp_angle_snapping_threshold;
|
return compute_angle_penalty(angle) > SeamPlacer::sharp_angle_penalty_snapping_threshold;
|
||||||
})) {
|
})) {
|
||||||
float total_dist = std::accumulate(lengths.begin(), lengths.end(), 0.0f);
|
float total_dist = std::accumulate(lengths.begin(), lengths.end(), 0.0f);
|
||||||
float avg_dist = total_dist / float(lengths.size());
|
float avg_dist = total_dist / float(lengths.size());
|
||||||
@ -579,7 +589,8 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
viable_points_indices.push_back(last_enforced_idx);
|
viable_points_indices.push_back(last_enforced_idx);
|
||||||
if (abs(result.points[last_enforced_idx].local_ccw_angle) > SeamPlacer::sharp_angle_snapping_threshold) {
|
if (compute_angle_penalty(result.points[last_enforced_idx].local_ccw_angle)
|
||||||
|
< SeamPlacer::sharp_angle_penalty_snapping_threshold) {
|
||||||
orig_large_angle_points_indices.push_back(last_enforced_idx);
|
orig_large_angle_points_indices.push_back(last_enforced_idx);
|
||||||
}
|
}
|
||||||
last_enforced_idx = next_index(last_enforced_idx);
|
last_enforced_idx = next_index(last_enforced_idx);
|
||||||
@ -846,16 +857,6 @@ struct SeamComparator {
|
|||||||
return is_first_not_much_worse(a, b) && is_first_not_much_worse(b, a);
|
return is_first_not_much_worse(a, b) && is_first_not_much_worse(b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
float compute_angle_penalty(float ccw_angle) const {
|
|
||||||
// This function is used:
|
|
||||||
// ((ℯ^(((1)/(x^(2)*3+1)))-1)/(ℯ-1))*1+((1)/(2+ℯ^(-x)))
|
|
||||||
// looks scary, but it is gaussian combined with sigmoid,
|
|
||||||
// so that concave points have much smaller penalty over convex ones
|
|
||||||
// https://github.com/prusa3d/PrusaSlicer/tree/master/doc/seam_placement/corner_penalty_function.png
|
|
||||||
return gauss(ccw_angle, 0.0f, 1.0f, 3.0f) +
|
|
||||||
1.0f / (2 + std::exp(-ccw_angle));
|
|
||||||
}
|
|
||||||
|
|
||||||
float weight(const SeamCandidate &a) const {
|
float weight(const SeamCandidate &a) const {
|
||||||
if (setup == SeamPosition::spAligned && a.central_enforcer) {
|
if (setup == SeamPosition::spAligned && a.central_enforcer) {
|
||||||
return 2.0f;
|
return 2.0f;
|
||||||
@ -1390,8 +1391,7 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
|
|||||||
last_point_pos = pos;
|
last_point_pos = pos;
|
||||||
observations[index] = pos.head<2>();
|
observations[index] = pos.head<2>();
|
||||||
observation_points[index] = pos.z();
|
observation_points[index] = pos.z();
|
||||||
weights[index] = std::min(1.0f,
|
weights[index] = comparator.weight(layers[seam_string[index].first].points[seam_string[index].second]);
|
||||||
comparator.weight(layers[seam_string[index].first].points[seam_string[index].second]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Curve Fitting
|
// Curve Fitting
|
||||||
@ -1404,14 +1404,14 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
|
|||||||
for (size_t index = 0; index < seam_string.size(); ++index) {
|
for (size_t index = 0; index < seam_string.size(); ++index) {
|
||||||
const auto &pair = seam_string[index];
|
const auto &pair = seam_string[index];
|
||||||
const float t =
|
const float t =
|
||||||
abs(layers[pair.first].points[pair.second].local_ccw_angle)
|
compute_angle_penalty(layers[pair.first].points[pair.second].local_ccw_angle)
|
||||||
> SeamPlacer::sharp_angle_snapping_threshold
|
< SeamPlacer::sharp_angle_penalty_snapping_threshold
|
||||||
? 1.0 : 0.0f;
|
? 0.8f : 0.0f;
|
||||||
Vec3f current_pos = layers[pair.first].points[pair.second].position;
|
Vec3f current_pos = layers[pair.first].points[pair.second].position;
|
||||||
Vec2f fitted_pos = curve.get_fitted_value(current_pos.z());
|
Vec2f fitted_pos = curve.get_fitted_value(current_pos.z());
|
||||||
|
|
||||||
//interpolate between current and fitted position, prefer current pos for large weights.
|
//interpolate between current and fitted position, prefer current pos for large weights.
|
||||||
Vec3f final_position = t * current_pos + (1 - t) * to_3d(fitted_pos, current_pos.z());
|
Vec3f final_position = t * current_pos + (1.0f - t) * to_3d(fitted_pos, current_pos.z());
|
||||||
|
|
||||||
Perimeter &perimeter = layers[pair.first].points[pair.second].perimeter;
|
Perimeter &perimeter = layers[pair.first].points[pair.second].perimeter;
|
||||||
perimeter.seam_index = pair.second;
|
perimeter.seam_index = pair.second;
|
||||||
|
@ -128,7 +128,8 @@ public:
|
|||||||
|
|
||||||
// arm length used during angles computation
|
// arm length used during angles computation
|
||||||
static constexpr float polygon_local_angles_arm_distance = 0.3f;
|
static constexpr float polygon_local_angles_arm_distance = 0.3f;
|
||||||
static constexpr float sharp_angle_snapping_threshold = (60.0f / 180.0f) * float(PI);
|
// value for angles with penalty lower than this threshold - such angles will be snapped to their original position instead of spline interpolated position
|
||||||
|
static constexpr float sharp_angle_penalty_snapping_threshold = 0.6f;
|
||||||
|
|
||||||
// max tolerable distance from the previous layer is overhang_distance_tolerance_factor * flow_width
|
// max tolerable distance from the previous layer is overhang_distance_tolerance_factor * flow_width
|
||||||
static constexpr float overhang_distance_tolerance_factor = 0.5f;
|
static constexpr float overhang_distance_tolerance_factor = 0.5f;
|
||||||
|
Loading…
Reference in New Issue
Block a user