Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::PresetHints Class Reference

#include <src/slic3r/GUI/PresetHints.hpp>

Static Public Member Functions

static std::string cooling_description (const Preset &preset)
 
static std::string maximum_volumetric_flow_description (const PresetBundle &preset_bundle)
 
static std::string recommended_thin_wall_thickness (const PresetBundle &preset_bundle)
 
static std::string top_bottom_shell_thickness_explanation (const PresetBundle &preset_bundle)
 

Detailed Description

Member Function Documentation

◆ cooling_description()

std::string Slic3r::PresetHints::cooling_description ( const Preset preset)
static
19{
20 std::string out;
21
22 bool cooling = preset.config.opt_bool("cooling", 0);
23 int fan_below_layer_time = preset.config.opt_int("fan_below_layer_time", 0);
24 int full_fan_speed_layer = preset.config.opt_int("full_fan_speed_layer", 0);
25
26 if (cooling) {
27 int slowdown_below_layer_time = preset.config.opt_int("slowdown_below_layer_time", 0);
28 int min_fan_speed = preset.config.opt_int("min_fan_speed", 0);
29 int max_fan_speed = preset.config.opt_int("max_fan_speed", 0);
30 int min_print_speed = int(preset.config.opt_float("min_print_speed", 0) + 0.5);
31
32 out += GUI::format(_L("If estimated layer time is below ~%1%s, "
33 "fan will run at %2%%% and print speed will be reduced "
34 "so that no less than %3%s are spent on that layer "
35 "(however, speed will never be reduced below %4%mm/s)."),
36 slowdown_below_layer_time, max_fan_speed, slowdown_below_layer_time, min_print_speed);
37 if (fan_below_layer_time > slowdown_below_layer_time) {
38 out += "\n";
39 if (min_fan_speed != max_fan_speed)
40 out += GUI::format(_L("If estimated layer time is greater, but still below ~%1%s, "
41 "fan will run at a proportionally decreasing speed between %2%%% and %3%%%."),
42 fan_below_layer_time, max_fan_speed, min_fan_speed);
43 else
44 out += GUI::format(_L("If estimated layer time is greater, but still below ~%1%s, "
45 "fan will run at %2%%%"),
46 fan_below_layer_time, min_fan_speed);
47 }
48 out += "\n";
49 }
50 if (preset.config.opt_bool("fan_always_on", 0)) {
51 int disable_fan_first_layers = preset.config.opt_int("disable_fan_first_layers", 0);
52 int min_fan_speed = preset.config.opt_int("min_fan_speed", 0);
53
54 if (full_fan_speed_layer > disable_fan_first_layers + 1)
55 out += GUI::format(_L("Fan speed will be ramped from zero at layer %1% to %2%%% at layer %3%."), disable_fan_first_layers, min_fan_speed, full_fan_speed_layer);
56 else {
57 out += GUI::format(cooling ? _L("During the other layers, fan will always run at %1%%%") : _L("Fan will always run at %1%%%"), min_fan_speed) + " ";
58 if (disable_fan_first_layers > 1)
59 out += GUI::format(_L("except for the first %1% layers."), disable_fan_first_layers);
60 else if (disable_fan_first_layers == 1)
61 out += GUI::format(_L("except for the first layer."));
62 }
63 } else
64 out += cooling ? _u8L("During the other layers, fan will be turned off.") : _u8L("Fan will be turned off.");
65
66 return out;
67}
#define _u8L(s)
macro used to mark string used at localization, return same string
Definition SLAPrint.cpp:29
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:56
#define _L(s)
Definition I18N.hpp:3

References _L, _u8L, Slic3r::Preset::config, Slic3r::GUI::format(), Slic3r::ConfigBase::opt_bool(), Slic3r::ConfigBase::opt_float(), and Slic3r::ConfigBase::opt_int().

+ Here is the call graph for this function:

◆ maximum_volumetric_flow_description()

std::string Slic3r::PresetHints::maximum_volumetric_flow_description ( const PresetBundle preset_bundle)
static
75{
76 // Find out, to which nozzle index is the current filament profile assigned.
77 int idx_extruder = 0;
78 int num_extruders = (int)preset_bundle.extruders_filaments.size();
79 for (; idx_extruder < num_extruders; ++ idx_extruder)
80 if (preset_bundle.extruders_filaments[idx_extruder].get_selected_preset_name() == preset_bundle.filaments.get_selected_preset_name())
81 break;
82 if (idx_extruder == num_extruders)
83 // The current filament preset is not active for any extruder.
84 idx_extruder = -1;
85
86 const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config;
87 const DynamicPrintConfig &filament_config = preset_bundle.filaments.get_edited_preset().config;
88 const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
89
90 // Current printer values.
91 float nozzle_diameter = (float)printer_config.opt_float("nozzle_diameter", idx_extruder);
92
93 // Print config values
94 double layer_height = print_config.opt_float("layer_height");
95 assert(! print_config.option<ConfigOptionFloatOrPercent>("first_layer_height")->percent);
96 double first_layer_height = print_config.opt_float("first_layer_height");
97 double support_material_speed = print_config.opt_float("support_material_speed");
98 double support_material_interface_speed = print_config.get_abs_value("support_material_interface_speed", support_material_speed);
99 double bridge_speed = print_config.opt_float("bridge_speed");
100 double bridge_flow_ratio = print_config.opt_float("bridge_flow_ratio");
101 double perimeter_speed = print_config.opt_float("perimeter_speed");
102 double external_perimeter_speed = print_config.get_abs_value("external_perimeter_speed", perimeter_speed);
103 // double gap_fill_speed = print_config.opt_bool("gap_fill_enabled") ? print_config.opt_float("gap_fill_speed") : 0.;
104 double infill_speed = print_config.opt_float("infill_speed");
105 double small_perimeter_speed = print_config.get_abs_value("small_perimeter_speed", perimeter_speed);
106 double solid_infill_speed = print_config.get_abs_value("solid_infill_speed", infill_speed);
107 double top_solid_infill_speed = print_config.get_abs_value("top_solid_infill_speed", solid_infill_speed);
108 // Maximum print speed when auto-speed is enabled by setting any of the above speed values to zero.
109 double max_print_speed = print_config.opt_float("max_print_speed");
110 // Maximum volumetric speed allowed for the print profile.
111 double max_volumetric_speed = print_config.opt_float("max_volumetric_speed");
112
113 const auto &extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("extrusion_width");
114 const auto &external_perimeter_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width");
115 const auto &first_layer_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("first_layer_extrusion_width");
116 const auto &infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("infill_extrusion_width");
117 const auto &perimeter_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("perimeter_extrusion_width");
118 const auto &solid_infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("solid_infill_extrusion_width");
119 const auto &support_material_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("support_material_extrusion_width");
120 const auto &top_infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("top_infill_extrusion_width");
121 const auto &first_layer_speed = *print_config.option<ConfigOptionFloatOrPercent>("first_layer_speed");
122
123 // Index of an extruder assigned to a feature. If set to 0, an active extruder will be used for a multi-material print.
124 // If different from idx_extruder, it will not be taken into account for this hint.
125 auto feature_extruder_active = [idx_extruder, num_extruders](int i) {
126 return i <= 0 || i > num_extruders || idx_extruder == -1 || idx_extruder == i - 1;
127 };
128 bool perimeter_extruder_active = feature_extruder_active(print_config.opt_int("perimeter_extruder"));
129 bool infill_extruder_active = feature_extruder_active(print_config.opt_int("infill_extruder"));
130 bool solid_infill_extruder_active = feature_extruder_active(print_config.opt_int("solid_infill_extruder"));
131 bool support_material_extruder_active = feature_extruder_active(print_config.opt_int("support_material_extruder"));
132 bool support_material_interface_extruder_active = feature_extruder_active(print_config.opt_int("support_material_interface_extruder"));
133
134 // Current filament values
135 double filament_diameter = filament_config.opt_float("filament_diameter", 0);
136 double filament_crossection = M_PI * 0.25 * filament_diameter * filament_diameter;
137 // double extrusion_multiplier = filament_config.opt_float("extrusion_multiplier", 0);
138 // The following value will be annotated by this hint, so it does not take part in the calculation.
139// double filament_max_volumetric_speed = filament_config.opt_float("filament_max_volumetric_speed", 0);
140
141 std::string out;
142 for (size_t idx_type = (first_layer_extrusion_width.value == 0) ? 1 : 0; idx_type < 3; ++ idx_type) {
143 // First test the maximum volumetric extrusion speed for non-bridging extrusions.
144 bool first_layer = idx_type == 0;
145 bool bridging = idx_type == 2;
146 const ConfigOptionFloatOrPercent *first_layer_extrusion_width_ptr = (first_layer && first_layer_extrusion_width.value > 0) ?
147 &first_layer_extrusion_width : nullptr;
148 const float lh = float(first_layer ? first_layer_height : layer_height);
149 double max_flow = 0.;
150 std::string max_flow_extrusion_type;
151 auto limit_by_first_layer_speed = [&first_layer_speed, first_layer](double speed_normal, double speed_max) {
152 if (first_layer && first_layer_speed.value > 0)
153 // Apply the first layer limit.
154 speed_normal = first_layer_speed.get_abs_value(speed_normal);
155 return (speed_normal > 0.) ? speed_normal : speed_max;
156 };
157 auto test_flow =
158 [first_layer_extrusion_width_ptr, extrusion_width, nozzle_diameter, lh, bridging, bridge_speed, bridge_flow_ratio, limit_by_first_layer_speed, max_print_speed, &max_flow, &max_flow_extrusion_type]
159 (FlowRole flow_role, const ConfigOptionFloatOrPercent &this_extrusion_width, double speed, const char *err_msg) {
160 Flow flow = bridging ?
161 Flow::new_from_config_width(flow_role, first_positive(first_layer_extrusion_width_ptr, this_extrusion_width, extrusion_width), nozzle_diameter, lh) :
162 Flow::bridging_flow(nozzle_diameter * bridge_flow_ratio, nozzle_diameter);
163 double volumetric_flow = flow.mm3_per_mm() * (bridging ? bridge_speed : limit_by_first_layer_speed(speed, max_print_speed));
164 if (max_flow < volumetric_flow) {
165 max_flow = volumetric_flow;
166 max_flow_extrusion_type = GUI::into_u8(_(err_msg));
167 }
168 };
169 if (perimeter_extruder_active) {
170 test_flow(frExternalPerimeter, external_perimeter_extrusion_width, std::max(external_perimeter_speed, small_perimeter_speed), L("external perimeters"));
171 test_flow(frPerimeter, perimeter_extrusion_width, std::max(perimeter_speed, small_perimeter_speed), L("perimeters"));
172 }
173 if (! bridging && infill_extruder_active)
174 test_flow(frInfill, infill_extrusion_width, infill_speed, L("infill"));
175 if (solid_infill_extruder_active) {
176 test_flow(frInfill, solid_infill_extrusion_width, solid_infill_speed, L("solid infill"));
177 if (! bridging)
178 test_flow(frInfill, top_infill_extrusion_width, top_solid_infill_speed, L("top solid infill"));
179 }
180 if (! bridging && support_material_extruder_active)
181 test_flow(frSupportMaterial, support_material_extrusion_width, support_material_speed, L("support"));
182 if (support_material_interface_extruder_active)
183 test_flow(frSupportMaterialInterface, support_material_extrusion_width, support_material_interface_speed, L("support interface"));
184 //FIXME handle gap_fill_speed
185 if (! out.empty())
186 out += "\n";
187 out += (first_layer ? _u8L("First layer volumetric") : (bridging ? _u8L("Bridging volumetric") : _u8L("Volumetric")));
188 out += " " + _u8L("flow rate is maximized") + " ";
189 bool limited_by_max_volumetric_speed = max_volumetric_speed > 0 && max_volumetric_speed < max_flow;
190 out += (limited_by_max_volumetric_speed ?
191 _u8L("by the print profile maximum") :
192 (_u8L("when printing")+ " " + max_flow_extrusion_type))
193 + " " + _u8L("with a volumetric rate")+ " ";
194 if (limited_by_max_volumetric_speed)
195 max_flow = max_volumetric_speed;
196
197 out += format(_u8L("%3.2f mm³/s at filament speed %3.2f mm/s."), max_flow, (max_flow / filament_crossection));
198 }
199
200 return out;
201}
#define M_PI
Definition ExtrusionSimulator.cpp:20
static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height)
Definition Flow.cpp:115
#define _(msgid)
Definition getopt.c:87
std::string into_u8(const wxString &str)
Definition GUI.cpp:442
small_perimeter_speed((ConfigOptionFloat, solid_infill_below_area))((ConfigOptionInt
filament_diameter((ConfigOptionFloats, filament_density))((ConfigOptionStrings
max_print_speed((ConfigOptionFloat, max_volumetric_speed))((ConfigOptionFloat
infill_extrusion_width((ConfigOptionInt, infill_every_layers))((ConfigOptionFloatOrPercent
layer_height((ConfigOptionInt, faded_layers))((ConfigOptionFloat
FlowRole
Definition Flow.hpp:16
@ frSupportMaterial
Definition Flow.hpp:22
@ frExternalPerimeter
Definition Flow.hpp:17
@ frPerimeter
Definition Flow.hpp:18
@ frSupportMaterialInterface
Definition Flow.hpp:23
@ frInfill
Definition Flow.hpp:19
bridge_speed((ConfigOptionEnum< InfillPattern >, top_fill_pattern))((ConfigOptionEnum< InfillPattern >
external_perimeter_speed((ConfigOptionBool, enable_dynamic_overhang_speeds))((ConfigOptionFloatOrPercent
top_solid_infill_speed((ConfigOptionBool, wipe_into_infill))) PRINT_CONFIG_CLASS_DEFINE(MachineEnvelopeConfig
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:44
perimeter_speed((ConfigOptionInt, perimeters))((ConfigOptionFloatOrPercent
static const ConfigOptionFloatOrPercent & first_positive(const ConfigOptionFloatOrPercent *v1, const ConfigOptionFloatOrPercent &v2, const ConfigOptionFloatOrPercent &v3)
Definition PresetHints.cpp:69
#define L(s)
Definition I18N.hpp:18

References _, _u8L, Slic3r::bridge_speed(), Slic3r::Flow::bridging_flow(), Slic3r::Preset::config, Slic3r::external_perimeter_speed(), Slic3r::PresetBundle::extruders_filaments, Slic3r::filament_diameter(), Slic3r::PresetBundle::filaments, Slic3r::first_positive(), Slic3r::format(), Slic3r::frExternalPerimeter, Slic3r::frInfill, Slic3r::frPerimeter, Slic3r::frSupportMaterial, Slic3r::frSupportMaterialInterface, Slic3r::ConfigBase::get_abs_value(), Slic3r::ConfigOptionFloatOrPercent::get_abs_value(), Slic3r::PresetCollection::get_edited_preset(), Slic3r::PresetCollection::get_selected_preset_name(), Slic3r::infill_extrusion_width(), Slic3r::GUI::into_u8(), L, Slic3r::layer_height(), M_PI, Slic3r::max_print_speed(), Slic3r::Flow::mm3_per_mm(), Slic3r::Flow::new_from_config_width(), Slic3r::ConfigBase::opt_float(), Slic3r::ConfigBase::opt_int(), Slic3r::ConfigBase::option(), Slic3r::ConfigOptionFloatOrPercent::percent, Slic3r::perimeter_speed(), Slic3r::PresetBundle::printers, Slic3r::PresetBundle::prints, Slic3r::small_perimeter_speed(), Slic3r::top_solid_infill_speed(), and Slic3r::ConfigOptionSingle< T >::value.

+ Here is the call graph for this function:

◆ recommended_thin_wall_thickness()

std::string Slic3r::PresetHints::recommended_thin_wall_thickness ( const PresetBundle preset_bundle)
static
204{
205 const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config;
206 const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
207
208 float layer_height = float(print_config.opt_float("layer_height"));
209 int num_perimeters = print_config.opt_int("perimeters");
210 bool thin_walls = print_config.opt_bool("thin_walls");
211 float nozzle_diameter = float(printer_config.opt_float("nozzle_diameter", 0));
212
213 std::string out;
214 if (layer_height <= 0.f) {
215 out += _u8L("Recommended object thin wall thickness: Not available due to invalid layer height.");
216 return out;
217 }
218
219 if (num_perimeters > 0) {
220 int num_lines = std::min(num_perimeters * 2, 10);
221 out += (boost::format(_u8L("Recommended object thin wall thickness for layer height %.2f and")) % layer_height).str() + " ";
222 // Start with the width of two closely spaced
223 try {
224 Flow external_perimeter_flow = Flow::new_from_config_width(
226 *print_config.opt<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width"),
227 nozzle_diameter, layer_height);
228 Flow perimeter_flow = Flow::new_from_config_width(
230 *print_config.opt<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"),
231 nozzle_diameter, layer_height);
232 double width = external_perimeter_flow.width() + external_perimeter_flow.spacing();
233 for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) {
234 if (i > 2)
235 out += ", ";
236 out += (boost::format(_u8L("%d lines: %.2f mm")) % i % width).str() + " ";
237 width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f);
238 }
239 } catch (const FlowErrorNegativeSpacing &) {
240 out = _u8L("Recommended object thin wall thickness: Not available due to excessively small extrusion width.");
241 }
242 }
243 return out;
244}
coord_t width(const BoundingBox &box)
Definition Arrange.cpp:539
thin_walls((ConfigOptionFloatOrPercent, top_infill_extrusion_width))((ConfigOptionInt

References _u8L, Slic3r::Preset::config, Slic3r::frExternalPerimeter, Slic3r::frPerimeter, Slic3r::PresetCollection::get_edited_preset(), Slic3r::layer_height(), Slic3r::Flow::new_from_config_width(), Slic3r::ConfigBase::opt(), Slic3r::ConfigBase::opt_bool(), Slic3r::ConfigBase::opt_float(), Slic3r::ConfigBase::opt_int(), Slic3r::PresetBundle::printers, Slic3r::PresetBundle::prints, Slic3r::Flow::spacing(), Slic3r::thin_walls(), and Slic3r::Flow::width().

Referenced by Slic3r::GUI::TabPrint::update_description_lines().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ top_bottom_shell_thickness_explanation()

std::string Slic3r::PresetHints::top_bottom_shell_thickness_explanation ( const PresetBundle preset_bundle)
static
251{
252 const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config;
253 const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
254
255 std::string out;
256
257 int top_solid_layers = print_config.opt_int("top_solid_layers");
258 int bottom_solid_layers = print_config.opt_int("bottom_solid_layers");
259 bool has_top_layers = top_solid_layers > 0;
260 bool has_bottom_layers = bottom_solid_layers > 0;
261 double top_solid_min_thickness = print_config.opt_float("top_solid_min_thickness");
262 double bottom_solid_min_thickness = print_config.opt_float("bottom_solid_min_thickness");
263 double layer_height = print_config.opt_float("layer_height");
264 bool variable_layer_height = printer_config.opt_bool("variable_layer_height");
265 //FIXME the following line takes into account the 1st extruder only.
266 double min_layer_height = variable_layer_height ? Slicing::min_layer_height_from_nozzle(printer_config, 1) : layer_height;
267
268 if (layer_height <= 0.f) {
269 out += _u8L("Top / bottom shell thickness hint: Not available due to invalid layer height.");
270 return out;
271 }
272
273 if (has_top_layers) {
274 double top_shell_thickness = top_solid_layers * layer_height;
275 if (top_shell_thickness < top_solid_min_thickness) {
276 // top_solid_min_shell_thickness triggers even in case of normal layer height. Round the top_shell_thickness up
277 // to an integer multiply of layer_height.
278 double n = ceil(top_solid_min_thickness / layer_height);
279 top_shell_thickness = n * layer_height;
280 }
281 double top_shell_thickness_minimum = std::max(top_solid_min_thickness, top_solid_layers * min_layer_height);
282 out += (boost::format(_u8L("Top shell is %1% mm thick for layer height %2% mm.")) % top_shell_thickness % layer_height).str();
283 if (variable_layer_height && top_shell_thickness_minimum < top_shell_thickness) {
284 out += " ";
285 out += (boost::format(_u8L("Minimum top shell thickness is %1% mm.")) % top_shell_thickness_minimum).str();
286 }
287 } else
288 out += _u8L("Top is open.");
289
290 out += "\n";
291
292 if (has_bottom_layers) {
293 double bottom_shell_thickness = bottom_solid_layers * layer_height;
294 if (bottom_shell_thickness < bottom_solid_min_thickness) {
295 // bottom_solid_min_shell_thickness triggers even in case of normal layer height. Round the bottom_shell_thickness up
296 // to an integer multiply of layer_height.
298 bottom_shell_thickness = n * layer_height;
299 }
300 double bottom_shell_thickness_minimum = std::max(bottom_solid_min_thickness, bottom_solid_layers * min_layer_height);
301 out += (boost::format(_u8L("Bottom shell is %1% mm thick for layer height %2% mm.")) % bottom_shell_thickness % layer_height).str();
302 if (variable_layer_height && bottom_shell_thickness_minimum < bottom_shell_thickness) {
303 out += " ";
304 out += (boost::format(_u8L("Minimum bottom shell thickness is %1% mm.")) % bottom_shell_thickness_minimum).str();
305 }
306 } else
307 out += _u8L("Bottom is open.");
308
309 return out;
310}
EIGEN_DEVICE_FUNC const CeilReturnType ceil() const
Definition ArrayCwiseUnaryOps.h:402
coordf_t min_layer_height_from_nozzle(const DynamicPrintConfig &print_config, int idx_nozzle)
Definition Slicing.cpp:45
top_solid_layers((ConfigOptionFloat, top_solid_min_thickness))((ConfigOptionFloatOrPercent
variable_layer_height((ConfigOptionFloat, cooling_tube_retraction))((ConfigOptionFloat
bottom_solid_min_thickness((ConfigOptionFloat, bridge_flow_ratio))((ConfigOptionFloat

References _u8L, Slic3r::bottom_solid_min_thickness(), ceil(), Slic3r::Preset::config, Slic3r::PresetCollection::get_edited_preset(), Slic3r::layer_height(), Slic3r::Slicing::min_layer_height_from_nozzle(), Slic3r::ConfigBase::opt_bool(), Slic3r::ConfigBase::opt_float(), Slic3r::ConfigBase::opt_int(), Slic3r::PresetBundle::printers, Slic3r::PresetBundle::prints, Slic3r::top_solid_layers(), and Slic3r::variable_layer_height().

Referenced by Slic3r::GUI::TabPrint::update_description_lines().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

The documentation for this class was generated from the following files: