ENH: cherry pick some fix about seam from PrusaSlicer
Synced from PrusaSlicer. Thanks Signed-off-by: salt.wei <salt.wei@bambulab.com> Change-Id: I043088d9795f5352d4e0b5060402b70897fd7592
This commit is contained in:
parent
36528738fe
commit
5bea8a76fc
|
@ -422,11 +422,12 @@ void process_perimeter_polygon(
|
|||
if (orig_polygon.size() == 0) { return; }
|
||||
Polygon polygon = orig_polygon;
|
||||
bool was_clockwise = polygon.make_counter_clockwise();
|
||||
float angle_arm_len = region != nullptr ? region->flow(FlowRole::frExternalPerimeter).nozzle_diameter() : 0.5f;
|
||||
|
||||
std::vector<float> lengths{};
|
||||
for (size_t point_idx = 0; point_idx < polygon.size() - 1; ++point_idx) { lengths.push_back((unscale(polygon[point_idx]) - unscale(polygon[point_idx + 1])).norm()); }
|
||||
lengths.push_back(std::max((unscale(polygon[0]) - unscale(polygon[polygon.size() - 1])).norm(), 0.1));
|
||||
std::vector<float> polygon_angles = calculate_polygon_angles_at_vertices(polygon, lengths, SeamPlacer::polygon_local_angles_arm_distance);
|
||||
std::vector<float> polygon_angles = calculate_polygon_angles_at_vertices(polygon, lengths, angle_arm_len);
|
||||
|
||||
result.perimeters.push_back({});
|
||||
Perimeter &perimeter = result.perimeters.back();
|
||||
|
@ -829,6 +830,10 @@ void pick_random_seam_point(const std::vector<SeamCandidate> &perimeter_points,
|
|||
};
|
||||
std::vector<Viable> viables;
|
||||
|
||||
const Vec3f pseudornd_seed = perimeter_points[viable_example_index].position;
|
||||
float rand = std::abs(sin(pseudornd_seed.dot(Vec3f(12.9898f, 78.233f, 133.3333f))) * 43758.5453f);
|
||||
rand = rand - (int) rand;
|
||||
|
||||
for (size_t index = start_index; index < end_index; ++index) {
|
||||
if (comparator.are_similar(perimeter_points[index], perimeter_points[viable_example_index])) {
|
||||
// index ok, push info into viables
|
||||
|
@ -851,7 +856,7 @@ void pick_random_seam_point(const std::vector<SeamCandidate> &perimeter_points,
|
|||
|
||||
// now pick random point from the stored options
|
||||
float len_sum = std::accumulate(viables.begin(), viables.end(), 0.0f, [](const float acc, const Viable &v) { return acc + v.edge_length; });
|
||||
float picked_len = len_sum * (rand() / (float(RAND_MAX) + 1));
|
||||
float picked_len = len_sum * rand;
|
||||
|
||||
size_t point_idx = 0;
|
||||
while (picked_len - viables[point_idx].edge_length > 0) {
|
||||
|
@ -873,11 +878,7 @@ class PerimeterDistancer
|
|||
public:
|
||||
PerimeterDistancer(const Layer *layer)
|
||||
{
|
||||
static const float eps = float(scale_(g_config_slice_closing_radius));
|
||||
// merge with offset
|
||||
ExPolygons merged = layer->merged(eps);
|
||||
// ofsset back
|
||||
ExPolygons layer_outline = offset_ex(merged, -eps);
|
||||
ExPolygons layer_outline = layer->lslices;
|
||||
for (const ExPolygon &island : layer_outline) {
|
||||
assert(island.contour.is_counter_clockwise());
|
||||
for (const auto &line : island.contour.lines()) { lines.emplace_back(unscale(line.a), unscale(line.b)); }
|
||||
|
@ -889,9 +890,9 @@ public:
|
|||
tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines);
|
||||
}
|
||||
|
||||
float distance_from_perimeter(const Point &point) const
|
||||
float distance_from_perimeter(const Vec2f &point) const
|
||||
{
|
||||
Vec2d p = unscale(point);
|
||||
Vec2d p = point.cast<double>();
|
||||
size_t hit_idx_out{};
|
||||
Vec2d hit_point_out = Vec2d::Zero();
|
||||
auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, hit_idx_out, hit_point_out);
|
||||
|
@ -966,17 +967,15 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po)
|
|||
std::unique_ptr<PerimeterDistancer> current_layer_distancer = std::make_unique<PerimeterDistancer>(po->layers()[layer_idx]);
|
||||
|
||||
for (SeamCandidate &perimeter_point : layers[layer_idx].points) {
|
||||
Point point = Point::new_scale(Vec2f{perimeter_point.position.head<2>()});
|
||||
Vec2f point = Vec2f{perimeter_point.position.head<2>()};
|
||||
if (prev_layer_distancer.get() != nullptr) {
|
||||
perimeter_point.overhang = (prev_layer_distancer->distance_from_perimeter(point) + 0.5f * perimeter_point.perimeter.flow_width -
|
||||
tan(SeamPlacer::overhang_angle_threshold) * po->layers()[layer_idx]->height) /
|
||||
(3.0f * perimeter_point.perimeter.flow_width);
|
||||
// NOTE disables the feature to place seams on slowly decreasing areas. Remove the following line to enable.
|
||||
perimeter_point.overhang = prev_layer_distancer->distance_from_perimeter(point) + 0.6f * perimeter_point.perimeter.flow_width -
|
||||
tan(SeamPlacer::overhang_angle_threshold) * po->layers()[layer_idx]->height;
|
||||
perimeter_point.overhang = perimeter_point.overhang < 0.0f ? 0.0f : perimeter_point.overhang;
|
||||
}
|
||||
|
||||
if (should_compute_layer_embedding) { // search for embedded perimeter points (points hidden inside the print ,e.g. multimaterial join, best position for seam)
|
||||
perimeter_point.embedded_distance = current_layer_distancer->distance_from_perimeter(point) + 0.5f * perimeter_point.perimeter.flow_width;
|
||||
perimeter_point.embedded_distance = current_layer_distancer->distance_from_perimeter(point) + 0.6f * perimeter_point.perimeter.flow_width;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1199,7 +1198,7 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
|
|||
observations[index] = current.position.head<2>();
|
||||
observation_points[index] = current.position.z();
|
||||
weights[index] = angle_weight(current.local_ccw_angle);
|
||||
float sign = layer_angle > 2.0 * std::abs(current.local_ccw_angle) ? -1.0f : 1.0f;
|
||||
float sign = layer_angle > 2.0 * std::abs(current.local_ccw_angle) ? -0.8f : 1.0f;
|
||||
if (current.type == EnforcedBlockedSeamPoint::Enforced) {
|
||||
sign = 1.0f;
|
||||
weights[index] += 3.0f;
|
||||
|
@ -1216,8 +1215,8 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
|
|||
// Perimeter structure of the point; also set flag aligned to true
|
||||
for (size_t index = 0; index < seam_string.size(); ++index) {
|
||||
const auto &pair = seam_string[index];
|
||||
float t = std::min(1.0f, std::abs(layers[pair.first].points[pair.second].local_ccw_angle) / SeamPlacer::sharp_angle_snapping_threshold);
|
||||
if (layers[pair.first].points[pair.second].type == EnforcedBlockedSeamPoint::Enforced) { t = std::max(0.7f, t); }
|
||||
float t = std::min(1.0f, std::pow(std::abs(layers[pair.first].points[pair.second].local_ccw_angle) / SeamPlacer::sharp_angle_snapping_threshold, 3.0f));
|
||||
if (layers[pair.first].points[pair.second].type == EnforcedBlockedSeamPoint::Enforced) { t = std::max(0.4f, t); }
|
||||
|
||||
Vec3f current_pos = layers[pair.first].points[pair.second].position;
|
||||
Vec2f fitted_pos = curve.get_fitted_value(current_pos.z());
|
||||
|
@ -1373,8 +1372,7 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
|
|||
|
||||
// Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns,
|
||||
// thus empty path segments will not be produced by G-code export.
|
||||
//if (!loop.split_at_vertex(seam_point, scaled<double>(0.0015))) {
|
||||
if (!loop.split_at_vertex(seam_point)) {
|
||||
if (!loop.split_at_vertex(seam_point, scaled<double>(0.0015))) {
|
||||
// The point is not in the original loop.
|
||||
// Insert it.
|
||||
loop.split_at(seam_point, true);
|
||||
|
|
|
@ -118,11 +118,10 @@ public:
|
|||
// square of number of rays per sample point
|
||||
static constexpr size_t sqr_rays_per_sample_point = 5;
|
||||
|
||||
// arm length used during angles computation
|
||||
static constexpr float polygon_local_angles_arm_distance = 0.3f;
|
||||
// snapping angle - angles larger than this value will be snapped to during seam painting
|
||||
static constexpr float sharp_angle_snapping_threshold = 55.0f * float(PI) / 180.0f;
|
||||
// overhang angle for seam placement that still yields good results, in degrees, measured from vertical direction
|
||||
//BBS
|
||||
static constexpr float overhang_angle_threshold = 45.0f * float(PI) / 180.0f;
|
||||
|
||||
// determines angle importance compared to visibility ( neutral value is 1.0f. )
|
||||
|
|
Loading…
Reference in New Issue