brim integration into SupportSpotGenerator

This commit is contained in:
PavelMikus 2023-01-25 16:57:52 +01:00 committed by Pavel Mikuš
parent c31e3ec1a2
commit c09a44779d
4 changed files with 86 additions and 28 deletions

View file

@ -32,8 +32,8 @@ public:
ExPolygon& operator=(const ExPolygon &other) = default;
ExPolygon& operator=(ExPolygon &&other) = default;
Polygon contour;
Polygons holes;
Polygon contour; //CCW
Polygons holes; //CW
void clear() { contour.points.clear(); holes.clear(); }
void scale(double factor);

View file

@ -422,7 +422,8 @@ void PrintObject::generate_support_spots()
PrintTryCancel cancel_func = m_print->make_try_cancel();
SupportSpotsGenerator::Params params{this->print()->m_config.filament_type.values,
float(this->print()->m_config.perimeter_acceleration.getFloat()),
this->config().raft_layers.getInt()};
this->config().raft_layers.getInt(), this->config().brim_type.value,
float(this->config().brim_width.getFloat())};
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();
@ -430,27 +431,33 @@ void PrintObject::generate_support_spots()
auto alert_fn = [&](PrintStateBase::WarningLevel level, SupportSpotsGenerator::SupportPointCause cause) {
switch (cause) {
case SupportSpotsGenerator::SupportPointCause::LongBridge:
this->active_step_add_warning(level, L("There are bridges longer than allowed distance. Consider adding supports. "));
this->active_step_add_warning(level, L("There are bridges longer than recommended length. Consider adding supports.") +
(L("Object name")) + ": " + this->model_object()->name);
break;
case SupportSpotsGenerator::SupportPointCause::FloatingBridgeAnchor:
this->active_step_add_warning(level, L("Unsupported bridges will collapse. Supports are needed."));
this->active_step_add_warning(level, L("Unsupported bridges will collapse. Supports are needed.") + (L("Object name")) +
": " + this->model_object()->name);
break;
case SupportSpotsGenerator::SupportPointCause::FloatingExtrusion:
if (level == PrintStateBase::WarningLevel::CRITICAL) {
this->active_step_add_warning(level, L("Clusters of unsupported extrusions found. Supports are needed."));
this->active_step_add_warning(level, L("Clusters of unsupported extrusions found. Supports are needed.") +
(L("Object name")) + ": " + this->model_object()->name);
} else {
this->active_step_add_warning(level, L("Some unspported extrusions found. Consider adding supports. "));
this->active_step_add_warning(level, L("Some unspported extrusions found. Consider adding supports. ") +
(L("Object name")) + ": " + this->model_object()->name);
}
break;
case SupportSpotsGenerator::SupportPointCause::SeparationFromBed:
this->active_step_add_warning(level, L("Object part may break from the bed. Consider adding brim and/or supports."));
this->active_step_add_warning(level, L("Object part may break from the bed. Consider adding brim and/or supports.") +
(L("Object name")) + ": " + this->model_object()->name);
break;
case SupportSpotsGenerator::SupportPointCause::UnstableFloatingPart:
this->active_step_add_warning(level, L("Floating object parts detected. Supports are needed."));
this->active_step_add_warning(level, L("Floating object parts detected. Supports are needed.") + (L("Object name")) +
": " + this->model_object()->name);
break;
case SupportSpotsGenerator::SupportPointCause::WeakObjectPart:
this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
L("Thin parts of the object may break. Supports are needed."));
this->active_step_add_warning(level, L("Thin parts of the object may break. Consider adding supports.") +
(L("Object name")) + ": " + this->model_object()->name);
break;
}
};
@ -495,9 +502,9 @@ void PrintObject::estimate_curled_extrusions()
// Estimate curling of support material and add it to the malformaition lines of each layer
float support_flow_width = support_material_flow(this, this->config().layer_height).width();
SupportSpotsGenerator::Params params{this->print()->m_config.filament_type.values,
float(this->print()->config().perimeter_acceleration.getFloat()),
this->config().raft_layers.getInt()
};
float(this->print()->m_config.perimeter_acceleration.getFloat()),
this->config().raft_layers.getInt(), this->config().brim_type.value,
float(this->config().brim_width.getFloat())};
SupportSpotsGenerator::estimate_supports_malformations(this->support_layers(), support_flow_width, params);
SupportSpotsGenerator::estimate_malformations(this->layers(), params);
m_print->throw_if_canceled();
@ -609,6 +616,7 @@ bool PrintObject::invalidate_state_by_config_options(
if ( opt_key == "brim_width"
|| opt_key == "brim_separation"
|| opt_key == "brim_type") {
steps.emplace_back(posSupportSpotsSearch);
// Brim is printed below supports, support invalidates brim and skirt.
steps.emplace_back(posSupportMaterial);
} else if (

View file

@ -11,6 +11,7 @@
#include "PrincipalComponents2D.hpp"
#include "Print.hpp"
#include "PrintBase.hpp"
#include "PrintConfig.hpp"
#include "Tesselate.hpp"
#include "libslic3r.h"
#include "tbb/parallel_for.h"
@ -598,10 +599,11 @@ public:
};
// return new object part and actual area covered by extrusions
std::tuple<ObjectPart, float> build_object_part_from_slice(const LayerSlice &slice, const Layer *layer, const Params& params)
std::tuple<ObjectPart, float> build_object_part_from_slice(const size_t &slice_idx, const Layer *layer, const Params& params)
{
ObjectPart new_object_part;
float area_covered_by_extrusions = 0;
const LayerSlice& slice = layer->lslices_ex.at(slice_idx);
auto add_extrusions_to_object = [&new_object_part, &area_covered_by_extrusions, &params](const ExtrusionEntity *e,
const LayerRegion *region) {
@ -659,6 +661,49 @@ std::tuple<ObjectPart, float> build_object_part_from_slice(const LayerSlice &sli
}
}
// BRIM HANDLING
if (layer->id() == params.raft_layers_count && params.raft_layers_count == 0 && params.brim_type != BrimType::btNoBrim) {
// TODO: The algorithm here should take into account that multiple slices may have coliding Brim areas and the final brim area is
// smaller,
// thus has lower adhesion. For now this effect will be neglected.
ExPolygon slice_poly = layer->lslices[slice_idx];
ExPolygons brim;
if (params.brim_type == BrimType::btOuterAndInner || params.brim_type == BrimType::btOuterOnly) {
Polygon brim_hole = slice_poly.contour;
brim_hole.reverse();
brim.push_back(ExPolygon{expand(slice_poly.contour, scale_(params.brim_width)).front(), brim_hole});
}
if (params.brim_type == BrimType::btOuterAndInner || params.brim_type == BrimType::btInnerOnly) {
Polygons brim_contours = slice_poly.holes;
polygons_reverse(brim_contours);
for (const Polygon &brim_contour : brim_contours) {
Polygons brim_holes = shrink({brim_contour}, scale_(params.brim_width));
polygons_reverse(brim_holes);
ExPolygon inner_brim{brim_contour};
inner_brim.holes = brim_holes;
brim.push_back(inner_brim);
}
}
for (const Polygon &poly : to_polygons(brim)) {
Vec2f p0 = unscaled(poly.first_point()).cast<float>();
for (size_t i = 2; i < poly.points.size(); i++) {
Vec2f p1 = unscaled(poly.points[i - 1]).cast<float>();
Vec2f p2 = unscaled(poly.points[i]).cast<float>();
float sign = cross2(p1 - p0, p2 - p1) > 0 ? 1.0f : -1.0f;
auto [area, first_moment_of_area, second_moment_area,
second_moment_of_area_covariance] = compute_moments_of_area_of_triangle(p0, p1, p2);
new_object_part.sticking_area += sign * area;
new_object_part.sticking_centroid_accumulator += sign * Vec3f(first_moment_of_area.x(), first_moment_of_area.y(),
layer->print_z * area);
new_object_part.sticking_second_moment_of_area_accumulator += sign * second_moment_area;
new_object_part.sticking_second_moment_of_area_covariance_accumulator += sign * second_moment_of_area_covariance;
}
}
}
return {new_object_part, area_covered_by_extrusions};
}
@ -730,7 +775,7 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject *po,
for (size_t slice_idx = 0; slice_idx < layer->lslices_ex.size(); ++slice_idx) {
const LayerSlice &slice = layer->lslices_ex.at(slice_idx);
auto [new_part, covered_area] = build_object_part_from_slice(slice, layer, params);
auto [new_part, covered_area] = build_object_part_from_slice(slice_idx, layer, params);
SliceConnection connection_to_below = estimate_slice_connection(slice_idx, layer);
#ifdef DETAILED_DEBUG_LOGS
@ -1146,13 +1191,6 @@ void raise_alerts_for_issues(const SupportPoints
}
}
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::WeakObjectPart) {
alert_fn(PrintStateBase::WarningLevel::CRITICAL, SupportPointCause::WeakObjectPart);
return;
}
}
std::vector<SupportPoint> ext_supp_points{};
ext_supp_points.reserve(support_points.size());
for (const SupportPoint &sp : support_points) {
@ -1189,8 +1227,15 @@ void raise_alerts_for_issues(const SupportPoints
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::LongBridge) {
alert_fn(PrintStateBase::WarningLevel::CRITICAL, SupportPointCause::LongBridge);
return;
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::LongBridge);
break;
}
}
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::WeakObjectPart) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::WeakObjectPart);
break;
}
}
}

View file

@ -4,6 +4,7 @@
#include "Layer.hpp"
#include "Line.hpp"
#include "PrintBase.hpp"
#include "PrintConfig.hpp"
#include <boost/log/trivial.hpp>
#include <cstddef>
#include <vector>
@ -14,8 +15,9 @@ namespace SupportSpotsGenerator {
struct Params
{
Params(const std::vector<std::string> &filament_types, float max_acceleration, int raft_layers_count)
: max_acceleration(max_acceleration), raft_layers_count(raft_layers_count)
Params(
const std::vector<std::string> &filament_types, float max_acceleration, int raft_layers_count, BrimType brim_type, float brim_width)
: max_acceleration(max_acceleration), raft_layers_count(raft_layers_count), brim_type(brim_type), brim_width(brim_width)
{
if (filament_types.size() > 1) {
BOOST_LOG_TRIVIAL(warning)
@ -37,6 +39,9 @@ struct Params
const int raft_layers_count;
std::string filament_type;
BrimType brim_type;
const float brim_width;
const std::pair<float,float> malformation_distance_factors = std::pair<float, float> { 0.4, 1.2 };
const float max_curled_height_factor = 10.0f;
@ -53,7 +58,7 @@ struct Params
// MPa * 1e^6 = (g*mm/s^2)/mm^2 = g/(mm*s^2); yield strength of the bed surface
double get_bed_adhesion_yield_strength() const {
if (raft_layers_count > 0) {
return get_support_spots_adhesion_strength();
return get_support_spots_adhesion_strength() * 2.0;
}
if (filament_type == "PLA") {