From 86b258f727212fde4cf4a7a5160bfe7d2b7e0972 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Fri, 6 Sep 2019 17:46:55 +0200
Subject: [PATCH 1/9] Fixed many warnings in following files:
 src/slic3r/Config/Snapshot.cpp src/slic3r/GUI/Field.cpp
 src/slic3r/GUI/GLToolbar.cpp src/slic3r/GUI/GUI_ObjectList.cpp
 src/slic3r/GUI/GUI_ObjectList.hpp src/slic3r/GUI/Plater.cpp
 src/slic3r/GUI/Plater.hpp src/slic3r/GUI/PresetBundle.cpp
 src/slic3r/GUI/Tab.cpp src/slic3r/GUI/wxExtensions.cpp

---
 src/slic3r/Config/Snapshot.cpp    |  8 ++++----
 src/slic3r/GUI/Field.cpp          |  2 +-
 src/slic3r/GUI/GLToolbar.cpp      | 13 +++++--------
 src/slic3r/GUI/GUI_ObjectList.cpp | 12 ++++++------
 src/slic3r/GUI/GUI_ObjectList.hpp |  6 +++---
 src/slic3r/GUI/Plater.cpp         | 14 +++++++-------
 src/slic3r/GUI/Plater.hpp         |  6 +++---
 src/slic3r/GUI/PresetBundle.cpp   | 11 ++++++-----
 src/slic3r/GUI/Tab.cpp            | 16 ++++++++--------
 src/slic3r/GUI/wxExtensions.cpp   | 28 ++++++++++++++--------------
 10 files changed, 57 insertions(+), 59 deletions(-)

diff --git a/src/slic3r/Config/Snapshot.cpp b/src/slic3r/Config/Snapshot.cpp
index 3757ec25b..2aebd0c72 100644
--- a/src/slic3r/Config/Snapshot.cpp
+++ b/src/slic3r/Config/Snapshot.cpp
@@ -202,9 +202,9 @@ void Snapshot::export_selections(AppConfig &config) const
     config.clear_section("presets");
     config.set("presets", "print",    print);
     config.set("presets", "filament", filaments.front());
-	for (int i = 1; i < filaments.size(); ++i) {
+    for (unsigned i = 1; i < filaments.size(); ++i) {
         char name[64];
-        sprintf(name, "filament_%d", i);
+        sprintf(name, "filament_%u", i);
         config.set("presets", name, filaments[i]);
     }
     config.set("presets", "printer",  printer);
@@ -373,9 +373,9 @@ const Snapshot&	SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot:
     snapshot.print   = app_config.get("presets", "print");
     snapshot.filaments.emplace_back(app_config.get("presets", "filament"));
     snapshot.printer = app_config.get("presets", "printer");
-    for (unsigned int i = 1; i < 1000; ++ i) {
+    for (unsigned i = 1; i < 1000; ++ i) {
         char name[64];
-        sprintf(name, "filament_%d", i);
+        sprintf(name, "filament_%u", i);
         if (! app_config.has("presets", name))
             break;
 	    snapshot.filaments.emplace_back(app_config.get("presets", name));
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index f0384329d..07d75c947 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -854,7 +854,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
 			text_value = wxString::Format(_T("%i"), int(boost::any_cast<int>(value)));
 		else
 			text_value = boost::any_cast<wxString>(value);
-		auto idx = 0;
+        size_t idx = 0;
 		for (auto el : m_opt.enum_values)
 		{
 			if (el == text_value)
diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp
index caadec61c..51d787d9d 100644
--- a/src/slic3r/GUI/GLToolbar.cpp
+++ b/src/slic3r/GUI/GLToolbar.cpp
@@ -861,11 +861,10 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
     float left = m_layout.left + scaled_border;
     float top = m_layout.top - scaled_border;
 
-    int id = -1;
-    
-    for (GLToolbarItem* item : m_items)
+
+    for (size_t id=0; id<m_items.size(); ++id)
     {
-        ++id;
+        GLToolbarItem* item = m_items[id];
         
         if (!item->is_visible())
             continue;
@@ -936,11 +935,9 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
     float left = m_layout.left + scaled_border;
     float top = m_layout.top - scaled_border;
 
-    int id = -1;
-
-    for (GLToolbarItem* item : m_items)
+    for (size_t id=0; id<m_items.size(); ++id)
     {
-        ++id;
+        GLToolbarItem* item = m_items[id];
 
         if (!item->is_visible())
             continue;
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index b14498087..c8812abbf 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -422,7 +422,7 @@ DynamicPrintConfig& ObjectList::get_item_config(const wxDataViewItem& item) cons
                             (*m_objects)[obj_idx]->config;
 }
 
-wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count)
+wxDataViewColumn* ObjectList::create_objects_list_extruder_column(size_t extruders_count)
 {
     wxArrayString choices;
     choices.Add(_(L("default")));
@@ -435,9 +435,9 @@ wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_
     return column;
 }
 
-void ObjectList::update_extruder_values_for_items(const int max_extruder)
+void ObjectList::update_extruder_values_for_items(const size_t max_extruder)
 {
-    for (int i = 0; i < m_objects->size(); ++i)
+    for (size_t i = 0; i < m_objects->size(); ++i)
     {
         wxDataViewItem item = m_objects_model->GetItemById(i);
         if (!item) continue;
@@ -453,7 +453,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder)
         m_objects_model->SetValue(extruder, item, colExtruder);
 
         if (object->volumes.size() > 1) {
-            for (auto id = 0; id < object->volumes.size(); id++) {
+            for (size_t id = 0; id < object->volumes.size(); id++) {
                 item = m_objects_model->GetItemByVolumeId(i, id);
                 if (!item) continue;
                 if (!object->volumes[id]->config.has("extruder") ||
@@ -468,7 +468,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder)
     }
 }
 
-void ObjectList::update_objects_list_extruder_column(int extruders_count)
+void ObjectList::update_objects_list_extruder_column(size_t extruders_count)
 {
     if (!this) return; // #ys_FIXME
     if (printer_technology() == ptSLA)
@@ -3262,7 +3262,7 @@ void ObjectList::change_part_type()
 void ObjectList::last_volume_is_deleted(const int obj_idx)
 {
 
-    if (obj_idx < 0 || obj_idx >= m_objects->size() || (*m_objects)[obj_idx]->volumes.size() != 1)
+    if (obj_idx < 0 || size_t(obj_idx) >= m_objects->size() || (*m_objects)[obj_idx]->volumes.size() != 1)
         return;
 
     auto volume = (*m_objects)[obj_idx]->volumes.front();
diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp
index d19a1002d..13d1106fc 100644
--- a/src/slic3r/GUI/GUI_ObjectList.hpp
+++ b/src/slic3r/GUI/GUI_ObjectList.hpp
@@ -182,15 +182,15 @@ public:
 
     void                create_objects_ctrl();
     void                create_popup_menus();
-    wxDataViewColumn*   create_objects_list_extruder_column(int extruders_count);
-    void                update_objects_list_extruder_column(int extruders_count);
+    wxDataViewColumn*   create_objects_list_extruder_column(size_t extruders_count);
+    void                update_objects_list_extruder_column(size_t extruders_count);
     // show/hide "Extruder" column for Objects List
     void                set_extruder_column_hidden(const bool hide) const;
     // update extruder in current config
     void                update_extruder_in_config(const wxDataViewItem& item);
     // update changed name in the object model
     void                update_name_in_model(const wxDataViewItem& item) const;
-    void                update_extruder_values_for_items(const int max_extruder);
+    void                update_extruder_values_for_items(const size_t max_extruder);
 
     void                init_icons();
     void                msw_rescale_icons();
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index db8a52e17..eef3a5c54 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -883,7 +883,7 @@ void Sidebar::init_filament_combo(PresetComboBox **combo, const int extr_idx) {
     sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | wxBOTTOM, 1);
 }
 
-void Sidebar::remove_unused_filament_combos(const int current_extruder_count)
+void Sidebar::remove_unused_filament_combos(const size_t current_extruder_count)
 {
     if (current_extruder_count >= p->combos_filament.size())
         return;
@@ -926,9 +926,9 @@ void Sidebar::update_presets(Preset::Type preset_type)
     switch (preset_type) {
     case Preset::TYPE_FILAMENT:
     {
-        const int extruder_cnt = print_tech != ptFFF ? 1 :
+        const size_t extruder_cnt = print_tech != ptFFF ? 1 :
                                 dynamic_cast<ConfigOptionFloats*>(preset_bundle.printers.get_edited_preset().config.option("nozzle_diameter"))->values.size();
-        const int filament_cnt = p->combos_filament.size() > extruder_cnt ? extruder_cnt : p->combos_filament.size();
+        const size_t filament_cnt = p->combos_filament.size() > extruder_cnt ? extruder_cnt : p->combos_filament.size();
 
         if (filament_cnt == 1) {
             // Single filament printer, synchronize the filament presets.
@@ -1051,7 +1051,7 @@ wxButton* Sidebar::get_wiping_dialog_button()
     return p->frequently_changed_parameters->get_wiping_dialog_button();
 }
 
-void Sidebar::update_objects_list_extruder_column(int extruders_count)
+void Sidebar::update_objects_list_extruder_column(size_t extruders_count)
 {
     p->object_list->update_objects_list_extruder_column(extruders_count);
 }
@@ -4684,7 +4684,7 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou
     out_text = "";
 }
 
-void Plater::on_extruders_change(int num_extruders)
+void Plater::on_extruders_change(size_t num_extruders)
 {
     auto& choices = sidebar().combos_filament();
 
@@ -4693,7 +4693,7 @@ void Plater::on_extruders_change(int num_extruders)
 
     wxWindowUpdateLocker noUpdates_scrolled_panel(&sidebar()/*.scrolled_panel()*/);
 
-    int i = choices.size();
+    size_t i = choices.size();
     while ( i < num_extruders )
     {
         PresetComboBox* choice/*{ nullptr }*/;
@@ -4880,7 +4880,7 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs)
     if (object_idxs.empty())
         return;
 
-    for (int obj_idx : object_idxs)
+    for (size_t obj_idx : object_idxs)
     {
         if (obj_idx < p->model.objects.size())
             // recenter and re - align to Z = 0
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 2d104bc46..6b488fef1 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -89,7 +89,7 @@ public:
     ~Sidebar();
 
     void init_filament_combo(PresetComboBox **combo, const int extr_idx);
-    void remove_unused_filament_combos(const int current_extruder_count);
+    void remove_unused_filament_combos(const size_t current_extruder_count);
     void update_all_preset_comboboxes();
     void update_presets(Slic3r::Preset::Type preset_type);
     void update_mode_sizer() const;
@@ -105,7 +105,7 @@ public:
 
     ConfigOptionsGroup*     og_freq_chng_params(const bool is_fff);
     wxButton*               get_wiping_dialog_button();
-    void                    update_objects_list_extruder_column(int extruders_count);
+    void                    update_objects_list_extruder_column(size_t extruders_count);
     void                    show_info_sizer();
     void                    show_sliced_info_sizer(const bool show);
     void                    enable_buttons(bool enable);
@@ -209,7 +209,7 @@ public:
     void enter_gizmos_stack();
     void leave_gizmos_stack();
 
-    void on_extruders_change(int extruders_count);
+    void on_extruders_change(size_t extruders_count);
     void on_config_change(const DynamicPrintConfig &config);
     // On activating the parent window.
     void on_activate();
diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp
index 3acff7689..d9e90333c 100644
--- a/src/slic3r/GUI/PresetBundle.cpp
+++ b/src/slic3r/GUI/PresetBundle.cpp
@@ -366,7 +366,7 @@ void PresetBundle::load_selections(const AppConfig &config, const std::string &p
     this->filament_presets = { filaments.get_selected_preset_name() };
     for (unsigned int i = 1; i < 1000; ++ i) {
         char name[64];
-        sprintf(name, "filament_%d", i);
+        sprintf(name, "filament_%u", i);
         if (! config.has("presets", name))
             break;
         this->filament_presets.emplace_back(remove_ini_suffix(config.get("presets", name)));
@@ -388,11 +388,12 @@ void PresetBundle::export_selections(AppConfig &config)
     config.clear_section("presets");
     config.set("presets", "print",        prints.get_selected_preset_name());
     config.set("presets", "filament",     filament_presets.front());
-	for (int i = 1; i < filament_presets.size(); ++i) {
+    for (unsigned i = 1; i < filament_presets.size(); ++i) {
         char name[64];
-        sprintf(name, "filament_%d", i);
+        sprintf(name, "filament_%u", i);
         config.set("presets", name, filament_presets[i]);
     }
+
     config.set("presets", "sla_print",    sla_prints.get_selected_preset_name());
     config.set("presets", "sla_material", sla_materials.get_selected_preset_name());
     config.set("presets", "printer",      printers.get_selected_preset_name());
@@ -779,7 +780,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
                 Preset *loaded = nullptr;
                 if (is_external)
                     loaded = &this->filaments.load_external_preset(name_or_path, name,
-                        (i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "",
+                        (i < int(old_filament_profile_names->values.size())) ? old_filament_profile_names->values[i] : "",
                         std::move(cfg), i == 0);
                 else {
                     // Used by the config wizard when creating a custom setup.
@@ -1262,7 +1263,7 @@ void PresetBundle::update_multi_material_filament_presets()
 
     // Now verify if wiping_volumes_matrix has proper size (it is used to deduce number of extruders in wipe tower generator):
     std::vector<double> old_matrix = this->project_config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values;
-    size_t old_number_of_extruders = int(sqrt(old_matrix.size())+EPSILON);
+    size_t old_number_of_extruders = size_t(sqrt(old_matrix.size())+EPSILON);
     if (num_extruders != old_number_of_extruders) {
             // First verify if purging volumes presets for each extruder matches number of extruders
             std::vector<double>& extruders = this->project_config.option<ConfigOptionFloats>("wiping_volumes_extruders")->values;
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 77bd613d5..c87626a48 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -232,7 +232,7 @@ void Tab::create_preset_tab()
         //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data());
         //! we doing next:
         int selected_item = m_presets_choice->GetSelection();
-        if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty())
+        if (m_selected_preset_item == size_t(selected_item) && !m_presets->current_is_dirty())
             return;
         if (selected_item >= 0) {
             std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data();
@@ -489,7 +489,7 @@ template<class T>
 void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::string, int>& map, Tab *tab, const int& value)
 {
     T *opt_cur = static_cast<T*>(tab->m_config->option(opt_key));
-    for (int i = 0; i < opt_cur->values.size(); i++)
+    for (size_t i = 0; i < opt_cur->values.size(); i++)
         map.emplace(opt_key + "#" + std::to_string(i), value);
 }
 
@@ -1808,7 +1808,7 @@ void TabPrinter::build_fff()
         optgroup->append_single_option_line("single_extruder_multi_material");
 
         optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) {
-            size_t extruders_count = boost::any_cast<int>(optgroup->get_value("extruders_count"));
+            size_t extruders_count = boost::any_cast<size_t>(optgroup->get_value("extruders_count"));
             wxTheApp->CallAfter([this, opt_key, value, extruders_count]() {
                 if (opt_key == "extruders_count" || opt_key == "single_extruder_multi_material") {
                     extruders_count_changed(extruders_count);
@@ -2228,7 +2228,7 @@ void TabPrinter::build_unregular_pages()
 
     // Add/delete Kinematics page according to is_marlin_flavor
     size_t existed_page = 0;
-    for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already
+    for (size_t i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already
         if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) {
             if (!is_marlin_flavor || m_rebuild_kinematics_page)
                 m_pages.erase(m_pages.begin() + i);
@@ -2253,7 +2253,7 @@ void TabPrinter::build_unregular_pages()
         (m_has_single_extruder_MM_page && m_extruders_count == 1))
     {
         // if we have a single extruder MM setup, add a page with configuration options:
-        for (int i = 0; i < m_pages.size(); ++i) // first make sure it's not there already
+        for (size_t i = 0; i < m_pages.size(); ++i) // first make sure it's not there already
             if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) {
                 m_pages.erase(m_pages.begin() + i);
                 break;
@@ -2399,8 +2399,8 @@ void TabPrinter::on_preset_loaded()
 {
     // update the extruders count field
     auto   *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
-    int extruders_count = nozzle_diameter->values.size();
-    set_value("extruders_count", extruders_count);
+    size_t extruders_count = nozzle_diameter->values.size();
+    set_value("extruders_count", int(extruders_count));
     // update the GUI field according to the number of nozzle diameters supplied
     extruders_count_changed(extruders_count);
 }
@@ -2538,7 +2538,7 @@ void TabPrinter::update_fff()
             DynamicPrintConfig new_conf = *m_config;
             if (dialog.ShowModal() == wxID_YES) {
                 auto wipe = static_cast<ConfigOptionBools*>(m_config->option("wipe")->clone());
-                for (int w = 0; w < wipe->values.size(); w++)
+                for (size_t w = 0; w < wipe->values.size(); w++)
                     wipe->values[w] = false;
                 new_conf.set_key_value("wipe", wipe);
             }
diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp
index 71eaa3fc8..5f1e779d6 100644
--- a/src/slic3r/GUI/wxExtensions.cpp
+++ b/src/slic3r/GUI/wxExtensions.cpp
@@ -940,7 +940,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item)
             // node can be deleted by the Delete, let's check its type while we safely can
             bool is_instance_root = (node->m_type & itInstanceRoot);
 
-            for (int i = node->GetChildCount() - 1; i >= (is_instance_root ? 1 : 0); i--)
+            for (int i = int(node->GetChildCount() - 1); i >= (is_instance_root ? 1 : 0); i--)
                 Delete(wxDataViewItem(node->GetNthChild(i)));
 
             return parent;
@@ -1020,7 +1020,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item)
         {
             int vol_cnt = 0;
             int vol_idx = 0;
-            for (int i = 0; i < node_parent->GetChildCount(); ++i) {
+            for (size_t i = 0; i < node_parent->GetChildCount(); ++i) {
                 if (node_parent->GetNthChild(i)->GetType() == itVolume) {
                     vol_idx = i;
                     vol_cnt++;
@@ -1059,7 +1059,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item)
 	else
 	{
 		auto it = find(m_objects.begin(), m_objects.end(), node);
-		auto id = it - m_objects.begin();
+        size_t id = it - m_objects.begin();
 		if (it != m_objects.end())
 		{
             // Delete all sub-items
@@ -1230,7 +1230,7 @@ void ObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent)
 
 wxDataViewItem ObjectDataViewModel::GetItemById(int obj_idx)
 {
-	if (obj_idx >= m_objects.size())
+    if (size_t(obj_idx) >= m_objects.size())
 	{
 		printf("Error! Out of objects range.\n");
 		return wxDataViewItem(0);
@@ -1241,7 +1241,7 @@ wxDataViewItem ObjectDataViewModel::GetItemById(int obj_idx)
 
 wxDataViewItem ObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx)
 {
-	if (obj_idx >= m_objects.size() || obj_idx < 0) {
+    if (size_t(obj_idx) >= m_objects.size()) {
 		printf("Error! Out of objects range.\n");
 		return wxDataViewItem(0);
 	}
@@ -1265,7 +1265,7 @@ wxDataViewItem ObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_id
 
 wxDataViewItem ObjectDataViewModel::GetItemById(const int obj_idx, const int sub_obj_idx, const ItemType parent_type)
 {
-    if (obj_idx >= m_objects.size() || obj_idx < 0) {
+    if (size_t(obj_idx) >= m_objects.size()) {
         printf("Error! Out of objects range.\n");
         return wxDataViewItem(0);
     }
@@ -1294,7 +1294,7 @@ wxDataViewItem ObjectDataViewModel::GetItemByLayerId(int obj_idx, int layer_idx)
 
 wxDataViewItem ObjectDataViewModel::GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range)
 {
-    if (obj_idx >= m_objects.size() || obj_idx < 0) {
+    if (size_t(obj_idx) >= m_objects.size()) {
         printf("Error! Out of objects range.\n");
         return wxDataViewItem(0);
     }
@@ -1411,13 +1411,13 @@ int ObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const
 
     int row_num = 0;
     
-    for (int i = 0; i < m_objects.size(); i++)
+    for (size_t i = 0; i < m_objects.size(); i++)
     {
         row_num++;
         if (item == wxDataViewItem(m_objects[i]))
             return row_num;
 
-        for (int j = 0; j < m_objects[i]->GetChildCount(); j++)
+        for (size_t j = 0; j < m_objects[i]->GetChildCount(); j++)
         {
             row_num++;
             ObjectDataViewModelNode* cur_node = m_objects[i]->GetNthChild(j);
@@ -1429,7 +1429,7 @@ int ObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const
             if (cur_node->m_type == itInstanceRoot)
             {
                 row_num++;
-                for (int t = 0; t < cur_node->GetChildCount(); t++)
+                for (size_t t = 0; t < cur_node->GetChildCount(); t++)
                 {
                     row_num++;
                     if (item == wxDataViewItem(cur_node->GetNthChild(t)))
@@ -1503,7 +1503,7 @@ bool ObjectDataViewModel::SetValue(const wxVariant &variant, const wxDataViewIte
 
 bool ObjectDataViewModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col)
 {
-	if (item_idx < 0 || item_idx >= m_objects.size())
+    if (size_t(item_idx) >= m_objects.size())
 		return false;
 
 	return m_objects[item_idx]->SetValue(variant, col);
@@ -1662,7 +1662,7 @@ wxDataViewItem ObjectDataViewModel::GetItemByType(const wxDataViewItem &parent_i
     if (node->GetChildCount() == 0)
         return wxDataViewItem(0);
 
-    for (int i = 0; i < node->GetChildCount(); i++) {
+    for (size_t i = 0; i < node->GetChildCount(); i++) {
         if (node->GetNthChild(i)->m_type == type)
             return wxDataViewItem((void*)node->GetNthChild(i));
     }
@@ -2145,7 +2145,7 @@ void DoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const int hig
     wxCoord segm_end_x = is_horizontal() ? higher_pos : width*0.5 - 1;
     wxCoord segm_end_y = is_horizontal() ? height*0.5 - 1 : higher_pos-1;
 
-    for (int id = 0; id < m_line_pens.size(); id++)
+    for (size_t id = 0; id < m_line_pens.size(); id++)
     {
         dc.SetPen(*m_line_pens[id]);
         dc.DrawLine(line_beg_x, line_beg_y, line_end_x, line_end_y);
@@ -2494,7 +2494,7 @@ void DoubleSlider::draw_colored_band(wxDC& dc)
     dc.SetBrush(clr);
     dc.DrawRectangle(main_band);
 
-    int i = 1;
+    size_t i = 1;
     for (auto tick : m_ticks)
     {
         if (i == colors_cnt)

From c5f78dd6e26522ad88bbdff8b644f2744e7507c0 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Mon, 9 Sep 2019 13:46:12 +0200
Subject: [PATCH 2/9] Some more warnings fixed (WipeTower.cpp/.hpp)

---
 src/libslic3r/GCode/WipeTower.cpp | 36 +++++++++++++++----------------
 src/libslic3r/GCode/WipeTower.hpp |  4 ++--
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp
index 9e2ec1251..84d03ba20 100644
--- a/src/libslic3r/GCode/WipeTower.cpp
+++ b/src/libslic3r/GCode/WipeTower.cpp
@@ -82,7 +82,7 @@ public:
     }
 
     WipeTowerWriter&          change_analyzer_mm3_per_mm(float len, float e) {
-            static const float area = M_PI * 1.75f * 1.75f / 4.f;
+            static const float area = float(M_PI) * 1.75f * 1.75f / 4.f;
             float mm3_per_mm = (len == 0.f ? 0.f : area * e / len);
             // adds tag for analyzer:
             char buf[64];
@@ -100,7 +100,7 @@ public:
 		return *this;
 	}
 
-	WipeTowerWriter&				 set_initial_tool(const unsigned int tool) { m_current_tool = tool; return *this; }
+    WipeTowerWriter&				 set_initial_tool(size_t tool) { m_current_tool = tool; return *this; }
 
 	WipeTowerWriter&				 set_z(float z) 
 		{ m_current_z = z; return *this; }
@@ -311,7 +311,7 @@ public:
 		return *this;
 	}
 
-    WipeTowerWriter& set_tool(unsigned tool)
+    WipeTowerWriter& set_tool(size_t tool)
 	{
 		m_current_tool = tool;
 		return *this;
@@ -406,7 +406,7 @@ private:
 	Vec2f         m_current_pos;
 	float    	  m_current_z;
 	float 	  	  m_current_feedrate;
-	unsigned int  m_current_tool;
+    size_t        m_current_tool;
 	float 		  m_layer_height;
 	float 	  	  m_extrusion_flow;
 	bool		  m_preview_suppressed;
@@ -417,7 +417,7 @@ private:
 	float		  m_y_shift = 0.f;
 	float 		  m_wipe_tower_width = 0.f;
 	float		  m_wipe_tower_depth = 0.f;
-    unsigned      m_last_fan_speed = 0.f;
+    unsigned      m_last_fan_speed = 0;
     int           current_temp = -1;
     const float   m_default_analyzer_line_width;
     float         m_used_filament_length = 0.f;
@@ -568,7 +568,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
 
     // Iterate over all priming toolchanges and push respective ToolChangeResults into results vector.
     for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
-        int old_tool = m_current_tool;
+        size_t old_tool = m_current_tool;
 
         WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
         writer.set_extrusion_flow(m_extrusion_flow)
@@ -617,8 +617,8 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
 
         ToolChangeResult result;
         result.priming      = true;
-        result.initial_tool = old_tool;
-        result.new_tool     = m_current_tool;
+        result.initial_tool = int(old_tool);
+        result.new_tool     = int(m_current_tool);
         result.print_z 	  	= this->m_z_pos;
         result.layer_height = this->m_layer_height;
         result.gcode   	  	= writer.gcode();
@@ -653,12 +653,12 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
 	return results;
 }
 
-WipeTower::ToolChangeResult WipeTower::tool_change(unsigned int tool, bool last_in_layer)
+WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_layer)
 {
 	if ( m_print_brim )
 		return toolchange_Brim();
 
-    int old_tool = m_current_tool;
+    size_t old_tool = m_current_tool;
 
 	float wipe_area = 0.f;
 	bool last_change_in_layer = false;
@@ -751,8 +751,8 @@ WipeTower::ToolChangeResult WipeTower::tool_change(unsigned int tool, bool last_
 
 	ToolChangeResult result;
     result.priming      = false;
-    result.initial_tool = old_tool;
-    result.new_tool     = m_current_tool;
+    result.initial_tool = int(old_tool);
+    result.new_tool     = int(m_current_tool);
 	result.print_z 	  	= this->m_z_pos;
 	result.layer_height = this->m_layer_height;
 	result.gcode   	  	= writer.gcode();
@@ -765,7 +765,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(unsigned int tool, bool last_
 
 WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_offset)
 {
-    int old_tool = m_current_tool;
+    size_t old_tool = m_current_tool;
 
 	const box_coordinates wipeTower_box(
 		Vec2f::Zero(),
@@ -809,8 +809,8 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
 
 	ToolChangeResult result;
     result.priming      = false;
-    result.initial_tool = old_tool;
-    result.new_tool     = m_current_tool;
+    result.initial_tool = int(old_tool);
+    result.new_tool     = int(m_current_tool);
 	result.print_z 	  	= this->m_z_pos;
 	result.layer_height = this->m_layer_height;
 	result.gcode   	  	= writer.gcode();
@@ -1115,7 +1115,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
 	// Otherwise the caller would likely travel to the wipe tower in vain.
 	assert(! this->layer_finished());
 
-    int old_tool = m_current_tool;
+    size_t old_tool = m_current_tool;
 
 	WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
 	writer.set_extrusion_flow(m_extrusion_flow)
@@ -1198,8 +1198,8 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
 
 	ToolChangeResult result;
     result.priming      = false;
-    result.initial_tool = old_tool;
-    result.new_tool     = m_current_tool;
+    result.initial_tool = int(old_tool);
+    result.new_tool     = int(m_current_tool);
 	result.print_z 	  	= this->m_z_pos;
 	result.layer_height = this->m_layer_height;
 	result.gcode   	  	= writer.gcode();
diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp
index 63aedcba3..5477aa609 100644
--- a/src/libslic3r/GCode/WipeTower.hpp
+++ b/src/libslic3r/GCode/WipeTower.hpp
@@ -148,7 +148,7 @@ public:
 
 	// Returns gcode for a toolchange and a final print head position.
 	// On the first layer, extrude a brim around the future wipe tower first.
-	ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer);
+    ToolChangeResult tool_change(size_t new_tool, bool last_in_layer);
 
 	// Fill the unfilled space with a sparse infill.
 	// Call this method only if layer_finished() is false.
@@ -194,7 +194,7 @@ private:
     const bool  m_peters_wipe_tower   = false; // sparse wipe tower inspired by Peter's post processor - not finished yet
     const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
     const float WT_EPSILON            = 1e-3f;
-    const float filament_area() const {
+    float filament_area() const {
         return m_filpar[0].filament_area; // all extruders are assumed to have the same filament diameter at this point
     }
 

From 4fc20090c86fc1ed11f40a8bc6a7d897012bb7bf Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 10 Sep 2019 12:34:03 +0200
Subject: [PATCH 3/9] GUI_ObjectList.cpp: Max layer height defaults to
 0.75*nozzle_diameter as it should (#2892)

---
 src/slic3r/GUI/GUI_ObjectList.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index c8812abbf..a79426ed2 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -2565,7 +2565,14 @@ static double get_min_layer_height(const int extruder_idx)
 static double get_max_layer_height(const int extruder_idx)
 {
     const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
-    return config.opt_float("max_layer_height", extruder_idx <= 0 ? 0 : extruder_idx-1);
+    int extruder_idx_zero_based = extruder_idx <= 0 ? 0 : extruder_idx-1;
+    double max_layer_height = config.opt_float("max_layer_height", extruder_idx_zero_based);
+
+    // In case max_layer_height is set to zero, it should default to 75 % of nozzle diameter:
+    if (max_layer_height < EPSILON)
+        max_layer_height = 0.75 * config.opt_float("nozzle_diameter", extruder_idx_zero_based);
+
+    return max_layer_height;
 }
 
 void ObjectList::add_layer_range_after_current(const t_layer_height_range& current_range)

From 2fef16c39aea81831ac376caae472b51082d6582 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 10 Sep 2019 12:49:20 +0200
Subject: [PATCH 4/9] Fix of #1266 and #2258 In case there were empty object
 layers supposed to be floating on supports which were set to use a specific
 extruder, wipe tower was missing layer required to do the toolchange, leading
 to a crash Such cases are now detected and layers that need it are
 additionally assigned as wipe tower layers

Also tracked as SPE-526
---
 src/libslic3r/GCode/ToolOrdering.cpp | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp
index 677d6b868..0a9ec320e 100644
--- a/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/src/libslic3r/GCode/ToolOrdering.cpp
@@ -329,6 +329,28 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
         }
     }
 
+    // If the model contains empty layers (such as https://github.com/prusa3d/Slic3r/issues/1266), there might be layers
+    // that were not marked as has_wipe_tower, even when they should have been. This produces a crash with soluble supports
+    // and maybe other problems. We will therefore go through layer_tools and detect and fix this.
+    // So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder),
+    // we'll mark it with has_wipe tower.
+    for (unsigned int i=0; i+1<m_layer_tools.size(); ++i) {
+        LayerTools& lt = m_layer_tools[i];
+        LayerTools& lt_next = m_layer_tools[i+1];
+        if (lt.extruders.empty() || lt_next.extruders.empty())
+            break;
+        if (!lt_next.has_wipe_tower && (lt_next.extruders.front() != lt.extruders.back() || lt_next.extruders.size() > 1))
+            lt_next.has_wipe_tower = true;
+        // We should also check that the next wipe tower layer is no further than max_layer_height:
+        unsigned int j = i+1;
+        double last_wipe_tower_print_z = lt_next.print_z;
+        while (++j < m_layer_tools.size()-1 && !m_layer_tools[j].has_wipe_tower)
+            if (m_layer_tools[j+1].print_z - last_wipe_tower_print_z > max_layer_height) {
+                m_layer_tools[j].has_wipe_tower = true;
+                last_wipe_tower_print_z = m_layer_tools[j].print_z;
+            }
+    }
+
     // Calculate the wipe_tower_layer_height values.
     coordf_t wipe_tower_print_z_last = 0.;
     for (LayerTools &lt : m_layer_tools)

From 1c20c4c43d4c3c448e599c9d169749f522bb8ea5 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Tue, 10 Sep 2019 13:31:29 +0200
Subject: [PATCH 5/9] Fix arrangement of objects larger than the print bed.
 Issue #2897

---
 .../include/libnest2d/placers/nfpplacer.hpp   | 16 ++++++++++--
 .../libnest2d/selections/djd_heuristic.hpp    | 11 +-------
 .../include/libnest2d/selections/filler.hpp   |  9 ++++---
 .../include/libnest2d/selections/firstfit.hpp | 13 ++--------
 .../selections/selection_boilerplate.hpp      | 15 +++++++++++
 src/libslic3r/Arrange.cpp                     | 25 +++++++++++++------
 6 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp
index 4ef1fe71d..1a341d691 100644
--- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp
+++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp
@@ -546,7 +546,12 @@ public:
 
     inline explicit _NofitPolyPlacer(const BinType& bin):
         Base(bin),
-        norm_(std::sqrt(sl::area(bin))) {}
+        norm_(std::sqrt(sl::area(bin)))
+    {
+        // In order to not have items out of bin, it will be shrinked by an
+        // very little empiric offset value.
+        // sl::offset(bin_, 1e-5 * norm_);
+    }
 
     _NofitPolyPlacer(const _NofitPolyPlacer&) = default;
     _NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default;
@@ -1179,7 +1184,14 @@ private:
     }
 
     void setInitialPosition(Item& item) {
-        Box&& bb = item.boundingBox();
+        auto sh = item.rawShape();
+        sl::translate(sh, item.translation());
+        sl::rotate(sh, item.rotation());
+        
+        Box bb = sl::boundingBox(sh);
+        bb.minCorner() += item.translation();
+        bb.maxCorner() += item.translation();
+        
         Vertex ci, cb;
         auto bbin = sl::boundingBox(bin_);
 
diff --git a/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp b/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp
index f904210aa..30ee7b627 100644
--- a/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp
+++ b/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp
@@ -550,16 +550,7 @@ public:
             return ret;
         };
 
-        // Safety test: try to pack each item into an empty bin. If it fails
-        // then it should be removed from the not_packed list
-        { auto it = store_.begin();
-            while (it != store_.end() && !this->stopcond_()) {
-                Placer p(bin); p.configure(pconfig);
-                if(!p.pack(*it, rem(it, store_))) {
-                    it = store_.erase(it);
-                } else it++;
-            }
-        }
+        this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
 
         int acounter = int(store_.size());
         std::atomic_flag flg = ATOMIC_FLAG_INIT;
diff --git a/src/libnest2d/include/libnest2d/selections/filler.hpp b/src/libnest2d/include/libnest2d/selections/filler.hpp
index 19c44bfaa..3b6527d3e 100644
--- a/src/libnest2d/include/libnest2d/selections/filler.hpp
+++ b/src/libnest2d/include/libnest2d/selections/filler.hpp
@@ -30,7 +30,8 @@ public:
                    TBin&& bin,
                    PConfig&& pconfig = PConfig())
     {
-
+        using Placer = PlacementStrategyLike<TPlacer>;
+        
         store_.clear();
         auto total = last-first;
         store_.reserve(total);
@@ -57,10 +58,12 @@ public:
         auto sortfunc = [](Item& i1, Item& i2) {
             return i1.area() > i2.area();
         };
-
+        
+        this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
+        
         std::sort(store_.begin(), store_.end(), sortfunc);
 
-        PlacementStrategyLike<TPlacer> placer(bin);
+        Placer placer(bin);
         placer.configure(pconfig);
 
         auto it = store_.begin();
diff --git a/src/libnest2d/include/libnest2d/selections/firstfit.hpp b/src/libnest2d/include/libnest2d/selections/firstfit.hpp
index 5585e565d..373e8b618 100644
--- a/src/libnest2d/include/libnest2d/selections/firstfit.hpp
+++ b/src/libnest2d/include/libnest2d/selections/firstfit.hpp
@@ -77,17 +77,8 @@ public:
         };
 
         auto& cancelled = this->stopcond_;
-
-        // Safety test: try to pack each item into an empty bin. If it fails
-        // then it should be removed from the list
-        { auto it = store_.begin();
-            while (it != store_.end() && !cancelled()) {
-                Placer p(bin); p.configure(pconfig);
-                if(!p.pack(*it)) {
-                    it = store_.erase(it);
-                } else it++;
-            }
-        }
+        
+        this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
 
         auto it = store_.begin();
 
diff --git a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp
index 9ae92fe29..741893078 100644
--- a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp
+++ b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp
@@ -25,6 +25,21 @@ public:
     inline void clear() { packed_bins_.clear(); }
 
 protected:
+    
+    template<class Placer, class Container, class Bin, class PCfg>
+    void remove_unpackable_items(Container &c, const Bin &bin, const PCfg& pcfg)
+    {
+        // Safety test: try to pack each item into an empty bin. If it fails
+        // then it should be removed from the list
+        auto it = c.begin();
+        while (it != c.end() && !stopcond_()) {
+            Placer p{bin};
+            p.configure(pcfg);
+            Item cpy{*it};
+            if (!p.pack(cpy)) it = c.erase(it);
+            else it++;
+        }
+    }
 
     PackGroup packed_bins_;
     ProgressFunction progress_ = [](unsigned){};
diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp
index 34e07302a..52168c929 100644
--- a/src/libslic3r/Arrange.cpp
+++ b/src/libslic3r/Arrange.cpp
@@ -350,6 +350,12 @@ public:
         m_pck.configure(m_pconf);
     }
     
+    AutoArranger(const TBin &                  bin,
+                 std::function<void(unsigned)> progressind,
+                 std::function<bool(void)>     stopcond)
+        : AutoArranger{bin, 0 /* no min distance */, progressind, stopcond}
+    {}
+     
     template<class It> inline void operator()(It from, It to) {
         m_rtree.clear();
         m_item_count += size_t(to - from);
@@ -553,13 +559,21 @@ BedShapeHint &BedShapeHint::operator=(const BedShapeHint &cpy)
     return *this;
 }
 
+template<class Bin> void remove_large_items(std::vector<Item> &items, Bin &&bin)
+{
+    auto it = items.begin();
+    while (it != items.end())
+        sl::isInside(it->transformedShape(), bin) ?
+            ++it : it = items.erase(it);
+}
+
 template<class BinT> // Arrange for arbitrary bin type
 void _arrange(
         std::vector<Item> &           shapes,
         std::vector<Item> &           excludes,
         const BinT &                  bin,
         coord_t                       minobjd,
-        std::function<void(unsigned)> prind,
+        std::function<void(unsigned)> progressfn,
         std::function<bool()>         stopfn)
 {
     // Integer ceiling the min distance from the bed perimeters
@@ -569,16 +583,13 @@ void _arrange(
     auto corrected_bin = bin;
     sl::offset(corrected_bin, md);
     
-    AutoArranger<BinT> arranger{corrected_bin, 0, prind, stopfn};
+    AutoArranger<BinT> arranger{corrected_bin, progressfn, stopfn};
     
     auto infl = coord_t(std::ceil(minobjd / 2.0));
     for (Item& itm : shapes) itm.inflate(infl);
     for (Item& itm : excludes) itm.inflate(infl);
     
-    auto it = excludes.begin();
-    while (it != excludes.end())
-        sl::isInside(it->transformedShape(), corrected_bin) ?
-            ++it : it = excludes.erase(it);
+    remove_large_items(excludes, corrected_bin);
 
     // If there is something on the plate
     if (!excludes.empty()) arranger.preload(excludes);
@@ -674,7 +685,7 @@ void arrange(ArrangePolygons &             arrangables,
         _arrange(items, fixeditems, Box::infinite(), min_obj_dist, pri, cfn);
         break;
     }
-    };
+    }
     
     for(size_t i = 0; i < items.size(); ++i) {
         clppr::IntPoint tr = items[i].translation();

From 84e8081413b7b57b9280fec57c61fd0508cd9fdb Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Tue, 10 Sep 2019 14:00:48 +0200
Subject: [PATCH 6/9] Fix compilation on OSX

---
 .../include/libnest2d/selections/selection_boilerplate.hpp     | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp
index 741893078..4bb2e72af 100644
--- a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp
+++ b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp
@@ -35,7 +35,8 @@ protected:
         while (it != c.end() && !stopcond_()) {
             Placer p{bin};
             p.configure(pcfg);
-            Item cpy{*it};
+            const Item& itm = *it;
+            Item cpy{itm};
             if (!p.pack(cpy)) it = c.erase(it);
             else it++;
         }

From 246dc64c99250449b709618bf0816af7d64831e6 Mon Sep 17 00:00:00 2001
From: bubnikv <bubnikv@gmail.com>
Date: Tue, 10 Sep 2019 19:03:37 +0200
Subject: [PATCH 7/9] Fix of "Bridging and gap fill are parsed incorrectly when
 infill is set to 0" #1476

The gap fill was disabled for zero infill.
Now the gap fill is enabled in between the perimeters, but disabled between
the inner-most perimeter and infill in case the infill is set to zero.

Also in case there are multiple infill regions inside a perimeter,
the mutliple infills are considered as non-zero if at least one infill
is non-zero, therefore the gap fill will be added inside the inner-most
perimeter.
---
 src/libslic3r/Layer.cpp               | 13 +++++++++----
 src/libslic3r/PerimeterGenerator.cpp  | 10 ++++++++--
 src/slic3r/GUI/ConfigManipulation.cpp |  3 ++-
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp
index 399833c69..4ac64b777 100644
--- a/src/libslic3r/Layer.cpp
+++ b/src/libslic3r/Layer.cpp
@@ -121,7 +121,6 @@ void Layer::make_perimeters()
         for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it) {
             LayerRegion* other_layerm = *it;
             const PrintRegionConfig &other_config = other_layerm->region()->config();
-            
             if (config.perimeter_extruder   == other_config.perimeter_extruder
                 && config.perimeters        == other_config.perimeters
                 && config.perimeter_speed   == other_config.perimeter_speed
@@ -130,7 +129,8 @@ void Layer::make_perimeters()
                 && config.overhangs         == other_config.overhangs
                 && config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width")
                 && config.thin_walls        == other_config.thin_walls
-                && config.external_perimeters_first == other_config.external_perimeters_first) {
+                && config.external_perimeters_first == other_config.external_perimeters_first
+                && config.infill_overlap    == other_config.infill_overlap) {
                 layerms.push_back(other_layerm);
                 done[it - m_regions.begin()] = true;
             }
@@ -142,12 +142,17 @@ void Layer::make_perimeters()
             (*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
         } else {
             SurfaceCollection new_slices;
+            // Use the region with highest infill rate, as the make_perimeters() function below decides on the gap fill based on the infill existence.
+            LayerRegion *layerm_config = layerms.front();
             {
                 // group slices (surfaces) according to number of extra perimeters
                 std::map<unsigned short, Surfaces> slices;  // extra_perimeters => [ surface, surface... ]
-                for (LayerRegion *layerm : layerms)
+                for (LayerRegion *layerm : layerms) {
                     for (Surface &surface : layerm->slices.surfaces)
                         slices[surface.extra_perimeters].emplace_back(surface);
+                    if (layerm->region()->config().fill_density > layerm_config->region()->config().fill_density)
+                    	layerm_config = layerm;
+                }
                 // merge the surfaces assigned to each group
                 for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
                     new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front());
@@ -155,7 +160,7 @@ void Layer::make_perimeters()
             
             // make perimeters
             SurfaceCollection fill_surfaces;
-            (*layerm)->make_perimeters(new_slices, &fill_surfaces);
+            layerm_config->make_perimeters(new_slices, &fill_surfaces);
 
             // assign fill_surfaces to each layer
             if (!fill_surfaces.surfaces.empty()) { 
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index 4dac192ad..74df07935 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -37,7 +37,8 @@ void PerimeterGenerator::process()
     // internal flow which is unrelated.
     coord_t min_spacing         = perimeter_spacing      * (1 - INSET_OVERLAP_TOLERANCE);
     coord_t ext_min_spacing     = ext_perimeter_spacing  * (1 - INSET_OVERLAP_TOLERANCE);
-    
+    bool    has_gap_fill 		= this->config->gap_fill_speed.value > 0;
+
     // prepare grown lower layer slices for overhang detection
     if (this->lower_slices != NULL && this->config->overhangs) {
         // We consider overhang any part where the entire nozzle diameter is not supported by the
@@ -105,7 +106,7 @@ void PerimeterGenerator::process()
                         // leads to overflows, as in prusa3d/Slic3r GH #32
                         offset_ex(last, - distance);
                     // look for gaps
-                    if (this->config->gap_fill_speed.value > 0 && this->config->fill_density.value > 0)
+                    if (has_gap_fill)
                         // not using safety offset here would "detect" very narrow gaps
                         // (but still long enough to escape the area threshold) that gap fill
                         // won't be able to fill but we'd still remove from infill area
@@ -132,6 +133,11 @@ void PerimeterGenerator::process()
                     }
                 }
                 last = std::move(offsets);
+                if (i == loop_number && (! has_gap_fill || this->config->fill_density.value == 0)) {
+                	// The last run of this loop is executed to collect gaps for gap fill.
+                	// As the gap fill is either disabled or not 
+                	break;
+                }
             }
 
             // nest loops: holes first
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index 2f37eb894..c9cdff162 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -243,7 +243,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
                     "infill_speed", "bridge_speed" })
         toggle_field(el, have_infill || have_solid_infill);
 
-    toggle_field("gap_fill_speed", have_perimeters && have_infill);
+    // Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
+    toggle_field("gap_fill_speed", have_perimeters);
 
     bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0;
     for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })

From 413e737d7e8e30079e61514f525263a437e5e308 Mon Sep 17 00:00:00 2001
From: bubnikv <bubnikv@gmail.com>
Date: Tue, 10 Sep 2019 19:08:04 +0200
Subject: [PATCH 8/9] Fix of previous infill refactoring.

---
 src/libslic3r/Fill/Fill.cpp | 65 ++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 15 deletions(-)

diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 77cb5f47f..ad308adab 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -116,7 +116,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 	        	has_internal_voids = true;
 	        else {
 		        FlowRole extrusion_role = (surface.surface_type == stTop) ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill);
-		        bool     is_bridge 	    = layerm.layer()->id() > 0 && surface.is_bridge();
+		        bool     is_bridge 	    = layer.id() > 0 && surface.is_bridge();
 		        params.extruder 	 = layerm.region()->extruder(extrusion_role);
 		        params.pattern 		 = layerm.region()->config().fill_pattern.value;
 		        params.density       = float(layerm.region()->config().fill_density);
@@ -141,11 +141,11 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 		        // calculate the actual flow we'll be using for this infill
 		        params.flow = layerm.region()->flow(
 		            extrusion_role,
-		            (surface.thickness == -1) ? layerm.layer()->height : surface.thickness, // extrusion height
-		            is_bridge || Fill::use_bridge_flow(params.pattern), 					// bridge flow?
-		            layerm.layer()->id() == 0,          									// first layer?
-		            -1,                                 									// auto width
-		            *layerm.layer()->object()
+		            (surface.thickness == -1) ? layer.height : surface.thickness, 	// extrusion height
+		            is_bridge || Fill::use_bridge_flow(params.pattern), 			// bridge flow?
+		            layer.id() == 0,          										// first layer?
+		            -1,                                 							// auto width
+		            *layer.object()
 		        );
 		        
 		        // Calculate flow spacing for infill pattern generation.
@@ -156,7 +156,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 		            // layer height
 		            params.spacing = layerm.region()->flow(
 			                frInfill,
-			                layerm.layer()->object()->config().layer_height.value,  // TODO: handle infill_every_layers?
+			                layer.object()->config().layer_height.value,  // TODO: handle infill_every_layers?
 			                false,  // no bridge
 			                false,  // no first layer
 			                -1,     // auto width
@@ -199,12 +199,14 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 		Polygons all_polygons;
 		for (SurfaceFill &fill : surface_fills)
 			if (! fill.expolygons.empty()) {
-				Polygons polys = to_polygons(std::move(fill.expolygons));
-				if (fill.expolygons.size() > 1 || ! all_polygons.empty())
+				if (fill.expolygons.size() > 1 || ! all_polygons.empty()) {
+					Polygons polys = to_polygons(std::move(fill.expolygons));
 		            // Make a union of polygons, use a safety offset, subtract the preceding polygons.
 				    // Bridges are processed first (see SurfaceFill::operator<())
 		            fill.expolygons = all_polygons.empty() ? union_ex(polys, true) : diff_ex(polys, all_polygons, true);
-				append(all_polygons, std::move(polys));
+					append(all_polygons, std::move(polys));
+				} else if (&fill != &surface_fills.back())
+					append(all_polygons, to_polygons(fill.expolygons));
 	        }
 	}
 
@@ -259,7 +261,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 				region_id = region_some_infill;
 			const LayerRegion& layerm = *layer.regions()[region_id];
 	        for (SurfaceFill &surface_fill : surface_fills)
-	        	if (surface_fill.surface.surface_type == stInternalSolid && std::abs(layerm.layer()->height - surface_fill.params.flow.height) < EPSILON) {
+	        	if (surface_fill.surface.surface_type == stInternalSolid && std::abs(layer.height - surface_fill.params.flow.height) < EPSILON) {
 	        		internal_solid_fill = &surface_fill;
 	        		break;
 	        	}
@@ -273,10 +275,10 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 		        // calculate the actual flow we'll be using for this infill
 		        params.flow = layerm.region()->flow(
 		            frSolidInfill,
-		            layerm.layer()->height, 		// extrusion height
-		            false, 							// bridge flow?
-		            layerm.layer()->id() == 0,      // first layer?
-		            -1,                             // auto width
+		            layer.height, 		// extrusion height
+		            false, 				// bridge flow?
+		            layer.id() == 0,    // first layer?
+		            -1,                 // auto width
 		            *layer.object()
 		        );
 		        params.spacing = params.flow.spacing();	        
@@ -294,15 +296,48 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 	return surface_fills;
 }
 
+#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
+void export_group_fills_to_svg(const char *path, const std::vector<SurfaceFill> &fills)
+{
+    BoundingBox bbox;
+    for (const auto &fill : fills)
+        for (const auto &expoly : fill.expolygons)
+            bbox.merge(get_extents(expoly));
+    Point legend_size = export_surface_type_legend_to_svg_box_size();
+    Point legend_pos(bbox.min(0), bbox.max(1));
+    bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
+
+    SVG svg(path, bbox);
+    const float transparency = 0.5f;
+    for (const auto &fill : fills)
+        for (const auto &expoly : fill.expolygons)
+            svg.draw(expoly, surface_type_to_color_name(fill.surface.surface_type), transparency);
+    export_surface_type_legend_to_svg(svg, legend_pos);
+    svg.Close(); 
+}
+#endif
+
 // friend to Layer
 void Layer::make_fills()
 {
 	for (LayerRegion *layerm : m_regions)
 		layerm->fills.clear();
 
+
+#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
+//	this->export_region_fill_surfaces_to_svg_debug("10_fill-initial");
+#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
+
 	std::vector<SurfaceFill>  surface_fills = group_fills(*this);
 	const Slic3r::BoundingBox bbox = this->object()->bounding_box();
 
+#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
+	{
+		static int iRun = 0;
+		export_group_fills_to_svg(debug_out_path("Layer-fill_surfaces-10_fill-final-%d.svg", iRun ++).c_str(), surface_fills);
+	}
+#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
+
     for (SurfaceFill &surface_fill : surface_fills) {
         // Create the filler object.
         std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));

From b9389f2d39171a72c7dd81eb0c77cd9d9bceb725 Mon Sep 17 00:00:00 2001
From: bubnikv <bubnikv@gmail.com>
Date: Tue, 10 Sep 2019 19:09:37 +0200
Subject: [PATCH 9/9] Some C++11 refactoring

---
 src/libslic3r/LayerRegion.cpp | 23 ++++++++++-------------
 src/libslic3r/PrintConfig.cpp |  2 +-
 2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp
index 3fc8d03d1..6fc0b4e37 100644
--- a/src/libslic3r/LayerRegion.cpp
+++ b/src/libslic3r/LayerRegion.cpp
@@ -365,26 +365,23 @@ void LayerRegion::prepare_fill_surfaces()
     
     // if no solid layers are requested, turn top/bottom surfaces to internal
     if (this->region()->config().top_solid_layers == 0) {
-        for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
-            if (surface->surface_type == stTop)
-                surface->surface_type = (this->layer()->object()->config().infill_only_where_needed) ? 
-                    stInternalVoid : stInternal;
+        for (Surface &surface : this->fill_surfaces.surfaces)
+            if (surface.is_top())
+                surface.surface_type = this->layer()->object()->config().infill_only_where_needed ? stInternalVoid : stInternal;
     }
     if (this->region()->config().bottom_solid_layers == 0) {
-        for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
-            if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge)
-                surface->surface_type = stInternal;
-        }
+        for (Surface &surface : this->fill_surfaces.surfaces)
+            if (surface.is_bottom()) // (surface.surface_type == stBottom)
+                surface.surface_type = stInternal;
     }
-        
+
     // turn too small internal regions into solid regions according to the user setting
     if (this->region()->config().fill_density.value > 0) {
         // scaling an area requires two calls!
         double min_area = scale_(scale_(this->region()->config().solid_infill_below_area.value));
-        for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
-            if (surface->surface_type == stInternal && surface->area() <= min_area)
-                surface->surface_type = stInternalSolid;
-        }
+        for (Surface &surface : this->fill_surfaces.surfaces)
+            if (surface.surface_type == stInternal && surface.area() <= min_area)
+                surface.surface_type = stInternalSolid;
     }
 
 #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index c4cc5e31d..1ce00f269 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -2894,7 +2894,7 @@ void DynamicPrintConfig::normalize()
         {
             this->opt<ConfigOptionInt>("perimeters", true)->value       = 1;
             this->opt<ConfigOptionInt>("top_solid_layers", true)->value = 0;
-            this->opt<ConfigOptionPercent>("fill_density", true)->value  = 0;
+            this->opt<ConfigOptionPercent>("fill_density", true)->value = 0;
         }
     }
 }