From b06030f2bce0226bc83586ac74cc4b89b718841b Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Tue, 23 Feb 2021 19:23:35 +0100
Subject: [PATCH 01/53] creality.ini: allow slightly steeper unsupported angles

---
 resources/profiles/Creality.ini | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 1426ee596..e66df8f66 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -335,7 +335,7 @@ support_material_pattern = rectilinear
 support_material_spacing = 2
 support_material_speed = 40
 support_material_synchronize_layers = 0
-support_material_threshold = 45
+support_material_threshold = 40
 support_material_with_sheath = 0
 support_material_xy_spacing = 60%
 thin_walls = 0

From f9b4bbb016566eead32d32092939a88c10c80f1f Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Tue, 23 Feb 2021 19:53:30 +0100
Subject: [PATCH 02/53] creality.ini: more accurate extruder_clearance for
 Ender-3

radius = 47mm = 45mm carriage (including bltouch upgrade)
              +  2mm safety margin

height = 34mm = 30mm nozzle
              +  2mm bltouch probe pin
              +  2mm safety margin
---
 resources/profiles/Creality.ini | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index e66df8f66..e09f829d8 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -269,8 +269,8 @@ external_perimeters_first = 0
 external_perimeter_extrusion_width = 0.45
 external_perimeter_speed = 25
 extra_perimeters = 0
-extruder_clearance_height = 25
-extruder_clearance_radius = 45
+extruder_clearance_height = 34
+extruder_clearance_radius = 47
 extrusion_width = 0.45
 fill_angle = 45
 fill_density = 20%

From 9b7621dc7e5c824b468342d4bad81b826b2e7e86 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Tue, 23 Feb 2021 20:06:55 +0100
Subject: [PATCH 03/53] creality.ini: double digit layer height (cosmetic)

---
 resources/profiles/Creality.ini | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index e09f829d8..9d86d3dea 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -359,7 +359,7 @@ top_solid_layers = 11
 
 [print:*0.10mm*]
 inherits = *common*
-layer_height = 0.1
+layer_height = 0.10
 perimeters = 3
 bottom_solid_layers = 7
 top_solid_layers = 9

From 539e80e890abcdd7c19233339f577e1833f203d4 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Wed, 24 Feb 2021 19:49:38 +0100
Subject: [PATCH 04/53] Fix of supports create overkill material that actually
 sopports nothing above it. #2245 When expanding the 1st layer support layer,
 do it by small steps while trimming with object to avoid supports to leak
 through object walls.

---
 src/libslic3r/SupportMaterial.cpp | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp
index cbe9ffb1b..d9efd7553 100644
--- a/src/libslic3r/SupportMaterial.cpp
+++ b/src/libslic3r/SupportMaterial.cpp
@@ -2643,9 +2643,18 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
         }
     } else if (columns_base != nullptr) {
         // Expand the bases of the support columns in the 1st layer.
-        columns_base->polygons = diff(
-            inflate_factor_1st_layer > 0 ? offset(columns_base->polygons, inflate_factor_1st_layer) : columns_base->polygons,
-            offset(m_object->layers().front()->lslices, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS));
+        {
+            Polygons &raft     = columns_base->polygons;
+            Polygons  trimming = offset(m_object->layers().front()->lslices, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS);
+            if (inflate_factor_1st_layer > SCALED_EPSILON) {
+                // Inflate in multiple steps to avoid leaking of the support 1st layer through object walls.
+                auto  nsteps = std::max(5, int(ceil(inflate_factor_1st_layer / m_first_layer_flow.scaled_width())));
+                float step   = inflate_factor_1st_layer / nsteps;
+                for (int i = 0; i < nsteps; ++ i)
+                    raft = diff(offset(raft, step), trimming);
+            } else
+                raft = diff(raft, trimming);
+        }
         if (contacts != nullptr)
             columns_base->polygons = diff(columns_base->polygons, interface_polygons);
         if (! brim.empty()) {

From 6f5bf71f11b989e056ef8e31ff811548443085c2 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Wed, 24 Feb 2021 19:53:50 +0100
Subject: [PATCH 05/53] Fixing some compiler warnings

---
 src/libslic3r/PrintConfig.hpp | 2 +-
 src/slic3r/GUI/Tab.cpp        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index f56316356..c1e3f82cb 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -513,7 +513,7 @@ public:
     ConfigOptionFloat               support_material_interface_spacing;
     ConfigOptionFloatOrPercent      support_material_interface_speed;
     ConfigOptionEnum<SupportMaterialPattern> support_material_pattern;
-    ConfigOptionEnum<SupportMaterialPattern> support_material_interface_pattern;
+    ConfigOptionEnum<SupportMaterialInterfacePattern> support_material_interface_pattern;
     // Spacing between support material lines (the hatching distance).
     ConfigOptionFloat               support_material_spacing;
     ConfigOptionFloat               support_material_speed;
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 374789815..947c058a4 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -3834,7 +3834,7 @@ bool Tab::validate_custom_gcodes()
 {
     bool valid = true;
     if ((m_type == Preset::TYPE_FILAMENT || 
-        m_type == Preset::TYPE_PRINTER && static_cast<TabPrinter*>(this)->m_printer_technology == ptFFF) &&
+        (m_type == Preset::TYPE_PRINTER && static_cast<TabPrinter*>(this)->m_printer_technology == ptFFF)) &&
         m_active_page->title() == "Custom G-code") {
             for (auto opt_group : m_active_page->m_optgroups) {
                 assert(opt_group->opt_map().size() == 1);

From 1e33b95ed71fcee14197501cabc43c6c24dbc68b Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Thu, 25 Feb 2021 08:23:45 +0100
Subject: [PATCH 06/53] Follow-up of 33aa6be7b7f3d8b81d6b948f9bd6841db10b61cf
 -> Validation of custom g-code added using vertical slider in preview at
 gcode generation level

---
 src/libslic3r/GCode.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index f3bffe331..c7b2c8f78 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -667,6 +667,14 @@ namespace DoExport {
                     break;
             }
         }
+        if (ret.size() < MAX_TAGS_COUNT) {
+            const CustomGCode::Info& custom_gcode_per_print_z = print.model().custom_gcode_per_print_z;
+            for (const auto& gcode : custom_gcode_per_print_z.gcodes) {
+                check(_(L("Custom G-code")), gcode.extra);
+                if (ret.size() == MAX_TAGS_COUNT)
+                    break;
+            }
+        }
 
         return ret;
     }

From 43c05d35eaf60c52f355db044a38f2147dd695c5 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Thu, 25 Feb 2021 12:18:00 +0100
Subject: [PATCH 07/53] Fix of crash when using raft with modified Shape-Box
 with height 0.5mm #5652 Reworked skirt generator to only generate skirt at
 non-empty layers (layers that actually extruder object or support) and to
 respect minimum layer height. Skirt generator stops at the first layer where
 those both conditions cannot be met.

---
 src/libslic3r/GCode.cpp              | 36 ++++++-------
 src/libslic3r/GCode/ToolOrdering.cpp | 77 +++++++++++++++++++++++-----
 src/libslic3r/GCode/ToolOrdering.hpp | 14 ++---
 src/libslic3r/PrintObject.cpp        |  2 +-
 4 files changed, 87 insertions(+), 42 deletions(-)

diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index c7b2c8f78..26a206247 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1803,7 +1803,6 @@ namespace Skirt {
 
     static std::map<unsigned int, std::pair<size_t, size_t>> make_skirt_loops_per_extruder_1st_layer(
         const Print             				&print,
-        const std::vector<GCode::LayerToPrint> 	& /*layers */,
         const LayerTools                		&layer_tools,
         // Heights (print_z) at which the skirt has already been extruded.
         std::vector<coordf_t>  			    	&skirt_done)
@@ -1811,7 +1810,8 @@ namespace Skirt {
         // Extrude skirt at the print_z of the raft layers and normal object layers
         // not at the print_z of the interlaced support material layers.
         std::map<unsigned int, std::pair<size_t, size_t>> skirt_loops_per_extruder_out;
-        if (skirt_done.empty() && print.has_skirt() && ! print.skirt().entities.empty()) {
+        assert(skirt_done.empty());
+        if (skirt_done.empty() && print.has_skirt() && ! print.skirt().entities.empty() && layer_tools.has_skirt) {
             skirt_loops_per_extruder_all_printing(print, layer_tools, skirt_loops_per_extruder_out);
             skirt_done.emplace_back(layer_tools.print_z);
         }
@@ -1820,36 +1820,34 @@ namespace Skirt {
 
     static std::map<unsigned int, std::pair<size_t, size_t>> make_skirt_loops_per_extruder_other_layers(
         const Print 							&print,
-        const std::vector<GCode::LayerToPrint> 	&layers,
         const LayerTools                		&layer_tools,
-        // First non-empty support layer.
-        const SupportLayer  					*support_layer,
         // Heights (print_z) at which the skirt has already been extruded.
         std::vector<coordf_t>			    	&skirt_done)
     {
         // Extrude skirt at the print_z of the raft layers and normal object layers
         // not at the print_z of the interlaced support material layers.
         std::map<unsigned int, std::pair<size_t, size_t>> skirt_loops_per_extruder_out;
-        if (print.has_skirt() && ! print.skirt().entities.empty() &&
+        if (print.has_skirt() && ! print.skirt().entities.empty() && layer_tools.has_skirt &&
             // Not enough skirt layers printed yet.
             //FIXME infinite or high skirt does not make sense for sequential print!
-            (skirt_done.size() < (size_t)print.config().skirt_height.value || print.has_infinite_skirt()) &&
+            (skirt_done.size() < (size_t)print.config().skirt_height.value || print.has_infinite_skirt())) {
+            bool valid = ! skirt_done.empty() && skirt_done.back() < layer_tools.print_z - EPSILON;
+            assert(valid);
             // This print_z has not been extruded yet (sequential print)
             // FIXME: The skirt_done should not be empty at this point. The check is a workaround
             // of https://github.com/prusa3d/PrusaSlicer/issues/5652, but it deserves a real fix.
-            (! skirt_done.empty() && skirt_done.back() < layer_tools.print_z - EPSILON) &&
-            // and this layer is an object layer, or it is a raft layer.
-            (layer_tools.has_object || support_layer->id() < (size_t)support_layer->object()->config().raft_layers.value)) {
+            if (valid) {
 #if 0
-            // Prime just the first printing extruder. This is original Slic3r's implementation.
-            skirt_loops_per_extruder_out[layer_tools.extruders.front()] = std::pair<size_t, size_t>(0, print.config().skirts.value);
+                // Prime just the first printing extruder. This is original Slic3r's implementation.
+                skirt_loops_per_extruder_out[layer_tools.extruders.front()] = std::pair<size_t, size_t>(0, print.config().skirts.value);
 #else
-            // Prime all extruders planned for this layer, see
-            // https://github.com/prusa3d/PrusaSlicer/issues/469#issuecomment-322450619
-            skirt_loops_per_extruder_all_printing(print, layer_tools, skirt_loops_per_extruder_out);
+                // Prime all extruders planned for this layer, see
+                // https://github.com/prusa3d/PrusaSlicer/issues/469#issuecomment-322450619
+                skirt_loops_per_extruder_all_printing(print, layer_tools, skirt_loops_per_extruder_out);
 #endif
-            assert(!skirt_done.empty());
-            skirt_done.emplace_back(layer_tools.print_z);
+                assert(!skirt_done.empty());
+                skirt_done.emplace_back(layer_tools.print_z);
+            }
         }
         return skirt_loops_per_extruder_out;
     }
@@ -1992,8 +1990,8 @@ void GCode::process_layer(
     // Extrude skirt at the print_z of the raft layers and normal object layers
     // not at the print_z of the interlaced support material layers.
     skirt_loops_per_extruder = first_layer ?
-        Skirt::make_skirt_loops_per_extruder_1st_layer(print, layers, layer_tools, m_skirt_done) :
-        Skirt::make_skirt_loops_per_extruder_other_layers(print, layers, layer_tools, support_layer, m_skirt_done);
+        Skirt::make_skirt_loops_per_extruder_1st_layer(print, layer_tools, m_skirt_done) :
+        Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done);
 
     // Group extrusions by an extruder, then by an object, an island and a region.
     std::map<unsigned int, std::vector<ObjectByExtruder>> by_extruder;
diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp
index fae4028de..8520cf35b 100644
--- a/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/src/libslic3r/GCode/ToolOrdering.cpp
@@ -70,6 +70,20 @@ unsigned int LayerTools::extruder(const ExtrusionEntityCollection &extrusions, c
 	return (extruder == 0) ? 0 : extruder - 1;
 }
 
+static double calc_max_layer_height(const PrintConfig &config, double max_object_layer_height)
+{
+    double max_layer_height = std::numeric_limits<double>::max();
+    for (size_t i = 0; i < config.nozzle_diameter.values.size(); ++ i) {
+        double mlh = config.max_layer_height.values[i];
+        if (mlh == 0.)
+            mlh = 0.75 * config.nozzle_diameter.values[i];
+        max_layer_height = std::min(max_layer_height, mlh);
+    }
+    // The Prusa3D Fast (0.35mm layer height) print profile sets a higher layer height than what is normally allowed
+    // by the nozzle. This is a hack and it works by increasing extrusion width. See GH #3919.
+    return std::max(max_layer_height, max_object_layer_height);
+}
+
 // For the use case when each object is printed separately
 // (print.config().complete_objects is true).
 ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extruder, bool prime_multi_material)
@@ -87,6 +101,7 @@ ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extrude
             zs.emplace_back(layer->print_z);
         this->initialize_layers(zs);
     }
+    double max_layer_height = calc_max_layer_height(object.print()->config(), object.config().layer_height);
 
     // Collect extruders reuqired to print the layers.
     this->collect_extruders(object, std::vector<std::pair<double, unsigned int>>());
@@ -94,9 +109,11 @@ ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extrude
     // Reorder the extruders to minimize tool switches.
     this->reorder_extruders(first_extruder);
 
-    this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height, object.config().layer_height);
+    this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height, max_layer_height);
 
     this->collect_extruder_statistics(prime_multi_material);
+
+    this->mark_skirt_layers(object.print()->config(), max_layer_height);
 }
 
 // For the use case when all objects are printed at once.
@@ -128,6 +145,7 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
         }
         this->initialize_layers(zs);
     }
+    max_layer_height = calc_max_layer_height(print.config(), max_layer_height);
 
 	// Use the extruder switches from Model::custom_gcode_per_print_z to override the extruder to print the object.
 	// Do it only if all the objects were configured to be printed with a single extruder.
@@ -150,6 +168,8 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
     this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
 
     this->collect_extruder_statistics(prime_multi_material);
+
+    this->mark_skirt_layers(print.config(), max_layer_height);
 }
 
 void ToolOrdering::initialize_layers(std::vector<coordf_t> &zs)
@@ -321,7 +341,7 @@ void ToolOrdering::reorder_extruders(unsigned int last_extruder_id)
         }    
 }
 
-void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_object_layer_height)
+void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height)
 {
     if (m_layer_tools.empty())
         return;
@@ -347,17 +367,6 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
         lt.has_wipe_tower = (lt.has_object && lt.wipe_tower_partitions > 0) || lt.print_z < object_bottom_z + EPSILON;
 
     // Test for a raft, insert additional wipe tower layer to fill in the raft separation gap.
-    double max_layer_height = std::numeric_limits<double>::max();
-    for (size_t i = 0; i < config.nozzle_diameter.values.size(); ++ i) {
-        double mlh = config.max_layer_height.values[i];
-        if (mlh == 0.)
-            mlh = 0.75 * config.nozzle_diameter.values[i];
-        max_layer_height = std::min(max_layer_height, mlh);
-    }
-    // The Prusa3D Fast (0.35mm layer height) print profile sets a higher layer height than what is normally allowed
-    // by the nozzle. This is a hack and it works by increasing extrusion width. See GH #3919.
-    max_layer_height = std::max(max_layer_height, max_object_layer_height);
-
     for (size_t i = 0; i + 1 < m_layer_tools.size(); ++ i) {
         const LayerTools &lt      = m_layer_tools[i];
         const LayerTools &lt_next = m_layer_tools[i + 1];
@@ -460,6 +469,48 @@ void ToolOrdering::collect_extruder_statistics(bool prime_multi_material)
     }
 }
 
+// Layers are marked for infinite skirt aka draft shield. Not all the layers have to be printed.
+void ToolOrdering::mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height)
+{
+    if (m_layer_tools.empty())
+        return;
+
+    if (m_layer_tools.front().extruders.empty()) {
+        // Empty first layer, no skirt will be printed.
+        //FIXME throw an exception?
+        return;
+    }
+
+    size_t i = 0;
+    for (;;) {
+        m_layer_tools[i].has_skirt = true;
+        size_t j = i + 1;
+        for (; j < m_layer_tools.size() && ! m_layer_tools[j].has_object; ++ j);
+        // i and j are two successive layers printing an object.
+        if (j == m_layer_tools.size())
+            // Don't print skirt above the last object layer.
+            break;
+        // Mark some printing intermediate layers as having skirt.
+        double last_z = m_layer_tools[i].print_z;
+        for (size_t k = i + 1; k < j; ++ k) {
+            if (m_layer_tools[k + 1].print_z - last_z > max_layer_height + EPSILON) {
+                // Layer k is the last one not violating the maximum layer height.
+                // Don't extrude skirt on empty layers.
+                while (m_layer_tools[k].extruders.empty())
+                    -- k;
+                if (m_layer_tools[k].has_skirt) {
+                    // Skirt cannot be generated due to empty layers, there would be a missing layer in the skirt.
+                    //FIXME throw an exception?
+                    break;
+                }
+                m_layer_tools[k].has_skirt = true;
+                last_z = m_layer_tools[k].print_z;
+            }
+        }
+        i = j;
+    }
+}
+
 // Assign a pointer to a custom G-code to the respective ToolOrdering::LayerTools.
 // Ignore color changes, which are performed on a layer and for such an extruder, that the extruder will not be printing above that layer.
 // If multiple events are planned over a span of a single layer, use the last one.
diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp
index e2e07533f..036730325 100644
--- a/src/libslic3r/GCode/ToolOrdering.hpp
+++ b/src/libslic3r/GCode/ToolOrdering.hpp
@@ -17,8 +17,6 @@ class LayerTools;
 namespace CustomGCode { struct Item; }
 class PrintRegion;
 
-
-
 // Object of this class holds information about whether an extrusion is printed immediately
 // after a toolchange (as part of infill/perimeter wiping) or not. One extrusion can be a part
 // of several copies - this has to be taken into account.
@@ -69,8 +67,6 @@ private:
     const LayerTools* m_layer_tools = nullptr;    // so we know which LayerTools object this belongs to
 };
 
-
-
 class LayerTools
 {
 public:
@@ -99,6 +95,9 @@ public:
     // If per layer extruder switches are inserted by the G-code preview slider, this value contains the new (1 based) extruder, with which the whole object layer is being printed with.
     // If not overriden, it is set to 0.
     unsigned int 				extruder_override = 0;
+    // Should a skirt be printed at this layer?
+    // Layers are marked for infinite skirt aka draft shield. Not all the layers have to be printed.
+    bool                        has_skirt = false;
     // Will there be anything extruded on this layer for the wipe tower?
     // Due to the support layers possibly interleaving the object layers,
     // wipe tower will be disabled for some support only layers.
@@ -120,12 +119,10 @@ private:
     WipingExtrusions m_wiping_extrusions;
 };
 
-
-
 class ToolOrdering
 {
 public:
-    ToolOrdering() {}
+    ToolOrdering() = default;
 
     // For the use case when each object is printed separately
     // (print.config.complete_objects is true).
@@ -169,6 +166,7 @@ private:
     void 				collect_extruders(const PrintObject &object, const std::vector<std::pair<double, unsigned int>> &per_layer_extruder_switches);
     void				reorder_extruders(unsigned int last_extruder_id);
     void 				fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height);
+    void                mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height);
     void 				collect_extruder_statistics(bool prime_multi_material);
 
     std::vector<LayerTools>    m_layer_tools;
@@ -182,8 +180,6 @@ private:
     const PrintConfig*         m_print_config_ptr = nullptr;
 };
 
-
-
 } // namespace SLic3r
 
 #endif /* slic3r_ToolOrdering_hpp_ */
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 84fdf3f62..c963418c3 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -418,7 +418,7 @@ void PrintObject::generate_support_material()
 {
     if (this->set_started(posSupportMaterial)) {
         this->clear_support_layers();
-        if (this->has_support_material() && m_layers.size() > 1) {
+        if ((this->has_support() && m_layers.size() > 1) || (this->has_raft() && ! m_layers.empty())) {
             m_print->set_status(85, L("Generating support material"));    
             this->_generate_support_material();
             m_print->throw_if_canceled();

From 6e73ddab8efbb8f3b64ba9bf75f10f856d2c8c30 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Thu, 25 Feb 2021 12:29:08 +0100
Subject: [PATCH 08/53] Support generator: Debugging visualization of "don't
 support bridges". Fixed a bug in raft generator - 1st layer did not respect
 the 1st layer density.

---
 src/libslic3r/SupportMaterial.cpp | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp
index d9efd7553..9a984ba39 100644
--- a/src/libslic3r/SupportMaterial.cpp
+++ b/src/libslic3r/SupportMaterial.cpp
@@ -1264,6 +1264,14 @@ namespace SupportMaterialInternal {
                 offset(layerm->unsupported_bridge_edges, scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS));
         // Remove bridged areas from the supported areas.
         contact_polygons = diff(contact_polygons, bridges, true);
+
+        #ifdef SLIC3R_DEBUG
+            static int iRun = 0;
+            SVG::export_expolygons(debug_out_path("support-top-contacts-remove-bridges-run%d.svg", iRun ++),
+                { { { union_ex(offset(layerm->unsupported_bridge_edges, scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS), false) }, { "unsupported_bridge_edges", "orange", 0.5f } },
+                  { { union_ex(contact_polygons, false) },            { "contact_polygons",           "blue",   0.5f } },
+                  { { union_ex(bridges, false) },                     { "bridges",                    "red",    "black", "", scaled<coord_t>(0.1f), 0.5f } } });
+        #endif /* SLIC3R_DEBUG */
     }
 }
 
@@ -1678,7 +1686,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
                     #endif /* SLIC3R_DEBUG */
                         }
                     }
-                    #ifdef SLIC3R_DEBUG
+                #ifdef SLIC3R_DEBUG
                     SVG::export_expolygons(debug_out_path("support-top-contacts-final0-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z),
                         { { { union_ex(lower_layer_polygons, false) },        { "lower_layer_polygons",       "gray",   0.2f } },
                           { { union_ex(*new_layer.contact_polygons, false) }, { "new_layer.contact_polygons", "yellow", 0.5f } },
@@ -3573,8 +3581,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
                 // Base flange.
                 filler->angle = raft_angle_1st_layer;
                 filler->spacing = m_first_layer_flow.spacing();
-                // 70% of density on the 1st layer.
-                density       = 0.7f;
+                density       = float(m_object_config->raft_first_layer_density.value * 0.01);
             } else if (support_layer_id >= m_slicing_params.base_raft_layers) {
                 filler->angle = raft_angle_interface;
                 // We don't use $base_flow->spacing because we need a constant spacing

From be7e2f2ae15b78fea898d65b62ebded3af732942 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Thu, 25 Feb 2021 12:40:42 +0100
Subject: [PATCH 09/53] Tech ENABLE_WX_3_1_3_DPI_CHANGED_EVENT set as default

---
 src/libslic3r/Technologies.hpp          |  3 ---
 src/slic3r/GUI/GUI_Utils.hpp            | 12 ++----------
 src/slic3r/GUI/MainFrame.cpp            |  8 ++------
 src/slic3r/GUI/SavePresetDialog.cpp     |  4 ++--
 src/slic3r/GUI/UnsavedChangesDialog.cpp |  8 ++++----
 5 files changed, 10 insertions(+), 25 deletions(-)

diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index 1c21e2f86..fe6c349b4 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -52,9 +52,6 @@
 // Enable error logging for OpenGL calls when SLIC3R_LOGLEVEL >= 5
 #define ENABLE_OPENGL_ERROR_LOGGING (1 && ENABLE_2_3_0_ALPHA1)
 
-// Enable built-in DPI changed event handler of wxWidgets 3.1.3
-#define ENABLE_WX_3_1_3_DPI_CHANGED_EVENT (1 && ENABLE_2_3_0_ALPHA1)
-
 
 //====================
 // 2.3.0.alpha3 techs
diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp
index dbb200f83..4f02c6c23 100644
--- a/src/slic3r/GUI/GUI_Utils.hpp
+++ b/src/slic3r/GUI/GUI_Utils.hpp
@@ -26,11 +26,7 @@ class wxCheckBox;
 class wxTopLevelWindow;
 class wxRect;
 
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 #define wxVERSION_EQUAL_OR_GREATER_THAN(major, minor, release) ((wxMAJOR_VERSION > major) || ((wxMAJOR_VERSION == major) && (wxMINOR_VERSION > minor)) || ((wxMAJOR_VERSION == major) && (wxMINOR_VERSION == minor) && (wxRELEASE_NUMBER >= release)))
-#else
-#define wxVERSION_EQUAL_OR_GREATER_THAN(major, minor, release) 0
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 
 namespace Slic3r {
 namespace GUI {
@@ -99,12 +95,12 @@ public:
 
         // Linux specific issue : get_dpi_for_window(this) still doesn't responce to the Display's scale in new wxWidgets(3.1.3).
         // So, calculate the m_em_unit value from the font size, as before
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && !defined(__WXGTK__)
+#if !defined(__WXGTK__)
         m_em_unit = std::max<size_t>(10, 10.0f * m_scale_factor);
 #else
         // initialize default width_unit according to the width of the one symbol ("m") of the currently active font of this window.
         m_em_unit = std::max<size_t>(10, this->GetTextExtent("m").x - 1);
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
+#endif // __WXGTK__
 
 //        recalc_font();
 
@@ -235,11 +231,7 @@ private:
         m_normal_font = this->GetFont();
 
         // update em_unit value for new window font
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
         m_em_unit = std::max<int>(10, 10.0f * m_scale_factor);
-#else
-        m_em_unit = std::max<size_t>(10, this->GetTextExtent("m").x - 1);
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 
         // rescale missed controls sizes and images
         on_dpi_changed(suggested_rect);
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 386a150f7..91357ff6c 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -803,11 +803,7 @@ bool MainFrame::can_reslice() const
 
 void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
 {
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
     wxGetApp().update_fonts(this);
-#else
-    wxGetApp().update_fonts();
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
     this->SetFont(this->normal_font());
 
     // update Plater
@@ -1848,14 +1844,14 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
     if (wxGetApp().is_gcode_viewer())
         return;
 
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__)
+#if defined(__WXMSW__)
     // ys_FIXME! temporary workaround for correct font scaling
     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
 #else
     this->SetFont(wxGetApp().normal_font());
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
+#endif // __WXMSW__
     this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
 
     // Load the icon either from the exe, or from the ico file.
diff --git a/src/slic3r/GUI/SavePresetDialog.cpp b/src/slic3r/GUI/SavePresetDialog.cpp
index e659f8e02..9c5e72fde 100644
--- a/src/slic3r/GUI/SavePresetDialog.cpp
+++ b/src/slic3r/GUI/SavePresetDialog.cpp
@@ -209,12 +209,12 @@ SavePresetDialog::~SavePresetDialog()
 void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix)
 {
     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__)
+#if defined(__WXMSW__)
     // ys_FIXME! temporary workaround for correct font scaling
     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
+#endif // __WXMSW__
 
     if (suffix.empty())
         suffix = _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName");
diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp
index 473f7e6e1..7d2879f0a 100644
--- a/src/slic3r/GUI/UnsavedChangesDialog.cpp
+++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp
@@ -792,12 +792,12 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
     wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
     SetBackgroundColour(bgr_clr);
 
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__)
+#if defined(__WXMSW__)
     // ys_FIXME! temporary workaround for correct font scaling
     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
+#endif // __WXMSW__
 
     int border = 10;
     int em = em_unit();
@@ -1375,12 +1375,12 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
     wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
     SetBackgroundColour(bgr_clr);
 
-#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__)
+#if defined(__WXMSW__)
     // ys_FIXME! temporary workaround for correct font scaling
     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-#endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
+#endif // __WXMSW__
 
     int border = 10;
     int em = em_unit();

From 89f065b57e2a8c69a3183814502a92659d05438c Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Thu, 25 Feb 2021 12:55:06 +0100
Subject: [PATCH 10/53] Fix of #5510: ctrlsub.cpp(231): assert "IsValid(n)"
 failed in GetClientData(): Invalid index passed to GetClientData()

BitmapComboBox: Use virtual OnSelect() on wxEVT_COMBO event
Don't save information about preset combobox type to the evt.SetInt(). This information can be received from BitmapComboBox::get_type() now.
---
 src/slic3r/GUI/Plater.cpp           |   8 +-
 src/slic3r/GUI/PresetComboBoxes.cpp | 154 +++++++++++++++-------------
 src/slic3r/GUI/PresetComboBoxes.hpp |   3 +
 3 files changed, 86 insertions(+), 79 deletions(-)

diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 6400bbbcc..815cf3912 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -3336,16 +3336,14 @@ void Plater::priv::set_current_panel(wxPanel* panel)
 
 void Plater::priv::on_select_preset(wxCommandEvent &evt)
 {
-    auto preset_type = static_cast<Preset::Type>(evt.GetInt());
-    auto *combo = static_cast<PlaterPresetComboBox*>(evt.GetEventObject());
+    PlaterPresetComboBox* combo = static_cast<PlaterPresetComboBox*>(evt.GetEventObject());
+    Preset::Type preset_type    = combo->get_type();
 
     // see https://github.com/prusa3d/PrusaSlicer/issues/3889
     // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender"),
     // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
     // So, use GetSelection() from event parameter 
-    // But in this function we couldn't use evt.GetSelection(), because m_commandInt is used for preset_type
-    // Thus, get selection in this way:
-    int selection = combo->FindString(evt.GetString(), true);
+    int selection = evt.GetSelection();
 
     auto idx = combo->get_extruder_idx();
 
diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp
index 0754df571..da723a36b 100644
--- a/src/slic3r/GUI/PresetComboBoxes.cpp
+++ b/src/slic3r/GUI/PresetComboBoxes.cpp
@@ -121,23 +121,26 @@ PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const
     Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_suppress_change = false; });
     Bind(wxEVT_COMBOBOX_CLOSEUP,  [this](wxCommandEvent&) { m_suppress_change = true;  });
 
-    Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
-        // see https://github.com/prusa3d/PrusaSlicer/issues/3889
-        // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
-        // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
-        // So, use GetSelection() from event parameter 
-        auto selected_item = evt.GetSelection();
+    Bind(wxEVT_COMBOBOX, &PresetComboBox::OnSelect, this);
+}
 
-        auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
-        if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX)
-            this->SetSelection(this->m_last_selected);
-        else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
-            m_last_selected = selected_item;
-            on_selection_changed(selected_item);
-            evt.StopPropagation();
-        }
-        evt.Skip();
-    });
+void PresetComboBox::OnSelect(wxCommandEvent& evt)
+{
+    // see https://github.com/prusa3d/PrusaSlicer/issues/3889
+    // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
+    // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
+    // So, use GetSelection() from event parameter 
+    auto selected_item = evt.GetSelection();
+
+    auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
+    if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX)
+        this->SetSelection(this->m_last_selected);
+    else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
+        m_last_selected = selected_item;
+        on_selection_changed(selected_item);
+        evt.StopPropagation();
+    }
+    evt.Skip();
 }
 
 PresetComboBox::~PresetComboBox()
@@ -602,34 +605,6 @@ void PresetComboBox::OnDrawItem(wxDC& dc,
 PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset_type) :
     PresetComboBox(parent, preset_type, wxSize(15 * wxGetApp().em_unit(), -1))
 {
-    Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
-        auto selected_item = evt.GetSelection();
-
-        auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
-        if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) {
-            this->SetSelection(this->m_last_selected);
-            evt.StopPropagation();
-            if (marker == LABEL_ITEM_WIZARD_PRINTERS)
-                show_add_menu();
-            else
-            {
-                ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME;
-                switch (marker) {
-                case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break;
-                case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break;
-                default: break;
-                }
-                wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); });
-            }
-        } else if (marker == LABEL_ITEM_PHYSICAL_PRINTER || this->m_last_selected != selected_item || m_collection->current_is_dirty() ) {
-            this->m_last_selected = selected_item;
-            evt.SetInt(this->m_type);
-            evt.Skip();
-        } else {
-            evt.StopPropagation();
-        }
-    });
-
     if (m_type == Preset::TYPE_FILAMENT)
     {
         Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &event) {
@@ -717,6 +692,35 @@ PlaterPresetComboBox::~PlaterPresetComboBox()
         edit_btn->Destroy();
 }
 
+void PlaterPresetComboBox::OnSelect(wxCommandEvent &evt)
+{
+    auto selected_item = evt.GetSelection();
+
+    auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
+    if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) {
+        this->SetSelection(this->m_last_selected);
+        evt.StopPropagation();
+        if (marker == LABEL_ITEM_MARKER)
+            return;
+        if (marker == LABEL_ITEM_WIZARD_PRINTERS)
+            show_add_menu();
+        else {
+            ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME;
+            switch (marker) {
+            case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break;
+            case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break;
+            default: break;
+            }
+            wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); });
+        }
+        return;
+    }
+    else if (marker == LABEL_ITEM_PHYSICAL_PRINTER || this->m_last_selected != selected_item || m_collection->current_is_dirty())
+        this->m_last_selected = selected_item;
+        
+    evt.Skip();
+}
+
 bool PlaterPresetComboBox::switch_to_tab()
 {
     Tab* tab = wxGetApp().get_tab(m_type);
@@ -957,40 +961,42 @@ void PlaterPresetComboBox::msw_rescale()
 TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type) :
     PresetComboBox(parent, preset_type, wxSize(35 * wxGetApp().em_unit(), -1))
 {
-    Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
-        // see https://github.com/prusa3d/PrusaSlicer/issues/3889
-        // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
-        // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
-        // So, use GetSelection() from event parameter 
-        auto selected_item = evt.GetSelection();
+}
 
-        auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
-        if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) {
-            this->SetSelection(this->m_last_selected);
-            if (marker == LABEL_ITEM_WIZARD_PRINTERS)
-                wxTheApp->CallAfter([this]() {
-                wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS);
+void TabPresetComboBox::OnSelect(wxCommandEvent &evt)
+{
+    // see https://github.com/prusa3d/PrusaSlicer/issues/3889
+    // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
+    // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
+    // So, use GetSelection() from event parameter 
+    auto selected_item = evt.GetSelection();
 
-                // update combobox if its parent is a PhysicalPrinterDialog
-                PhysicalPrinterDialog* parent = dynamic_cast<PhysicalPrinterDialog*>(this->GetParent());
-                if (parent != nullptr)
-                    update();
-            });
-        }
-        else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty()) ) {
-            m_last_selected = selected_item;
-            on_selection_changed(selected_item);
-        }
+    auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
+    if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) {
+        this->SetSelection(this->m_last_selected);
+        if (marker == LABEL_ITEM_WIZARD_PRINTERS)
+            wxTheApp->CallAfter([this]() {
+            wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS);
 
-        evt.StopPropagation();
+            // update combobox if its parent is a PhysicalPrinterDialog
+            PhysicalPrinterDialog* parent = dynamic_cast<PhysicalPrinterDialog*>(this->GetParent());
+            if (parent != nullptr)
+                update();
+        });
+    }
+    else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
+        m_last_selected = selected_item;
+        on_selection_changed(selected_item);
+    }
+
+    evt.StopPropagation();
 #ifdef __WXMSW__
-        // From the Win 2004 preset combobox lose a focus after change the preset selection
-        // and that is why the up/down arrow doesn't work properly
-        // (see https://github.com/prusa3d/PrusaSlicer/issues/5531 ).
-        // So, set the focus to the combobox explicitly
-        this->SetFocus();
-#endif    
-    });
+    // From the Win 2004 preset combobox lose a focus after change the preset selection
+    // and that is why the up/down arrow doesn't work properly
+    // (see https://github.com/prusa3d/PrusaSlicer/issues/5531 ).
+    // So, set the focus to the combobox explicitly
+    this->SetFocus();
+#endif
 }
 
 wxString TabPresetComboBox::get_preset_name(const Preset& preset)
diff --git a/src/slic3r/GUI/PresetComboBoxes.hpp b/src/slic3r/GUI/PresetComboBoxes.hpp
index 6f41c95f4..efcbec370 100644
--- a/src/slic3r/GUI/PresetComboBoxes.hpp
+++ b/src/slic3r/GUI/PresetComboBoxes.hpp
@@ -71,6 +71,7 @@ public:
     void             show_all(bool show_all);
     virtual void update();
     virtual void msw_rescale();
+    virtual void OnSelect(wxCommandEvent& evt);
 
 protected:
     typedef std::size_t Marker;
@@ -167,6 +168,7 @@ public:
     wxString get_preset_name(const Preset& preset) override;
     void update() override;
     void msw_rescale() override;
+    void OnSelect(wxCommandEvent& evt) override;
 
 private:
     int     m_extruder_idx = -1;
@@ -193,6 +195,7 @@ public:
     void update() override;
     void update_dirty();
     void msw_rescale() override;
+    void OnSelect(wxCommandEvent& evt) override;
 
     void set_enable_all(bool enable=true) { m_enable_all = enable; }
 

From 21b044b5563800e9604c9329e8a4aeb256fcfaea Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Thu, 18 Feb 2021 15:33:13 +0100
Subject: [PATCH 11/53] Fix of #5152 assert ""HasFlag(0x0020)"" failed in
 GetSelection(): must be single selection listbox This assert was invoked by
 list_printer->GetSelection() because of list_printer was created with
 wxLB_MULTIPLE flag.

---
 src/slic3r/GUI/ConfigWizard.cpp         | 21 +++++++++------------
 src/slic3r/GUI/ConfigWizard_private.hpp |  5 +++--
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp
index 59908bd80..b0bb6a8a4 100644
--- a/src/slic3r/GUI/ConfigWizard.cpp
+++ b/src/slic3r/GUI/ConfigWizard.cpp
@@ -629,13 +629,13 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
     append(html_window, 0, wxEXPAND);
 
 	list_printer->Bind(wxEVT_LISTBOX, [this](wxCommandEvent& evt) {
-		update_lists(evt.GetInt(), list_type->GetSelection(), list_vendor->GetSelection());
+		update_lists(list_type->GetSelection(), list_vendor->GetSelection(), evt.GetInt());
 		});
     list_type->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) {
-        update_lists(list_printer->GetSelection(), list_type->GetSelection(), list_vendor->GetSelection());
+        update_lists(list_type->GetSelection(), list_vendor->GetSelection());
     });
     list_vendor->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) {
-        update_lists(list_printer->GetSelection(), list_type->GetSelection(), list_vendor->GetSelection());
+        update_lists(list_type->GetSelection(), list_vendor->GetSelection());
     });
 
     list_profile->Bind(wxEVT_CHECKLISTBOX, [this](wxCommandEvent &evt) { select_material(evt.GetInt()); });
@@ -681,8 +681,7 @@ void PageMaterials::reload_presets()
     sort_list_data(list_printer, true, false);
     if (list_printer->GetCount() > 0) {
         list_printer->SetSelection(0);
-		sel_printer_count_prev = wxNOT_FOUND;
-        sel_printer_item_prev = wxNOT_FOUND;
+        sel_printers_prev.Clear();
         sel_type_prev = wxNOT_FOUND;
         sel_vendor_prev = wxNOT_FOUND;
         update_lists(0, 0, 0);
@@ -812,7 +811,7 @@ void PageMaterials::on_material_highlighted(int sel_material)
     set_compatible_printers_html_window(names, names.size() == materials->printers.size());
 }
 
-void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor)
+void PageMaterials::update_lists(int sel_type, int sel_vendor, int last_selected_printer/* = -1*/)
 {
 	wxWindowUpdateLocker freeze_guard(this);
 	(void)freeze_guard;
@@ -820,7 +819,7 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor)
 	wxArrayInt sel_printers;
 	int sel_printers_count = list_printer->GetSelections(sel_printers);
 
-	if (sel_printers_count != sel_printer_count_prev || (sel_printers_count == 1 && sel_printer_item_prev != sel_printer && sel_printer != -1)) {
+	if (sel_printers != sel_printers_prev) {
         // Refresh type list
 		list_type->Clear();
 		list_type->append(_L("(All)"), &EMPTY);
@@ -828,7 +827,7 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor)
             // If all is selected with other printers
             // unselect "all" or all printers depending on last value
             if (sel_printers[0] == 0 && sel_printers_count > 1) {
-                if (sel_printer == 0) {
+                if (last_selected_printer == 0) {
                     list_printer->SetSelection(wxNOT_FOUND);
                     list_printer->SetSelection(0);
                 } else {
@@ -869,8 +868,7 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor)
             sort_list_data(list_type, true, true);
 		}
 
-		sel_printer_count_prev = sel_printers_count;
-        sel_printer_item_prev = sel_printer;
+		sel_printers_prev = sel_printers;
 		sel_type = 0;
 		sel_type_prev = wxNOT_FOUND;
 		list_type->SetSelection(sel_type);
@@ -1089,8 +1087,7 @@ void PageMaterials::clear()
     list_type->Clear();
     list_vendor->Clear();
     list_profile->Clear();
-	sel_printer_count_prev = wxNOT_FOUND;
-    sel_printer_item_prev = wxNOT_FOUND;
+	sel_printers_prev.Clear();
     sel_type_prev = wxNOT_FOUND;
     sel_vendor_prev = wxNOT_FOUND;
     presets_loaded = false;
diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp
index d9c0e2dc1..581ec39b1 100644
--- a/src/slic3r/GUI/ConfigWizard_private.hpp
+++ b/src/slic3r/GUI/ConfigWizard_private.hpp
@@ -327,7 +327,8 @@ struct PageMaterials: ConfigWizardPage
     Materials *materials;
     StringList *list_printer, *list_type, *list_vendor;
     PresetList *list_profile;
-    int sel_printer_count_prev, sel_printer_item_prev, sel_type_prev, sel_vendor_prev;
+    wxArrayInt sel_printers_prev;
+    int sel_type_prev, sel_vendor_prev;
     bool presets_loaded;
 
     wxFlexGridSizer *grid;
@@ -342,7 +343,7 @@ struct PageMaterials: ConfigWizardPage
     PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name);
 
     void reload_presets();
-	void update_lists(int sel1, int sel2, int sel3);
+	void update_lists(int sel_type, int sel_vendor, int last_selected_printer = -1);
 	void on_material_highlighted(int sel_material);
     void on_material_hovered(int sel_material);
     void select_material(int i);

From 8f8217723ced26cd3d24ed8a7a31d49959e786fd Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Thu, 25 Feb 2021 13:38:52 +0100
Subject: [PATCH 12/53] Tech ENABLE_OPENGL_ERROR_LOGGING set as default

---
 src/libslic3r/Technologies.hpp | 3 ---
 src/slic3r/GUI/3DScene.cpp     | 7 +++----
 src/slic3r/GUI/3DScene.hpp     | 5 +----
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index fe6c349b4..a456b3d85 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -49,9 +49,6 @@
 // Enable smoothing of objects normals
 #define ENABLE_SMOOTH_NORMALS (0 && ENABLE_2_3_0_ALPHA1)
 
-// Enable error logging for OpenGL calls when SLIC3R_LOGLEVEL >= 5
-#define ENABLE_OPENGL_ERROR_LOGGING (1 && ENABLE_2_3_0_ALPHA1)
-
 
 //====================
 // 2.3.0.alpha3 techs
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index 3aafc9a3b..04301061d 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -39,12 +39,11 @@
 #ifdef HAS_GLSAFE
 void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name)
 {
-#if defined(NDEBUG) && ENABLE_OPENGL_ERROR_LOGGING
-    // In release mode, if OpenGL debugging was forced by ENABLE_OPENGL_ERROR_LOGGING, only show
-    // OpenGL errors if sufficiently high loglevel.
+#if defined(NDEBUG)
+    // In release mode, only show OpenGL errors if sufficiently high loglevel.
     if (Slic3r::get_logging_level() < 5)
         return;
-#endif // ENABLE_OPENGL_ERROR_LOGGING
+#endif // NDEBUG
 
     GLenum err = glGetError();
     if (err == GL_NO_ERROR)
diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp
index 6565d5c09..e4d9c6067 100644
--- a/src/slic3r/GUI/3DScene.hpp
+++ b/src/slic3r/GUI/3DScene.hpp
@@ -10,10 +10,7 @@
 
 #include <functional>
 
-#if ENABLE_OPENGL_ERROR_LOGGING || ! defined(NDEBUG)
-    #define HAS_GLSAFE
-#endif
-
+#define HAS_GLSAFE
 #ifdef HAS_GLSAFE
     extern void glAssertRecentCallImpl(const char *file_name, unsigned int line, const char *function_name);
     inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); }

From 4146fd337a441c1cadd5eaab08953377b45760e0 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Thu, 25 Feb 2021 14:28:53 +0100
Subject: [PATCH 13/53] Tech ENABLE_HACK_CLOSING_ON_OSX_10_9_5 set as default

---
 src/libslic3r/Technologies.hpp   | 21 ++-------------------
 src/slic3r/GUI/OpenGLManager.cpp | 14 --------------
 src/slic3r/GUI/OpenGLManager.hpp |  4 ----
 3 files changed, 2 insertions(+), 37 deletions(-)

diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index a456b3d85..f008fcd86 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -27,27 +27,10 @@
 #define ENABLE_GCODE_VIEWER_STATISTICS 0
 // Enable G-Code viewer comparison between toolpaths height and width detected from gcode and calculated at gcode generation 
 #define ENABLE_GCODE_VIEWER_DATA_CHECKING 0
-
-
-//=================
-// 2.2.0.rc1 techs
-//=================
-#define ENABLE_2_2_0_RC1 1
-
-// Enable hack to remove crash when closing on OSX 10.9.5
-#define ENABLE_HACK_CLOSING_ON_OSX_10_9_5 (1 && ENABLE_2_2_0_RC1)
-
-
-//====================
-// 2.3.0.alpha1 techs
-//====================
-#define ENABLE_2_3_0_ALPHA1 1
-
 // Enable rendering of objects using environment map
-#define ENABLE_ENVIRONMENT_MAP (0 && ENABLE_2_3_0_ALPHA1)
-
+#define ENABLE_ENVIRONMENT_MAP 0
 // Enable smoothing of objects normals
-#define ENABLE_SMOOTH_NORMALS (0 && ENABLE_2_3_0_ALPHA1)
+#define ENABLE_SMOOTH_NORMALS 0
 
 
 //====================
diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp
index 4f1e00793..0fa97bfc1 100644
--- a/src/slic3r/GUI/OpenGLManager.cpp
+++ b/src/slic3r/GUI/OpenGLManager.cpp
@@ -14,14 +14,10 @@
 #include <wx/glcanvas.h>
 #include <wx/msgdlg.h>
 
-#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 #ifdef __APPLE__
 // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
 #include <wx/platinfo.h>
-#endif // __APPLE__
-#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 
-#ifdef __APPLE__
 #include "../Utils/MacDarkMode.hpp"
 #endif // __APPLE__
 
@@ -202,34 +198,26 @@ bool OpenGLManager::s_compressed_textures_supported = false;
 OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown;
 OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown;
 
-#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 #ifdef __APPLE__ 
 // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
 OpenGLManager::OSInfo OpenGLManager::s_os_info;
 #endif // __APPLE__ 
-#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 
 OpenGLManager::~OpenGLManager()
 {
     m_shaders_manager.shutdown();
 
-#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 #ifdef __APPLE__ 
     // This is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5 with newer wxWidgets
     // The crash is triggered inside wxGLContext destructor
     if (s_os_info.major != 10 || s_os_info.minor != 9 || s_os_info.micro != 5)
     {
 #endif //__APPLE__
-#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
-
         if (m_context != nullptr)
             delete m_context;
-
-#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 #ifdef __APPLE__ 
     }
 #endif //__APPLE__
-#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 }
 
 bool OpenGLManager::init_gl()
@@ -286,14 +274,12 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas)
     if (m_context == nullptr) {
         m_context = new wxGLContext(&canvas);
 
-#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 #ifdef __APPLE__ 
         // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
         s_os_info.major = wxPlatformInfo::Get().GetOSMajorVersion();
         s_os_info.minor = wxPlatformInfo::Get().GetOSMinorVersion();
         s_os_info.micro = wxPlatformInfo::Get().GetOSMicroVersion();
 #endif //__APPLE__
-#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
     }
     return m_context;
 }
diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp
index c89cdf3a6..5f8cd7959 100644
--- a/src/slic3r/GUI/OpenGLManager.hpp
+++ b/src/slic3r/GUI/OpenGLManager.hpp
@@ -51,7 +51,6 @@ public:
         void detect() const;
     };
 
-#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 #ifdef __APPLE__ 
     // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
     struct OSInfo
@@ -61,7 +60,6 @@ public:
         int micro{ 0 };
     };
 #endif //__APPLE__
-#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 
 private:
     enum class EMultisampleState : unsigned char
@@ -75,12 +73,10 @@ private:
     wxGLContext* m_context{ nullptr };
     GLShadersManager m_shaders_manager;
     static GLInfo s_gl_info;
-#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 #ifdef __APPLE__ 
     // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
     static OSInfo s_os_info;
 #endif //__APPLE__
-#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
     static bool s_compressed_textures_supported;
     static EMultisampleState s_multisample;
     static EFramebufferType s_framebuffers_type;

From 750cfdd099d2a9dc57db91a5ff94e83434cfed52 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Thu, 25 Feb 2021 14:50:35 +0100
Subject: [PATCH 14/53] Fix of support generator after merging Base type
 interfaces for soluble interface supports #6017

---
 src/libslic3r/SupportMaterial.cpp | 19 ++++++++++++++-----
 src/libslic3r/SupportMaterial.hpp |  1 +
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp
index 9a984ba39..459a15603 100644
--- a/src/libslic3r/SupportMaterial.cpp
+++ b/src/libslic3r/SupportMaterial.cpp
@@ -501,7 +501,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
     // If raft is to be generated, the 1st top_contact layer will contain the 1st object layer silhouette with holes filled.
     // There is also a 1st intermediate layer containing bases of support columns.
     // Inflate the bases of the support columns and create the raft base under the object.
-    MyLayersPtr raft_layers = this->generate_raft_base(object, top_contacts, interface_layers, intermediate_layers, layer_storage);
+    MyLayersPtr raft_layers = this->generate_raft_base(object, top_contacts, interface_layers, intermediate_layers, base_interface_layers, layer_storage);
 
 #ifdef SLIC3R_DEBUG
     for (const MyLayer *l : interface_layers)
@@ -2546,6 +2546,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
     const PrintObject   &object,
     const MyLayersPtr   &top_contacts,
     const MyLayersPtr   &interface_layers,
+    const MyLayersPtr   &base_interface_layers,
     const MyLayersPtr   &base_layers,
     MyLayerStorage      &layer_storage) const
 {
@@ -2581,15 +2582,19 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
     // How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed.
     const float inflate_factor_fine      = float(scale_((m_slicing_params.raft_layers() > 1) ? 0.5 : EPSILON));
     const float inflate_factor_1st_layer = std::max(0.f, float(scale_(object.config().raft_first_layer_expansion)) - inflate_factor_fine);
-    MyLayer       *contacts      = top_contacts    .empty() ? nullptr : top_contacts    .front();
-    MyLayer       *interfaces    = interface_layers.empty() ? nullptr : interface_layers.front();
-    MyLayer       *columns_base  = base_layers     .empty() ? nullptr : base_layers     .front();
+    MyLayer       *contacts         = top_contacts         .empty() ? nullptr : top_contacts         .front();
+    MyLayer       *interfaces       = interface_layers     .empty() ? nullptr : interface_layers     .front();
+    MyLayer       *base_interfaces  = base_interface_layers.empty() ? nullptr : base_interface_layers.front();
+    MyLayer       *columns_base     = base_layers          .empty() ? nullptr : base_layers          .front();
     if (contacts != nullptr && contacts->print_z > std::max(m_slicing_params.first_print_layer_height, m_slicing_params.raft_contact_top_z) + EPSILON)
         // This is not the raft contact layer.
         contacts = nullptr;
     if (interfaces != nullptr && interfaces->bottom_print_z() > m_slicing_params.raft_interface_top_z + EPSILON)
         // This is not the raft column base layer.
         interfaces = nullptr;
+    if (base_interfaces != nullptr && base_interfaces->bottom_print_z() > m_slicing_params.raft_interface_top_z + EPSILON)
+        // This is not the raft column base layer.
+        base_interfaces = nullptr;
     if (columns_base != nullptr && columns_base->bottom_print_z() > m_slicing_params.raft_interface_top_z + EPSILON)
         // This is not the raft interface layer.
         columns_base = nullptr;
@@ -2599,6 +2604,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
         polygons_append(interface_polygons, offset(contacts->polygons, inflate_factor_fine, SUPPORT_SURFACES_OFFSET_PARAMETERS));
     if (interfaces != nullptr && ! interfaces->polygons.empty())
         polygons_append(interface_polygons, offset(interfaces->polygons, inflate_factor_fine, SUPPORT_SURFACES_OFFSET_PARAMETERS));
+    if (base_interfaces != nullptr && ! base_interfaces->polygons.empty())
+        polygons_append(interface_polygons, offset(base_interfaces->polygons, inflate_factor_fine, SUPPORT_SURFACES_OFFSET_PARAMETERS));
  
     // Output vector.
     MyLayersPtr raft_layers;
@@ -2671,6 +2678,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
                 contacts->polygons = diff(contacts->polygons, brim);
             if (interfaces)
                 interfaces->polygons = diff(interfaces->polygons, brim);
+            if (base_interfaces)
+                base_interfaces->polygons = diff(base_interfaces->polygons, brim);
         }
     }
 
@@ -2723,7 +2732,7 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
             layer_new.bridging   = intermediate_layer.bridging;
             // Merge top into bottom, unite them with a safety offset.
             append(bottom, std::move(top));
-            layer_new.polygons   = union_(std::move(bottom), true);
+            layer_new.polygons   = intersection(union_(std::move(bottom), true), intermediate_layer.polygons);
             // Subtract the interface from the base regions.
             intermediate_layer.polygons = diff(intermediate_layer.polygons, layer_new.polygons, false);
             if (subtract)
diff --git a/src/libslic3r/SupportMaterial.hpp b/src/libslic3r/SupportMaterial.hpp
index ddc5b944c..7123290a6 100644
--- a/src/libslic3r/SupportMaterial.hpp
+++ b/src/libslic3r/SupportMaterial.hpp
@@ -195,6 +195,7 @@ private:
     	const PrintObject   &object,
 	    const MyLayersPtr   &top_contacts,
 	    const MyLayersPtr   &interface_layers,
+	    const MyLayersPtr   &base_interface_layers,
 	    const MyLayersPtr   &base_layers,
 	    MyLayerStorage      &layer_storage) const;
 

From a3b60c09bc636e4eb3a4a4769c9f4ae5d7f8d3c7 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Thu, 25 Feb 2021 15:22:12 +0100
Subject: [PATCH 15/53] Tech ENABLE_CTRL_M_ON_WINDOWS set as default

---
 src/libslic3r/AppConfig.cpp          |  2 --
 src/libslic3r/Technologies.hpp       |  8 --------
 src/slic3r/GUI/GLCanvas3D.cpp        | 14 --------------
 src/slic3r/GUI/KBShortcutsDialog.cpp |  6 ------
 src/slic3r/GUI/Mouse3DController.cpp | 14 --------------
 src/slic3r/GUI/Mouse3DController.hpp |  2 --
 src/slic3r/GUI/Plater.cpp            |  2 --
 src/slic3r/GUI/Preferences.cpp       |  2 --
 8 files changed, 50 deletions(-)

diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index fd1ddf055..08e5fdf6d 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -156,12 +156,10 @@ void AppConfig::set_defaults()
     if (get("show_splash_screen").empty())
         set("show_splash_screen", "1");
 
-#if ENABLE_CTRL_M_ON_WINDOWS
 #ifdef _WIN32
     if (get("use_legacy_3DConnexion").empty())
         set("use_legacy_3DConnexion", "0");
 #endif // _WIN32
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 
     // Remove legacy window positions/sizes
     erase("", "main_frame_maximized");
diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index f008fcd86..0d4bd2303 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -33,14 +33,6 @@
 #define ENABLE_SMOOTH_NORMALS 0
 
 
-//====================
-// 2.3.0.alpha3 techs
-//====================
-#define ENABLE_2_3_0_ALPHA3 1
-
-#define ENABLE_CTRL_M_ON_WINDOWS (1 && ENABLE_2_3_0_ALPHA3)
-
-
 //====================
 // 2.3.0.alpha4 techs
 //====================
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 0aec25404..3267320df 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -2509,8 +2509,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
 #endif /* __APPLE__ */
             post_event(SimpleEvent(EVT_GLTOOLBAR_COPY));
         break;
-
-#if ENABLE_CTRL_M_ON_WINDOWS
 #ifdef __APPLE__
         case 'm':
         case 'M':
@@ -2529,18 +2527,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
 #endif //_WIN32
             break;
         }
-#else
-#if defined(__linux__) || defined(__APPLE__)
-        case WXK_CONTROL_M:
-        {
-            Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller();
-            controller.show_settings_dialog(!controller.is_settings_dialog_shown());
-            m_dirty = true;
-            break;
-        }
-#endif /* __linux__ */
-#endif // ENABLE_CTRL_M_ON_WINDOWS
-
 #ifdef __APPLE__
         case 'v':
         case 'V':
diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp
index 04e6769e4..a7363837e 100644
--- a/src/slic3r/GUI/KBShortcutsDialog.cpp
+++ b/src/slic3r/GUI/KBShortcutsDialog.cpp
@@ -147,17 +147,11 @@ void KBShortcutsDialog::fill_shortcuts()
             { "O", L("Zoom out") },
             { "Tab", L("Switch between Editor/Preview") },
             { "Shift+Tab", L("Collapse/Expand the sidebar") },
-#if ENABLE_CTRL_M_ON_WINDOWS
 #ifdef _WIN32
             { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog, if enabled") },
 #else
             { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") },
 #endif // _WIN32
-#else
-#if defined(__linux__) || defined(__APPLE__)
-            { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") },
-#endif // __linux__
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 #if ENABLE_RENDER_PICKING_PASS
             // Don't localize debugging texts.
             { "P", "Toggle picking pass texture rendering on/off" },
diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp
index 9ff5688be..57b82fc78 100644
--- a/src/slic3r/GUI/Mouse3DController.cpp
+++ b/src/slic3r/GUI/Mouse3DController.cpp
@@ -100,7 +100,6 @@ void Mouse3DController::State::append_button(unsigned int id, size_t /* input_qu
 }
 
 #ifdef _WIN32
-#if ENABLE_CTRL_M_ON_WINDOWS
 static std::string format_device_string(int vid, int pid)
 {
     std::string ret;
@@ -257,7 +256,6 @@ static std::string detect_attached_device()
 
     return ret;
 }
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 
 // Called by Win32 HID enumeration callback.
 void Mouse3DController::device_attached(const std::string &device)
@@ -274,7 +272,6 @@ void Mouse3DController::device_attached(const std::string &device)
 			// Never mind, enumeration will be performed until connected.
 		    m_wakeup = true;
 			m_stop_condition.notify_all();
-#if ENABLE_CTRL_M_ON_WINDOWS
             m_device_str = format_device_string(vid, pid);
             if (auto it_params = m_params_by_device.find(m_device_str); it_params != m_params_by_device.end()) {
                 tbb::mutex::scoped_lock lock(m_params_ui_mutex);
@@ -283,12 +280,10 @@ void Mouse3DController::device_attached(const std::string &device)
             else
                 m_params_by_device[format_device_string(vid, pid)] = Params();
             m_connected = true;
-#endif // ENABLE_CTRL_M_ON_WINDOWS
         }
 	}
 }
 
-#if ENABLE_CTRL_M_ON_WINDOWS
 void Mouse3DController::device_detached(const std::string& device)
 {
     int vid = 0;
@@ -302,7 +297,6 @@ void Mouse3DController::device_detached(const std::string& device)
     m_device_str = "";
     m_connected = false;
 }
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 
 // Filter out mouse scroll events produced by the 3DConnexion driver.
 bool Mouse3DController::State::process_mouse_wheel()
@@ -415,7 +409,6 @@ bool Mouse3DController::apply(Camera& camera)
         m_settings_dialog_closed_by_user = false;
     }
 
-#if ENABLE_CTRL_M_ON_WINDOWS
 #ifdef _WIN32
     {
         tbb::mutex::scoped_lock lock(m_params_ui_mutex);
@@ -425,7 +418,6 @@ bool Mouse3DController::apply(Camera& camera)
         }
     }
 #endif // _WIN32
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 
     return m_state.apply(m_params, camera);
 }
@@ -661,7 +653,6 @@ bool Mouse3DController::handle_input(const DataPacketAxis& packet)
 // Initialize the application.
 void Mouse3DController::init()
 {
-#if ENABLE_CTRL_M_ON_WINDOWS
 #ifdef _WIN32
     m_device_str = detect_attached_device();
     if (!m_device_str.empty()) {
@@ -670,7 +661,6 @@ void Mouse3DController::init()
             m_params = m_params_ui = it_params->second;
     }
 #endif // _WIN32
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 
 	assert(! m_thread.joinable());
     if (! m_thread.joinable()) {
@@ -698,12 +688,10 @@ void Mouse3DController::shutdown()
         m_stop = false;
 	}
 
-#if ENABLE_CTRL_M_ON_WINDOWS
 #ifdef _WIN32
     if (!m_device_str.empty())
         m_params_by_device[m_device_str] = m_params_ui;
 #endif // _WIN32
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 }
 
 // Main routine of the worker thread.
@@ -1064,9 +1052,7 @@ bool Mouse3DController::handle_raw_input_win32(const unsigned char *data, const
         DataPacketRaw packet;
     	memcpy(packet.data(), data, packet_length);
         handle_packet(packet, packet_length, m_params, m_state);
-#if ENABLE_CTRL_M_ON_WINDOWS
         m_connected = true;
-#endif // ENABLE_CTRL_M_ON_WINDOWS
     }
 
     return true;
diff --git a/src/slic3r/GUI/Mouse3DController.hpp b/src/slic3r/GUI/Mouse3DController.hpp
index af131992c..3376ef814 100644
--- a/src/slic3r/GUI/Mouse3DController.hpp
+++ b/src/slic3r/GUI/Mouse3DController.hpp
@@ -195,9 +195,7 @@ public:
 
     // Called by Win32 HID enumeration callback.
     void device_attached(const std::string &device);
-#if ENABLE_CTRL_M_ON_WINDOWS
     void device_detached(const std::string& device);
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 
     // On Windows, the 3DConnexion driver sends out mouse wheel rotation events to an active application
     // if the application does not register at the driver. This is a workaround to ignore these superfluous
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 815cf3912..fe6704925 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1931,11 +1931,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
     this->q->Bind(EVT_HID_DEVICE_ATTACHED, [this](HIDDeviceAttachedEvent &evt) {
     	mouse3d_controller.device_attached(evt.data);
         });
-#if ENABLE_CTRL_M_ON_WINDOWS
     this->q->Bind(EVT_HID_DEVICE_DETACHED, [this](HIDDeviceAttachedEvent& evt) {
         mouse3d_controller.device_detached(evt.data);
         });
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 #endif /* _WIN32 */
 
 	notification_manager = new NotificationManager(this->q);
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index cba941a39..e28bd589d 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -215,7 +215,6 @@ void PreferencesDialog::build()
 	option = Option(def, "show_splash_screen");
 	m_optgroup_general->append_single_option_line(option);
 
-#if ENABLE_CTRL_M_ON_WINDOWS
 #if defined(_WIN32) || defined(__APPLE__)
 	def.label = L("Enable support for legacy 3DConnexion devices");
 	def.type = coBool;
@@ -224,7 +223,6 @@ void PreferencesDialog::build()
 	option = Option(def, "use_legacy_3DConnexion");
 	m_optgroup_general->append_single_option_line(option);
 #endif // _WIN32 || __APPLE__
-#endif // ENABLE_CTRL_M_ON_WINDOWS
 
 	activate_options_tab(m_optgroup_general);
 

From 48481c10b4720d54e042c284670b1218c11ffdde Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Thu, 25 Feb 2021 16:29:18 +0100
Subject: [PATCH 16/53] Tech ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING set as
 default

---
 src/libslic3r/GCode/GCodeProcessor.cpp | 18 ------------------
 src/libslic3r/GCode/GCodeProcessor.hpp |  2 --
 src/libslic3r/Technologies.hpp         | 10 +---------
 3 files changed, 1 insertion(+), 29 deletions(-)

diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp
index c4b2a3518..a4769af8e 100644
--- a/src/libslic3r/GCode/GCodeProcessor.cpp
+++ b/src/libslic3r/GCode/GCodeProcessor.cpp
@@ -705,10 +705,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
     }
 
     m_time_processor.export_remaining_time_enabled = config.remaining_times.value;
-
-#if ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
     m_use_volumetric_e = config.use_volumetric_e;
-#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
 }
 
 void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
@@ -870,11 +867,9 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
     if (m_time_processor.machine_limits.machine_max_acceleration_x.values.size() > 1)
         enable_stealth_time_estimator(true);
 
-#if ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
     const ConfigOptionBool* use_volumetric_e = config.option<ConfigOptionBool>("use_volumetric_e");
     if (use_volumetric_e != nullptr)
         m_use_volumetric_e = use_volumetric_e->value;
-#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
 }
 
 void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
@@ -930,9 +925,7 @@ void GCodeProcessor::reset()
     m_result.reset();
     m_result.id = ++s_result_id;
 
-#if ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
     m_use_volumetric_e = false;
-#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
 
 #if ENABLE_GCODE_VIEWER_DATA_CHECKING
     m_mm3_per_mm_compare.reset();
@@ -1840,14 +1833,10 @@ void GCodeProcessor::process_G0(const GCodeReader::GCodeLine& line)
 
 void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
 {
-#if ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
     float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_filament_diameters.size()) ? m_filament_diameters[m_extruder_id] : m_filament_diameters.back();
     float filament_radius = 0.5f * filament_diameter;
     float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius);
     auto absolute_position = [this, area_filament_cross_section](Axis axis, const GCodeReader::GCodeLine& lineG1) {
-#else
-    auto absolute_position = [this](Axis axis, const GCodeReader::GCodeLine& lineG1) {
-#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
         bool is_relative = (m_global_positioning_type == EPositioningType::Relative);
         if (axis == E)
             is_relative |= (m_e_local_positioning_type == EPositioningType::Relative);
@@ -1855,10 +1844,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
         if (lineG1.has(Slic3r::Axis(axis))) {
             float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f;
             float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
-#if ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
             if (axis == E && m_use_volumetric_e)
                 ret /= area_filament_cross_section;
-#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
             return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret;
         }
         else
@@ -1916,11 +1903,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
 
     if (type == EMoveType::Extrude) {
         float delta_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
-#if !ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
-        float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_filament_diameters.size()) ? m_filament_diameters[m_extruder_id] : m_filament_diameters.back();
-        float filament_radius = 0.5f * filament_diameter;
-        float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius);
-#endif // !ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
         float volume_extruded_filament = area_filament_cross_section * delta_pos[E];
         float area_toolpath_cross_section = volume_extruded_filament / delta_xyz;
 
diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp
index 05f9a2ce3..f884df8ec 100644
--- a/src/libslic3r/GCode/GCodeProcessor.hpp
+++ b/src/libslic3r/GCode/GCodeProcessor.hpp
@@ -473,9 +473,7 @@ namespace Slic3r {
         unsigned int m_g1_line_id;
         unsigned int m_layer_id;
         CpColor m_cp_color;
-#if ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
         bool m_use_volumetric_e;
-#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
 
         enum class EProducer
         {
diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index 0d4bd2303..3ada1cd35 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -49,22 +49,14 @@
 #define ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN (1 && ENABLE_2_3_0_BETA1)
 
 
-//=================
-// 2.3.0.rc1 techs
-//=================
-#define ENABLE_2_3_0_RC1 1
-
-#define ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING (1 && ENABLE_2_3_0_RC1)
-
-
 //====================
 // 2.3.1.alpha1 techs
 //====================
 #define ENABLE_2_3_1_ALPHA1 1
 
 #define ENABLE_SPLITTED_VERTEX_BUFFER (1 && ENABLE_2_3_1_ALPHA1)
-#define ENABLE_RELOAD_FROM_DISK_FOR_3MF (1 && ENABLE_2_3_1_ALPHA1)
 #define ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS (1 && ENABLE_SPLITTED_VERTEX_BUFFER)
+#define ENABLE_RELOAD_FROM_DISK_FOR_3MF (1 && ENABLE_2_3_1_ALPHA1)
 #define ENABLE_WARNING_TEXTURE_REMOVAL (1 && ENABLE_2_3_1_ALPHA1)
 #define ENABLE_GCODE_LINES_ID_IN_H_SLIDER (1 && ENABLE_2_3_1_ALPHA1)
 #define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_3_1_ALPHA1)

From 55c62887ccc2627ca714506a3221f9f1a9d7aef8 Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Thu, 25 Feb 2021 20:23:53 +0100
Subject: [PATCH 17/53] Fix of #5503 - Physical printer disappears from Slicer
 upon close of application

---
 src/libslic3r/Preset.cpp      | 27 ++++++++++++---------------
 src/libslic3r/Preset.hpp      |  4 ++--
 src/libslic3r/PrintConfig.cpp | 10 ++++++----
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 6c500b84a..98ccf280f 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -1393,9 +1393,8 @@ const std::vector<std::string>& PhysicalPrinter::printer_options()
     static std::vector<std::string> s_opts;
     if (s_opts.empty()) {
         s_opts = {
-            "preset_name",
+            "preset_names",
             "printer_technology",
-//            "printer_model",
             "host_type",
             "print_host",
             "printhost_apikey",
@@ -1453,11 +1452,10 @@ bool PhysicalPrinter::has_empty_config() const
 void PhysicalPrinter::update_preset_names_in_config()
 {
     if (!preset_names.empty()) {
-        std::string name;
-        for (auto el : preset_names)
-            name += el + ";";
-        name.pop_back();
-        config.set_key_value("preset_name", new ConfigOptionString(name));
+        std::vector<std::string>& values = config.option<ConfigOptionStrings>("preset_names")->values;
+        values.clear();
+        for (auto preset : preset_names)
+            values.push_back(preset);
     }
 }
 
@@ -1482,14 +1480,13 @@ void PhysicalPrinter::update_from_config(const DynamicPrintConfig& new_config)
 {
     config.apply_only(new_config, printer_options(), false);
 
-    std::string str = config.opt_string("preset_name");
-    std::set<std::string> values{};
-    if (!str.empty()) {
-        boost::split(values, str, boost::is_any_of(";"));
+    const std::vector<std::string>& values = config.option<ConfigOptionStrings>("preset_names")->values;
+
+    if (values.empty())
+        preset_names.clear();
+    else
         for (const std::string& val : values)
             preset_names.emplace(val);
-    }
-    preset_names = values;
 }
 
 void PhysicalPrinter::reset_presets()
@@ -1817,7 +1814,7 @@ bool PhysicalPrinterCollection::delete_preset_from_printers( const std::string&
     return true;
 }
 
-// Get list of printers which have more than one preset and "preset_name" preset is one of them
+// Get list of printers which have more than one preset and "preset_names" preset is one of them
 std::vector<std::string> PhysicalPrinterCollection::get_printers_with_preset(const std::string& preset_name)
 {
     std::vector<std::string> printers;
@@ -1832,7 +1829,7 @@ std::vector<std::string> PhysicalPrinterCollection::get_printers_with_preset(con
     return printers;
 }
 
-// Get list of printers which has only "preset_name" preset
+// Get list of printers which has only "preset_names" preset
 std::vector<std::string> PhysicalPrinterCollection::get_printers_with_only_preset(const std::string& preset_name)
 {
     std::vector<std::string> printers;
diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp
index d81717f0e..6e56ad911 100644
--- a/src/libslic3r/Preset.hpp
+++ b/src/libslic3r/Preset.hpp
@@ -685,9 +685,9 @@ public:
     // returns true if all presets were deleted successfully.
     bool            delete_preset_from_printers(const std::string& preset_name);
 
-    // Get list of printers which have more than one preset and "preset_name" preset is one of them
+    // Get list of printers which have more than one preset and "preset_names" preset is one of them
     std::vector<std::string> get_printers_with_preset( const std::string &preset_name);
-    // Get list of printers which has only "preset_name" preset
+    // Get list of printers which has only "preset_names" preset
     std::vector<std::string> get_printers_with_only_preset( const std::string &preset_name);
 
     // Return the selected preset, without the user modifications applied.
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 480ce4590..810b651c4 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -151,11 +151,11 @@ void PrintConfigDef::init_common_params()
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionString(""));
     
-    def = this->add("preset_name", coString);
-    def->label = L("Printer preset name");
-    def->tooltip = L("Related printer preset name");
+    def = this->add("preset_names", coStrings);
+    def->label = L("Printer preset names");
+    def->tooltip = L("Names of presets related to the physical printer");
     def->mode = comAdvanced;
-    def->set_default_value(new ConfigOptionString(""));
+    def->set_default_value(new ConfigOptionStrings());
 
     def = this->add("printhost_authorization_type", coEnum);
     def->label = L("Authorization Type");
@@ -3366,6 +3366,8 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
         opt_key = "printhost_cafile";
     } else if (opt_key == "octoprint_apikey") {
         opt_key = "printhost_apikey";
+    } else if (opt_key == "preset_name") {
+        opt_key = "preset_names";
     }
 
     // Ignore the following obsolete configuration keys:

From 0593a413503d41c6c14c1b47d6d56669556e8635 Mon Sep 17 00:00:00 2001
From: rtyr <36745189+rtyr@users.noreply.github.com>
Date: Thu, 25 Feb 2021 23:00:32 +0100
Subject: [PATCH 18/53] Updated vendor name.

---
 resources/profiles/INAT.ini | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/profiles/INAT.ini b/resources/profiles/INAT.ini
index 0c4cbe5f4..e11aeab86 100644
--- a/resources/profiles/INAT.ini
+++ b/resources/profiles/INAT.ini
@@ -2,7 +2,7 @@
 
 [vendor]
 # Vendor name will be shown by the Config Wizard.
-name = INAT s.r.o.
+name = INAT
 config_version = 0.0.1
 config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/INAT/
 

From a53de51b2266137f687417292808a0e0c09b8cef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= <hejl.lukas@gmail.com>
Date: Thu, 25 Feb 2021 23:30:22 +0100
Subject: [PATCH 19/53] Fix of 8f293f0cb560b80b6ace68d1febdb026b379097f

When was set use_external_mp_once to true then after first calling the avoid crossing perimeters this flag was reset which cases that on the second call of the avoid crossing perimeters the travel move didn't process as external.
---
 src/libslic3r/GCode.cpp                         | 15 +++++++++++----
 src/libslic3r/GCode/AvoidCrossingPerimeters.hpp |  1 +
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 26a206247..838435961 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -2838,9 +2838,11 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
     Polyline travel { this->last_pos(), point };
 
     // check whether a straight travel move would need retraction
-    bool needs_retraction       = this->needs_retraction(travel, role);
+    bool needs_retraction             = this->needs_retraction(travel, role);
     // check whether wipe could be disabled without causing visible stringing
-    bool could_be_wipe_disabled = false;
+    bool could_be_wipe_disabled       = false;
+    // Save state of use_external_mp_once for the case that will be needed to call twice m_avoid_crossing_perimeters.travel_to.
+    const bool used_external_mp_once  = m_avoid_crossing_perimeters.used_external_mp_once();
 
     // if a retraction would be needed, try to use avoid_crossing_perimeters to plan a
     // multi-hop travel path inside the configuration space
@@ -2868,8 +2870,13 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
         // Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction()
         // FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations.
         if (last_post_before_retract != this->last_pos() && m_config.avoid_crossing_perimeters) {
-            Polyline retract_travel = m_avoid_crossing_perimeters.travel_to(*this, point);
-            travel = std::move(retract_travel);
+            // If in the previous call of m_avoid_crossing_perimeters.travel_to was use_external_mp_once set to true restore this value for next call.
+            if (used_external_mp_once)
+                m_avoid_crossing_perimeters.use_external_mp_once();
+            travel = m_avoid_crossing_perimeters.travel_to(*this, point);
+            // If state of use_external_mp_once was changed reset it to right value.
+            if (used_external_mp_once)
+                m_avoid_crossing_perimeters.reset_once_modifiers();
         }
     } else
         // Reset the wipe path when traveling, so one would not wipe along an old path.
diff --git a/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp b/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp
index 03c420a32..d178e3c89 100644
--- a/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp
+++ b/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp
@@ -18,6 +18,7 @@ public:
     // Routing around the objects vs. inside a single object.
     void        use_external_mp(bool use = true) { m_use_external_mp = use; };
     void        use_external_mp_once()  { m_use_external_mp_once = true; }
+    bool        used_external_mp_once() { return m_use_external_mp_once; }
     void        disable_once()          { m_disabled_once = true; }
     bool        disabled_once() const   { return m_disabled_once; }
     void        reset_once_modifiers()  { m_use_external_mp_once = false; m_disabled_once = false; }

From 19cfeb1a78c695e6e0fa9c0d6e17452d9f751488 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Fri, 26 Feb 2021 07:57:48 +0100
Subject: [PATCH 20/53] Fix of a crash when using active_step_add_warning on
 PrintObjects

PrintObjectBase::status_update_warnings called PrintBase::status_update_warnings, which in turn set
SlicingStatus flag to UPDATE_PRINT_STEP_WARNINGS (instead of UPDATE_PRINT_OBEJCT_STEP_WARNINGS) and
saved its own ObjectID. This led to spurious and hard to read thread-unsafe crashes.
---
 src/libslic3r/PrintBase.cpp | 12 +++++++-----
 src/libslic3r/PrintBase.hpp |  6 +++---
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/libslic3r/PrintBase.cpp b/src/libslic3r/PrintBase.cpp
index 721741d4a..d129aaad2 100644
--- a/src/libslic3r/PrintBase.cpp
+++ b/src/libslic3r/PrintBase.cpp
@@ -94,12 +94,14 @@ std::string PrintBase::output_filepath(const std::string &path, const std::strin
     return path;
 }
 
-void PrintBase::status_update_warnings(ObjectID object_id, int step, PrintStateBase::WarningLevel /* warning_level */, const std::string &message)
+void PrintBase::status_update_warnings(int step, PrintStateBase::WarningLevel /* warning_level */, const std::string &message, const PrintObjectBase* print_object)
 {
-    if (this->m_status_callback)
-        m_status_callback(SlicingStatus(*this, step));
+    if (this->m_status_callback) {
+        auto status = print_object ? SlicingStatus(*print_object, step) : SlicingStatus(*this, step);
+        m_status_callback(status);
+    }
     else if (! message.empty())
-    	printf("%s warning: %s\n", (object_id == this->id()) ? "print" : "print object", message.c_str());
+        printf("%s warning: %s\n",  print_object ? "print_object" : "print", message.c_str());
 }
 
 tbb::mutex& PrintObjectBase::state_mutex(PrintBase *print)
@@ -114,7 +116,7 @@ std::function<void()> PrintObjectBase::cancel_callback(PrintBase *print)
 
 void PrintObjectBase::status_update_warnings(PrintBase *print, int step, PrintStateBase::WarningLevel warning_level, const std::string &message)
 {
-	print->status_update_warnings(this->id(), step, warning_level, message);
+    print->status_update_warnings(step, warning_level, message, this);
 }
 
 } // namespace Slic3r
diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp
index 8fca43319..2aff13ae9 100644
--- a/src/libslic3r/PrintBase.hpp
+++ b/src/libslic3r/PrintBase.hpp
@@ -481,7 +481,7 @@ protected:
 	// Notify UI about a new warning of a milestone "step" on this PrintBase.
 	// The UI will be notified by calling a status callback.
 	// If no status callback is registered, the message is printed to console.
-	void 				   status_update_warnings(ObjectID object_id, int step, PrintStateBase::WarningLevel warning_level, const std::string &message);
+    void 				   status_update_warnings(int step, PrintStateBase::WarningLevel warning_level, const std::string &message, const PrintObjectBase* print_object = nullptr);
 
     // If the background processing stop was requested, throw CanceledException.
     // To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
@@ -528,7 +528,7 @@ protected:
 	PrintStateBase::TimeStamp set_done(PrintStepEnum step) { 
 		std::pair<PrintStateBase::TimeStamp, bool> status = m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); });
         if (status.second)
-            this->status_update_warnings(this->id(), static_cast<int>(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string());
+            this->status_update_warnings(static_cast<int>(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string());
         return status.first;
 	}
     bool            invalidate_step(PrintStepEnum step)
@@ -550,7 +550,7 @@ protected:
     	std::pair<PrintStepEnum, bool> active_step = m_state.active_step_add_warning(warning_level, message, message_id, this->state_mutex());
     	if (active_step.second)
     		// Update UI.
-    		this->status_update_warnings(this->id(), static_cast<int>(active_step.first), warning_level, message);
+            this->status_update_warnings(static_cast<int>(active_step.first), warning_level, message);
     }
 
 private:

From 8cb8a24dedaf682763f3be3a7f223edfd985a224 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Fri, 26 Feb 2021 10:18:16 +0100
Subject: [PATCH 21/53] Tech ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN set
 as default

---
 src/libslic3r/AppConfig.cpp             |  4 ----
 src/libslic3r/Technologies.hpp          | 27 +++++++++----------------
 src/slic3r/GUI/ConfigWizard.cpp         |  8 --------
 src/slic3r/GUI/ConfigWizard_private.hpp |  4 ----
 src/slic3r/GUI/GUI_App.cpp              | 10 ---------
 src/slic3r/GUI/GUI_App.hpp              |  9 ---------
 src/slic3r/GUI/Preferences.cpp          |  4 ----
 7 files changed, 10 insertions(+), 56 deletions(-)

diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index 08e5fdf6d..d9301d1f3 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -68,14 +68,12 @@ void AppConfig::set_defaults()
         if (get("export_sources_full_pathnames").empty())
             set("export_sources_full_pathnames", "0");
 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
         if (get("associate_3mf").empty())
             set("associate_3mf", "0");
         if (get("associate_stl").empty())
             set("associate_stl", "0");
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
         // remove old 'use_legacy_opengl' parameter from this config, if present
         if (!get("use_legacy_opengl").empty())
@@ -127,14 +125,12 @@ void AppConfig::set_defaults()
         if (get("color_mapinulation_panel").empty())
             set("color_mapinulation_panel", "0");
     }
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
     else {
 #ifdef _WIN32
         if (get("associate_gcode").empty())
             set("associate_gcode", "0");
 #endif // _WIN32
     }
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
     if (get("seq_top_layer_only").empty())
         set("seq_top_layer_only", "1");
diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index 3ada1cd35..77e1712b1 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -4,7 +4,6 @@
 //=============
 // debug techs
 //=============
-
 // Shows camera target in the 3D scene
 #define ENABLE_SHOW_CAMERA_TARGET 0
 // Log debug messages to console when changing selection
@@ -27,26 +26,14 @@
 #define ENABLE_GCODE_VIEWER_STATISTICS 0
 // Enable G-Code viewer comparison between toolpaths height and width detected from gcode and calculated at gcode generation 
 #define ENABLE_GCODE_VIEWER_DATA_CHECKING 0
+
+
 // Enable rendering of objects using environment map
 #define ENABLE_ENVIRONMENT_MAP 0
 // Enable smoothing of objects normals
 #define ENABLE_SMOOTH_NORMALS 0
-
-
-//====================
-// 2.3.0.alpha4 techs
-//====================
-#define ENABLE_2_3_0_ALPHA4 1
-
-#define ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS (1 && ENABLE_2_3_0_ALPHA4)
-
-
-//===================
-// 2.3.0.beta1 techs
-//===================
-#define ENABLE_2_3_0_BETA1 1
-
-#define ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN (1 && ENABLE_2_3_0_BETA1)
+// Enable rendering markers for options in preview as fixed screen size points
+#define ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS 1
 
 
 //====================
@@ -54,11 +41,17 @@
 //====================
 #define ENABLE_2_3_1_ALPHA1 1
 
+// Enable splitting of vertex buffers used to render toolpaths
 #define ENABLE_SPLITTED_VERTEX_BUFFER (1 && ENABLE_2_3_1_ALPHA1)
+// Enable rendering only starting and final caps for toolpaths
 #define ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS (1 && ENABLE_SPLITTED_VERTEX_BUFFER)
+// Enable reload from disk command for 3mf files
 #define ENABLE_RELOAD_FROM_DISK_FOR_3MF (1 && ENABLE_2_3_1_ALPHA1)
+// Removes obsolete warning texture code
 #define ENABLE_WARNING_TEXTURE_REMOVAL (1 && ENABLE_2_3_1_ALPHA1)
+// Enable showing gcode line numbers in previeww horizontal slider
 #define ENABLE_GCODE_LINES_ID_IN_H_SLIDER (1 && ENABLE_2_3_1_ALPHA1)
+// Enable validation of custom gcode against gcode processor resserved keywords
 #define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_3_1_ALPHA1)
 
 
diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp
index b0bb6a8a4..77e847201 100644
--- a/src/slic3r/GUI/ConfigWizard.cpp
+++ b/src/slic3r/GUI/ConfigWizard.cpp
@@ -1186,7 +1186,6 @@ PageReloadFromDisk::PageReloadFromDisk(ConfigWizard* parent)
     box_pathnames->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { this->full_pathnames = event.IsChecked(); });
 }
 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
 PageFilesAssociation::PageFilesAssociation(ConfigWizard* parent)
     : ConfigWizardPage(parent, _L("Files association"), _L("Files association"))
@@ -1200,7 +1199,6 @@ PageFilesAssociation::PageFilesAssociation(ConfigWizard* parent)
 //    append(cb_gcode);
 }
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
 PageMode::PageMode(ConfigWizard *parent)
     : ConfigWizardPage(parent, _L("View mode"), _L("View mode"))
@@ -1813,11 +1811,9 @@ void ConfigWizard::priv::load_pages()
 
     index->add_page(page_update);
     index->add_page(page_reload_from_disk);
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
     index->add_page(page_files_association);
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
     index->add_page(page_mode);
 
     index->go_to(former_active);   // Will restore the active item/page if possible
@@ -2411,7 +2407,6 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
     app_config->set("preset_update", page_update->preset_update ? "1" : "0");
     app_config->set("export_sources_full_pathnames", page_reload_from_disk->full_pathnames ? "1" : "0");
 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
     app_config->set("associate_3mf", page_files_association->associate_3mf() ? "1" : "0");
     app_config->set("associate_stl", page_files_association->associate_stl() ? "1" : "0");
@@ -2429,7 +2424,6 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
 //    }
 
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
     page_mode->serialize_mode(app_config);
 
@@ -2594,11 +2588,9 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
     
     p->add_page(p->page_update   = new PageUpdate(this));
     p->add_page(p->page_reload_from_disk = new PageReloadFromDisk(this));
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
     p->add_page(p->page_files_association = new PageFilesAssociation(this));
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
     p->add_page(p->page_mode     = new PageMode(this));
     p->add_page(p->page_firmware = new PageFirmware(this));
     p->add_page(p->page_bed      = new PageBedShape(this));
diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp
index 581ec39b1..eee906ae7 100644
--- a/src/slic3r/GUI/ConfigWizard_private.hpp
+++ b/src/slic3r/GUI/ConfigWizard_private.hpp
@@ -393,7 +393,6 @@ struct PageReloadFromDisk : ConfigWizardPage
     PageReloadFromDisk(ConfigWizard* parent);
 };
 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
 struct PageFilesAssociation : ConfigWizardPage
 {
@@ -410,7 +409,6 @@ public:
 //    bool associate_gcode() const { return cb_gcode->IsChecked(); }
 };
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
 struct PageMode: ConfigWizardPage
 {
@@ -572,11 +570,9 @@ struct ConfigWizard::priv
     PageCustom       *page_custom = nullptr;
     PageUpdate       *page_update = nullptr;
     PageReloadFromDisk *page_reload_from_disk = nullptr;
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
     PageFilesAssociation* page_files_association = nullptr;
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
     PageMode         *page_mode = nullptr;
     PageVendors      *page_vendors = nullptr;
     Pages3rdparty     pages_3rdparty;
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 90e178090..2fde30cd1 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -835,14 +835,10 @@ bool GUI_App::on_init_inner()
 
     if (is_editor()) {
 #ifdef __WXMSW__ 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
         if (app_config->get("associate_3mf") == "1")
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
             associate_3mf_files();
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
         if (app_config->get("associate_stl") == "1")
             associate_stl_files();
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #endif // __WXMSW__
 
         preset_updater = new PresetUpdater();
@@ -858,9 +854,7 @@ bool GUI_App::on_init_inner()
     }
     else {
 #ifdef __WXMSW__ 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
         if (app_config->get("associate_gcode") == "1")
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
             associate_gcode_files();
 #endif // __WXMSW__
     }
@@ -1722,7 +1716,6 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
                 if (dlg.seq_top_layer_only_changed())
 #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
                     this->plater_->refresh_print();
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
                 if (is_editor()) {
                     if (app_config->get("associate_3mf") == "1")
@@ -1735,7 +1728,6 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
                         associate_gcode_files();
                 }
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
             }
             if (app_layout_changed) {
                 // hide full main_sizer for mainFrame
@@ -2303,7 +2295,6 @@ void GUI_App::associate_3mf_files()
         ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
 }
 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 void GUI_App::associate_stl_files()
 {
     wchar_t app_path[MAX_PATH];
@@ -2327,7 +2318,6 @@ void GUI_App::associate_stl_files()
         // notify Windows only when any of the values gets changed
         ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
 }
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
 void GUI_App::associate_gcode_files()
 {
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 132776dcb..5572c5071 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -279,13 +279,11 @@ public:
     bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); }
     bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); }
 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef __WXMSW__
     void            associate_3mf_files();
     void            associate_stl_files();
     void            associate_gcode_files();
 #endif // __WXMSW__
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
 private:
     bool            on_init_inner();
@@ -297,13 +295,6 @@ private:
 
     bool            config_wizard_startup();
 	void            check_updates(const bool verbose);
-
-#if !ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
-#ifdef __WXMSW__
-    void            associate_3mf_files();
-    void            associate_gcode_files();
-#endif // __WXMSW__
-#endif // !ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 };
 
 DECLARE_APP(GUI_App)
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index e28bd589d..67381cf22 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -106,7 +106,6 @@ void PreferencesDialog::build()
 		option = Option(def, "export_sources_full_pathnames");
 		m_optgroup_general->append_single_option_line(option);
 
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
 		// Please keep in sync with ConfigWizard
 		def.label = L("Associate .3mf files to PrusaSlicer");
@@ -123,7 +122,6 @@ void PreferencesDialog::build()
 		option = Option(def, "associate_stl");
 		m_optgroup_general->append_single_option_line(option);
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
 		// Please keep in sync with ConfigWizard
 		def.label = L("Update built-in Presets automatically");
@@ -184,7 +182,6 @@ void PreferencesDialog::build()
 		option = Option(def, "default_action_on_select_preset");
 		m_optgroup_general->append_single_option_line(option);
 	}
-#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 #ifdef _WIN32
 	else {
 		def.label = L("Associate .gcode files to PrusaSlicer G-code Viewer");
@@ -195,7 +192,6 @@ void PreferencesDialog::build()
 		m_optgroup_general->append_single_option_line(option);
 	}
 #endif // _WIN32
-#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 
 #if __APPLE__
 	def.label = L("Use Retina resolution for the 3D scene");

From 2d52e155a58740cde9fc9aea5ec860b37c04d5e9 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Fri, 26 Feb 2021 13:56:51 +0100
Subject: [PATCH 22/53] Follow-up of 86d7e1fb907d9841a1d0cf516415fea84e8b5280
 -> Fixed update after editing custom g-code in settings tabs

---
 src/slic3r/GUI/Tab.cpp | 32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 947c058a4..cf1879bb1 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -1732,10 +1732,10 @@ bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode)
     return !invalid;
 }
 
-static void validate_custom_gcode_cb(Tab* tab, ConfigOptionsGroupShp opt_group, const boost::any& value) {
+static void validate_custom_gcode_cb(Tab* tab, ConfigOptionsGroupShp opt_group, const t_config_option_key& opt_key, const boost::any& value) {
     Tab::validate_custom_gcode(opt_group->title, boost::any_cast<std::string>(value));
     tab->update_dirty();
-    tab->update();
+    tab->on_value_change(opt_key, value);
 }
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 
@@ -1964,7 +1964,7 @@ void TabFilament::build()
         optgroup = page->new_optgroup(L("Start G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, value);
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("start_filament_gcode");
@@ -1976,7 +1976,7 @@ void TabFilament::build()
         optgroup = page->new_optgroup(L("End G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, value);
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("end_filament_gcode");
@@ -2273,17 +2273,11 @@ void TabPrinter::build_fff()
 
     const int gcode_field_height = 15; // 150
     const int notes_field_height = 25; // 250
-#if ENABLE_VALIDATE_CUSTOM_GCODE
-    // WARNING !!
-    // if you are going to change any of the following optgroup/option titles
-    // or to add/remove optgroups/options
-    // update also TabPrinter::validate_custom_gcodes()
-#endif // ENABLE_VALIDATE_CUSTOM_GCODE
     page = add_options_page(L("Custom G-code"), "cog");
         optgroup = page->new_optgroup(L("Start G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("start_gcode");
@@ -2295,7 +2289,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("End G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("end_gcode");
@@ -2307,7 +2301,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("Before layer change G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("before_layer_gcode");
@@ -2319,7 +2313,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("After layer change G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("layer_gcode");
@@ -2331,7 +2325,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("Tool change G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("toolchange_gcode");
@@ -2343,7 +2337,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("Between objects G-code (for sequential printing)"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("between_objects_gcode");
@@ -2355,7 +2349,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("Color Change G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("color_change_gcode");
@@ -2366,7 +2360,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("Pause Print G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("pause_print_gcode");
@@ -2377,7 +2371,7 @@ void TabPrinter::build_fff()
         optgroup = page->new_optgroup(L("Template Custom G-code"), 0);
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
-            validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value));
+            validate_custom_gcode_cb(this, optgroup, opt_key, value);
         };
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
         option = optgroup->get_option("template_custom_gcode");

From c9666ea257e4161bdcf5591e91cca2724f562228 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Fri, 26 Feb 2021 14:17:53 +0100
Subject: [PATCH 23/53] #4402 - Review and merge of #6106 Temperature
 visualization in preview and G-code Viewer by combolek

---
 src/libslic3r/GCode/GCodeProcessor.cpp | 33 ++++++++++++++++++++++++++
 src/libslic3r/GCode/GCodeProcessor.hpp | 10 ++++++++
 src/slic3r/GUI/GCodeViewer.cpp         | 11 +++++++--
 src/slic3r/GUI/GCodeViewer.hpp         |  5 ++++
 src/slic3r/GUI/GUI_Preview.cpp         |  1 +
 5 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp
index a4769af8e..c1038bded 100644
--- a/src/libslic3r/GCode/GCodeProcessor.cpp
+++ b/src/libslic3r/GCode/GCodeProcessor.cpp
@@ -678,6 +678,8 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
         m_extruder_colors[i] = static_cast<unsigned char>(i);
     }
 
+    m_extruder_temps.resize(extruders_count);
+
     m_filament_diameters.resize(config.filament_diameter.values.size());
     for (size_t i = 0; i < config.filament_diameter.values.size(); ++i) {
         m_filament_diameters[i] = static_cast<float>(config.filament_diameter.values[i]);
@@ -776,6 +778,8 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
         m_extruder_colors[i] = static_cast<unsigned char>(i);
     }
 
+    m_extruder_temps.resize(m_result.extruders_count);
+
     const ConfigOptionFloats* filament_load_time = config.option<ConfigOptionFloats>("filament_load_time");
     if (filament_load_time != nullptr) {
         m_time_processor.filament_load_times.resize(filament_load_time->values.size());
@@ -910,6 +914,10 @@ void GCodeProcessor::reset()
     for (size_t i = 0; i < Min_Extruder_Count; ++i) {
         m_extruder_colors[i] = static_cast<unsigned char>(i);
     }
+    m_extruder_temps.resize(Min_Extruder_Count);
+    for (size_t i = 0; i < Min_Extruder_Count; ++i) {
+        m_extruder_temps[i] = 0.0f;
+    }
 
     m_filament_diameters = std::vector<float>(Min_Extruder_Count, 1.75f);
     m_extruded_last_z = 0.0f;
@@ -1123,9 +1131,11 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line)
                 case 1:   { process_M1(line); break; }   // Sleep or Conditional stop
                 case 82:  { process_M82(line); break; }  // Set extruder to absolute mode
                 case 83:  { process_M83(line); break; }  // Set extruder to relative mode
+                case 104: { process_M104(line); break; } // Set extruder temperature
                 case 106: { process_M106(line); break; } // Set fan speed
                 case 107: { process_M107(line); break; } // Disable fan
                 case 108: { process_M108(line); break; } // Set tool (Sailfish)
+                case 109: { process_M109(line); break; } // Set extruder temperature and wait
                 case 132: { process_M132(line); break; } // Recall stored home offsets
                 case 135: { process_M135(line); break; } // Set tool (MakerWare)
                 case 201: { process_M201(line); break; } // Set max printing acceleration
@@ -2211,6 +2221,13 @@ void GCodeProcessor::process_M83(const GCodeReader::GCodeLine& line)
     m_e_local_positioning_type = EPositioningType::Relative;
 }
 
+void GCodeProcessor::process_M104(const GCodeReader::GCodeLine& line)
+{
+    float new_temp;
+    if (line.has_value('S', new_temp))
+        m_extruder_temps[m_extruder_id] = new_temp;
+}
+
 void GCodeProcessor::process_M106(const GCodeReader::GCodeLine& line)
 {
     if (!line.has('P')) {
@@ -2243,6 +2260,21 @@ void GCodeProcessor::process_M108(const GCodeReader::GCodeLine& line)
         process_T(cmd.substr(pos));
 }
 
+void GCodeProcessor::process_M109(const GCodeReader::GCodeLine& line)
+{
+    float new_temp;
+    if (line.has_value('R', new_temp)) {
+        float val;
+        if (line.has_value('T', val)) {
+            size_t eid = static_cast<size_t>(val);
+            if (eid < m_extruder_temps.size())
+                m_extruder_temps[eid] = new_temp;
+        }
+        else
+            m_extruder_temps[m_extruder_id] = new_temp;
+    }
+}
+
 void GCodeProcessor::process_M132(const GCodeReader::GCodeLine& line)
 {
     // This command is used by Makerbot to load the current home position from EEPROM
@@ -2531,6 +2563,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
         m_height,
         m_mm3_per_mm,
         m_fan_speed,
+        m_extruder_temps[m_extruder_id],
         static_cast<float>(m_result.moves.size())
     };
     m_result.moves.emplace_back(vertex);
diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp
index f884df8ec..f619864c4 100644
--- a/src/libslic3r/GCode/GCodeProcessor.hpp
+++ b/src/libslic3r/GCode/GCodeProcessor.hpp
@@ -121,6 +121,7 @@ namespace Slic3r {
     private:
         using AxisCoords = std::array<float, 4>;
         using ExtruderColors = std::vector<unsigned char>;
+        using ExtruderTemps = std::vector<float>;
 
         enum class EUnits : unsigned char
         {
@@ -211,6 +212,7 @@ namespace Slic3r {
             float height{ 0.0f }; // mm
             float mm3_per_mm{ 0.0f };
             float fan_speed{ 0.0f }; // percentage
+            float temperature{ 0.0f }; // Celsius degrees
             float time{ 0.0f }; // s
 
             float volumetric_rate() const { return feedrate * mm3_per_mm; }
@@ -320,6 +322,7 @@ namespace Slic3r {
             float height{ 0.0f }; // mm
             float mm3_per_mm{ 0.0f };
             float fan_speed{ 0.0f }; // percentage
+            float temperature{ 0.0f }; // Celsius degrees
             float time{ 0.0f }; // s
 
             float volumetric_rate() const { return feedrate * mm3_per_mm; }
@@ -468,6 +471,7 @@ namespace Slic3r {
         ExtrusionRole m_extrusion_role;
         unsigned char m_extruder_id;
         ExtruderColors m_extruder_colors;
+        ExtruderTemps m_extruder_temps;
         std::vector<float> m_filament_diameters;
         float m_extruded_last_z;
         unsigned int m_g1_line_id;
@@ -586,6 +590,9 @@ namespace Slic3r {
         // Set extruder to relative mode
         void process_M83(const GCodeReader::GCodeLine& line);
 
+        // Set extruder temperature
+        void process_M104(const GCodeReader::GCodeLine& line);
+
         // Set fan speed
         void process_M106(const GCodeReader::GCodeLine& line);
 
@@ -595,6 +602,9 @@ namespace Slic3r {
         // Set tool (Sailfish)
         void process_M108(const GCodeReader::GCodeLine& line);
 
+        // Set extruder temperature and wait
+        void process_M109(const GCodeReader::GCodeLine& line);
+
         // Recall stored home offsets
         void process_M132(const GCodeReader::GCodeLine& line);
 
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index 71441e037..e1c61bbd3 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -180,11 +180,13 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsi
     // use rounding to reduce the number of generated paths
 #if ENABLE_SPLITTED_VERTEX_BUFFER
     paths.push_back({ move.type, move.extrusion_role, move.delta_extruder,
-        round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed,
+        round_to_nearest(move.height, 2), round_to_nearest(move.width, 2),
+        move.feedrate, move.fan_speed, move.temperature,
         move.volumetric_rate(), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } });
 #else
     paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder,
-        round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed,
+        round_to_nearest(move.height, 2), round_to_nearest(move.width, 2),
+        move.feedrate, move.fan_speed, move.temperature,
         move.volumetric_rate(), move.extruder_id, move.cp_color_id });
 #endif // ENABLE_SPLITTED_VERTEX_BUFFER
 }
@@ -492,6 +494,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std:
             m_extrusions.ranges.height.update_from(round_to_nearest(curr.height, 2));
             m_extrusions.ranges.width.update_from(round_to_nearest(curr.width, 2));
             m_extrusions.ranges.fan_speed.update_from(curr.fan_speed);
+            m_extrusions.ranges.temperature.update_from(curr.temperature);
             m_extrusions.ranges.volumetric_rate.update_from(round_to_nearest(curr.volumetric_rate(), 2));
             [[fallthrough]];
         }
@@ -2725,6 +2728,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
         case EViewType::Width:          { color = m_extrusions.ranges.width.get_color_at(path.width); break; }
         case EViewType::Feedrate:       { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; }
         case EViewType::FanSpeed:       { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; }
+        case EViewType::Temperature:    { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; }
         case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; }
         case EViewType::Tool:           { color = m_tool_colors[path.extruder_id]; break; }
         case EViewType::ColorPrint:     {
@@ -3184,6 +3188,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
         case EViewType::Width:          { color = m_extrusions.ranges.width.get_color_at(path.width); break; }
         case EViewType::Feedrate:       { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; }
         case EViewType::FanSpeed:       { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; }
+        case EViewType::Temperature:    { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; }
         case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; }
         case EViewType::Tool:           { color = m_tool_colors[path.extruder_id]; break; }
         case EViewType::ColorPrint:     {
@@ -4014,6 +4019,7 @@ void GCodeViewer::render_legend() const
     case EViewType::Width:          { imgui.title(_u8L("Width (mm)")); break; }
     case EViewType::Feedrate:       { imgui.title(_u8L("Speed (mm/s)")); break; }
     case EViewType::FanSpeed:       { imgui.title(_u8L("Fan Speed (%)")); break; }
+    case EViewType::Temperature:    { imgui.title(_u8L("Temperature (°C)")); break; }
     case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; }
     case EViewType::Tool:           { imgui.title(_u8L("Tool")); break; }
     case EViewType::ColorPrint:     { imgui.title(_u8L("Color Print")); break; }
@@ -4048,6 +4054,7 @@ void GCodeViewer::render_legend() const
     case EViewType::Width:          { append_range(m_extrusions.ranges.width, 3); break; }
     case EViewType::Feedrate:       { append_range(m_extrusions.ranges.feedrate, 1); break; }
     case EViewType::FanSpeed:       { append_range(m_extrusions.ranges.fan_speed, 0); break; }
+    case EViewType::Temperature:    { append_range(m_extrusions.ranges.temperature, 0); break; }
     case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; }
     case EViewType::Tool:
     {
diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp
index 290c13d51..2abbb81f1 100644
--- a/src/slic3r/GUI/GCodeViewer.hpp
+++ b/src/slic3r/GUI/GCodeViewer.hpp
@@ -179,6 +179,7 @@ class GCodeViewer
         float width{ 0.0f };
         float feedrate{ 0.0f };
         float fan_speed{ 0.0f };
+        float temperature{ 0.0f };
         float volumetric_rate{ 0.0f };
         unsigned char extruder_id{ 0 };
         unsigned char cp_color_id{ 0 };
@@ -407,6 +408,8 @@ class GCodeViewer
             Range fan_speed;
             // Color mapping by volumetric extrusion rate.
             Range volumetric_rate;
+            // Color mapping by extrusion temperature.
+            Range temperature;
 
             void reset() {
                 height.reset();
@@ -414,6 +417,7 @@ class GCodeViewer
                 feedrate.reset();
                 fan_speed.reset();
                 volumetric_rate.reset();
+                temperature.reset();
             }
         };
 
@@ -626,6 +630,7 @@ public:
         Width,
         Feedrate,
         FanSpeed,
+        Temperature,
         VolumetricRate,
         Tool,
         ColorPrint,
diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp
index 76677660d..2f11d66f5 100644
--- a/src/slic3r/GUI/GUI_Preview.cpp
+++ b/src/slic3r/GUI/GUI_Preview.cpp
@@ -211,6 +211,7 @@ bool Preview::init(wxWindow* parent, Model* model)
     m_choice_view_type->Append(_L("Width"));
     m_choice_view_type->Append(_L("Speed"));
     m_choice_view_type->Append(_L("Fan speed"));
+    m_choice_view_type->Append(_L("Temperature"));
     m_choice_view_type->Append(_L("Volumetric flow rate"));
     m_choice_view_type->Append(_L("Tool"));
     m_choice_view_type->Append(_L("Color Print"));

From 9a31580bde1e3cc94cfadfafd3a138154640c3c5 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Fri, 26 Feb 2021 16:00:32 +0100
Subject: [PATCH 24/53] GCodeProcessor -> use boost::starts_with()

---
 src/libslic3r/GCode/GCodeProcessor.cpp | 51 ++++++++++----------------
 src/libslic3r/Technologies.hpp         |  2 +-
 2 files changed, 21 insertions(+), 32 deletions(-)

diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp
index c1038bded..46fd3c5b3 100644
--- a/src/libslic3r/GCode/GCodeProcessor.cpp
+++ b/src/libslic3r/GCode/GCodeProcessor.cpp
@@ -4,6 +4,9 @@
 #include "GCodeProcessor.hpp"
 
 #include <boost/log/trivial.hpp>
+#if ENABLE_VALIDATE_CUSTOM_GCODE
+#include <boost/algorithm/string/predicate.hpp>
+#endif // ENABLE_VALIDATE_CUSTOM_GCODE
 #include <boost/nowide/fstream.hpp>
 #include <boost/nowide/cstdio.hpp>
 
@@ -594,12 +597,6 @@ const std::vector<std::pair<GCodeProcessor::EProducer, std::string>> GCodeProces
 unsigned int GCodeProcessor::s_result_id = 0;
 
 #if ENABLE_VALIDATE_CUSTOM_GCODE
-static inline bool starts_with(const std::string_view comment, const std::string_view tag)
-{
-    size_t tag_len = tag.size();
-    return comment.size() >= tag_len && comment.substr(0, tag_len) == tag;
-}
-
 bool GCodeProcessor::contains_reserved_tag(const std::string& gcode, std::string& found_tag)
 {
     bool ret = false;
@@ -610,7 +607,7 @@ bool GCodeProcessor::contains_reserved_tag(const std::string& gcode, std::string
         if (comment.length() > 2 && comment.front() == ';') {
             comment = comment.substr(1);
             for (const std::string& s : Reserved_Tags) {
-                if (starts_with(comment, s)) {
+                if (boost::starts_with(comment, s)) {
                     ret = true;
                     found_tag = comment;
                     parser.quit_parsing();
@@ -635,7 +632,7 @@ bool GCodeProcessor::contains_reserved_tags(const std::string& gcode, unsigned i
         if (comment.length() > 2 && comment.front() == ';') {
             comment = comment.substr(1);
             for (const std::string& s : Reserved_Tags) {
-                if (starts_with(comment, s)) {
+                if (boost::starts_with(comment, s)) {
                     ret = true;
                     found_tag.push_back(comment);
                     if (found_tag.size() == max_count) {
@@ -1168,14 +1165,6 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line)
     }
 }
 
-#if !ENABLE_VALIDATE_CUSTOM_GCODE
-static inline bool starts_with(const std::string_view comment, const std::string_view tag)
-{
-    size_t tag_len = tag.size();
-    return comment.size() >= tag_len && comment.substr(0, tag_len) == tag;
-}
-#endif // !ENABLE_VALIDATE_CUSTOM_GCODE
-
 #if __has_include(<charconv>)
     template <typename T, typename = void>
     struct is_from_chars_convertible : std::false_type {};
@@ -1229,37 +1218,37 @@ void GCodeProcessor::process_tags(const std::string_view comment)
 
 #if ENABLE_VALIDATE_CUSTOM_GCODE
     // extrusion role tag
-    if (starts_with(comment, reserved_tag(ETags::Role))) {
+    if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
         m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length()));
         return;
     }
 
     // wipe start tag
-    if (starts_with(comment, reserved_tag(ETags::Wipe_Start))) {
+    if (boost::starts_with(comment, reserved_tag(ETags::Wipe_Start))) {
         m_wiping = true;
         return;
     }
 
     // wipe end tag
-    if (starts_with(comment, reserved_tag(ETags::Wipe_End))) {
+    if (boost::starts_with(comment, reserved_tag(ETags::Wipe_End))) {
         m_wiping = false;
         return;
     }
 #else
     // extrusion role tag
-    if (starts_with(comment, Extrusion_Role_Tag)) {
+    if (boost::starts_with(comment, Extrusion_Role_Tag)) {
         m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(Extrusion_Role_Tag.length()));
         return;
     }
 
     // wipe start tag
-    if (starts_with(comment, Wipe_Start_Tag)) {
+    if (boost::starts_with(comment, Wipe_Start_Tag)) {
         m_wiping = true;
         return;
     }
 
     // wipe end tag
-    if (starts_with(comment, Wipe_End_Tag)) {
+    if (boost::starts_with(comment, Wipe_End_Tag)) {
         m_wiping = false;
         return;
     }
@@ -1268,26 +1257,26 @@ void GCodeProcessor::process_tags(const std::string_view comment)
     if (!m_producers_enabled || m_producer == EProducer::PrusaSlicer) {
 #if ENABLE_VALIDATE_CUSTOM_GCODE
         // height tag
-        if (starts_with(comment, reserved_tag(ETags::Height))) {
+        if (boost::starts_with(comment, reserved_tag(ETags::Height))) {
             if (!parse_number(comment.substr(reserved_tag(ETags::Height).size()), m_forced_height))
                 BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ").";
             return;
         }
         // width tag
-        if (starts_with(comment, reserved_tag(ETags::Width))) {
+        if (boost::starts_with(comment, reserved_tag(ETags::Width))) {
             if (!parse_number(comment.substr(reserved_tag(ETags::Width).size()), m_forced_width))
                 BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ").";
             return;
         }
 #else
         // height tag
-        if (starts_with(comment, Height_Tag)) {
+        if (boost::starts_with(comment, Height_Tag)) {
             if (!parse_number(comment.substr(Height_Tag.size()), m_forced_height))
                 BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ").";
             return;
         }
         // width tag
-        if (starts_with(comment, Width_Tag)) {
+        if (boost::starts_with(comment, Width_Tag)) {
             if (!parse_number(comment.substr(Width_Tag.size()), m_forced_width))
                 BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ").";
             return;
@@ -1297,9 +1286,9 @@ void GCodeProcessor::process_tags(const std::string_view comment)
 
 #if ENABLE_VALIDATE_CUSTOM_GCODE
     // color change tag
-    if (starts_with(comment, reserved_tag(ETags::Color_Change))) {
+    if (boost::starts_with(comment, reserved_tag(ETags::Color_Change))) {
         unsigned char extruder_id = 0;
-        if (starts_with(comment.substr(reserved_tag(ETags::Color_Change).size()), ",T")) {
+        if (boost::starts_with(comment.substr(reserved_tag(ETags::Color_Change).size()), ",T")) {
             int eid;
             if (!parse_number(comment.substr(reserved_tag(ETags::Color_Change).size() + 2), eid) || eid < 0 || eid > 255) {
                 BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ").";
@@ -1343,9 +1332,9 @@ void GCodeProcessor::process_tags(const std::string_view comment)
     }
 #else
     // color change tag
-    if (starts_with(comment, Color_Change_Tag)) {
+    if (boost::starts_with(comment, Color_Change_Tag)) {
         unsigned char extruder_id = 0;
-        if (starts_with(comment.substr(Color_Change_Tag.size()), ",T")) {
+        if (boost::starts_with(comment.substr(Color_Change_Tag.size()), ",T")) {
             int eid;
             if (! parse_number(comment.substr(Color_Change_Tag.size() + 2), eid) || eid < 0 || eid > 255) {
                 BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ").";
@@ -1391,7 +1380,7 @@ void GCodeProcessor::process_tags(const std::string_view comment)
 
 #if ENABLE_GCODE_VIEWER_DATA_CHECKING
     // mm3_per_mm print tag
-    if (starts_with(comment, Mm3_Per_Mm_Tag)) {
+    if (boost::starts_with(comment, Mm3_Per_Mm_Tag)) {
         if (! parse_number(comment.substr(Mm3_Per_Mm_Tag.size()), m_mm3_per_mm_compare.last_tag_value))
             BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Mm3_Per_Mm (" << comment << ").";
         return;
diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index 77e1712b1..55de9637a 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -51,7 +51,7 @@
 #define ENABLE_WARNING_TEXTURE_REMOVAL (1 && ENABLE_2_3_1_ALPHA1)
 // Enable showing gcode line numbers in previeww horizontal slider
 #define ENABLE_GCODE_LINES_ID_IN_H_SLIDER (1 && ENABLE_2_3_1_ALPHA1)
-// Enable validation of custom gcode against gcode processor resserved keywords
+// Enable validation of custom gcode against gcode processor reserved keywords
 #define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_3_1_ALPHA1)
 
 

From b10d064a24d30a04117a429d096e23851c4df570 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Fri, 26 Feb 2021 13:56:09 +0100
Subject: [PATCH 25/53] Added an empty category icon for Fuzzy Skin to prevent
 crashes in ObjectList The icon should later be replaced by a proper one.

---
 resources/icons/fuzzy_skin.svg    | 8 ++++++++
 src/slic3r/GUI/GUI_ObjectList.cpp | 1 +
 2 files changed, 9 insertions(+)
 create mode 100644 resources/icons/fuzzy_skin.svg

diff --git a/resources/icons/fuzzy_skin.svg b/resources/icons/fuzzy_skin.svg
new file mode 100644
index 000000000..b8ba0a651
--- /dev/null
+++ b/resources/icons/fuzzy_skin.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
+<g>
+	<circle fill="#808080" cx="8" cy="8" r="0"/>
+</g>
+</svg>
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 5247558c7..ad5ee151d 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -93,6 +93,7 @@ ObjectList::ObjectList(wxWindow* parent) :
         CATEGORY_ICON[L("Layers and Perimeters")]    = create_scaled_bitmap("layers");
         CATEGORY_ICON[L("Infill")]                   = create_scaled_bitmap("infill");
         CATEGORY_ICON[L("Ironing")]                  = create_scaled_bitmap("ironing");
+        CATEGORY_ICON[L("Fuzzy Skin")]               = create_scaled_bitmap("fuzzy_skin");
         CATEGORY_ICON[L("Support material")]         = create_scaled_bitmap("support");
         CATEGORY_ICON[L("Speed")]                    = create_scaled_bitmap("time");
         CATEGORY_ICON[L("Extruders")]                = create_scaled_bitmap("funnel");

From 6391d4243ff42ddcca10ca22f870cf5bcde77b25 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sat, 27 Feb 2021 17:40:44 +0100
Subject: [PATCH 26/53] creality.ini: tweak fill_density and skirt_distance

---
 resources/profiles/Creality.ini | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 9d86d3dea..67ae69a3c 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -273,7 +273,7 @@ extruder_clearance_height = 34
 extruder_clearance_radius = 47
 extrusion_width = 0.45
 fill_angle = 45
-fill_density = 20%
+fill_density = 15%
 fill_pattern = grid
 first_layer_extrusion_width = 0.42
 first_layer_height = 0.2
@@ -309,7 +309,7 @@ resolution = 0
 seam_position = nearest
 single_extruder_multi_material_priming = 1
 skirts = 1
-skirt_distance = 2
+skirt_distance = 3
 skirt_height = 2
 small_perimeter_speed = 25
 solid_infill_below_area = 0

From 19c50c7e694351c493d211c4dcad339702980d28 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sat, 27 Feb 2021 17:51:57 +0100
Subject: [PATCH 27/53] creality.ini: consolidate more properties to *common*

---
 resources/profiles/Creality.ini | 107 +++++++++++++-------------------
 1 file changed, 42 insertions(+), 65 deletions(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 67ae69a3c..2bc03751e 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -712,7 +712,7 @@ printer_technology = FFF
 before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0\n;[layer_z]\n\n
 between_objects_gcode = 
 pause_print_gcode = 
-deretract_speed = 0
+deretract_speed = 40
 extruder_colour = #FCE94F
 extruder_offset = 0x0
 gcode_flavor = marlin
@@ -735,23 +735,24 @@ machine_max_jerk_z = 0.4
 machine_min_extruding_rate = 0
 machine_min_travel_rate = 0
 layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
-max_layer_height = 0.3
-min_layer_height = 0.07
+max_layer_height = 0.28
+min_layer_height = 0.08
 max_print_height = 250
 nozzle_diameter = 0.4
 printer_notes = 
 printer_settings_id = 
-retract_before_travel = 1
-retract_before_wipe = 0%
+printer_variant = 0.4
+retract_before_travel = 2
+retract_before_wipe = 70%
 retract_layer_change = 1
-retract_length = 1
+retract_length = 5
 retract_length_toolchange = 1
 retract_lift = 0
 retract_lift_above = 0
 retract_lift_below = 0
 retract_restart_extra = 0
 retract_restart_extra_toolchange = 0
-retract_speed = 35
+retract_speed = 60
 single_extruder_multi_material = 0
 toolchange_gcode = 
 use_firmware_retraction = 0
@@ -763,39 +764,6 @@ z_offset = 0
 printer_model = 
 default_print_profile = 0.16mm OPTIMAL @CREALITY
 default_filament_profile = Generic PLA @CREALITY
-
-[printer:Creality Ender-3]
-inherits = *common*
-renamed_from = "Creality ENDER-3"
-printer_model = ENDER3
-printer_variant = 0.4
-max_layer_height = 0.28
-min_layer_height = 0.08
-printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3\nPRINTER_HAS_BOWDEN
-bed_shape = 3x3,228x3,228x228,3x228
-max_print_height = 250
-machine_max_acceleration_e = 5000
-machine_max_acceleration_extruding = 500
-machine_max_acceleration_retracting = 1000
-machine_max_acceleration_x = 500
-machine_max_acceleration_y = 500
-machine_max_acceleration_z = 100
-machine_max_feedrate_e = 60
-machine_max_feedrate_x = 500
-machine_max_feedrate_y = 500
-machine_max_feedrate_z = 10
-machine_max_jerk_e = 5
-machine_max_jerk_x = 8
-machine_max_jerk_y = 8
-machine_max_jerk_z = 0.4
-machine_min_extruding_rate = 0
-machine_min_travel_rate = 0
-nozzle_diameter = 0.4
-retract_before_travel = 2
-retract_length = 5
-retract_speed = 60
-deretract_speed = 40
-retract_before_wipe = 70%
 start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S120 ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling\nM140 S[first_layer_bed_temperature] ; set final bed temp\nG4 S10 ; allow partial nozzle warmup\nG28 ; home all axis\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set final nozzle temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp to stabilize\nM109 S[first_layer_temperature] ; wait for nozzle temp to stabilize\nG1 Z0.28 F240\nG92 E0\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E10 F1200 ; prime the nozzle\nG92 E0
 end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors
 
@@ -842,19 +810,28 @@ retract_restart_extra_toolchange = 0,0
 retract_speed = 60,60
 wipe = 1,1
 
+[printer:Creality Ender-3]
+inherits = *common*
+renamed_from = "Creality ENDER-3"
+bed_shape = 3x3,228x3,228x228,3x228
+max_print_height = 250
+printer_model = ENDER3
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3\nPRINTER_HAS_BOWDEN
+
 [printer:Creality Ender-3 BLTouch]
 inherits = Creality Ender-3; *fastabl*
 renamed_from = "Creality ENDER-3 BLTouch"
 printer_model = ENDER3BLTOUCH
 
 [printer:Creality Ender-3 V2]
-inherits = Creality Ender-3
+inherits = *common*
 renamed_from = "Creality Ender-3V2"
-printer_model = ENDER3V2
 bed_shape = 5x0,215x0,215x220,5x220
+max_print_height = 250
+printer_model = ENDER3V2
 
 #[printer:Creality Ender-3 Max]
-#inherits = Creality Ender-3
+#inherits = *common*
 #retract_length = 6
 #bed_shape = 5x5,295x5,295x295,5x295
 #max_print_height = 340
@@ -862,14 +839,14 @@ bed_shape = 5x0,215x0,215x220,5x220
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3MAX\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality Ender-4]
-#inherits = Creality Ender-3; *descendingz*
+#inherits = *common*; *descendingz*
 #bed_shape = 5x0,215x0,215x220,5x220
 #max_print_height = 300
 #printer_model = ENDER4
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER4\nPRINTER_HAS_BOWDEN
 
 [printer:Creality Ender-5]
-inherits = Creality Ender-3; *descendingz*
+inherits = *common*; *descendingz*
 retract_length = 6
 bed_shape = 5x2.5,225x2.5,225x222.5,5x222.5
 max_print_height = 300
@@ -879,7 +856,7 @@ machine_max_acceleration_e = 1000
 machine_max_feedrate_z = 5
 
 [printer:Creality Ender-5 Plus]
-inherits = Creality Ender-3; *slowabl*; *descendingz*
+inherits = *common*; *slowabl*; *descendingz*
 retract_length = 6
 bed_shape = 5x5,355x5,355x355,5x355
 max_print_height = 400
@@ -891,14 +868,14 @@ machine_max_feedrate_x = 300
 machine_max_feedrate_y = 300
 
 #[printer:Creality Ender-6]
-#inherits = Creality Ender-3; *descendingz*
+#inherits = *common*; *descendingz*
 #bed_shape = 5x5,255x5,255x255,5x255
 #max_print_height = 400
 #printer_model = ENDER6
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER6\nPRINTER_HAS_BOWDEN
 
 [printer:Creality Ender-2]
-inherits = Creality Ender-3
+inherits = *common*
 renamed_from = "Creality ENDER-2"
 bed_shape = 0x0,150x0,150x150,0x150
 max_print_height = 200
@@ -906,13 +883,13 @@ printer_model = ENDER2
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER2\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-6 SE]
-#inherits = Creality Ender-3; *fastabl*; *pauseprint*
+#inherits = *common*; *fastabl*; *pauseprint*
 #bed_shape = 5x0,230x0,230x235,5x235
 #printer_model = CR6SE
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-6 Max]
-#inherits = Creality Ender-3; *slowabl*
+#inherits = *common*; *slowabl*
 #retract_length = 6
 #bed_shape = 5x5,395x5,395x395,5x395
 #max_print_height = 400
@@ -920,7 +897,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6MAX\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 Mini]
-inherits = Creality Ender-3
+inherits = *common*
 retract_length = 6
 bed_shape = 2.5x5,2.5x225,302.5x225,302.5x5
 max_print_height = 300
@@ -928,7 +905,7 @@ printer_model = CR10MINI
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10MINI\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-10 Max]
-#inherits = Creality Ender-3; *slowabl*
+#inherits = *common*; *slowabl*
 #retract_length = 6
 #bed_shape = 5x5,445x5,445x445,5x445
 #max_print_height = 470
@@ -936,7 +913,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10MAX\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10]
-inherits = Creality Ender-3
+inherits = *common*
 retract_length = 6
 bed_shape = 5x5,305x5,305x305,5x305
 max_print_height = 400
@@ -944,7 +921,7 @@ printer_model = CR10
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 V2]
-inherits = Creality Ender-3
+inherits = *common*
 retract_length = 6
 bed_shape = 5x5,305x5,305x305,5x305
 max_print_height = 400
@@ -952,7 +929,7 @@ printer_model = CR10V2
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10V2\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 V3]
-inherits = Creality Ender-3
+inherits = *common*
 retract_length = 1
 bed_shape = 5x5,305x5,305x305,5x305
 max_print_height = 400
@@ -960,7 +937,7 @@ printer_model = CR10V3
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10V3
 
 [printer:Creality CR-10 S]
-inherits = Creality Ender-3
+inherits = *common*
 retract_length = 6
 bed_shape = 5x5,305x5,305x305,5x305
 max_print_height = 400
@@ -968,7 +945,7 @@ printer_model = CR10S
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10S\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 S Pro]
-inherits = Creality Ender-3; *slowabl*
+inherits = *common*; *slowabl*
 retract_length = 6
 bed_shape = 5x5,295x5,295x295,5x295
 max_print_height = 400
@@ -976,7 +953,7 @@ printer_model = CR10SPRO
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10SPRO\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 S Pro V2]
-inherits = Creality Ender-3; *slowabl*
+inherits = *common*; *slowabl*
 retract_length = 6
 bed_shape = 5x5,305x5,305x305,5x305
 max_print_height = 400
@@ -984,7 +961,7 @@ printer_model = CR10SPROV2
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10SPROV2\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 S4]
-inherits = Creality Ender-3
+inherits = *common*
 retract_length = 6
 bed_shape = 5x5,395x5,395x395,5x395
 max_print_height = 400
@@ -992,7 +969,7 @@ printer_model = CR10S4
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10S4\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 S5]
-inherits = Creality Ender-3
+inherits = *common*
 retract_length = 6
 bed_shape = 5x5,505x5,505x505,5x505
 max_print_height = 500
@@ -1000,25 +977,25 @@ printer_model = CR10S5
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10S5\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-20]
-inherits = Creality Ender-3
+inherits = *common*
 printer_model = CR20
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR20\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-20 Pro]
-inherits = Creality Ender-3; *fastabl*
+inherits = *common*; *fastabl*
 retract_length = 4
 printer_model = CR20PRO
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR20PRO\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-8]
-#inherits = Creality Ender-3
+#inherits = *common*
 #bed_shape = 5x5,215x5,215x215,5x215
 #max_print_height = 210
 #printer_model = CR8
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR8\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-X]
-#inherits = Creality Ender-3; *dualextruder*
+#inherits = *common*; *dualextruder*
 #retract_length = 6,6
 #bed_shape = 5x5,295x5,295x295,5x295
 #max_print_height = 400
@@ -1026,7 +1003,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CRX\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-X Pro]
-#inherits = Creality Ender-3; *dualextruder*; *slowabl*
+#inherits = *common*; *dualextruder*; *slowabl*
 #retract_length = 6,6
 #bed_shape = 5x5,295x5,295x295,5x295
 #max_print_height = 400

From c142af74c52d28eb3aa9c80a07760f421c78a38f Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sat, 27 Feb 2021 17:53:20 +0100
Subject: [PATCH 28/53] creality.ini: add printer_notes to Ender3V2

---
 resources/profiles/Creality.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 2bc03751e..c439ed0e4 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -829,6 +829,7 @@ renamed_from = "Creality Ender-3V2"
 bed_shape = 5x0,215x0,215x220,5x220
 max_print_height = 250
 printer_model = ENDER3V2
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3V2\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality Ender-3 Max]
 #inherits = *common*

From bc9c968f0546fa0531931e3f9cdc34a330c15305 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sat, 27 Feb 2021 18:16:47 +0100
Subject: [PATCH 29/53] creality.ini disable
 single_extruder_multi_material_priming

---
 resources/profiles/Creality.ini | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index c439ed0e4..6dfe32b40 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -307,7 +307,7 @@ print_settings_id =
 raft_layers = 0
 resolution = 0
 seam_position = nearest
-single_extruder_multi_material_priming = 1
+single_extruder_multi_material_priming = 0
 skirts = 1
 skirt_distance = 3
 skirt_height = 2
@@ -787,6 +787,7 @@ end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2,
 # Intended for printers with dual extruders and a single hotend/nozzle, like the CR-X series
 [printer:*dualextruder*]
 single_extruder_multi_material = 1
+single_extruder_multi_material_priming = 0
 cooling_tube_length = 5
 cooling_tube_retraction = 91.5
 extra_loading_move = -2

From 249670f82c04d5d9d475ea6b38dc191beac32295 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sun, 28 Feb 2021 16:36:58 +0100
Subject: [PATCH 30/53] creality.ini: fix CR-10 Mini bed_shape

---
 resources/profiles/Creality.ini | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 6dfe32b40..67b108209 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -901,7 +901,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 [printer:Creality CR-10 Mini]
 inherits = *common*
 retract_length = 6
-bed_shape = 2.5x5,2.5x225,302.5x225,302.5x5
+bed_shape = 2.5x5,302.5x5,302.5x225,2.5x225
 max_print_height = 300
 printer_model = CR10MINI
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10MINI\nPRINTER_HAS_BOWDEN

From 2d762ec3202e9d7e400db4b20e3e5630098f6a19 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sun, 28 Feb 2021 16:38:05 +0100
Subject: [PATCH 31/53] creality.ini: add CR-5 Pro

retract_length = 3
to prevent clogging since this printer is suspected to have
an all metal hot end, as Creality claims print temperatures
up to 300C
---
 resources/profiles/Creality.ini | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 67b108209..790c352ff 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -95,6 +95,15 @@ bed_model = ender2_bed.stl
 bed_texture = ender2.svg
 default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
+#[printer_model:CR5PRO]
+#name = Creality CR-5 Pro
+#variants = 0.4
+#technology = FFF
+#family = CR
+#bed_model = cr10mini_bed.stl
+#bed_texture = cr10mini.svg
+#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+
 #[printer_model:CR6SE]
 #name = Creality CR-6 SE
 #variants = 0.4
@@ -884,6 +893,14 @@ max_print_height = 200
 printer_model = ENDER2
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER2\nPRINTER_HAS_BOWDEN
 
+#[printer:Creality CR-5 Pro]
+#inherits = *common*; *slowabl*; *descendingz*
+#retract_length = 3
+#bed_shape = 2.5x5,302.5x5,302.5x225,2.5x225
+#max_print_height = 380
+#printer_model = CR5PRO
+#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PRO\nPRINTER_HAS_BOWDEN
+
 #[printer:Creality CR-6 SE]
 #inherits = *common*; *fastabl*; *pauseprint*
 #bed_shape = 5x0,230x0,230x235,5x235

From 19ba6f14927d47fad09410d56f927d861f55560d Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sun, 28 Feb 2021 16:53:33 +0100
Subject: [PATCH 32/53] creality.ini: add CR-200B

---
 resources/profiles/Creality.ini            |   14 +
 resources/profiles/Creality/cr200b.svg     |    4 +
 resources/profiles/Creality/cr200b_bed.stl | 2774 ++++++++++++++++++++
 3 files changed, 2792 insertions(+)
 create mode 100644 resources/profiles/Creality/cr200b.svg
 create mode 100644 resources/profiles/Creality/cr200b_bed.stl

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 790c352ff..2e9971f21 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -230,6 +230,15 @@ bed_model = ender3_bed.stl
 bed_texture = cr20.svg
 default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
+#[printer_model:CR200B]
+#name = Creality CR-200B
+#variants = 0.4
+#technology = FFF
+#family = CR
+#bed_model = cr200b_bed.stl
+#bed_texture = cr200b.svg
+#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+
 #[printer_model:CR8]
 #name = Creality CR-8
 #variants = 0.4
@@ -1006,6 +1015,11 @@ retract_length = 4
 printer_model = CR20PRO
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR20PRO\nPRINTER_HAS_BOWDEN
 
+#[printer:Creality CR-200B]
+#inherits = *common*
+#printer_model = CR200B
+#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR200B\nPRINTER_HAS_BOWDEN
+
 #[printer:Creality CR-8]
 #inherits = *common*
 #bed_shape = 5x5,215x5,215x215,5x215
diff --git a/resources/profiles/Creality/cr200b.svg b/resources/profiles/Creality/cr200b.svg
new file mode 100644
index 000000000..6012188d7
--- /dev/null
+++ b/resources/profiles/Creality/cr200b.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="190mm" height="190mm" version="1.1" viewBox="0 0 190 190" xmlns="http://www.w3.org/2000/svg">
+  <rect x=".25" y=".25" width="189.5" height="189.5" fill="none" stroke="#fff" stroke-width=".5"/>
+</svg>
diff --git a/resources/profiles/Creality/cr200b_bed.stl b/resources/profiles/Creality/cr200b_bed.stl
new file mode 100644
index 000000000..210c329e7
--- /dev/null
+++ b/resources/profiles/Creality/cr200b_bed.stl
@@ -0,0 +1,2774 @@
+solid OpenSCAD_Model
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.1047 -99.9982 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 97.3136 -99.9836 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 97.3136 -99.9836 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 97.5209 -99.9544 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 100 -97 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 97.5209 -99.9544 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 97.7258 -99.9109 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 97.7258 -99.9109 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 97.927 -99.8532 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 97.927 -99.8532 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 98.1238 -99.7815 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 98.1238 -99.7815 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 98.3151 -99.6964 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 98.3151 -99.6964 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 98.5 -99.5981 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 98.5 -99.5981 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 98.6776 -99.4871 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 98.6776 -99.4871 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 98.847 -99.364 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 98.847 -99.364 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.0074 -99.2294 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.0074 -99.2294 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.158 -99.084 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.158 -99.084 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.2981 -98.9284 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.2981 -98.9284 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.427 -98.7634 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.427 -98.7634 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.5441 -98.5898 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.5441 -98.5898 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.6488 -98.4084 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.6488 -98.4084 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.7406 -98.2202 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.7406 -98.2202 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.8191 -98.026 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.8191 -98.026 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.8838 -97.8269 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.8838 -97.8269 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.9344 -97.6237 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.9344 -97.6237 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.9708 -97.4175 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.9708 -97.4175 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 99.9927 -97.2093 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 99.9927 -97.2093 -3
+      vertex 97.0018 -99.9982 -3
+      vertex 100 -97 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 100 -97 -3
+      vertex 97.0018 99.9982 -3
+      vertex 100 97 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.0018 99.9982 -3
+      vertex 99.9708 97.4175 -3
+      vertex 99.9927 97.2093 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 99.8838 97.8269 -3
+      vertex 99.9344 97.6237 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 99.7406 98.2202 -3
+      vertex 97.0018 99.9982 -3
+      vertex 99.6488 98.4084 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 99.7406 98.2202 -3
+      vertex 99.8191 98.026 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.0018 99.9982 -3
+      vertex 99.0074 99.2294 -3
+      vertex 99.158 99.084 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 99.427 98.7634 -3
+      vertex 97.0018 99.9982 -3
+      vertex 99.2981 98.9284 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 99.427 98.7634 -3
+      vertex 99.5441 98.5898 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 99.2981 98.9284 -3
+      vertex 97.0018 99.9982 -3
+      vertex 99.158 99.084 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.0018 99.9982 -3
+      vertex 97.927 99.8532 -3
+      vertex 98.1238 99.7815 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 98.847 99.364 -3
+      vertex 97.0018 99.9982 -3
+      vertex 98.6776 99.4871 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 98.847 99.364 -3
+      vertex 99.0074 99.2294 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 98.6776 99.4871 -3
+      vertex 97.0018 99.9982 -3
+      vertex 98.5 99.5981 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 98.5 99.5981 -3
+      vertex 97.0018 99.9982 -3
+      vertex 98.3151 99.6964 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 98.3151 99.6964 -3
+      vertex 97.0018 99.9982 -3
+      vertex 98.1238 99.7815 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 99.6488 98.4084 -3
+      vertex 97.0018 99.9982 -3
+      vertex 99.5441 98.5898 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.7258 99.9109 -3
+      vertex 97.0018 99.9982 -3
+      vertex 97.5209 99.9544 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 97.7258 99.9109 -3
+      vertex 97.927 99.8532 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 99.8191 98.026 -3
+      vertex 99.8838 97.8269 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 97.3136 99.9836 -3
+      vertex 97.5209 99.9544 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.0018 99.9982 -3
+      vertex 99.9344 97.6237 -3
+      vertex 99.9708 97.4175 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.0018 99.9982 -3
+      vertex 97.1047 99.9982 -3
+      vertex 97.3136 99.9836 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 100 97 -3
+      vertex 97.0018 99.9982 -3
+      vertex 99.9927 97.2093 -3
+    endloop
+  endfacet
+  facet normal 0 -0 -1
+    outer loop
+      vertex -97 100 -3
+      vertex 97 100 -3
+      vertex -97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex 97 100 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.0018 -99.9982 -3
+      vertex -97.0018 99.9982 -3
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -100 -97 -3
+      vertex -100 97 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -97.3136 99.9836 -3
+      vertex -97.1047 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -97.5209 99.9544 -3
+      vertex -97.3136 99.9836 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -97.7258 99.9109 -3
+      vertex -97.5209 99.9544 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -97.927 99.8532 -3
+      vertex -97.7258 99.9109 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -98.1238 99.7815 -3
+      vertex -97.927 99.8532 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -98.3151 99.6964 -3
+      vertex -98.1238 99.7815 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -98.5 99.5981 -3
+      vertex -98.3151 99.6964 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -98.6776 99.4871 -3
+      vertex -98.5 99.5981 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -98.847 99.364 -3
+      vertex -98.6776 99.4871 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.0074 99.2294 -3
+      vertex -98.847 99.364 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.158 99.084 -3
+      vertex -99.0074 99.2294 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.2981 98.9284 -3
+      vertex -99.158 99.084 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.427 98.7634 -3
+      vertex -99.2981 98.9284 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.5441 98.5898 -3
+      vertex -99.427 98.7634 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.6488 98.4084 -3
+      vertex -99.5441 98.5898 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.7406 98.2202 -3
+      vertex -99.6488 98.4084 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.8191 98.026 -3
+      vertex -99.7406 98.2202 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.8838 97.8269 -3
+      vertex -99.8191 98.026 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.9344 97.6237 -3
+      vertex -99.8838 97.8269 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.9708 97.4175 -3
+      vertex -99.9344 97.6237 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -99.9927 97.2093 -3
+      vertex -99.9708 97.4175 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -100 97 -3
+      vertex -99.9927 97.2093 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -100 97 -3
+      vertex -97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 97.0018 -99.9982 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -99.9708 -97.4175 -3
+      vertex -99.9927 -97.2093 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.8838 -97.8269 -3
+      vertex -99.9344 -97.6237 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.7406 -98.2202 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -99.6488 -98.4084 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.7406 -98.2202 -3
+      vertex -99.8191 -98.026 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -99.0074 -99.2294 -3
+      vertex -99.158 -99.084 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.427 -98.7634 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -99.2981 -98.9284 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.427 -98.7634 -3
+      vertex -99.5441 -98.5898 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.2981 -98.9284 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -99.158 -99.084 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -97.927 -99.8532 -3
+      vertex -98.1238 -99.7815 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -98.847 -99.364 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -98.6776 -99.4871 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -98.847 -99.364 -3
+      vertex -99.0074 -99.2294 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -98.6776 -99.4871 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -98.5 -99.5981 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -98.5 -99.5981 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -98.3151 -99.6964 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -98.3151 -99.6964 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -98.1238 -99.7815 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.6488 -98.4084 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -99.5441 -98.5898 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.7258 -99.9109 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -97.5209 -99.9544 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.7258 -99.9109 -3
+      vertex -97.927 -99.8532 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -99.8191 -98.026 -3
+      vertex -99.8838 -97.8269 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.3136 -99.9836 -3
+      vertex -97.5209 -99.9544 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -99.9344 -97.6237 -3
+      vertex -99.9708 -97.4175 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -97.1047 -99.9982 -3
+      vertex -97.3136 -99.9836 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 97.0018 -99.9982 -3
+      vertex 97 -100 -3
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex 97 -100 -3
+      vertex -97 -100 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -100 -97 -3
+      vertex -97.0018 -99.9982 -3
+      vertex -99.9927 -97.2093 -3
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.3136 -99.9836 0
+      vertex 97.0018 -99.9982 0
+      vertex 97.1047 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.5209 -99.9544 0
+      vertex 97.0018 -99.9982 0
+      vertex 97.3136 -99.9836 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 97.0018 -99.9982 0
+      vertex 100 -97 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.7258 -99.9109 0
+      vertex 97.0018 -99.9982 0
+      vertex 97.5209 -99.9544 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.927 -99.8532 0
+      vertex 97.0018 -99.9982 0
+      vertex 97.7258 -99.9109 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.1238 -99.7815 0
+      vertex 97.0018 -99.9982 0
+      vertex 97.927 -99.8532 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.3151 -99.6964 0
+      vertex 97.0018 -99.9982 0
+      vertex 98.1238 -99.7815 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.5 -99.5981 0
+      vertex 97.0018 -99.9982 0
+      vertex 98.3151 -99.6964 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.6776 -99.4871 0
+      vertex 97.0018 -99.9982 0
+      vertex 98.5 -99.5981 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.847 -99.364 0
+      vertex 97.0018 -99.9982 0
+      vertex 98.6776 -99.4871 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.0074 -99.2294 0
+      vertex 97.0018 -99.9982 0
+      vertex 98.847 -99.364 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.158 -99.084 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.0074 -99.2294 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.2981 -98.9284 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.158 -99.084 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.427 -98.7634 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.2981 -98.9284 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.5441 -98.5898 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.427 -98.7634 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.6488 -98.4084 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.5441 -98.5898 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.7406 -98.2202 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.6488 -98.4084 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.8191 -98.026 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.7406 -98.2202 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.8838 -97.8269 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.8191 -98.026 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.9344 -97.6237 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.8838 -97.8269 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.9708 -97.4175 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.9344 -97.6237 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.9927 -97.2093 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.9708 -97.4175 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 100 -97 0
+      vertex 97.0018 -99.9982 0
+      vertex 99.9927 -97.2093 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 100 97 0
+      vertex 97.0018 99.9982 0
+      vertex 100 -97 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.9927 97.2093 0
+      vertex 99.9708 97.4175 0
+      vertex 97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 99.9344 97.6237 0
+      vertex 99.8838 97.8269 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.6488 98.4084 0
+      vertex 97.0018 99.9982 0
+      vertex 99.7406 98.2202 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 99.8191 98.026 0
+      vertex 99.7406 98.2202 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.158 99.084 0
+      vertex 99.0074 99.2294 0
+      vertex 97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.2981 98.9284 0
+      vertex 97.0018 99.9982 0
+      vertex 99.427 98.7634 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 99.5441 98.5898 0
+      vertex 99.427 98.7634 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.158 99.084 0
+      vertex 97.0018 99.9982 0
+      vertex 99.2981 98.9284 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.1238 99.7815 0
+      vertex 97.927 99.8532 0
+      vertex 97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.6776 99.4871 0
+      vertex 97.0018 99.9982 0
+      vertex 98.847 99.364 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 99.0074 99.2294 0
+      vertex 98.847 99.364 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.5 99.5981 0
+      vertex 97.0018 99.9982 0
+      vertex 98.6776 99.4871 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.3151 99.6964 0
+      vertex 97.0018 99.9982 0
+      vertex 98.5 99.5981 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 98.1238 99.7815 0
+      vertex 97.0018 99.9982 0
+      vertex 98.3151 99.6964 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.5441 98.5898 0
+      vertex 97.0018 99.9982 0
+      vertex 99.6488 98.4084 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.5209 99.9544 0
+      vertex 97.0018 99.9982 0
+      vertex 97.7258 99.9109 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 97.927 99.8532 0
+      vertex 97.7258 99.9109 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 99.8838 97.8269 0
+      vertex 99.8191 98.026 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 97.5209 99.9544 0
+      vertex 97.3136 99.9836 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.9708 97.4175 0
+      vertex 99.9344 97.6237 0
+      vertex 97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.3136 99.9836 0
+      vertex 97.1047 99.9982 0
+      vertex 97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 99.9927 97.2093 0
+      vertex 97.0018 99.9982 0
+      vertex 100 97 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 99.9982 0
+      vertex 97 100 0
+      vertex -97 100 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex 97 100 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 97.0018 99.9982 0
+      vertex -97.0018 99.9982 0
+      vertex 97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -100 97 0
+      vertex -100 -97 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -97.1047 99.9982 0
+      vertex -97.3136 99.9836 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -97.3136 99.9836 0
+      vertex -97.5209 99.9544 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -97.5209 99.9544 0
+      vertex -97.7258 99.9109 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -97.7258 99.9109 0
+      vertex -97.927 99.8532 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -97.927 99.8532 0
+      vertex -98.1238 99.7815 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -98.1238 99.7815 0
+      vertex -98.3151 99.6964 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -98.3151 99.6964 0
+      vertex -98.5 99.5981 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -98.5 99.5981 0
+      vertex -98.6776 99.4871 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -98.6776 99.4871 0
+      vertex -98.847 99.364 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -98.847 99.364 0
+      vertex -99.0074 99.2294 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.0074 99.2294 0
+      vertex -99.158 99.084 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.158 99.084 0
+      vertex -99.2981 98.9284 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.2981 98.9284 0
+      vertex -99.427 98.7634 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.427 98.7634 0
+      vertex -99.5441 98.5898 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.5441 98.5898 0
+      vertex -99.6488 98.4084 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.6488 98.4084 0
+      vertex -99.7406 98.2202 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.7406 98.2202 0
+      vertex -99.8191 98.026 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.8191 98.026 0
+      vertex -99.8838 97.8269 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.8838 97.8269 0
+      vertex -99.9344 97.6237 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.9344 97.6237 0
+      vertex -99.9708 97.4175 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.9708 97.4175 0
+      vertex -99.9927 97.2093 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -99.9927 97.2093 0
+      vertex -100 97 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 99.9982 0
+      vertex -100 97 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 99.9982 0
+      vertex -97.0018 -99.9982 0
+      vertex 97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -99.9927 -97.2093 0
+      vertex -99.9708 -97.4175 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -99.9344 -97.6237 0
+      vertex -99.8838 -97.8269 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -99.6488 -98.4084 0
+      vertex -97.0018 -99.9982 0
+      vertex -99.7406 -98.2202 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -99.8191 -98.026 0
+      vertex -99.7406 -98.2202 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -99.158 -99.084 0
+      vertex -99.0074 -99.2294 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -99.2981 -98.9284 0
+      vertex -97.0018 -99.9982 0
+      vertex -99.427 -98.7634 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -99.5441 -98.5898 0
+      vertex -99.427 -98.7634 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -99.158 -99.084 0
+      vertex -97.0018 -99.9982 0
+      vertex -99.2981 -98.9284 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -98.1238 -99.7815 0
+      vertex -97.927 -99.8532 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -98.6776 -99.4871 0
+      vertex -97.0018 -99.9982 0
+      vertex -98.847 -99.364 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -99.0074 -99.2294 0
+      vertex -98.847 -99.364 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -98.5 -99.5981 0
+      vertex -97.0018 -99.9982 0
+      vertex -98.6776 -99.4871 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -98.3151 -99.6964 0
+      vertex -97.0018 -99.9982 0
+      vertex -98.5 -99.5981 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -98.1238 -99.7815 0
+      vertex -97.0018 -99.9982 0
+      vertex -98.3151 -99.6964 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -99.5441 -98.5898 0
+      vertex -97.0018 -99.9982 0
+      vertex -99.6488 -98.4084 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -97.5209 -99.9544 0
+      vertex -97.0018 -99.9982 0
+      vertex -97.7258 -99.9109 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -97.927 -99.8532 0
+      vertex -97.7258 -99.9109 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -99.8838 -97.8269 0
+      vertex -99.8191 -98.026 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex -97.5209 -99.9544 0
+      vertex -97.3136 -99.9836 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -99.9708 -97.4175 0
+      vertex -99.9344 -97.6237 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -97.3136 -99.9836 0
+      vertex -97.1047 -99.9982 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -97.0018 -99.9982 0
+      vertex 97 -100 0
+      vertex 97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 -0 1
+    outer loop
+      vertex -97 -100 0
+      vertex 97 -100 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -99.9927 -97.2093 0
+      vertex -97.0018 -99.9982 0
+      vertex -100 -97 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 97.1047 -99.9982 -3
+      vertex 97.0018 -99.9982 0
+      vertex 97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 97.1047 -99.9982 -3
+      vertex 97.1047 -99.9982 0
+      vertex 97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0.0697198 -0.997567 0
+    outer loop
+      vertex 97.3136 -99.9836 -3
+      vertex 97.1047 -99.9982 0
+      vertex 97.1047 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0.0697198 -0.997567 0
+    outer loop
+      vertex 97.3136 -99.9836 -3
+      vertex 97.3136 -99.9836 0
+      vertex 97.1047 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0.139482 -0.990225 0
+    outer loop
+      vertex 97.5209 -99.9544 -3
+      vertex 97.3136 -99.9836 0
+      vertex 97.3136 -99.9836 -3
+    endloop
+  endfacet
+  facet normal 0.139482 -0.990225 0
+    outer loop
+      vertex 97.5209 -99.9544 -3
+      vertex 97.5209 -99.9544 0
+      vertex 97.3136 -99.9836 0
+    endloop
+  endfacet
+  facet normal 0.20767 -0.978199 0
+    outer loop
+      vertex 97.7258 -99.9109 -3
+      vertex 97.5209 -99.9544 0
+      vertex 97.5209 -99.9544 -3
+    endloop
+  endfacet
+  facet normal 0.20767 -0.978199 0
+    outer loop
+      vertex 97.7258 -99.9109 -3
+      vertex 97.7258 -99.9109 0
+      vertex 97.5209 -99.9544 0
+    endloop
+  endfacet
+  facet normal 0.275668 -0.961253 0
+    outer loop
+      vertex 97.927 -99.8532 -3
+      vertex 97.7258 -99.9109 0
+      vertex 97.7258 -99.9109 -3
+    endloop
+  endfacet
+  facet normal 0.275668 -0.961253 0
+    outer loop
+      vertex 97.927 -99.8532 -3
+      vertex 97.927 -99.8532 0
+      vertex 97.7258 -99.9109 0
+    endloop
+  endfacet
+  facet normal 0.342318 -0.939584 0
+    outer loop
+      vertex 98.1238 -99.7815 -3
+      vertex 97.927 -99.8532 0
+      vertex 97.927 -99.8532 -3
+    endloop
+  endfacet
+  facet normal 0.342318 -0.939584 0
+    outer loop
+      vertex 98.1238 -99.7815 -3
+      vertex 98.1238 -99.7815 0
+      vertex 97.927 -99.8532 0
+    endloop
+  endfacet
+  facet normal 0.406449 -0.913674 0
+    outer loop
+      vertex 98.3151 -99.6964 -3
+      vertex 98.1238 -99.7815 0
+      vertex 98.1238 -99.7815 -3
+    endloop
+  endfacet
+  facet normal 0.406449 -0.913674 0
+    outer loop
+      vertex 98.3151 -99.6964 -3
+      vertex 98.3151 -99.6964 0
+      vertex 98.1238 -99.7815 0
+    endloop
+  endfacet
+  facet normal 0.469423 -0.882973 0
+    outer loop
+      vertex 98.5 -99.5981 -3
+      vertex 98.3151 -99.6964 0
+      vertex 98.3151 -99.6964 -3
+    endloop
+  endfacet
+  facet normal 0.469423 -0.882973 0
+    outer loop
+      vertex 98.5 -99.5981 -3
+      vertex 98.5 -99.5981 0
+      vertex 98.3151 -99.6964 0
+    endloop
+  endfacet
+  facet normal 0.529999 -0.847998 0
+    outer loop
+      vertex 98.6776 -99.4871 -3
+      vertex 98.5 -99.5981 0
+      vertex 98.5 -99.5981 -3
+    endloop
+  endfacet
+  facet normal 0.529999 -0.847998 0
+    outer loop
+      vertex 98.6776 -99.4871 -3
+      vertex 98.6776 -99.4871 0
+      vertex 98.5 -99.5981 0
+    endloop
+  endfacet
+  facet normal 0.587859 -0.808963 0
+    outer loop
+      vertex 98.847 -99.364 -3
+      vertex 98.6776 -99.4871 0
+      vertex 98.6776 -99.4871 -3
+    endloop
+  endfacet
+  facet normal 0.587859 -0.808963 0
+    outer loop
+      vertex 98.847 -99.364 -3
+      vertex 98.847 -99.364 0
+      vertex 98.6776 -99.4871 0
+    endloop
+  endfacet
+  facet normal 0.642811 -0.766025 0
+    outer loop
+      vertex 99.0074 -99.2294 -3
+      vertex 98.847 -99.364 0
+      vertex 98.847 -99.364 -3
+    endloop
+  endfacet
+  facet normal 0.642811 -0.766025 0
+    outer loop
+      vertex 99.0074 -99.2294 -3
+      vertex 99.0074 -99.2294 0
+      vertex 98.847 -99.364 0
+    endloop
+  endfacet
+  facet normal 0.694577 -0.719418 0
+    outer loop
+      vertex 99.158 -99.084 -3
+      vertex 99.0074 -99.2294 0
+      vertex 99.0074 -99.2294 -3
+    endloop
+  endfacet
+  facet normal 0.694577 -0.719418 0
+    outer loop
+      vertex 99.158 -99.084 -3
+      vertex 99.158 -99.084 0
+      vertex 99.0074 -99.2294 0
+    endloop
+  endfacet
+  facet normal 0.743152 -0.669123 0
+    outer loop
+      vertex 99.2981 -98.9284 -3
+      vertex 99.158 -99.084 0
+      vertex 99.158 -99.084 -3
+    endloop
+  endfacet
+  facet normal 0.743152 -0.669123 0
+    outer loop
+      vertex 99.2981 -98.9284 -3
+      vertex 99.2981 -98.9284 0
+      vertex 99.158 -99.084 0
+    endloop
+  endfacet
+  facet normal 0.788039 -0.615626 0
+    outer loop
+      vertex 99.427 -98.7634 -3
+      vertex 99.2981 -98.9284 0
+      vertex 99.2981 -98.9284 -3
+    endloop
+  endfacet
+  facet normal 0.788039 -0.615626 0
+    outer loop
+      vertex 99.427 -98.7634 -3
+      vertex 99.427 -98.7634 0
+      vertex 99.2981 -98.9284 0
+    endloop
+  endfacet
+  facet normal 0.829026 -0.55921 0
+    outer loop
+      vertex 99.5441 -98.5898 -3
+      vertex 99.427 -98.7634 0
+      vertex 99.427 -98.7634 -3
+    endloop
+  endfacet
+  facet normal 0.829026 -0.55921 0
+    outer loop
+      vertex 99.5441 -98.5898 -3
+      vertex 99.5441 -98.5898 0
+      vertex 99.427 -98.7634 0
+    endloop
+  endfacet
+  facet normal 0.86609 -0.499888 0
+    outer loop
+      vertex 99.6488 -98.4084 -3
+      vertex 99.5441 -98.5898 0
+      vertex 99.5441 -98.5898 -3
+    endloop
+  endfacet
+  facet normal 0.86609 -0.499888 0
+    outer loop
+      vertex 99.6488 -98.4084 -3
+      vertex 99.6488 -98.4084 0
+      vertex 99.5441 -98.5898 0
+    endloop
+  endfacet
+  facet normal 0.898778 -0.438405 0
+    outer loop
+      vertex 99.7406 -98.2202 -3
+      vertex 99.6488 -98.4084 0
+      vertex 99.6488 -98.4084 -3
+    endloop
+  endfacet
+  facet normal 0.898778 -0.438405 0
+    outer loop
+      vertex 99.7406 -98.2202 -3
+      vertex 99.7406 -98.2202 0
+      vertex 99.6488 -98.4084 0
+    endloop
+  endfacet
+  facet normal 0.927121 -0.374763 0
+    outer loop
+      vertex 99.8191 -98.026 -3
+      vertex 99.7406 -98.2202 0
+      vertex 99.7406 -98.2202 -3
+    endloop
+  endfacet
+  facet normal 0.927121 -0.374763 0
+    outer loop
+      vertex 99.8191 -98.026 -3
+      vertex 99.8191 -98.026 0
+      vertex 99.7406 -98.2202 0
+    endloop
+  endfacet
+  facet normal 0.951045 -0.309054 0
+    outer loop
+      vertex 99.8838 -97.8269 -3
+      vertex 99.8191 -98.026 0
+      vertex 99.8191 -98.026 -3
+    endloop
+  endfacet
+  facet normal 0.951045 -0.309054 0
+    outer loop
+      vertex 99.8838 -97.8269 -3
+      vertex 99.8838 -97.8269 0
+      vertex 99.8191 -98.026 0
+    endloop
+  endfacet
+  facet normal 0.970367 -0.241637 0
+    outer loop
+      vertex 99.9344 -97.6237 -3
+      vertex 99.8838 -97.8269 0
+      vertex 99.8838 -97.8269 -3
+    endloop
+  endfacet
+  facet normal 0.970367 -0.241637 0
+    outer loop
+      vertex 99.9344 -97.6237 -3
+      vertex 99.9344 -97.6237 0
+      vertex 99.8838 -97.8269 0
+    endloop
+  endfacet
+  facet normal 0.984774 -0.17384 0
+    outer loop
+      vertex 99.9708 -97.4175 -3
+      vertex 99.9344 -97.6237 0
+      vertex 99.9344 -97.6237 -3
+    endloop
+  endfacet
+  facet normal 0.984774 -0.17384 0
+    outer loop
+      vertex 99.9708 -97.4175 -3
+      vertex 99.9708 -97.4175 0
+      vertex 99.9344 -97.6237 0
+    endloop
+  endfacet
+  facet normal 0.994513 -0.10461 0
+    outer loop
+      vertex 99.9927 -97.2093 -3
+      vertex 99.9708 -97.4175 0
+      vertex 99.9708 -97.4175 -3
+    endloop
+  endfacet
+  facet normal 0.994513 -0.10461 0
+    outer loop
+      vertex 99.9927 -97.2093 -3
+      vertex 99.9927 -97.2093 0
+      vertex 99.9708 -97.4175 0
+    endloop
+  endfacet
+  facet normal 0.999392 -0.034857 0
+    outer loop
+      vertex 100 -97 -3
+      vertex 99.9927 -97.2093 0
+      vertex 99.9927 -97.2093 -3
+    endloop
+  endfacet
+  facet normal 0.999392 -0.034857 0
+    outer loop
+      vertex 100 -97 -3
+      vertex 100 -97 0
+      vertex 99.9927 -97.2093 0
+    endloop
+  endfacet
+  facet normal 1 0 0
+    outer loop
+      vertex 100 97 -3
+      vertex 100 -97 0
+      vertex 100 -97 -3
+    endloop
+  endfacet
+  facet normal 1 0 -0
+    outer loop
+      vertex 100 97 -3
+      vertex 100 97 0
+      vertex 100 -97 0
+    endloop
+  endfacet
+  facet normal 0.999392 0.034857 0
+    outer loop
+      vertex 99.9927 97.2093 -3
+      vertex 100 97 0
+      vertex 100 97 -3
+    endloop
+  endfacet
+  facet normal 0.999392 0.034857 -0
+    outer loop
+      vertex 99.9927 97.2093 -3
+      vertex 99.9927 97.2093 0
+      vertex 100 97 0
+    endloop
+  endfacet
+  facet normal 0.994513 0.10461 0
+    outer loop
+      vertex 99.9708 97.4175 -3
+      vertex 99.9927 97.2093 0
+      vertex 99.9927 97.2093 -3
+    endloop
+  endfacet
+  facet normal 0.994513 0.10461 -0
+    outer loop
+      vertex 99.9708 97.4175 -3
+      vertex 99.9708 97.4175 0
+      vertex 99.9927 97.2093 0
+    endloop
+  endfacet
+  facet normal 0.984774 0.17384 0
+    outer loop
+      vertex 99.9344 97.6237 -3
+      vertex 99.9708 97.4175 0
+      vertex 99.9708 97.4175 -3
+    endloop
+  endfacet
+  facet normal 0.984774 0.17384 -0
+    outer loop
+      vertex 99.9344 97.6237 -3
+      vertex 99.9344 97.6237 0
+      vertex 99.9708 97.4175 0
+    endloop
+  endfacet
+  facet normal 0.970367 0.241637 0
+    outer loop
+      vertex 99.8838 97.8269 -3
+      vertex 99.9344 97.6237 0
+      vertex 99.9344 97.6237 -3
+    endloop
+  endfacet
+  facet normal 0.970367 0.241637 -0
+    outer loop
+      vertex 99.8838 97.8269 -3
+      vertex 99.8838 97.8269 0
+      vertex 99.9344 97.6237 0
+    endloop
+  endfacet
+  facet normal 0.951045 0.309054 0
+    outer loop
+      vertex 99.8191 98.026 -3
+      vertex 99.8838 97.8269 0
+      vertex 99.8838 97.8269 -3
+    endloop
+  endfacet
+  facet normal 0.951045 0.309054 -0
+    outer loop
+      vertex 99.8191 98.026 -3
+      vertex 99.8191 98.026 0
+      vertex 99.8838 97.8269 0
+    endloop
+  endfacet
+  facet normal 0.927121 0.374763 0
+    outer loop
+      vertex 99.7406 98.2202 -3
+      vertex 99.8191 98.026 0
+      vertex 99.8191 98.026 -3
+    endloop
+  endfacet
+  facet normal 0.927121 0.374763 -0
+    outer loop
+      vertex 99.7406 98.2202 -3
+      vertex 99.7406 98.2202 0
+      vertex 99.8191 98.026 0
+    endloop
+  endfacet
+  facet normal 0.898778 0.438405 0
+    outer loop
+      vertex 99.6488 98.4084 -3
+      vertex 99.7406 98.2202 0
+      vertex 99.7406 98.2202 -3
+    endloop
+  endfacet
+  facet normal 0.898778 0.438405 -0
+    outer loop
+      vertex 99.6488 98.4084 -3
+      vertex 99.6488 98.4084 0
+      vertex 99.7406 98.2202 0
+    endloop
+  endfacet
+  facet normal 0.86609 0.499888 0
+    outer loop
+      vertex 99.5441 98.5898 -3
+      vertex 99.6488 98.4084 0
+      vertex 99.6488 98.4084 -3
+    endloop
+  endfacet
+  facet normal 0.86609 0.499888 -0
+    outer loop
+      vertex 99.5441 98.5898 -3
+      vertex 99.5441 98.5898 0
+      vertex 99.6488 98.4084 0
+    endloop
+  endfacet
+  facet normal 0.829026 0.55921 0
+    outer loop
+      vertex 99.427 98.7634 -3
+      vertex 99.5441 98.5898 0
+      vertex 99.5441 98.5898 -3
+    endloop
+  endfacet
+  facet normal 0.829026 0.55921 -0
+    outer loop
+      vertex 99.427 98.7634 -3
+      vertex 99.427 98.7634 0
+      vertex 99.5441 98.5898 0
+    endloop
+  endfacet
+  facet normal 0.788039 0.615626 0
+    outer loop
+      vertex 99.2981 98.9284 -3
+      vertex 99.427 98.7634 0
+      vertex 99.427 98.7634 -3
+    endloop
+  endfacet
+  facet normal 0.788039 0.615626 -0
+    outer loop
+      vertex 99.2981 98.9284 -3
+      vertex 99.2981 98.9284 0
+      vertex 99.427 98.7634 0
+    endloop
+  endfacet
+  facet normal 0.743152 0.669123 0
+    outer loop
+      vertex 99.158 99.084 -3
+      vertex 99.2981 98.9284 0
+      vertex 99.2981 98.9284 -3
+    endloop
+  endfacet
+  facet normal 0.743152 0.669123 -0
+    outer loop
+      vertex 99.158 99.084 -3
+      vertex 99.158 99.084 0
+      vertex 99.2981 98.9284 0
+    endloop
+  endfacet
+  facet normal 0.694577 0.719418 0
+    outer loop
+      vertex 99.0074 99.2294 -3
+      vertex 99.158 99.084 0
+      vertex 99.158 99.084 -3
+    endloop
+  endfacet
+  facet normal 0.694577 0.719418 -0
+    outer loop
+      vertex 99.0074 99.2294 -3
+      vertex 99.0074 99.2294 0
+      vertex 99.158 99.084 0
+    endloop
+  endfacet
+  facet normal 0.642811 0.766025 0
+    outer loop
+      vertex 98.847 99.364 -3
+      vertex 99.0074 99.2294 0
+      vertex 99.0074 99.2294 -3
+    endloop
+  endfacet
+  facet normal 0.642811 0.766025 -0
+    outer loop
+      vertex 98.847 99.364 -3
+      vertex 98.847 99.364 0
+      vertex 99.0074 99.2294 0
+    endloop
+  endfacet
+  facet normal 0.587859 0.808963 0
+    outer loop
+      vertex 98.6776 99.4871 -3
+      vertex 98.847 99.364 0
+      vertex 98.847 99.364 -3
+    endloop
+  endfacet
+  facet normal 0.587859 0.808963 -0
+    outer loop
+      vertex 98.6776 99.4871 -3
+      vertex 98.6776 99.4871 0
+      vertex 98.847 99.364 0
+    endloop
+  endfacet
+  facet normal 0.529999 0.847998 0
+    outer loop
+      vertex 98.5 99.5981 -3
+      vertex 98.6776 99.4871 0
+      vertex 98.6776 99.4871 -3
+    endloop
+  endfacet
+  facet normal 0.529999 0.847998 -0
+    outer loop
+      vertex 98.5 99.5981 -3
+      vertex 98.5 99.5981 0
+      vertex 98.6776 99.4871 0
+    endloop
+  endfacet
+  facet normal 0.469423 0.882973 0
+    outer loop
+      vertex 98.3151 99.6964 -3
+      vertex 98.5 99.5981 0
+      vertex 98.5 99.5981 -3
+    endloop
+  endfacet
+  facet normal 0.469423 0.882973 -0
+    outer loop
+      vertex 98.3151 99.6964 -3
+      vertex 98.3151 99.6964 0
+      vertex 98.5 99.5981 0
+    endloop
+  endfacet
+  facet normal 0.406449 0.913674 0
+    outer loop
+      vertex 98.1238 99.7815 -3
+      vertex 98.3151 99.6964 0
+      vertex 98.3151 99.6964 -3
+    endloop
+  endfacet
+  facet normal 0.406449 0.913674 -0
+    outer loop
+      vertex 98.1238 99.7815 -3
+      vertex 98.1238 99.7815 0
+      vertex 98.3151 99.6964 0
+    endloop
+  endfacet
+  facet normal 0.342318 0.939584 0
+    outer loop
+      vertex 97.927 99.8532 -3
+      vertex 98.1238 99.7815 0
+      vertex 98.1238 99.7815 -3
+    endloop
+  endfacet
+  facet normal 0.342318 0.939584 -0
+    outer loop
+      vertex 97.927 99.8532 -3
+      vertex 97.927 99.8532 0
+      vertex 98.1238 99.7815 0
+    endloop
+  endfacet
+  facet normal 0.275668 0.961253 0
+    outer loop
+      vertex 97.7258 99.9109 -3
+      vertex 97.927 99.8532 0
+      vertex 97.927 99.8532 -3
+    endloop
+  endfacet
+  facet normal 0.275668 0.961253 -0
+    outer loop
+      vertex 97.7258 99.9109 -3
+      vertex 97.7258 99.9109 0
+      vertex 97.927 99.8532 0
+    endloop
+  endfacet
+  facet normal 0.20767 0.978199 0
+    outer loop
+      vertex 97.5209 99.9544 -3
+      vertex 97.7258 99.9109 0
+      vertex 97.7258 99.9109 -3
+    endloop
+  endfacet
+  facet normal 0.20767 0.978199 -0
+    outer loop
+      vertex 97.5209 99.9544 -3
+      vertex 97.5209 99.9544 0
+      vertex 97.7258 99.9109 0
+    endloop
+  endfacet
+  facet normal 0.139482 0.990225 0
+    outer loop
+      vertex 97.3136 99.9836 -3
+      vertex 97.5209 99.9544 0
+      vertex 97.5209 99.9544 -3
+    endloop
+  endfacet
+  facet normal 0.139482 0.990225 -0
+    outer loop
+      vertex 97.3136 99.9836 -3
+      vertex 97.3136 99.9836 0
+      vertex 97.5209 99.9544 0
+    endloop
+  endfacet
+  facet normal 0.0697198 0.997567 0
+    outer loop
+      vertex 97.1047 99.9982 -3
+      vertex 97.3136 99.9836 0
+      vertex 97.3136 99.9836 -3
+    endloop
+  endfacet
+  facet normal 0.0697198 0.997567 -0
+    outer loop
+      vertex 97.1047 99.9982 -3
+      vertex 97.1047 99.9982 0
+      vertex 97.3136 99.9836 0
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex 97.0018 99.9982 -3
+      vertex 97.1047 99.9982 0
+      vertex 97.1047 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex 97.0018 99.9982 -3
+      vertex 97.0018 99.9982 0
+      vertex 97.1047 99.9982 0
+    endloop
+  endfacet
+  facet normal 0.707107 0.707107 0
+    outer loop
+      vertex 97 100 -3
+      vertex 97.0018 99.9982 0
+      vertex 97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0.707107 0.707107 -0
+    outer loop
+      vertex 97 100 -3
+      vertex 97 100 0
+      vertex 97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -97 100 -3
+      vertex 97 100 0
+      vertex 97 100 -3
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -97 100 -3
+      vertex -97 100 0
+      vertex 97 100 0
+    endloop
+  endfacet
+  facet normal -0.707107 0.707107 0
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -97 100 0
+      vertex -97 100 -3
+    endloop
+  endfacet
+  facet normal -0.707107 0.707107 0
+    outer loop
+      vertex -97.0018 99.9982 -3
+      vertex -97.0018 99.9982 0
+      vertex -97 100 0
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -97.1047 99.9982 -3
+      vertex -97.0018 99.9982 0
+      vertex -97.0018 99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -97.1047 99.9982 -3
+      vertex -97.1047 99.9982 0
+      vertex -97.0018 99.9982 0
+    endloop
+  endfacet
+  facet normal -0.0697198 0.997567 0
+    outer loop
+      vertex -97.3136 99.9836 -3
+      vertex -97.1047 99.9982 0
+      vertex -97.1047 99.9982 -3
+    endloop
+  endfacet
+  facet normal -0.0697198 0.997567 0
+    outer loop
+      vertex -97.3136 99.9836 -3
+      vertex -97.3136 99.9836 0
+      vertex -97.1047 99.9982 0
+    endloop
+  endfacet
+  facet normal -0.139482 0.990225 0
+    outer loop
+      vertex -97.5209 99.9544 -3
+      vertex -97.3136 99.9836 0
+      vertex -97.3136 99.9836 -3
+    endloop
+  endfacet
+  facet normal -0.139482 0.990225 0
+    outer loop
+      vertex -97.5209 99.9544 -3
+      vertex -97.5209 99.9544 0
+      vertex -97.3136 99.9836 0
+    endloop
+  endfacet
+  facet normal -0.20767 0.978199 0
+    outer loop
+      vertex -97.7258 99.9109 -3
+      vertex -97.5209 99.9544 0
+      vertex -97.5209 99.9544 -3
+    endloop
+  endfacet
+  facet normal -0.20767 0.978199 0
+    outer loop
+      vertex -97.7258 99.9109 -3
+      vertex -97.7258 99.9109 0
+      vertex -97.5209 99.9544 0
+    endloop
+  endfacet
+  facet normal -0.275668 0.961253 0
+    outer loop
+      vertex -97.927 99.8532 -3
+      vertex -97.7258 99.9109 0
+      vertex -97.7258 99.9109 -3
+    endloop
+  endfacet
+  facet normal -0.275668 0.961253 0
+    outer loop
+      vertex -97.927 99.8532 -3
+      vertex -97.927 99.8532 0
+      vertex -97.7258 99.9109 0
+    endloop
+  endfacet
+  facet normal -0.342318 0.939584 0
+    outer loop
+      vertex -98.1238 99.7815 -3
+      vertex -97.927 99.8532 0
+      vertex -97.927 99.8532 -3
+    endloop
+  endfacet
+  facet normal -0.342318 0.939584 0
+    outer loop
+      vertex -98.1238 99.7815 -3
+      vertex -98.1238 99.7815 0
+      vertex -97.927 99.8532 0
+    endloop
+  endfacet
+  facet normal -0.406449 0.913674 0
+    outer loop
+      vertex -98.3151 99.6964 -3
+      vertex -98.1238 99.7815 0
+      vertex -98.1238 99.7815 -3
+    endloop
+  endfacet
+  facet normal -0.406449 0.913674 0
+    outer loop
+      vertex -98.3151 99.6964 -3
+      vertex -98.3151 99.6964 0
+      vertex -98.1238 99.7815 0
+    endloop
+  endfacet
+  facet normal -0.469423 0.882973 0
+    outer loop
+      vertex -98.5 99.5981 -3
+      vertex -98.3151 99.6964 0
+      vertex -98.3151 99.6964 -3
+    endloop
+  endfacet
+  facet normal -0.469423 0.882973 0
+    outer loop
+      vertex -98.5 99.5981 -3
+      vertex -98.5 99.5981 0
+      vertex -98.3151 99.6964 0
+    endloop
+  endfacet
+  facet normal -0.529999 0.847998 0
+    outer loop
+      vertex -98.6776 99.4871 -3
+      vertex -98.5 99.5981 0
+      vertex -98.5 99.5981 -3
+    endloop
+  endfacet
+  facet normal -0.529999 0.847998 0
+    outer loop
+      vertex -98.6776 99.4871 -3
+      vertex -98.6776 99.4871 0
+      vertex -98.5 99.5981 0
+    endloop
+  endfacet
+  facet normal -0.587859 0.808963 0
+    outer loop
+      vertex -98.847 99.364 -3
+      vertex -98.6776 99.4871 0
+      vertex -98.6776 99.4871 -3
+    endloop
+  endfacet
+  facet normal -0.587859 0.808963 0
+    outer loop
+      vertex -98.847 99.364 -3
+      vertex -98.847 99.364 0
+      vertex -98.6776 99.4871 0
+    endloop
+  endfacet
+  facet normal -0.642811 0.766025 0
+    outer loop
+      vertex -99.0074 99.2294 -3
+      vertex -98.847 99.364 0
+      vertex -98.847 99.364 -3
+    endloop
+  endfacet
+  facet normal -0.642811 0.766025 0
+    outer loop
+      vertex -99.0074 99.2294 -3
+      vertex -99.0074 99.2294 0
+      vertex -98.847 99.364 0
+    endloop
+  endfacet
+  facet normal -0.694577 0.719418 0
+    outer loop
+      vertex -99.158 99.084 -3
+      vertex -99.0074 99.2294 0
+      vertex -99.0074 99.2294 -3
+    endloop
+  endfacet
+  facet normal -0.694577 0.719418 0
+    outer loop
+      vertex -99.158 99.084 -3
+      vertex -99.158 99.084 0
+      vertex -99.0074 99.2294 0
+    endloop
+  endfacet
+  facet normal -0.743152 0.669123 0
+    outer loop
+      vertex -99.2981 98.9284 -3
+      vertex -99.158 99.084 0
+      vertex -99.158 99.084 -3
+    endloop
+  endfacet
+  facet normal -0.743152 0.669123 0
+    outer loop
+      vertex -99.2981 98.9284 -3
+      vertex -99.2981 98.9284 0
+      vertex -99.158 99.084 0
+    endloop
+  endfacet
+  facet normal -0.788039 0.615626 0
+    outer loop
+      vertex -99.427 98.7634 -3
+      vertex -99.2981 98.9284 0
+      vertex -99.2981 98.9284 -3
+    endloop
+  endfacet
+  facet normal -0.788039 0.615626 0
+    outer loop
+      vertex -99.427 98.7634 -3
+      vertex -99.427 98.7634 0
+      vertex -99.2981 98.9284 0
+    endloop
+  endfacet
+  facet normal -0.829026 0.55921 0
+    outer loop
+      vertex -99.5441 98.5898 -3
+      vertex -99.427 98.7634 0
+      vertex -99.427 98.7634 -3
+    endloop
+  endfacet
+  facet normal -0.829026 0.55921 0
+    outer loop
+      vertex -99.5441 98.5898 -3
+      vertex -99.5441 98.5898 0
+      vertex -99.427 98.7634 0
+    endloop
+  endfacet
+  facet normal -0.86609 0.499888 0
+    outer loop
+      vertex -99.6488 98.4084 -3
+      vertex -99.5441 98.5898 0
+      vertex -99.5441 98.5898 -3
+    endloop
+  endfacet
+  facet normal -0.86609 0.499888 0
+    outer loop
+      vertex -99.6488 98.4084 -3
+      vertex -99.6488 98.4084 0
+      vertex -99.5441 98.5898 0
+    endloop
+  endfacet
+  facet normal -0.898778 0.438405 0
+    outer loop
+      vertex -99.7406 98.2202 -3
+      vertex -99.6488 98.4084 0
+      vertex -99.6488 98.4084 -3
+    endloop
+  endfacet
+  facet normal -0.898778 0.438405 0
+    outer loop
+      vertex -99.7406 98.2202 -3
+      vertex -99.7406 98.2202 0
+      vertex -99.6488 98.4084 0
+    endloop
+  endfacet
+  facet normal -0.927121 0.374763 0
+    outer loop
+      vertex -99.8191 98.026 -3
+      vertex -99.7406 98.2202 0
+      vertex -99.7406 98.2202 -3
+    endloop
+  endfacet
+  facet normal -0.927121 0.374763 0
+    outer loop
+      vertex -99.8191 98.026 -3
+      vertex -99.8191 98.026 0
+      vertex -99.7406 98.2202 0
+    endloop
+  endfacet
+  facet normal -0.951045 0.309054 0
+    outer loop
+      vertex -99.8838 97.8269 -3
+      vertex -99.8191 98.026 0
+      vertex -99.8191 98.026 -3
+    endloop
+  endfacet
+  facet normal -0.951045 0.309054 0
+    outer loop
+      vertex -99.8838 97.8269 -3
+      vertex -99.8838 97.8269 0
+      vertex -99.8191 98.026 0
+    endloop
+  endfacet
+  facet normal -0.970367 0.241637 0
+    outer loop
+      vertex -99.9344 97.6237 -3
+      vertex -99.8838 97.8269 0
+      vertex -99.8838 97.8269 -3
+    endloop
+  endfacet
+  facet normal -0.970367 0.241637 0
+    outer loop
+      vertex -99.9344 97.6237 -3
+      vertex -99.9344 97.6237 0
+      vertex -99.8838 97.8269 0
+    endloop
+  endfacet
+  facet normal -0.984774 0.17384 0
+    outer loop
+      vertex -99.9708 97.4175 -3
+      vertex -99.9344 97.6237 0
+      vertex -99.9344 97.6237 -3
+    endloop
+  endfacet
+  facet normal -0.984774 0.17384 0
+    outer loop
+      vertex -99.9708 97.4175 -3
+      vertex -99.9708 97.4175 0
+      vertex -99.9344 97.6237 0
+    endloop
+  endfacet
+  facet normal -0.994513 0.10461 0
+    outer loop
+      vertex -99.9927 97.2093 -3
+      vertex -99.9708 97.4175 0
+      vertex -99.9708 97.4175 -3
+    endloop
+  endfacet
+  facet normal -0.994513 0.10461 0
+    outer loop
+      vertex -99.9927 97.2093 -3
+      vertex -99.9927 97.2093 0
+      vertex -99.9708 97.4175 0
+    endloop
+  endfacet
+  facet normal -0.999392 0.034857 0
+    outer loop
+      vertex -100 97 -3
+      vertex -99.9927 97.2093 0
+      vertex -99.9927 97.2093 -3
+    endloop
+  endfacet
+  facet normal -0.999392 0.034857 0
+    outer loop
+      vertex -100 97 -3
+      vertex -100 97 0
+      vertex -99.9927 97.2093 0
+    endloop
+  endfacet
+  facet normal -1 0 0
+    outer loop
+      vertex -100 -97 -3
+      vertex -100 97 0
+      vertex -100 97 -3
+    endloop
+  endfacet
+  facet normal -1 0 0
+    outer loop
+      vertex -100 -97 -3
+      vertex -100 -97 0
+      vertex -100 97 0
+    endloop
+  endfacet
+  facet normal -0.999392 -0.034857 0
+    outer loop
+      vertex -99.9927 -97.2093 -3
+      vertex -100 -97 0
+      vertex -100 -97 -3
+    endloop
+  endfacet
+  facet normal -0.999392 -0.034857 0
+    outer loop
+      vertex -99.9927 -97.2093 -3
+      vertex -99.9927 -97.2093 0
+      vertex -100 -97 0
+    endloop
+  endfacet
+  facet normal -0.994513 -0.10461 0
+    outer loop
+      vertex -99.9708 -97.4175 -3
+      vertex -99.9927 -97.2093 0
+      vertex -99.9927 -97.2093 -3
+    endloop
+  endfacet
+  facet normal -0.994513 -0.10461 0
+    outer loop
+      vertex -99.9708 -97.4175 -3
+      vertex -99.9708 -97.4175 0
+      vertex -99.9927 -97.2093 0
+    endloop
+  endfacet
+  facet normal -0.984774 -0.17384 0
+    outer loop
+      vertex -99.9344 -97.6237 -3
+      vertex -99.9708 -97.4175 0
+      vertex -99.9708 -97.4175 -3
+    endloop
+  endfacet
+  facet normal -0.984774 -0.17384 0
+    outer loop
+      vertex -99.9344 -97.6237 -3
+      vertex -99.9344 -97.6237 0
+      vertex -99.9708 -97.4175 0
+    endloop
+  endfacet
+  facet normal -0.970367 -0.241637 0
+    outer loop
+      vertex -99.8838 -97.8269 -3
+      vertex -99.9344 -97.6237 0
+      vertex -99.9344 -97.6237 -3
+    endloop
+  endfacet
+  facet normal -0.970367 -0.241637 0
+    outer loop
+      vertex -99.8838 -97.8269 -3
+      vertex -99.8838 -97.8269 0
+      vertex -99.9344 -97.6237 0
+    endloop
+  endfacet
+  facet normal -0.951045 -0.309054 0
+    outer loop
+      vertex -99.8191 -98.026 -3
+      vertex -99.8838 -97.8269 0
+      vertex -99.8838 -97.8269 -3
+    endloop
+  endfacet
+  facet normal -0.951045 -0.309054 0
+    outer loop
+      vertex -99.8191 -98.026 -3
+      vertex -99.8191 -98.026 0
+      vertex -99.8838 -97.8269 0
+    endloop
+  endfacet
+  facet normal -0.927121 -0.374763 0
+    outer loop
+      vertex -99.7406 -98.2202 -3
+      vertex -99.8191 -98.026 0
+      vertex -99.8191 -98.026 -3
+    endloop
+  endfacet
+  facet normal -0.927121 -0.374763 0
+    outer loop
+      vertex -99.7406 -98.2202 -3
+      vertex -99.7406 -98.2202 0
+      vertex -99.8191 -98.026 0
+    endloop
+  endfacet
+  facet normal -0.898778 -0.438405 0
+    outer loop
+      vertex -99.6488 -98.4084 -3
+      vertex -99.7406 -98.2202 0
+      vertex -99.7406 -98.2202 -3
+    endloop
+  endfacet
+  facet normal -0.898778 -0.438405 0
+    outer loop
+      vertex -99.6488 -98.4084 -3
+      vertex -99.6488 -98.4084 0
+      vertex -99.7406 -98.2202 0
+    endloop
+  endfacet
+  facet normal -0.86609 -0.499888 0
+    outer loop
+      vertex -99.5441 -98.5898 -3
+      vertex -99.6488 -98.4084 0
+      vertex -99.6488 -98.4084 -3
+    endloop
+  endfacet
+  facet normal -0.86609 -0.499888 0
+    outer loop
+      vertex -99.5441 -98.5898 -3
+      vertex -99.5441 -98.5898 0
+      vertex -99.6488 -98.4084 0
+    endloop
+  endfacet
+  facet normal -0.829026 -0.55921 0
+    outer loop
+      vertex -99.427 -98.7634 -3
+      vertex -99.5441 -98.5898 0
+      vertex -99.5441 -98.5898 -3
+    endloop
+  endfacet
+  facet normal -0.829026 -0.55921 0
+    outer loop
+      vertex -99.427 -98.7634 -3
+      vertex -99.427 -98.7634 0
+      vertex -99.5441 -98.5898 0
+    endloop
+  endfacet
+  facet normal -0.788039 -0.615626 0
+    outer loop
+      vertex -99.2981 -98.9284 -3
+      vertex -99.427 -98.7634 0
+      vertex -99.427 -98.7634 -3
+    endloop
+  endfacet
+  facet normal -0.788039 -0.615626 0
+    outer loop
+      vertex -99.2981 -98.9284 -3
+      vertex -99.2981 -98.9284 0
+      vertex -99.427 -98.7634 0
+    endloop
+  endfacet
+  facet normal -0.743152 -0.669123 0
+    outer loop
+      vertex -99.158 -99.084 -3
+      vertex -99.2981 -98.9284 0
+      vertex -99.2981 -98.9284 -3
+    endloop
+  endfacet
+  facet normal -0.743152 -0.669123 0
+    outer loop
+      vertex -99.158 -99.084 -3
+      vertex -99.158 -99.084 0
+      vertex -99.2981 -98.9284 0
+    endloop
+  endfacet
+  facet normal -0.694577 -0.719418 0
+    outer loop
+      vertex -99.0074 -99.2294 -3
+      vertex -99.158 -99.084 0
+      vertex -99.158 -99.084 -3
+    endloop
+  endfacet
+  facet normal -0.694577 -0.719418 0
+    outer loop
+      vertex -99.0074 -99.2294 -3
+      vertex -99.0074 -99.2294 0
+      vertex -99.158 -99.084 0
+    endloop
+  endfacet
+  facet normal -0.642811 -0.766025 0
+    outer loop
+      vertex -98.847 -99.364 -3
+      vertex -99.0074 -99.2294 0
+      vertex -99.0074 -99.2294 -3
+    endloop
+  endfacet
+  facet normal -0.642811 -0.766025 0
+    outer loop
+      vertex -98.847 -99.364 -3
+      vertex -98.847 -99.364 0
+      vertex -99.0074 -99.2294 0
+    endloop
+  endfacet
+  facet normal -0.587859 -0.808963 0
+    outer loop
+      vertex -98.6776 -99.4871 -3
+      vertex -98.847 -99.364 0
+      vertex -98.847 -99.364 -3
+    endloop
+  endfacet
+  facet normal -0.587859 -0.808963 0
+    outer loop
+      vertex -98.6776 -99.4871 -3
+      vertex -98.6776 -99.4871 0
+      vertex -98.847 -99.364 0
+    endloop
+  endfacet
+  facet normal -0.529999 -0.847998 0
+    outer loop
+      vertex -98.5 -99.5981 -3
+      vertex -98.6776 -99.4871 0
+      vertex -98.6776 -99.4871 -3
+    endloop
+  endfacet
+  facet normal -0.529999 -0.847998 0
+    outer loop
+      vertex -98.5 -99.5981 -3
+      vertex -98.5 -99.5981 0
+      vertex -98.6776 -99.4871 0
+    endloop
+  endfacet
+  facet normal -0.469423 -0.882973 0
+    outer loop
+      vertex -98.3151 -99.6964 -3
+      vertex -98.5 -99.5981 0
+      vertex -98.5 -99.5981 -3
+    endloop
+  endfacet
+  facet normal -0.469423 -0.882973 0
+    outer loop
+      vertex -98.3151 -99.6964 -3
+      vertex -98.3151 -99.6964 0
+      vertex -98.5 -99.5981 0
+    endloop
+  endfacet
+  facet normal -0.406449 -0.913674 0
+    outer loop
+      vertex -98.1238 -99.7815 -3
+      vertex -98.3151 -99.6964 0
+      vertex -98.3151 -99.6964 -3
+    endloop
+  endfacet
+  facet normal -0.406449 -0.913674 0
+    outer loop
+      vertex -98.1238 -99.7815 -3
+      vertex -98.1238 -99.7815 0
+      vertex -98.3151 -99.6964 0
+    endloop
+  endfacet
+  facet normal -0.342318 -0.939584 0
+    outer loop
+      vertex -97.927 -99.8532 -3
+      vertex -98.1238 -99.7815 0
+      vertex -98.1238 -99.7815 -3
+    endloop
+  endfacet
+  facet normal -0.342318 -0.939584 0
+    outer loop
+      vertex -97.927 -99.8532 -3
+      vertex -97.927 -99.8532 0
+      vertex -98.1238 -99.7815 0
+    endloop
+  endfacet
+  facet normal -0.275668 -0.961253 0
+    outer loop
+      vertex -97.7258 -99.9109 -3
+      vertex -97.927 -99.8532 0
+      vertex -97.927 -99.8532 -3
+    endloop
+  endfacet
+  facet normal -0.275668 -0.961253 0
+    outer loop
+      vertex -97.7258 -99.9109 -3
+      vertex -97.7258 -99.9109 0
+      vertex -97.927 -99.8532 0
+    endloop
+  endfacet
+  facet normal -0.20767 -0.978199 0
+    outer loop
+      vertex -97.5209 -99.9544 -3
+      vertex -97.7258 -99.9109 0
+      vertex -97.7258 -99.9109 -3
+    endloop
+  endfacet
+  facet normal -0.20767 -0.978199 0
+    outer loop
+      vertex -97.5209 -99.9544 -3
+      vertex -97.5209 -99.9544 0
+      vertex -97.7258 -99.9109 0
+    endloop
+  endfacet
+  facet normal -0.139482 -0.990225 0
+    outer loop
+      vertex -97.3136 -99.9836 -3
+      vertex -97.5209 -99.9544 0
+      vertex -97.5209 -99.9544 -3
+    endloop
+  endfacet
+  facet normal -0.139482 -0.990225 0
+    outer loop
+      vertex -97.3136 -99.9836 -3
+      vertex -97.3136 -99.9836 0
+      vertex -97.5209 -99.9544 0
+    endloop
+  endfacet
+  facet normal -0.0697198 -0.997567 0
+    outer loop
+      vertex -97.1047 -99.9982 -3
+      vertex -97.3136 -99.9836 0
+      vertex -97.3136 -99.9836 -3
+    endloop
+  endfacet
+  facet normal -0.0697198 -0.997567 0
+    outer loop
+      vertex -97.1047 -99.9982 -3
+      vertex -97.1047 -99.9982 0
+      vertex -97.3136 -99.9836 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -97.1047 -99.9982 0
+      vertex -97.1047 -99.9982 -3
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex -97.0018 -99.9982 -3
+      vertex -97.0018 -99.9982 0
+      vertex -97.1047 -99.9982 0
+    endloop
+  endfacet
+  facet normal -0.707107 -0.707107 0
+    outer loop
+      vertex -97 -100 -3
+      vertex -97.0018 -99.9982 0
+      vertex -97.0018 -99.9982 -3
+    endloop
+  endfacet
+  facet normal -0.707107 -0.707107 0
+    outer loop
+      vertex -97 -100 -3
+      vertex -97 -100 0
+      vertex -97.0018 -99.9982 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 97 -100 -3
+      vertex -97 -100 0
+      vertex -97 -100 -3
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 97 -100 -3
+      vertex 97 -100 0
+      vertex -97 -100 0
+    endloop
+  endfacet
+  facet normal 0.707107 -0.707107 0
+    outer loop
+      vertex 97.0018 -99.9982 -3
+      vertex 97 -100 0
+      vertex 97 -100 -3
+    endloop
+  endfacet
+  facet normal 0.707107 -0.707107 0
+    outer loop
+      vertex 97.0018 -99.9982 -3
+      vertex 97.0018 -99.9982 0
+      vertex 97 -100 0
+    endloop
+  endfacet
+endsolid OpenSCAD_Model

From e5b7b20be1dc0fe827e451633d4d9a506ed775e3 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sun, 28 Feb 2021 16:57:35 +0100
Subject: [PATCH 33/53] creality.ini: CR-5 Pro more accurate bed

---
 resources/profiles/Creality.ini            |    6 +-
 resources/profiles/Creality/cr5pro.svg     |    4 +
 resources/profiles/Creality/cr5pro_bed.stl | 2774 ++++++++++++++++++++
 3 files changed, 2781 insertions(+), 3 deletions(-)
 create mode 100644 resources/profiles/Creality/cr5pro.svg
 create mode 100644 resources/profiles/Creality/cr5pro_bed.stl

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 2e9971f21..de6f103a0 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -100,8 +100,8 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
 #variants = 0.4
 #technology = FFF
 #family = CR
-#bed_model = cr10mini_bed.stl
-#bed_texture = cr10mini.svg
+#bed_model = cr5pro_bed.stl
+#bed_texture = cr5pro.svg
 #default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
 #[printer_model:CR6SE]
@@ -905,7 +905,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 #[printer:Creality CR-5 Pro]
 #inherits = *common*; *slowabl*; *descendingz*
 #retract_length = 3
-#bed_shape = 2.5x5,302.5x5,302.5x225,2.5x225
+#bed_shape = 5x5,295x5,295x215,5x215
 #max_print_height = 380
 #printer_model = CR5PRO
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PRO\nPRINTER_HAS_BOWDEN
diff --git a/resources/profiles/Creality/cr5pro.svg b/resources/profiles/Creality/cr5pro.svg
new file mode 100644
index 000000000..7f44fd602
--- /dev/null
+++ b/resources/profiles/Creality/cr5pro.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="290mm" height="215mm" version="1.1" viewBox="0 0 290 215" xmlns="http://www.w3.org/2000/svg">
+  <rect x=".25" y=".25" width="289.5" height="214.5" fill="none" stroke="#fff" stroke-width=".5"/>
+</svg>
diff --git a/resources/profiles/Creality/cr5pro_bed.stl b/resources/profiles/Creality/cr5pro_bed.stl
new file mode 100644
index 000000000..b3e13687b
--- /dev/null
+++ b/resources/profiles/Creality/cr5pro_bed.stl
@@ -0,0 +1,2774 @@
+solid OpenSCAD_Model
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.105 -112.498 -3
+      vertex 147.002 -112.498 -3
+      vertex 147.314 -112.484 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 147.314 -112.484 -3
+      vertex 147.002 -112.498 -3
+      vertex 147.521 -112.454 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 150 -109.5 -3
+      vertex 147.002 -112.498 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 147.521 -112.454 -3
+      vertex 147.002 -112.498 -3
+      vertex 147.726 -112.411 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 147.726 -112.411 -3
+      vertex 147.002 -112.498 -3
+      vertex 147.927 -112.353 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 147.927 -112.353 -3
+      vertex 147.002 -112.498 -3
+      vertex 148.124 -112.282 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 148.124 -112.282 -3
+      vertex 147.002 -112.498 -3
+      vertex 148.315 -112.196 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 148.315 -112.196 -3
+      vertex 147.002 -112.498 -3
+      vertex 148.5 -112.098 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 148.5 -112.098 -3
+      vertex 147.002 -112.498 -3
+      vertex 148.678 -111.987 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 148.678 -111.987 -3
+      vertex 147.002 -112.498 -3
+      vertex 148.847 -111.864 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 148.847 -111.864 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.007 -111.729 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.007 -111.729 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.158 -111.584 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.158 -111.584 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.298 -111.428 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.298 -111.428 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.427 -111.263 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.427 -111.263 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.544 -111.09 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.544 -111.09 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.649 -110.908 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.649 -110.908 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.741 -110.72 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.741 -110.72 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.819 -110.526 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.819 -110.526 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.884 -110.327 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.884 -110.327 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.934 -110.124 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.934 -110.124 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.971 -109.918 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.971 -109.918 -3
+      vertex 147.002 -112.498 -3
+      vertex 149.993 -109.709 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 149.993 -109.709 -3
+      vertex 147.002 -112.498 -3
+      vertex 150 -109.5 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 150 -109.5 -3
+      vertex 147.002 112.498 -3
+      vertex 150 109.5 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.002 112.498 -3
+      vertex 149.971 109.918 -3
+      vertex 149.993 109.709 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 149.884 110.327 -3
+      vertex 149.934 110.124 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 149.741 110.72 -3
+      vertex 147.002 112.498 -3
+      vertex 149.649 110.908 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 149.741 110.72 -3
+      vertex 149.819 110.526 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.002 112.498 -3
+      vertex 149.007 111.729 -3
+      vertex 149.158 111.584 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 149.427 111.263 -3
+      vertex 147.002 112.498 -3
+      vertex 149.298 111.428 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 149.427 111.263 -3
+      vertex 149.544 111.09 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 149.298 111.428 -3
+      vertex 147.002 112.498 -3
+      vertex 149.158 111.584 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.002 112.498 -3
+      vertex 147.927 112.353 -3
+      vertex 148.124 112.282 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 148.847 111.864 -3
+      vertex 147.002 112.498 -3
+      vertex 148.678 111.987 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 148.847 111.864 -3
+      vertex 149.007 111.729 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 148.678 111.987 -3
+      vertex 147.002 112.498 -3
+      vertex 148.5 112.098 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 148.5 112.098 -3
+      vertex 147.002 112.498 -3
+      vertex 148.315 112.196 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 148.315 112.196 -3
+      vertex 147.002 112.498 -3
+      vertex 148.124 112.282 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 149.649 110.908 -3
+      vertex 147.002 112.498 -3
+      vertex 149.544 111.09 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.726 112.411 -3
+      vertex 147.002 112.498 -3
+      vertex 147.521 112.454 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 147.726 112.411 -3
+      vertex 147.927 112.353 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 149.819 110.526 -3
+      vertex 149.884 110.327 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 147.314 112.484 -3
+      vertex 147.521 112.454 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.002 112.498 -3
+      vertex 149.934 110.124 -3
+      vertex 149.971 109.918 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.002 112.498 -3
+      vertex 147.105 112.498 -3
+      vertex 147.314 112.484 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 150 109.5 -3
+      vertex 147.002 112.498 -3
+      vertex 149.993 109.709 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex 147.002 -112.498 -3
+      vertex 147 112.5 -3
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex 147.002 -112.498 -3
+      vertex 147 -112.5 -3
+      vertex 147 112.5 -3
+    endloop
+  endfacet
+  facet normal -0 -0 -1
+    outer loop
+      vertex 147 112.5 -3
+      vertex 147 -112.5 -3
+      vertex -147 112.5 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -150 109.5 -3
+      vertex -147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal -0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -147.314 112.484 -3
+      vertex -147.105 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -147.521 112.454 -3
+      vertex -147.314 112.484 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -147.726 112.411 -3
+      vertex -147.521 112.454 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -147.927 112.353 -3
+      vertex -147.726 112.411 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -148.124 112.282 -3
+      vertex -147.927 112.353 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -148.315 112.196 -3
+      vertex -148.124 112.282 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -148.5 112.098 -3
+      vertex -148.315 112.196 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -148.678 111.987 -3
+      vertex -148.5 112.098 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -148.847 111.864 -3
+      vertex -148.678 111.987 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.007 111.729 -3
+      vertex -148.847 111.864 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.158 111.584 -3
+      vertex -149.007 111.729 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.298 111.428 -3
+      vertex -149.158 111.584 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.427 111.263 -3
+      vertex -149.298 111.428 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.544 111.09 -3
+      vertex -149.427 111.263 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.649 110.908 -3
+      vertex -149.544 111.09 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.741 110.72 -3
+      vertex -149.649 110.908 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.819 110.526 -3
+      vertex -149.741 110.72 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.884 110.327 -3
+      vertex -149.819 110.526 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.934 110.124 -3
+      vertex -149.884 110.327 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.971 109.918 -3
+      vertex -149.934 110.124 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -149.993 109.709 -3
+      vertex -149.971 109.918 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -150 109.5 -3
+      vertex -149.993 109.709 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -150 -109.5 -3
+      vertex -150 109.5 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.521 -112.454 -3
+      vertex -147.002 -112.498 -3
+      vertex -147.314 -112.484 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -149.971 -109.918 -3
+      vertex -149.993 -109.709 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.884 -110.327 -3
+      vertex -149.934 -110.124 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.741 -110.72 -3
+      vertex -147.002 -112.498 -3
+      vertex -149.649 -110.908 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.741 -110.72 -3
+      vertex -149.819 -110.526 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -149.007 -111.729 -3
+      vertex -149.158 -111.584 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.427 -111.263 -3
+      vertex -147.002 -112.498 -3
+      vertex -149.298 -111.428 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.427 -111.263 -3
+      vertex -149.544 -111.09 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.298 -111.428 -3
+      vertex -147.002 -112.498 -3
+      vertex -149.158 -111.584 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -147.927 -112.353 -3
+      vertex -148.124 -112.282 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -148.847 -111.864 -3
+      vertex -147.002 -112.498 -3
+      vertex -148.678 -111.987 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -148.847 -111.864 -3
+      vertex -149.007 -111.729 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -148.678 -111.987 -3
+      vertex -147.002 -112.498 -3
+      vertex -148.5 -112.098 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -148.5 -112.098 -3
+      vertex -147.002 -112.498 -3
+      vertex -148.315 -112.196 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -148.315 -112.196 -3
+      vertex -147.002 -112.498 -3
+      vertex -148.124 -112.282 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.649 -110.908 -3
+      vertex -147.002 -112.498 -3
+      vertex -149.544 -111.09 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.726 -112.411 -3
+      vertex -147.002 -112.498 -3
+      vertex -147.521 -112.454 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.726 -112.411 -3
+      vertex -147.927 -112.353 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.819 -110.526 -3
+      vertex -149.884 -110.327 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -149.934 -110.124 -3
+      vertex -149.971 -109.918 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.105 -112.498 -3
+      vertex -147.314 -112.484 -3
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -149.993 -109.709 -3
+      vertex -150 -109.5 -3
+    endloop
+  endfacet
+  facet normal 0 -0 -1
+    outer loop
+      vertex -147 112.5 -3
+      vertex -147 -112.5 -3
+      vertex -147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147 112.5 -3
+      vertex 147 -112.5 -3
+      vertex -147 -112.5 -3
+    endloop
+  endfacet
+  facet normal 0 0 -1
+    outer loop
+      vertex -147 -112.5 -3
+      vertex -147.002 -112.498 -3
+      vertex -147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.314 -112.484 0
+      vertex 147.002 -112.498 0
+      vertex 147.105 -112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.521 -112.454 0
+      vertex 147.002 -112.498 0
+      vertex 147.314 -112.484 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 147.002 -112.498 0
+      vertex 150 -109.5 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.726 -112.411 0
+      vertex 147.002 -112.498 0
+      vertex 147.521 -112.454 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.927 -112.353 0
+      vertex 147.002 -112.498 0
+      vertex 147.726 -112.411 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.124 -112.282 0
+      vertex 147.002 -112.498 0
+      vertex 147.927 -112.353 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.315 -112.196 0
+      vertex 147.002 -112.498 0
+      vertex 148.124 -112.282 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.5 -112.098 0
+      vertex 147.002 -112.498 0
+      vertex 148.315 -112.196 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.678 -111.987 0
+      vertex 147.002 -112.498 0
+      vertex 148.5 -112.098 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.847 -111.864 0
+      vertex 147.002 -112.498 0
+      vertex 148.678 -111.987 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.007 -111.729 0
+      vertex 147.002 -112.498 0
+      vertex 148.847 -111.864 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.158 -111.584 0
+      vertex 147.002 -112.498 0
+      vertex 149.007 -111.729 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.298 -111.428 0
+      vertex 147.002 -112.498 0
+      vertex 149.158 -111.584 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.427 -111.263 0
+      vertex 147.002 -112.498 0
+      vertex 149.298 -111.428 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.544 -111.09 0
+      vertex 147.002 -112.498 0
+      vertex 149.427 -111.263 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.649 -110.908 0
+      vertex 147.002 -112.498 0
+      vertex 149.544 -111.09 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.741 -110.72 0
+      vertex 147.002 -112.498 0
+      vertex 149.649 -110.908 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.819 -110.526 0
+      vertex 147.002 -112.498 0
+      vertex 149.741 -110.72 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.884 -110.327 0
+      vertex 147.002 -112.498 0
+      vertex 149.819 -110.526 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.934 -110.124 0
+      vertex 147.002 -112.498 0
+      vertex 149.884 -110.327 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.971 -109.918 0
+      vertex 147.002 -112.498 0
+      vertex 149.934 -110.124 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.993 -109.709 0
+      vertex 147.002 -112.498 0
+      vertex 149.971 -109.918 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 150 -109.5 0
+      vertex 147.002 -112.498 0
+      vertex 149.993 -109.709 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 150 109.5 0
+      vertex 147.002 112.498 0
+      vertex 150 -109.5 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.993 109.709 0
+      vertex 149.971 109.918 0
+      vertex 147.002 112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 149.934 110.124 0
+      vertex 149.884 110.327 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.649 110.908 0
+      vertex 147.002 112.498 0
+      vertex 149.741 110.72 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 149.819 110.526 0
+      vertex 149.741 110.72 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.158 111.584 0
+      vertex 149.007 111.729 0
+      vertex 147.002 112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.298 111.428 0
+      vertex 147.002 112.498 0
+      vertex 149.427 111.263 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 149.544 111.09 0
+      vertex 149.427 111.263 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.158 111.584 0
+      vertex 147.002 112.498 0
+      vertex 149.298 111.428 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.124 112.282 0
+      vertex 147.927 112.353 0
+      vertex 147.002 112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.678 111.987 0
+      vertex 147.002 112.498 0
+      vertex 148.847 111.864 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 149.007 111.729 0
+      vertex 148.847 111.864 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.5 112.098 0
+      vertex 147.002 112.498 0
+      vertex 148.678 111.987 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.315 112.196 0
+      vertex 147.002 112.498 0
+      vertex 148.5 112.098 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 148.124 112.282 0
+      vertex 147.002 112.498 0
+      vertex 148.315 112.196 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.544 111.09 0
+      vertex 147.002 112.498 0
+      vertex 149.649 110.908 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.521 112.454 0
+      vertex 147.002 112.498 0
+      vertex 147.726 112.411 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 147.927 112.353 0
+      vertex 147.726 112.411 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 149.884 110.327 0
+      vertex 149.819 110.526 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 147.521 112.454 0
+      vertex 147.314 112.484 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.971 109.918 0
+      vertex 149.934 110.124 0
+      vertex 147.002 112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.314 112.484 0
+      vertex 147.105 112.498 0
+      vertex 147.002 112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 149.993 109.709 0
+      vertex 147.002 112.498 0
+      vertex 150 109.5 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147.002 112.498 0
+      vertex 147 112.5 0
+      vertex 147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex 147 112.5 0
+      vertex 147 -112.5 0
+      vertex 147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -147 112.5 0
+      vertex 147 -112.5 0
+      vertex 147 112.5 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 112.498 0
+      vertex -150 109.5 0
+      vertex -147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -147.105 112.498 0
+      vertex -147.314 112.484 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -147.314 112.484 0
+      vertex -147.521 112.454 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -147.521 112.454 0
+      vertex -147.726 112.411 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -147.726 112.411 0
+      vertex -147.927 112.353 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -147.927 112.353 0
+      vertex -148.124 112.282 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -148.124 112.282 0
+      vertex -148.315 112.196 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -148.315 112.196 0
+      vertex -148.5 112.098 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -148.5 112.098 0
+      vertex -148.678 111.987 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -148.678 111.987 0
+      vertex -148.847 111.864 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -148.847 111.864 0
+      vertex -149.007 111.729 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.007 111.729 0
+      vertex -149.158 111.584 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.158 111.584 0
+      vertex -149.298 111.428 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.298 111.428 0
+      vertex -149.427 111.263 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.427 111.263 0
+      vertex -149.544 111.09 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.544 111.09 0
+      vertex -149.649 110.908 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.649 110.908 0
+      vertex -149.741 110.72 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.741 110.72 0
+      vertex -149.819 110.526 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.819 110.526 0
+      vertex -149.884 110.327 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.884 110.327 0
+      vertex -149.934 110.124 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.934 110.124 0
+      vertex -149.971 109.918 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.971 109.918 0
+      vertex -149.993 109.709 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -149.993 109.709 0
+      vertex -150 109.5 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -150 109.5 0
+      vertex -150 -109.5 0
+      vertex -147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -147.314 -112.484 0
+      vertex -147.002 -112.498 0
+      vertex -147.521 -112.454 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -149.993 -109.709 0
+      vertex -149.971 -109.918 0
+      vertex -147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -149.934 -110.124 0
+      vertex -149.884 -110.327 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -149.649 -110.908 0
+      vertex -147.002 -112.498 0
+      vertex -149.741 -110.72 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -149.819 -110.526 0
+      vertex -149.741 -110.72 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -149.158 -111.584 0
+      vertex -149.007 -111.729 0
+      vertex -147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -149.298 -111.428 0
+      vertex -147.002 -112.498 0
+      vertex -149.427 -111.263 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -149.544 -111.09 0
+      vertex -149.427 -111.263 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -149.158 -111.584 0
+      vertex -147.002 -112.498 0
+      vertex -149.298 -111.428 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -148.124 -112.282 0
+      vertex -147.927 -112.353 0
+      vertex -147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -148.678 -111.987 0
+      vertex -147.002 -112.498 0
+      vertex -148.847 -111.864 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -149.007 -111.729 0
+      vertex -148.847 -111.864 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -148.5 -112.098 0
+      vertex -147.002 -112.498 0
+      vertex -148.678 -111.987 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -148.315 -112.196 0
+      vertex -147.002 -112.498 0
+      vertex -148.5 -112.098 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -148.124 -112.282 0
+      vertex -147.002 -112.498 0
+      vertex -148.315 -112.196 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -149.544 -111.09 0
+      vertex -147.002 -112.498 0
+      vertex -149.649 -110.908 0
+    endloop
+  endfacet
+  facet normal -0 -0 1
+    outer loop
+      vertex -147.521 -112.454 0
+      vertex -147.002 -112.498 0
+      vertex -147.726 -112.411 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -147.927 -112.353 0
+      vertex -147.726 -112.411 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -149.884 -110.327 0
+      vertex -149.819 -110.526 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -149.971 -109.918 0
+      vertex -149.934 -110.124 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 -112.498 0
+      vertex -147.314 -112.484 0
+      vertex -147.105 -112.498 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -150 -109.5 0
+      vertex -149.993 -109.709 0
+      vertex -147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal -0 0 1
+    outer loop
+      vertex -147.002 112.498 0
+      vertex -147 -112.5 0
+      vertex -147 112.5 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147 -112.5 0
+      vertex 147 -112.5 0
+      vertex -147 112.5 0
+    endloop
+  endfacet
+  facet normal 0 0 1
+    outer loop
+      vertex -147.002 112.498 0
+      vertex -147.002 -112.498 0
+      vertex -147 -112.5 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 147.105 -112.498 -3
+      vertex 147.002 -112.498 0
+      vertex 147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 147.105 -112.498 -3
+      vertex 147.105 -112.498 0
+      vertex 147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal 0.0668359 -0.997764 0
+    outer loop
+      vertex 147.314 -112.484 -3
+      vertex 147.105 -112.498 0
+      vertex 147.105 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0.0668359 -0.997764 0
+    outer loop
+      vertex 147.314 -112.484 -3
+      vertex 147.314 -112.484 0
+      vertex 147.105 -112.498 0
+    endloop
+  endfacet
+  facet normal 0.143429 -0.989661 0
+    outer loop
+      vertex 147.521 -112.454 -3
+      vertex 147.314 -112.484 0
+      vertex 147.314 -112.484 -3
+    endloop
+  endfacet
+  facet normal 0.143429 -0.989661 0
+    outer loop
+      vertex 147.521 -112.454 -3
+      vertex 147.521 -112.454 0
+      vertex 147.314 -112.484 0
+    endloop
+  endfacet
+  facet normal 0.205289 -0.978701 0
+    outer loop
+      vertex 147.726 -112.411 -3
+      vertex 147.521 -112.454 0
+      vertex 147.521 -112.454 -3
+    endloop
+  endfacet
+  facet normal 0.205289 -0.978701 0
+    outer loop
+      vertex 147.726 -112.411 -3
+      vertex 147.726 -112.411 0
+      vertex 147.521 -112.454 0
+    endloop
+  endfacet
+  facet normal 0.277246 -0.960799 0
+    outer loop
+      vertex 147.927 -112.353 -3
+      vertex 147.726 -112.411 0
+      vertex 147.726 -112.411 -3
+    endloop
+  endfacet
+  facet normal 0.277246 -0.960799 0
+    outer loop
+      vertex 147.927 -112.353 -3
+      vertex 147.927 -112.353 0
+      vertex 147.726 -112.411 0
+    endloop
+  endfacet
+  facet normal 0.339058 -0.940766 0
+    outer loop
+      vertex 148.124 -112.282 -3
+      vertex 147.927 -112.353 0
+      vertex 147.927 -112.353 -3
+    endloop
+  endfacet
+  facet normal 0.339058 -0.940766 0
+    outer loop
+      vertex 148.124 -112.282 -3
+      vertex 148.124 -112.282 0
+      vertex 147.927 -112.353 0
+    endloop
+  endfacet
+  facet normal 0.410563 -0.911832 0
+    outer loop
+      vertex 148.315 -112.196 -3
+      vertex 148.124 -112.282 0
+      vertex 148.124 -112.282 -3
+    endloop
+  endfacet
+  facet normal 0.410563 -0.911832 0
+    outer loop
+      vertex 148.315 -112.196 -3
+      vertex 148.315 -112.196 0
+      vertex 148.124 -112.282 0
+    endloop
+  endfacet
+  facet normal 0.468107 -0.883672 0
+    outer loop
+      vertex 148.5 -112.098 -3
+      vertex 148.315 -112.196 0
+      vertex 148.315 -112.196 -3
+    endloop
+  endfacet
+  facet normal 0.468107 -0.883672 0
+    outer loop
+      vertex 148.5 -112.098 -3
+      vertex 148.5 -112.098 0
+      vertex 148.315 -112.196 0
+    endloop
+  endfacet
+  facet normal 0.529142 -0.848533 0
+    outer loop
+      vertex 148.678 -111.987 -3
+      vertex 148.5 -112.098 0
+      vertex 148.5 -112.098 -3
+    endloop
+  endfacet
+  facet normal 0.529142 -0.848533 0
+    outer loop
+      vertex 148.678 -111.987 -3
+      vertex 148.678 -111.987 0
+      vertex 148.5 -112.098 0
+    endloop
+  endfacet
+  facet normal 0.588456 -0.808529 0
+    outer loop
+      vertex 148.847 -111.864 -3
+      vertex 148.678 -111.987 0
+      vertex 148.678 -111.987 -3
+    endloop
+  endfacet
+  facet normal 0.588456 -0.808529 0
+    outer loop
+      vertex 148.847 -111.864 -3
+      vertex 148.847 -111.864 0
+      vertex 148.678 -111.987 0
+    endloop
+  endfacet
+  facet normal 0.644871 -0.764291 0
+    outer loop
+      vertex 149.007 -111.729 -3
+      vertex 148.847 -111.864 0
+      vertex 148.847 -111.864 -3
+    endloop
+  endfacet
+  facet normal 0.644871 -0.764291 0
+    outer loop
+      vertex 149.007 -111.729 -3
+      vertex 149.007 -111.729 0
+      vertex 148.847 -111.864 0
+    endloop
+  endfacet
+  facet normal 0.692631 -0.721292 0
+    outer loop
+      vertex 149.158 -111.584 -3
+      vertex 149.007 -111.729 0
+      vertex 149.007 -111.729 -3
+    endloop
+  endfacet
+  facet normal 0.692631 -0.721292 0
+    outer loop
+      vertex 149.158 -111.584 -3
+      vertex 149.158 -111.584 0
+      vertex 149.007 -111.729 0
+    endloop
+  endfacet
+  facet normal 0.744242 -0.66791 0
+    outer loop
+      vertex 149.298 -111.428 -3
+      vertex 149.158 -111.584 0
+      vertex 149.158 -111.584 -3
+    endloop
+  endfacet
+  facet normal 0.744242 -0.66791 0
+    outer loop
+      vertex 149.298 -111.428 -3
+      vertex 149.298 -111.428 0
+      vertex 149.158 -111.584 0
+    endloop
+  endfacet
+  facet normal 0.787807 -0.615922 0
+    outer loop
+      vertex 149.427 -111.263 -3
+      vertex 149.298 -111.428 0
+      vertex 149.298 -111.428 -3
+    endloop
+  endfacet
+  facet normal 0.787807 -0.615922 0
+    outer loop
+      vertex 149.427 -111.263 -3
+      vertex 149.427 -111.263 0
+      vertex 149.298 -111.428 0
+    endloop
+  endfacet
+  facet normal 0.828349 -0.560213 0
+    outer loop
+      vertex 149.544 -111.09 -3
+      vertex 149.427 -111.263 0
+      vertex 149.427 -111.263 -3
+    endloop
+  endfacet
+  facet normal 0.828349 -0.560213 0
+    outer loop
+      vertex 149.544 -111.09 -3
+      vertex 149.544 -111.09 0
+      vertex 149.427 -111.263 0
+    endloop
+  endfacet
+  facet normal 0.866186 -0.499722 0
+    outer loop
+      vertex 149.649 -110.908 -3
+      vertex 149.544 -111.09 0
+      vertex 149.544 -111.09 -3
+    endloop
+  endfacet
+  facet normal 0.866186 -0.499722 0
+    outer loop
+      vertex 149.649 -110.908 -3
+      vertex 149.649 -110.908 0
+      vertex 149.544 -111.09 0
+    endloop
+  endfacet
+  facet normal 0.898217 -0.439553 0
+    outer loop
+      vertex 149.741 -110.72 -3
+      vertex 149.649 -110.908 0
+      vertex 149.649 -110.908 -3
+    endloop
+  endfacet
+  facet normal 0.898217 -0.439553 0
+    outer loop
+      vertex 149.741 -110.72 -3
+      vertex 149.741 -110.72 0
+      vertex 149.649 -110.908 0
+    endloop
+  endfacet
+  facet normal 0.927816 -0.373039 0
+    outer loop
+      vertex 149.819 -110.526 -3
+      vertex 149.741 -110.72 0
+      vertex 149.741 -110.72 -3
+    endloop
+  endfacet
+  facet normal 0.927816 -0.373039 0
+    outer loop
+      vertex 149.819 -110.526 -3
+      vertex 149.819 -110.526 0
+      vertex 149.741 -110.72 0
+    endloop
+  endfacet
+  facet normal 0.950577 -0.31049 0
+    outer loop
+      vertex 149.884 -110.327 -3
+      vertex 149.819 -110.526 0
+      vertex 149.819 -110.526 -3
+    endloop
+  endfacet
+  facet normal 0.950577 -0.31049 0
+    outer loop
+      vertex 149.884 -110.327 -3
+      vertex 149.884 -110.327 0
+      vertex 149.819 -110.526 0
+    endloop
+  endfacet
+  facet normal 0.970981 -0.239158 0
+    outer loop
+      vertex 149.934 -110.124 -3
+      vertex 149.884 -110.327 0
+      vertex 149.884 -110.327 -3
+    endloop
+  endfacet
+  facet normal 0.970981 -0.239158 0
+    outer loop
+      vertex 149.934 -110.124 -3
+      vertex 149.934 -110.124 0
+      vertex 149.884 -110.327 0
+    endloop
+  endfacet
+  facet normal 0.98425 -0.176783 0
+    outer loop
+      vertex 149.971 -109.918 -3
+      vertex 149.934 -110.124 0
+      vertex 149.934 -110.124 -3
+    endloop
+  endfacet
+  facet normal 0.98425 -0.176783 0
+    outer loop
+      vertex 149.971 -109.918 -3
+      vertex 149.971 -109.918 0
+      vertex 149.934 -110.124 0
+    endloop
+  endfacet
+  facet normal 0.994505 -0.104685 0
+    outer loop
+      vertex 149.993 -109.709 -3
+      vertex 149.971 -109.918 0
+      vertex 149.971 -109.918 -3
+    endloop
+  endfacet
+  facet normal 0.994505 -0.104685 0
+    outer loop
+      vertex 149.993 -109.709 -3
+      vertex 149.993 -109.709 0
+      vertex 149.971 -109.918 0
+    endloop
+  endfacet
+  facet normal 0.99944 -0.0334741 0
+    outer loop
+      vertex 150 -109.5 -3
+      vertex 149.993 -109.709 0
+      vertex 149.993 -109.709 -3
+    endloop
+  endfacet
+  facet normal 0.99944 -0.0334741 0
+    outer loop
+      vertex 150 -109.5 -3
+      vertex 150 -109.5 0
+      vertex 149.993 -109.709 0
+    endloop
+  endfacet
+  facet normal 1 0 0
+    outer loop
+      vertex 150 109.5 -3
+      vertex 150 -109.5 0
+      vertex 150 -109.5 -3
+    endloop
+  endfacet
+  facet normal 1 0 -0
+    outer loop
+      vertex 150 109.5 -3
+      vertex 150 109.5 0
+      vertex 150 -109.5 0
+    endloop
+  endfacet
+  facet normal 0.99944 0.0334741 0
+    outer loop
+      vertex 149.993 109.709 -3
+      vertex 150 109.5 0
+      vertex 150 109.5 -3
+    endloop
+  endfacet
+  facet normal 0.99944 0.0334741 -0
+    outer loop
+      vertex 149.993 109.709 -3
+      vertex 149.993 109.709 0
+      vertex 150 109.5 0
+    endloop
+  endfacet
+  facet normal 0.994505 0.104685 0
+    outer loop
+      vertex 149.971 109.918 -3
+      vertex 149.993 109.709 0
+      vertex 149.993 109.709 -3
+    endloop
+  endfacet
+  facet normal 0.994505 0.104685 -0
+    outer loop
+      vertex 149.971 109.918 -3
+      vertex 149.971 109.918 0
+      vertex 149.993 109.709 0
+    endloop
+  endfacet
+  facet normal 0.98425 0.176783 0
+    outer loop
+      vertex 149.934 110.124 -3
+      vertex 149.971 109.918 0
+      vertex 149.971 109.918 -3
+    endloop
+  endfacet
+  facet normal 0.98425 0.176783 -0
+    outer loop
+      vertex 149.934 110.124 -3
+      vertex 149.934 110.124 0
+      vertex 149.971 109.918 0
+    endloop
+  endfacet
+  facet normal 0.970981 0.239158 0
+    outer loop
+      vertex 149.884 110.327 -3
+      vertex 149.934 110.124 0
+      vertex 149.934 110.124 -3
+    endloop
+  endfacet
+  facet normal 0.970981 0.239158 -0
+    outer loop
+      vertex 149.884 110.327 -3
+      vertex 149.884 110.327 0
+      vertex 149.934 110.124 0
+    endloop
+  endfacet
+  facet normal 0.950577 0.31049 0
+    outer loop
+      vertex 149.819 110.526 -3
+      vertex 149.884 110.327 0
+      vertex 149.884 110.327 -3
+    endloop
+  endfacet
+  facet normal 0.950577 0.31049 -0
+    outer loop
+      vertex 149.819 110.526 -3
+      vertex 149.819 110.526 0
+      vertex 149.884 110.327 0
+    endloop
+  endfacet
+  facet normal 0.927816 0.373039 0
+    outer loop
+      vertex 149.741 110.72 -3
+      vertex 149.819 110.526 0
+      vertex 149.819 110.526 -3
+    endloop
+  endfacet
+  facet normal 0.927816 0.373039 -0
+    outer loop
+      vertex 149.741 110.72 -3
+      vertex 149.741 110.72 0
+      vertex 149.819 110.526 0
+    endloop
+  endfacet
+  facet normal 0.898217 0.439553 0
+    outer loop
+      vertex 149.649 110.908 -3
+      vertex 149.741 110.72 0
+      vertex 149.741 110.72 -3
+    endloop
+  endfacet
+  facet normal 0.898217 0.439553 -0
+    outer loop
+      vertex 149.649 110.908 -3
+      vertex 149.649 110.908 0
+      vertex 149.741 110.72 0
+    endloop
+  endfacet
+  facet normal 0.866186 0.499722 0
+    outer loop
+      vertex 149.544 111.09 -3
+      vertex 149.649 110.908 0
+      vertex 149.649 110.908 -3
+    endloop
+  endfacet
+  facet normal 0.866186 0.499722 -0
+    outer loop
+      vertex 149.544 111.09 -3
+      vertex 149.544 111.09 0
+      vertex 149.649 110.908 0
+    endloop
+  endfacet
+  facet normal 0.828349 0.560213 0
+    outer loop
+      vertex 149.427 111.263 -3
+      vertex 149.544 111.09 0
+      vertex 149.544 111.09 -3
+    endloop
+  endfacet
+  facet normal 0.828349 0.560213 -0
+    outer loop
+      vertex 149.427 111.263 -3
+      vertex 149.427 111.263 0
+      vertex 149.544 111.09 0
+    endloop
+  endfacet
+  facet normal 0.787807 0.615922 0
+    outer loop
+      vertex 149.298 111.428 -3
+      vertex 149.427 111.263 0
+      vertex 149.427 111.263 -3
+    endloop
+  endfacet
+  facet normal 0.787807 0.615922 -0
+    outer loop
+      vertex 149.298 111.428 -3
+      vertex 149.298 111.428 0
+      vertex 149.427 111.263 0
+    endloop
+  endfacet
+  facet normal 0.744242 0.66791 0
+    outer loop
+      vertex 149.158 111.584 -3
+      vertex 149.298 111.428 0
+      vertex 149.298 111.428 -3
+    endloop
+  endfacet
+  facet normal 0.744242 0.66791 -0
+    outer loop
+      vertex 149.158 111.584 -3
+      vertex 149.158 111.584 0
+      vertex 149.298 111.428 0
+    endloop
+  endfacet
+  facet normal 0.692631 0.721292 0
+    outer loop
+      vertex 149.007 111.729 -3
+      vertex 149.158 111.584 0
+      vertex 149.158 111.584 -3
+    endloop
+  endfacet
+  facet normal 0.692631 0.721292 -0
+    outer loop
+      vertex 149.007 111.729 -3
+      vertex 149.007 111.729 0
+      vertex 149.158 111.584 0
+    endloop
+  endfacet
+  facet normal 0.644871 0.764291 0
+    outer loop
+      vertex 148.847 111.864 -3
+      vertex 149.007 111.729 0
+      vertex 149.007 111.729 -3
+    endloop
+  endfacet
+  facet normal 0.644871 0.764291 -0
+    outer loop
+      vertex 148.847 111.864 -3
+      vertex 148.847 111.864 0
+      vertex 149.007 111.729 0
+    endloop
+  endfacet
+  facet normal 0.588456 0.808529 0
+    outer loop
+      vertex 148.678 111.987 -3
+      vertex 148.847 111.864 0
+      vertex 148.847 111.864 -3
+    endloop
+  endfacet
+  facet normal 0.588456 0.808529 -0
+    outer loop
+      vertex 148.678 111.987 -3
+      vertex 148.678 111.987 0
+      vertex 148.847 111.864 0
+    endloop
+  endfacet
+  facet normal 0.529142 0.848533 0
+    outer loop
+      vertex 148.5 112.098 -3
+      vertex 148.678 111.987 0
+      vertex 148.678 111.987 -3
+    endloop
+  endfacet
+  facet normal 0.529142 0.848533 -0
+    outer loop
+      vertex 148.5 112.098 -3
+      vertex 148.5 112.098 0
+      vertex 148.678 111.987 0
+    endloop
+  endfacet
+  facet normal 0.468107 0.883672 0
+    outer loop
+      vertex 148.315 112.196 -3
+      vertex 148.5 112.098 0
+      vertex 148.5 112.098 -3
+    endloop
+  endfacet
+  facet normal 0.468107 0.883672 -0
+    outer loop
+      vertex 148.315 112.196 -3
+      vertex 148.315 112.196 0
+      vertex 148.5 112.098 0
+    endloop
+  endfacet
+  facet normal 0.410563 0.911832 0
+    outer loop
+      vertex 148.124 112.282 -3
+      vertex 148.315 112.196 0
+      vertex 148.315 112.196 -3
+    endloop
+  endfacet
+  facet normal 0.410563 0.911832 -0
+    outer loop
+      vertex 148.124 112.282 -3
+      vertex 148.124 112.282 0
+      vertex 148.315 112.196 0
+    endloop
+  endfacet
+  facet normal 0.339058 0.940766 0
+    outer loop
+      vertex 147.927 112.353 -3
+      vertex 148.124 112.282 0
+      vertex 148.124 112.282 -3
+    endloop
+  endfacet
+  facet normal 0.339058 0.940766 -0
+    outer loop
+      vertex 147.927 112.353 -3
+      vertex 147.927 112.353 0
+      vertex 148.124 112.282 0
+    endloop
+  endfacet
+  facet normal 0.277246 0.960799 0
+    outer loop
+      vertex 147.726 112.411 -3
+      vertex 147.927 112.353 0
+      vertex 147.927 112.353 -3
+    endloop
+  endfacet
+  facet normal 0.277246 0.960799 -0
+    outer loop
+      vertex 147.726 112.411 -3
+      vertex 147.726 112.411 0
+      vertex 147.927 112.353 0
+    endloop
+  endfacet
+  facet normal 0.205289 0.978701 0
+    outer loop
+      vertex 147.521 112.454 -3
+      vertex 147.726 112.411 0
+      vertex 147.726 112.411 -3
+    endloop
+  endfacet
+  facet normal 0.205289 0.978701 -0
+    outer loop
+      vertex 147.521 112.454 -3
+      vertex 147.521 112.454 0
+      vertex 147.726 112.411 0
+    endloop
+  endfacet
+  facet normal 0.143429 0.989661 0
+    outer loop
+      vertex 147.314 112.484 -3
+      vertex 147.521 112.454 0
+      vertex 147.521 112.454 -3
+    endloop
+  endfacet
+  facet normal 0.143429 0.989661 -0
+    outer loop
+      vertex 147.314 112.484 -3
+      vertex 147.314 112.484 0
+      vertex 147.521 112.454 0
+    endloop
+  endfacet
+  facet normal 0.0668359 0.997764 0
+    outer loop
+      vertex 147.105 112.498 -3
+      vertex 147.314 112.484 0
+      vertex 147.314 112.484 -3
+    endloop
+  endfacet
+  facet normal 0.0668359 0.997764 -0
+    outer loop
+      vertex 147.105 112.498 -3
+      vertex 147.105 112.498 0
+      vertex 147.314 112.484 0
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex 147.002 112.498 -3
+      vertex 147.105 112.498 0
+      vertex 147.105 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex 147.002 112.498 -3
+      vertex 147.002 112.498 0
+      vertex 147.105 112.498 0
+    endloop
+  endfacet
+  facet normal 0.707107 0.707107 0
+    outer loop
+      vertex 147 112.5 -3
+      vertex 147.002 112.498 0
+      vertex 147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0.707107 0.707107 -0
+    outer loop
+      vertex 147 112.5 -3
+      vertex 147 112.5 0
+      vertex 147.002 112.498 0
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -147 112.5 -3
+      vertex 147 112.5 0
+      vertex 147 112.5 -3
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -147 112.5 -3
+      vertex -147 112.5 0
+      vertex 147 112.5 0
+    endloop
+  endfacet
+  facet normal -0.707107 0.707107 0
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -147 112.5 0
+      vertex -147 112.5 -3
+    endloop
+  endfacet
+  facet normal -0.707107 0.707107 0
+    outer loop
+      vertex -147.002 112.498 -3
+      vertex -147.002 112.498 0
+      vertex -147 112.5 0
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -147.105 112.498 -3
+      vertex -147.002 112.498 0
+      vertex -147.002 112.498 -3
+    endloop
+  endfacet
+  facet normal 0 1 0
+    outer loop
+      vertex -147.105 112.498 -3
+      vertex -147.105 112.498 0
+      vertex -147.002 112.498 0
+    endloop
+  endfacet
+  facet normal -0.0668359 0.997764 0
+    outer loop
+      vertex -147.314 112.484 -3
+      vertex -147.105 112.498 0
+      vertex -147.105 112.498 -3
+    endloop
+  endfacet
+  facet normal -0.0668359 0.997764 0
+    outer loop
+      vertex -147.314 112.484 -3
+      vertex -147.314 112.484 0
+      vertex -147.105 112.498 0
+    endloop
+  endfacet
+  facet normal -0.143429 0.989661 0
+    outer loop
+      vertex -147.521 112.454 -3
+      vertex -147.314 112.484 0
+      vertex -147.314 112.484 -3
+    endloop
+  endfacet
+  facet normal -0.143429 0.989661 0
+    outer loop
+      vertex -147.521 112.454 -3
+      vertex -147.521 112.454 0
+      vertex -147.314 112.484 0
+    endloop
+  endfacet
+  facet normal -0.205289 0.978701 0
+    outer loop
+      vertex -147.726 112.411 -3
+      vertex -147.521 112.454 0
+      vertex -147.521 112.454 -3
+    endloop
+  endfacet
+  facet normal -0.205289 0.978701 0
+    outer loop
+      vertex -147.726 112.411 -3
+      vertex -147.726 112.411 0
+      vertex -147.521 112.454 0
+    endloop
+  endfacet
+  facet normal -0.277246 0.960799 0
+    outer loop
+      vertex -147.927 112.353 -3
+      vertex -147.726 112.411 0
+      vertex -147.726 112.411 -3
+    endloop
+  endfacet
+  facet normal -0.277246 0.960799 0
+    outer loop
+      vertex -147.927 112.353 -3
+      vertex -147.927 112.353 0
+      vertex -147.726 112.411 0
+    endloop
+  endfacet
+  facet normal -0.339058 0.940766 0
+    outer loop
+      vertex -148.124 112.282 -3
+      vertex -147.927 112.353 0
+      vertex -147.927 112.353 -3
+    endloop
+  endfacet
+  facet normal -0.339058 0.940766 0
+    outer loop
+      vertex -148.124 112.282 -3
+      vertex -148.124 112.282 0
+      vertex -147.927 112.353 0
+    endloop
+  endfacet
+  facet normal -0.410563 0.911832 0
+    outer loop
+      vertex -148.315 112.196 -3
+      vertex -148.124 112.282 0
+      vertex -148.124 112.282 -3
+    endloop
+  endfacet
+  facet normal -0.410563 0.911832 0
+    outer loop
+      vertex -148.315 112.196 -3
+      vertex -148.315 112.196 0
+      vertex -148.124 112.282 0
+    endloop
+  endfacet
+  facet normal -0.468107 0.883672 0
+    outer loop
+      vertex -148.5 112.098 -3
+      vertex -148.315 112.196 0
+      vertex -148.315 112.196 -3
+    endloop
+  endfacet
+  facet normal -0.468107 0.883672 0
+    outer loop
+      vertex -148.5 112.098 -3
+      vertex -148.5 112.098 0
+      vertex -148.315 112.196 0
+    endloop
+  endfacet
+  facet normal -0.529142 0.848533 0
+    outer loop
+      vertex -148.678 111.987 -3
+      vertex -148.5 112.098 0
+      vertex -148.5 112.098 -3
+    endloop
+  endfacet
+  facet normal -0.529142 0.848533 0
+    outer loop
+      vertex -148.678 111.987 -3
+      vertex -148.678 111.987 0
+      vertex -148.5 112.098 0
+    endloop
+  endfacet
+  facet normal -0.588456 0.808529 0
+    outer loop
+      vertex -148.847 111.864 -3
+      vertex -148.678 111.987 0
+      vertex -148.678 111.987 -3
+    endloop
+  endfacet
+  facet normal -0.588456 0.808529 0
+    outer loop
+      vertex -148.847 111.864 -3
+      vertex -148.847 111.864 0
+      vertex -148.678 111.987 0
+    endloop
+  endfacet
+  facet normal -0.644871 0.764291 0
+    outer loop
+      vertex -149.007 111.729 -3
+      vertex -148.847 111.864 0
+      vertex -148.847 111.864 -3
+    endloop
+  endfacet
+  facet normal -0.644871 0.764291 0
+    outer loop
+      vertex -149.007 111.729 -3
+      vertex -149.007 111.729 0
+      vertex -148.847 111.864 0
+    endloop
+  endfacet
+  facet normal -0.692631 0.721292 0
+    outer loop
+      vertex -149.158 111.584 -3
+      vertex -149.007 111.729 0
+      vertex -149.007 111.729 -3
+    endloop
+  endfacet
+  facet normal -0.692631 0.721292 0
+    outer loop
+      vertex -149.158 111.584 -3
+      vertex -149.158 111.584 0
+      vertex -149.007 111.729 0
+    endloop
+  endfacet
+  facet normal -0.744242 0.66791 0
+    outer loop
+      vertex -149.298 111.428 -3
+      vertex -149.158 111.584 0
+      vertex -149.158 111.584 -3
+    endloop
+  endfacet
+  facet normal -0.744242 0.66791 0
+    outer loop
+      vertex -149.298 111.428 -3
+      vertex -149.298 111.428 0
+      vertex -149.158 111.584 0
+    endloop
+  endfacet
+  facet normal -0.787807 0.615922 0
+    outer loop
+      vertex -149.427 111.263 -3
+      vertex -149.298 111.428 0
+      vertex -149.298 111.428 -3
+    endloop
+  endfacet
+  facet normal -0.787807 0.615922 0
+    outer loop
+      vertex -149.427 111.263 -3
+      vertex -149.427 111.263 0
+      vertex -149.298 111.428 0
+    endloop
+  endfacet
+  facet normal -0.828349 0.560213 0
+    outer loop
+      vertex -149.544 111.09 -3
+      vertex -149.427 111.263 0
+      vertex -149.427 111.263 -3
+    endloop
+  endfacet
+  facet normal -0.828349 0.560213 0
+    outer loop
+      vertex -149.544 111.09 -3
+      vertex -149.544 111.09 0
+      vertex -149.427 111.263 0
+    endloop
+  endfacet
+  facet normal -0.866186 0.499722 0
+    outer loop
+      vertex -149.649 110.908 -3
+      vertex -149.544 111.09 0
+      vertex -149.544 111.09 -3
+    endloop
+  endfacet
+  facet normal -0.866186 0.499722 0
+    outer loop
+      vertex -149.649 110.908 -3
+      vertex -149.649 110.908 0
+      vertex -149.544 111.09 0
+    endloop
+  endfacet
+  facet normal -0.898217 0.439553 0
+    outer loop
+      vertex -149.741 110.72 -3
+      vertex -149.649 110.908 0
+      vertex -149.649 110.908 -3
+    endloop
+  endfacet
+  facet normal -0.898217 0.439553 0
+    outer loop
+      vertex -149.741 110.72 -3
+      vertex -149.741 110.72 0
+      vertex -149.649 110.908 0
+    endloop
+  endfacet
+  facet normal -0.927816 0.373039 0
+    outer loop
+      vertex -149.819 110.526 -3
+      vertex -149.741 110.72 0
+      vertex -149.741 110.72 -3
+    endloop
+  endfacet
+  facet normal -0.927816 0.373039 0
+    outer loop
+      vertex -149.819 110.526 -3
+      vertex -149.819 110.526 0
+      vertex -149.741 110.72 0
+    endloop
+  endfacet
+  facet normal -0.950577 0.31049 0
+    outer loop
+      vertex -149.884 110.327 -3
+      vertex -149.819 110.526 0
+      vertex -149.819 110.526 -3
+    endloop
+  endfacet
+  facet normal -0.950577 0.31049 0
+    outer loop
+      vertex -149.884 110.327 -3
+      vertex -149.884 110.327 0
+      vertex -149.819 110.526 0
+    endloop
+  endfacet
+  facet normal -0.970981 0.239158 0
+    outer loop
+      vertex -149.934 110.124 -3
+      vertex -149.884 110.327 0
+      vertex -149.884 110.327 -3
+    endloop
+  endfacet
+  facet normal -0.970981 0.239158 0
+    outer loop
+      vertex -149.934 110.124 -3
+      vertex -149.934 110.124 0
+      vertex -149.884 110.327 0
+    endloop
+  endfacet
+  facet normal -0.98425 0.176783 0
+    outer loop
+      vertex -149.971 109.918 -3
+      vertex -149.934 110.124 0
+      vertex -149.934 110.124 -3
+    endloop
+  endfacet
+  facet normal -0.98425 0.176783 0
+    outer loop
+      vertex -149.971 109.918 -3
+      vertex -149.971 109.918 0
+      vertex -149.934 110.124 0
+    endloop
+  endfacet
+  facet normal -0.994505 0.104685 0
+    outer loop
+      vertex -149.993 109.709 -3
+      vertex -149.971 109.918 0
+      vertex -149.971 109.918 -3
+    endloop
+  endfacet
+  facet normal -0.994505 0.104685 0
+    outer loop
+      vertex -149.993 109.709 -3
+      vertex -149.993 109.709 0
+      vertex -149.971 109.918 0
+    endloop
+  endfacet
+  facet normal -0.99944 0.0334741 0
+    outer loop
+      vertex -150 109.5 -3
+      vertex -149.993 109.709 0
+      vertex -149.993 109.709 -3
+    endloop
+  endfacet
+  facet normal -0.99944 0.0334741 0
+    outer loop
+      vertex -150 109.5 -3
+      vertex -150 109.5 0
+      vertex -149.993 109.709 0
+    endloop
+  endfacet
+  facet normal -1 0 0
+    outer loop
+      vertex -150 -109.5 -3
+      vertex -150 109.5 0
+      vertex -150 109.5 -3
+    endloop
+  endfacet
+  facet normal -1 0 0
+    outer loop
+      vertex -150 -109.5 -3
+      vertex -150 -109.5 0
+      vertex -150 109.5 0
+    endloop
+  endfacet
+  facet normal -0.99944 -0.0334741 0
+    outer loop
+      vertex -149.993 -109.709 -3
+      vertex -150 -109.5 0
+      vertex -150 -109.5 -3
+    endloop
+  endfacet
+  facet normal -0.99944 -0.0334741 0
+    outer loop
+      vertex -149.993 -109.709 -3
+      vertex -149.993 -109.709 0
+      vertex -150 -109.5 0
+    endloop
+  endfacet
+  facet normal -0.994505 -0.104685 0
+    outer loop
+      vertex -149.971 -109.918 -3
+      vertex -149.993 -109.709 0
+      vertex -149.993 -109.709 -3
+    endloop
+  endfacet
+  facet normal -0.994505 -0.104685 0
+    outer loop
+      vertex -149.971 -109.918 -3
+      vertex -149.971 -109.918 0
+      vertex -149.993 -109.709 0
+    endloop
+  endfacet
+  facet normal -0.98425 -0.176783 0
+    outer loop
+      vertex -149.934 -110.124 -3
+      vertex -149.971 -109.918 0
+      vertex -149.971 -109.918 -3
+    endloop
+  endfacet
+  facet normal -0.98425 -0.176783 0
+    outer loop
+      vertex -149.934 -110.124 -3
+      vertex -149.934 -110.124 0
+      vertex -149.971 -109.918 0
+    endloop
+  endfacet
+  facet normal -0.970981 -0.239158 0
+    outer loop
+      vertex -149.884 -110.327 -3
+      vertex -149.934 -110.124 0
+      vertex -149.934 -110.124 -3
+    endloop
+  endfacet
+  facet normal -0.970981 -0.239158 0
+    outer loop
+      vertex -149.884 -110.327 -3
+      vertex -149.884 -110.327 0
+      vertex -149.934 -110.124 0
+    endloop
+  endfacet
+  facet normal -0.950577 -0.31049 0
+    outer loop
+      vertex -149.819 -110.526 -3
+      vertex -149.884 -110.327 0
+      vertex -149.884 -110.327 -3
+    endloop
+  endfacet
+  facet normal -0.950577 -0.31049 0
+    outer loop
+      vertex -149.819 -110.526 -3
+      vertex -149.819 -110.526 0
+      vertex -149.884 -110.327 0
+    endloop
+  endfacet
+  facet normal -0.927816 -0.373039 0
+    outer loop
+      vertex -149.741 -110.72 -3
+      vertex -149.819 -110.526 0
+      vertex -149.819 -110.526 -3
+    endloop
+  endfacet
+  facet normal -0.927816 -0.373039 0
+    outer loop
+      vertex -149.741 -110.72 -3
+      vertex -149.741 -110.72 0
+      vertex -149.819 -110.526 0
+    endloop
+  endfacet
+  facet normal -0.898217 -0.439553 0
+    outer loop
+      vertex -149.649 -110.908 -3
+      vertex -149.741 -110.72 0
+      vertex -149.741 -110.72 -3
+    endloop
+  endfacet
+  facet normal -0.898217 -0.439553 0
+    outer loop
+      vertex -149.649 -110.908 -3
+      vertex -149.649 -110.908 0
+      vertex -149.741 -110.72 0
+    endloop
+  endfacet
+  facet normal -0.866186 -0.499722 0
+    outer loop
+      vertex -149.544 -111.09 -3
+      vertex -149.649 -110.908 0
+      vertex -149.649 -110.908 -3
+    endloop
+  endfacet
+  facet normal -0.866186 -0.499722 0
+    outer loop
+      vertex -149.544 -111.09 -3
+      vertex -149.544 -111.09 0
+      vertex -149.649 -110.908 0
+    endloop
+  endfacet
+  facet normal -0.828349 -0.560213 0
+    outer loop
+      vertex -149.427 -111.263 -3
+      vertex -149.544 -111.09 0
+      vertex -149.544 -111.09 -3
+    endloop
+  endfacet
+  facet normal -0.828349 -0.560213 0
+    outer loop
+      vertex -149.427 -111.263 -3
+      vertex -149.427 -111.263 0
+      vertex -149.544 -111.09 0
+    endloop
+  endfacet
+  facet normal -0.787807 -0.615922 0
+    outer loop
+      vertex -149.298 -111.428 -3
+      vertex -149.427 -111.263 0
+      vertex -149.427 -111.263 -3
+    endloop
+  endfacet
+  facet normal -0.787807 -0.615922 0
+    outer loop
+      vertex -149.298 -111.428 -3
+      vertex -149.298 -111.428 0
+      vertex -149.427 -111.263 0
+    endloop
+  endfacet
+  facet normal -0.744242 -0.66791 0
+    outer loop
+      vertex -149.158 -111.584 -3
+      vertex -149.298 -111.428 0
+      vertex -149.298 -111.428 -3
+    endloop
+  endfacet
+  facet normal -0.744242 -0.66791 0
+    outer loop
+      vertex -149.158 -111.584 -3
+      vertex -149.158 -111.584 0
+      vertex -149.298 -111.428 0
+    endloop
+  endfacet
+  facet normal -0.692631 -0.721292 0
+    outer loop
+      vertex -149.007 -111.729 -3
+      vertex -149.158 -111.584 0
+      vertex -149.158 -111.584 -3
+    endloop
+  endfacet
+  facet normal -0.692631 -0.721292 0
+    outer loop
+      vertex -149.007 -111.729 -3
+      vertex -149.007 -111.729 0
+      vertex -149.158 -111.584 0
+    endloop
+  endfacet
+  facet normal -0.644871 -0.764291 0
+    outer loop
+      vertex -148.847 -111.864 -3
+      vertex -149.007 -111.729 0
+      vertex -149.007 -111.729 -3
+    endloop
+  endfacet
+  facet normal -0.644871 -0.764291 0
+    outer loop
+      vertex -148.847 -111.864 -3
+      vertex -148.847 -111.864 0
+      vertex -149.007 -111.729 0
+    endloop
+  endfacet
+  facet normal -0.588456 -0.808529 0
+    outer loop
+      vertex -148.678 -111.987 -3
+      vertex -148.847 -111.864 0
+      vertex -148.847 -111.864 -3
+    endloop
+  endfacet
+  facet normal -0.588456 -0.808529 0
+    outer loop
+      vertex -148.678 -111.987 -3
+      vertex -148.678 -111.987 0
+      vertex -148.847 -111.864 0
+    endloop
+  endfacet
+  facet normal -0.529142 -0.848533 0
+    outer loop
+      vertex -148.5 -112.098 -3
+      vertex -148.678 -111.987 0
+      vertex -148.678 -111.987 -3
+    endloop
+  endfacet
+  facet normal -0.529142 -0.848533 0
+    outer loop
+      vertex -148.5 -112.098 -3
+      vertex -148.5 -112.098 0
+      vertex -148.678 -111.987 0
+    endloop
+  endfacet
+  facet normal -0.468107 -0.883672 0
+    outer loop
+      vertex -148.315 -112.196 -3
+      vertex -148.5 -112.098 0
+      vertex -148.5 -112.098 -3
+    endloop
+  endfacet
+  facet normal -0.468107 -0.883672 0
+    outer loop
+      vertex -148.315 -112.196 -3
+      vertex -148.315 -112.196 0
+      vertex -148.5 -112.098 0
+    endloop
+  endfacet
+  facet normal -0.410563 -0.911832 0
+    outer loop
+      vertex -148.124 -112.282 -3
+      vertex -148.315 -112.196 0
+      vertex -148.315 -112.196 -3
+    endloop
+  endfacet
+  facet normal -0.410563 -0.911832 0
+    outer loop
+      vertex -148.124 -112.282 -3
+      vertex -148.124 -112.282 0
+      vertex -148.315 -112.196 0
+    endloop
+  endfacet
+  facet normal -0.339058 -0.940766 0
+    outer loop
+      vertex -147.927 -112.353 -3
+      vertex -148.124 -112.282 0
+      vertex -148.124 -112.282 -3
+    endloop
+  endfacet
+  facet normal -0.339058 -0.940766 0
+    outer loop
+      vertex -147.927 -112.353 -3
+      vertex -147.927 -112.353 0
+      vertex -148.124 -112.282 0
+    endloop
+  endfacet
+  facet normal -0.277246 -0.960799 0
+    outer loop
+      vertex -147.726 -112.411 -3
+      vertex -147.927 -112.353 0
+      vertex -147.927 -112.353 -3
+    endloop
+  endfacet
+  facet normal -0.277246 -0.960799 0
+    outer loop
+      vertex -147.726 -112.411 -3
+      vertex -147.726 -112.411 0
+      vertex -147.927 -112.353 0
+    endloop
+  endfacet
+  facet normal -0.205289 -0.978701 0
+    outer loop
+      vertex -147.521 -112.454 -3
+      vertex -147.726 -112.411 0
+      vertex -147.726 -112.411 -3
+    endloop
+  endfacet
+  facet normal -0.205289 -0.978701 0
+    outer loop
+      vertex -147.521 -112.454 -3
+      vertex -147.521 -112.454 0
+      vertex -147.726 -112.411 0
+    endloop
+  endfacet
+  facet normal -0.143429 -0.989661 0
+    outer loop
+      vertex -147.314 -112.484 -3
+      vertex -147.521 -112.454 0
+      vertex -147.521 -112.454 -3
+    endloop
+  endfacet
+  facet normal -0.143429 -0.989661 0
+    outer loop
+      vertex -147.314 -112.484 -3
+      vertex -147.314 -112.484 0
+      vertex -147.521 -112.454 0
+    endloop
+  endfacet
+  facet normal -0.0668359 -0.997764 0
+    outer loop
+      vertex -147.105 -112.498 -3
+      vertex -147.314 -112.484 0
+      vertex -147.314 -112.484 -3
+    endloop
+  endfacet
+  facet normal -0.0668359 -0.997764 0
+    outer loop
+      vertex -147.105 -112.498 -3
+      vertex -147.105 -112.498 0
+      vertex -147.314 -112.484 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -147.105 -112.498 0
+      vertex -147.105 -112.498 -3
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex -147.002 -112.498 -3
+      vertex -147.002 -112.498 0
+      vertex -147.105 -112.498 0
+    endloop
+  endfacet
+  facet normal -0.707107 -0.707107 0
+    outer loop
+      vertex -147 -112.5 -3
+      vertex -147.002 -112.498 0
+      vertex -147.002 -112.498 -3
+    endloop
+  endfacet
+  facet normal -0.707107 -0.707107 0
+    outer loop
+      vertex -147 -112.5 -3
+      vertex -147 -112.5 0
+      vertex -147.002 -112.498 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 147 -112.5 -3
+      vertex -147 -112.5 0
+      vertex -147 -112.5 -3
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 147 -112.5 -3
+      vertex 147 -112.5 0
+      vertex -147 -112.5 0
+    endloop
+  endfacet
+  facet normal 0.707107 -0.707107 0
+    outer loop
+      vertex 147.002 -112.498 -3
+      vertex 147 -112.5 0
+      vertex 147 -112.5 -3
+    endloop
+  endfacet
+  facet normal 0.707107 -0.707107 0
+    outer loop
+      vertex 147.002 -112.498 -3
+      vertex 147.002 -112.498 0
+      vertex 147 -112.5 0
+    endloop
+  endfacet
+endsolid OpenSCAD_Model

From 90f58fe90a3f8ac23937ed8af34def83bc4560ff Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sun, 28 Feb 2021 17:06:24 +0100
Subject: [PATCH 34/53] creality.ini: CR-200B bed_shape and max_print_height

---
 resources/profiles/Creality.ini | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index de6f103a0..2c1b9da20 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -1017,6 +1017,8 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 
 #[printer:Creality CR-200B]
 #inherits = *common*
+#bed_shape = 5x5,195x5,195x195,5x195
+#max_print_height = 200
 #printer_model = CR200B
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR200B\nPRINTER_HAS_BOWDEN
 

From 34202f71e5ab56c5e96fb3c9d9e6262b4cdd1231 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Sun, 28 Feb 2021 17:10:25 +0100
Subject: [PATCH 35/53] creality.ini: move Ender-3 specific extruder_clearance

replace general extruder_clearance with higher values so there's
a lot of clearance leeway until we get exact figures for each
printer model.

related: f9b4bbb016566eead32d32092939a88c10c80f1f
---
 resources/profiles/Creality.ini | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 2c1b9da20..62d0d837f 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -287,8 +287,8 @@ external_perimeters_first = 0
 external_perimeter_extrusion_width = 0.45
 external_perimeter_speed = 25
 extra_perimeters = 0
-extruder_clearance_height = 34
-extruder_clearance_radius = 47
+extruder_clearance_height = 50
+extruder_clearance_radius = 70
 extrusion_width = 0.45
 fill_angle = 45
 fill_density = 15%
@@ -834,6 +834,8 @@ inherits = *common*
 renamed_from = "Creality ENDER-3"
 bed_shape = 3x3,228x3,228x228,3x228
 max_print_height = 250
+extruder_clearance_height = 34
+extruder_clearance_radius = 47
 printer_model = ENDER3
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3\nPRINTER_HAS_BOWDEN
 

From 3f1299c9b7e0a8689d5a16b8d704ed413419c7fa Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Mon, 1 Mar 2021 10:03:49 +0100
Subject: [PATCH 36/53] Fix build against wxWidgets older than 3.1.1

---
 src/slic3r/GUI/ConfigWizard.cpp | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp
index 77e847201..bd6986d3e 100644
--- a/src/slic3r/GUI/ConfigWizard.cpp
+++ b/src/slic3r/GUI/ConfigWizard.cpp
@@ -819,7 +819,22 @@ void PageMaterials::update_lists(int sel_type, int sel_vendor, int last_selected
 	wxArrayInt sel_printers;
 	int sel_printers_count = list_printer->GetSelections(sel_printers);
 
-	if (sel_printers != sel_printers_prev) {
+    // Does our wxWidgets version support operator== for wxArrayInt ?
+    // https://github.com/prusa3d/PrusaSlicer/issues/5152#issuecomment-787208614
+#if wxCHECK_VERSION(3, 1, 1)
+    if (sel_printers != sel_printers_prev) {
+#else
+    auto are_equal = [](const wxArrayInt& arr_first, const wxArrayInt& arr_second) {
+        if (arr_first.GetCount() != arr_second.GetCount())
+            return false;
+        for (size_t i = 0; i < arr_first.GetCount(); i++)
+            if (arr_first[i] != arr_second[i])
+                return false;
+        return true;
+    };
+    if (!are_equal(sel_printers, sel_printers_prev)) {
+#endif
+
         // Refresh type list
 		list_type->Clear();
 		list_type->append(_L("(All)"), &EMPTY);

From 13b3e813cfe2b9bd4887ba2e0fa9938b6352aad8 Mon Sep 17 00:00:00 2001
From: rtyr <36745189+rtyr@users.noreply.github.com>
Date: Mon, 1 Mar 2021 10:50:41 +0100
Subject: [PATCH 37/53] CR5PRO and CR200B thumbnails

---
 .../profiles/Creality/CR200B_thumbnail.png      | Bin 0 -> 27228 bytes
 .../profiles/Creality/CR5PRO_thumbnail.png      | Bin 0 -> 38706 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 resources/profiles/Creality/CR200B_thumbnail.png
 create mode 100644 resources/profiles/Creality/CR5PRO_thumbnail.png

diff --git a/resources/profiles/Creality/CR200B_thumbnail.png b/resources/profiles/Creality/CR200B_thumbnail.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5b964ac937c400e81e11ca0e8e3681ecf7db315
GIT binary patch
literal 27228
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
UJIxV%?GT!hyqa9O%+tXC19$y2#Q*>R

literal 0
HcmV?d00001

diff --git a/resources/profiles/Creality/CR5PRO_thumbnail.png b/resources/profiles/Creality/CR5PRO_thumbnail.png
new file mode 100644
index 0000000000000000000000000000000000000000..df2f1b665f2f7a3d7d5e45ff3bb29a4fb674bdfe
GIT binary patch
literal 38706
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

literal 0
HcmV?d00001


From d7a786e8c8d82eb0be95e81094665e0fb23ce66b Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Mon, 1 Mar 2021 10:43:13 +0100
Subject: [PATCH 38/53] Bumping up wxWidgets to 3.1.4-patched on all platforms.

---
 deps/wxWidgets/wxWidgets.cmake | 9 +--------
 src/libslic3r/Geometry.cpp     | 6 ++----
 2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake
index bf23698cf..c7facc2c6 100644
--- a/deps/wxWidgets/wxWidgets.cmake
+++ b/deps/wxWidgets/wxWidgets.cmake
@@ -1,11 +1,4 @@
-if (APPLE)
-    # The new OSX 11 (Big Sur) is not compatible with wxWidgets 3.1.3.
-    # Let's use patched wxWidgets 3.1.4, even though it is not quite tested.
-    set(_wx_git_tag v3.1.4-patched)
-else ()
-    # Use the tested patched wxWidgets 3.1.3 everywhere else.
-    set(_wx_git_tag v3.1.3-patched)
-endif ()
+set(_wx_git_tag v3.1.4-patched)
 
 # set(_patch_command "")
 set(_wx_toolkit "")
diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp
index 45730dd9f..aac7c7752 100644
--- a/src/libslic3r/Geometry.cpp
+++ b/src/libslic3r/Geometry.cpp
@@ -245,8 +245,7 @@ Polygon convex_hull(Points points)
     return hull;
 }
 
-Pointf3s
-convex_hull(Pointf3s points)
+Pointf3s convex_hull(Pointf3s points)
 {
     assert(points.size() >= 3);
     // sort input points
@@ -304,8 +303,7 @@ convex_hull(Pointf3s points)
     return hull;
 }
 
-Polygon
-convex_hull(const Polygons &polygons)
+Polygon convex_hull(const Polygons &polygons)
 {
     Points pp;
     for (Polygons::const_iterator p = polygons.begin(); p != polygons.end(); ++p) {

From 224f3e506c9db3d2de9e2e441ee4443de2bab964 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Mon, 1 Mar 2021 12:52:40 +0100
Subject: [PATCH 39/53] Fix of Custom G-code for color change does not process
 macro #5782 Added macro processing of color_change_gcode, pause_print_gcode
 and template_custom_gcode custom G-codes when emitting them into the output
 G-code.

---
 src/libslic3r/GCode.cpp | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 838435961..ca714549d 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1705,7 +1705,9 @@ namespace ProcessLayer
 {
 
     static std::string emit_custom_gcode_per_print_z(
+        GCode                                                   &gcodegen,
         const CustomGCode::Item 								*custom_gcode,
+        unsigned int                                             current_extruder_id,
         // ID of the first extruder printing this layer.
         unsigned int                                             first_extruder_id,
         const PrintConfig                                       &config)
@@ -1746,12 +1748,14 @@ namespace ProcessLayer
                     // && !MMU1
                     ) {
                     //! FIXME_in_fw show message during print pause
-                    gcode += config.pause_print_gcode;// pause print
+                    DynamicConfig cfg;
+                    cfg.set_key_value("color_change_extruder", new ConfigOptionInt(m600_extruder_before_layer));
+                    gcode += gcodegen.placeholder_parser_process("pause_print_gcode", config.pause_print_gcode, current_extruder_id, &cfg);
                     gcode += "\n";
                     gcode += "M117 Change filament for Extruder " + std::to_string(m600_extruder_before_layer) + "\n";
                 }
                 else {
-                    gcode += config.color_change_gcode;//ColorChangeCode;
+                    gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id);
                     gcode += "\n";
                 }
 	        } 
@@ -1767,7 +1771,7 @@ namespace ProcessLayer
                     //! FIXME_in_fw show message during print pause
 	                if (!pause_print_msg.empty())
 	                    gcode += "M117 " + pause_print_msg + "\n";
-                    gcode += config.pause_print_gcode;
+                    gcode += gcodegen.placeholder_parser_process("pause_print_gcode", config.pause_print_gcode, current_extruder_id);
                 }
 	            else {
                     // add tag for processor
@@ -1776,8 +1780,8 @@ namespace ProcessLayer
 #else
                     gcode += ";" + GCodeProcessor::Custom_Code_Tag + "\n";
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
-                    if (gcode_type == CustomGCode::Template)    // Template Cistom Gcode
-                        gcode += config.template_custom_gcode;
+                    if (gcode_type == CustomGCode::Template)    // Template Custom Gcode
+                        gcode += gcodegen.placeholder_parser_process("template_custom_gcode", config.template_custom_gcode, current_extruder_id);
                     else                                        // custom Gcode
                         gcode += custom_gcode->extra;
 
@@ -1985,7 +1989,7 @@ void GCode::process_layer(
 
     if (single_object_instance_idx == size_t(-1)) {
         // Normal (non-sequential) print.
-        gcode += ProcessLayer::emit_custom_gcode_per_print_z(layer_tools.custom_gcode, first_extruder_id, print.config());
+        gcode += ProcessLayer::emit_custom_gcode_per_print_z(*this, layer_tools.custom_gcode, m_writer.extruder()->id(), first_extruder_id, print.config());
     }
     // Extrude skirt at the print_z of the raft layers and normal object layers
     // not at the print_z of the interlaced support material layers.

From 908c48ae6a1950eec1cf76840a06ee84e83ea155 Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Mon, 1 Mar 2021 13:03:43 +0100
Subject: [PATCH 40/53] Follow-up of 86d7e1fb907d9841a1d0cf516415fea84e8b5280
 -> Fixed update after switching tab after editing custom g-code in settings
 tabs

---
 src/slic3r/GUI/MainFrame.cpp |  5 ++---
 src/slic3r/GUI/Tab.cpp       | 36 ++++++++++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 91357ff6c..6b0dd1ad5 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -549,9 +549,8 @@ void MainFrame::init_tabpanel()
         wxWindow* panel = m_tabpanel->GetCurrentPage();
         if (panel != nullptr) {
             Tab* tab = dynamic_cast<Tab*>(panel);
-            if (tab && (tab->type() == Preset::TYPE_FILAMENT || tab->type() == Preset::TYPE_PRINTER))
-                if (!tab->validate_custom_gcodes())
-                    evt.Veto();
+            if (tab != nullptr && !tab->validate_custom_gcodes())
+                evt.Veto();
         }
         });
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index cf1879bb1..eeb420e3e 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -3826,15 +3826,35 @@ void TabPrinter::apply_extruder_cnt_from_cache()
 #if ENABLE_VALIDATE_CUSTOM_GCODE
 bool Tab::validate_custom_gcodes()
 {
+    if (m_type != Preset::TYPE_FILAMENT &&
+        (m_type != Preset::TYPE_PRINTER || static_cast<TabPrinter*>(this)->m_printer_technology != ptFFF))
+        return true;
+    if (m_active_page->title() != L("Custom G-code"))
+        return true;
+
     bool valid = true;
-    if ((m_type == Preset::TYPE_FILAMENT || 
-        (m_type == Preset::TYPE_PRINTER && static_cast<TabPrinter*>(this)->m_printer_technology == ptFFF)) &&
-        m_active_page->title() == "Custom G-code") {
-            for (auto opt_group : m_active_page->m_optgroups) {
-                assert(opt_group->opt_map().size() == 1);
-                std::string key = opt_group->opt_map().begin()->first;
-                valid &= validate_custom_gcode(opt_group->title, boost::any_cast<std::string>(opt_group->get_value(key)));
-            }
+    for (auto opt_group : m_active_page->m_optgroups) {
+        assert(opt_group->opt_map().size() == 1);
+        std::string key = opt_group->opt_map().begin()->first;
+        std::string value = boost::any_cast<std::string>(opt_group->get_value(key));
+        std::string config_value = m_config->opt_string(key);
+        valid &= validate_custom_gcode(opt_group->title, value);
+        Field* field = opt_group->get_field(key);
+        TextCtrl* text_ctrl = dynamic_cast<TextCtrl*>(field);
+        if (text_ctrl != nullptr && text_ctrl->m_on_change != nullptr && !text_ctrl->m_disable_change_event) {
+            Slic3r::GUI::t_change callback = opt_group->m_on_change;
+            // temporary disable the opt_group->m_on_change callback to avoid multiple validations
+            opt_group->m_on_change = nullptr;
+            text_ctrl->m_on_change(key, value);
+            // restore the opt_group->m_on_change callback
+            opt_group->m_on_change = callback;
+
+            update_dirty();
+            on_value_change(key, value);
+        }
+
+        if (!valid)
+            break;
     }
     return valid;
 }

From 70fc0c232c745a74d3e8459422812e7edfc26ac3 Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Mon, 1 Mar 2021 16:01:53 +0100
Subject: [PATCH 41/53] Linux specific issue: DiffViewCtrl: Fixed scaling of
 the columns width

---
 src/slic3r/GUI/UnsavedChangesDialog.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp
index 7d2879f0a..7c0be76a4 100644
--- a/src/slic3r/GUI/UnsavedChangesDialog.cpp
+++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp
@@ -601,7 +601,7 @@ void DiffViewCtrl::AppendBmpTextColumn(const wxString& label, unsigned model_col
 #ifdef SUPPORTS_MARKUP
     rd->EnableMarkup(true);
 #endif
-    wxDataViewColumn* column = new wxDataViewColumn(label, rd, model_column, width, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT);
+    wxDataViewColumn* column = new wxDataViewColumn(label, rd, model_column, width * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT);
 #else
     wxDataViewColumn* column = new wxDataViewColumn(label, new BitmapTextRenderer(true, wxDATAVIEW_CELL_INERT), model_column, width * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE);
 #endif //__linux__
@@ -806,7 +806,7 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
     m_action_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold());
 
     m_tree = new DiffViewCtrl(this, wxSize(em * 60, em * 30));
-    m_tree->AppendToggleColumn_(L"\u2714"      , DiffModel::colToggle, wxLinux ? 8 : 6);
+    m_tree->AppendToggleColumn_(L"\u2714"      , DiffModel::colToggle, wxLinux ? 9 : 6);
     m_tree->AppendBmpTextColumn(""             , DiffModel::colIconText, 28);
     m_tree->AppendBmpTextColumn(_L("Old Value"), DiffModel::colOldValue, 12);
     m_tree->AppendBmpTextColumn(_L("New Value"), DiffModel::colNewValue, 12);

From 409849d238718b75cf0c5ef264ce1df0cedc5c6e Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Mon, 1 Mar 2021 16:32:47 +0100
Subject: [PATCH 42/53] Fixed loading of the project file with filament which
 is not installed for the selected printers If loaded filaments are
 invisible/non-instaled, set them as visible

---
 src/libslic3r/PresetBundle.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp
index 7d08c9359..dc52fdaff 100644
--- a/src/libslic3r/PresetBundle.cpp
+++ b/src/libslic3r/PresetBundle.cpp
@@ -876,6 +876,17 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
                 this->filament_presets[i] = loaded->name;
             }
         }
+
+        // 3.1) If loaded filaments are invisible/non-instaled, set them as visible
+        for (const std::string& filament : this->filament_presets) {
+            Preset* preset = this->filaments.find_preset(filament);
+            if (preset && !preset->is_visible) {
+                preset->is_visible = true;
+                if (preset->name == this->filaments.m_edited_preset.name)
+                    this->filaments.get_selected_preset().is_visible = true;
+            }
+        }
+
         // 4) Load the project config values (the per extruder wipe matrix etc).
         this->project_config.apply_only(config, s_project_options);
 

From 5e78b0f24f17380653ea299da561b7b7b0041711 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Mon, 1 Mar 2021 18:21:27 +0100
Subject: [PATCH 43/53] creality.ini: remove ignored renamed_from from
 *descendingz*

fixes: Nonpublic intermediate preset *descendingz* contains a "renamed_from" field, which is ignored
---
 resources/profiles/Creality.ini | 1 -
 1 file changed, 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 62d0d837f..d0e2bac3b 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -799,7 +799,6 @@ pause_print_gcode = M25 ; pause print
 
 # Intended for printers where the Z-axis lowers the print bed during printing, like the Ender-5 series
 [printer:*descendingz*]
-renamed_from = "*invertedz*"
 end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; move print head out of the way\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed close to the bottom\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors
 
 # Intended for printers with dual extruders and a single hotend/nozzle, like the CR-X series

From f5863cd5d89a271178cb0e07264d493be5f61119 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Mon, 1 Mar 2021 18:24:44 +0100
Subject: [PATCH 44/53] creality.ini: CR-200B also has a descending z axis

---
 resources/profiles/Creality.ini | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index d0e2bac3b..b7c0f4e96 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -1017,7 +1017,7 @@ printer_model = CR20PRO
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR20PRO\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-200B]
-#inherits = *common*
+#inherits = *common*; *descendingz*
 #bed_shape = 5x5,195x5,195x195,5x195
 #max_print_height = 200
 #printer_model = CR200B

From 586ed35e3a688500c05b1823b8b795845622c6d3 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Mon, 1 Mar 2021 18:34:18 +0100
Subject: [PATCH 45/53] creality.ini: fix CR-5 Pro bed_shape

---
 resources/profiles/Creality.ini | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index b7c0f4e96..f68d067d3 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -906,7 +906,7 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 #[printer:Creality CR-5 Pro]
 #inherits = *common*; *slowabl*; *descendingz*
 #retract_length = 3
-#bed_shape = 5x5,295x5,295x215,5x215
+#bed_shape = 5x5,295x5,295x220,5x220
 #max_print_height = 380
 #printer_model = CR5PRO
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PRO\nPRINTER_HAS_BOWDEN

From 7fbb3a2b420910e7ce3cabbe44bfcf576b69a176 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Mon, 1 Mar 2021 18:40:33 +0100
Subject: [PATCH 46/53] creality.ini: Add CR-5 Pro H

this is a high temp variant of the regular CR-5 Pro, with the
suspected all metal hotend, presumably the non-H variant has
a teflon lined hotend

related: 2d762ec3202e9d7e400db4b20e3e5630098f6a19
---
 resources/profiles/Creality.ini               |  19 +++++++++++++++++-
 .../profiles/Creality/CR5PROH_thumbnail.png   | Bin 0 -> 38706 bytes
 2 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 resources/profiles/Creality/CR5PROH_thumbnail.png

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index f68d067d3..423daef0f 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -104,6 +104,15 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
 #bed_texture = cr5pro.svg
 #default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
+#[printer_model:CR5PROH]
+#name = Creality CR-5 Pro H
+#variants = 0.4
+#technology = FFF
+#family = CR
+#bed_model = cr5pro_bed.stl
+#bed_texture = cr5pro.svg
+#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+
 #[printer_model:CR6SE]
 #name = Creality CR-6 SE
 #variants = 0.4
@@ -905,12 +914,20 @@ printer_notes = Don't remove the following keywords! These keywords are used in
 
 #[printer:Creality CR-5 Pro]
 #inherits = *common*; *slowabl*; *descendingz*
-#retract_length = 3
+#retract_length = 6
 #bed_shape = 5x5,295x5,295x220,5x220
 #max_print_height = 380
 #printer_model = CR5PRO
 #printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PRO\nPRINTER_HAS_BOWDEN
 
+#[printer:Creality CR-5 Pro H]
+#inherits = *common*; *slowabl*; *descendingz*
+#retract_length = 3
+#bed_shape = 5x5,295x5,295x220,5x220
+#max_print_height = 380
+#printer_model = CR5PROH
+#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PROH\nPRINTER_HAS_BOWDEN
+
 #[printer:Creality CR-6 SE]
 #inherits = *common*; *fastabl*; *pauseprint*
 #bed_shape = 5x0,230x0,230x235,5x235
diff --git a/resources/profiles/Creality/CR5PROH_thumbnail.png b/resources/profiles/Creality/CR5PROH_thumbnail.png
new file mode 100644
index 0000000000000000000000000000000000000000..df2f1b665f2f7a3d7d5e45ff3bb29a4fb674bdfe
GIT binary patch
literal 38706
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

literal 0
HcmV?d00001


From 5276bd98d7afaf953138d5e46963d9b4fab044c6 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Mon, 1 Mar 2021 18:41:36 +0100
Subject: [PATCH 47/53] WIP: MutablePolygon - linked list based polygon
 implementation allowing rapid insertion and removal of points. WIP: porting
 smooth_outward() from Cura.

---
 src/libslic3r/CMakeLists.txt             |   2 +
 src/libslic3r/MutablePolygon.cpp         | 242 +++++++++++++++++++++++
 src/libslic3r/MutablePolygon.hpp         | 227 +++++++++++++++++++++
 src/libslic3r/Point.hpp                  |  20 +-
 tests/libslic3r/CMakeLists.txt           |   1 +
 tests/libslic3r/test_mutable_polygon.cpp | 145 ++++++++++++++
 6 files changed, 632 insertions(+), 5 deletions(-)
 create mode 100644 src/libslic3r/MutablePolygon.cpp
 create mode 100644 src/libslic3r/MutablePolygon.hpp
 create mode 100644 tests/libslic3r/test_mutable_polygon.cpp

diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index 1267e216c..6159b2c5c 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -145,6 +145,8 @@ add_library(libslic3r STATIC
     Point.hpp
     Polygon.cpp
     Polygon.hpp
+    MutablePolygon.cpp
+    MutablePolygon.hpp
     PolygonTrimmer.cpp
     PolygonTrimmer.hpp
     Polyline.cpp
diff --git a/src/libslic3r/MutablePolygon.cpp b/src/libslic3r/MutablePolygon.cpp
new file mode 100644
index 000000000..951485259
--- /dev/null
+++ b/src/libslic3r/MutablePolygon.cpp
@@ -0,0 +1,242 @@
+#include "MutablePolygon.hpp"
+#include "Line.hpp"
+
+namespace Slic3r {
+
+// Remove exact duplicate points. May reduce the polygon down to empty polygon.
+void remove_duplicates(MutablePolygon &polygon)
+{
+    if (! polygon.empty()) {
+        auto begin = polygon.begin();
+        auto it    = begin;
+        for (++ it; it != begin;) {
+            auto prev = it.prev();
+            if (*prev == *it)
+                it = it.remove();
+            else
+                ++ it;
+        }
+    }
+}
+
+// Remove nearly duplicate points. May reduce the polygon down to empty polygon.
+void remove_duplicates(MutablePolygon &polygon, double eps)
+{
+    if (! polygon.empty()) {
+        auto eps2 = eps * eps;
+        auto begin = polygon.begin();
+        auto it = begin;
+        for (++ it; it != begin;) {
+            auto prev = it.prev();
+            if ((*it - *prev).cast<double>().squaredNorm() < eps2)
+                it = it.remove();
+            else
+                ++ it;
+        }
+    }
+}
+
+// Sample a point on line (a, b) at distance "dist" from ref_pt.
+// If two points fulfill the condition, then the first one (closer to point a) is taken.
+// If none of the two points falls on line (a, b), return false.
+template<typename VectorType>
+static inline VectorType point_on_line_at_dist(const VectorType &a, const VectorType &b, const VectorType &ref_pt, const double dist)
+{
+    using T = typename VectorType::Scalar;
+    auto   v   = b - a;
+    auto   l2  = v.squaredNorm();
+    assert(l2 > T(0));
+    auto   vpt = ref_pt - a;
+    // Parameter of the foot point of ref_pt on line (a, b).
+    auto   t   = v.dot(vpt) / l2;
+    // Foot point of ref_pt on line (a, b).
+    auto   foot_pt = a + t * v;
+    auto   dfoot2 = vpt.squaredNorm() - (foot_pt - ref_pt).squaredNorm();
+    // Distance of the result point from the foot point, normalized to length of (a, b).
+    auto   dfoot  = dfoot2 > T(0) ? sqrt(dfoot2) / sqrt(l2) : T(0);
+    auto   t_result = t - dfoot;
+    if (t_result < T(0))
+        t_result = t + dfoot;
+    t_result = Slic3r::clamp(0., 1., t_result);
+    return a + v * t;
+}
+
+static bool smooth_corner_complex(const Vec2d p1, MutablePolygon::iterator &it0, MutablePolygon::iterator &it2, const double shortcut_length)
+{
+    // walk away from the corner until the shortcut > shortcut_length or it would smooth a piece inward
+    // - walk in both directions untill shortcut > shortcut_length
+    // - stop walking in one direction if it would otherwise cut off a corner in that direction
+    // - same in the other direction
+    // - stop if both are cut off
+    // walk by updating p0_it and p2_it
+    double shortcut_length2    = shortcut_length * shortcut_length;
+    bool   forward_is_blocked  = false;
+    bool   forward_is_too_far  = false;
+    bool   backward_is_blocked = false;
+    bool   backward_is_too_far = false;
+    for (;;) {
+        const bool forward_has_converged  = forward_is_blocked  || forward_is_too_far;
+        const bool backward_has_converged = backward_is_blocked || backward_is_too_far;
+        if (forward_has_converged && backward_has_converged) {
+            if (forward_is_too_far && backward_is_too_far && (*it0.prev() - *it2.next()).cast<double>().squaredNorm() < shortcut_length2) {
+                // Trim the narrowing region.
+                -- it0;
+                ++ it2;
+                forward_is_too_far  = false;
+                backward_is_too_far = false;
+                continue;
+            } else
+                break;
+        }
+
+        const Vec2d p0 = it0->cast<double>();
+        const Vec2d p2 = it2->cast<double>();
+        if (! forward_has_converged && (backward_has_converged || (p2 - p1).squaredNorm() < (p0 - p1).squaredNorm())) {
+            // walk forward
+            const auto  it2_2 = it2.next();
+            const Vec2d p2_2  = it2_2->cast<double>();
+            if (cross2(p2 - p0, p2_2 - p0) > 0) {
+                forward_is_blocked  = true;
+            } else if ((p2_2 - p0).squaredNorm() > shortcut_length2) {
+                forward_is_too_far  = true;
+            } else {
+                it2                 = it2_2; // make one step in the forward direction
+                backward_is_blocked = false; // invalidate data about backward walking
+                backward_is_too_far = false;
+            }
+        } else {
+            // walk backward
+            const auto  it0_2 = it0.prev();
+            const Vec2d p0_2  = it0_2->cast<double>();
+            if (cross2(p0_2 - p0, p2 - p0_2) > 0) {
+                backward_is_blocked = true;
+            } else if ((p2 - p0_2).squaredNorm() > shortcut_length2) {
+                backward_is_too_far = true;
+            } else {
+                it0                = it0_2; // make one step in the backward direction
+                forward_is_blocked = false; // invalidate data about forward walking
+                forward_is_too_far = false;
+            }
+        }
+
+        if (it0.prev() == it2 || it0 == it2) {
+            // stop if we went all the way around the polygon
+            // this should only be the case for hole polygons (?)
+            if (forward_is_too_far && backward_is_too_far) {
+                // in case p0_it.prev() == p2_it :
+                //     /                                                .
+                //    /                /|
+                //   |       becomes  | |
+                //    \                \|
+                //     \                                                .
+                // in case p0_it == p2_it :
+                //     /                                                .
+                //    /    becomes     /|
+                //    \                \|
+                //     \                                                .
+                break;
+            } else {
+                // this whole polygon can be removed
+                return true;
+            }
+        }
+    }
+
+    const Vec2d   p0     = it0->cast<double>();
+    const Vec2d   p2     = it2->cast<double>();
+    const Vec2d   v02    = p2 - p0;
+    const int64_t l2_v02 = v02.squaredNorm();
+    if (std::abs(l2_v02 - shortcut_length2) < shortcut_length * 10) // i.e. if (size2 < l * (l+10) && size2 > l * (l-10))
+    { // v02 is approximately shortcut length
+        // handle this separately to avoid rounding problems below in the getPointOnLineWithDist function
+        // p0_it and p2_it are already correct
+    } else if (! backward_is_blocked && ! forward_is_blocked) {
+        const auto  l_v02 = sqrt(l2_v02);
+        const Vec2d p0_2  = it0.prev()->cast<double>();
+        const Vec2d p2_2  = it2.next()->cast<double>();
+        double t = Slic3r::clamp(0., 1., (shortcut_length - l_v02) / ((p2_2 - p0_2).norm() - l_v02));
+        it0 = it0.prev().insert((p0 + (p0_2 - p0) * t).cast<coord_t>());
+        it2 = it2.insert((p2 + (p2_2 - p2) * t).cast<coord_t>());
+    } else if (! backward_is_blocked) {
+        it0 = it0.prev().insert(point_on_line_at_dist(p0, Vec2d(it0.prev()->cast<double>()), p2, shortcut_length).cast<coord_t>());
+    } else if (! forward_is_blocked) {
+        it2 = it2.insert(point_on_line_at_dist(p2, Vec2d(it2.next()->cast<double>()), p0, shortcut_length).cast<coord_t>());
+    } else {
+        //        |
+        //      __|2
+        //     | /  > shortcut cannot be of the desired length
+        //  ___|/                                                       .
+        //     0
+        // both are blocked and p0_it and p2_it are already correct
+    }
+    // Delete all the points between it0 and it2.
+    while (it0.next() != it2)
+        it0.next().remove();
+    return false;
+}
+
+void smooth_outward(MutablePolygon &polygon, double shortcut_length)
+{
+    remove_duplicates(polygon, scaled<double>(0.01));
+
+    const int                     shortcut_length2 = shortcut_length * shortcut_length;
+    static constexpr const double cos_min_angle    = -0.70710678118654752440084436210485; // cos(135 degrees)
+
+    MutablePolygon::iterator it1 = polygon.begin();
+    do {
+        const Vec2d p1  = it1->cast<double>();
+        auto        it0 = it1.prev();
+        auto        it2 = it1.next();
+        const Vec2d p0  = it0->cast<double>();
+        const Vec2d p2  = it2->cast<double>();
+        const Vec2d v1  = p0 - p1;
+        const Vec2d v2  = p2 - p1;
+        const double cos_angle = v1.dot(v2);
+        if (cos_angle < cos_min_angle && cross2(v1, v2) < 0) {
+            // Simplify the sharp angle.
+            const Vec2d  v02   = p2 - p0;
+            const double l2_v02 = v02.squaredNorm();
+            if (l2_v02 >= shortcut_length2) {
+                // Trim an obtuse corner.
+                it1.remove();
+                if (l2_v02 > Slic3r::sqr(shortcut_length + SCALED_EPSILON)) {
+                    double l2_1 = v1.squaredNorm();
+                    double l2_2 = v2.squaredNorm();
+                    bool trim = true;
+                    if (cos_angle > 0.9999) {
+                        // The triangle p0, p1, p2 is likely degenerate.
+                        // Measure height of the triangle.
+                        double d2 = l2_1 > l2_2 ? line_alg::distance_to_squared(Linef{ p0, p1 }, p2) : line_alg::distance_to_squared(Linef{ p2, p1 }, p0);
+                        if (d2 < Slic3r::sqr(scaled<double>(0.02)))
+                            trim = false;
+                    }
+                    if (trim) {
+                        Vec2d  bisector  = v1 / l2_1 + v2 / l2_2;
+                        double d1        = v1.dot(bisector) / l2_1;
+                        double d2        = v2.dot(bisector) / l2_2;
+                        double lbisector = bisector.norm();
+                        if (d1 < shortcut_length && d2 < shortcut_length) {
+                            it0.insert((p1 + v1 * (shortcut_length / d1)).cast<coord_t>())
+                               .insert((p1 + v2 * (shortcut_length / d2)).cast<coord_t>());
+                        } else if (v1.squaredNorm() < v2.squaredNorm())
+                            it0.insert(point_on_line_at_dist(p1, p2, p0, shortcut_length).cast<coord_t>());
+                        else
+                            it0.insert(point_on_line_at_dist(p1, p0, p2, shortcut_length).cast<coord_t>());
+                    }
+                }
+            } else {
+                bool remove_poly = smooth_corner_complex(p1, it0, it2, shortcut_length); // edits p0_it and p2_it!
+                if (remove_poly) {
+                    // don't convert ListPolygon into result
+                    return;
+                }
+            }
+            // update:
+            it1 = it2; // next point to consider for whether it's an internal corner
+        }
+        else
+            ++ it1;
+    } while (it1 != polygon.begin());
+}
+
+} // namespace Slic3r
diff --git a/src/libslic3r/MutablePolygon.hpp b/src/libslic3r/MutablePolygon.hpp
new file mode 100644
index 000000000..b699a25ed
--- /dev/null
+++ b/src/libslic3r/MutablePolygon.hpp
@@ -0,0 +1,227 @@
+#ifndef slic3r_MutablePolygon_hpp_
+#define slic3r_MutablePolygon_hpp_
+
+#include "Point.hpp"
+#include "Polygon.hpp"
+
+namespace Slic3r {
+
+class MutablePolygon
+{
+public:
+    using IndexType = int32_t;
+    using PointType = Point;
+    class const_iterator {
+    public:
+        bool             operator==(const const_iterator &rhs) const { assert(m_data == rhs.m_data); assert(this->valid()); return m_idx == rhs.m_idx; }
+        bool             operator!=(const const_iterator &rhs) const { return ! (*this == rhs); }
+        const_iterator&  operator--()    { assert(this->valid()); m_idx = m_data->at(m_idx).prev; return *this; }
+        const_iterator   operator--(int) { const_iterator result(*this); --(*this); return result; }
+        const_iterator&  operator++()    { assert(this->valid()); m_idx = m_data->at(m_idx).next; return *this; }
+        const_iterator   operator++(int) { const_iterator result(*this); ++(*this); return result; }
+        const_iterator   prev()    const { assert(this->valid()); return { m_data, m_data->at(m_idx).prev }; }
+        const_iterator   next()    const { assert(this->valid()); return { m_data, m_data->at(m_idx).next }; }
+        bool             valid()   const { return m_idx >= 0; }
+        const PointType& operator*() const { return m_data->at(m_idx).point; }
+        const PointType* operator->() const { return &m_data->at(m_idx).point; }
+        const MutablePolygon& polygon() const { assert(this->valid()); m_data; }
+        IndexType        size()    const { assert(this->valid()); m_data->size(); }
+    private:
+        const_iterator(const MutablePolygon *data, IndexType idx) : m_data(data), m_idx(idx) {}
+        friend class MutablePolygon;
+        const MutablePolygon  *m_data;
+        IndexType              m_idx;
+    };
+
+    class iterator {
+    public:
+        bool            operator==(const iterator &rhs) const { assert(m_data == rhs.m_data); assert(this->valid()); return m_idx == rhs.m_idx; }
+        bool            operator!=(const iterator &rhs) const { return !(*this == rhs); }
+        iterator&       operator--()    { assert(this->valid()); m_idx = m_data->at(m_idx).prev; return *this; }
+        iterator        operator--(int) { iterator result(*this); --(*this); return result; }
+        iterator&       operator++()    { assert(this->valid()); m_idx = m_data->at(m_idx).next; return *this; }
+        iterator        operator++(int) { iterator result(*this); ++(*this); return result; }
+        iterator        prev()    const { assert(this->valid()); return { m_data, m_data->at(m_idx).prev }; }
+        iterator        next()    const { assert(this->valid()); return { m_data, m_data->at(m_idx).next }; }
+        bool            valid()   const { return m_idx >= 0; }
+        PointType&      operator*() const { return m_data->at(m_idx).point; }
+        PointType*      operator->() const { return &m_data->at(m_idx).point; }
+        MutablePolygon& polygon() const { assert(this->valid()); m_data; }
+        IndexType       size()    const { assert(this->valid()); m_data->size(); }
+        iterator&       remove()        { this->m_idx = m_data->remove(*this).m_idx; return *this; }
+        iterator        insert(const PointType pt) const { return m_data->insert(*this, pt); }
+    private:
+        iterator(MutablePolygon *data, IndexType idx) : m_data(data), m_idx(idx) {}
+        friend class MutablePolygon;
+        MutablePolygon  *m_data;
+        IndexType        m_idx;
+    };
+
+    MutablePolygon() = default;
+    MutablePolygon(const Polygon &rhs, size_t reserve = 0) : MutablePolygon(rhs.points.begin(), rhs.points.end(), reserve) {}
+    MutablePolygon(std::initializer_list<Point> rhs, size_t reserve = 0) : MutablePolygon(rhs.begin(), rhs.end(), reserve) {}
+
+    template<typename IT>
+    MutablePolygon(IT begin, IT end, size_t reserve = 0) {
+        m_size = IndexType(end - begin);
+        if (m_size > 0) {
+            m_head = 0;
+            m_data.reserve(std::max<size_t>(m_size, reserve));
+            auto i = IndexType(-1);
+            auto j = IndexType(1);
+            for (auto it = begin; it != end; ++ it)
+                m_data.push_back({ *it, i ++, j ++ });
+            m_data.front().prev = m_size - 1;
+            m_data.back ().next = 0;
+        }
+    };
+
+    Polygon polygon() const {
+        Polygon out;
+        if (this->valid()) {
+            out.points.reserve(this->size());
+            for (auto it = this->cbegin(); it != this->cend(); ++ it)
+                out.points.emplace_back(*it);
+        }
+        return out;
+    };
+
+    bool            empty()  const { return this->m_size == 0; }
+    size_t          size()   const { return this->m_size; }
+    size_t          capacity() const { return this->m_data.capacity(); }
+    bool            valid()  const { return this->m_size >= 3; }
+
+    iterator        begin()        { return { this, m_head }; }
+    const_iterator  cbegin() const { return { this, m_head }; }
+    const_iterator  begin()  const { return this->cbegin(); }
+    // End points to the last item before roll over. This is different from the usual end() concept!
+    iterator        end()          { return { this, this->empty() ? -1 : this->at(m_head).prev }; }
+    const_iterator  cend()   const { return { this, this->empty() ? -1 : this->at(m_head).prev }; }
+    const_iterator  end()    const { return this->cend(); }
+
+    // Returns iterator following the removed element. Returned iterator will become invalid if last point is removed.
+    // If begin() is removed, then the next element will become the new begin().
+    iterator        remove(const iterator it) { assert(it.m_data == this); return { this, this->remove(it.m_idx) }; }
+    // Insert a new point before it. Returns iterator to the newly inserted point.
+    // begin() will not change, end() may point to the newly inserted point.
+    iterator        insert(const iterator it, const PointType pt) { assert(it.m_data == this); return { this, this->insert(it.m_idx, pt) }; }
+
+private:
+    struct LinkedPoint {
+        PointType point;
+        IndexType prev;
+        IndexType next;
+    };
+    std::vector<LinkedPoint>    m_data;
+    // Number of points in the linked list.
+    IndexType                   m_size { 0 };
+    IndexType                   m_head { IndexType(-1) };
+    // Head of the free list.
+    IndexType                   m_head_free { IndexType(-1) };
+
+    LinkedPoint&          at(IndexType i)       { return m_data[i]; }
+    const LinkedPoint&    at(IndexType i) const { return m_data[i]; }
+
+    IndexType remove(const IndexType i) {
+        assert(i >= 0);
+        assert(m_size > 0);
+        assert(m_head != -1);
+        LinkedPoint &lp = this->at(i);
+        IndexType prev = lp.prev;
+        IndexType next = lp.next;
+        lp.next = m_head_free;
+        m_head_free = i;
+        if (-- m_size == 0)
+            m_head = -1;
+        else if (m_head == i)
+            m_head = next;
+        assert(! this->empty() || (prev == i && next == i));
+        if (this->empty())
+            return IndexType(-1);
+        this->at(prev).next = next;
+        this->at(next).prev = prev;
+        return next;
+    }
+
+    IndexType insert(const IndexType i, const Point pt) {
+        assert(i >= 0);
+        IndexType n;
+        IndexType j = this->at(i).prev;
+        if (m_head_free == -1) {
+            // Allocate a new item.
+            n = IndexType(m_data.size());
+            m_data.push_back({ pt, j, i });
+        } else {
+            n = m_head_free;
+            LinkedPoint &nlp = this->at(n);
+            m_head_free = nlp.next;
+            nlp = { pt, j, i };
+        }
+        this->at(j).next = n;
+        this->at(i).prev = n;
+        ++ m_size;
+        return n;
+    }
+
+    /*
+    IndexType insert(const IndexType i, const Point pt) {
+        assert(i >= 0);
+        if (this->at(i).point == pt)
+            return i;
+        IndexType j = this->at(i).next;
+        if (this->at(j).point == pt)
+            return i;
+        IndexType n;
+        if (m_head_free == -1) {
+            // Allocate a new item.
+            n = IndexType(m_data.size());
+            m_data.push_back({ pt, i, j });
+        } else {
+            LinkedPoint &nlp = this->at(m_head_free);
+            m_head_free = nlp.next;
+            nlp = { pt, i, j };
+        }
+        this->at(i).next = n;
+        this->at(j).prev = n;
+        ++ m_size;
+        return n;
+    }
+    */
+};
+
+inline bool operator==(const MutablePolygon &p1, const MutablePolygon &p2) 
+{ 
+    if (p1.size() != p2.size())
+        return false;
+    if (p1.empty())
+        return true;
+    auto begin = p1.cbegin();
+    auto it  = begin;
+    auto it2 = p2.cbegin();
+    for (;;) {
+        if (! (*it == *it2))
+            return false;
+        if (++ it == begin)
+            return true;
+        ++ it2;
+    }
+}
+
+inline bool operator!=(const MutablePolygon &p1, const MutablePolygon &p2) { return ! (p1 == p2); }
+
+// Remove exact duplicate points. May reduce the polygon down to empty polygon.
+void remove_duplicates(MutablePolygon &polygon);
+void remove_duplicates(MutablePolygon &polygon, double eps);
+
+void smooth_outward(MutablePolygon &polygon, double shortcut_length);
+
+inline Polygon smooth_outward(const Polygon &polygon, double shortcut_length) 
+{ 
+    MutablePolygon mp(polygon, polygon.size() * 2);
+    smooth_outward(mp, shortcut_length);
+    return mp.polygon();
+}
+
+}
+
+#endif // slic3r_MutablePolygon_hpp_
diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp
index d11af8b58..84b4a825d 100644
--- a/src/libslic3r/Point.hpp
+++ b/src/libslic3r/Point.hpp
@@ -56,11 +56,21 @@ typedef Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign> Transform3d
 
 inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
 
-// One likely does not want to perform the cross product with a 32bit accumulator.
-//inline int32_t cross2(const Vec2i32 &v1, const Vec2i32 &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
-inline int64_t cross2(const Vec2i64 &v1, const Vec2i64 &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
-inline float   cross2(const Vec2f   &v1, const Vec2f   &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
-inline double  cross2(const Vec2d   &v1, const Vec2d   &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+template<int Options>
+int32_t cross2(const Eigen::MatrixBase<Eigen::Matrix<int32_t, 2, 1, Options>> &v1, const Eigen::MatrixBase<Eigen::Matrix<int32_t, 2, 1, Options>> &v2) = delete;
+
+template<typename T, int Options>
+inline T cross2(const Eigen::MatrixBase<Eigen::Matrix<T, 2, 1, Options>> &v1, const Eigen::MatrixBase<Eigen::Matrix<T, 2, 1, Options>> &v2)
+{
+    return v1(0) * v2(1) - v1(1) * v2(0);
+}
+
+template<typename Derived, typename Derived2>
+inline typename Derived::Scalar cross2(const Eigen::MatrixBase<Derived> &v1, const Eigen::MatrixBase<Derived2> &v2)
+{
+    static_assert(std::is_same<typename Derived::Scalar, typename Derived2::Scalar>::value, "cross2(): Scalar types of 1st and 2nd operand must be equal.");
+    return v1(0) * v2(1) - v1(1) * v2(0);
+}
 
 template<typename T, int Options>
 inline Eigen::Matrix<T, 2, 1, Eigen::DontAlign> perp(const Eigen::MatrixBase<Eigen::Matrix<T, 2, 1, Options>> &v) { return Eigen::Matrix<T, 2, 1, Eigen::DontAlign>(- v.y(), v.x()); }
diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt
index 501af0c6f..f93cf10af 100644
--- a/tests/libslic3r/CMakeLists.txt
+++ b/tests/libslic3r/CMakeLists.txt
@@ -11,6 +11,7 @@ add_executable(${_TEST_NAME}_tests
 	test_geometry.cpp
 	test_placeholder_parser.cpp
 	test_polygon.cpp
+	test_mutable_polygon.cpp
 	test_stl.cpp
 	test_meshsimplify.cpp
 	test_meshboolean.cpp
diff --git a/tests/libslic3r/test_mutable_polygon.cpp b/tests/libslic3r/test_mutable_polygon.cpp
new file mode 100644
index 000000000..2214da6ef
--- /dev/null
+++ b/tests/libslic3r/test_mutable_polygon.cpp
@@ -0,0 +1,145 @@
+#include <catch2/catch.hpp>
+
+#include "libslic3r/MutablePolygon.hpp"
+
+using namespace Slic3r;
+
+SCENARIO("Iterators", "[MutablePolygon]") {
+    GIVEN("Polygon with three points") {
+        Slic3r::MutablePolygon p({ { 0, 0 }, { 0, 1 }, { 1, 0 } });
+        WHEN("Iterating upwards") {
+            auto begin = p.begin();
+            auto end   = p.end();
+            auto it    = begin;
+            THEN("++ it is not equal to begin") { 
+                REQUIRE(++ it != begin);
+            } THEN("++ it is not equal to end")   { 
+                REQUIRE(++ it != end);
+            } THEN("++ (++ it) is not equal to begin") { 
+                REQUIRE(++ (++ it) != begin);
+            } THEN("++ (++ it) is equal to end") { 
+                REQUIRE(++ (++ it) == end);
+            } THEN("++ (++ (++ it)) is equal to begin") { 
+                REQUIRE(++ (++ (++ it)) == begin);
+            } THEN("++ (++ (++ it)) is not equal to end") { 
+                REQUIRE(++ (++ (++ it)) != end);
+            } 
+        }
+        WHEN("Iterating downwards") {
+            auto begin = p.begin();
+            auto end = p.end();
+            auto it = begin;
+            THEN("-- it is not equal to begin") {
+                REQUIRE(-- it != begin);
+            } THEN("-- it is equal to end") {
+                REQUIRE(-- it == end);
+            } THEN("-- (-- it) is not equal to begin") {
+                REQUIRE(-- (-- it) != begin);
+            } THEN("-- (-- it) is not equal to end") {
+                REQUIRE(-- (-- it) != end);
+            } THEN("-- (-- (-- it)) is equal to begin") {
+                REQUIRE(-- (-- (-- it)) == begin);
+            } THEN("-- (-- (-- it)) is not equal to end") {
+                REQUIRE(-- (-- (-- it)) != end);
+            }
+        }
+        WHEN("Deleting 1st point") {
+            auto it_2nd = p.begin().next();
+            auto it_3rd = p.end();
+            auto it     = p.begin().remove();
+            THEN("Size is 2") {
+                REQUIRE(p.size() == 2);
+            } THEN("p.begin().remove() == it_2nd") {
+                REQUIRE(it == it_2nd);
+            } THEN("it_2nd == new begin()") {
+                REQUIRE(it_2nd == p.begin());
+            }
+        }
+        WHEN("Deleting 2nd point") {
+            auto it_1st = p.begin();
+            auto it_2nd = it_1st.next();
+            auto it_3rd = p.end();
+            auto it = it_2nd.remove();
+            THEN("Size is 2") {
+                REQUIRE(p.size() == 2);
+                REQUIRE(! p.empty());
+            } THEN("it_2nd.remove() == it_3rd") {
+                REQUIRE(it == it_2nd);
+            } THEN("it_1st == new begin()") {
+                REQUIRE(it_1st == p.begin());
+            }
+        }
+        WHEN("Deleting two points") {
+            p.begin().remove().remove();
+            THEN("Size is 1") {
+                REQUIRE(p.size() == 1);
+            } THEN("p.begin().next() == p.begin()") {
+                REQUIRE(p.begin().next() == p.begin());
+            } THEN("p.begin().prev() == p.begin()") {
+                REQUIRE(p.begin().prev() == p.begin());
+            }
+        }
+        WHEN("Deleting all points") {
+            auto it = p.begin().remove().remove().remove();
+            THEN("Size is 0") {
+                REQUIRE(p.size() == 0);
+                REQUIRE(p.empty());
+            } THEN("! p.begin().valid()") {
+                REQUIRE(!p.begin().valid());
+            } THEN("last iterator not valid") {
+                REQUIRE(! it.valid());
+            }
+        }
+        WHEN("Inserting a point at the beginning") {
+            p.insert(p.begin(), { 3, 4 });
+            THEN("Polygon content is ok") {
+                REQUIRE(p == MutablePolygon{ { 0, 0 }, { 0, 1 }, { 1, 0 }, { 3, 4 } });
+            }
+        }
+        WHEN("Inserting a point at the 2nd position") {
+            p.insert(++ p.begin(), { 3, 4 });
+            THEN("Polygon content is ok") {
+                REQUIRE(p == MutablePolygon{ { 0, 0 }, { 3, 4 }, { 0, 1 }, { 1, 0 } });
+            }
+        } WHEN("Inserting a point after a point was removed") {
+            size_t capacity = p.capacity();
+            THEN("Initial capacity is 3") {
+                REQUIRE(capacity == 3);
+            }
+            p.begin().remove();
+            THEN("After removal of the 1st point the capacity is still 3") {
+                REQUIRE(p.capacity() == 3);
+            }
+            THEN("After removal of the 1st point the content is ok") {
+                REQUIRE(p == MutablePolygon{ { 0, 1 }, { 1, 0 } });
+            }
+            p.insert(p.begin(), { 5, 6 });
+            THEN("After insertion at head position the polygon content is ok") {
+                REQUIRE(p == MutablePolygon{ { 0, 1 }, { 1, 0 }, { 5, 6 } });
+            } THEN("and the capacity is still 3") {
+                REQUIRE(p.capacity() == 3);
+            }
+        }
+    }
+}
+
+SCENARIO("Remove degenerate points from MutablePolygon", "[MutablePolygon]") {
+    GIVEN("Polygon with duplicate points"){
+        Slic3r::MutablePolygon p({
+            { 0, 0 },
+            { 0, 100 }, { 0, 100 }, { 0, 100 },
+            { 0, 150 },
+            { 0, 200 },
+            { 200, 200 },
+            { 180, 200 }, { 180, 200 },
+            { 180, 20 },
+            { 180, 0 },
+        });
+        WHEN("Duplicate points are removed") {
+            remove_duplicates(p);
+            THEN("Polygon content is ok") {
+                REQUIRE(p == Slic3r::MutablePolygon{ { 0, 0 }, { 0, 100 }, { 0, 150 }, { 0, 200 }, { 200, 200 }, { 180, 200 }, { 180, 20 }, { 180, 0 } });
+            }
+        }
+    }
+}

From 065a129d474e0d684d986fa49f1192dc5f14fbd1 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Mon, 1 Mar 2021 18:43:40 +0100
Subject: [PATCH 48/53] creality.ini: remove
 single_extruder_multi_material_priming from printer section

---
 resources/profiles/Creality.ini | 1 -
 1 file changed, 1 deletion(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index 423daef0f..b42be5597 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -813,7 +813,6 @@ end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2,
 # Intended for printers with dual extruders and a single hotend/nozzle, like the CR-X series
 [printer:*dualextruder*]
 single_extruder_multi_material = 1
-single_extruder_multi_material_priming = 0
 cooling_tube_length = 5
 cooling_tube_retraction = 91.5
 extra_loading_move = -2

From 45cbac0b7c165a245bcb2f55c0b5768c5c248566 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Mon, 1 Mar 2021 19:00:04 +0100
Subject: [PATCH 49/53] creality.ini: unhide new printers (except CR-X)

---
 resources/profiles/Creality.ini | 288 ++++++++++++++++----------------
 1 file changed, 144 insertions(+), 144 deletions(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index b42be5597..f3f5836de 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -41,23 +41,23 @@ bed_model = ender3v2_bed.stl
 bed_texture = ender3v2.svg
 default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:ENDER3MAX]
-#name = Creality Ender-3 Max
-#variants = 0.4
-#technology = FFF
-#family = ENDER
-#bed_model = cr10v2_bed.stl
-#bed_texture = cr10spro.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:ENDER3MAX]
+name = Creality Ender-3 Max
+variants = 0.4
+technology = FFF
+family = ENDER
+bed_model = cr10v2_bed.stl
+bed_texture = cr10spro.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:ENDER4]
-#name = Creality Ender-4
-#variants = 0.4
-#technology = FFF
-#family = ENDER
-#bed_model = ender3v2_bed.stl
-#bed_texture = ender3v2.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:ENDER4]
+name = Creality Ender-4
+variants = 0.4
+technology = FFF
+family = ENDER
+bed_model = ender3v2_bed.stl
+bed_texture = ender3v2.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
 [printer_model:ENDER5]
 name = Creality Ender-5
@@ -77,14 +77,14 @@ bed_model = ender5plus_bed.stl
 bed_texture = ender5plus.svg
 default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:ENDER6]
-#name = Creality Ender-6
-#variants = 0.4
-#technology = FFF
-#family = ENDER
-#bed_model = ender6_bed.stl
-#bed_texture = ender6.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:ENDER6]
+name = Creality Ender-6
+variants = 0.4
+technology = FFF
+family = ENDER
+bed_model = ender6_bed.stl
+bed_texture = ender6.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
 [printer_model:ENDER2]
 name = Creality Ender-2
@@ -95,41 +95,41 @@ bed_model = ender2_bed.stl
 bed_texture = ender2.svg
 default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:CR5PRO]
-#name = Creality CR-5 Pro
-#variants = 0.4
-#technology = FFF
-#family = CR
-#bed_model = cr5pro_bed.stl
-#bed_texture = cr5pro.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:CR5PRO]
+name = Creality CR-5 Pro
+variants = 0.4
+technology = FFF
+family = CR
+bed_model = cr5pro_bed.stl
+bed_texture = cr5pro.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:CR5PROH]
-#name = Creality CR-5 Pro H
-#variants = 0.4
-#technology = FFF
-#family = CR
-#bed_model = cr5pro_bed.stl
-#bed_texture = cr5pro.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:CR5PROH]
+name = Creality CR-5 Pro H
+variants = 0.4
+technology = FFF
+family = CR
+bed_model = cr5pro_bed.stl
+bed_texture = cr5pro.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:CR6SE]
-#name = Creality CR-6 SE
-#variants = 0.4
-#technology = FFF
-#family = CR
-#bed_model = cr6se_bed.stl
-#bed_texture = cr6se.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:CR6SE]
+name = Creality CR-6 SE
+variants = 0.4
+technology = FFF
+family = CR
+bed_model = cr6se_bed.stl
+bed_texture = cr6se.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:CR6MAX]
-#name = Creality CR-6 Max
-#variants = 0.4
-#technology = FFF
-#family = CR
-#bed_model = cr10s4_bed.stl
-#bed_texture = cr10s4.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:CR6MAX]
+name = Creality CR-6 Max
+variants = 0.4
+technology = FFF
+family = CR
+bed_model = cr10s4_bed.stl
+bed_texture = cr10s4.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
 [printer_model:CR10MINI]
 name = Creality CR-10 Mini
@@ -140,14 +140,14 @@ bed_model = cr10mini_bed.stl
 bed_texture = cr10mini.svg
 default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:CR10MAX]
-#name = Creality CR-10 Max
-#variants = 0.4
-#technology = FFF
-#family = CR
-#bed_model = cr10max_bed.stl
-#bed_texture = cr10max.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:CR10MAX]
+name = Creality CR-10 Max
+variants = 0.4
+technology = FFF
+family = CR
+bed_model = cr10max_bed.stl
+bed_texture = cr10max.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
 [printer_model:CR10]
 name = Creality CR-10
@@ -239,23 +239,23 @@ bed_model = ender3_bed.stl
 bed_texture = cr20.svg
 default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:CR200B]
-#name = Creality CR-200B
-#variants = 0.4
-#technology = FFF
-#family = CR
-#bed_model = cr200b_bed.stl
-#bed_texture = cr200b.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:CR200B]
+name = Creality CR-200B
+variants = 0.4
+technology = FFF
+family = CR
+bed_model = cr200b_bed.stl
+bed_texture = cr200b.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
-#[printer_model:CR8]
-#name = Creality CR-8
-#variants = 0.4
-#technology = FFF
-#family = CR
-#bed_model = cr8_bed.stl
-#bed_texture = cr8.svg
-#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
+[printer_model:CR8]
+name = Creality CR-8
+variants = 0.4
+technology = FFF
+family = CR
+bed_model = cr8_bed.stl
+bed_texture = cr8.svg
+default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 123-3D Jupiter PLA @CREALITY
 
 #[printer_model:CRX]
 #name = Creality CR-X
@@ -859,20 +859,20 @@ max_print_height = 250
 printer_model = ENDER3V2
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3V2\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality Ender-3 Max]
-#inherits = *common*
-#retract_length = 6
-#bed_shape = 5x5,295x5,295x295,5x295
-#max_print_height = 340
-#printer_model = ENDER3MAX
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3MAX\nPRINTER_HAS_BOWDEN
+[printer:Creality Ender-3 Max]
+inherits = *common*
+retract_length = 6
+bed_shape = 5x5,295x5,295x295,5x295
+max_print_height = 340
+printer_model = ENDER3MAX
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3MAX\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality Ender-4]
-#inherits = *common*; *descendingz*
-#bed_shape = 5x0,215x0,215x220,5x220
-#max_print_height = 300
-#printer_model = ENDER4
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER4\nPRINTER_HAS_BOWDEN
+[printer:Creality Ender-4]
+inherits = *common*; *descendingz*
+bed_shape = 5x0,215x0,215x220,5x220
+max_print_height = 300
+printer_model = ENDER4
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER4\nPRINTER_HAS_BOWDEN
 
 [printer:Creality Ender-5]
 inherits = *common*; *descendingz*
@@ -896,12 +896,12 @@ machine_max_feedrate_z = 5
 machine_max_feedrate_x = 300
 machine_max_feedrate_y = 300
 
-#[printer:Creality Ender-6]
-#inherits = *common*; *descendingz*
-#bed_shape = 5x5,255x5,255x255,5x255
-#max_print_height = 400
-#printer_model = ENDER6
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER6\nPRINTER_HAS_BOWDEN
+[printer:Creality Ender-6]
+inherits = *common*; *descendingz*
+bed_shape = 5x5,255x5,255x255,5x255
+max_print_height = 400
+printer_model = ENDER6
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER6\nPRINTER_HAS_BOWDEN
 
 [printer:Creality Ender-2]
 inherits = *common*
@@ -911,35 +911,35 @@ max_print_height = 200
 printer_model = ENDER2
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER2\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality CR-5 Pro]
-#inherits = *common*; *slowabl*; *descendingz*
-#retract_length = 6
-#bed_shape = 5x5,295x5,295x220,5x220
-#max_print_height = 380
-#printer_model = CR5PRO
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PRO\nPRINTER_HAS_BOWDEN
+[printer:Creality CR-5 Pro]
+inherits = *common*; *slowabl*; *descendingz*
+retract_length = 6
+bed_shape = 5x5,295x5,295x220,5x220
+max_print_height = 380
+printer_model = CR5PRO
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PRO\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality CR-5 Pro H]
-#inherits = *common*; *slowabl*; *descendingz*
-#retract_length = 3
-#bed_shape = 5x5,295x5,295x220,5x220
-#max_print_height = 380
-#printer_model = CR5PROH
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PROH\nPRINTER_HAS_BOWDEN
+[printer:Creality CR-5 Pro H]
+inherits = *common*; *slowabl*; *descendingz*
+retract_length = 3
+bed_shape = 5x5,295x5,295x220,5x220
+max_print_height = 380
+printer_model = CR5PROH
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PROH\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality CR-6 SE]
-#inherits = *common*; *fastabl*; *pauseprint*
-#bed_shape = 5x0,230x0,230x235,5x235
-#printer_model = CR6SE
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN
+[printer:Creality CR-6 SE]
+inherits = *common*; *fastabl*; *pauseprint*
+bed_shape = 5x0,230x0,230x235,5x235
+printer_model = CR6SE
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality CR-6 Max]
-#inherits = *common*; *slowabl*
-#retract_length = 6
-#bed_shape = 5x5,395x5,395x395,5x395
-#max_print_height = 400
-#printer_model = CR6MAX
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6MAX\nPRINTER_HAS_BOWDEN
+[printer:Creality CR-6 Max]
+inherits = *common*; *slowabl*
+retract_length = 6
+bed_shape = 5x5,395x5,395x395,5x395
+max_print_height = 400
+printer_model = CR6MAX
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6MAX\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10 Mini]
 inherits = *common*
@@ -949,13 +949,13 @@ max_print_height = 300
 printer_model = CR10MINI
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10MINI\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality CR-10 Max]
-#inherits = *common*; *slowabl*
-#retract_length = 6
-#bed_shape = 5x5,445x5,445x445,5x445
-#max_print_height = 470
-#printer_model = CR10MAX
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10MAX\nPRINTER_HAS_BOWDEN
+[printer:Creality CR-10 Max]
+inherits = *common*; *slowabl*
+retract_length = 6
+bed_shape = 5x5,445x5,445x445,5x445
+max_print_height = 470
+printer_model = CR10MAX
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR10MAX\nPRINTER_HAS_BOWDEN
 
 [printer:Creality CR-10]
 inherits = *common*
@@ -1032,19 +1032,19 @@ retract_length = 4
 printer_model = CR20PRO
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR20PRO\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality CR-200B]
-#inherits = *common*; *descendingz*
-#bed_shape = 5x5,195x5,195x195,5x195
-#max_print_height = 200
-#printer_model = CR200B
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR200B\nPRINTER_HAS_BOWDEN
+[printer:Creality CR-200B]
+inherits = *common*; *descendingz*
+bed_shape = 5x5,195x5,195x195,5x195
+max_print_height = 200
+printer_model = CR200B
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR200B\nPRINTER_HAS_BOWDEN
 
-#[printer:Creality CR-8]
-#inherits = *common*
-#bed_shape = 5x5,215x5,215x215,5x215
-#max_print_height = 210
-#printer_model = CR8
-#printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR8\nPRINTER_HAS_BOWDEN
+[printer:Creality CR-8]
+inherits = *common*
+bed_shape = 5x5,215x5,215x215,5x215
+max_print_height = 210
+printer_model = CR8
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR8\nPRINTER_HAS_BOWDEN
 
 #[printer:Creality CR-X]
 #inherits = *common*; *dualextruder*

From 7eaadf0e47f6edcdccaeef23dc7687d26fc3a174 Mon Sep 17 00:00:00 2001
From: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Date: Mon, 1 Mar 2021 23:56:08 +0100
Subject: [PATCH 50/53] Revert "creality.ini: move Ender-3 specific
 extruder_clearance"

Due to #589.

This reverts commit 34202f71e5ab56c5e96fb3c9d9e6262b4cdd1231.
---
 resources/profiles/Creality.ini | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini
index f3f5836de..1c11210de 100644
--- a/resources/profiles/Creality.ini
+++ b/resources/profiles/Creality.ini
@@ -296,8 +296,8 @@ external_perimeters_first = 0
 external_perimeter_extrusion_width = 0.45
 external_perimeter_speed = 25
 extra_perimeters = 0
-extruder_clearance_height = 50
-extruder_clearance_radius = 70
+extruder_clearance_height = 34
+extruder_clearance_radius = 47
 extrusion_width = 0.45
 fill_angle = 45
 fill_density = 15%
@@ -841,8 +841,6 @@ inherits = *common*
 renamed_from = "Creality ENDER-3"
 bed_shape = 3x3,228x3,228x228,3x228
 max_print_height = 250
-extruder_clearance_height = 34
-extruder_clearance_radius = 47
 printer_model = ENDER3
 printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3\nPRINTER_HAS_BOWDEN
 

From 92a2951b234f513769380d4b1417cae36746a72b Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 2 Mar 2021 08:13:36 +0100
Subject: [PATCH 51/53] Fix build caused by missing returns

---
 src/libslic3r/MutablePolygon.hpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/libslic3r/MutablePolygon.hpp b/src/libslic3r/MutablePolygon.hpp
index b699a25ed..f40b89e74 100644
--- a/src/libslic3r/MutablePolygon.hpp
+++ b/src/libslic3r/MutablePolygon.hpp
@@ -24,8 +24,8 @@ public:
         bool             valid()   const { return m_idx >= 0; }
         const PointType& operator*() const { return m_data->at(m_idx).point; }
         const PointType* operator->() const { return &m_data->at(m_idx).point; }
-        const MutablePolygon& polygon() const { assert(this->valid()); m_data; }
-        IndexType        size()    const { assert(this->valid()); m_data->size(); }
+        const MutablePolygon& polygon() const { assert(this->valid()); return *m_data; }
+        IndexType        size()    const { assert(this->valid()); return m_data->size(); }
     private:
         const_iterator(const MutablePolygon *data, IndexType idx) : m_data(data), m_idx(idx) {}
         friend class MutablePolygon;
@@ -46,8 +46,8 @@ public:
         bool            valid()   const { return m_idx >= 0; }
         PointType&      operator*() const { return m_data->at(m_idx).point; }
         PointType*      operator->() const { return &m_data->at(m_idx).point; }
-        MutablePolygon& polygon() const { assert(this->valid()); m_data; }
-        IndexType       size()    const { assert(this->valid()); m_data->size(); }
+        MutablePolygon& polygon() const { assert(this->valid()); return *m_data; }
+        IndexType       size()    const { assert(this->valid()); return m_data->size(); }
         iterator&       remove()        { this->m_idx = m_data->remove(*this).m_idx; return *this; }
         iterator        insert(const PointType pt) const { return m_data->insert(*this, pt); }
     private:

From 28b92215c3dcf9f9c62cce308608a8bd500b456b Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Tue, 2 Mar 2021 12:06:11 +0100
Subject: [PATCH 52/53] Follow-up
 https://github.com/prusa3d/PrusaSlicer/commit/409849d238718b75cf0c5ef264ce1df0cedc5c6e:
 Added check for visibility for all loaded presets. Added notification about
 this action.  + PresetComboBox: Fixed update() function for physical
 printers, when some of related presets are invisible.

---
 src/libslic3r/PresetBundle.cpp      | 10 ------
 src/slic3r/GUI/Plater.cpp           | 51 +++++++++++++++++++++++++++--
 src/slic3r/GUI/PresetComboBoxes.cpp |  4 +--
 3 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp
index dc52fdaff..e7f818d08 100644
--- a/src/libslic3r/PresetBundle.cpp
+++ b/src/libslic3r/PresetBundle.cpp
@@ -877,16 +877,6 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
             }
         }
 
-        // 3.1) If loaded filaments are invisible/non-instaled, set them as visible
-        for (const std::string& filament : this->filament_presets) {
-            Preset* preset = this->filaments.find_preset(filament);
-            if (preset && !preset->is_visible) {
-                preset->is_visible = true;
-                if (preset->name == this->filaments.m_edited_preset.name)
-                    this->filaments.get_selected_preset().is_visible = true;
-            }
-        }
-
         // 4) Load the project config values (the per extruder wipe matrix etc).
         this->project_config.apply_only(config, s_project_options);
 
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index fe6704925..762acfdf1 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -2189,9 +2189,56 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
                 {
                     if (!config.empty()) {
                         Preset::normalize(config);
-                        wxGetApp().preset_bundle->load_config_model(filename.string(), std::move(config));
+                        PresetBundle* preset_bundle = wxGetApp().preset_bundle;
+                        preset_bundle->load_config_model(filename.string(), std::move(config));
+                        {
+                            // After loading of the presets from project, check if they are visible.
+                            // Set them to visible if they are not.
+
+                            auto update_selected_preset_visibility = [](PresetCollection& presets, std::vector<std::string>& names) {
+                                if (!presets.get_selected_preset().is_visible) {
+                                    assert(presets.get_selected_preset().name == presets.get_edited_preset().name);
+                                    presets.get_selected_preset().is_visible = true;
+                                    presets.get_edited_preset().is_visible = true;
+                                    names.emplace_back(presets.get_selected_preset().name);
+                                }
+                            };
+
+                            std::vector<std::string> names;
+                            if (printer_technology == ptFFF) {
+                                update_selected_preset_visibility(preset_bundle->prints, names);
+                                for (const std::string& filament : preset_bundle->filament_presets) {
+                                    Preset* preset = preset_bundle->filaments.find_preset(filament);
+                                    if (preset && !preset->is_visible) {
+                                        preset->is_visible = true;
+                                        names.emplace_back(preset->name);
+                                        if (preset->name == preset_bundle->filaments.get_edited_preset().name)
+                                            preset_bundle->filaments.get_selected_preset().is_visible = true;
+                                    }
+                                }
+                            }
+                            else {
+                                update_selected_preset_visibility(preset_bundle->sla_prints, names);
+                                update_selected_preset_visibility(preset_bundle->sla_materials, names);
+                            }
+                            update_selected_preset_visibility(preset_bundle->printers, names);
+
+                            preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
+
+                            // show notification about temporary instaled presets
+                            if (!names.empty()) {
+                                std::string notif_text = into_u8(_L_PLURAL("The preset below was temporary instaled on active instance of PrusaSlicer",
+                                                                           "The presets below were temporary instaled on active instance of PrusaSlicer", names.size())) + ":";
+                                for (std::string& name : names)
+                                    notif_text += "\n - " + name;
+                                notification_manager->push_notification(NotificationType::CustomNotification,
+                                    NotificationManager::NotificationLevel::RegularNotification, notif_text);
+                            }
+                        }
+
                         if (printer_technology == ptFFF)
-                            CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &wxGetApp().preset_bundle->project_config);
+                            CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &preset_bundle->project_config);
+
                         // For exporting from the amf/3mf we shouldn't check printer_presets for the containing information about "Print Host upload"
                         wxGetApp().load_current_presets(false);
                         // Update filament colors for the MM-printer profile in the full config 
diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp
index da723a36b..c6a3006b7 100644
--- a/src/slic3r/GUI/PresetComboBoxes.cpp
+++ b/src/slic3r/GUI/PresetComboBoxes.cpp
@@ -899,7 +899,7 @@ void PlaterPresetComboBox::update()
             for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) {
                 for (const std::string& preset_name : it->get_preset_names()) {
                     Preset* preset = m_collection->find_preset(preset_name);
-                    if (!preset)
+                    if (!preset || !preset->is_visible)
                         continue;
                     std::string main_icon_name, bitmap_key = main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name;
                     wxBitmap* bmp = get_bmp(main_icon_name, wide_icons, main_icon_name);
@@ -1086,7 +1086,7 @@ void TabPresetComboBox::update()
             for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) {
                 for (const std::string& preset_name : it->get_preset_names()) {
                     Preset* preset = m_collection->find_preset(preset_name);
-                    if (!preset)
+                    if (!preset || !preset->is_visible)
                         continue;
                     std::string main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name;
 

From 91ffd8d50167bc987ce44be93df651b82613a9ba Mon Sep 17 00:00:00 2001
From: Enrico Turri <enricoturri@seznam.cz>
Date: Tue, 2 Mar 2021 17:00:11 +0100
Subject: [PATCH 53/53] Custom G-code validation - Do not veto setting tab
 switch when invalid g-code is found

---
 src/slic3r/GUI/MainFrame.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 6b0dd1ad5..c1aadb370 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -549,8 +549,10 @@ void MainFrame::init_tabpanel()
         wxWindow* panel = m_tabpanel->GetCurrentPage();
         if (panel != nullptr) {
             Tab* tab = dynamic_cast<Tab*>(panel);
-            if (tab != nullptr && !tab->validate_custom_gcodes())
-                evt.Veto();
+            if (tab != nullptr)
+                tab->validate_custom_gcodes();
+//            if (tab != nullptr && !tab->validate_custom_gcodes())
+//                evt.Veto();
         }
         });
 #endif // ENABLE_VALIDATE_CUSTOM_GCODE