first implementation, but for overhangs the code is not run for some reason
This commit is contained in:
parent
11a7eb86fc
commit
38a287fec4
5 changed files with 149 additions and 4 deletions
|
@ -137,6 +137,13 @@ public:
|
|||
tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(this->lines);
|
||||
}
|
||||
|
||||
explicit LinesDistancer(std::vector<LineType> &&lines) : lines(lines)
|
||||
{
|
||||
tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(this->lines);
|
||||
}
|
||||
|
||||
LinesDistancer() = default;
|
||||
|
||||
// negative sign means inside
|
||||
std::tuple<Floating, size_t, Vec<2, Floating>> signed_distance_from_lines_extra(const Vec<2, Scalar> &point) const
|
||||
{
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "libslic3r.h"
|
||||
#include "ExPolygon.hpp"
|
||||
#include "Flow.hpp"
|
||||
#include "GCode/OverhangProcessor.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include "Exception.hpp"
|
||||
|
@ -38,6 +41,7 @@
|
|||
#include "SVG.hpp"
|
||||
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <utility>
|
||||
|
||||
// Intel redesigned some TBB interface considerably when merging TBB with their oneAPI set of libraries, see GH #7332.
|
||||
// We are using quite an old TBB 2017 U7. Before we update our build servers, let's use the old API, which is deprecated in up to date TBB.
|
||||
|
@ -2168,6 +2172,13 @@ LayerResult GCode::process_layer(
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<Linef> layer_lines;
|
||||
for (const LayerToPrint &layer_to_print : layers) {
|
||||
std::vector<Linef> object_lines = to_unscaled_linesf(layer_to_print.object_layer->lslices);
|
||||
layer_lines.insert(layer_lines.end() ,object_lines.begin(), object_lines.end());
|
||||
}
|
||||
m_prev_layer_boundary = AABBTreeLines::LinesDistancer<Linef>{std::move(layer_lines)};
|
||||
|
||||
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
|
||||
for (unsigned int extruder_id : layer_tools.extruders)
|
||||
{
|
||||
|
@ -2845,12 +2856,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||
acceleration = m_config.first_layer_acceleration.value;
|
||||
} else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) {
|
||||
acceleration = m_config.first_layer_acceleration_over_raft.value;
|
||||
} else if (m_config.perimeter_acceleration.value > 0 && is_perimeter(path.role())) {
|
||||
acceleration = m_config.perimeter_acceleration.value;
|
||||
} else if (m_config.bridge_acceleration.value > 0 && is_bridge(path.role())) {
|
||||
acceleration = m_config.bridge_acceleration.value;
|
||||
} else if (m_config.infill_acceleration.value > 0 && is_infill(path.role())) {
|
||||
acceleration = m_config.infill_acceleration.value;
|
||||
} else if (m_config.perimeter_acceleration.value > 0 && is_perimeter(path.role())) {
|
||||
acceleration = m_config.perimeter_acceleration.value;
|
||||
} else {
|
||||
acceleration = m_config.default_acceleration.value;
|
||||
}
|
||||
|
@ -2869,7 +2880,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||
speed = m_config.get_abs_value("perimeter_speed");
|
||||
} else if (path.role() == erExternalPerimeter) {
|
||||
speed = m_config.get_abs_value("external_perimeter_speed");
|
||||
} else if (path.role() == erOverhangPerimeter || path.role() == erBridgeInfill) {
|
||||
} else if (path.role() == erOverhangPerimeter) {
|
||||
float quality = estimate_overhang_quality(path, path.width, this->m_prev_layer_boundary);
|
||||
speed = std::max(10.0, quality * m_config.get_abs_value("bridge_speed"));
|
||||
} else if (path.role() == erBridgeInfill) {
|
||||
speed = m_config.get_abs_value("bridge_speed");
|
||||
} else if (path.role() == erInternalInfill) {
|
||||
speed = m_config.get_abs_value("infill_speed");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef slic3r_GCode_hpp_
|
||||
#define slic3r_GCode_hpp_
|
||||
|
||||
#include "GCode/OverhangProcessor.hpp"
|
||||
#include "JumpPointSearch.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include "ExPolygon.hpp"
|
||||
|
@ -332,6 +333,8 @@ private:
|
|||
|
||||
// Cache for custom seam enforcers/blockers for each layer.
|
||||
SeamPlacer m_seam_placer;
|
||||
|
||||
AABBTreeLines::LinesDistancer<Linef>m_prev_layer_boundary;
|
||||
|
||||
/* Origin of print coordinates expressed in unscaled G-code coordinates.
|
||||
This affects the input arguments supplied to the extrude*() and travel_to()
|
||||
|
|
121
src/libslic3r/GCode/OverhangProcessor.hpp
Normal file
121
src/libslic3r/GCode/OverhangProcessor.hpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
#ifndef slic3r_OverhangProcessor_hpp_
|
||||
#define slic3r_OverhangProcessor_hpp_
|
||||
|
||||
#include "../AABBTreeLines.hpp"
|
||||
#include "../SupportSpotsGenerator.hpp"
|
||||
#include "../libslic3r.h"
|
||||
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class SlidingWindowCurvatureAccumulator
|
||||
{
|
||||
float window_size;
|
||||
float total_distance = 0; // accumulated distance
|
||||
float total_curvature = 0; // accumulated signed ccw angles
|
||||
deque<float> distances;
|
||||
deque<float> angles;
|
||||
|
||||
public:
|
||||
SlidingWindowCurvatureAccumulator(float window_size) : window_size(window_size) {}
|
||||
|
||||
void add_point(float distance, float angle)
|
||||
{
|
||||
total_distance += distance;
|
||||
total_curvature += angle;
|
||||
distances.push_back(distance);
|
||||
angles.push_back(angle);
|
||||
|
||||
while (distances.size() > 1 && total_distance > window_size) {
|
||||
total_distance -= distances.front();
|
||||
total_curvature -= angles.front();
|
||||
distances.pop_front();
|
||||
angles.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
float get_curvature() const
|
||||
{
|
||||
if (total_distance <= 0.0) { return 0.0; }
|
||||
|
||||
return total_curvature / std::min(total_distance, window_size);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
total_curvature = 0;
|
||||
total_distance = 0;
|
||||
distances.clear();
|
||||
angles.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class CurvatureEstimator
|
||||
{
|
||||
static const size_t sliders_count = 4;
|
||||
SlidingWindowCurvatureAccumulator sliders[sliders_count] = {{2.0}, {4.0}, {8.0}, {16.0}};
|
||||
|
||||
public:
|
||||
void add_point(float distance, float angle)
|
||||
{
|
||||
for (SlidingWindowCurvatureAccumulator &slider : sliders) { slider.add_point(distance, angle); }
|
||||
}
|
||||
float get_curvature()
|
||||
{
|
||||
float max_curvature = std::numeric_limits<float>::min();
|
||||
for (const SlidingWindowCurvatureAccumulator &slider : sliders) { max_curvature = std::max(max_curvature, slider.get_curvature()); }
|
||||
return max_curvature;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
for (SlidingWindowCurvatureAccumulator &slider : sliders) { slider.reset(); }
|
||||
}
|
||||
};
|
||||
|
||||
inline float estimate_overhang_quality(const ExtrusionPath &entity,
|
||||
float flow_width,
|
||||
AABBTreeLines::LinesDistancer<Linef> &prev_layer_boundary)
|
||||
{
|
||||
// value of 1 is for nice straigth lines that are either in air or mostly lying on the prev layer.
|
||||
float quality = 1.0;
|
||||
|
||||
float min_malformation_dist = 0.0f;
|
||||
float max_malformation_dist = 0.7 * flow_width;
|
||||
|
||||
CurvatureEstimator cestim{};
|
||||
std::vector<Vec2f> points;
|
||||
Polyline pl = entity.as_polyline();
|
||||
points.reserve(pl.size());
|
||||
for (const Point &p : pl) { points.push_back(unscaled(p).cast<float>()); }
|
||||
|
||||
for (size_t point_idx = 0; point_idx < points.size(); ++point_idx) {
|
||||
Vec2f a = points[point_idx > 0 ? point_idx - 1 : point_idx];
|
||||
Vec2f b = points[point_idx];
|
||||
Vec2f c = points[point_idx < points.size() - 1 ? point_idx + 1 : point_idx];
|
||||
|
||||
const Vec2f v1 = b - a;
|
||||
const Vec2f v2 = c - b;
|
||||
float curr_angle = angle(v1, v2);
|
||||
|
||||
cestim.add_point(v1.norm(), curr_angle);
|
||||
// malformation in concave angles does not happen
|
||||
if (curr_angle < -20.0 * PI / 180.0) { cestim.reset(); }
|
||||
|
||||
double dist_from_prev_layer = prev_layer_boundary.signed_distance_from_lines(b.cast<double>());
|
||||
|
||||
float distance_quality = std::abs(dist_from_prev_layer - (max_malformation_dist + min_malformation_dist) * 0.5);
|
||||
float curvature_quality = std::abs(cestim.get_curvature()) * 10.0f;
|
||||
curvature_quality = std::max(curvature_quality, 1.0f);
|
||||
distance_quality /= curvature_quality;
|
||||
|
||||
if (distance_quality < quality) { quality = 0.8 * quality + 0.2 * distance_quality; }
|
||||
}
|
||||
|
||||
return quality;
|
||||
}
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
||||
#endif // slic3r_OverhangProcessor_hpp_
|
|
@ -881,7 +881,7 @@ SupportPoints full_search(const PrintObject *po, const Params ¶ms)
|
|||
|
||||
struct LayerCurlingEstimator
|
||||
{
|
||||
LD prev_layer_lines = LD({});
|
||||
LD prev_layer_lines;
|
||||
Params params;
|
||||
std::function<float(const ExtrusionLine &)> flow_width_getter;
|
||||
|
||||
|
|
Loading…
Reference in a new issue