From 44c05fa2099b3c0a7daa96181d07a8d61e8f6397 Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Wed, 5 Jun 2019 16:47:09 +0200
Subject: [PATCH] Implemented additional settings for layers range (except of
 "extruder")

---
 src/slic3r/GUI/GUI_ObjectLayers.hpp   |  2 +-
 src/slic3r/GUI/GUI_ObjectList.cpp     | 80 +++++++++++++++++++++------
 src/slic3r/GUI/GUI_ObjectList.hpp     |  2 +
 src/slic3r/GUI/GUI_ObjectSettings.cpp | 11 ++--
 4 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp
index bec2a1f49..55002ff35 100644
--- a/src/slic3r/GUI/GUI_ObjectLayers.hpp
+++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp
@@ -5,7 +5,7 @@
 #include "wxExtensions.hpp"
 
 #ifdef __WXOSX__
-#include "..\libslic3r\PrintConfig.hpp"
+#include "../libslic3r/PrintConfig.hpp"
 #endif
 
 class wxBoxSizer;
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index b7a582062..f68130ddd 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -360,6 +360,21 @@ DynamicPrintConfig& ObjectList::get_item_config(const wxDataViewItem& item) cons
                             (*m_objects)[obj_idx]->config;
 }
 
+const t_layer_height_range& ObjectList::get_layer_range_from_item(const wxDataViewItem layer_item, const int obj_idx) const
+{
+    ModelObject* object = (*m_objects)[obj_idx];
+    t_layer_config_ranges::iterator layer_range = object->layer_config_ranges.begin();
+    int id = m_objects_model->GetLayerIdByItem(layer_item);
+
+    // May be not a best solution #ys_FIXME
+    while (id > 0 && layer_range != object->layer_config_ranges.end()) {
+        ++layer_range;
+        id--;
+    }
+
+    return layer_range->first;
+}
+
 wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count)
 {
     wxArrayString choices;
@@ -1037,11 +1052,11 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name)
 {
     std::vector<std::string> options = get_options_for_bundle(bundle_name);
 
-    /* Because of we couldn't edited layer_height for ItVolume and itLayer from settings list,
+    /* Because of we couldn't edited layer_height for ItVolume from settings list,
      * correct options according to the selected item type :
      * remove "layer_height" option
      */
-    if (m_objects_model->GetItemType(GetSelection()) & (itVolume | itLayer) && bundle_name == _("Layers and Perimeters")) {
+    if ((m_objects_model->GetItemType(GetSelection()) & itVolume) && bundle_name == _("Layers and Perimeters")) {
         const auto layer_height_it = std::find(options.begin(), options.end(), "layer_height");
         if (layer_height_it != options.end())
             options.erase(layer_height_it);
@@ -1833,7 +1848,7 @@ void ObjectList::layers_editing()
         t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges;
         
         if (ranges.empty())
-            ranges[{ 0.0f, 0.2f }] = *DynamicPrintConfig::new_from_defaults_keys({"layer_height"});// some default value
+            ranges[{ 0.0f, 0.6f }] = get_default_layer_config(obj_idx);
 
         // and create Layer item(s) according to the layer_config_ranges
         for (const auto range : ranges)
@@ -1845,6 +1860,18 @@ void ObjectList::layers_editing()
     Expand(layers_item);
 }
 
+DynamicPrintConfig ObjectList::get_default_layer_config(const int obj_idx)
+{
+    DynamicPrintConfig config;
+    coordf_t layer_height = object(obj_idx)->config.has("layer_height") ? 
+                            object(obj_idx)->config.opt_float("layer_height") : 
+                            wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("layer_height");
+    config.set_key_value("layer_height",new ConfigOptionFloat(layer_height));
+    config.set_key_value("extruder",    new ConfigOptionInt(0));
+
+    return config;
+}
+
 bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume)
 {
     auto obj_idx = get_selected_obj_idx();
@@ -1937,22 +1964,28 @@ void ObjectList::part_selection_changed()
                 update_and_show_manipulations = true;
             }
             else {
-                auto parent = m_objects_model->GetParent(item);
-                // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene
-                obj_idx = m_objects_model->GetIdByItem(parent);
+                obj_idx = m_objects_model->GetObjectIdByItem(item);
+                
                 const ItemType type = m_objects_model->GetItemType(item);
                 if (type & itSettings) {
-                    if (m_objects_model->GetParent(parent) == wxDataViewItem(0)) {
+                    const auto parent = m_objects_model->GetParent(item);
+                    const ItemType parent_type = m_objects_model->GetItemType(parent);
+
+                    if (parent_type & itObject) {
                         og_name = _(L("Object Settings to modify"));
                         m_config = &(*m_objects)[obj_idx]->config;
                     }
-                    else {
+                    else if (parent_type & itVolume) {
                         og_name = _(L("Part Settings to modify"));
-                        auto main_parent = m_objects_model->GetParent(parent);
-                        obj_idx = m_objects_model->GetIdByItem(main_parent);
-                        const auto volume_id = m_objects_model->GetVolumeIdByItem(parent);
+                        volume_id = m_objects_model->GetVolumeIdByItem(parent);
                         m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config;
                     }
+                    else if (parent_type & itLayer) {
+                        og_name = _(L("Layer range Settings to modify"));
+
+                        const t_layer_height_range& layer_height_range = get_layer_range_from_item(parent, obj_idx);
+                        m_config = &(*m_objects)[obj_idx]->layer_config_ranges[layer_height_range];
+                    }
                     update_and_show_settings = true;
                 }
                 else if (type & itVolume) {
@@ -1966,12 +1999,14 @@ void ObjectList::part_selection_changed()
                     update_and_show_manipulations = true;
 
                     // fill m_config by object's values
-                    const int obj_idx_ = m_objects_model->GetObjectIdByItem(item);
-                    m_config = &(*m_objects)[obj_idx_]->config;
+                    m_config = &(*m_objects)[obj_idx]->config;
                 }
                 else if (type & (itLayerRoot|itLayer)) {
                     og_name = type & itLayerRoot ? _(L("Layers Editing")) : _(L("Layer Editing"));
                     update_and_show_layers = true;
+
+                    const t_layer_height_range& layer_height_range = get_layer_range_from_item(item, obj_idx);
+                    m_config = &(*m_objects)[obj_idx]->layer_config_ranges[layer_height_range];
                 }
             }
         }
@@ -2259,8 +2294,8 @@ void ObjectList::add_layer_range(const t_layer_height_range& range)
     
     if (selected_range->first == last_range->first)
     {
-        const t_layer_height_range new_range = { last_range->first.second, last_range->first.second + 0.2f };
-        ranges[new_range] = last_range->second;
+        const t_layer_height_range new_range = { last_range->first.second, last_range->first.second + 0.5f };
+        ranges[new_range] = get_default_layer_config(obj_idx);
         add_layer_item(new_range, layers_item);
     }
     else
@@ -2300,13 +2335,13 @@ void ObjectList::add_layer_range(const t_layer_height_range& range)
             add_layer_item(new_range, layers_item, layer_idx);
 
             new_range = { selected_range->first.second, midl_layer };
-            ranges[new_range] = selected_range->second;            
+            ranges[new_range] = get_default_layer_config(obj_idx);
             add_layer_item(new_range, layers_item, layer_idx);
         }
         else
         {
             const t_layer_height_range new_range = { selected_range->first.second, next_range->first.first };
-            ranges[new_range] = selected_range->second;
+            ranges[new_range] = get_default_layer_config(obj_idx);
             add_layer_item(new_range, layers_item, layer_idx);
         }        
     }
@@ -2322,7 +2357,16 @@ void ObjectList::add_layer_item(const t_layer_height_range& range,
                                 const int layer_idx /* = -1*/)
 {
     const std::string label = (boost::format(" %.2f-%.2f ") % range.first % range.second).str();
-    m_objects_model->AddLayersChild(layers_item, label, layer_idx);
+    const wxDataViewItem layer_item = m_objects_model->AddLayersChild(layers_item, label, layer_idx);
+
+    const int obj_idx = get_selected_obj_idx();
+    if (obj_idx < 0) return;
+
+//     auto opt_keys = object(obj_idx)->layer_config_ranges[range].keys();
+    const DynamicPrintConfig& config = object(obj_idx)->layer_config_ranges[range];
+//     if (!opt_keys.empty() && !(opt_keys.size() == 2 && opt_keys[0] == "layer_height" && opt_keys[1] == "extruder"))
+    if (config.keys().size() > 2)
+        select_item(m_objects_model->AddSettingsChild(layer_item));
 }
 
 void ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height)
diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp
index 24c9f65b2..ad7587a01 100644
--- a/src/slic3r/GUI/GUI_ObjectList.hpp
+++ b/src/slic3r/GUI/GUI_ObjectList.hpp
@@ -235,6 +235,7 @@ public:
     bool                del_subobject_from_object(const int obj_idx, const int idx, const int type);
     void                split();
     void                layers_editing();
+    DynamicPrintConfig  get_default_layer_config(const int obj_idx);
     bool                get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume);
     bool                is_splittable();
     bool                selected_instances_of_same_object();
@@ -244,6 +245,7 @@ public:
     wxBoxSizer*         get_sizer() {return  m_sizer;}
     int                 get_selected_obj_idx() const;
     DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const;
+    const t_layer_height_range& get_layer_range_from_item(const wxDataViewItem layer_item, const int obj_idx) const;
 
     void                changed_object(const int obj_idx = -1) const;
     void                part_selection_changed();
diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp
index a4aa7dec2..ab2614895 100644
--- a/src/slic3r/GUI/GUI_ObjectSettings.cpp
+++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp
@@ -72,6 +72,8 @@ void ObjectSettings::update_settings_list()
     auto config         = wxGetApp().obj_list()->config();
 
     const auto item = objects_ctrl->GetSelection();
+    const bool is_layers_range_settings = objects_model->GetItemType(objects_model->GetParent(item)) == itLayer;
+
     if (item && !objects_ctrl->multiple_selection() && 
         config && objects_model->IsSettingsItem(item))
 	{
@@ -119,7 +121,8 @@ void ObjectSettings::update_settings_list()
             }
 
             for (auto& cat : cat_options) {
-                if (cat.second.size() == 1 && cat.second[0] == "extruder")
+                if (cat.second.size() == 1 && 
+                    (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height"))
                     continue;
 
                 auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), _(cat.first), config, false, extra_column);
@@ -129,14 +132,14 @@ void ObjectSettings::update_settings_list()
                 optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) {
                                         wxGetApp().obj_list()->changed_object(); };
 
-                const bool is_extriders_cat = cat.first == "Extruders";
+                const bool is_extruders_cat = cat.first == "Extruders";
                 for (auto& opt : cat.second)
                 {
-                    if (opt == "extruder")
+                    if (opt == "extruder" || is_layers_range_settings && opt == "layer_height")
                         continue;
                     Option option = optgroup->get_option(opt);
                     option.opt.width = 12;
-                    if (is_extriders_cat)
+                    if (is_extruders_cat)
                         option.opt.max = wxGetApp().extruders_cnt();
                     optgroup->append_single_option_line(option);
                 }