mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-29 16:52:01 +08:00
Fix overhang perimeter dynamic speed.
* Use "corner" intersections when estimating the curl up height. * If there is a redundant point in an extrusion loop at the end remove it.
This commit is contained in:
parent
10c0f7f255
commit
c6858d41bd
@ -17,8 +17,14 @@ ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath
|
||||
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
|
||||
const AABBTreeLines::LinesDistancer<CurledLine> &prev_layer_curled_lines)
|
||||
{
|
||||
std::vector<ExtendedPoint> extended_points = estimate_points_properties<true, true, true, true>(path.polyline.points,
|
||||
unscaled_prev_layer, path.width());
|
||||
ExtrusionProcessor::PropertiesEstimationConfig config{};
|
||||
config.add_corners = true;
|
||||
config.prev_layer_boundary_offset = true;
|
||||
config.flow_width = path.width();
|
||||
std::vector<ExtendedPoint> extended_points = estimate_points_properties<true>(
|
||||
path.polyline.points, unscaled_prev_layer, config
|
||||
);
|
||||
|
||||
std::vector<std::pair<float, float>> calculated_distances(extended_points.size());
|
||||
|
||||
for (size_t i = 0; i < extended_points.size(); i++) {
|
||||
@ -118,9 +124,28 @@ ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(const Extru
|
||||
} else if (auto *loop = dynamic_cast<const ExtrusionLoop *>(e)) {
|
||||
ExtrusionLoop new_loop = *loop;
|
||||
new_loop.paths.clear();
|
||||
for (const ExtrusionPath &p : loop->paths) {
|
||||
auto paths = calculate_and_split_overhanging_extrusions(p, unscaled_prev_layer, prev_layer_curled_lines);
|
||||
new_loop.paths.insert(new_loop.paths.end(), paths.begin(), paths.end());
|
||||
|
||||
ExtrusionPaths paths{loop->paths};
|
||||
if (!paths.empty()) {
|
||||
ExtrusionPath& first_path{paths.front()};
|
||||
ExtrusionPath& last_path{paths.back()};
|
||||
|
||||
if (first_path.attributes() == last_path.attributes()) {
|
||||
if (first_path.polyline.size() > 1 && last_path.polyline.size() > 2) {
|
||||
const Line start{first_path.polyline.front(), *std::next(first_path.polyline.begin())};
|
||||
const Line end{last_path.polyline.back(), *std::next(last_path.polyline.rbegin())};
|
||||
|
||||
if (std::abs(start.direction() - end.direction()) < 1e-5) {
|
||||
first_path.polyline.points.front() = *std::next(last_path.polyline.points.rbegin());
|
||||
last_path.polyline.points.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const ExtrusionPath &p : paths) {
|
||||
auto resulting_paths = calculate_and_split_overhanging_extrusions(p, unscaled_prev_layer, prev_layer_curled_lines);
|
||||
new_loop.paths.insert(new_loop.paths.end(), resulting_paths.begin(), resulting_paths.end());
|
||||
}
|
||||
result.append(new_loop);
|
||||
} else if (auto *mp = dynamic_cast<const ExtrusionMultiPath *>(e)) {
|
||||
|
@ -61,13 +61,20 @@ struct OverhangSpeeds
|
||||
float fan_speed;
|
||||
};
|
||||
|
||||
template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFFSET, bool SIGNED_DISTANCE, typename POINTS, typename L>
|
||||
std::vector<ExtendedPoint> estimate_points_properties(const POINTS &input_points,
|
||||
const AABBTreeLines::LinesDistancer<L> &unscaled_prev_layer,
|
||||
float flow_width,
|
||||
float max_line_length = -1.0f)
|
||||
{
|
||||
bool looped = input_points.front() == input_points.back();
|
||||
struct PropertiesEstimationConfig {
|
||||
bool add_corners{};
|
||||
bool prev_layer_boundary_offset{};
|
||||
float flow_width;
|
||||
float max_line_length{-1.0f};
|
||||
};
|
||||
|
||||
template<bool SIGNED_DISTANCE, typename POINTS, typename L>
|
||||
std::vector<ExtendedPoint> estimate_points_properties(
|
||||
const POINTS &input_points,
|
||||
const AABBTreeLines::LinesDistancer<L> &unscaled_prev_layer,
|
||||
const PropertiesEstimationConfig &config
|
||||
) {
|
||||
bool looped = input_points.front() == input_points.back();
|
||||
std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
|
||||
if (idx > 0) {
|
||||
return idx - 1;
|
||||
@ -95,32 +102,28 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
||||
};
|
||||
};
|
||||
|
||||
using P = typename POINTS::value_type;
|
||||
|
||||
using AABBScalar = typename AABBTreeLines::LinesDistancer<L>::Scalar;
|
||||
if (input_points.empty())
|
||||
return {};
|
||||
float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f;
|
||||
auto maybe_unscale = [](const P &p) { return SCALED_INPUT ? unscaled(p) : p.template cast<double>(); };
|
||||
float boundary_offset = config.prev_layer_boundary_offset ? 0.5 * config.flow_width : 0.0f;
|
||||
|
||||
std::vector<ExtendedPoint> points;
|
||||
points.reserve(input_points.size() * (ADD_INTERSECTIONS ? 1.5 : 1));
|
||||
points.reserve(input_points.size() * 1.5);
|
||||
|
||||
{
|
||||
ExtendedPoint start_point{maybe_unscale(input_points.front())};
|
||||
ExtendedPoint start_point{unscaled(input_points.front())};
|
||||
auto [distance, nearest_line,
|
||||
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(start_point.position.cast<AABBScalar>());
|
||||
start_point.distance = distance + boundary_offset;
|
||||
points.push_back(start_point);
|
||||
}
|
||||
for (size_t i = 1; i < input_points.size(); i++) {
|
||||
ExtendedPoint next_point{maybe_unscale(input_points[i])};
|
||||
ExtendedPoint next_point{unscaled(input_points[i])};
|
||||
auto [distance, nearest_line,
|
||||
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(next_point.position.cast<AABBScalar>());
|
||||
next_point.distance = distance + boundary_offset;
|
||||
|
||||
if (ADD_INTERSECTIONS &&
|
||||
((points.back().distance > boundary_offset + EPSILON) != (next_point.distance > boundary_offset + EPSILON))) {
|
||||
if (((points.back().distance > boundary_offset + EPSILON) != (next_point.distance > boundary_offset + EPSILON))) {
|
||||
const ExtendedPoint &prev_point = points.back();
|
||||
auto intersections = unscaled_prev_layer.template intersections_with_line<true>(
|
||||
L{prev_point.position.cast<AABBScalar>(), next_point.position.cast<AABBScalar>()});
|
||||
@ -134,7 +137,7 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
||||
points.push_back(next_point);
|
||||
}
|
||||
|
||||
if (PREV_LAYER_BOUNDARY_OFFSET && ADD_INTERSECTIONS) {
|
||||
if (config.add_corners) {
|
||||
std::vector<ExtendedPoint> new_points;
|
||||
new_points.reserve(points.size() * 2);
|
||||
new_points.push_back(points.front());
|
||||
@ -176,7 +179,7 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
||||
points = std::move(new_points);
|
||||
}
|
||||
|
||||
if (max_line_length > 0) {
|
||||
if (config.max_line_length > 0) {
|
||||
std::vector<ExtendedPoint> new_points;
|
||||
new_points.reserve(points.size() * 2);
|
||||
{
|
||||
@ -185,7 +188,7 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
||||
const ExtendedPoint &next = points[i + 1];
|
||||
new_points.push_back(curr);
|
||||
double len = (next.position - curr.position).squaredNorm();
|
||||
double t = sqrt((max_line_length * max_line_length) / len);
|
||||
double t = sqrt((config.max_line_length * config.max_line_length) / len);
|
||||
size_t new_point_count = 1.0 / t;
|
||||
for (size_t j = 1; j < new_point_count + 1; j++) {
|
||||
Vec2d pos = curr.position * (1.0 - j * t) + next.position * (j * t);
|
||||
|
@ -4,6 +4,7 @@
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "SupportSpotsGenerator.hpp"
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <oneapi/tbb/concurrent_vector.h>
|
||||
@ -337,9 +338,16 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
|
||||
return {};
|
||||
}
|
||||
const float flow_width = get_flow_width(layer_region, entity->role());
|
||||
|
||||
ExtrusionProcessor::PropertiesEstimationConfig config{};
|
||||
config.add_corners = true;
|
||||
config.prev_layer_boundary_offset = true;
|
||||
config.max_line_length = params.bridge_distance;
|
||||
config.flow_width = flow_width;
|
||||
|
||||
std::vector<ExtrusionProcessor::ExtendedPoint> annotated_points =
|
||||
ExtrusionProcessor::estimate_points_properties<true, true, true, true>(entity->as_polyline().points, prev_layer_boundary,
|
||||
flow_width, params.bridge_distance);
|
||||
ExtrusionProcessor::estimate_points_properties<
|
||||
true>(entity->as_polyline().points, prev_layer_boundary, config);
|
||||
|
||||
std::vector<ExtrusionLine> lines_out;
|
||||
lines_out.reserve(annotated_points.size());
|
||||
@ -391,9 +399,12 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
|
||||
|
||||
const float flow_width = get_flow_width(layer_region, entity->role());
|
||||
// Compute only unsigned distance - prev_layer_lines can contain unconnected paths, thus the sign of the distance is unreliable
|
||||
|
||||
ExtrusionProcessor::PropertiesEstimationConfig config{};
|
||||
config.max_line_length = params.bridge_distance;
|
||||
config.flow_width = flow_width;
|
||||
std::vector<ExtrusionProcessor::ExtendedPoint> annotated_points =
|
||||
ExtrusionProcessor::estimate_points_properties<true, true, false, false>(entity->as_polyline().points, prev_layer_lines,
|
||||
flow_width, params.bridge_distance);
|
||||
ExtrusionProcessor::estimate_points_properties<false>(entity->as_polyline().points, prev_layer_lines, config);
|
||||
|
||||
std::vector<ExtrusionLine> lines_out;
|
||||
lines_out.reserve(annotated_points.size());
|
||||
@ -1248,8 +1259,10 @@ void estimate_supports_malformations(SupportLayerPtrs &layers, float flow_width,
|
||||
Polygon pol(pl.points);
|
||||
pol.make_counter_clockwise();
|
||||
|
||||
auto annotated_points = ExtrusionProcessor::estimate_points_properties<true, true, false, false>(pol.points, prev_layer_lines,
|
||||
flow_width);
|
||||
ExtrusionProcessor::PropertiesEstimationConfig config{};
|
||||
config.flow_width = flow_width;
|
||||
auto annotated_points = ExtrusionProcessor::estimate_points_properties<
|
||||
false>(pol.points, prev_layer_lines, config);
|
||||
|
||||
for (size_t i = 0; i < annotated_points.size(); ++i) {
|
||||
const ExtrusionProcessor::ExtendedPoint &a = i > 0 ? annotated_points[i - 1] : annotated_points[i];
|
||||
@ -1324,10 +1337,14 @@ void estimate_malformations(LayerPtrs &layers, const Params ¶ms)
|
||||
Points extrusion_pts;
|
||||
extrusion->collect_points(extrusion_pts);
|
||||
float flow_width = get_flow_width(layer_region, extrusion->role());
|
||||
auto annotated_points = ExtrusionProcessor::estimate_points_properties<true, true, false, false>(extrusion_pts,
|
||||
prev_layer_lines,
|
||||
flow_width,
|
||||
params.bridge_distance);
|
||||
|
||||
ExtrusionProcessor::PropertiesEstimationConfig config{};
|
||||
config.max_line_length = params.bridge_distance;
|
||||
config.add_corners = true;
|
||||
config.flow_width = flow_width;
|
||||
auto annotated_points = ExtrusionProcessor::estimate_points_properties<
|
||||
false>(extrusion_pts, prev_layer_lines, config);
|
||||
|
||||
for (size_t i = 0; i < annotated_points.size(); ++i) {
|
||||
const ExtrusionProcessor::ExtendedPoint &a = i > 0 ? annotated_points[i - 1] : annotated_points[i];
|
||||
const ExtrusionProcessor::ExtendedPoint &b = annotated_points[i];
|
||||
|
Loading…
x
Reference in New Issue
Block a user