From a6a723928c6f5eda7b51b634fdf25cff64dac376 Mon Sep 17 00:00:00 2001 From: PavelMikus Date: Wed, 7 Sep 2022 17:11:58 +0200 Subject: [PATCH] create cradle around small parts, break tiny connections in the model graph, fix PETG support --- src/libslic3r/PrintObject.cpp | 2 +- src/libslic3r/SupportSpotsGenerator.cpp | 61 ++++++++++++------------- src/libslic3r/SupportSpotsGenerator.hpp | 27 +++++------ 3 files changed, 44 insertions(+), 46 deletions(-) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 71ec15e07d..f4b69bb812 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -435,7 +435,7 @@ void PrintObject::generate_support_spots() Vec3f point = Vec3f(inv_transform.cast() * support_point.position); Vec3f origin = Vec3f( inv_transform.cast() * Vec3f(support_point.position.x(), support_point.position.y(), 0.0f)); - selector.enforce_spot(point, origin, 1.5f); + selector.enforce_spot(point, origin, support_point.spot_radius); } model_volume->supported_facets.set(selector.selector); diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index f976bac1ac..0a6ab5e9da 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -16,8 +16,8 @@ #include "libslic3r/ClipperUtils.hpp" #include "Geometry/ConvexHull.hpp" -//#define DETAILED_DEBUG_LOGS -//#define DEBUG_FILES +// #define DETAILED_DEBUG_LOGS +// #define DEBUG_FILES #ifdef DEBUG_FILES #include @@ -66,8 +66,8 @@ auto get_b(ExtrusionLine &&l) { namespace SupportSpotsGenerator { -SupportPoint::SupportPoint(const Vec3f &position, float force, const Vec3f &direction) : - position(position), force(force), direction(direction) { +SupportPoint::SupportPoint(const Vec3f &position, float force, float spot_radius, const Vec3f &direction) : + position(position), force(force), spot_radius(spot_radius), direction(direction) { } class LinesDistancer { @@ -405,16 +405,9 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity, float max_malformation_dist = tan(params.malformation_angle_span_deg.second * PI / 180.0f) * layer_region->layer()->height; - Points points { }; - entity->collect_points(points); std::vector lines = to_short_lines(entity, params.bridge_distance); if (lines.empty()) return; - if (entity->total_volume() < params.supportable_volume_threshold) { - checked_lines_out.insert(checked_lines_out.end(), lines.begin(), lines.end()); - return; - } - ExtrusionPropertiesAccumulator bridging_acc { }; ExtrusionPropertiesAccumulator malformation_acc { }; bridging_acc.add_distance(params.bridge_distance + 1.0f); @@ -429,6 +422,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity, curr_angle = angle(v1, v2); } bridging_acc.add_angle(curr_angle); + // malformation in concave angles does not happen malformation_acc.add_angle(std::max(0.0f, curr_angle)); size_t nearest_line_idx; @@ -444,11 +438,11 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity, bool in_layer_dist_condition = bridging_acc.distance > params.bridge_distance / (1.0f + (bridging_acc.max_curvature * params.bridge_distance_decrease_by_curvature_factor / PI)); - bool between_layers_condition = fabs(dist_from_prev_layer) > 3.0f * flow_width || + bool between_layers_condition = fabs(dist_from_prev_layer) > flow_width || prev_layer_lines.get_line(nearest_line_idx).malformation > 3.0f * layer_region->layer()->height; if (in_layer_dist_condition && between_layers_condition) { - issues.support_points.emplace_back(to_vec3f(current_line.b), 0.0f, Vec3f(0.f, 0.0f, -1.0f)); + issues.support_points.emplace_back(to_vec3f(current_line.b), 0.0f, params.support_points_interface_radius, Vec3f(0.f, 0.0f, -1.0f)); current_line.support_point_generated = true; bridging_acc.reset(); } @@ -562,7 +556,7 @@ std::tuple reckon_islands( for (size_t lidx = extrusions[extrusion_idx].first; lidx < extrusions[extrusion_idx].second; ++lidx) { line_to_island_mapping[lidx] = result.islands.size(); const ExtrusionLine &line = layer_lines[lidx]; - float volume = line.origin_entity->min_mm3_per_mm() * line.len; + float volume = line.len * layer->height * flow_width * PI / 4.0f; island.volume += volume; island.volume_centroid_accumulator += to_3d(Vec2f((line.a + line.b) / 2.0f), float(layer->slice_z)) * volume; @@ -632,6 +626,15 @@ std::tuple reckon_islands( } } + // filter out very small connection areas, they brake the graph building + for (Island &island : result.islands) { + std::vector conns_to_remove; + for (const auto &conn : island.connected_islands) { + if (conn.second.area < params.connections_min_considerable_area) { conns_to_remove.push_back(conn.first); } + } + for (size_t conn : conns_to_remove) { island.connected_islands.erase(conn); } + } + return {result, current_layer_grid}; } @@ -1039,12 +1042,6 @@ Issues check_global_stability(SupportGridFilter supports_presence_grid, const Island &island = islands_graph[layer_idx].islands[island_idx]; ObjectPart &part = active_object_parts.access(prev_island_to_object_part_mapping[island_idx]); - //skip small drops of material - if they grow in size, they will be supported in next layers; - // if they dont grow, they are not worthy - if (part.get_volume() < params.supportable_volume_threshold) { - continue; - } - IslandConnection &weakest_conn = prev_island_weakest_connection[island_idx]; #ifdef DETAILED_DEBUG_LOGS weakest_conn.print_info("weakest connection info: "); @@ -1068,21 +1065,21 @@ Issues check_global_stability(SupportGridFilter supports_presence_grid, auto force = part.is_stable_while_extruding(weakest_conn, line, support_point, layer_z, params); if (force > 0) { if (!supports_presence_grid.position_taken(support_point)) { - float area = std::min(float(unscaled(line.origin_entity->length())), - params.support_points_interface_radius * params.support_points_interface_radius - * float(PI)); - float altered_area = area * params.get_support_spots_adhesion_strength() / params.get_bed_adhesion_yield_strength(); - part.add_support_point(support_point, area); - issues.support_points.emplace_back(support_point, force, - to_3d(Vec2f(line.b - line.a).normalized(), 0.0f)); + float orig_area = params.support_points_interface_radius * params.support_points_interface_radius * float(PI); + // artifically lower the area for materials that have strong bed adhesion, as this adhesion does not apply for support points + float altered_area = orig_area * params.get_support_spots_adhesion_strength() / params.get_bed_adhesion_yield_strength(); + part.add_support_point(support_point, altered_area); + + float radius = part.get_volume() < params.small_parts_threshold ? params.small_parts_support_points_interface_radius : params.support_points_interface_radius; + issues.support_points.emplace_back(support_point, force, radius, to_3d(Vec2f(line.b - line.a).normalized(), 0.0f)); supports_presence_grid.take_position(support_point); weakest_conn.area += altered_area; weakest_conn.centroid_accumulator += support_point * altered_area; - weakest_conn.second_moment_of_area_accumulator += altered_area - * support_point.head<2>().cwiseProduct(support_point.head<2>()); - weakest_conn.second_moment_of_area_covariance_accumulator += altered_area * support_point.x() - * support_point.y(); + weakest_conn.second_moment_of_area_accumulator += altered_area * + support_point.head<2>().cwiseProduct(support_point.head<2>()); + weakest_conn.second_moment_of_area_covariance_accumulator += altered_area * support_point.x() * + support_point.y(); } } } @@ -1104,7 +1101,7 @@ std::tuple> check_extrusions_and_build_graph(c std::vector islands_graph; std::vector layer_lines; float flow_width = get_flow_width(po->layers()[po->layer_count() - 1]->regions()[0], erExternalPerimeter); - PixelGrid prev_layer_grid(po, flow_width); + PixelGrid prev_layer_grid(po, flow_width*2.0f); // PREPARE BASE LAYER const Layer *layer = po->layers()[0]; diff --git a/src/libslic3r/SupportSpotsGenerator.hpp b/src/libslic3r/SupportSpotsGenerator.hpp index 9a45c38d98..61a1bc5385 100644 --- a/src/libslic3r/SupportSpotsGenerator.hpp +++ b/src/libslic3r/SupportSpotsGenerator.hpp @@ -30,40 +30,41 @@ struct Params { const std::pair malformation_angle_span_deg = std::pair { 45.0f, 80.0f }; const float min_distance_between_support_points = 3.0f; //mm - const float support_points_interface_radius = 2.0f; // mm - - // NOTE: Currently disabled, does not work correctly due to inability of the algorithm to correctly detect islands at each layer - const float supportable_volume_threshold = 0.0f; // mm^3 + const float support_points_interface_radius = 1.5f; // mm + const float connections_min_considerable_area = 1.5f; //mm^2 + const float small_parts_threshold = 5.0f; //mm^3 + const float small_parts_support_points_interface_radius = 3.0f; // mm std::string filament_type; const float gravity_constant = 9806.65f; // mm/s^2; gravity acceleration on Earth's surface, algorithm assumes that printer is in upwards position. const float max_acceleration = 9 * 1000.0f; // mm/s^2 ; max acceleration of object (bed) in XY (NOTE: The max hit is received by the object in the jerk phase, so the usual machine limits are too low) - const float filament_density = 1.25e-3f; // g/mm^3 ; Common filaments are very lightweight, so precise number is not that important - const float material_yield_strength = 33.0f * 1e6f; // (g*mm/s^2)/mm^2; 33 MPa is yield strength of ABS, which has the lowest yield strength from common materials. + const double filament_density = 1.25e-3f; // g/mm^3 ; Common filaments are very lightweight, so precise number is not that important + const double material_yield_strength = 33.0f * 1e6f; // (g*mm/s^2)/mm^2; 33 MPa is yield strength of ABS, which has the lowest yield strength from common materials. const float standard_extruder_conflict_force = 20.0f * gravity_constant; // force that can occasionally push the model due to various factors (filament leaks, small curling, ... ); const float malformations_additive_conflict_extruder_force = 300.0f * gravity_constant; // for areas with possible high layered curled filaments // MPa * 1e^6 = (g*mm/s^2)/mm^2 = g/(mm*s^2); yield strength of the bed surface - float get_bed_adhesion_yield_strength() const { + double get_bed_adhesion_yield_strength() const { if (filament_type == "PLA") { - return 0.018f * 1e6f; + return 0.018 * 1e6; } else if (filament_type == "PET" || filament_type == "PETG") { - return 0.3f * 1e6f; + return 0.3 * 1e6; } else { //PLA default value - defensive approach, PLA has quite low adhesion - return 0.018f * 1e6f; + return 0.018 * 1e6; } } //just return PLA adhesion value as value for supports - float get_support_spots_adhesion_strength() const { - return 0.018f * 1e6f; + double get_support_spots_adhesion_strength() const { + return 0.018f * 1e6; } }; struct SupportPoint { - SupportPoint(const Vec3f &position, float force, const Vec3f &direction); + SupportPoint(const Vec3f &position, float force, float spot_radius, const Vec3f &direction); Vec3f position; float force; + float spot_radius; Vec3f direction; };