diff --git a/src/libslic3r/Flow.cpp b/src/libslic3r/Flow.cpp index b367be0226..1678be999c 100644 --- a/src/libslic3r/Flow.cpp +++ b/src/libslic3r/Flow.cpp @@ -11,6 +11,12 @@ namespace Slic3r { +FlowErrorNegativeSpacing::FlowErrorNegativeSpacing() : + FlowError("Flow::spacing() produced negative spacing. Did you set some extrusion width too small?") {} + +FlowErrorNegativeFlow::FlowErrorNegativeFlow() : + FlowError("Flow::mm3_per_mm() produced negative flow. Did you set some extrusion width too small?") {} + // This static method returns a sane extrusion width default. float Flow::auto_extrusion_width(FlowRole role, float nozzle_diameter) { @@ -52,7 +58,7 @@ static inline FlowRole opt_key_to_flow_role(const std::string &opt_key) static inline void throw_on_missing_variable(const std::string &opt_key, const char *dependent_opt_key) { - throw std::runtime_error((boost::format(L("Cannot calculate extrusion width for %1%: Variable \"%2%\" not accessible.")) % opt_key % dependent_opt_key).str()); + throw FlowErrorMissingVariable((boost::format(L("Cannot calculate extrusion width for %1%: Variable \"%2%\" not accessible.")) % opt_key % dependent_opt_key).str()); } // Used to provide hints to the user on default extrusion width values, and to provide reasonable values to the PlaceholderParser. @@ -174,7 +180,7 @@ float Flow::spacing() const #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?"); + throw FlowErrorNegativeSpacing(); return res; } @@ -190,7 +196,7 @@ float Flow::spacing(const Flow &other) const 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?"); + throw FlowErrorNegativeSpacing(); return res; } @@ -204,7 +210,7 @@ double Flow::mm3_per_mm() const float(this->height * (this->width - this->height * (1. - 0.25 * PI))); //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?"); + throw FlowErrorNegativeFlow(); return res; } diff --git a/src/libslic3r/Flow.hpp b/src/libslic3r/Flow.hpp index aad189775f..7d6e35873d 100644 --- a/src/libslic3r/Flow.hpp +++ b/src/libslic3r/Flow.hpp @@ -27,6 +27,31 @@ enum FlowRole { frSupportMaterialInterface, }; +class FlowError : public std::invalid_argument +{ +public: + FlowError(const std::string& what_arg) : invalid_argument(what_arg) {} + FlowError(const char* what_arg) : invalid_argument(what_arg) {} +}; + +class FlowErrorNegativeSpacing : public FlowError +{ +public: + FlowErrorNegativeSpacing(); +}; + +class FlowErrorNegativeFlow : public FlowError +{ +public: + FlowErrorNegativeFlow(); +}; + +class FlowErrorMissingVariable : public FlowError +{ +public: + FlowErrorMissingVariable(const std::string& what_arg) : FlowError(what_arg) {} +}; + class Flow { public: diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index cd3554bc40..22fa09f6cc 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -262,12 +262,16 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre int num_lines = std::min(num_perimeters * 2, 10); out += (boost::format(_utf8(L("Recommended object thin wall thickness for layer height %.2f and"))) % layer_height).str() + " "; // Start with the width of two closely spaced - double width = external_perimeter_flow.width + external_perimeter_flow.spacing(); - for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) { - if (i > 2) - out += ", "; - out += (boost::format(_utf8(L("%d lines: %.2f mm"))) % i % width).str() + " "; - width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f); + try { + double width = external_perimeter_flow.width + external_perimeter_flow.spacing(); + for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) { + if (i > 2) + out += ", "; + out += (boost::format(_utf8(L("%d lines: %.2f mm"))) % i % width).str() + " "; + width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f); + } + } catch (const FlowErrorNegativeSpacing &) { + out = _utf8(L("Recommended object thin wall thickness: Not available due to excessively small extrusion width.")); } } return out;