From be61ab37f4d7073d09c66fa988227495767fba96 Mon Sep 17 00:00:00 2001 From: PavelMikus Date: Thu, 19 Jan 2023 15:07:06 +0100 Subject: [PATCH] Document extensively the generated SupportPoint structure, fix wrong estimation of weight torque for connections --- src/libslic3r/SupportSpotsGenerator.cpp | 19 +++++++++++++------ src/libslic3r/SupportSpotsGenerator.hpp | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index e881f7bba..7c1c4f3c6 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -463,7 +463,7 @@ public: #ifdef DETAILED_DEBUG_LOGS BOOST_LOG_TRIVIAL(debug) << "bed_centroid: " << bed_centroid.x() << " " << bed_centroid.y() << " " << bed_centroid.z(); BOOST_LOG_TRIVIAL(debug) << "SSG: bed_yield_torque: " << bed_yield_torque; - BOOST_LOG_TRIVIAL(debug) << "SSG: bed_weight_arm: " << bed_weight_arm; + BOOST_LOG_TRIVIAL(debug) << "SSG: bed_weight_arm: " << bed_weight_arm_len; BOOST_LOG_TRIVIAL(debug) << "SSG: bed_weight_torque: " << bed_weight_torque; BOOST_LOG_TRIVIAL(debug) << "SSG: bed_movement_arm: " << bed_movement_arm; BOOST_LOG_TRIVIAL(debug) << "SSG: bed_movement_torque: " << bed_movement_torque; @@ -492,7 +492,7 @@ public: params.material_yield_strength; float conn_weight_arm = (conn_centroid.head<2>() - mass_centroid.head<2>()).norm(); - float conn_weight_torque = conn_weight_arm * weight * (conn_centroid.z() / layer_z); + float conn_weight_torque = conn_weight_arm * weight * (1.0f - conn_centroid.z() / layer_z); float conn_movement_arm = std::max(0.0f, mass_centroid.z() - conn_centroid.z()); float conn_movement_torque = movement_force * conn_movement_arm; @@ -732,17 +732,24 @@ SupportPoints check_stability(const PrintObject *po, const PrintTryCancel& cance // and the support presence grid and add the point to the issues. auto reckon_new_support_point = [&part, &weakest_conn, &supp_points, &supports_presence_grid, ¶ms, &layer_idx](const Vec3f &support_point, float force, const Vec2f &dir) { + // if position is taken and point is for global stability (force > 0) or we are too close to the bed, do not add + // This allows local support points (e.g. bridging) to be generated densely if ((supports_presence_grid.position_taken(support_point) && force > 0) || layer_idx <= 1) { return; } + float area = params.support_points_interface_radius * params.support_points_interface_radius * float(PI); - part.add_support_point(support_point, area); + // add the stability effect of the point only if the spot is not taken, so that the densely created local support points do not add + // unrealistic amount of stability to the object (due to overlaping of local support points) + if (!(supports_presence_grid.position_taken(support_point))) { + part.add_support_point(support_point, area); + } float radius = params.support_points_interface_radius; supp_points.emplace_back(support_point, force, radius, dir); - if (force > 0) { - supports_presence_grid.take_position(support_point); - } + supports_presence_grid.take_position(support_point); + + // The support point also increases the stability of the weakest connection of the object, which should be reflected if (weakest_conn.area > EPSILON) { // Do not add it to the weakest connection if it is not valid - does not exist weakest_conn.area += area; weakest_conn.centroid_accumulator += support_point * area; diff --git a/src/libslic3r/SupportSpotsGenerator.hpp b/src/libslic3r/SupportSpotsGenerator.hpp index 1c07c1381..8e8983ac1 100644 --- a/src/libslic3r/SupportSpotsGenerator.hpp +++ b/src/libslic3r/SupportSpotsGenerator.hpp @@ -63,11 +63,33 @@ struct Params { } }; +// The support points are generated for two reasons: +// 1. Local extrusion support for extrusions that are printed in the air and would not +// withstand on their own (too long bridges, sharp turns in large overhang, concave bridge holes, etc.) +// These points have negative force (-EPSILON) and Vec2f::Zero() direction +// The algorithm still expects that these points will be supported and accounts for them in the global stability check +// 2. Global stability support points are generated at each spot, where the algorithm detects that extruding the current line +// may cause separation of the object part from the bed and/or its support spots or crack in the weak connection of the object parts +// The generated point's direction is the estimated falling direction of the object part, and the force is equal to te difference +// between forces that destabilize the object (extruder conflicts with curled filament, weight if instable center of mass, bed movements etc) +// and forces that stabilize the object (bed adhesion, other support spots adhesion, weight if stable center of mass) +// Note that the force is only the difference - the amount needed to stabilize the object again. struct SupportPoint { SupportPoint(const Vec3f &position, float force, float spot_radius, const Vec2f &direction); + bool is_local_extrusion_support() const { return force < 0; } + bool is_global_object_support() const { return !is_local_extrusion_support(); } + + //position is in unscaled coords. The z coordinate is aligned with the layers bottom_z coordiantes Vec3f position; + // force that destabilizes the object to the point of falling/breaking. It is in g*mm/s^2 units + // values gathered from large XL print: Min : 0 | Max : 18713800 | Average : 1361186 | Median : 329103 + // For reference 18713800 is weight of 1.8 Kg object, 329103 is weight of 0.03 Kg + // The final printed object weight was approx 0.5 Kg float force; + // Expected spot size. The support point strength is calculated from the area defined by this value. + // Currently equal to the support_points_interface_radius parameter above float spot_radius; + // direction of the fall of the object (z part is neglected) Vec2f direction; };