mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 17:15:53 +08:00
new step for overhangs
This commit is contained in:
parent
98c011d59b
commit
28cd3ac212
@ -211,6 +211,92 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void calculate_and_split_overhanging_extrusions(ExtrusionPath &path,
|
||||||
|
AABBTreeLines::LinesDistancer<Line> prev_layer_polygon,
|
||||||
|
AABBTreeLines::LinesDistancer<CurledLine> prev_layer_curled_lines)
|
||||||
|
{
|
||||||
|
std::vector<ExtendedPoint> extended_points = estimate_points_properties<true, true, true, true>(path.polyline.points,
|
||||||
|
prev_layer_polygon, path.width());
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < extended_points.size(); i++) {
|
||||||
|
const ExtendedPoint &curr = extended_points[i];
|
||||||
|
const ExtendedPoint &next = extended_points[i + 1 < extended_points.size() ? i + 1 : i];
|
||||||
|
|
||||||
|
// The following code artifically increases the distance to provide slowdown for extrusions that are over curled lines
|
||||||
|
float artificial_distance_to_curled_lines = 0.0;
|
||||||
|
const double dist_limit = 10.0 * path.width();
|
||||||
|
{
|
||||||
|
Vec2d middle = 0.5 * (curr.position + next.position);
|
||||||
|
auto line_indices = prev_layer_curled_lines.all_lines_in_radius(Point::new_scale(middle), scale_(dist_limit));
|
||||||
|
if (!line_indices.empty()) {
|
||||||
|
double len = (next.position - curr.position).norm();
|
||||||
|
// 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
|
||||||
|
// The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down.
|
||||||
|
// NOTE that this is still quite rough approximation, e.g. we are still checking lines only near the middle point
|
||||||
|
// TODO maybe split the lines into smaller segments before running this alg? but can be demanding, and GCode will be huge
|
||||||
|
if (len > 8) {
|
||||||
|
Vec2d dir = Vec2d(next.position - curr.position) / len;
|
||||||
|
Vec2d right = Vec2d(-dir.y(), dir.x());
|
||||||
|
|
||||||
|
Polygon box_of_influence = {
|
||||||
|
scaled(Vec2d(curr.position + right * dist_limit)),
|
||||||
|
scaled(Vec2d(next.position + right * dist_limit)),
|
||||||
|
scaled(Vec2d(next.position - right * dist_limit)),
|
||||||
|
scaled(Vec2d(curr.position - right * dist_limit)),
|
||||||
|
};
|
||||||
|
|
||||||
|
double projected_lengths_sum = 0;
|
||||||
|
for (size_t idx : line_indices) {
|
||||||
|
const CurledLine &line = prev_layer_curled_lines.get_line(idx);
|
||||||
|
Lines inside = intersection_ln({{line.a, line.b}}, {box_of_influence});
|
||||||
|
if (inside.empty())
|
||||||
|
continue;
|
||||||
|
double projected_length = abs(dir.dot(unscaled(Vec2d((inside.back().b - inside.back().a).cast<double>()))));
|
||||||
|
projected_lengths_sum += projected_length;
|
||||||
|
}
|
||||||
|
if (projected_lengths_sum < 0.4 * len) {
|
||||||
|
line_indices.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t idx : line_indices) {
|
||||||
|
const CurledLine &line = prev_layer_curled_lines.get_line(idx);
|
||||||
|
float distance_from_curled = unscaled(line_alg::distance_to(line, Point::new_scale(middle)));
|
||||||
|
float dist = path.width() * (1.0 - (distance_from_curled / dist_limit)) * (1.0 - (distance_from_curled / dist_limit)) *
|
||||||
|
(line.curled_height / (path.height() * 10.0f)); // max_curled_height_factor from SupportSpotGenerator
|
||||||
|
artificial_distance_to_curled_lines = std::max(artificial_distance_to_curled_lines, dist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto interpolate_speed = [](const std::map<float, float> &values, float distance) {
|
||||||
|
auto upper_dist = values.lower_bound(distance);
|
||||||
|
if (upper_dist == values.end()) {
|
||||||
|
return values.rbegin()->second;
|
||||||
|
}
|
||||||
|
if (upper_dist == values.begin()) {
|
||||||
|
return upper_dist->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lower_dist = std::prev(upper_dist);
|
||||||
|
float t = (distance - lower_dist->first) / (upper_dist->first - lower_dist->first);
|
||||||
|
return (1.0f - t) * lower_dist->second + t * upper_dist->second;
|
||||||
|
};
|
||||||
|
|
||||||
|
float extrusion_speed = std::min(interpolate_speed(speed_sections, curr.distance), interpolate_speed(speed_sections, next.distance));
|
||||||
|
float curled_base_speed = interpolate_speed(speed_sections, artificial_distance_to_curled_lines);
|
||||||
|
float final_speed = std::min(curled_base_speed, extrusion_speed);
|
||||||
|
float fan_speed = std::min(interpolate_speed(fan_speed_sections, curr.distance),
|
||||||
|
interpolate_speed(fan_speed_sections, next.distance));
|
||||||
|
|
||||||
|
processed_points.push_back({scaled(curr.position), final_speed, int(fan_speed)});
|
||||||
|
}
|
||||||
|
return processed_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ProcessedPoint
|
struct ProcessedPoint
|
||||||
{
|
{
|
||||||
Point p;
|
Point p;
|
||||||
|
@ -67,7 +67,7 @@ enum PrintStep : unsigned int {
|
|||||||
|
|
||||||
enum PrintObjectStep : unsigned int {
|
enum PrintObjectStep : unsigned int {
|
||||||
posSlice, posPerimeters, posPrepareInfill,
|
posSlice, posPerimeters, posPrepareInfill,
|
||||||
posInfill, posIroning, posSupportSpotsSearch, posSupportMaterial, posEstimateCurledExtrusions, posCount,
|
posInfill, posIroning, posSupportSpotsSearch, posSupportMaterial, posEstimateCurledExtrusions, posCalculateOverhangingPerimeters, posCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
// A PrintRegion object represents a group of volumes to print
|
// A PrintRegion object represents a group of volumes to print
|
||||||
@ -376,6 +376,7 @@ private:
|
|||||||
void generate_support_spots();
|
void generate_support_spots();
|
||||||
void generate_support_material();
|
void generate_support_material();
|
||||||
void estimate_curled_extrusions();
|
void estimate_curled_extrusions();
|
||||||
|
void calculate_overhanging_perimeters();
|
||||||
|
|
||||||
void slice_volumes();
|
void slice_volumes();
|
||||||
// Has any support (not counting the raft).
|
// Has any support (not counting the raft).
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Exception.hpp"
|
#include "Exception.hpp"
|
||||||
#include "Flow.hpp"
|
#include "Flow.hpp"
|
||||||
#include "KDTreeIndirect.hpp"
|
#include "KDTreeIndirect.hpp"
|
||||||
|
#include "Line.hpp"
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
#include "Polygon.hpp"
|
#include "Polygon.hpp"
|
||||||
#include "Polyline.hpp"
|
#include "Polyline.hpp"
|
||||||
@ -533,6 +534,40 @@ void PrintObject::estimate_curled_extrusions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintObject::calculate_overhanging_perimeters()
|
||||||
|
{
|
||||||
|
if (this->set_started(posCalculateOverhangingPerimeters)) {
|
||||||
|
std::unordered_set<const PrintRegion *> regions_with_dynamic_overhangs;
|
||||||
|
for (const PrintRegion *pr : this->print()->m_print_regions) {
|
||||||
|
if (pr->config().enable_dynamic_overhang_speeds.getBool()) {
|
||||||
|
regions_with_dynamic_overhangs.insert(pr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!regions_with_dynamic_overhangs.empty()) {
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Calculating overhanging perimeters - start";
|
||||||
|
m_print->set_status(89, _u8L("Calculating overhanging perimeters"));
|
||||||
|
|
||||||
|
std::unordered_map<size_t, AABBTreeLines::LinesDistancer<CurledLine>> curled_lines;
|
||||||
|
for (const Layer *l : this->layers()) {
|
||||||
|
curled_lines[l->id()] = AABBTreeLines::LinesDistancer<CurledLine>{l->curled_lines};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Layer *l : this->layers()) {
|
||||||
|
for (const LayerRegion *layer_region : l->regions()) {
|
||||||
|
if (regions_with_dynamic_overhangs.find(layer_region->m_region) == regions_with_dynamic_overhangs.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_print->throw_if_canceled();
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Calculating overhanging perimeters - end";
|
||||||
|
}
|
||||||
|
this->set_done(posCalculateOverhangingPerimeters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> PrintObject::prepare_adaptive_infill_data(
|
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> PrintObject::prepare_adaptive_infill_data(
|
||||||
const std::vector<std::pair<const Surface *, float>> &surfaces_w_bottom_z) const
|
const std::vector<std::pair<const Surface *, float>> &surfaces_w_bottom_z) const
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user