mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-09-28 13:03:14 +08:00
ENH: smooth overhang degree in arachne mode
jira: STUDIO-12110,STUDIO-11630 Signed-off-by: xun.zhang <xun.zhang@bambulab.com> Change-Id: I4e430dd2cea4bd4ad206e699d574abed3a656ce2
This commit is contained in:
parent
f2304fe1fc
commit
4b022b8287
@ -278,7 +278,17 @@ double ExtrusionLine::area() const
|
||||
} // namespace Slic3r::Arachne
|
||||
|
||||
namespace Slic3r {
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, int overhang)
|
||||
|
||||
void extrusion_paths_append(std::list<ExtrusionPath> &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, double overhang)
|
||||
{
|
||||
for (const ClipperLib_Z::Path &extrusion_path : extrusion_paths) {
|
||||
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion_path);
|
||||
ExtrusionPaths path = thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON), overhang).paths;
|
||||
dst.insert(dst.end(), std::make_move_iterator(path.begin()), std::make_move_iterator(path.end()));
|
||||
}
|
||||
}
|
||||
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, double overhang)
|
||||
{
|
||||
for (const ClipperLib_Z::Path &extrusion_path : extrusion_paths) {
|
||||
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion_path);
|
||||
@ -286,13 +296,13 @@ void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extr
|
||||
}
|
||||
}
|
||||
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow, int overhang)
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow, double overhang)
|
||||
{
|
||||
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion);
|
||||
Slic3r::append(dst, thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON), overhang).paths);
|
||||
}
|
||||
|
||||
void extrusion_path_append(ExtrusionPaths &dst, const ThickPolyline &thick_polyline, const ExtrusionRole role, const Flow &flow, int overhang)
|
||||
void extrusion_path_append(ExtrusionPaths &dst, const ThickPolyline &thick_polyline, const ExtrusionRole role, const Flow &flow, double overhang)
|
||||
{
|
||||
Slic3r::append(dst, thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON), overhang).paths);
|
||||
}
|
||||
|
@ -301,9 +301,10 @@ using VariableWidthLines = std::vector<ExtrusionLine>; //<! The ExtrusionLines g
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, int overhang = 0);
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow, int overhang = 0);
|
||||
void extrusion_path_append(ExtrusionPaths &dst, const ThickPolyline &thick_polyline, const ExtrusionRole role, const Flow &flow, int overhang = 0);
|
||||
void extrusion_paths_append(std::list<ExtrusionPath> &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, double overhang = 0);
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, double overhang = 0);
|
||||
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow, double overhang = 0);
|
||||
void extrusion_path_append(ExtrusionPaths &dst, const ThickPolyline &thick_polyline, const ExtrusionRole role, const Flow &flow, double overhang = 0);
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // UTILS_EXTRUSION_LINE_H
|
||||
|
@ -19,11 +19,12 @@ public:
|
||||
|
||||
MultiPoint() {}
|
||||
MultiPoint(const MultiPoint &other) : points(other.points) {}
|
||||
MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
|
||||
MultiPoint(MultiPoint &&other) noexcept : points(std::move(other.points)) {}
|
||||
MultiPoint(std::initializer_list<Point> list) : points(list) {}
|
||||
explicit MultiPoint(const Points &_points) : points(_points) {}
|
||||
MultiPoint(Points&& _points) noexcept: points(std::move(_points)){}
|
||||
MultiPoint& operator=(const MultiPoint &other) { points = other.points; return *this; }
|
||||
MultiPoint& operator=(MultiPoint &&other) { points = std::move(other.points); return *this; }
|
||||
MultiPoint& operator=(MultiPoint &&other) noexcept { points = std::move(other.points); return *this; }
|
||||
void scale(double factor);
|
||||
void scale(double factor_x, double factor_y);
|
||||
void translate(double x, double y) { this->translate(Point(coord_t(x), coord_t(y))); }
|
||||
|
@ -173,6 +173,7 @@ namespace Slic3r {
|
||||
const double nozzle_diameter)
|
||||
{
|
||||
ExtrusionPaths ret_paths;
|
||||
std::list<ExtrusionPath> ret_path_list;
|
||||
ZPaths paths_in_range = clip_extrusion(extrusion_path, clip_paths, ClipperLib_Z::ctIntersection); //doing intersection first would be faster.
|
||||
|
||||
paths_in_range = add_sampling_points(paths_in_range, scale_(2));// enough?
|
||||
@ -184,13 +185,15 @@ namespace Slic3r {
|
||||
for (auto& p : path) { assert(p.z() != 0); }
|
||||
}
|
||||
|
||||
auto in_same_degree_range = [](double a, double b) -> bool {
|
||||
int ceil_a = std::ceil(a);
|
||||
int floor_a = std::floor(a);
|
||||
int ceil_b = std::ceil(b);
|
||||
int floor_b = std::floor(b);
|
||||
return ceil_a == ceil_b && floor_a == floor_b;
|
||||
};
|
||||
auto get_base_degree = [](double d){
|
||||
return std::floor(d/min_degree_gap_arachne) * min_degree_gap_arachne;
|
||||
};
|
||||
|
||||
auto in_same_degree_range = [&](double a, double b) -> bool {
|
||||
double base_a = get_base_degree(a);
|
||||
double base_b = get_base_degree(b);
|
||||
return std::abs(base_a - base_b) < EPSILON;
|
||||
};
|
||||
|
||||
struct SplitPoint
|
||||
{
|
||||
@ -199,11 +202,10 @@ namespace Slic3r {
|
||||
double degree;
|
||||
};
|
||||
|
||||
auto get_split_points = [](const Point& pa, const Point& pb, const coord_t wa, const coord_t wb, const double da, const double db) -> std::vector<SplitPoint> {
|
||||
auto get_split_points = [&](const Point& pa, const Point& pb, const coord_t wa, const coord_t wb, const double da, const double db) -> std::vector<SplitPoint> {
|
||||
std::vector<SplitPoint> ret;
|
||||
|
||||
int start_d = (int)(std::ceil(std::min(da, db)));
|
||||
int end_d = (int)(std::floor(std::max(da, db)));
|
||||
double start_d = get_base_degree(std::min(da, db)) + min_degree_gap_arachne;
|
||||
double end_d = get_base_degree(std::max(da, db));
|
||||
|
||||
if (start_d > end_d) return ret;
|
||||
|
||||
@ -211,7 +213,7 @@ namespace Slic3r {
|
||||
if (std::abs(delta_d) < 1e-6) return ret;
|
||||
|
||||
if (da < db) {
|
||||
for (int k = start_d; k <= end_d; ++k) {
|
||||
for (double k = start_d; k <= end_d; k+=min_degree_gap_arachne) {
|
||||
const double t = (k - da) / delta_d;
|
||||
const Point pt = pa + (pb - pa) * t;
|
||||
const coord_t w = wa + coord_t((wb - wa) * t);
|
||||
@ -219,14 +221,13 @@ namespace Slic3r {
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int k = end_d; k >= start_d; --k) {
|
||||
for (double k = end_d; k >= start_d; k-=min_degree_gap_arachne) {
|
||||
const double t = (k - da) / delta_d;
|
||||
const Point pt = pa + (pb - pa) * t;
|
||||
const coord_t w = wa + coord_t((wb - wa) * t);
|
||||
ret.emplace_back(SplitPoint{ pt, w, (double)k });
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
@ -287,11 +288,11 @@ namespace Slic3r {
|
||||
for (auto& split_point : split_points) {
|
||||
prev_line.push_back({ split_point.p.x(), split_point.p.y(), split_point.w });
|
||||
double target_degree = 0;
|
||||
if (prev_d < curr_d)
|
||||
target_degree = split_point.degree - 1;
|
||||
if( prev_d < curr_d)
|
||||
target_degree = split_point.degree - min_degree_gap_arachne;
|
||||
else
|
||||
target_degree = split_point.degree;
|
||||
extrusion_paths_append(ret_paths, { prev_line }, role, flow, target_degree);
|
||||
extrusion_paths_append(ret_path_list , { prev_line }, role, flow, target_degree);
|
||||
prev_line.clear();
|
||||
prev_line.push_back({ split_point.p.x(), split_point.p.y(), split_point.w });
|
||||
}
|
||||
@ -301,8 +302,12 @@ namespace Slic3r {
|
||||
prev_line.push_back(path[idx]);
|
||||
}
|
||||
}
|
||||
if (prev_line.size() > 1) { extrusion_paths_append(ret_paths, { prev_line }, role, flow, std::floor(prev_d)); }
|
||||
if (prev_line.size() > 1) { extrusion_paths_append(ret_path_list, { prev_line }, role, flow, get_base_degree(prev_d)); }
|
||||
}
|
||||
|
||||
ret_paths.reserve(ret_path_list.size());
|
||||
ret_paths.insert(ret_paths.end(), std::make_move_iterator(ret_path_list.begin()), std::make_move_iterator(ret_path_list.end()));
|
||||
|
||||
return ret_paths;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,8 @@ using ZPath = ClipperLib_Z::Path;
|
||||
using ZPaths = ClipperLib_Z::Paths;
|
||||
|
||||
static const int overhang_sampling_number = 6;
|
||||
static const double min_degree_gap = 0.1;
|
||||
static const double min_degree_gap_classic = 0.1;
|
||||
static const double min_degree_gap_arachne = 0.25;
|
||||
static const int max_overhang_degree = overhang_sampling_number - 1;
|
||||
static const std::vector<double> non_uniform_degree_map = { 0, 10, 25, 50, 75, 100};
|
||||
static const int insert_point_count = 3;
|
||||
|
@ -243,14 +243,14 @@ static std::deque<PolylineWithDegree> split_polyline_by_degree(const Polyline &p
|
||||
size_t poly_size = polyline_with_insert_points.size();
|
||||
// BBS: merge degree in limited range
|
||||
//find first degee base
|
||||
double degree_base = int(points_overhang[points_overhang.size() - 1] / min_degree_gap) * min_degree_gap + min_degree_gap;
|
||||
double degree_base = int(points_overhang[points_overhang.size() - 1] / min_degree_gap_classic) * min_degree_gap_classic + min_degree_gap_classic;
|
||||
degree_base = degree_base > max_overhang_degree ? max_overhang_degree : degree_base;
|
||||
double short_poly_len = 0;
|
||||
for (int point_idx = points_overhang.size() - 2; point_idx > 0; --point_idx) {
|
||||
|
||||
double degree = points_overhang[point_idx];
|
||||
|
||||
if ( degree <= degree_base && degree >= degree_base - min_degree_gap )
|
||||
if ( degree <= degree_base && degree >= degree_base - min_degree_gap_classic )
|
||||
continue;
|
||||
|
||||
temp_copy.split_at_index(point_idx, &left, &right);
|
||||
@ -258,7 +258,7 @@ static std::deque<PolylineWithDegree> split_polyline_by_degree(const Polyline &p
|
||||
temp_copy = std::move(left);
|
||||
out.push_back(PolylineWithDegree(right, degree_base));
|
||||
|
||||
degree_base = int(degree / min_degree_gap) * min_degree_gap + min_degree_gap;
|
||||
degree_base = int(degree / min_degree_gap_classic) * min_degree_gap_classic + min_degree_gap_classic;
|
||||
degree_base = degree_base > max_overhang_degree ? max_overhang_degree : degree_base;
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ static void insert_point_to_line( double left_point_degree,
|
||||
{
|
||||
Line line_temp(left_point, right_point);
|
||||
double line_length = line_temp.length();
|
||||
if (std::abs(left_point_degree - right_point_degree) <= 0.5 * min_degree_gap || line_length<scale_(1.5))
|
||||
if (std::abs(left_point_degree - right_point_degree) <= 0.5 * min_degree_gap_classic || line_length<scale_(1.5))
|
||||
return;
|
||||
|
||||
Point middle_pt((left_point + right_point) / 2);
|
||||
|
@ -20,7 +20,7 @@ class Polyline : public MultiPoint {
|
||||
public:
|
||||
Polyline() {};
|
||||
Polyline(const Polyline& other) : MultiPoint(other.points), fitting_result(other.fitting_result) {}
|
||||
Polyline(Polyline &&other) : MultiPoint(std::move(other.points)), fitting_result(std::move(other.fitting_result)) {}
|
||||
Polyline(Polyline &&other) noexcept : MultiPoint(std::move(other.points)), fitting_result(std::move(other.fitting_result)) {}
|
||||
Polyline(std::initializer_list<Point> list) : MultiPoint(list) {
|
||||
fitting_result.clear();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance, int overhang)
|
||||
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance, double overhang)
|
||||
{
|
||||
ExtrusionMultiPath multi_path;
|
||||
ExtrusionPath path(role);
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "Flow.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance, int overhang);
|
||||
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance, double overhang);
|
||||
void variable_width(const ThickPolylines& polylines, ExtrusionRole role, const Flow& flow, std::vector<ExtrusionEntity*>& out);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user