initial warnings version

This commit is contained in:
PavelMikus 2023-01-24 11:54:16 +01:00 committed by Pavel Mikuš
parent fb4c1bf612
commit a4de5c6553
3 changed files with 134 additions and 18 deletions

View File

@ -1,4 +1,5 @@
#include "Exception.hpp"
#include "Point.hpp"
#include "Print.hpp"
#include "BoundingBox.hpp"
#include "ClipperUtils.hpp"
@ -21,9 +22,13 @@
#include "SupportSpotsGenerator.hpp"
#include "TriangleSelectorWrapper.hpp"
#include "format.hpp"
#include "libslic3r.h"
#include <algorithm>
#include <cmath>
#include <float.h>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <boost/log/trivial.hpp>
@ -406,21 +411,6 @@ void PrintObject::ironing()
}
}
/*
std::vector<size_t> problematic_layers = SupportSpotsGenerator::quick_search(this);
if (!problematic_layers.empty()) {
std::cout << "Object needs supports" << std::endl;
this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
L("Supportable issues found. Consider enabling supports for this object"));
this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
L("Supportable issues found. Consider enabling supports for this object"));
for (size_t index = 0; index < std::min(problematic_layers.size(), size_t(4)); ++index) {
this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
format(L("Layer with issues: %1%"), problematic_layers[index] + 1));
}
}
*/
void PrintObject::generate_support_spots()
{
if (this->set_started(posSupportSpotsSearch)) {
@ -434,6 +424,124 @@ void PrintObject::generate_support_spots()
auto [supp_points, partial_objects] = SupportSpotsGenerator::full_search(this, cancel_func, params);
this->m_shared_regions->generated_support_points = {this->trafo_centered(), supp_points};
m_print->throw_if_canceled();
auto check_problems = [&]() {
std::unordered_map<SupportSpotsGenerator::SupportPointCause, SupportSpotsGenerator::SupportPoints> sp_by_cause{};
for (const SupportSpotsGenerator::SupportPoint &sp : supp_points) {
sp_by_cause[sp.cause].push_back(sp);
}
if (!sp_by_cause[SupportSpotsGenerator::SupportPointCause::SeparationFromBed].empty()) {
this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL,
L("Object part may break from the bed. Consider adding brim and/or supports."));
}
std::reverse(partial_objects.begin(), partial_objects.end());
std::sort(partial_objects.begin(), partial_objects.end(),
[](const SupportSpotsGenerator::PartialObject &left, const SupportSpotsGenerator::PartialObject &right) {
return left.volume > right.volume;
});
float max_volume_part = partial_objects.front().volume;
for (const SupportSpotsGenerator::PartialObject &p : partial_objects) {
if (p.volume > max_volume_part / 1000.0f && !p.connected_to_bed) {
this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
L("Floating object parts detected. Please add supports."));
return;
}
}
if (!sp_by_cause[SupportSpotsGenerator::SupportPointCause::WeakObjectPart].empty()) {
this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
L("Thin parts of the object may break. Please add supports."));
return;
}
if (!sp_by_cause[SupportSpotsGenerator::SupportPointCause::FloatingBridgeAnchor].empty()) {
Vec3f last_pos = Vec3f::Zero();
size_t count = 0;
for (const SupportSpotsGenerator::SupportPoint &sp :
sp_by_cause[SupportSpotsGenerator::SupportPointCause::FloatingBridgeAnchor]) {
if ((sp.position - last_pos).squaredNorm() < 9.0f) {
count++;
last_pos = sp.position;
} else {
last_pos = sp.position;
count = 1;
}
if (count > 1) {
this->active_step_add_warning(
PrintStateBase::WarningLevel::CRITICAL,
L("Bridges without supported endpoints will collapse. Please add supports. "));
break;
}
}
}
if (!sp_by_cause[SupportSpotsGenerator::SupportPointCause::LongUnsupportedExtrusion].empty()) {
Vec3f last_pos = Vec3f::Zero();
size_t count = 0;
for (const SupportSpotsGenerator::SupportPoint &sp :
sp_by_cause[SupportSpotsGenerator::SupportPointCause::LongUnsupportedExtrusion]) {
if ((sp.position - last_pos).squaredNorm() < 9.0f) {
count++;
last_pos = sp.position;
} else {
last_pos = sp.position;
count = 1;
}
if (count > 1) {
this->active_step_add_warning(
PrintStateBase::WarningLevel::CRITICAL,
L("Long unsupported extrusions will collapse. Please add supports. "));
break;
}
}
}
if (!sp_by_cause[SupportSpotsGenerator::SupportPointCause::LongBridge].empty()) {
this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL,
L("There are bridges longer than allowed distance. Consider adding supports. "));
}
if (!sp_by_cause[SupportSpotsGenerator::SupportPointCause::FloatingExtrusion].empty()) {
Vec3f last_pos = Vec3f::Zero();
size_t count = 0;
bool small_warning = false;
for (const SupportSpotsGenerator::SupportPoint &sp :
sp_by_cause[SupportSpotsGenerator::SupportPointCause::FloatingExtrusion]) {
if ((sp.position - last_pos).squaredNorm() <
params.bridge_distance + EPSILON) {
count++;
last_pos = sp.position;
} else {
if (count > 6) {
this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
L("Object has large part with loose extrusions. Please enable supports. "));
small_warning = false;
break;
}
if (count > 3) {
small_warning = true;
}
last_pos = sp.position;
count = 1;
}
}
if (small_warning) {
this->active_step_add_warning(
PrintStateBase::WarningLevel::NON_CRITICAL,
L("Object has parts with loose extrusions and may look bad. Consider enabling supports. "));
} else if (sp_by_cause[SupportSpotsGenerator::SupportPointCause::FloatingExtrusion].size() > max_volume_part / 100) {
this->active_step_add_warning(
PrintStateBase::WarningLevel::NON_CRITICAL,
L("There are many loose surface extrusions on this object. Consider enabling supports. "));
}
}
};
check_problems();
}
BOOST_LOG_TRIVIAL(debug) << "Searching support spots - end";
this->set_done(posSupportSpotsSearch);

View File

@ -321,6 +321,12 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
curr_point.distance *= sign;
SupportPointCause potential_cause = SupportPointCause::FloatingExtrusion;
if (curr_point.distance > flow_width * 5.0) {
if (std::abs(curr_point.curvature) > 0.1)
potential_cause = SupportPointCause::LongUnsupportedExtrusion;
else
potential_cause = SupportPointCause::LongBridge;
}
float max_bridge_len = std::max(params.support_points_interface_radius * 2.0f,
params.bridge_distance /
@ -919,6 +925,7 @@ void debug_export(const SupportPoints& support_points,const PartialObjects& obje
case SupportPointCause::FloatingBridgeAnchor: color = {0.863281f, 0.109375f, 0.113281f}; break; //RED
case SupportPointCause::LongBridge: color = {0.960938f, 0.90625f, 0.0625f}; break; // YELLOW
case SupportPointCause::FloatingExtrusion: color = {0.921875f, 0.515625f, 0.101563f}; break; // ORANGE
case SupportPointCause::LongUnsupportedExtrusion: color = {0.863281f, 0.109375f, 0.113281f}; break; // RED
case SupportPointCause::SeparationFromBed: color = {0.0f, 1.0f, 0.0}; break; // GREEN
case SupportPointCause::UnstableFloatingPart: color = {0.105469f, 0.699219f, 0.84375f}; break; // BLUE
case SupportPointCause::WeakObjectPart: color = {0.609375f, 0.210938f, 0.621094f}; break; // PURPLE

View File

@ -32,8 +32,8 @@ struct Params
// the algorithm should use the following units for all computations: distance [mm], mass [g], time [s], force [g*mm/s^2]
const float bridge_distance = 12.0f; // mm
const float max_acceleration; // 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 max_acceleration; // mm/s^2 ; max acceleration of object in XY -- should be applicable only to printers with bed slinger,
// however we do not have such info yet. The force is usually small anyway, so not such a big deal to include it everytime
const int raft_layers_count;
std::string filament_type;
@ -74,9 +74,10 @@ struct Params
};
enum class SupportPointCause {
LongBridge, // point generated on bridge extrusion longer than the allowed length
LongBridge, // point generated on bridge and straight perimeter extrusion longer than the allowed length
FloatingBridgeAnchor, // point generated on unsupported bridge endpoint
FloatingExtrusion, // point generated on extrusion that does not hold on its own
LongUnsupportedExtrusion, // similar to above, but with large distance to object. This really needs supports.
SeparationFromBed, // point generated for object parts that are connected to the bed, but the area is too small and there is a risk of separation (brim may help)
UnstableFloatingPart, // point generated for object parts not connected to the bed, holded only by the other support points (brim will not help here)
WeakObjectPart // point generated when some part of the object is too weak to hold the upper part and may break (imagine hourglass)