OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::ConfigManipulation Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/ConfigManipulation.hpp>

Collaboration diagram for Slic3r::GUI::ConfigManipulation:

Public Member Functions

 ConfigManipulation (std::function< void()> load_config, std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_field, std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_line, std::function< void(const std::string &, const boost::any &)> cb_value_change, const DynamicPrintConfig *local_config=nullptr, wxWindow *msg_dlg_parent=nullptr, std::function< void(const std::string &, const wxString &, int opt_index)> cb_set_option_label=nullptr)
 ConfigManipulation ()
 ~ConfigManipulation ()
bool is_applying () const
void apply (DynamicPrintConfig *config, DynamicPrintConfig *new_config)
t_config_option_keys const & applying_keys () const
void toggle_field (const std::string &field_key, const bool toggle, int opt_index=-1)
void toggle_line (const std::string &field_key, const bool toggle, int opt_index=-1)
void set_option_label (const std::string &field_key, const wxString &label, int opt_index=-1)
void update_print_fff_config (DynamicPrintConfig *config, const bool is_global_config=false, const bool is_plate_config=false)
void toggle_print_fff_options (DynamicPrintConfig *config, int variant_index, const bool is_global_config=false)
void apply_null_fff_config (DynamicPrintConfig *config, std::vector< std::string > const &keys, std::map< ObjectBase *, ModelConfig * > const &configs)
void check_nozzle_recommended_temperature_range (DynamicPrintConfig *config, unsigned int variant_index)
void check_nozzle_temperature_range (DynamicPrintConfig *config, unsigned int variant_index)
void check_nozzle_temperature_initial_layer_range (DynamicPrintConfig *config, unsigned int variant_index)
void check_adaptive_pressure_advance_model (DynamicPrintConfig *config)
void check_filament_max_volumetric_speed (DynamicPrintConfig *config)
void check_filament_ironing_spacing (DynamicPrintConfig *config)
void check_chamber_temperature (DynamicPrintConfig *config)
void check_chamber_minimal_temperature (DynamicPrintConfig *config)
bool check_layer_height (DynamicPrintConfig *config)
bool layer_height_out_of_range_dialog (DynamicPrintConfig *config, double clamp_to)
void layer_height_limits (double &min_layer_height, double &max_layer_height) const
void set_is_BBL_Printer (bool is_bbl_printer)
bool get_is_BBL_Printer ()
void update_print_sla_config (DynamicPrintConfig *config, const bool is_global_config=false)
void toggle_print_sla_options (DynamicPrintConfig *config)
bool is_initialized_support_material_overhangs_queried ()
void initialize_support_material_overhangs_queried (bool queried)
int show_spiral_mode_settings_dialog (bool is_object_config=false)

Private Member Functions

bool get_temperature_range (DynamicPrintConfig *config, int &range_low, int &range_high, unsigned int variant_index)

Private Attributes

bool is_msg_dlg_already_exist { false }
bool m_is_initialized_support_material_overhangs_queried { false }
bool m_support_material_overhangs_queried { false }
bool is_BBL_Printer {false}
std::function< void()> load_config = nullptr
std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_field = nullptr
std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_line = nullptr
std::function< void(const std::string &, const wxString &, int opt_index)> cb_set_option_label = nullptr
std::function< void(const std::string &, const boost::any &)> cb_value_change = nullptr
const DynamicPrintConfig * local_config = nullptr
wxWindow * m_msg_dlg_parent {nullptr}
t_config_option_keys m_applying_keys

Detailed Description

Constructor & Destructor Documentation

◆ ConfigManipulation() [1/2]

Slic3r::GUI::ConfigManipulation::ConfigManipulation ( std::function< void()> load_config,
std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_field,
std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_line,
std::function< void(const std::string &, const boost::any &)> cb_value_change,
const DynamicPrintConfig * local_config = nullptr,
wxWindow * msg_dlg_parent = nullptr,
std::function< void(const std::string &, const wxString &, int opt_index)> cb_set_option_label = nullptr )
inline
59 :
65 m_msg_dlg_parent(msg_dlg_parent),
std::function< void(const std::string &, const wxString &, int opt_index)> cb_set_option_label
Definition ConfigManipulation.hpp:41
std::function< void()> load_config
Definition ConfigManipulation.hpp:38
wxWindow * m_msg_dlg_parent
Definition ConfigManipulation.hpp:47
std::function< void(const std::string &, const boost::any &)> cb_value_change
Definition ConfigManipulation.hpp:43
std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_field
Definition ConfigManipulation.hpp:39
const DynamicPrintConfig * local_config
Definition ConfigManipulation.hpp:45
std::function< void(const std::string &, bool toggle, int opt_index)> cb_toggle_line
Definition ConfigManipulation.hpp:40

References cb_set_option_label, cb_toggle_field, cb_toggle_line, cb_value_change, load_config, local_config, and m_msg_dlg_parent.

◆ ConfigManipulation() [2/2]

Slic3r::GUI::ConfigManipulation::ConfigManipulation ( )
inline
67{}

◆ ~ConfigManipulation()

Slic3r::GUI::ConfigManipulation::~ConfigManipulation ( )
inline
69 {
70 load_config = nullptr;
71 cb_toggle_field = nullptr;
72 cb_toggle_line = nullptr;
73 cb_set_option_label = nullptr;
74 cb_value_change = nullptr;
75 }

References cb_set_option_label, cb_toggle_field, cb_toggle_line, cb_value_change, and load_config.

Member Function Documentation

◆ apply()

void Slic3r::GUI::ConfigManipulation::apply ( DynamicPrintConfig * config,
DynamicPrintConfig * new_config )
47{
48 bool modified = false;
49 m_applying_keys = config->diff(*new_config);
50 for (auto opt_key : m_applying_keys) {
51 config->set_key_value(opt_key, new_config->option(opt_key)->clone());
52 modified = true;
53 }
54 if (modified && load_config != nullptr)
56 m_applying_keys.clear();
57}
t_config_option_keys m_applying_keys
Definition ConfigManipulation.hpp:49

References Slic3r::ConfigOption::clone(), Slic3r::DynamicConfig::diff(), load_config, m_applying_keys, Slic3r::ConfigBase::option(), and Slic3r::DynamicConfig::set_key_value().

Referenced by check_chamber_minimal_temperature(), check_filament_ironing_spacing(), check_filament_max_volumetric_speed(), check_layer_height(), layer_height_out_of_range_dialog(), toggle_print_fff_options(), update_print_fff_config(), and update_print_sla_config().

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

◆ apply_null_fff_config()

void Slic3r::GUI::ConfigManipulation::apply_null_fff_config ( DynamicPrintConfig * config,
std::vector< std::string > const & keys,
std::map< ObjectBase *, ModelConfig * > const & configs )
750{
751 for (auto &k : keys) {
752 if (k == "independent_support_layer_height" || k == "enable_support" || k == "detect_thin_wall")
753 config->set_key_value(k, new ConfigOptionBool(true));
754 else if (k == "wall_loops")
755 config->set_key_value(k, new ConfigOptionInt(0));
756 else if (k == "top_shell_layers" || k == "enforce_support_layers")
757 config->set_key_value(k, new ConfigOptionInt(1));
758 else if (k == "sparse_infill_density") {
759 double v = config->option<ConfigOptionPercent>(k)->value;
760 for (auto &c : configs) {
761 auto o = c.second->get().option<ConfigOptionPercent>(k);
762 if (o && o->value > v) v = o->value;
763 }
764 config->set_key_value(k, new ConfigOptionPercent(v)); // sparse_infill_pattern
765 }
766 else if (k == "detect_overhang_wall")
767 config->set_key_value(k, new ConfigOptionBool(false));
768 else if (k == "sparse_infill_pattern")
769 config->set_key_value(k, new ConfigOptionEnum<InfillPattern>(ipGrid));
770 }
771}
@ ipGrid
Definition PrintConfig.hpp:129

References Slic3r::ipGrid, Slic3r::ConfigBase::option(), Slic3r::DynamicConfig::set_key_value(), and Slic3r::ConfigOptionSingle< T >::value.

Here is the call graph for this function:

◆ applying_keys()

t_config_option_keys const & Slic3r::GUI::ConfigManipulation::applying_keys ( ) const
62{
63 return m_applying_keys;
64}

References m_applying_keys.

◆ check_adaptive_pressure_advance_model()

void Slic3r::GUI::ConfigManipulation::check_adaptive_pressure_advance_model ( DynamicPrintConfig * config)
178{
179 if (is_msg_dlg_already_exist || !config->has("adaptive_pressure_advance_model"))
180 return;
181
182 const auto* model = config->option<ConfigOptionStrings>("adaptive_pressure_advance_model");
183 if (model == nullptr)
184 return;
185
186 // Each extruder variant holds its own model.
187 std::string error;
188 for (const std::string& variant_model : model->values) {
190 if (!error.empty())
191 break;
192 }
193 if (!error.empty()) {
194 wxString msg_text = _L("Adaptive Pressure Advance model validation failed:\n");
195 msg_text += from_u8(error);
196 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
198 dialog.ShowModal();
200 }
201}
#define _L(s)
Definition OBJ.cpp:34
static std::string validate_adaptive_pa_model(const std::string &model_str)
Validates an adaptive pressure advance model string.
Definition AdaptivePAProcessor.cpp:303
bool is_msg_dlg_already_exist
Definition ConfigManipulation.hpp:32
wxString from_u8(const std::string &str)
Definition GUI.cpp:544

References _L, Slic3r::GUI::from_u8(), Slic3r::ConfigOptionResolver::has(), is_msg_dlg_already_exist, m_msg_dlg_parent, Slic3r::ConfigBase::option(), Slic3r::GUI::DPIAware< P >::ShowModal(), and Slic3r::AdaptivePAProcessor::validate_adaptive_pa_model().

Here is the call graph for this function:

◆ check_chamber_minimal_temperature()

void Slic3r::GUI::ConfigManipulation::check_chamber_minimal_temperature ( DynamicPrintConfig * config)
267{
268 // Orca: the minimal chamber temperature is a "start printing" threshold that is passed to the
269 // print start macro. It must not exceed the target chamber temperature, otherwise the macro
270 // could wait forever for a temperature the heater is never asked to reach.
271 if (config->has("chamber_minimal_temperature") && config->has("chamber_temperature")) {
272 const int chamber_min_temp = config->option<ConfigOptionInts>("chamber_minimal_temperature")->get_at(0);
273 const int chamber_target_temp = config->option<ConfigOptionInts>("chamber_temperature")->get_at(0);
274 if (chamber_min_temp > chamber_target_temp) {
275 wxString msg_text = wxString::Format(_L("The minimal chamber temperature (%d℃) is higher than the target chamber temperature (%d℃). "
276 "The minimal value is the threshold at which printing starts while the chamber keeps heating toward the target, "
277 "so it should not exceed it. It will be clamped to the target."),
278 chamber_min_temp, chamber_target_temp);
279 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
280 DynamicPrintConfig new_conf = *config;
282 dialog.ShowModal();
283 new_conf.set_key_value("chamber_minimal_temperature", new ConfigOptionInts({chamber_target_temp}));
284 apply(config, &new_conf);
286 }
287 }
288}
void apply(DynamicPrintConfig *config, DynamicPrintConfig *new_config)
Definition ConfigManipulation.cpp:46
ConfigOptionIntsTempl< false > ConfigOptionInts
Definition Config.hpp:1154

References _L, apply(), Slic3r::ConfigOptionResolver::has(), is_msg_dlg_already_exist, m_msg_dlg_parent, Slic3r::ConfigBase::option(), Slic3r::DynamicConfig::set_key_value(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ check_chamber_temperature()

void Slic3r::GUI::ConfigManipulation::check_chamber_temperature ( DynamicPrintConfig * config)
249{
250 bool support_chamber_temp_control=GUI::wxGetApp().preset_bundle->printers.get_selected_preset().config.opt_bool("support_chamber_temp_control");
251 if (support_chamber_temp_control&&config->has("chamber_temperature")) {
252 std::string filament_type = config->option<ConfigOptionStrings>("filament_type")->get_at(0);
253 int chamber_min_temp, chamber_max_temp;
254 if (MaterialType::get_chamber_temperature_range(filament_type, chamber_min_temp, chamber_max_temp)) {
255 if (chamber_max_temp < config->option<ConfigOptionInts>("chamber_temperature")->get_at(0)) {
256 wxString msg_text = wxString::Format(_L("Current chamber temperature is higher than the material\'s safe temperature; this may result in material softening and nozzle clogs. The maximum safe temperature for the material is %d"), chamber_max_temp);
257 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
259 dialog.ShowModal();
261 }
262 }
263 }
264}
static bool get_chamber_temperature_range(const std::string &type, int &chamber_min_temp, int &chamber_max_temp)
Definition MaterialType.cpp:122
zaa_minimize_perimeter_height filament_type((ConfigOptionBools, filament_soluble))((ConfigOptionStrings
zaa_minimize_perimeter_height support_chamber_temp_control((ConfigOptionEnumsGeneric, extruder_type))((ConfigOptionEnumsGeneric

References _L, Slic3r::filament_type(), Slic3r::MaterialType::get_chamber_temperature_range(), Slic3r::ConfigOptionResolver::has(), is_msg_dlg_already_exist, m_msg_dlg_parent, Slic3r::ConfigBase::option(), Slic3r::GUI::DPIAware< P >::ShowModal(), and Slic3r::support_chamber_temp_control().

Here is the call graph for this function:

◆ check_filament_ironing_spacing()

void Slic3r::GUI::ConfigManipulation::check_filament_ironing_spacing ( DynamicPrintConfig * config)
225{
226 const auto *opt = config->option<ConfigOptionFloatsNullable>("filament_ironing_spacing");
227 if (opt == nullptr)
228 return;
229 std::vector<double> values = opt->values;
230 bool reset = false;
231 for (size_t i = 0; i < values.size(); ++i)
232 if (!opt->is_nil(i) && values[i] < IRONING_SPACING_MIN) {
233 values[i] = 0.1;
234 reset = true;
235 }
236 if (!reset)
237 return;
238 const wxString msg_text = _(L("Ironing spacing too small\nIt has been reset to 0.1"));
239 MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
240 DynamicPrintConfig new_conf = *config;
242 dialog.ShowModal();
243 new_conf.set_key_value("filament_ironing_spacing", new ConfigOptionFloatsNullable(values));
244 apply(config, &new_conf);
246}
#define _(s)
Definition 3mf.cpp:306
#define L(s)
Definition ExtrusionEntity.cpp:25
std::vector< double > values
Definition Config.hpp:418
ConfigOptionFloatsTempl< true > ConfigOptionFloatsNullable
Definition Config.hpp:1016
constexpr double IRONING_SPACING_MIN
Definition PrintConfig.hpp:212

References _, apply(), Slic3r::IRONING_SPACING_MIN, is_msg_dlg_already_exist, L, Slic3r::ConfigBase::option(), Slic3r::DynamicConfig::set_key_value(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ check_filament_max_volumetric_speed()

void Slic3r::GUI::ConfigManipulation::check_filament_max_volumetric_speed ( DynamicPrintConfig * config)
205{
206 //if (is_msg_dlg_already_exist) return;
207 //float max_volumetric_speed = config->opt_float("filament_max_volumetric_speed");
208
209 float max_volumetric_speed = config->has("filament_max_volumetric_speed") ? config->opt_float("filament_max_volumetric_speed", (float) 0.5) : 0.5;
210 // BBS: limite the min max_volumetric_speed
211 if (max_volumetric_speed < 0.5) {
212 const wxString msg_text = _(L("Too small max volumetric speed.\nValue was reset to 0.5"));
213 MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
214 DynamicPrintConfig new_conf = *config;
216 dialog.ShowModal();
217 new_conf.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats({0.5}));
218 apply(config, &new_conf);
220 }
221
222}
ConfigOptionFloatsTempl< false > ConfigOptionFloats
Definition Config.hpp:1015

References _, apply(), Slic3r::ConfigOptionResolver::has(), is_msg_dlg_already_exist, L, Slic3r::DynamicConfig::opt_float(), Slic3r::DynamicConfig::set_key_value(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ check_layer_height()

bool Slic3r::GUI::ConfigManipulation::check_layer_height ( DynamicPrintConfig * config)
300{
301 double min_layer_height = 0., max_layer_height = 0.;
302 layer_height_limits(min_layer_height, max_layer_height);
303 const double layer_height = config->opt_float("layer_height");
304
305 if (min_layer_height > EPSILON && layer_height < EPSILON) {
306 const wxString msg_text = wxString::Format(_L("Layer height is too small. It will be set to the minimum (%g mm)."), min_layer_height);
307 MessageDialog dialog(wxGetApp().plater(), msg_text, "", wxICON_WARNING | wxOK);
308 dialog.SetButtonLabel(wxID_OK, _L("OK"));
310 dialog.ShowModal();
312 DynamicPrintConfig new_conf = *config;
313 new_conf.set_key_value("layer_height", new ConfigOptionFloat(min_layer_height));
314 apply(config, &new_conf);
315 return true;
316 }
317 if (max_layer_height > EPSILON && layer_height > max_layer_height + EPSILON)
318 return layer_height_out_of_range_dialog(config, max_layer_height);
319 if (min_layer_height > EPSILON && layer_height < min_layer_height - EPSILON)
320 return layer_height_out_of_range_dialog(config, min_layer_height);
321 return false;
322}
#define EPSILON
Definition ColorUtils.cpp:64
void layer_height_limits(double &min_layer_height, double &max_layer_height) const
Definition ConfigManipulation.cpp:290
bool layer_height_out_of_range_dialog(DynamicPrintConfig *config, double clamp_to)
Definition ConfigManipulation.cpp:324
static std::string layer_height
Definition Tab.cpp:4294
static Plater * plater()
Definition GUI_Factories.cpp:400
zaa_minimize_perimeter_height ConfigOptionFloat
Definition PrintConfig.hpp:1954

References _L, apply(), Slic3r::ConfigOptionFloat, EPSILON, is_msg_dlg_already_exist, Slic3r::GUI::layer_height, layer_height_limits(), layer_height_out_of_range_dialog(), Slic3r::DynamicConfig::opt_float(), Slic3r::GUI::plater(), Slic3r::DynamicConfig::set_key_value(), Slic3r::GUI::MsgDialog::SetButtonLabel(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by Slic3r::GUI::ObjectSettings::update_config_values(), and Slic3r::GUI::ObjectTableSettings::update_config_values().

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

◆ check_nozzle_recommended_temperature_range()

void Slic3r::GUI::ConfigManipulation::check_nozzle_recommended_temperature_range ( DynamicPrintConfig * config,
unsigned int variant_index )
90 {
92 return;
93
94 int temperature_range_low, temperature_range_high;
95 if (!get_temperature_range(config, temperature_range_low, temperature_range_high, variant_index)) return;
96
97 // Get the selected filament type
98 std::string filament_type = "";
99 if (config->has("filament_type") && config->option<ConfigOptionStrings>("filament_type")->values.size() > 0) {
100 filament_type = config->option<ConfigOptionStrings>("filament_type")->values[0];
101 }
102
103 int min_recommended_temp = 190;
104 int max_recommended_temp = 300;
105
106 if (!MaterialType::get_temperature_range(filament_type, min_recommended_temp, max_recommended_temp)){
107 filament_type = "Unknown";
108 }
109
110 wxString msg_text;
111 bool need_check = false;
112 if (temperature_range_low < min_recommended_temp) {
113 msg_text += wxString::Format(_L("A minimum temperature above %d\u2103 is recommended for %s.\n"),
114 min_recommended_temp, filament_type);
115 need_check = true;
116 }
117 if (temperature_range_high > max_recommended_temp) {
118 msg_text += wxString::Format(_L("A maximum temperature below %d\u2103 is recommended for %s.\n"),
119 max_recommended_temp, filament_type);
120 need_check = true;
121 }
122 if (temperature_range_low > temperature_range_high) {
123 msg_text += _L("The recommended minimum temperature cannot be higher than the recommended maximum temperature.\n");
124 need_check = true;
125 }
126 if (need_check) {
127 msg_text += _L("Please check.\n");
128 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
130 dialog.ShowModal();
132 }
133}
bool get_temperature_range(DynamicPrintConfig *config, int &range_low, int &range_high, unsigned int variant_index)
Definition ConfigManipulation.cpp:1425
static bool get_temperature_range(const std::string &type, int &min_temp, int &max_temp)
Definition MaterialType.cpp:108

References _L, Slic3r::filament_type(), get_temperature_range(), Slic3r::MaterialType::get_temperature_range(), Slic3r::ConfigOptionResolver::has(), is_msg_dlg_already_exist, m_msg_dlg_parent, Slic3r::ConfigBase::option(), Slic3r::GUI::DPIAware< P >::ShowModal(), and Slic3r::ConfigOptionVector< T >::values.

Here is the call graph for this function:

◆ check_nozzle_temperature_initial_layer_range()

void Slic3r::GUI::ConfigManipulation::check_nozzle_temperature_initial_layer_range ( DynamicPrintConfig * config,
unsigned int variant_index )
156{
158 return;
159
160 int temperature_range_low, temperature_range_high;
161 if (!get_temperature_range(config, temperature_range_low, temperature_range_high, variant_index)) return;
162
163 if (config->has("nozzle_temperature_initial_layer")) {
164 if (config->opt_int("nozzle_temperature_initial_layer", variant_index) < temperature_range_low ||
165 config->opt_int("nozzle_temperature_initial_layer", variant_index) > temperature_range_high)
166 {
167 wxString msg_text = _(L("The nozzle may become clogged when the temperature is out of the recommended range.\nPlease make sure whether to use this temperature to print.\n\n"));
168 msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high);
169 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
171 dialog.ShowModal();
173 }
174 }
175}

References _, _L, get_temperature_range(), Slic3r::ConfigOptionResolver::has(), is_msg_dlg_already_exist, L, m_msg_dlg_parent, Slic3r::DynamicConfig::opt_int(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ check_nozzle_temperature_range()

void Slic3r::GUI::ConfigManipulation::check_nozzle_temperature_range ( DynamicPrintConfig * config,
unsigned int variant_index )
136{
138 return;
139
140 int temperature_range_low, temperature_range_high;
141 if (!get_temperature_range(config, temperature_range_low, temperature_range_high, variant_index)) return;
142
143 if (config->has("nozzle_temperature")) {
144 if (config->opt_int("nozzle_temperature", variant_index) < temperature_range_low || config->opt_int("nozzle_temperature", variant_index) > temperature_range_high) {
145 wxString msg_text = _(L("The nozzle may become clogged when the temperature is out of the recommended range.\nPlease make sure whether to use this temperature to print.\n\n"));
146 msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high);
147 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
149 dialog.ShowModal();
151 }
152 }
153}

References _, _L, get_temperature_range(), Slic3r::ConfigOptionResolver::has(), is_msg_dlg_already_exist, L, m_msg_dlg_parent, Slic3r::DynamicConfig::opt_int(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ get_is_BBL_Printer()

bool Slic3r::GUI::ConfigManipulation::get_is_BBL_Printer ( )
inline
105{ return is_BBL_Printer; };
bool is_BBL_Printer
Definition ConfigManipulation.hpp:35

References is_BBL_Printer.

◆ get_temperature_range()

bool Slic3r::GUI::ConfigManipulation::get_temperature_range ( DynamicPrintConfig * config,
int & range_low,
int & range_high,
unsigned int variant_index )
private
1426{
1427 bool range_low_exist = false, range_high_exist = false;
1428 if (config->has("nozzle_temperature_range_low")) {
1429 range_low = config->opt_int("nozzle_temperature_range_low", variant_index);
1430 range_low_exist = true;
1431 }
1432 if (config->has("nozzle_temperature_range_high")) {
1433 range_high = config->opt_int("nozzle_temperature_range_high", variant_index);
1434 range_high_exist = true;
1435 }
1436 return range_low_exist && range_high_exist;
1437}

References Slic3r::ConfigOptionResolver::has(), and Slic3r::DynamicConfig::opt_int().

Referenced by check_nozzle_recommended_temperature_range(), check_nozzle_temperature_initial_layer_range(), and check_nozzle_temperature_range().

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

◆ initialize_support_material_overhangs_queried()

void Slic3r::GUI::ConfigManipulation::initialize_support_material_overhangs_queried ( bool queried)
inline
112 {
115 }
bool m_is_initialized_support_material_overhangs_queried
Definition ConfigManipulation.hpp:33
bool m_support_material_overhangs_queried
Definition ConfigManipulation.hpp:34

References m_is_initialized_support_material_overhangs_queried, and m_support_material_overhangs_queried.

◆ is_applying()

bool Slic3r::GUI::ConfigManipulation::is_applying ( ) const

◆ is_initialized_support_material_overhangs_queried()

bool Slic3r::GUI::ConfigManipulation::is_initialized_support_material_overhangs_queried ( )
inline

◆ layer_height_limits()

void Slic3r::GUI::ConfigManipulation::layer_height_limits ( double & min_layer_height,
double & max_layer_height ) const
291{
292 const DynamicPrintConfig& printer_config = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config;
293 const std::vector<double>& min_limits = printer_config.option<ConfigOptionFloats>("min_layer_height")->values;
294 const std::vector<double>& max_limits = printer_config.option<ConfigOptionFloats>("max_layer_height")->values;
295 min_layer_height = *std::min_element(min_limits.begin(), min_limits.end());
296 max_layer_height = *std::max_element(max_limits.begin(), max_limits.end());
297}
ConfigOption * option(const t_config_option_key &opt_key, bool create=false)
Definition Config.hpp:2768
static DynamicPrintConfig & printer_config()
Definition GUI_ObjectList.cpp:131

References Slic3r::GUI::printer_config().

Referenced by check_layer_height().

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

◆ layer_height_out_of_range_dialog()

bool Slic3r::GUI::ConfigManipulation::layer_height_out_of_range_dialog ( DynamicPrintConfig * config,
double clamp_to )
325{
326 wxString msg_text = _(L("Layer height is outside the limits set in Printer Settings -> Extruder -> Layer height limits, "
327 "this may cause printing quality issues."));
328 msg_text += "\n\n" + wxString::Format(_L("Adjust it to the limit (%g mm) automatically?"), clamp_to);
329 MessageDialog dialog(wxGetApp().plater(), msg_text, "", wxICON_WARNING | wxYES | wxNO);
330 dialog.SetButtonLabel(wxID_YES, _L("Adjust"));
331 dialog.SetButtonLabel(wxID_NO, _L("Ignore"));
333 const bool adjust = dialog.ShowModal() == wxID_YES;
334 if (adjust) {
335 DynamicPrintConfig new_conf = *config;
336 new_conf.set_key_value("layer_height", new ConfigOptionFloat(clamp_to));
337 apply(config, &new_conf);
338 }
340 return adjust;
341}

References _, _L, apply(), Slic3r::ConfigOptionFloat, is_msg_dlg_already_exist, L, Slic3r::GUI::plater(), Slic3r::DynamicConfig::set_key_value(), Slic3r::GUI::MsgDialog::SetButtonLabel(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by check_layer_height().

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

◆ set_is_BBL_Printer()

void Slic3r::GUI::ConfigManipulation::set_is_BBL_Printer ( bool is_bbl_printer)
inline
104{ is_BBL_Printer = is_bbl_printer; };

References is_BBL_Printer.

Referenced by Slic3r::GUI::ObjectSettings::update_config_values(), Slic3r::GUI::ObjectTableSettings::update_config_values(), and Slic3r::GUI::ObjectTableSettings::update_settings_list().

Here is the caller graph for this function:

◆ set_option_label()

void Slic3r::GUI::ConfigManipulation::set_option_label ( const std::string & field_key,
const wxString & label,
int opt_index = -1 )
85{
87 cb_set_option_label(opt_key, label, opt_index);
88}

References cb_set_option_label.

Referenced by toggle_print_fff_options().

Here is the caller graph for this function:

◆ show_spiral_mode_settings_dialog()

int Slic3r::GUI::ConfigManipulation::show_spiral_mode_settings_dialog ( bool is_object_config = false)
1406{
1407 wxString msg_text = _(L("Spiral mode only works when wall loops is 1, support is disabled, clumping detection by probing is disabled, top shell layers is 0, sparse infill density is 0 and timelapse type is traditional."));
1408 auto printer_structure_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure");
1409 if (printer_structure_opt && printer_structure_opt->value == PrinterStructure::psI3) {
1410 msg_text += _(L(" But machines with I3 structure will not generate timelapse videos."));
1411 }
1412 if (!is_object_config)
1413 msg_text += "\n\n" + _(L("Change these settings automatically\?\nYes - Change these settings and enable spiral/vase mode automatically\nNo - Cancel enabling spiral mode"));
1414
1415 MessageDialog dialog(wxGetApp().plater(), msg_text, "",
1416 wxICON_WARNING | (!is_object_config ? wxYES | wxNO : wxOK));
1418 auto answer = dialog.ShowModal();
1420 if (is_object_config)
1421 answer = wxID_YES;
1422 return answer;
1423}
@ psI3
Definition PrintConfig.hpp:560

References _, is_msg_dlg_already_exist, L, Slic3r::GUI::plater(), Slic3r::psI3, and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by update_print_fff_config().

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

◆ toggle_field()

void Slic3r::GUI::ConfigManipulation::toggle_field ( const std::string & field_key,
const bool toggle,
int opt_index = -1 )
67{
68 if (local_config) {
69 if (local_config->option(opt_key) == nullptr) return;
70 }
71 cb_toggle_field(opt_key, toggle, opt_index);
72}

References cb_toggle_field, and local_config.

Referenced by toggle_print_fff_options(), and toggle_print_sla_options().

Here is the caller graph for this function:

◆ toggle_line()

void Slic3r::GUI::ConfigManipulation::toggle_line ( const std::string & field_key,
const bool toggle,
int opt_index = -1 )
75{
76 if (local_config) {
77 if (local_config->option(opt_key) == nullptr)
78 return;
79 }
81 cb_toggle_line(opt_key, toggle, opt_index);
82}

References cb_toggle_line, and local_config.

Referenced by toggle_print_fff_options().

Here is the caller graph for this function:

◆ toggle_print_fff_options()

void Slic3r::GUI::ConfigManipulation::toggle_print_fff_options ( DynamicPrintConfig * config,
int variant_index,
const bool is_global_config = false )
774{
775 PresetBundle *preset_bundle = wxGetApp().preset_bundle;
776
777 const GCodeFlavor gcflavor = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value;
778
779 // Orca: use booleans to avoid repeated comparisons with enum values
780 const bool gcf_is_marlin_firmware = gcflavor == GCodeFlavor::gcfMarlinFirmware;
781 const bool gcf_is_klipper = gcflavor == GCodeFlavor::gcfKlipper;
782
783 // Belt printer: detect early since it affects multiple toggle decisions below.
784 // `is_belt_tilted` is the stricter test that mirrors PrintObject::has_belt_brim():
785 // only a tilted belt gets the belt-plane brim, while a belt printer with no
786 // rotation is geometrically a flat bed and keeps the ordinary plate brim.
787 bool is_belt_printer = false;
788 bool is_belt_tilted = false;
789 {
790 const auto &printer_cfg = preset_bundle->printers.get_edited_preset().config;
791 const auto *belt_opt = printer_cfg.option<ConfigOptionBool>("belt_printer");
792 if (belt_opt)
793 is_belt_printer = belt_opt->value;
794 const auto *axis = printer_cfg.option<ConfigOptionEnum<BeltRotationAxis>>("belt_slice_rotation");
795 const auto *angle = printer_cfg.option<ConfigOptionFloat>("belt_slice_rotation_angle");
796 if (is_belt_printer && axis != nullptr && angle != nullptr) {
797 // Same window as Print::has_tilted_belt(); shared constants so the GUI and
798 // the backend cannot drift apart.
799 const double tilt = std::abs(angle->value);
800 is_belt_tilted = (axis->value == BeltRotationAxis::X || axis->value == BeltRotationAxis::Y)
802 }
803 }
804
805 bool have_volumetric_extrusion_rate_slope = config->option<ConfigOptionFloat>("max_volumetric_extrusion_rate_slope")->value > 0;
806 float have_volumetric_extrusion_rate_slope_segment_length = config->option<ConfigOptionFloat>("max_volumetric_extrusion_rate_slope_segment_length")->value;
807 toggle_field("enable_arc_fitting", !have_volumetric_extrusion_rate_slope && !is_belt_printer);
808 toggle_line("max_volumetric_extrusion_rate_slope_segment_length", have_volumetric_extrusion_rate_slope);
809 toggle_line("extrusion_rate_smoothing_external_perimeter_only", have_volumetric_extrusion_rate_slope);
810 if(have_volumetric_extrusion_rate_slope) config->set_key_value("enable_arc_fitting", new ConfigOptionEnum<ArcFittingMode>(ArcFittingMode::Disabled));
811 if(have_volumetric_extrusion_rate_slope_segment_length < 0.5) {
812 DynamicPrintConfig new_conf = *config;
813 new_conf.set_key_value("max_volumetric_extrusion_rate_slope_segment_length", new ConfigOptionFloat(1));
814 apply(config, &new_conf);
815 }
816
817 bool have_perimeters = config->opt_int("wall_loops") > 0;
818 for (auto el : { "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "detect_thin_wall", "detect_overhang_wall",
819 "seam_position", "staggered_inner_seams", "wall_sequence", "outer_wall_line_width" })
820 toggle_field(el, have_perimeters);
821 for (auto el : { "inner_wall_speed", "outer_wall_speed", "small_perimeter_speed", "small_perimeter_threshold" })
822 toggle_field(el, have_perimeters, variant_index);
823
824 bool have_infill = config->option<ConfigOptionPercent>("sparse_infill_density")->value > 0;
825 // sparse_infill_filament_id uses the same logic as in Print::extruders()
826 for (auto el : { "sparse_infill_pattern", "infill_combination", "fill_multiline","infill_direction",
827 "infill_complete_top",
828 "minimum_sparse_infill_area", "sparse_infill_filament_id","infill_shift_step","sparse_infill_rotate_template","symmetric_infill_y_axis"})
829 toggle_line(el, have_infill);
830
831 InfillPattern pattern = config->opt_enum<InfillPattern>("sparse_infill_pattern");
832
833 // Orca: the concentric patterns follow the surface outline instead of crossing it, so there is
834 // nothing for an infill anchor to attach to. Hide the anchor settings for them.
835 bool have_infill_anchor = have_infill && pattern != ipConcentric && pattern != ipSpiralInset;
836 toggle_line("infill_anchor", have_infill_anchor);
837 toggle_line("infill_anchor_max", have_infill_anchor);
838
839 bool have_combined_infill = config->opt_bool("infill_combination") && have_infill;
840 toggle_line("infill_combination_max_layer_height", have_combined_infill);
841
842 // Infill patterns that support multiline infill.
843 bool have_multiline_infill_pattern = pattern == ipGyroid || pattern == ipGrid || pattern == ipRectilinear || pattern == ipTpmsD || pattern == ipTpmsFK || pattern == ipCrossHatch || pattern == ipHoneycomb || pattern == ipLateralLattice || pattern == ipLateralHoneycomb || pattern == ipConcentric ||
844 pattern == ipCubic || pattern == ipStars || pattern == ipAlignedRectilinear || pattern == ipLightning || pattern == ip3DHoneycomb || pattern == ipAdaptiveCubic || pattern == ipSupportCubic|| pattern == ipTriangles || pattern == ipQuarterCubic|| pattern == ipArchimedeanChords || pattern == ipHilbertCurve || pattern == ipOctagramSpiral;
845
846 // The sparse infill density is the surface density of the adaptive infill; at 100% the infill is solid.
847 bool have_adaptive_infill_pattern = have_infill && config->option<ConfigOptionPercent>("sparse_infill_density")->value < 100 &&
849 toggle_line("adaptive_infill_mode", have_adaptive_infill_pattern);
850 bool have_adaptive_infill = have_adaptive_infill_pattern && config->opt_enum<AdaptiveInfillMode>("adaptive_infill_mode") != AdaptiveInfillMode::Disabled;
851 toggle_line("adaptive_infill_interior_density", have_adaptive_infill);
852 toggle_line("adaptive_infill_gradient", have_adaptive_infill);
853
854 // gyroid_optimized only applies when the sparse infill pattern is gyroid without adaptive density;
855 // hide the whole line otherwise.
856 toggle_line("gyroid_optimized", have_infill && pattern == ipGyroid && !have_adaptive_infill);
857
858 // If there is infill, enable/disable fill_multiline according to whether the pattern supports multiline infill.
859 if (have_infill) {
860 toggle_field("fill_multiline", have_multiline_infill_pattern);
861 // If the infill pattern does not support multiline fill_multiline is changed to 1.
862 // Necessary when the pattern contains params.multiline (for example, triangles because they belong to the rectilinear class)
863 if (!have_multiline_infill_pattern) {
864 DynamicPrintConfig new_conf = *config;
865 new_conf.set_key_value("fill_multiline", new ConfigOptionInt(1));
866 apply(config, &new_conf);
867 }
868 // Hide infill anchor max if sparse_infill_pattern is not line or if sparse_infill_pattern is line but infill_anchor_max is 0.
869 bool infill_anchor = config->opt_enum<InfillPattern>("sparse_infill_pattern") != ipLine;
870 toggle_field("infill_anchor_max", infill_anchor);
871
872 // Only allow configuration of open anchors if the anchoring is enabled.
873 bool has_infill_anchors = infill_anchor && config->option<ConfigOptionFloatOrPercent>("infill_anchor_max")->value > 0;
874 toggle_field("infill_anchor", has_infill_anchors);
875 }
876
877 //cross zag
878 bool is_cross_zag = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value == InfillPattern::ipCrossZag;
879 bool is_locked_zig = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value == InfillPattern::ipLockedZag;
880
881 toggle_line("infill_shift_step", is_cross_zag || is_locked_zig);
882
883 for (auto el : { "skeleton_infill_density", "skin_infill_density", "infill_lock_depth", "skin_infill_depth","skin_infill_line_width", "skeleton_infill_line_width" })
884 toggle_line(el, is_locked_zig);
885
886 bool is_zig_zag = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value == InfillPattern::ipZigZag;
887
888 toggle_line("symmetric_infill_y_axis", is_zig_zag || is_cross_zag || is_locked_zig);
889
890 bool is_3Dhoneycomb = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value == InfillPattern::ip3DHoneycomb;
891 toggle_line("infill_complete_top", have_infill && is_3Dhoneycomb);
892
893 bool has_spiral_vase = config->opt_bool("spiral_mode");
894 toggle_line("spiral_mode_smooth", has_spiral_vase);
895 toggle_line("spiral_mode_max_xy_smoothing", has_spiral_vase && config->opt_bool("spiral_mode_smooth"));
896 toggle_line("spiral_starting_flow_ratio", has_spiral_vase);
897 toggle_line("spiral_finishing_flow_ratio", has_spiral_vase);
898 bool has_top_shell_layers = config->opt_int("top_shell_layers") > 0 || (has_spiral_vase && config->opt_int("bottom_shell_layers") > 1);
899 bool has_top_shell = has_top_shell_layers && config->option<ConfigOptionPercent>("top_surface_density")->value > 0;
900 bool has_bottom_shell = config->opt_int("bottom_shell_layers") > 0;
901 bool has_solid_infill = has_top_shell_layers || has_bottom_shell;
902 toggle_line("sparse_infill_smooth_factor", have_infill && is_smoothable_infill_pattern(pattern, config->opt_int("fill_multiline")));
903 toggle_field("top_surface_pattern", has_top_shell);
904 toggle_field("bottom_surface_pattern", has_bottom_shell);
905 toggle_field("top_surface_density", has_top_shell_layers);
906 toggle_field("bottom_surface_density", has_bottom_shell);
907 toggle_field("top_layer_direction", has_top_shell);
908 toggle_field("bottom_layer_direction", has_bottom_shell);
909
910 toggle_line("top_surface_expansion", has_top_shell);
911 toggle_line("top_surface_expansion_margin", has_top_shell);
912 bool has_top_surface_expansion = config->opt_float("top_surface_expansion") > 0;
913 toggle_field("top_surface_expansion_margin", has_top_surface_expansion);
914 toggle_line("top_surface_expansion_direction", has_top_shell);
915 toggle_field("top_surface_expansion_direction", has_top_surface_expansion);
916
917 // Orca: Archimedean Chords and Octagram Spiral are the centered surface patterns that the
918 // pattern-centering feature acts on.
919 auto is_centered_pattern = [](InfillPattern p) {
921 };
922 bool is_top_centered = is_centered_pattern(config->option<ConfigOptionEnum<InfillPattern>>("top_surface_pattern")->value);
923 bool is_bottom_centered = is_centered_pattern(config->option<ConfigOptionEnum<InfillPattern>>("bottom_surface_pattern")->value);
924 bool has_centered_surface = (has_top_shell && is_top_centered) || (has_bottom_shell && is_bottom_centered);
925
926 // Orca: center of surface pattern
927 toggle_line("center_of_surface_pattern", has_centered_surface);
928
929 // Orca: separate infills
930 toggle_line("separated_infills", is_separable_infill_pattern(pattern));
931
932 // Fill order is only meaningful for the center-based surface fill patterns; hide it otherwise.
933 auto is_centered_fill = [](InfillPattern p) { return p == ipConcentric || p == ipSpiralInset || p == ipArchimedeanChords || p == ipOctagramSpiral; };
934 toggle_line("top_surface_fill_order", has_top_shell && is_centered_fill(config->opt_enum<InfillPattern>("top_surface_pattern")));
935 toggle_line("bottom_surface_fill_order", has_bottom_shell && is_centered_fill(config->opt_enum<InfillPattern>("bottom_surface_pattern")));
936
937 for (auto el : { "infill_direction", "sparse_infill_line_width", "gap_fill_target","filter_out_gap_fill","infill_wall_overlap",
938 "bridge_angle", "internal_bridge_angle", "relative_bridge_angle",
939 "solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id",
940 })
941 toggle_field(el, have_infill || has_solid_infill);
942 for (auto el : { "sparse_infill_speed", "bridge_speed", "internal_bridge_speed"})
943 toggle_field(el, have_infill || has_solid_infill, variant_index);
944
945 toggle_field("top_shell_thickness", ! has_spiral_vase && has_top_shell_layers);
946 toggle_field("bottom_shell_thickness", ! has_spiral_vase && has_bottom_shell);
947
948 // Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
949 toggle_field("gap_infill_speed", have_perimeters, variant_index);
950
951 toggle_field("top_surface_line_width", has_top_shell);
952 toggle_field("top_surface_speed", has_top_shell, variant_index);
953
954 bool have_default_acceleration = config->opt_float_nullable("default_acceleration", variant_index) > 0;
955
956 for (auto el : {"outer_wall_acceleration", "inner_wall_acceleration", "initial_layer_acceleration", "initial_layer_travel_acceleration",
957 "top_surface_acceleration", "travel_acceleration", "bridge_acceleration", "sparse_infill_acceleration", "internal_solid_infill_acceleration"})
958 toggle_field(el, have_default_acceleration, variant_index);
959
960 bool machine_supports_junction_deviation = false;
961 if (gcf_is_marlin_firmware) {
962 if (const auto *machine_jd = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("machine_max_junction_deviation")) {
963 machine_supports_junction_deviation = !machine_jd->values.empty() && machine_jd->values.front() > 0.0;
964 }
965 }
966 toggle_line("default_junction_deviation", gcf_is_marlin_firmware, variant_index);
967 if (machine_supports_junction_deviation) {
968 toggle_field("default_junction_deviation", true, variant_index);
969 toggle_field("default_jerk", false, variant_index);
970 for (auto el : { "outer_wall_jerk", "inner_wall_jerk", "initial_layer_jerk", "initial_layer_travel_jerk", "top_surface_jerk", "travel_jerk", "infill_jerk"})
971 toggle_line(el, false, variant_index);
972 } else {
973 toggle_field("default_junction_deviation", false, variant_index);
974 toggle_field("default_jerk", true, variant_index);
975 bool have_default_jerk = config->has("default_jerk") && config->opt_float_nullable("default_jerk", variant_index) > 0;
976 for (auto el : { "outer_wall_jerk", "inner_wall_jerk", "initial_layer_jerk", "initial_layer_travel_jerk", "top_surface_jerk", "travel_jerk", "infill_jerk"}) {
977 toggle_line(el, true, variant_index);
978 toggle_field(el, have_default_jerk, variant_index);
979 }
980 }
981
982 // Belt printer: disable skirt, brim, raft, and draft shield controls.
983 bool have_skirt = config->opt_int("skirt_loops") > 0 && !is_belt_printer;
984 toggle_field("skirt_height", have_skirt && config->opt_enum<DraftShield>("draft_shield") != dsEnabled);
985 toggle_line("single_loop_draft_shield", have_skirt); // ORCA: Display one wall if skirt enabled
986 for (auto el : {"skirt_type", "min_skirt_length", "skirt_distance", "skirt_start_angle", "skirt_speed", "draft_shield"})
987 toggle_field(el, have_skirt);
988 if (is_belt_printer) {
989 toggle_field("skirt_loops", false);
990 toggle_field("skirt_height", false);
991 }
992
993 // Belt printers now get a brim too, laid onto the tilted belt by BeltBrim.cpp,
994 // so brim type / width / object gap all apply. A belt printer with no tilt is
995 // geometrically a flat bed and uses the ordinary plate brim, hence the separate
996 // is_belt_tilted test.
997 bool have_brim = config->opt_enum<BrimType>("brim_type") != btNoBrim;
998 toggle_field("brim_object_gap", have_brim);
999 // Both are first-layer-only concepts that the belt path cannot honour.
1000 toggle_field("brim_use_efc_outline", have_brim && !is_belt_tilted);
1001 toggle_field("combine_brims", have_brim && !is_belt_tilted);
1002 bool have_brim_width = have_brim && config->opt_enum<BrimType>("brim_type") != btAutoBrim &&
1003 config->opt_enum<BrimType>("brim_type") != btPainted;
1004 // On a tilted belt Auto / Mouse ear / Painted all collapse to outer-only at the
1005 // configured width, so the width field has to stay live for them too.
1006 toggle_field("brim_width", have_brim_width || (have_brim && is_belt_tilted));
1007 toggle_field("brim_flow_ratio", have_brim);
1008 // Paired toggle_line + toggle_field: cb_toggle_line is null in the per-object
1009 // override panel, so the row cannot be hidden there and greying out is the
1010 // fallback. Both extras are belt-only: one extends the brim ahead along the belt,
1011 // the other widens it across the belt.
1012 for (auto el : { "leading_brim_length", "extra_brim_width" }) {
1013 toggle_line(el, is_belt_tilted);
1014 toggle_field(el, is_belt_tilted && have_brim);
1015 }
1016 // Wall filament selectors use the same logic as in Print::extruders().
1017 toggle_field("outer_wall_filament_id", have_perimeters || have_brim);
1018 toggle_field("inner_wall_filament_id", have_perimeters || have_brim);
1019
1020 const BrimType brim_type = config->opt_enum<BrimType>("brim_type");
1021 const bool have_auto_brim_ear = brim_type == btEar && !is_belt_tilted;
1022 const bool have_painted_brim_ear = brim_type == btPainted && !is_belt_tilted;
1023 set_option_label("brim_width", have_auto_brim_ear ? L("Brim ear radius") : L("Brim width"));
1024 const auto brim_width = config->opt_float("brim_width");
1025 // Automatic brim ear settings require a non-zero brim width.
1026 toggle_field("brim_ears_max_angle", brim_width > 0.0f);
1027 toggle_field("brim_ears_detection_length", brim_width > 0.0f);
1028 // Painted ears carry their own radius and do not depend on brim_width.
1029 toggle_field("brim_ears_outer_only", have_painted_brim_ear || brim_width > 0.0f);
1030 toggle_line("brim_ears_max_angle", have_auto_brim_ear);
1031 toggle_line("brim_ears_detection_length", have_auto_brim_ear);
1032 toggle_line("brim_ears_outer_only", have_auto_brim_ear || have_painted_brim_ear);
1033
1034 // Hide Elephant foot compensation layers if elefant_foot_compensation is not enabled
1035 toggle_line("elefant_foot_compensation_layers", config->opt_float("elefant_foot_compensation") > 0 || config->option<ConfigOptionPercent>("elefant_foot_layers_density")->get_abs_value(1.0f) < 1.0f);
1036
1037 bool have_raft = config->opt_int("raft_layers") > 0 && !is_belt_printer;
1038 if (is_belt_printer)
1039 toggle_field("raft_layers", false);
1040 bool have_support_material = config->opt_bool("enable_support") || have_raft;
1041
1042 SupportType support_type = config->opt_enum<SupportType>("support_type");
1043 bool have_support_interface = config->opt_int("support_interface_top_layers") > 0 || config->opt_int("support_interface_bottom_layers") > 0;
1044 bool have_support_soluble = have_support_material && config->opt_float("support_top_z_distance") == 0;
1045 auto support_style = config->opt_enum<SupportMaterialStyle>("support_style");
1046 for (auto el : { "support_style", "support_base_pattern",
1047 "support_base_pattern_spacing", "support_expansion", "support_angle",
1048 "support_interface_pattern", "support_interface_top_layers", "support_interface_bottom_layers",
1049 "bridge_no_support", "max_bridge_length", "support_top_z_distance", "support_bottom_z_distance",
1050 "support_type", "support_on_build_plate_only", "support_critical_regions_only", "support_interface_not_for_body",
1051 "support_object_xy_distance", "support_object_first_layer_gap", "independent_support_layer_height"})
1052 toggle_field(el, have_support_material);
1053 toggle_field("support_threshold_angle", have_support_material && is_auto(support_type));
1054 toggle_field("support_threshold_overlap", config->opt_int("support_threshold_angle") == 0 && have_support_material && is_auto(support_type));
1055 //toggle_field("support_closing_radius", have_support_material && support_style == smsSnug);
1056
1057 bool support_is_tree = config->opt_bool("enable_support") && is_tree(support_type);
1058 bool support_is_organic = support_is_tree && (support_style == smsTreeOrganic || support_style == smsDefault);
1059 bool support_is_normal_tree = support_is_tree && !support_is_organic;
1060
1061 // hide settings that are not used by tree supports
1062 toggle_line("support_threshold_overlap", !support_is_tree); // ORCA: tree supports do not use Threshold Overlap
1063 // settings specific to normal trees
1064 for (auto el : {"tree_support_branch_angle", "tree_support_branch_distance", "tree_support_branch_diameter", "tree_support_auto_brim", "tree_support_brim_width"})
1065 toggle_line(el, support_is_normal_tree);
1066 // settings specific to organic trees
1067 for (auto el : {"tree_support_branch_angle_organic", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_angle_slow", "tree_support_tip_diameter", "tree_support_top_rate", "tree_support_branch_diameter_angle"})
1068 toggle_line(el, support_is_organic);
1069 // ORCA: Independent support layer height is not compatible with organic tree supports,
1070 // as they rely on the support layers being the same as the object layers to determine where to place branches.
1071 toggle_line("independent_support_layer_height", have_support_material && !support_is_organic);
1072
1073 toggle_field("tree_support_brim_width", support_is_tree && !config->opt_bool("tree_support_auto_brim"));
1074 // tree support use max_bridge_length instead of bridge_no_support
1075 toggle_line("max_bridge_length", support_is_tree);
1076 toggle_line("bridge_no_support", !support_is_tree);
1077 toggle_line("support_critical_regions_only", is_auto(support_type) && support_is_tree);
1078
1079 for (auto el : { "support_interface_filament",
1080 "support_interface_loop_pattern", "support_bottom_interface_spacing" })
1081 toggle_field(el, have_support_material && have_support_interface);
1082
1083 bool can_ironing_support = have_raft || (have_support_material && config->opt_int("support_interface_top_layers") > 0);
1084 toggle_field("support_ironing", can_ironing_support);
1085 bool has_support_ironing = can_ironing_support && config->opt_bool("support_ironing");
1086 for (auto el : {"support_ironing_pattern", "support_ironing_flow", "support_ironing_spacing" })
1087 toggle_line(el, has_support_ironing);
1088 // Orca: Force solid support interface when using support ironing
1089 toggle_field("support_interface_spacing", have_support_material && have_support_interface && !has_support_ironing);
1090
1091// see issue #10915
1092// bool have_skirt_height = have_skirt &&
1093// (config->opt_int("skirt_height") > 1 || config->opt_enum<DraftShield>("draft_shield") != dsEnabled);
1094// toggle_line("support_speed", have_support_material || have_skirt_height);
1095// toggle_line("support_interface_speed", have_support_material && have_support_interface);
1096
1097 // Orca:
1098 for (auto el : {"small_support_perimeter_speed", "small_support_perimeter_threshold"})
1099 toggle_field(el, config->opt_bool("enable_support"));
1100
1101 // BBS
1102 //toggle_field("support_material_synchronize_layers", have_support_soluble);
1103
1104 toggle_field("inner_wall_line_width", have_perimeters || have_skirt || have_brim);
1105 toggle_field("support_filament", have_support_material || have_skirt);
1106
1107 toggle_line("raft_contact_distance", have_raft && !have_support_soluble);
1108 // Orca:Hide raft expansion when raft is not enabled
1109 toggle_line("raft_expansion", have_raft);
1110 // Orca: Slim, Strong and Hybrid tree supports size their raft by first layer expansion only.
1111 toggle_field("raft_expansion", !(is_tree(support_type) && (support_style == smsTreeSlim || support_style == smsTreeStrong || support_style == smsTreeHybrid)));
1112
1113 // Orca: First-layer density is available for supports broadly.
1114 toggle_field("raft_first_layer_density", have_support_material);
1115 // Orca: For regular tree (Slim/Strong) without raft, hide first-layer expansion.
1116 // Keep it enabled for non-tree supports, organic tree, hybrid tree, and any raft case.
1117 toggle_field("raft_first_layer_expansion",
1118 have_support_material && ((!support_is_normal_tree || support_style == smsTreeHybrid) || have_raft));
1119
1120 bool has_ironing = (config->opt_enum<IroningType>("ironing_type") != IroningType::NoIroning);
1121 for (auto el : { "ironing_pattern", "ironing_flow", "ironing_spacing", "ironing_angle", "ironing_inset", "ironing_angle_fixed" })
1122 toggle_line(el, has_ironing);
1123 bool has_rectilinear_ironing = (config->opt_enum<InfillPattern>("ironing_pattern") == InfillPattern::ipRectilinear);
1124 for (auto el : {"ironing_angle", "ironing_angle_fixed"})
1125 toggle_field(el, has_ironing && has_rectilinear_ironing);
1126
1127 toggle_line("ironing_speed", has_ironing || has_support_ironing);
1128
1129 bool has_zaa = config->opt_bool("zaa_enabled");
1130 for (auto el : {"zaa_minimize_perimeter_height", "zaa_min_z", "zaa_dont_alternate_fill_direction", "ironing_expansion"})
1131 toggle_line(el, has_zaa);
1132
1133 bool have_sequential_printing = (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
1134 // for (auto el : { "extruder_clearance_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" })
1135 // toggle_field(el, have_sequential_printing);
1136 toggle_field("print_order", !have_sequential_printing);
1137
1138 toggle_field("single_extruder_multi_material", !is_BBL_Printer);
1139
1140 auto bSEMM = preset_bundle->printers.get_edited_preset().config.opt_bool("single_extruder_multi_material");
1141 const bool supports_wipe_tower_2 = !is_BBL_Printer && preset_bundle->printers.get_edited_preset().config.opt_enum<WipeTowerType>("wipe_tower_type") == WipeTowerType::Type2;
1142
1143 toggle_field("ooze_prevention", !bSEMM);
1144 bool have_ooze_prevention = config->opt_bool("ooze_prevention");
1145 toggle_line("standby_temperature_delta", have_ooze_prevention);
1146 toggle_line("preheat_time", have_ooze_prevention);
1147 int preheat_steps = config->opt_int("preheat_steps");
1148 toggle_line("preheat_steps", have_ooze_prevention && (preheat_steps > 0));
1149
1150 bool have_prime_tower = config->opt_bool("enable_prime_tower");
1151 // ORCA-Belt: belt printers replace the classic wipe tower with the
1152 // auto-generated belt purge prism, enabled by the belt-only printer option
1153 // enable_belt_purge_tower. Its width (a process option) is only relevant
1154 // then. (is_belt_printer is computed at the top of this function.)
1155 const bool have_belt_purge_tower = is_belt_printer
1156 && preset_bundle->printers.get_edited_preset().config.has("enable_belt_purge_tower")
1157 && preset_bundle->printers.get_edited_preset().config.opt_bool("enable_belt_purge_tower");
1158 toggle_line("belt_purge_tower_width", have_belt_purge_tower);
1159 for (auto el : {"prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "wipe_tower_wall_type", "prime_tower_infill_gap","prime_tower_enable_framework", "enable_tower_interface_features"})
1160 toggle_line(el, have_prime_tower && !is_belt_printer);
1161
1162 toggle_line("enable_tower_interface_cooldown_during_tower",
1163 have_prime_tower && !is_belt_printer && config->opt_bool("enable_tower_interface_features"));
1164
1165 bool purge_in_primetower = preset_bundle->printers.get_edited_preset().config.opt_bool("purge_in_prime_tower");
1166
1167 for (auto el : {"wipe_tower_rotation_angle", "wipe_tower_cone_angle",
1168 "wipe_tower_extra_spacing", "wipe_tower_max_purge_speed",
1169 "wipe_tower_bridging", "wipe_tower_extra_flow"})
1170 toggle_line(el, have_prime_tower && supports_wipe_tower_2 && !is_belt_printer);
1171
1172 // Orca: both tower generators skip sparse layers, so this is not a wipe tower 2 exclusive.
1173 toggle_line("wipe_tower_no_sparse_layers", have_prime_tower && !is_belt_printer);
1174 // Dropping the sparse layers outright leaves nothing to combine, so the two are exclusive.
1175 toggle_line("wipe_tower_sparse_layers_combination", have_prime_tower && !is_belt_printer && !config->opt_bool("wipe_tower_no_sparse_layers"));
1176
1177 WipeTowerWallType wipe_tower_wall_type = config->opt_enum<WipeTowerWallType>("wipe_tower_wall_type");
1178 bool have_rib_wall = (wipe_tower_wall_type == WipeTowerWallType::wtwRib)&&have_prime_tower&&!is_belt_printer;
1179 toggle_line("wipe_tower_cone_angle", have_prime_tower && supports_wipe_tower_2 && !is_belt_printer && wipe_tower_wall_type == WipeTowerWallType::wtwCone);
1180 toggle_line("wipe_tower_extra_rib_length", have_rib_wall);
1181 toggle_line("wipe_tower_rib_width", have_rib_wall);
1182 toggle_line("wipe_tower_fillet_wall", have_rib_wall);
1183 toggle_field("prime_tower_width", have_prime_tower && !have_rib_wall && !is_belt_printer);
1184
1185 toggle_line("single_extruder_multi_material_priming", !bSEMM && have_prime_tower && supports_wipe_tower_2 && !is_belt_printer);
1186
1187 bool use_cyclic_ordering = config->opt_enum<ToolChangeOrderingType>("toolchange_ordering") == ToolChangeOrderingType::Cyclic;
1188 toggle_line("toolchange_cyclic_order", use_cyclic_ordering);
1189 toggle_line("toolchange_cyclic_first_layer", use_cyclic_ordering);
1190
1191 toggle_line("prime_volume",have_prime_tower && (!purge_in_primetower || !bSEMM));
1192
1193 for (auto el : {"flush_into_infill", "flush_into_support", "flush_into_objects"})
1194 toggle_field(el, have_prime_tower);
1195
1196 bool have_avoid_crossing_perimeters = config->opt_bool("reduce_crossing_wall");
1197 toggle_line("max_travel_detour_distance", have_avoid_crossing_perimeters);
1198
1199 bool has_set_other_flow_ratios = config->opt_bool("set_other_flow_ratios");
1200 for (auto el : {"first_layer_flow_ratio", "outer_wall_flow_ratio", "inner_wall_flow_ratio", "overhang_flow_ratio", "sparse_infill_flow_ratio", "internal_solid_infill_flow_ratio", "gap_fill_flow_ratio", "support_flow_ratio", "support_interface_flow_ratio"})
1201 toggle_line(el, has_set_other_flow_ratios);
1202
1203 bool has_overhang_speed = config->opt_bool_nullable("enable_overhang_speed", variant_index);
1204 for (auto el : {"overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed"})
1205 toggle_line(el, has_overhang_speed, variant_index);
1206
1207 toggle_line("slowdown_for_curled_perimeters", has_overhang_speed, variant_index);
1208
1209 toggle_line("flush_into_objects", !is_global_config);
1210
1211 toggle_line("support_interface_not_for_body",config->opt_int("support_interface_filament")&&!config->opt_int("support_filament"));
1212
1213 // Get the current fuzzy skin state
1214 bool has_fuzzy_skin = config->opt_enum<FuzzySkinType>("fuzzy_skin") != FuzzySkinType::Disabled_fuzzy;
1215
1216 // Show fuzzy skin options when fuzzy skin is not disabled
1217 for (auto el : {"fuzzy_skin_mode", "fuzzy_skin_noise_type", "fuzzy_skin_point_distance", "fuzzy_skin_thickness", "fuzzy_skin_first_layer"})
1218 toggle_line(el, has_fuzzy_skin);
1219
1220 // Show noise type specific options with the same logic
1221 NoiseType fuzzy_skin_noise_type = config->opt_enum<NoiseType>("fuzzy_skin_noise_type");
1222 const bool is_ripple = fuzzy_skin_noise_type == NoiseType::Ripple;
1223 toggle_line("fuzzy_skin_scale", fuzzy_skin_noise_type != NoiseType::Classic && has_fuzzy_skin && !is_ripple);
1224 toggle_line("fuzzy_skin_octaves", fuzzy_skin_noise_type != NoiseType::Classic && fuzzy_skin_noise_type != NoiseType::Voronoi && has_fuzzy_skin && !is_ripple);
1225 toggle_line("fuzzy_skin_persistence", (fuzzy_skin_noise_type == NoiseType::Perlin || fuzzy_skin_noise_type == NoiseType::Billow) && has_fuzzy_skin && !is_ripple);
1226 toggle_line("fuzzy_skin_ripples_per_layer", is_ripple && has_fuzzy_skin);
1227 toggle_line("fuzzy_skin_ripple_offset", is_ripple && has_fuzzy_skin);
1228 toggle_line("fuzzy_skin_layers_between_ripple_offset", is_ripple && has_fuzzy_skin);
1229
1230 bool have_arachne = config->opt_enum<PerimeterGeneratorType>("wall_generator") == PerimeterGeneratorType::Arachne;
1231 for (auto el : {"wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", "min_feature_size", "min_length_factor",
1232 "min_bead_width", "wall_distribution_count", "initial_layer_min_bead_width", "wall_maximum_resolution", "wall_maximum_deviation"})
1233 toggle_line(el, have_arachne);
1234 toggle_field("detect_thin_wall", !have_arachne);
1235
1236 // Orca
1237 auto is_role_based_wipe_speed = config->opt_bool("role_based_wipe_speed");
1238 toggle_field("wipe_speed",!is_role_based_wipe_speed);
1239
1240 const bool have_wipe_inward = config->opt_bool("wipe_inward");
1241 toggle_line("wipe_inward_distance", have_wipe_inward);
1242
1243 for (auto el : {"accel_to_decel_enable", "accel_to_decel_factor"})
1244 toggle_line(el, gcf_is_klipper);
1245 if(gcf_is_klipper)
1246 toggle_field("accel_to_decel_factor", config->opt_bool("accel_to_decel_enable"));
1247
1248 toggle_line("exclude_object_tolerance", gcf_is_klipper && config->opt_bool("exclude_object"));
1249
1250 bool have_make_overhang_printable = config->opt_bool("make_overhang_printable");
1251 toggle_line("make_overhang_printable_angle", have_make_overhang_printable);
1252 toggle_line("make_overhang_printable_hole_size", have_make_overhang_printable);
1253
1254 // Orca: the one-wall options act on top/bottom surfaces, which exist only with a shell. An unfilled surface
1255 // (0% surface density) is still a surface, so these are gated on the layer counts alone.
1256 toggle_line("only_one_wall_first_layer", has_bottom_shell);
1257 toggle_line("only_one_wall_top", has_top_shell_layers);
1258 toggle_line("min_width_top_surface", (has_top_shell_layers && config->opt_bool("only_one_wall_top")) || ((config->opt_float("min_length_factor") > 0.5f) && have_arachne)); // 0.5 is default value
1259
1260 for (auto el : { "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "hole_to_polyhole_max_edges" })
1261 toggle_line(el, config->opt_bool("hole_to_polyhole"));
1262
1263 bool has_detect_overhang_wall = config->opt_bool("detect_overhang_wall");
1264 bool has_overhang_reverse = config->opt_bool("overhang_reverse");
1265 bool allow_overhang_reverse = !has_spiral_vase;
1266 toggle_line("unsupported_wall_last", has_detect_overhang_wall);
1267 toggle_line("overhang_reverse", allow_overhang_reverse);
1268 toggle_line("overhang_reverse_internal_only", allow_overhang_reverse && has_overhang_reverse);
1269 bool has_overhang_reverse_internal_only = config->opt_bool("overhang_reverse_internal_only");
1270 if (has_overhang_reverse_internal_only){
1271 DynamicPrintConfig new_conf = *config;
1272 new_conf.set_key_value("overhang_reverse_threshold", new ConfigOptionFloatOrPercent(0,true));
1273 apply(config, &new_conf);
1274 }
1275 toggle_line("overhang_reverse_threshold", has_detect_overhang_wall && allow_overhang_reverse && has_overhang_reverse && !has_overhang_reverse_internal_only);
1276 toggle_line("timelapse_type", is_BBL_Printer);
1277
1278
1279 bool have_small_area_infill_flow_compensation = config->opt_bool("small_area_infill_flow_compensation");
1280 toggle_line("small_area_infill_flow_compensation_model", have_small_area_infill_flow_compensation);
1281
1282
1283 // Belt printers: the scarf would start one layer back along the belt, inside the
1284 // previous layer (GCode::extrude_loop skips it there too).
1285 toggle_field("seam_slope_type", !has_spiral_vase && !is_belt_printer);
1286 bool has_seam_slope = !has_spiral_vase && !is_belt_printer && config->opt_enum<SeamScarfType>("seam_slope_type") != SeamScarfType::None;
1287 toggle_line("seam_slope_conditional", has_seam_slope);
1288 toggle_line("seam_slope_start_height", has_seam_slope);
1289 toggle_line("seam_slope_entire_loop", has_seam_slope);
1290 toggle_line("seam_slope_min_length", has_seam_slope);
1291 toggle_line("seam_slope_steps", has_seam_slope);
1292 toggle_line("seam_slope_inner_walls", has_seam_slope);
1293 toggle_line("scarf_joint_speed", has_seam_slope);
1294 toggle_line("scarf_joint_flow_ratio", has_seam_slope);
1295 toggle_field("seam_slope_min_length", !config->opt_bool("seam_slope_entire_loop"));
1296 toggle_line("scarf_angle_threshold", has_seam_slope && config->opt_bool("seam_slope_conditional"));
1297 toggle_line("scarf_overhang_threshold", has_seam_slope && config->opt_bool("seam_slope_conditional"));
1298
1299 bool use_beam_interlocking = config->opt_bool("interlocking_beam");
1300 toggle_line("mmu_segmented_region_interlocking_depth", !use_beam_interlocking);
1301 toggle_line("interlocking_beam_width", use_beam_interlocking);
1302 toggle_line("interlocking_orientation", use_beam_interlocking);
1303 toggle_line("interlocking_beam_layer_count", use_beam_interlocking);
1304 toggle_line("interlocking_depth", use_beam_interlocking);
1305 toggle_line("interlocking_boundary_avoidance", use_beam_interlocking);
1306
1307 bool lattice_options = config->opt_enum<InfillPattern>("sparse_infill_pattern") == InfillPattern::ipLateralLattice;
1308 for (auto el : { "lateral_lattice_angle_1", "lateral_lattice_angle_2"})
1309 toggle_line(el, lattice_options);
1310
1311 bool lightning_options = config->opt_enum<InfillPattern>("sparse_infill_pattern") == InfillPattern::ipLightning;
1312 for (auto el : { "lightning_overhang_angle", "lightning_prune_angle", "lightning_straightening_angle" })
1313 toggle_line(el, lightning_options);
1314
1315 // Adaptative Cubic and support cubic infill patterns do not support infill rotation.
1316 bool FillAdaptive = (pattern == InfillPattern::ipAdaptiveCubic || pattern == InfillPattern::ipSupportCubic);
1317
1318 //Orca: disable infill_direction/solid_infill_direction if sparse_infill_rotate_template/solid_infill_rotate_template is not empty value and adaptive cubic/support cubic infill pattern is not selected
1319 toggle_field("sparse_infill_rotate_template", !FillAdaptive);
1320 toggle_field("infill_direction", config->opt_string("sparse_infill_rotate_template") == "" && !FillAdaptive);
1321 toggle_field("solid_infill_direction", config->opt_string("solid_infill_rotate_template") == "");
1322
1323 toggle_line("infill_overhang_angle", config->opt_enum<InfillPattern>("sparse_infill_pattern") == InfillPattern::ipLateralHoneycomb);
1324
1325 std::string printer_type = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle);
1326 toggle_line("enable_wrapping_detection", DevPrinterConfigUtil::support_wrapping_detection(printer_type));
1327}
static bool support_wrapping_detection(const std::string &type_str)
Definition DevConfigUtil.h:122
void toggle_field(const std::string &field_key, const bool toggle, int opt_index=-1)
Definition ConfigManipulation.cpp:66
void set_option_label(const std::string &field_key, const wxString &label, int opt_index=-1)
Definition ConfigManipulation.cpp:84
void toggle_line(const std::string &field_key, const bool toggle, int opt_index=-1)
Definition ConfigManipulation.cpp:74
GCodeFlavor
Definition PrintConfig.hpp:51
@ gcfMarlinFirmware
Definition PrintConfig.hpp:56
@ gcfKlipper
Definition PrintConfig.hpp:53
infill_anchor((ConfigOptionFloatOrPercent, infill_anchor_max))((ConfigOptionBool
constexpr double BELT_BRIM_MIN_TILT_DEG
Definition BeltBrim.hpp:49
BrimType
Definition PrintConfig.hpp:454
@ btEar
Definition PrintConfig.hpp:456
@ btPainted
Definition PrintConfig.hpp:457
@ btNoBrim
Definition PrintConfig.hpp:461
@ btAutoBrim
Definition PrintConfig.hpp:455
InfillPattern
Definition PrintConfig.hpp:126
@ ipStars
Definition PrintConfig.hpp:130
@ ipHilbertCurve
Definition PrintConfig.hpp:134
@ ipQuarterCubic
Definition PrintConfig.hpp:131
@ ipArchimedeanChords
Definition PrintConfig.hpp:134
@ ipConcentric
Definition PrintConfig.hpp:134
@ ipZigZag
Definition PrintConfig.hpp:128
@ ipTpmsD
Definition PrintConfig.hpp:133
@ ipLateralLattice
Definition PrintConfig.hpp:132
@ ipAlignedRectilinear
Definition PrintConfig.hpp:128
@ ip3DHoneycomb
Definition PrintConfig.hpp:132
@ ipAdaptiveCubic
Definition PrintConfig.hpp:131
@ ipCrossZag
Definition PrintConfig.hpp:128
@ ipLine
Definition PrintConfig.hpp:129
@ ipHoneycomb
Definition PrintConfig.hpp:132
@ ipCubic
Definition PrintConfig.hpp:131
@ ipOctagramSpiral
Definition PrintConfig.hpp:134
@ ipTriangles
Definition PrintConfig.hpp:130
@ ipSupportCubic
Definition PrintConfig.hpp:131
@ ipTpmsFK
Definition PrintConfig.hpp:133
@ ipRectilinear
Definition PrintConfig.hpp:128
@ ipCrossHatch
Definition PrintConfig.hpp:133
@ ipGyroid
Definition PrintConfig.hpp:133
@ ipLockedZag
Definition PrintConfig.hpp:128
@ ipLateralHoneycomb
Definition PrintConfig.hpp:132
@ ipLightning
Definition PrintConfig.hpp:131
@ ipSpiralInset
Definition PrintConfig.hpp:134
bool is_adaptive_infill_pattern(InfillPattern pattern)
Definition PrintConfig.hpp:176
@ X
Definition PrintConfig.hpp:343
@ Y
Definition PrintConfig.hpp:344
@ Disabled
Definition PrintConfig.hpp:239
AdaptiveInfillMode
Definition PrintConfig.hpp:290
@ Disabled
Definition PrintConfig.hpp:291
bool is_separable_infill_pattern(InfillPattern pattern)
Definition PrintConfig.hpp:140
bool is_auto(SupportType stype)
Definition PrintConfig.hpp:389
bool is_tree(SupportType stype)
Definition PrintConfig.hpp:381
constexpr double BELT_BRIM_MAX_TILT_DEG
Definition BeltBrim.hpp:50
static bool has_top_shell_layers(const PrintRegionConfig &config)
Definition PerimeterGenerator.cpp:619
bool is_smoothable_infill_pattern(InfillPattern pattern, int multiline=1)
Definition PrintConfig.hpp:181
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138
PrintSequence
Definition PrintConfig.hpp:310
@ ByObject
Definition PrintConfig.hpp:312
FuzzySkinType
Definition PrintConfig.hpp:76
@ Disabled_fuzzy
Definition PrintConfig.hpp:82
WipeTowerType
Definition PrintConfig.hpp:113
@ Type2
Definition PrintConfig.hpp:115
ToolChangeOrderingType
Definition PrintConfig.hpp:491
@ Cyclic
Definition PrintConfig.hpp:493
SupportType
Definition PrintConfig.hpp:378
IroningType
Definition PrintConfig.hpp:202
@ NoIroning
Definition PrintConfig.hpp:203
zaa_minimize_perimeter_height preheat_steps((ConfigOptionInts, nozzle_temperature))((ConfigOptionBools
SupportMaterialStyle
Definition PrintConfig.hpp:362
@ smsTreeHybrid
Definition PrintConfig.hpp:363
@ smsTreeStrong
Definition PrintConfig.hpp:363
@ smsDefault
Definition PrintConfig.hpp:363
@ smsTreeOrganic
Definition PrintConfig.hpp:363
@ smsTreeSlim
Definition PrintConfig.hpp:363
WipeTowerWallType
Definition PrintConfig.hpp:605
@ wtwRib
Definition PrintConfig.hpp:608
@ wtwCone
Definition PrintConfig.hpp:607
DraftShield
Definition PrintConfig.hpp:477
@ dsEnabled
Definition PrintConfig.hpp:478
SeamScarfType
Definition PrintConfig.hpp:399
@ None
Definition PrintConfig.hpp:400
NoiseType
Definition PrintConfig.hpp:104
@ Perlin
Definition PrintConfig.hpp:106
@ Billow
Definition PrintConfig.hpp:107
@ Ripple
Definition PrintConfig.hpp:110
@ Classic
Definition PrintConfig.hpp:105
@ Voronoi
Definition PrintConfig.hpp:109
PerimeterGeneratorType
Definition PrintConfig.hpp:482
@ Arachne
Definition PrintConfig.hpp:487

References Slic3r::angle(), apply(), Slic3r::Arachne, Slic3r::BELT_BRIM_MAX_TILT_DEG, Slic3r::BELT_BRIM_MIN_TILT_DEG, Slic3r::Billow, Slic3r::btAutoBrim, Slic3r::btEar, Slic3r::btNoBrim, Slic3r::btPainted, Slic3r::ByObject, Slic3r::Classic, Slic3r::Preset::config, Slic3r::ConfigOptionFloat, Slic3r::Cyclic, Slic3r::Disabled, Slic3r::Disabled_fuzzy, Slic3r::dsEnabled, Slic3r::gcfKlipper, Slic3r::gcfMarlinFirmware, Slic3r::ConfigOptionPercent::get_abs_value(), Slic3r::PresetCollection::get_edited_preset(), Slic3r::ConfigOptionResolver::has(), Slic3r::has_top_shell_layers(), Slic3r::infill_anchor(), Slic3r::ip3DHoneycomb, Slic3r::ipAdaptiveCubic, Slic3r::ipAlignedRectilinear, Slic3r::ipArchimedeanChords, Slic3r::ipConcentric, Slic3r::ipCrossHatch, Slic3r::ipCrossZag, Slic3r::ipCubic, Slic3r::ipGrid, Slic3r::ipGyroid, Slic3r::ipHilbertCurve, Slic3r::ipHoneycomb, Slic3r::ipLateralHoneycomb, Slic3r::ipLateralLattice, Slic3r::ipLightning, Slic3r::ipLine, Slic3r::ipLockedZag, Slic3r::ipOctagramSpiral, Slic3r::ipQuarterCubic, Slic3r::ipRectilinear, Slic3r::ipSpiralInset, Slic3r::ipStars, Slic3r::ipSupportCubic, Slic3r::ipTpmsD, Slic3r::ipTpmsFK, Slic3r::ipTriangles, Slic3r::ipZigZag, Slic3r::is_adaptive_infill_pattern(), Slic3r::is_auto(), is_BBL_Printer, Slic3r::is_separable_infill_pattern(), Slic3r::is_smoothable_infill_pattern(), Slic3r::is_tree(), L, Slic3r::NoIroning, Slic3r::None, Slic3r::DynamicConfig::opt_bool(), Slic3r::DynamicConfig::opt_bool_nullable(), Slic3r::DynamicConfig::opt_enum(), Slic3r::DynamicConfig::opt_float(), Slic3r::DynamicConfig::opt_float_nullable(), Slic3r::DynamicConfig::opt_int(), Slic3r::DynamicConfig::opt_string(), Slic3r::ConfigBase::option(), Slic3r::Perlin, Slic3r::preheat_steps(), Slic3r::PresetBundle::printers, Slic3r::Ripple, Slic3r::DynamicConfig::set_key_value(), set_option_label(), Slic3r::smsDefault, Slic3r::smsTreeHybrid, Slic3r::smsTreeOrganic, Slic3r::smsTreeSlim, Slic3r::smsTreeStrong, Slic3r::DevPrinterConfigUtil::support_wrapping_detection(), toggle_field(), toggle_line(), Slic3r::Type2, Slic3r::ConfigOptionSingle< T >::value, Slic3r::Voronoi, Slic3r::wtwCone, Slic3r::wtwRib, Slic3r::X, and Slic3r::Y.

Referenced by Slic3r::GUI::ObjectSettings::update_config_values(), Slic3r::GUI::ObjectTableSettings::update_config_values(), and Slic3r::GUI::ObjectTableSettings::update_settings_list().

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

◆ toggle_print_sla_options()

void Slic3r::GUI::ConfigManipulation::toggle_print_sla_options ( DynamicPrintConfig * config)
1364{
1365 bool supports_en = config->opt_bool("supports_enable");
1366
1367 toggle_field("support_head_front_diameter", supports_en);
1368 toggle_field("support_head_penetration", supports_en);
1369 toggle_field("support_head_width", supports_en);
1370 toggle_field("support_pillar_diameter", supports_en);
1371 toggle_field("support_small_pillar_diameter_percent", supports_en);
1372 toggle_field("support_max_bridges_on_pillar", supports_en);
1373 toggle_field("support_pillar_connection_mode", supports_en);
1374 toggle_field("support_buildplate_only", supports_en);
1375 toggle_field("support_base_diameter", supports_en);
1376 toggle_field("support_base_height", supports_en);
1377 toggle_field("support_base_safety_distance", supports_en);
1378 toggle_field("support_critical_angle", supports_en);
1379 toggle_field("support_max_bridge_length", supports_en);
1380 toggle_field("support_max_pillar_link_distance", supports_en);
1381 toggle_field("support_points_density_relative", supports_en);
1382 toggle_field("support_points_minimal_distance", supports_en);
1383
1384 bool pad_en = config->opt_bool("pad_enable");
1385
1386 toggle_field("pad_wall_thickness", pad_en);
1387 toggle_field("pad_wall_height", pad_en);
1388 toggle_field("pad_brim_size", pad_en);
1389 toggle_field("pad_max_merge_distance", pad_en);
1390 // toggle_field("pad_edge_radius", supports_en);
1391 toggle_field("pad_wall_slope", pad_en);
1392 toggle_field("pad_around_object", pad_en);
1393 toggle_field("pad_around_object_everywhere", pad_en);
1394
1395 bool zero_elev = config->opt_bool("pad_around_object") && pad_en;
1396
1397 toggle_field("support_object_elevation", supports_en && !zero_elev);
1398 toggle_field("pad_object_gap", zero_elev);
1399 toggle_field("pad_around_object_everywhere", zero_elev);
1400 toggle_field("pad_object_connector_stride", zero_elev);
1401 toggle_field("pad_object_connector_width", zero_elev);
1402 toggle_field("pad_object_connector_penetration", zero_elev);
1403}

References Slic3r::DynamicConfig::opt_bool(), and toggle_field().

Referenced by Slic3r::GUI::ObjectSettings::update_config_values(), Slic3r::GUI::ObjectTableSettings::update_config_values(), and Slic3r::GUI::ObjectTableSettings::update_settings_list().

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

◆ update_print_fff_config()

void Slic3r::GUI::ConfigManipulation::update_print_fff_config ( DynamicPrintConfig * config,
const bool is_global_config = false,
const bool is_plate_config = false )

Temporary workaround for the correct updates of the TextCtrl (like "layer_height"):

344{
345 // #ys_FIXME_to_delete
347 // KillFocus() for the wxSpinCtrl use CallAfter function. So,
348 // to except the duplicate call of the update() after dialog->ShowModal(),
349 // let check if this process is already started.
351 return;
352
353 bool is_object_config = (!is_global_config && !is_plate_config);
354
355 // Belt printer: a raft and a draft shield are refused by Print::validate(), and
356 // the fields that would clear them are greyed out in belt mode, so a preset that
357 // carries either could not be sliced at all. Reset them instead of only disabling
358 // the fields.
359 if (GUI::wxGetApp().preset_bundle != nullptr) {
360 const auto *belt_opt = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionBool>("belt_printer");
361 const auto *raft_opt = config->option<ConfigOptionInt>("raft_layers");
362 const auto *shield_opt = config->option<ConfigOptionEnum<DraftShield>>("draft_shield");
363 const bool has_raft = raft_opt != nullptr && raft_opt->value > 0;
364 const bool has_shield = shield_opt != nullptr && shield_opt->value != dsDisabled;
365 if (belt_opt != nullptr && belt_opt->value && (has_raft || has_shield)) {
366 const wxString msg_text = _(L("Raft and draft shield are not available on belt printers.\nThey have been disabled."));
367 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
368 DynamicPrintConfig new_conf = *config;
370 dialog.ShowModal();
371 if (has_raft)
372 new_conf.set_key_value("raft_layers", new ConfigOptionInt(0));
373 if (has_shield)
374 new_conf.set_key_value("draft_shield", new ConfigOptionEnum<DraftShield>(dsDisabled));
375 apply(config, &new_conf);
377 }
378 }
379
380 // layer_height shouldn't be equal to zero
381 auto layer_height = config->opt_float("layer_height");
382 if (layer_height < EPSILON)
383 {
384 const wxString msg_text = _(L("Layer height too small\nIt has been reset to 0.2"));
385 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
386 DynamicPrintConfig new_conf = *config;
388 dialog.ShowModal();
389 new_conf.set_key_value("layer_height", new ConfigOptionFloat(0.2));
390 apply(config, &new_conf);
392 }
393
394 //BBS: ironing_spacing shouldn't be too small or equal to zero
395 if (config->opt_float("ironing_spacing") < IRONING_SPACING_MIN)
396 {
397 const wxString msg_text = _(L("Ironing spacing too small\nIt has been reset to 0.1"));
398 MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
399 DynamicPrintConfig new_conf = *config;
401 dialog.ShowModal();
402 new_conf.set_key_value("ironing_spacing", new ConfigOptionFloat(0.1));
403 apply(config, &new_conf);
405 }
406 if (config->opt_float("support_ironing_spacing") < IRONING_SPACING_MIN)
407 {
408 const wxString msg_text = _(L("Ironing spacing too small\nIt has been reset to 0.1"));
409 MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
410 DynamicPrintConfig new_conf = *config;
412 dialog.ShowModal();
413 new_conf.set_key_value("support_ironing_spacing", new ConfigOptionFloat(0.1));
414 apply(config, &new_conf);
416 }
417
418 if (config->option<ConfigOptionFloat>("initial_layer_print_height")->value < EPSILON)
419 {
420 const wxString msg_text = _(L("Zero initial layer height is invalid.\n\nThe first layer height will be reset to 0.2."));
421 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
422 DynamicPrintConfig new_conf = *config;
424 dialog.ShowModal();
425 new_conf.set_key_value("initial_layer_print_height", new ConfigOptionFloat(0.2));
426 apply(config, &new_conf);
428 }
429
430 if (abs(config->option<ConfigOptionFloat>("xy_hole_compensation")->value) > 2)
431 {
432 const wxString msg_text = _(L("This setting is only used for tuning model size by small amounts.\nFor example, when the model size has small errors or when tolerances are incorrect. For large adjustments, please use the model scale function.\n\nThe value will be reset to 0."));
433 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
434 DynamicPrintConfig new_conf = *config;
436 dialog.ShowModal();
437 new_conf.set_key_value("xy_hole_compensation", new ConfigOptionFloat(0));
438 apply(config, &new_conf);
440 }
441
442 if (abs(config->option<ConfigOptionFloat>("xy_contour_compensation")->value) > 2)
443 {
444 const wxString msg_text = _(L("This setting is only used for tuning model size by small amounts.\nFor example, when the model size has small errors or when tolerances are incorrect. For large adjustments, please use the model scale function.\n\nThe value will be reset to 0."));
445 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
446 DynamicPrintConfig new_conf = *config;
448 dialog.ShowModal();
449 new_conf.set_key_value("xy_contour_compensation", new ConfigOptionFloat(0));
450 apply(config, &new_conf);
452 }
453
454 if (config->option<ConfigOptionFloat>("elefant_foot_compensation")->value > 1)
455 {
456 const wxString msg_text = _(L("The elephant foot compensation value is too large.\nIf there are significant elephant foot issues, please check other settings.\nThe bed temperature may be too high, for example.\n\nThe value will be reset to 0."));
457 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
458 DynamicPrintConfig new_conf = *config;
460 dialog.ShowModal();
461 new_conf.set_key_value("elefant_foot_compensation", new ConfigOptionFloat(0));
462 apply(config, &new_conf);
464 }
465
466 if (config->option<ConfigOptionBool>("enable_wrapping_detection")->value) {
467 std::string printer_type = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle);
469 DynamicPrintConfig new_conf = *config;
470 new_conf.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
471 apply(config, &new_conf);
472 }
473 }
474
475 double sparse_infill_density = config->option<ConfigOptionPercent>("sparse_infill_density")->value;
476 int fill_multiline = config->option<ConfigOptionInt>("fill_multiline")->value;
477 auto timelapse_type = config->opt_enum<TimelapseType>("timelapse_type");
478
479 if (!is_plate_config &&
480 config->opt_bool("spiral_mode") &&
481 ! (config->opt_int("wall_loops") == 1 &&
482 config->opt_int("top_shell_layers") == 0 &&
484 ! config->opt_bool("enable_support") &&
485 config->opt_int("enforce_support_layers") == 0 &&
486 ! config->opt_bool("detect_thin_wall") &&
487 ! config->opt_bool("overhang_reverse") &&
488 config->opt_enum<TimelapseType>("timelapse_type") == TimelapseType::tlTraditional &&
489 !config->opt_bool("enable_wrapping_detection")))
490 {
491 DynamicPrintConfig new_conf = *config;
492 auto answer = show_spiral_mode_settings_dialog(is_object_config);
493 bool support = true;
494 if (answer == wxID_YES) {
495 new_conf.set_key_value("wall_loops", new ConfigOptionInt(1));
496 new_conf.set_key_value("top_shell_layers", new ConfigOptionInt(0));
497 new_conf.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
498 new_conf.set_key_value("enable_support", new ConfigOptionBool(false));
499 new_conf.set_key_value("enforce_support_layers", new ConfigOptionInt(0));
500 new_conf.set_key_value("detect_thin_wall", new ConfigOptionBool(false));
501 new_conf.set_key_value("overhang_reverse", new ConfigOptionBool(false));
502 new_conf.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
503 new_conf.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
505 timelapse_type = TimelapseType::tlTraditional;
506 support = false;
507 }
508 else {
509 new_conf.set_key_value("spiral_mode", new ConfigOptionBool(false));
510 }
511 apply(config, &new_conf);
513 }
514
515 if (config->opt_bool("alternate_extra_wall") &&
516 (config->opt_enum<EnsureVerticalShellThickness>("ensure_vertical_shell_thickness") == evstAll)) {
517 wxString msg_text = _(L("Alternate extra wall doesn't work well when ensure vertical shell thickness is set to All."));
518
519 if (is_global_config)
520 msg_text += "\n\n" + _(L("Change these settings automatically?\n"
521 "Yes - Change ensure vertical shell thickness to Moderate and enable alternate extra wall\n"
522 "No - Don't use alternate extra wall"));
523
524 MessageDialog dialog(m_msg_dlg_parent, msg_text, "",
525 wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
526 DynamicPrintConfig new_conf = *config;
527 auto answer = dialog.ShowModal();
528 if (!is_global_config || answer == wxID_YES) {
529 new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionEnum<EnsureVerticalShellThickness>(evstModerate));
530 new_conf.set_key_value("alternate_extra_wall", new ConfigOptionBool(true));
531 }
532 else {
533 new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionEnum<EnsureVerticalShellThickness>(evstAll));
534 new_conf.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
535 }
536 apply(config, &new_conf);
537 }
538
539 // BBS
540 int filament_cnt = wxGetApp().preset_bundle->filament_presets.size();
541#if 0
542 bool has_wipe_tower = filament_cnt > 1 && config->opt_bool("enable_prime_tower");
543 if (has_wipe_tower && (config->opt_bool("adaptive_layer_height") || config->opt_bool("independent_support_layer_height"))) {
544 wxString msg_text;
545 if (config->opt_bool("adaptive_layer_height") && config->opt_bool("independent_support_layer_height")) {
546 msg_text = _(L("Prime tower does not work when Adaptive Layer Height or Independent Support Layer Height is on.\n"
547 "Which do you want to keep?\n"
548 "YES - Keep Prime Tower\n"
549 "NO - Keep Adaptive Layer Height and Independent Support Layer Height"));
550 }
551 else if (config->opt_bool("adaptive_layer_height")) {
552 msg_text = _(L("Prime tower does not work when Adaptive Layer Height is on.\n"
553 "Which do you want to keep?\n"
554 "YES - Keep Prime Tower\n"
555 "NO - Keep Adaptive Layer Height"));
556 }
557 else {
558 msg_text = _(L("Prime tower does not work when Independent Support Layer Height is on.\n"
559 "Which do you want to keep?\n"
560 "YES - Keep Prime Tower\n"
561 "NO - Keep Independent Support Layer Height"));
562 }
563
564 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxYES | wxNO);
566 auto answer = dialog.ShowModal();
567
568 DynamicPrintConfig new_conf = *config;
569 if (answer == wxID_YES) {
570 if (config->opt_bool("adaptive_layer_height"))
571 new_conf.set_key_value("adaptive_layer_height", new ConfigOptionBool(false));
572
573 if (config->opt_bool("independent_support_layer_height"))
574 new_conf.set_key_value("independent_support_layer_height", new ConfigOptionBool(false));
575 }
576 else
577 new_conf.set_key_value("enable_prime_tower", new ConfigOptionBool(false));
578
579 apply(config, &new_conf);
581 }
582
583 // BBS
584 if (has_wipe_tower && config->opt_bool("enable_support") && !config->opt_bool("independent_support_layer_height")) {
585 double top_gap_raw = config->opt_float("support_top_z_distance");
586 //double bottom_gap_raw = config->opt_float("support_bottom_z_distance");
587 double top_gap = std::round(top_gap_raw / layer_height) * layer_height;
588 //double bottom_gap = std::round(bottom_gap_raw / layer_height) * layer_height;
589 if (top_gap != top_gap_raw /* || bottom_gap != bottom_gap_raw*/) {
590 DynamicPrintConfig new_conf = *config;
591 new_conf.set_key_value("support_top_z_distance", new ConfigOptionFloat(top_gap));
592 //new_conf.set_key_value("support_bottom_z_distance", new ConfigOptionFloat(bottom_gap));
593 apply(config, &new_conf);
594
595 //wxMessageBox(_L("Support top/bottom Z distance is automatically changed to multiple of layer height."));
596 }
597 }
598#endif
599
600 // BBL printers do not support cone wipe tower
601 if (config->opt_bool("enable_prime_tower") && is_BBL_Printer) {
602 auto wipe_tower_wall_type = config->opt_enum<WipeTowerWallType>("wipe_tower_wall_type");
603 if (wipe_tower_wall_type == WipeTowerWallType::wtwCone) {
604 DynamicPrintConfig new_conf = *config;
605 new_conf.set_key_value("wipe_tower_wall_type", new ConfigOptionEnum<WipeTowerWallType>(WipeTowerWallType::wtwRectangle));
606 apply(config, &new_conf);
607 }
608 }
609
610 // Check "enable_support" and "overhangs" relations only on global settings level
611 if (is_global_config && config->opt_bool("enable_support")) {
612 // Ask only once.
615 if (!config->opt_bool("detect_overhang_wall")/* != 1*/) {
616 //BBS: detect_overhang_wall is setting in develop mode. Enable it directly.
617 DynamicPrintConfig new_conf = *config;
618 new_conf.set_key_value("detect_overhang_wall", new ConfigOptionBool(true));
619 apply(config, &new_conf);
620 }
621 }
622 }
623 else {
625 }
626
627 if (config->opt_bool("enable_support")) {
628 auto support_type = config->opt_enum<SupportType>("support_type");
629 auto support_style = config->opt_enum<SupportMaterialStyle>("support_style");
630 std::set<int> enum_set_normal = { smsDefault, smsGrid, smsSnug };
631 std::set<int> enum_set_tree = { smsDefault, smsTreeSlim, smsTreeStrong, smsTreeHybrid, smsTreeOrganic };
632 auto & set = is_tree(support_type) ? enum_set_tree : enum_set_normal;
633 if (set.find(support_style) == set.end()) {
634 DynamicPrintConfig new_conf = *config;
635 new_conf.set_key_value("support_style", new ConfigOptionEnum<SupportMaterialStyle>(smsDefault));
636 apply(config, &new_conf);
637 }
638 }
639
640 // BBS
641 // Reset filament overrides pointing at a slot that no longer exists. Support and the wipe
642 // tower additionally reject mixed slots: the engine consumes those keys directly, so a virtual
643 // slot would reach the G-code unresolved, while the per-feature keys are resolved per layer.
644 static const char* physical_only_keys[] = { "support_filament", "support_interface_filament", "wipe_tower_filament" };
645 static const char* feature_keys[] = { "outer_wall_filament_id", "inner_wall_filament_id",
646 "sparse_infill_filament_id", "internal_solid_filament_id",
647 "top_surface_filament_id", "bottom_surface_filament_id" };
648 auto reset_invalid_filament = [this, config, filament_cnt](const char* key, bool allow_mixed) {
649 auto* opt = dynamic_cast<ConfigOptionInt*>(config->option(key, false));
650 if (opt == nullptr)
651 return;
652 const int val = opt->getInt();
653 const bool out_of_range = val > filament_cnt;
654 const bool is_mixed = !allow_mixed && val > 0 && val <= filament_cnt &&
655 wxGetApp().preset_bundle->is_mixed_filament(val - 1);
656 if (!out_of_range && !is_mixed)
657 return;
658 DynamicPrintConfig new_conf = *config;
659 int new_value = 0;
660 if (out_of_range) {
661 const DynamicPrintConfig *conf_temp = wxGetApp().plater()->config();
662 if (conf_temp != nullptr && conf_temp->has(key))
663 new_value = conf_temp->opt_int(key);
664 }
665 new_conf.set_key_value(key, new ConfigOptionInt(new_value));
666 apply(config, &new_conf);
667 };
668 for (const char* key : physical_only_keys)
669 reset_invalid_filament(key, false);
670 for (const char* key : feature_keys)
671 reset_invalid_filament(key, true);
672
673 // Sub-layer splitting divides each layer by the mix ratio; an adaptive layer profile makes
674 // those sub-layer heights vary per layer, which degrades the blend. Warn once per enable.
675 {
676 static bool s_mixed_sublayer_warned = false;
677 bool sublayer_on = config->opt_bool("enable_mixed_color_sublayer");
678 if (sublayer_on && !s_mixed_sublayer_warned &&
679 wxGetApp().app_config->get("no_warn_mixed_sublayer_variable_layer") != "1") {
680 bool has_variable_layer = false;
681 for (const auto* obj : wxGetApp().model().objects) {
682 if (obj->layer_height_profile.get().size() > 4) {
683 has_variable_layer = true;
684 break;
685 }
686 }
687 if (has_variable_layer) {
688 MessageDialog dialog(m_msg_dlg_parent,
689 _L("Using variable layer height together with mixed color sublayer may result in poor color mixing quality."),
690 "", wxICON_WARNING | wxOK);
691 dialog.show_dsa_button();
693 dialog.ShowModal();
695 if (dialog.get_checkbox_state())
696 wxGetApp().app_config->set("no_warn_mixed_sublayer_variable_layer", "1");
697 s_mixed_sublayer_warned = true;
698 }
699 }
700 if (!sublayer_on)
701 s_mixed_sublayer_warned = false;
702 }
703
704 if (config->opt_enum<SeamScarfType>("seam_slope_type") != SeamScarfType::None &&
705 config->get_abs_value("seam_slope_start_height") >= layer_height) {
706 const wxString msg_text = _(L("seam_slope_start_height needs to be smaller than layer_height.\nReset to 0."));
707 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
708 DynamicPrintConfig new_conf = *config;
710 dialog.ShowModal();
711 new_conf.set_key_value("seam_slope_start_height", new ConfigOptionFloatOrPercent(0, false));
712 apply(config, &new_conf);
714 }
715
716 // layer_height shouldn't be equal to zero
717 float skin_depth = config->opt_float("skin_infill_depth");
718 if (config->opt_float("infill_lock_depth") > skin_depth) {
719 // xgettext:no-c-format, no-boost-format
720 const wxString msg_text = _(L("Lock depth should be smaller than skin depth.\nReset to 50% of skin depth."));
721 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
722 DynamicPrintConfig new_conf = *config;
724 dialog.ShowModal();
725 new_conf.set_key_value("infill_lock_depth", new ConfigOptionFloat(skin_depth / 2));
726 apply(config, &new_conf);
728 }
729
730 bool have_arachne = config->opt_enum<PerimeterGeneratorType>("wall_generator") == PerimeterGeneratorType::Arachne;
731 if (config->opt_enum<FuzzySkinMode>("fuzzy_skin_mode") != FuzzySkinMode::Displacement && !have_arachne) {
732 wxString msg_text = _(L("Both [Extrusion] and [Combined] modes of Fuzzy Skin require the Arachne Wall Generator to be enabled."));
733 msg_text += "\n\n" + _(L("Change these settings automatically?\n"
734 "Yes - Enable Arachne Wall Generator\n"
735 "No - Disable Arachne Wall Generator and set [Displacement] mode of the Fuzzy Skin"));
736 MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxYES | wxNO);
737 DynamicPrintConfig new_conf = *config;
739 auto answer = dialog.ShowModal();
740 if (answer == wxID_YES)
741 new_conf.set_key_value("wall_generator", new ConfigOptionEnum<PerimeterGeneratorType>(PerimeterGeneratorType::Arachne));
742 else
743 new_conf.set_key_value("fuzzy_skin_mode", new ConfigOptionEnum<FuzzySkinMode>(FuzzySkinMode::Displacement));
744 apply(config, &new_conf);
746 }
747}
int show_spiral_mode_settings_dialog(bool is_object_config=false)
Definition ConfigManipulation.cpp:1405
sparse_infill_density((ConfigOptionEnum< InfillPattern >, sparse_infill_pattern))((ConfigOptionPercent
TimelapseType
Definition PrintConfig.hpp:468
@ tlTraditional
Definition PrintConfig.hpp:469
FuzzySkinMode
Definition PrintConfig.hpp:85
@ Displacement
Definition PrintConfig.hpp:86
EnsureVerticalShellThickness
Definition PrintConfig.hpp:406
@ evstAll
Definition PrintConfig.hpp:410
@ evstModerate
Definition PrintConfig.hpp:409
@ smsGrid
Definition PrintConfig.hpp:363
@ smsSnug
Definition PrintConfig.hpp:363
@ wtwRectangle
Definition PrintConfig.hpp:606
@ dsDisabled
Definition PrintConfig.hpp:478
void set(id object, const void *key, id value)
Definition MacIME.mm:24

References _, _L, apply(), Slic3r::Arachne, Slic3r::ConfigOptionFloat, Slic3r::Displacement, Slic3r::dsDisabled, EPSILON, Slic3r::evstAll, Slic3r::evstModerate, Slic3r::ConfigBase::get_abs_value(), Slic3r::GUI::MsgDialog::get_checkbox_state(), Slic3r::ConfigOptionResolver::has(), Slic3r::IRONING_SPACING_MIN, is_BBL_Printer, is_msg_dlg_already_exist, Slic3r::is_tree(), L, Slic3r::GUI::layer_height, m_msg_dlg_parent, m_support_material_overhangs_queried, Slic3r::None, Slic3r::DynamicConfig::opt_bool(), Slic3r::DynamicConfig::opt_enum(), Slic3r::DynamicConfig::opt_float(), Slic3r::DynamicConfig::opt_int(), Slic3r::ConfigBase::option(), Slic3r::DynamicConfig::set_key_value(), Slic3r::GUI::MsgDialog::show_dsa_button(), show_spiral_mode_settings_dialog(), Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::smsDefault, Slic3r::smsGrid, Slic3r::smsSnug, Slic3r::smsTreeHybrid, Slic3r::smsTreeOrganic, Slic3r::smsTreeSlim, Slic3r::smsTreeStrong, Slic3r::sparse_infill_density(), Slic3r::DevPrinterConfigUtil::support_wrapping_detection(), Slic3r::tlTraditional, Slic3r::ConfigOptionSingle< T >::value, Slic3r::wtwCone, and Slic3r::wtwRectangle.

Referenced by Slic3r::GUI::ObjectSettings::update_config_values(), and Slic3r::GUI::ObjectTableSettings::update_config_values().

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

◆ update_print_sla_config()

void Slic3r::GUI::ConfigManipulation::update_print_sla_config ( DynamicPrintConfig * config,
const bool is_global_config = false )
1330{
1331 double head_penetration = config->opt_float("support_head_penetration");
1332 double head_width = config->opt_float("support_head_width");
1333 if (head_penetration > head_width) {
1334 //wxString msg_text = _(L("Head penetration should not be greater than the head width."));
1335 wxString msg_text = "Head penetration should not be greater than the head width.";
1336
1337 //MessageDialog dialog(m_msg_dlg_parent, msg_text, _(L("Invalid Head penetration")), wxICON_WARNING | wxOK);
1338 MessageDialog dialog(m_msg_dlg_parent, msg_text, "Invalid Head penetration", wxICON_WARNING | wxOK);
1339 DynamicPrintConfig new_conf = *config;
1340 if (dialog.ShowModal() == wxID_OK) {
1341 new_conf.set_key_value("support_head_penetration", new ConfigOptionFloat(head_width));
1342 apply(config, &new_conf);
1343 }
1344 }
1345
1346 double pinhead_d = config->opt_float("support_head_front_diameter");
1347 double pillar_d = config->opt_float("support_pillar_diameter");
1348 if (pinhead_d > pillar_d) {
1349 //wxString msg_text = _(L("Pinhead diameter should be smaller than the pillar diameter."));
1350 wxString msg_text = "Pinhead diameter should be smaller than the pillar diameter.";
1351
1352 //MessageDialog dialog(m_msg_dlg_parent, msg_text, _(L("Invalid pinhead diameter")), wxICON_WARNING | wxOK);
1353 MessageDialog dialog(m_msg_dlg_parent, msg_text, "Invalid pinhead diameter", wxICON_WARNING | wxOK);
1354
1355 DynamicPrintConfig new_conf = *config;
1356 if (dialog.ShowModal() == wxID_OK) {
1357 new_conf.set_key_value("support_head_front_diameter", new ConfigOptionFloat(pillar_d / 2.0));
1358 apply(config, &new_conf);
1359 }
1360 }
1361}

References apply(), Slic3r::ConfigOptionFloat, m_msg_dlg_parent, Slic3r::DynamicConfig::opt_float(), Slic3r::DynamicConfig::set_key_value(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by Slic3r::GUI::ObjectSettings::update_config_values(), and Slic3r::GUI::ObjectTableSettings::update_config_values().

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

Member Data Documentation

◆ cb_set_option_label

std::function<void(const std::string &, const wxString &, int opt_index)> Slic3r::GUI::ConfigManipulation::cb_set_option_label = nullptr
private

◆ cb_toggle_field

std::function<void (const std::string&, bool toggle, int opt_index)> Slic3r::GUI::ConfigManipulation::cb_toggle_field = nullptr
private

◆ cb_toggle_line

std::function<void(const std::string &, bool toggle, int opt_index)> Slic3r::GUI::ConfigManipulation::cb_toggle_line = nullptr
private

◆ cb_value_change

std::function<void(const std::string&, const boost::any&)> Slic3r::GUI::ConfigManipulation::cb_value_change = nullptr
private

◆ is_BBL_Printer

bool Slic3r::GUI::ConfigManipulation::is_BBL_Printer {false}
private

◆ is_msg_dlg_already_exist

◆ load_config

std::function<void()> Slic3r::GUI::ConfigManipulation::load_config = nullptr
private

◆ local_config

const DynamicPrintConfig* Slic3r::GUI::ConfigManipulation::local_config = nullptr
private

◆ m_applying_keys

t_config_option_keys Slic3r::GUI::ConfigManipulation::m_applying_keys
private

Referenced by apply(), and applying_keys().

◆ m_is_initialized_support_material_overhangs_queried

bool Slic3r::GUI::ConfigManipulation::m_is_initialized_support_material_overhangs_queried { false }
private

◆ m_msg_dlg_parent

◆ m_support_material_overhangs_queried

bool Slic3r::GUI::ConfigManipulation::m_support_material_overhangs_queried { false }
private

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