From 9d2e0160c311deb65b8ba19fb718174c053a81ba Mon Sep 17 00:00:00 2001 From: PavelMikus Date: Fri, 12 Aug 2022 13:39:10 +0200 Subject: [PATCH] fix patterns in Random seam - replace rand() with pseudorandom generator --- src/libslic3r/GCode/SeamPlacer.cpp | 76 +++++++++++------------------- 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 6139738755..ec380e749f 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -473,7 +473,6 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const } 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 lengths { }; for (size_t point_idx = 0; point_idx < polygon.size() - 1; ++point_idx) { @@ -481,7 +480,7 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const } lengths.push_back(std::max((unscale(polygon[0]) - unscale(polygon[polygon.size() - 1])).norm(), 0.1)); std::vector polygon_angles = calculate_polygon_angles_at_vertices(polygon, lengths, - angle_arm_len); + SeamPlacer::polygon_local_angles_arm_distance); result.perimeters.push_back( { }); Perimeter &perimeter = result.perimeters.back(); @@ -969,7 +968,7 @@ void pick_random_seam_point(const std::vector &perimeter_points, std::vector 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); + float rand = std::abs(sin(pseudornd_seed.dot(Vec3f(12.9898,78.233, 133.3333))) * 43758.5453); rand = rand - (int) rand; for (size_t index = start_index; index < end_index; ++index) { @@ -1020,7 +1019,11 @@ class PerimeterDistancer { public: PerimeterDistancer(const Layer *layer) { - ExPolygons layer_outline = layer->lslices; + static const float eps = float(scale_(layer->object()->config().slice_closing_radius.value)); + // merge with offset + ExPolygons merged = layer->merged(eps); + // ofsset back + ExPolygons layer_outline = offset_ex(merged, -eps); for (const ExPolygon &island : layer_outline) { assert(island.contour.is_counter_clockwise()); for (const auto &line : island.contour.lines()) { @@ -1036,8 +1039,8 @@ public: tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines); } - float distance_from_perimeter(const Vec2f &point) const { - Vec2d p = point.cast(); + float distance_from_perimeter(const Point &point) const { + Vec2d p = unscale(point); 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); @@ -1129,19 +1132,20 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) std::unique_ptr current_layer_distancer = std::make_unique(po->layers()[layer_idx]); for (SeamCandidate &perimeter_point : layers[layer_idx].points) { - Vec2f point = Vec2f { perimeter_point.position.head<2>() }; + Point point = Point::new_scale(Vec2f { perimeter_point.position.head<2>() }); if (prev_layer_distancer.get() != nullptr) { - perimeter_point.overhang = prev_layer_distancer->distance_from_perimeter(point) - + 0.6f * perimeter_point.perimeter.flow_width + 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; - perimeter_point.overhang = - perimeter_point.overhang < 0.0f ? 0.0f : perimeter_point.overhang; + * 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 = 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.6f * perimeter_point.perimeter.flow_width; + + 0.5f * perimeter_point.perimeter.flow_width; } } @@ -1399,7 +1403,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) ? -0.8f : 1.0f; + float sign = layer_angle > 2.0 * std::abs(current.local_ccw_angle) ? -1.0f : 1.0f; if (current.type == EnforcedBlockedSeamPoint::Enforced) { sign = 1.0f; weights[index] += 3.0f; @@ -1417,10 +1421,10 @@ 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::pow(std::abs(layers[pair.first].points[pair.second].local_ccw_angle) - / SeamPlacer::sharp_angle_snapping_threshold, 3.0f)); + 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.4f, t); + t = std::max(0.7f, t); } Vec3f current_pos = layers[pair.first].points[pair.second].position; @@ -1551,40 +1555,16 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern const size_t layer_index = layer->id() - po->slicing_parameters().raft_layers(); const double unscaled_z = layer->slice_z; - auto get_next_loop_point = [loop](ExtrusionLoop::ClosestPathPoint current) { - current.segment_idx += 1; - if (current.segment_idx >= loop.paths[current.path_idx].polyline.points.size()) { - current.path_idx = next_idx_modulo(current.path_idx, loop.paths.size()); - current.segment_idx = 0; - } - current.foot_pt = loop.paths[current.path_idx].polyline.points[current.segment_idx]; - return current; - }; - const PrintObjectSeamData::LayerSeams &layer_perimeters = m_seam_per_object.find(layer->object())->second.layers[layer_index]; - // Find the closest perimeter in the SeamPlacer to this loop. - // Repeat search until two consecutive points of the loop are found, that result in the same closest_perimeter - // This is beacuse with arachne, T-Junctions may exist and sometimes the wrong perimeter was chosen - size_t closest_perimeter_point_index = 0; - { // local space for the closest_perimeter_point_index - Perimeter *closest_perimeter = nullptr; - ExtrusionLoop::ClosestPathPoint closest_point{0,0,loop.paths[0].polyline.points[0]}; - size_t points_count = std::accumulate(loop.paths.begin(), loop.paths.end(), 0, [](size_t acc,const ExtrusionPath& p) { - return acc + p.polyline.points.size(); - }); - for (size_t _ = 0; _ < points_count; ++_) { - Vec2f unscaled_p = unscaled(closest_point.foot_pt); - closest_perimeter_point_index = find_closest_point(*layer_perimeters.points_tree.get(), - to_3d(unscaled_p, float(unscaled_z))); - if (closest_perimeter != &layer_perimeters.points[closest_perimeter_point_index].perimeter) { - closest_perimeter = &layer_perimeters.points[closest_perimeter_point_index].perimeter; - closest_point = get_next_loop_point(closest_point); - } else { - break; - } - } + // Find the closest perimeter in the SeamPlacer to the first point of this loop. + size_t closest_perimeter_point_index; + { + const Point &fp = loop.first_point(); + Vec2f unscaled_p = unscaled(fp); + closest_perimeter_point_index = find_closest_point(*layer_perimeters.points_tree.get(), + to_3d(unscaled_p, float(unscaled_z))); } Vec3f seam_position;