Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2019-08-23 17:08:24 +0300
committerbubnikv <bubnikv@gmail.com>2019-08-23 17:08:24 +0300
commit04d6cfe8def4dd6b5de08bf97888c209fadf8026 (patch)
treeb37df0cedfc83506fc4e6e977c7ca5b447de9ecd
parent8f019e5fa992eac2c9a1e84311c990a943f80b01 (diff)
parentee38d80318e9054da4bab817de43c15563edd56b (diff)
Merge remote-tracking branch 'remotes/origin/ys_update_settings'
-rw-r--r--src/slic3r/CMakeLists.txt2
-rw-r--r--src/slic3r/GUI/ConfigManipulation.cpp373
-rw-r--r--src/slic3r/GUI/ConfigManipulation.hpp62
-rw-r--r--src/slic3r/GUI/Field.cpp5
-rw-r--r--src/slic3r/GUI/Field.hpp2
-rw-r--r--src/slic3r/GUI/GUI_ObjectSettings.cpp63
-rw-r--r--src/slic3r/GUI/GUI_ObjectSettings.hpp3
-rw-r--r--src/slic3r/GUI/Tab.cpp52
-rw-r--r--src/slic3r/GUI/Tab.hpp4
9 files changed, 561 insertions, 5 deletions
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index b3e2990f9..e51415d53 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -87,6 +87,8 @@ set(SLIC3R_GUI_SOURCES
GUI/LambdaObjectDialog.hpp
GUI/Tab.cpp
GUI/Tab.hpp
+ GUI/ConfigManipulation.cpp
+ GUI/ConfigManipulation.hpp
GUI/Field.cpp
GUI/Field.hpp
GUI/OptionsGroup.cpp
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
new file mode 100644
index 000000000..236460dd2
--- /dev/null
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -0,0 +1,373 @@
+// #include "libslic3r/GCodeSender.hpp"
+#include "ConfigManipulation.hpp"
+#include "I18N.hpp"
+#include "GUI_App.hpp"
+#include "PresetBundle.hpp"
+
+#include <wx/msgdlg.h>
+
+namespace Slic3r {
+namespace GUI {
+
+void ConfigManipulation::apply(DynamicPrintConfig* config, DynamicPrintConfig* new_config)
+{
+ bool modified = false;
+ for (auto opt_key : config->diff(*new_config)) {
+ config->set_key_value(opt_key, new_config->option(opt_key)->clone());
+ modified = true;
+ }
+
+ if (modified && load_config != nullptr)
+ load_config();
+}
+
+void ConfigManipulation::toggle_field(const std::string& opt_key, const bool toggle, int opt_index/* = -1*/)
+{
+ if (local_config) {
+ if (local_config->option(opt_key) == nullptr)
+ return;
+ }
+ Field* field = get_field(opt_key, opt_index);
+ if (field==nullptr) return;
+ field->toggle(toggle);
+}
+
+void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config)
+{
+ // #ys_FIXME_to_delete
+ //! Temporary workaround for the correct updates of the TextCtrl (like "layer_height"):
+ // KillFocus() for the wxSpinCtrl use CallAfter function. So,
+ // to except the duplicate call of the update() after dialog->ShowModal(),
+ // let check if this process is already started.
+ if (is_msg_dlg_already_exist)
+ return;
+
+ // layer_height shouldn't be equal to zero
+ if (config->opt_float("layer_height") < EPSILON)
+ {
+ const wxString msg_text = _(L("Zero layer height is not valid.\n\nThe layer height will be reset to 0.01."));
+ auto dialog = new wxMessageDialog(nullptr, msg_text, _(L("Layer height")), wxICON_WARNING | wxOK);
+ DynamicPrintConfig new_conf = *config;
+ is_msg_dlg_already_exist = true;
+ dialog->ShowModal();
+ new_conf.set_key_value("layer_height", new ConfigOptionFloat(0.01));
+ apply(config, &new_conf);
+ is_msg_dlg_already_exist = false;
+ }
+
+ if (fabs(config->option<ConfigOptionFloatOrPercent>("first_layer_height")->value - 0) < EPSILON)
+ {
+ const wxString msg_text = _(L("Zero first layer height is not valid.\n\nThe first layer height will be reset to 0.01."));
+ auto dialog = new wxMessageDialog(nullptr, msg_text, _(L("First layer height")), wxICON_WARNING | wxOK);
+ DynamicPrintConfig new_conf = *config;
+ is_msg_dlg_already_exist = true;
+ dialog->ShowModal();
+ new_conf.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(0.01, false));
+ apply(config, &new_conf);
+ is_msg_dlg_already_exist = false;
+ }
+
+ double fill_density = config->option<ConfigOptionPercent>("fill_density")->value;
+
+ if (config->opt_bool("spiral_vase") &&
+ !(config->opt_int("perimeters") == 1 && config->opt_int("top_solid_layers") == 0 &&
+ fill_density == 0)) {
+ wxString msg_text = _(L("The Spiral Vase mode requires:\n"
+ "- one perimeter\n"
+ "- no top solid layers\n"
+ "- 0% fill density\n"
+ "- no support material\n"
+ "- no ensure_vertical_shell_thickness"));
+ if (is_global_config)
+ msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable Spiral Vase?"));
+ auto dialog = new wxMessageDialog(nullptr, msg_text, _(L("Spiral Vase")),
+ wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
+ DynamicPrintConfig new_conf = *config;
+ auto answer = dialog->ShowModal();
+ if (!is_global_config || answer == wxID_YES) {
+ new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
+ new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
+ new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
+ new_conf.set_key_value("support_material", new ConfigOptionBool(false));
+ new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0));
+ new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false));
+ fill_density = 0;
+ }
+ else {
+ new_conf.set_key_value("spiral_vase", new ConfigOptionBool(false));
+ }
+ apply(config, &new_conf);
+ if (cb_value_change)
+ cb_value_change("fill_density", fill_density);
+ }
+
+ if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
+ config->opt_float("support_material_contact_distance") > 0. &&
+ (config->opt_int("support_material_extruder") != 0 || config->opt_int("support_material_interface_extruder") != 0)) {
+ wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n"
+ "if they are printed with the current extruder without triggering a tool change.\n"
+ "(both support_material_extruder and support_material_interface_extruder need to be set to 0)."));
+ if (is_global_config)
+ msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable the Wipe Tower?"));
+ auto dialog = new wxMessageDialog(nullptr, msg_text, _(L("Wipe Tower")),
+ wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
+ DynamicPrintConfig new_conf = *config;
+ auto answer = dialog->ShowModal();
+ if (!is_global_config || answer == wxID_YES) {
+ new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0));
+ new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
+ }
+ else
+ new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
+ apply(config, &new_conf);
+ }
+
+ if (config->opt_bool("wipe_tower") && config->opt_bool("support_material") &&
+ config->opt_float("support_material_contact_distance") == 0 &&
+ !config->opt_bool("support_material_synchronize_layers")) {
+ wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
+ "need to be synchronized with the object layers."));
+ if (is_global_config)
+ msg_text += "\n\n" + _(L("Shall I synchronize support layers in order to enable the Wipe Tower?"));
+ auto dialog = new wxMessageDialog(nullptr, msg_text, _(L("Wipe Tower")),
+ wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
+ DynamicPrintConfig new_conf = *config;
+ auto answer = dialog->ShowModal();
+ if (!is_global_config || answer == wxID_YES) {
+ new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
+ }
+ else
+ new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
+ apply(config, &new_conf);
+ }
+
+ if (config->opt_bool("support_material")) {
+ // Ask only once.
+ if (!support_material_overhangs_queried) {
+ support_material_overhangs_queried = true;
+ if (!config->opt_bool("overhangs")/* != 1*/) {
+ wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
+ "- Detect bridging perimeters"));
+ if (is_global_config)
+ msg_text += "\n\n" + _(L("Shall I adjust those settings for supports?"));
+ auto dialog = new wxMessageDialog(nullptr, msg_text, _(L("Support Generator")),
+ wxICON_WARNING | (is_global_config ? wxYES | wxNO | wxCANCEL : wxOK));
+ DynamicPrintConfig new_conf = *config;
+ auto answer = dialog->ShowModal();
+ if (!is_global_config || answer == wxID_YES) {
+ // Enable "detect bridging perimeters".
+ new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
+ }
+ else if (answer == wxID_NO) {
+ // Do nothing, leave supports on and "detect bridging perimeters" off.
+ }
+ else if (answer == wxID_CANCEL) {
+ // Disable supports.
+ new_conf.set_key_value("support_material", new ConfigOptionBool(false));
+ support_material_overhangs_queried = false;
+ }
+ apply(config, &new_conf);
+ }
+ }
+ }
+ else {
+ support_material_overhangs_queried = false;
+ }
+
+ if (config->option<ConfigOptionPercent>("fill_density")->value == 100) {
+ auto fill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->value;
+ std::string str_fill_pattern = "";
+ t_config_enum_values map_names = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->get_enum_values();
+ for (auto it : map_names) {
+ if (fill_pattern == it.second) {
+ str_fill_pattern = it.first;
+ break;
+ }
+ }
+ if (!str_fill_pattern.empty()) {
+ const std::vector<std::string>& external_fill_pattern = config->def()->get("top_fill_pattern")->enum_values;
+ bool correct_100p_fill = false;
+ for (const std::string& fill : external_fill_pattern)
+ {
+ if (str_fill_pattern == fill)
+ correct_100p_fill = true;
+ }
+ // get fill_pattern name from enum_labels for using this one at dialog_msg
+ str_fill_pattern = _utf8(config->def()->get("fill_pattern")->enum_labels[fill_pattern]);
+ if (!correct_100p_fill) {
+ wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density."))) % str_fill_pattern).str());
+ if (is_global_config)
+ msg_text += "\n\n" + _(L("Shall I switch to rectilinear fill pattern?"));
+ auto dialog = new wxMessageDialog(nullptr, msg_text, _(L("Infill")),
+ wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
+ DynamicPrintConfig new_conf = *config;
+ auto answer = dialog->ShowModal();
+ if (!is_global_config || answer == wxID_YES) {
+ new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
+ fill_density = 100;
+ }
+ else
+ fill_density = wxGetApp().preset_bundle->prints.get_selected_preset().config.option<ConfigOptionPercent>("fill_density")->value;
+ new_conf.set_key_value("fill_density", new ConfigOptionPercent(fill_density));
+ apply(config, &new_conf);
+ if (cb_value_change)
+ cb_value_change("fill_density", fill_density);
+ }
+ }
+ }
+}
+
+void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
+{
+ bool have_perimeters = config->opt_int("perimeters") > 0;
+ for (auto el : { "extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
+ "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
+ "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" })
+ toggle_field(el, have_perimeters);
+
+ bool have_infill = config->option<ConfigOptionPercent>("fill_density")->value > 0;
+ // infill_extruder uses the same logic as in Print::extruders()
+ for (auto el : { "fill_pattern", "infill_every_layers", "infill_only_where_needed",
+ "solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
+ toggle_field(el, have_infill);
+
+ bool have_solid_infill = config->opt_int("top_solid_layers") > 0 || config->opt_int("bottom_solid_layers") > 0;
+ // solid_infill_extruder uses the same logic as in Print::extruders()
+ for (auto el : { "top_fill_pattern", "bottom_fill_pattern", "infill_first", "solid_infill_extruder",
+ "solid_infill_extrusion_width", "solid_infill_speed" })
+ toggle_field(el, have_solid_infill);
+
+ for (auto el : { "fill_angle", "bridge_angle", "infill_extrusion_width",
+ "infill_speed", "bridge_speed" })
+ toggle_field(el, have_infill || have_solid_infill);
+
+ toggle_field("gap_fill_speed", have_perimeters && have_infill);
+
+ bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0;
+ for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })
+ toggle_field(el, have_top_solid_infill);
+
+ bool have_default_acceleration = config->opt_float("default_acceleration") > 0;
+ for (auto el : { "perimeter_acceleration", "infill_acceleration",
+ "bridge_acceleration", "first_layer_acceleration" })
+ toggle_field(el, have_default_acceleration);
+
+ bool have_skirt = config->opt_int("skirts") > 0 || config->opt_float("min_skirt_length") > 0;
+ for (auto el : { "skirt_distance", "skirt_height" })
+ toggle_field(el, have_skirt);
+
+ bool have_brim = config->opt_float("brim_width") > 0;
+ // perimeter_extruder uses the same logic as in Print::extruders()
+ toggle_field("perimeter_extruder", have_perimeters || have_brim);
+
+ bool have_raft = config->opt_int("raft_layers") > 0;
+ bool have_support_material = config->opt_bool("support_material") || have_raft;
+ bool have_support_material_auto = have_support_material && config->opt_bool("support_material_auto");
+ bool have_support_interface = config->opt_int("support_material_interface_layers") > 0;
+ bool have_support_soluble = have_support_material && config->opt_float("support_material_contact_distance") == 0;
+ for (auto el : { "support_material_pattern", "support_material_with_sheath",
+ "support_material_spacing", "support_material_angle", "support_material_interface_layers",
+ "dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance",
+ "support_material_xy_spacing" })
+ toggle_field(el, have_support_material);
+ toggle_field("support_material_threshold", have_support_material_auto);
+
+ for (auto el : { "support_material_interface_spacing", "support_material_interface_extruder",
+ "support_material_interface_speed", "support_material_interface_contact_loops" })
+ toggle_field(el, have_support_material && have_support_interface);
+ toggle_field("support_material_synchronize_layers", have_support_soluble);
+
+ toggle_field("perimeter_extrusion_width", have_perimeters || have_skirt || have_brim);
+ toggle_field("support_material_extruder", have_support_material || have_skirt);
+ toggle_field("support_material_speed", have_support_material || have_brim || have_skirt);
+
+ bool have_sequential_printing = config->opt_bool("complete_objects");
+ for (auto el : { "extruder_clearance_radius", "extruder_clearance_height" })
+ toggle_field(el, have_sequential_printing);
+
+ bool have_ooze_prevention = config->opt_bool("ooze_prevention");
+ toggle_field("standby_temperature_delta", have_ooze_prevention);
+
+ bool have_wipe_tower = config->opt_bool("wipe_tower");
+ for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging" })
+ toggle_field(el, have_wipe_tower);
+}
+
+void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)
+{
+ double head_penetration = config->opt_float("support_head_penetration");
+ double head_width = config->opt_float("support_head_width");
+ if (head_penetration > head_width) {
+ wxString msg_text = _(L("Head penetration should not be greater than the head width."));
+
+ auto dialog = new wxMessageDialog(nullptr,
+ msg_text,
+ _(L("Invalid Head penetration")),
+ wxICON_WARNING | wxOK);
+
+ DynamicPrintConfig new_conf = *config;
+ if (dialog->ShowModal() == wxID_OK) {
+ new_conf.set_key_value("support_head_penetration", new ConfigOptionFloat(head_width));
+ apply(config, &new_conf);
+ }
+ }
+
+ double pinhead_d = config->opt_float("support_head_front_diameter");
+ double pillar_d = config->opt_float("support_pillar_diameter");
+ if (pinhead_d > pillar_d) {
+ wxString msg_text = _(L("Pinhead diameter should be smaller than the pillar diameter."));
+
+ auto dialog = new wxMessageDialog(nullptr,
+ msg_text,
+ _(L("Invalid pinhead diameter")),
+ wxICON_WARNING | wxOK);
+
+ DynamicPrintConfig new_conf = *config;
+ if (dialog->ShowModal() == wxID_OK) {
+ new_conf.set_key_value("support_head_front_diameter", new ConfigOptionFloat(pillar_d / 2.0));
+ apply(config, &new_conf);
+ }
+ }
+}
+
+void ConfigManipulation::toggle_print_sla_options(DynamicPrintConfig* config)
+{
+ bool supports_en = config->opt_bool("supports_enable");
+
+ toggle_field("support_head_front_diameter", supports_en);
+ toggle_field("support_head_penetration", supports_en);
+ toggle_field("support_head_width", supports_en);
+ toggle_field("support_pillar_diameter", supports_en);
+ toggle_field("support_pillar_connection_mode", supports_en);
+ toggle_field("support_buildplate_only", supports_en);
+ toggle_field("support_base_diameter", supports_en);
+ toggle_field("support_base_height", supports_en);
+ toggle_field("support_base_safety_distance", supports_en);
+ toggle_field("support_critical_angle", supports_en);
+ toggle_field("support_max_bridge_length", supports_en);
+ toggle_field("support_max_pillar_link_distance", supports_en);
+ toggle_field("support_points_density_relative", supports_en);
+ toggle_field("support_points_minimal_distance", supports_en);
+
+ bool pad_en = config->opt_bool("pad_enable");
+
+ toggle_field("pad_wall_thickness", pad_en);
+ toggle_field("pad_wall_height", pad_en);
+ toggle_field("pad_max_merge_distance", pad_en);
+ // toggle_field("pad_edge_radius", supports_en);
+ toggle_field("pad_wall_slope", pad_en);
+ toggle_field("pad_zero_elevation", pad_en);
+
+ bool has_suppad = pad_en && supports_en;
+ bool zero_elev = config->opt_bool("pad_zero_elevation") && has_suppad;
+
+ toggle_field("support_object_elevation", supports_en && !zero_elev);
+ toggle_field("pad_object_gap", zero_elev);
+ toggle_field("pad_object_connector_stride", zero_elev);
+ toggle_field("pad_object_connector_width", zero_elev);
+ toggle_field("pad_object_connector_penetration", zero_elev);
+}
+
+
+} // GUI
+} // Slic3r
diff --git a/src/slic3r/GUI/ConfigManipulation.hpp b/src/slic3r/GUI/ConfigManipulation.hpp
new file mode 100644
index 000000000..1dbadc2bd
--- /dev/null
+++ b/src/slic3r/GUI/ConfigManipulation.hpp
@@ -0,0 +1,62 @@
+#ifndef slic3r_ConfigManipulation_hpp_
+#define slic3r_ConfigManipulation_hpp_
+
+/* Class for validation config options
+ * and update (enable/disable) IU components
+ *
+ * Used for config validation for global config (Print Settings Tab)
+ * and local config (overrides options on sidebar)
+ * */
+
+#include "libslic3r/PrintConfig.hpp"
+#include "Field.hpp"
+//#include <boost-1_70/boost/any.hpp>
+
+namespace Slic3r {
+namespace GUI {
+
+class ConfigManipulation
+{
+ bool is_msg_dlg_already_exist{ false };
+ bool support_material_overhangs_queried{ false };
+
+ // function to loading of changed configuration
+ std::function<void()> load_config = nullptr;
+ std::function<Field* (const std::string&, int opt_index)> get_field = nullptr;
+ // callback to propagation of changed value, if needed
+ std::function<void(const std::string&, const boost::any&)> cb_value_change = nullptr;
+ DynamicPrintConfig* local_config = nullptr;
+
+public:
+ ConfigManipulation(std::function<void()> load_config,
+ std::function<Field* (const std::string&, int opt_index)> get_field,
+ std::function<void(const std::string&, const boost::any&)> cb_value_change,
+ DynamicPrintConfig* local_config = nullptr) :
+ load_config(load_config),
+ get_field(get_field),
+ cb_value_change(cb_value_change),
+ local_config(local_config) {}
+ ConfigManipulation() {}
+
+ ~ConfigManipulation() {
+ load_config = nullptr;
+ get_field = nullptr;
+ cb_value_change = nullptr;
+ }
+
+ void apply(DynamicPrintConfig* config, DynamicPrintConfig* new_config);
+ void toggle_field(const std::string& field_key, const bool toggle, int opt_index = -1);
+
+ // FFF print
+ void update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config = false);
+ void toggle_print_fff_options(DynamicPrintConfig* config);
+
+ // SLA print
+ void update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config = false);
+ void toggle_print_sla_options(DynamicPrintConfig* config);
+};
+
+} // GUI
+} // Slic3r
+
+#endif /* slic3r_ConfigManipulation_hpp_ */
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index 97a32e741..bb2dd34d9 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -637,6 +637,10 @@ void SpinCtrl::BUILD() {
void SpinCtrl::propagate_value()
{
+ if (suppress_propagation)
+ return;
+
+ suppress_propagation = true;
if (tmp_value == UNDEF_VALUE) {
on_kill_focus();
} else {
@@ -650,6 +654,7 @@ void SpinCtrl::propagate_value()
#endif
on_change_field();
}
+ suppress_propagation = false;
}
void SpinCtrl::msw_rescale()
diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp
index 761b99ed8..11775a67c 100644
--- a/src/slic3r/GUI/Field.hpp
+++ b/src/slic3r/GUI/Field.hpp
@@ -336,6 +336,8 @@ class SpinCtrl : public Field {
using Field::Field;
private:
static const int UNDEF_VALUE = INT_MIN;
+
+ bool suppress_propagation {false};
public:
SpinCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id), tmp_value(UNDEF_VALUE) {}
SpinCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id), tmp_value(UNDEF_VALUE) {}
diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp
index 19a0e785c..1b884cc24 100644
--- a/src/slic3r/GUI/GUI_ObjectSettings.cpp
+++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp
@@ -9,6 +9,7 @@
#include <boost/algorithm/string.hpp>
#include "I18N.hpp"
+#include "ConfigManipulation.hpp"
#include <wx/wupdlock.h>
@@ -117,7 +118,8 @@ bool ObjectSettings::update_settings_list()
optgroup->label_width = 15;
optgroup->sidetext_width = 5.5;
- optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) {
+ optgroup->m_on_change = [this, config](const t_config_option_key& opt_id, const boost::any& value) {
+ this->update_config_values(config);
wxGetApp().obj_list()->changed_object(); };
// call back for rescaling of the extracolumn control
@@ -152,8 +154,10 @@ bool ObjectSettings::update_settings_list()
m_og_settings.push_back(optgroup);
}
- if (!categories.empty())
+ if (!categories.empty()) {
objects_model->UpdateSettingsDigest(item, categories);
+ update_config_values(config);
+ }
}
else
{
@@ -164,6 +168,61 @@ bool ObjectSettings::update_settings_list()
return true;
}
+void ObjectSettings::update_config_values(DynamicPrintConfig* config)
+{
+ const auto objects_model = wxGetApp().obj_list()->GetModel();
+ const auto item = wxGetApp().obj_list()->GetSelection();
+ const auto printer_technology = wxGetApp().plater()->printer_technology();
+ const bool is_object_settings = objects_model->GetItemType(objects_model->GetParent(item)) == itObject;
+
+ // update config values according to configuration hierarchy
+ DynamicPrintConfig main_config = printer_technology == ptFFF ?
+ wxGetApp().preset_bundle->prints.get_edited_preset().config :
+ wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
+
+ auto load_config = [this, config, &main_config]()
+ {
+ // load checked values from main_config to config
+ config->apply_only(main_config, config->keys(), true);
+ // Initialize UI components with the config values.
+ for (auto og : m_og_settings)
+ og->reload_config();
+ // next config check
+ update_config_values(config);
+ };
+
+ auto get_field = [this](const t_config_option_key & opt_key, int opt_index)
+ {
+ Field* field = nullptr;
+ for (auto og : m_og_settings) {
+ field = og->get_fieldc(opt_key, opt_index);
+ if (field != nullptr)
+ return field;
+ }
+ return field;
+ };
+
+ ConfigManipulation config_manipulation(load_config, get_field, nullptr, config);
+
+ if (!is_object_settings)
+ {
+ const int obj_idx = objects_model->GetObjectIdByItem(item);
+ assert(obj_idx >= 0);
+ DynamicPrintConfig* obj_config = &wxGetApp().model().objects[obj_idx]->config;
+
+ main_config.apply(*obj_config, true);
+ printer_technology == ptFFF ? config_manipulation.update_print_fff_config(&main_config) :
+ config_manipulation.update_print_sla_config(&main_config) ;
+ }
+
+ main_config.apply(*config, true);
+ printer_technology == ptFFF ? config_manipulation.update_print_fff_config(&main_config) :
+ config_manipulation.update_print_sla_config(&main_config) ;
+
+ printer_technology == ptFFF ? config_manipulation.toggle_print_fff_options(&main_config) :
+ config_manipulation.toggle_print_sla_options(&main_config) ;
+}
+
void ObjectSettings::UpdateAndShow(const bool show)
{
OG_Settings::UpdateAndShow(show ? update_settings_list() : false);
diff --git a/src/slic3r/GUI/GUI_ObjectSettings.hpp b/src/slic3r/GUI/GUI_ObjectSettings.hpp
index 2a0c19c5c..61d90600b 100644
--- a/src/slic3r/GUI/GUI_ObjectSettings.hpp
+++ b/src/slic3r/GUI/GUI_ObjectSettings.hpp
@@ -5,6 +5,7 @@
#include <vector>
#include <wx/panel.h>
#include "wxExtensions.hpp"
+#include "libslic3r/PrintConfig.hpp"
class wxBoxSizer;
@@ -28,6 +29,7 @@ public:
virtual wxSizer* get_sizer();
ConfigOptionsGroup* get_og() { return m_og.get(); }
+ wxWindow* parent() const {return m_parent; }
};
@@ -46,6 +48,7 @@ public:
~ObjectSettings() {}
bool update_settings_list();
+ void update_config_values(DynamicPrintConfig*config);
void UpdateAndShow(const bool show) override;
void msw_rescale();
};
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 368854222..612204a92 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -62,6 +62,8 @@ Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) :
m_em_unit = wxGetApp().em_unit();
+ m_config_manipulation = get_config_manipulation();
+
Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) {
for (auto page : m_pages)
if (! page.get()->IsShown())
@@ -1251,6 +1253,7 @@ void TabPrint::update()
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
+ /*
// #ys_FIXME_to_delete
//! Temporary workaround for the correct updates of the TextCtrl (like "layer_height"):
// KillFocus() for the wxSpinCtrl use CallAfter function. So,
@@ -1258,10 +1261,13 @@ void TabPrint::update()
// let check if this process is already started.
if (is_msg_dlg_already_exist)
return;
+ */
m_update_cnt++;
// Freeze();
+ /* #ys_FIXME_delete_after_testing (refactoring)
+ *
// layer_height shouldn't be equal to zero
if (m_config->opt_float("layer_height") < EPSILON)
{
@@ -1355,7 +1361,7 @@ void TabPrint::update()
// Ask only once.
if (!m_support_material_overhangs_queried) {
m_support_material_overhangs_queried = true;
- if (!m_config->opt_bool("overhangs")/* != 1*/) {
+ if (!m_config->opt_bool("overhangs")/* != 1* /) {
wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
"- Detect bridging perimeters\n"
"\nShall I adjust those settings for supports?"));
@@ -1490,6 +1496,9 @@ void TabPrint::update()
bool have_wipe_tower = m_config->opt_bool("wipe_tower");
for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging"})
get_field(el)->toggle(have_wipe_tower);
+ */
+
+ m_config_manipulation.update_print_fff_config(m_config, true);
m_recommended_thin_wall_thickness_description_line->SetText(
from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
@@ -1498,8 +1507,13 @@ void TabPrint::update()
// Thaw();
m_update_cnt--;
- if (m_update_cnt==0)
+ if (m_update_cnt==0) {
+ m_config_manipulation.toggle_print_fff_options(m_config);
+
+ wxGetApp().obj_list()->update_and_show_object_settings_item();
+
wxGetApp().mainframe->on_config_changed(m_config);
+ }
}
void TabPrint::OnActivate()
@@ -3799,6 +3813,8 @@ void TabSLAPrint::update()
m_update_cnt++;
+ /* #ys_FIXME_delete_after_testing (refactoring)
+ *
bool supports_en = m_config->opt_bool("supports_enable");
get_field("support_head_front_diameter")->toggle(supports_en);
@@ -3873,11 +3889,41 @@ void TabSLAPrint::update()
get_field("pad_object_connector_stride")->toggle(zero_elev);
get_field("pad_object_connector_width")->toggle(zero_elev);
get_field("pad_object_connector_penetration")->toggle(zero_elev);
+*/
+ m_config_manipulation.update_print_sla_config(m_config, true);
m_update_cnt--;
- if (m_update_cnt == 0) wxGetApp().mainframe->on_config_changed(m_config);
+ if (m_update_cnt == 0) {
+ m_config_manipulation.toggle_print_sla_options(m_config);
+
+ wxGetApp().obj_list()->update_and_show_object_settings_item();
+
+ wxGetApp().mainframe->on_config_changed(m_config);
+ }
}
+ConfigManipulation Tab::get_config_manipulation()
+{
+ auto load_config = [this]()
+ {
+ update_dirty();
+ // Initialize UI components with the config values.
+ reload_config();
+ update();
+ };
+
+ auto get_field_ = [this](const t_config_option_key& opt_key, int opt_index) {
+ return get_field(opt_key, opt_index);
+ };
+
+ auto cb_value_change = [this](const std::string& opt_key, const boost::any& value) {
+ return on_value_change(opt_key, value);
+ };
+
+ return ConfigManipulation(load_config, get_field_, cb_value_change);
+}
+
+
} // GUI
} // Slic3r
diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp
index 0a9070700..f57558c45 100644
--- a/src/slic3r/GUI/Tab.hpp
+++ b/src/slic3r/GUI/Tab.hpp
@@ -32,6 +32,7 @@
#include "ButtonsDescription.hpp"
#include "Event.hpp"
#include "wxExtensions.hpp"
+#include "ConfigManipulation.hpp"
namespace Slic3r {
namespace GUI {
@@ -313,6 +314,9 @@ protected:
void update_frequently_changed_parameters();
void fill_icon_descriptions();
void set_tooltips_text();
+
+ ConfigManipulation m_config_manipulation;
+ ConfigManipulation get_config_manipulation();
};
class TabPrint : public Tab