Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::ExtrusionQualityEstimator Class Reference

#include <src/libslic3r/GCode/ExtrusionProcessor.hpp>

+ Collaboration diagram for Slic3r::ExtrusionQualityEstimator:

Public Member Functions

void set_current_object (const PrintObject *object)
 
void prepare_for_new_layer (const Layer *layer)
 
std::vector< ProcessedPointestimate_speed_from_extrusion_quality (const ExtrusionPath &path, const std::vector< std::pair< int, ConfigOptionFloatOrPercent > > overhangs_w_speeds, const std::vector< std::pair< int, ConfigOptionInts > > overhangs_w_fan_speeds, size_t extruder_id, float ext_perimeter_speed, float original_speed)
 

Private Attributes

std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< Linef > > prev_layer_boundaries
 
std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< Linef > > next_layer_boundaries
 
std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< CurledLine > > prev_curled_extrusions
 
std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< CurledLine > > next_curled_extrusions
 
const PrintObjectcurrent_object
 

Detailed Description

Member Function Documentation

◆ estimate_speed_from_extrusion_quality()

std::vector< ProcessedPoint > Slic3r::ExtrusionQualityEstimator::estimate_speed_from_extrusion_quality ( const ExtrusionPath path,
const std::vector< std::pair< int, ConfigOptionFloatOrPercent > >  overhangs_w_speeds,
const std::vector< std::pair< int, ConfigOptionInts > >  overhangs_w_fan_speeds,
size_t  extruder_id,
float  ext_perimeter_speed,
float  original_speed 
)
inline
250 {
251 float speed_base = ext_perimeter_speed > 0 ? ext_perimeter_speed : original_speed;
252 std::map<float, float> speed_sections;
253 for (size_t i = 0; i < overhangs_w_speeds.size(); i++) {
254 float distance = path.width * (1.0 - (overhangs_w_speeds[i].first / 100.0));
255 float speed = overhangs_w_speeds[i].second.percent ? (speed_base * overhangs_w_speeds[i].second.value / 100.0) :
256 overhangs_w_speeds[i].second.value;
257 if (speed < EPSILON) speed = speed_base;
258 speed_sections[distance] = speed;
259 }
260
261 std::map<float, float> fan_speed_sections;
262 for (size_t i = 0; i < overhangs_w_fan_speeds.size(); i++) {
263 float distance = path.width * (1.0 - (overhangs_w_fan_speeds[i].first / 100.0));
264 float fan_speed = overhangs_w_fan_speeds[i].second.get_at(extruder_id);
265 fan_speed_sections[distance] = fan_speed;
266 }
267
268 std::vector<ExtendedPoint> extended_points =
269 estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width);
270
271 std::vector<ProcessedPoint> processed_points;
272 processed_points.reserve(extended_points.size());
273 for (size_t i = 0; i < extended_points.size(); i++) {
274 const ExtendedPoint &curr = extended_points[i];
275 const ExtendedPoint &next = extended_points[i + 1 < extended_points.size() ? i + 1 : i];
276
277 // The following code artifically increases the distance to provide slowdown for extrusions that are over curled lines
278 float artificial_distance_to_curled_lines = 0.0;
279 const double dist_limit = 10.0 * path.width;
280 {
281 Vec2d middle = 0.5 * (curr.position + next.position);
282 auto line_indices = prev_curled_extrusions[current_object].all_lines_in_radius(Point::new_scale(middle), scale_(dist_limit));
283 if (!line_indices.empty()) {
284 double len = (next.position - curr.position).norm();
285 // For long lines, there is a problem with the additional slowdown. If by accident, there is small curled line near the middle of this long line
286 // The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down.
287 // NOTE that this is still quite rough approximation, e.g. we are still checking lines only near the middle point
288 // TODO maybe split the lines into smaller segments before running this alg? but can be demanding, and GCode will be huge
289 if (len > 8) {
290 Vec2d dir = Vec2d(next.position - curr.position) / len;
291 Vec2d right = Vec2d(-dir.y(), dir.x());
292
293 Polygon box_of_influence = {
294 scaled(Vec2d(curr.position + right * dist_limit)),
295 scaled(Vec2d(next.position + right * dist_limit)),
296 scaled(Vec2d(next.position - right * dist_limit)),
297 scaled(Vec2d(curr.position - right * dist_limit)),
298 };
299
300 double projected_lengths_sum = 0;
301 for (size_t idx : line_indices) {
302 const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
303 Lines inside = intersection_ln({{line.a, line.b}}, {box_of_influence});
304 if (inside.empty())
305 continue;
306 double projected_length = abs(dir.dot(unscaled(Vec2d((inside.back().b - inside.back().a).cast<double>()))));
307 projected_lengths_sum += projected_length;
308 }
309 if (projected_lengths_sum < 0.4 * len) {
310 line_indices.clear();
311 }
312 }
313
314 for (size_t idx : line_indices) {
315 const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
316 float distance_from_curled = unscaled(line_alg::distance_to(line, Point::new_scale(middle)));
317 float dist = path.width * (1.0 - (distance_from_curled / dist_limit)) *
318 (1.0 - (distance_from_curled / dist_limit)) *
319 (line.curled_height / (path.height * 10.0f)); // max_curled_height_factor from SupportSpotGenerator
320 artificial_distance_to_curled_lines = std::max(artificial_distance_to_curled_lines, dist);
321 }
322 }
323 }
324
325 auto interpolate_speed = [](const std::map<float, float> &values, float distance) {
326 auto upper_dist = values.lower_bound(distance);
327 if (upper_dist == values.end()) {
328 return values.rbegin()->second;
329 }
330 if (upper_dist == values.begin()) {
331 return upper_dist->second;
332 }
333
334 auto lower_dist = std::prev(upper_dist);
335 float t = (distance - lower_dist->first) / (upper_dist->first - lower_dist->first);
336 return (1.0f - t) * lower_dist->second + t * upper_dist->second;
337 };
338
339 float extrusion_speed = std::min(interpolate_speed(speed_sections, curr.distance),
340 interpolate_speed(speed_sections, next.distance));
341 float curled_base_speed = interpolate_speed(speed_sections, artificial_distance_to_curled_lines);
342 float final_speed = std::min(curled_base_speed, extrusion_speed);
343 float fan_speed = std::min(interpolate_speed(fan_speed_sections, curr.distance),
344 interpolate_speed(fan_speed_sections, next.distance));
345
346 processed_points.push_back({scaled(curr.position), final_speed, int(fan_speed)});
347 }
348 return processed_points;
349 }
std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< CurledLine > > prev_curled_extrusions
Definition ExtrusionProcessor.hpp:225
const PrintObject * current_object
Definition ExtrusionProcessor.hpp:227
std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< Linef > > prev_layer_boundaries
Definition ExtrusionProcessor.hpp:223
#define scale_(val)
Definition libslic3r.h:69
static constexpr double EPSILON
Definition libslic3r.h:51
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half &a)
Definition Half.h:445
bool inside(const Polygons &polygons, const Point &p)
T dist(const boost::polygon::point_data< T > &p1, const boost::polygon::point_data< T > &p2)
Definition Geometry.cpp:280
double distance_to(const L &line, const Vec< Dim< L >, Scalar< L > > &point)
Definition Line.hpp:82
std::vector< Line > Lines
Definition Line.hpp:17
Slic3r::Lines intersection_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip)
Definition ClipperUtils.hpp:482
BoundingBox scaled(const BoundingBoxf &bb)
Definition BoundingBox.hpp:240
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:51
constexpr Eigen::Matrix< Tout, 2, EigenArgs... > unscaled(const Slic3r::ClipperLib::IntPoint &v) noexcept
Definition Arrange.cpp:55
double distance(const P &p1, const P &p2)
Definition geometry_traits.hpp:329
Slic3r::Polygon Polygon
Definition Emboss.cpp:34

References Slic3r::Line::a, Slic3r::Line::b, Slic3r::CurledLine::curled_height, current_object, Slic3r::ExtendedPoint::distance, Slic3r::line_alg::distance_to(), EPSILON, Slic3r::ExtrusionPath::height, Slic3r::intersection_ln(), Slic3r::MultiPoint::points, Slic3r::ExtrusionPath::polyline, Slic3r::ExtendedPoint::position, prev_curled_extrusions, prev_layer_boundaries, scale_, Slic3r::scaled(), Slic3r::unscaled(), and Slic3r::ExtrusionPath::width.

Referenced by Slic3r::GCode::_extrude().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prepare_for_new_layer()

void Slic3r::ExtrusionQualityEstimator::prepare_for_new_layer ( const Layer layer)
inline
233 {
234 if (layer == nullptr)
235 return;
236 const PrintObject *object = layer->object();
238 next_layer_boundaries[object] = AABBTreeLines::LinesDistancer<Linef>{to_unscaled_linesf(layer->lslices)};
240 next_curled_extrusions[object] = AABBTreeLines::LinesDistancer<CurledLine>{layer->curled_lines};
241 }
std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< Linef > > next_layer_boundaries
Definition ExtrusionProcessor.hpp:224
std::unordered_map< const PrintObject *, AABBTreeLines::LinesDistancer< CurledLine > > next_curled_extrusions
Definition ExtrusionProcessor.hpp:226
Linesf to_unscaled_linesf(const ExPolygons &src)
Definition ExPolygon.hpp:175

References Slic3r::Layer::curled_lines, Slic3r::Layer::lslices, next_curled_extrusions, next_layer_boundaries, Slic3r::Layer::object(), prev_curled_extrusions, prev_layer_boundaries, and Slic3r::to_unscaled_linesf().

Referenced by Slic3r::GCode::process_layer().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_current_object()

void Slic3r::ExtrusionQualityEstimator::set_current_object ( const PrintObject object)
inline
230{ current_object = object; }

References current_object.

Referenced by Slic3r::GCode::process_layer_single_object().

+ Here is the caller graph for this function:

Member Data Documentation

◆ current_object

const PrintObject* Slic3r::ExtrusionQualityEstimator::current_object
private

◆ next_curled_extrusions

std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine> > Slic3r::ExtrusionQualityEstimator::next_curled_extrusions
private

Referenced by prepare_for_new_layer().

◆ next_layer_boundaries

std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<Linef> > Slic3r::ExtrusionQualityEstimator::next_layer_boundaries
private

Referenced by prepare_for_new_layer().

◆ prev_curled_extrusions

std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine> > Slic3r::ExtrusionQualityEstimator::prev_curled_extrusions
private

◆ prev_layer_boundaries

std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<Linef> > Slic3r::ExtrusionQualityEstimator::prev_layer_boundaries
private

The documentation for this class was generated from the following file: