mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 02:07:54 -06:00
Scarf joint seam enhancement: conditional scarf joint and slowdown for scarf joint only (#4317)
* Allow apply scarf joint seams to perimeters without sharp corners only * 1. Fix an error when detect whether a loop is smooth 2. Expose scarf_angle_threshold to UI * fix linux build error * minor code changes * Support slowdown speed for scarf joint only * update tips * improve the logic a bit * Fixed a bug that scarf speed may not respected for overhangs * Add a new scarf flow ratio option
This commit is contained in:
parent
6264fe64b4
commit
a4bf3dabb4
10 changed files with 144 additions and 4 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include "Utils.hpp"
|
||||
|
||||
#define L(s) (s)
|
||||
|
||||
|
@ -340,6 +341,65 @@ double ExtrusionLoop::min_mm3_per_mm() const
|
|||
return min_mm3_per_mm;
|
||||
}
|
||||
|
||||
// Orca: This function is used to check if the loop is smooth(continuous) or not.
|
||||
// TODO: the main logic is largly copied from the calculate_polygon_angles_at_vertices function in SeamPlacer file. Need to refactor the code in the future.
|
||||
bool ExtrusionLoop::is_smooth(double angle_threshold, double min_arm_length) const
|
||||
{
|
||||
// go through all the points in the loop and check if the angle between two segments(AB and BC) is less than the threshold
|
||||
size_t idx_prev = 0;
|
||||
size_t idx_curr = 0;
|
||||
size_t idx_next = 0;
|
||||
|
||||
float distance_to_prev = 0;
|
||||
float distance_to_next = 0;
|
||||
|
||||
const auto _polygon = polygon();
|
||||
const Points& points = _polygon.points;
|
||||
|
||||
std::vector<float> lengths{};
|
||||
for (size_t point_idx = 0; point_idx < points.size() - 1; ++point_idx) {
|
||||
lengths.push_back((unscale(points[point_idx]) - unscale(points[point_idx + 1])).norm());
|
||||
}
|
||||
lengths.push_back(std::max((unscale(points[0]) - unscale(points[points.size() - 1])).norm(), 0.1));
|
||||
|
||||
// push idx_prev far enough back as initialization
|
||||
while (distance_to_prev < min_arm_length) {
|
||||
idx_prev = Slic3r::prev_idx_modulo(idx_prev, points.size());
|
||||
distance_to_prev += lengths[idx_prev];
|
||||
}
|
||||
|
||||
for (size_t _i = 0; _i < points.size(); ++_i) {
|
||||
// pull idx_prev to current as much as possible, while respecting the min_arm_length
|
||||
while (distance_to_prev - lengths[idx_prev] > min_arm_length) {
|
||||
distance_to_prev -= lengths[idx_prev];
|
||||
idx_prev = Slic3r::next_idx_modulo(idx_prev, points.size());
|
||||
}
|
||||
|
||||
// push idx_next forward as far as needed
|
||||
while (distance_to_next < min_arm_length) {
|
||||
distance_to_next += lengths[idx_next];
|
||||
idx_next = Slic3r::next_idx_modulo(idx_next, points.size());
|
||||
}
|
||||
|
||||
// Calculate angle between idx_prev, idx_curr, idx_next.
|
||||
const Point& p0 = points[idx_prev];
|
||||
const Point& p1 = points[idx_curr];
|
||||
const Point& p2 = points[idx_next];
|
||||
const auto a = angle(p0 - p1, p2 - p1);
|
||||
if (a > 0 ? a < angle_threshold : a > -angle_threshold) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// increase idx_curr by one
|
||||
float curr_distance = lengths[idx_curr];
|
||||
idx_curr++;
|
||||
distance_to_prev += curr_distance;
|
||||
distance_to_next -= curr_distance;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ExtrusionLoopSloped::ExtrusionLoopSloped(ExtrusionPaths& original_paths,
|
||||
double seam_gap,
|
||||
double slope_min_length,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue