Skip to content

Commit

Permalink
Improved handling of excessive extrusion width values (too small
Browse files Browse the repository at this point in the history
or too big).
Fixes std: bad_alloc #2715
  • Loading branch information
bubnikv committed Aug 6, 2019
1 parent 29d9c65 commit 74e592c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 10 deletions.
20 changes: 15 additions & 5 deletions src/libslic3r/Flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,14 @@ float Flow::spacing() const
return this->width + BRIDGE_EXTRA_SPACING;
// rectangle with semicircles at the ends
float min_flow_spacing = this->width - this->height * (1. - 0.25 * PI);
return this->width - PERIMETER_LINE_OVERLAP_FACTOR * (this->width - min_flow_spacing);
float res = this->width - PERIMETER_LINE_OVERLAP_FACTOR * (this->width - min_flow_spacing);
#else
return float(this->bridge ? (this->width + BRIDGE_EXTRA_SPACING) : (this->width - this->height * (1. - 0.25 * PI)));
float res = float(this->bridge ? (this->width + BRIDGE_EXTRA_SPACING) : (this->width - this->height * (1. - 0.25 * PI)));
#endif
// assert(res > 0.f);
if (res <= 0.f)
throw std::runtime_error("Flow::spacing() produced negative spacing. Did you set some extrusion width too small?");
return res;
}

// This method returns the centerline spacing between an extrusion using this
Expand All @@ -89,20 +93,26 @@ float Flow::spacing(const Flow &other) const
{
assert(this->height == other.height);
assert(this->bridge == other.bridge);
return float(this->bridge ?
float res = float(this->bridge ?
0.5 * this->width + 0.5 * other.width + BRIDGE_EXTRA_SPACING :
0.5 * this->spacing() + 0.5 * other.spacing());
// assert(res > 0.f);
if (res <= 0.f)
throw std::runtime_error("Flow::spacing() produced negative spacing. Did you set some extrusion width too small?");
return res;
}

// This method returns extrusion volume per head move unit.
double Flow::mm3_per_mm() const
{
double res = this->bridge ?
float res = this->bridge ?
// Area of a circle with dmr of this->width.
(this->width * this->width) * 0.25 * PI :
// Rectangle with semicircles at the ends. ~ h (w - 0.215 h)
this->height * (this->width - this->height * (1. - 0.25 * PI));
assert(res > 0.);
//assert(res > 0.);
if (res <= 0.)
throw std::runtime_error("Flow::mm3_per_mm() produced negative flow. Did you set some extrusion width too small?");
return res;
}

Expand Down
33 changes: 31 additions & 2 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <limits>
#include <unordered_set>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
#include <boost/log/trivial.hpp>

//! macro used to mark string used at localization,
Expand Down Expand Up @@ -1168,7 +1169,7 @@ std::string Print::validate() const
bool has_custom_layering = false;
std::vector<std::vector<coordf_t>> layer_height_profiles;
for (const PrintObject *object : m_objects) {
has_custom_layering = ! object->model_object()->layer_config_ranges.empty() || ! object->model_object()->layer_height_profile.empty(); // #ys_FIXME_experiment
has_custom_layering = ! object->model_object()->layer_config_ranges.empty() || ! object->model_object()->layer_height_profile.empty();
if (has_custom_layering) {
layer_height_profiles.assign(m_objects.size(), std::vector<coordf_t>());
break;
Expand Down Expand Up @@ -1247,6 +1248,18 @@ std::string Print::validate() const
return L("One or more object were assigned an extruder that the printer does not have.");
#endif

auto validate_extrusion_width = [min_nozzle_diameter, max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool {
double extrusion_width_min = config.get_abs_value(opt_key, min_nozzle_diameter);
double extrusion_width_max = config.get_abs_value(opt_key, max_nozzle_diameter);
if (extrusion_width_min <= layer_height) {
err_msg = (boost::format(L("%1%=%2% mm is too low to be printable at a layer height %3% mm")) % opt_key % extrusion_width_min % layer_height).str();
return false;
} else if (extrusion_width_max >= max_nozzle_diameter * 2.) {
err_msg = (boost::format(L("Excessive %1%=%2% mm to be printable with a nozzle diameter %3% mm")) % opt_key % extrusion_width_max % max_nozzle_diameter).str();
return false;
}
return true;
};
for (PrintObject *object : m_objects) {
if (object->config().raft_layers > 0 || object->config().support_material.value) {
if ((object->config().support_material_extruder == 0 || object->config().support_material_interface_extruder == 0) && max_nozzle_diameter - min_nozzle_diameter > EPSILON) {
Expand Down Expand Up @@ -1290,8 +1303,24 @@ std::string Print::validate() const
return L("First layer height can't be greater than nozzle diameter");

// validate layer_height
if (object->config().layer_height.value > min_nozzle_diameter)
double layer_height = object->config().layer_height.value;
if (layer_height > min_nozzle_diameter)
return L("Layer height can't be greater than nozzle diameter");

// Validate extrusion widths.
for (const char *opt_key : { "extrusion_width", "support_material_extrusion_width" }) {
std::string err_msg;
if (! validate_extrusion_width(object->config(), opt_key, layer_height, err_msg))
return err_msg;
}
for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" }) {
for (size_t i = 0; i < object->region_volumes.size(); ++ i)
if (! object->region_volumes[i].empty()) {
std::string err_msg;
if (! validate_extrusion_width(this->get_region(i)->config(), opt_key, layer_height, err_msg))
return err_msg;
}
}
}
}

Expand Down
16 changes: 13 additions & 3 deletions src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,17 @@ void TabFilament::reload_config()
Tab::reload_config();
}

void TabFilament::update_volumetric_flow_preset_hints()
{
wxString text;
try {
text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle));
} catch (std::exception &ex) {
text = _(L("Volumetric flow hints not available\n\n")) + from_u8(ex.what());
}
m_volumetric_speed_description_line->SetText(text);
}

void TabFilament::update()
{
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
Expand All @@ -1767,8 +1778,7 @@ void TabFilament::update()

wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset()));
m_cooling_description_line->SetText(text);
text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle));
m_volumetric_speed_description_line->SetText(text);
this->update_volumetric_flow_preset_hints();
Layout();

bool cooling = m_config->opt_bool("cooling", 0);
Expand All @@ -1790,7 +1800,7 @@ void TabFilament::update()

void TabFilament::OnActivate()
{
m_volumetric_speed_description_line->SetText(from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)));
this->update_volumetric_flow_preset_hints();
Tab::OnActivate();
}

Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/Tab.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ class TabFilament : public Tab

void add_filament_overrides_page();
void update_filament_overrides_page();
void update_volumetric_flow_preset_hints();

std::map<std::string, wxCheckBox*> m_overrides_options;
public:
Expand Down

0 comments on commit 74e592c

Please sign in to comment.