slowdown fix, curvature quality estimation fix
This commit is contained in:
parent
bdc58c617b
commit
f4f1958cac
@ -2705,6 +2705,7 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, const std::s
|
||||
|
||||
std::string GCode::extrude_entity(const ExtrusionEntity &entity, const std::string_view description, double speed)
|
||||
{
|
||||
m_extrusion_quality_estimator.reset_for_next_extrusion();
|
||||
if (const ExtrusionPath* path = dynamic_cast<const ExtrusionPath*>(&entity))
|
||||
return this->extrude_path(*path, description, speed);
|
||||
else if (const ExtrusionMultiPath* multipath = dynamic_cast<const ExtrusionMultiPath*>(&entity))
|
||||
|
@ -6,7 +6,10 @@
|
||||
#include "../libslic3r.h"
|
||||
#include "../ExtrusionEntity.hpp"
|
||||
#include "../Layer.hpp"
|
||||
#include "../Point.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
@ -42,7 +45,7 @@ public:
|
||||
|
||||
float get_curvature() const
|
||||
{
|
||||
if (total_distance <= 0.0) { return 0.0; }
|
||||
if (total_distance < EPSILON) { return 0.0; }
|
||||
|
||||
return total_curvature / std::max(total_distance, window_size);
|
||||
}
|
||||
@ -58,8 +61,8 @@ public:
|
||||
|
||||
class CurvatureEstimator
|
||||
{
|
||||
static const size_t sliders_count = 4;
|
||||
SlidingWindowCurvatureAccumulator sliders[sliders_count] = {{2.0}, {4.0}, {8.0}, {16.0}};
|
||||
static const size_t sliders_count = 3;
|
||||
SlidingWindowCurvatureAccumulator sliders[sliders_count] = {{2.0},{4.0}, {8.0}};
|
||||
|
||||
public:
|
||||
void add_point(float distance, float angle)
|
||||
@ -83,8 +86,11 @@ class ExtrusionQualityEstimator
|
||||
{
|
||||
AABBTreeLines::LinesDistancer<Linef> prev_layer_boundary;
|
||||
AABBTreeLines::LinesDistancer<Linef> next_layer_boundary;
|
||||
CurvatureEstimator cestim;
|
||||
|
||||
public:
|
||||
void reset_for_next_extrusion() { cestim.reset(); }
|
||||
|
||||
void prepare_for_new_layer(const std::vector<const Layer *> &layers)
|
||||
{
|
||||
std::vector<Linef> layer_lines;
|
||||
@ -102,7 +108,7 @@ public:
|
||||
float flow_width = path.width;
|
||||
float min_malformation_dist = 0.0 * flow_width;
|
||||
float max_malformation_dist = 1.1 * flow_width;
|
||||
float worst_malformation_dist = 0.5 * (min_malformation_dist + max_malformation_dist);
|
||||
float worst_malformation_dist = 0.7 * flow_width;
|
||||
|
||||
std::vector<Vec2f> points;
|
||||
Polyline pl = path.as_polyline();
|
||||
@ -110,24 +116,55 @@ public:
|
||||
for (const Point &p : pl) { points.push_back(unscaled(p).cast<float>()); }
|
||||
|
||||
std::vector<float> point_qualities(points.size(), 1.0);
|
||||
for (size_t point_idx = 0; point_idx < points.size(); ++point_idx) {
|
||||
for (int point_idx = 0; point_idx < int(points.size()); ++point_idx) {
|
||||
const Vec2f &p = points[point_idx];
|
||||
|
||||
double dist_from_prev_layer = prev_layer_boundary.signed_distance_from_lines(p.cast<double>()) + flow_width * 0.5f;
|
||||
if (dist_from_prev_layer < min_malformation_dist) continue;
|
||||
|
||||
float basic_distance_quality = 0.5f * fmin(1.0f, (1.0f - (dist_from_prev_layer - min_malformation_dist) /
|
||||
(max_malformation_dist - min_malformation_dist)));
|
||||
float curling_distance_quality = 0.5f * fmin(1.0f, std::abs(dist_from_prev_layer - worst_malformation_dist) /
|
||||
(worst_malformation_dist - min_malformation_dist));
|
||||
float default_dist_quality = 0.5f;
|
||||
float distance_quality = 1.0f;
|
||||
if (dist_from_prev_layer < min_malformation_dist) {
|
||||
distance_quality = 1.0f;
|
||||
cestim.reset();
|
||||
continue;
|
||||
} else if (dist_from_prev_layer < worst_malformation_dist) {
|
||||
distance_quality = (worst_malformation_dist - dist_from_prev_layer) / (worst_malformation_dist - min_malformation_dist);
|
||||
} else if (dist_from_prev_layer < max_malformation_dist) {
|
||||
distance_quality = default_dist_quality * (1.0f - (max_malformation_dist - dist_from_prev_layer) /
|
||||
(max_malformation_dist - worst_malformation_dist));
|
||||
} else { // completely in the air. use the default value in that case
|
||||
distance_quality = default_dist_quality;
|
||||
}
|
||||
|
||||
float distance_quality = basic_distance_quality + curling_distance_quality;
|
||||
int prev_point_idx = point_idx;
|
||||
while (prev_point_idx > 0) {
|
||||
prev_point_idx--;
|
||||
if ((p - points[prev_point_idx]).squaredNorm() > EPSILON) { break; }
|
||||
}
|
||||
|
||||
point_qualities[point_idx] = distance_quality;
|
||||
int next_point_index = point_idx;
|
||||
while (next_point_index < int(points.size()) - 1) {
|
||||
next_point_index++;
|
||||
if ((p - points[next_point_index]).squaredNorm() > EPSILON) { break; }
|
||||
}
|
||||
|
||||
float curvature_penalty = 0.0f;
|
||||
if (prev_point_idx != point_idx && next_point_index != point_idx) {
|
||||
float distance = (p - points[prev_point_idx]).norm();
|
||||
float alfa = angle(p - points[prev_point_idx], points[next_point_index] - p);
|
||||
cestim.add_point(distance, alfa);
|
||||
|
||||
float curvature = std::abs(cestim.get_curvature());
|
||||
if (curvature > 1.0f) {
|
||||
curvature_penalty = 1.0f;
|
||||
} else if (curvature > 0.1f) {
|
||||
curvature_penalty = std::min(1.0, dist_from_prev_layer - min_malformation_dist) * curvature;
|
||||
}
|
||||
}
|
||||
|
||||
point_qualities[point_idx] = std::clamp(distance_quality - curvature_penalty, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
if (points.size() > 1) { point_qualities[0] = point_qualities[1]; }
|
||||
|
||||
for (size_t point_idx = 1; point_idx < points.size(); ++point_idx) {
|
||||
point_qualities[point_idx - 1] = std::max(point_qualities[point_idx - 1], point_qualities[point_idx]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user