Browse Source

Complete the C++ CLI; remove the #ifndef SLIC3RXS guards and fix CI by removing std::initializer_lists

Alessandro Ranellucci 6 years ago
parent
commit
f0f36cb935

+ 2 - 0
xs/MANIFEST

@@ -147,6 +147,8 @@ src/libslic3r/PrintGCode.cpp
 src/libslic3r/PrintGCode.hpp
 src/libslic3r/PrintObject.cpp
 src/libslic3r/PrintRegion.cpp
+src/libslic3r/SimplePrint.cpp
+src/libslic3r/SimplePrint.hpp
 src/libslic3r/SLAPrint.cpp
 src/libslic3r/SLAPrint.hpp
 src/libslic3r/SlicingAdaptive.cpp

+ 37 - 47
xs/src/libslic3r/Config.cpp

@@ -1,4 +1,3 @@
-#ifndef SLIC3RXS
 #include "Config.hpp"
 #include "Log.hpp"
 
@@ -22,7 +21,7 @@ Config::new_from_defaults(std::initializer_list<std::string> init)
 std::shared_ptr<Config> 
 Config::new_from_defaults(t_config_option_keys init)
 {
-    auto my_config(std::make_shared<Config>());
+    std::shared_ptr<Config>  my_config(std::make_shared<Config>());
     for (auto& opt_key : init) {
         if (print_config_def.has(opt_key)) {
             const std::string value { print_config_def.get(opt_key).default_value->serialize() };
@@ -33,30 +32,25 @@ Config::new_from_defaults(t_config_option_keys init)
     return my_config;
 }
 
-std::shared_ptr<Config> 
-new_from_cli(const int& argc, const char* argv[])
-{
-    return std::make_shared<Config>();
-}
-
 std::shared_ptr<Config> 
 Config::new_from_ini(const std::string& inifile) 
 { 
     
-    auto my_config(std::make_shared<Config>());
+    std::shared_ptr<Config> my_config(std::make_shared<Config>());
     my_config->read_ini(inifile);
     return my_config;
 }
 
+// TODO: this should be merged into ConfigBase::validate()
 bool
 Config::validate()
 {
     // general validation
     for (auto k : this->_config.keys()) {
         if (print_config_def.options.count(k) == 0) continue; // skip over keys that aren't in the master list
-        const auto& opt {print_config_def.options.at(k)};
+        const ConfigOptionDef& opt { print_config_def.options.at(k) };
         if (opt.cli == "" || std::regex_search(opt.cli, _match_info, _cli_pattern) == false) continue;
-        auto type {_match_info.str(1)};
+        std::string type { _match_info.str(1) };
         std::vector<std::string> values;
         if (std::regex_search(type, _match_info, std::regex("@$"))) {
             type = std::regex_replace(type, std::regex("@$"), std::string("")); // strip off the @ for later;
@@ -66,7 +60,7 @@ Config::validate()
             } catch (std::bad_cast& e) {
                 throw InvalidOptionType((std::string("(cast failure) Invalid value for ") + std::string(k)).c_str());
             }
-            auto tmp_str {tmp_opt->vserialize()};
+            const std::vector<std::string> tmp_str { tmp_opt->vserialize() };
             values.insert(values.end(), tmp_str.begin(), tmp_str.end());
         } else {
             Slic3r::Log::debug("Config::validate", std::string("Not an array"));
@@ -91,28 +85,28 @@ void
 Config::set(const t_config_option_key& opt_key, const std::string& value)
 {
     try {
-        const auto& def {print_config_def.options.at(opt_key)};
+        const auto& def = print_config_def.options.at(opt_key);
         switch (def.type) {
             case coInt:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
                     ptr->value = std::stoi(value);
                 } break;
             case coInts:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
                     if (!ptr->deserialize(value, true) ) {
                         throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
                     }
                 } break;
             case coFloat:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
                     ptr->setFloat(std::stod(value));
                 } break;
             case coFloatOrPercent:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
                     const size_t perc = value.find("%");
                     ptr->percent = (perc != std::string::npos);
                     if (ptr->percent) {
@@ -125,21 +119,21 @@ Config::set(const t_config_option_key& opt_key, const std::string& value)
                 } break;
             case coFloats:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
                     if (!ptr->deserialize(value, true) ) {
                         throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
                     }
                 } break;
             case coString:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
                     if (!ptr->deserialize(value) ) {
                         throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
                     }
                 } break;
             case coBool:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionBool* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
                     ptr->deserialize(value);
                 } break;
             default: 
@@ -156,42 +150,42 @@ void
 Config::set(const t_config_option_key& opt_key, const bool value) 
 {
     try {
-        const auto& def {print_config_def.options.at(opt_key)};
+        const auto& def = print_config_def.options.at(opt_key);
         switch (def.type) {
             case coBool:
                 {   
-                    auto* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionBool* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
                     ptr->value = value;
                 } break;
             case coInt:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
                     ptr->setInt(value);
                 } break;
             case coInts:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
                     ptr->deserialize(std::to_string(value), true);
                 } break;
             case coFloat:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
                     ptr->setFloat(value);
                 } break;
             case coFloatOrPercent:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
                     ptr->setFloat(value);
                     ptr->percent = false;
                 } break;
             case coFloats:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
                     ptr->deserialize(std::to_string(value), true);
                 } break;
             case coString:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
                     if (!ptr->deserialize(std::to_string(value)) ) {
                         throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
                     }
@@ -209,42 +203,42 @@ void
 Config::set(const t_config_option_key& opt_key, const int value)
 {
     try {
-        const auto& def {print_config_def.options.at(opt_key)};
+        const auto& def = print_config_def.options.at(opt_key);
         switch (def.type) {
             case coBool:
                 {   
-                    auto* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionBool* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
                     ptr->value = (value != 0);
                 } break;
             case coInt:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
                     ptr->setInt(value);
                 } break;
             case coInts:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
                     ptr->deserialize(std::to_string(value), true);
                 } break;
             case coFloat:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
                     ptr->setFloat(value);
                 } break;
             case coFloatOrPercent:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
                     ptr->setFloat(value);
                     ptr->percent = false;
                 } break;
             case coFloats:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
                     ptr->deserialize(std::to_string(value), true);
                 } break;
             case coString:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
                     if (!ptr->deserialize(std::to_string(value)) ) {
                         throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
                     }
@@ -262,37 +256,37 @@ void
 Config::set(const t_config_option_key& opt_key, const double value)
 {
     try {
-        const auto& def {print_config_def.options.at(opt_key)};
+        const auto& def = print_config_def.options.at(opt_key);
         switch (def.type) {
             case coInt:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
                     ptr->setInt(std::round(value));
                 } break;
             case coInts:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
                     ptr->deserialize(std::to_string(std::round(value)), true);
                 } break;
             case coFloat:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
                     ptr->setFloat(value);
                 } break;
             case coFloatOrPercent:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
                     ptr->setFloat(value);
                     ptr->percent = false;
                 } break;
             case coFloats:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
                     ptr->deserialize(std::to_string(value), true);
                 } break;
             case coString:
                 {
-                    auto* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
+                    ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
                     if (!ptr->deserialize(std::to_string(value)) ) {
                         throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
                     }
@@ -355,7 +349,3 @@ is_valid_float(const std::string& type, const ConfigOptionDef& opt, const std::s
 Config::Config() : _config(DynamicPrintConfig()) {};
 
 } // namespace Slic3r
-
-
-
-#endif // SLIC3RXS

+ 0 - 7
xs/src/libslic3r/Config.hpp

@@ -1,5 +1,3 @@
-#ifndef SLIC3RXS
-
 #ifndef CONFIG_HPP
 #define CONFIG_HPP
 
@@ -47,9 +45,6 @@ public:
     /// Factory method to construct a Config with specific default values loaded.
     static std::shared_ptr<Config> new_from_defaults(t_config_option_keys init);
 
-    /// Factory method to construct a Config from CLI options.
-    static std::shared_ptr<Config> new_from_cli(const int& argc, const char* argv[]);
-
     /// Factory method to construct a Config from an ini file.
     static std::shared_ptr<Config> new_from_ini(const std::string& inifile);
 
@@ -156,5 +151,3 @@ bool is_valid_float(const std::string& type, const ConfigOptionDef& opt, const s
 } // namespace Slic3r
 
 #endif // CONFIG_HPP
-
-#endif // SLIC3RXS

+ 3 - 3
xs/src/libslic3r/ConfigBase.cpp

@@ -378,7 +378,7 @@ ConfigBase::apply_only(const ConfigBase &other, const t_config_option_keys &opt_
             continue;
         }
         if (default_nonexistent && !other.has(opt_key)) {
-            auto* def_opt = this->def->get(opt_key)->default_value->clone();
+            auto* def_opt = this->def->get(opt_key).default_value->clone();
             // not the most efficient way, but easier than casting pointers to subclasses
             bool res = my_opt->deserialize( def_opt->serialize() );
             if (!res) {
@@ -434,11 +434,11 @@ ConfigBase::set_deserialize(t_config_option_key opt_key, std::string str, bool a
             }
         }
     }
-    if (!this->def->has(opt_key)) {
+    if (!this->def->has(opt_key))
         throw UnknownOptionException(opt_key);
     
     const ConfigOptionDef& optdef = this->def->options.at(opt_key);
-    if (!optdef.shortcut.empty())
+    if (!optdef.shortcut.empty()) {
         for (const t_config_option_key& shortcut : optdef.shortcut)
             if (!this->set_deserialize(shortcut, str))
                 return false;

+ 13 - 14
xs/src/libslic3r/Print.cpp

@@ -103,8 +103,6 @@ Print::delete_object(size_t idx)
     // TODO: purge unused regions
 }
 
-#ifndef SLIC3RXS
-
 void
 Print::process() 
 {
@@ -176,11 +174,11 @@ Print::make_skirt()
     // $skirt_height_z in this case is the highest possible skirt height for safety.
     double skirt_height_z {-1.0};
     for (const auto& object : this->objects) {
-        size_t skirt_height {
+        const size_t skirt_height {
             this->has_infinite_skirt() ? object->layer_count() :
             std::min(size_t(this->config.skirt_height()), object->layer_count())
         };
-        auto* highest_layer {object->get_layer(skirt_height - 1)};
+        const Layer* highest_layer { object->get_layer(skirt_height - 1) };
         skirt_height_z = std::max(skirt_height_z, highest_layer->print_z);
     }
 
@@ -303,8 +301,6 @@ Print::make_skirt()
     this->state.set_done(psSkirt);
 }
 
-#endif // SLIC3RXS
-
 void
 Print::reload_object(size_t idx)
 {
@@ -714,8 +710,6 @@ Print::add_model_object(ModelObject* model_object, int idx)
     }
 }
 
-#ifndef SLIC3RXS
-
 void
 Print::export_gcode(std::ostream& output, bool quiet)
 {
@@ -724,9 +718,8 @@ Print::export_gcode(std::ostream& output, bool quiet)
     
     if (this->status_cb != nullptr) 
         this->status_cb(90, "Exporting G-Code...");
-
-    auto export_handler {Slic3r::PrintGCode(*this, output)};
-    export_handler.output();
+    
+    Slic3r::PrintGCode(*this, output).output();
 }
 
 void
@@ -777,13 +770,12 @@ Print::export_gcode(std::string outfile, bool quiet)
     }
 }
 
-
+#ifndef SLIC3RXS
 bool
 Print::apply_config(config_ptr config) {
     // dereference the stored pointer and pass the resulting data to apply_config()
     return this->apply_config(config->config());
 }
-
 #endif
 
 bool
@@ -934,12 +926,19 @@ Print::validate() const
                 object->model_object()->instances.front()->transform_polygon(&convex_hull);
                 
                 // grow convex hull with the clearance margin
-                convex_hull = offset(convex_hull, scale_(this->config.extruder_clearance_radius.value)/2, 1, jtRound, scale_(0.1)).front();
+                convex_hull = offset(
+                    convex_hull,
+                    // safety_offset in intersection() is not enough for preventing false positives
+                    scale_(this->config.extruder_clearance_radius.value)/2 - scale_(0.01),
+                    CLIPPER_OFFSET_SCALE,
+                    jtRound, scale_(0.1)
+                ).front();
                 
                 // now we check that no instance of convex_hull intersects any of the previously checked object instances
                 for (Points::const_iterator copy = object->_shifted_copies.begin(); copy != object->_shifted_copies.end(); ++copy) {
                     Polygon p = convex_hull;
                     p.translate(*copy);
+                    
                     if (!intersection(a, p).empty())
                         throw InvalidPrintException{"Some objects are too close; your extruder will collide with them."};
                     

+ 5 - 14
xs/src/libslic3r/Print.hpp

@@ -113,7 +113,7 @@ class PrintObject
     // TODO: Fill* fill_maker        => (is => 'lazy');
     PrintState<PrintObjectStep> state;
     
-    Print* print();
+    Print* print() { return this->_print; };
     ModelObject* model_object() { return this->_model_object; };
     const ModelObject& model_object() const { return *(this->_model_object); };
     
@@ -167,8 +167,6 @@ class PrintObject
     void _make_perimeters();
     void _infill();
 
-#ifndef SLIC3RXS
-
     /// Initialize and generate support material.
     void generate_support_material();
 
@@ -200,7 +198,7 @@ class PrintObject
     /// Idempotence of this method is guaranteed by the fact that we don't remove things from
     /// fill_surfaces but we only turn them into VOID surfaces, thus preserving the boundaries.
     void clip_fill_surfaces();
-#endif // SLIC3RXS    
+      
     private:
     Print* _print;
     ModelObject* _model_object;
@@ -211,12 +209,10 @@ class PrintObject
     PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox);
     ~PrintObject();
 
-#ifndef SLIC3RXS
     /// Outer loop of logic for horizontal shell discovery
     void _discover_external_horizontal_shells(LayerRegion* layerm, const size_t& i, const size_t& region_id);
     /// Inner loop of logic for horizontal shell discovery
-    void _discover_neighbor_horizontal_shells(LayerRegion* layerm, const size_t& i, const size_t& region_id, const SurfaceType& type, Polygons& solid, const size_t& solid_layers);
-#endif // SLIC3RXS    
+    void _discover_neighbor_horizontal_shells(LayerRegion* layerm, const size_t& i, const size_t& region_id, const SurfaceType& type, Polygons& solid, const size_t& solid_layers);  
 
 };
 
@@ -233,13 +229,13 @@ class Print
     PrintObjectPtrs objects;
     PrintRegionPtrs regions;
     PlaceholderParser placeholder_parser;
-    #ifndef SLIC3RXS
+    
     std::function<void(int, const std::string&)> status_cb {nullptr};
 
     /// Function pointer for the UI side to call post-processing scripts.
     /// Vector is assumed to be the executable script and all arguments.
     std::function<void(std::vector<std::string>)> post_process_cb {nullptr};
-    #endif 
+    
     double total_used_filament, total_extruded_volume, total_cost, total_weight;
     std::map<size_t,float> filament_stats;
     PrintState<PrintStep> state;
@@ -263,7 +259,6 @@ class Print
     const PrintRegion* get_region(size_t idx) const { return this->regions.at(idx); };
     PrintRegion* add_region();
 
-    #ifndef SLIC3RXS
     /// Triggers the rest of the print process
     void process(); 
 
@@ -275,8 +270,6 @@ class Print
 
     /// commands a gcode export to a temporary file and return its name
     std::string export_gcode(bool quiet = false);
-
-    #endif // SLIC3RXS
     
     // methods for handling state
     bool invalidate_state_by_config(const PrintConfigBase &config);
@@ -301,14 +294,12 @@ class Print
     Flow skirt_flow() const;
     void _make_brim();
 
-    #ifndef SLIC3RXS
     /// Generates a skirt around the union of all of 
     /// the objects in the print.
     void make_skirt();
 
     /// Generates a brim around all of the objects in the print.
     void make_brim();
-    #endif // SLIC3RXS
     
     
     std::set<size_t> object_extruders() const;

+ 1 - 1
xs/src/libslic3r/PrintConfig.cpp

@@ -2029,7 +2029,7 @@ CLITransformConfigDef::CLITransformConfigDef()
 
     def = this->add("repair", coBool);
     def->label = __TRANS("Repair");
-    def->tooltip = __TRANS("Try to repair any non-manifold meshes (this option is implicitly added whenever we need to slice the model to perform the requested action.");
+    def->tooltip = __TRANS("Try to repair any non-manifold meshes (this option is implicitly added whenever we need to slice the model to perform the requested action).");
     def->cli = "repair";
     
     def = this->add("rotate", coFloat);

+ 184 - 169
xs/src/libslic3r/PrintGCode.cpp

@@ -1,4 +1,3 @@
-#ifndef SLIC3RXS
 #include "PrintGCode.hpp"
 #include "PrintConfig.hpp"
 
@@ -9,12 +8,6 @@ namespace Slic3r {
 void
 PrintGCode::output()
 {
-    auto& gcodegen {this->_gcodegen};
-    auto& fh {this->fh};
-    auto& print {this->_print};
-    const auto& config {this->config};
-    const auto extruders {print.extruders()};
-
     // Write information about the generator.
     time_t rawtime; tm * timeinfo;
     time(&rawtime);
@@ -25,16 +18,16 @@ PrintGCode::output()
     fh << "; Git Commit: " << BUILD_COMMIT << "\n\n";
 
     // Writes notes (content of all Settings tabs -> Notes)
-    fh << gcodegen.notes();
+    fh << _gcodegen.notes();
 
     // Write some terse information on the slicing parameters.
-    auto& first_object {*(this->objects.at(0))};
-    auto layer_height {first_object.config.layer_height.getFloat()};
+    PrintObject& first_object { *this->objects.at(0) };
+    const auto layer_height = first_object.config.layer_height.getFloat();
 
-    for (auto* region : print.regions) {
+    for (auto* region : _print.regions) {
         {
-            auto flow {region->flow(frExternalPerimeter, layer_height, false, false, -1, first_object)};
-            auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("external_perimeter_speed")};
+            const Flow flow { region->flow(frExternalPerimeter, layer_height, false, false, -1, first_object) };
+            auto vol_speed = flow.mm3_per_mm() * region->config.get_abs_value("external_perimeter_speed");
             if (config.max_volumetric_speed.getInt() > 0)
                 vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
             fh << "; external perimeters extrusion width = ";
@@ -42,8 +35,8 @@ PrintGCode::output()
             fh << "(" << vol_speed << "mm^3/s)\n";
         }
         {
-            auto flow {region->flow(frPerimeter, layer_height, false, false, -1, first_object)};
-            auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("perimeter_speed")};
+            const Flow flow { region->flow(frPerimeter, layer_height, false, false, -1, first_object) };
+            auto vol_speed = flow.mm3_per_mm() * region->config.get_abs_value("perimeter_speed");
             if (config.max_volumetric_speed.getInt() > 0)
                 vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
             fh << "; perimeters extrusion width = ";
@@ -51,8 +44,8 @@ PrintGCode::output()
             fh << "(" << vol_speed << "mm^3/s)\n";
         }
         {
-            auto flow {region->flow(frInfill, layer_height, false, false, -1, first_object)};
-            auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("infill_speed")};
+            const Flow flow { region->flow(frInfill, layer_height, false, false, -1, first_object) };
+            auto vol_speed = flow.mm3_per_mm() * region->config.get_abs_value("infill_speed");
             if (config.max_volumetric_speed.getInt() > 0)
                 vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
             fh << "; infill extrusion width = ";
@@ -60,8 +53,8 @@ PrintGCode::output()
             fh << "(" << vol_speed << "mm^3/s)\n";
         }
         {
-            auto flow {region->flow(frSolidInfill, layer_height, false, false, -1, first_object)};
-            auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("solid_infill_speed")};
+            const Flow flow { region->flow(frSolidInfill, layer_height, false, false, -1, first_object) };
+            auto vol_speed = flow.mm3_per_mm() * region->config.get_abs_value("solid_infill_speed");
             if (config.max_volumetric_speed.getInt() > 0)
                 vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
             fh << "; solid infill extrusion width = ";
@@ -69,26 +62,26 @@ PrintGCode::output()
             fh << "(" << vol_speed << "mm^3/s)\n";
         }
         {
-            auto flow {region->flow(frTopSolidInfill, layer_height, false, false, -1, first_object)};
-            auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("top_solid_infill_speed")};
+            const Flow flow { region->flow(frTopSolidInfill, layer_height, false, false, -1, first_object) };
+            auto vol_speed = flow.mm3_per_mm() * region->config.get_abs_value("top_solid_infill_speed");
             if (config.max_volumetric_speed.getInt() > 0)
                 vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
             fh << "; top solid infill extrusion width = ";
             fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
             fh << "(" << vol_speed << "mm^3/s)\n";
         }
-        if (print.has_support_material()) {
-            auto flow {first_object._support_material_flow()};
-            auto vol_speed {flow.mm3_per_mm() * first_object.config.get_abs_value("support_material_speed")};
+        if (_print.has_support_material()) {
+            const Flow flow { first_object._support_material_flow() };
+            auto vol_speed = flow.mm3_per_mm() * first_object.config.get_abs_value("support_material_speed");
             if (config.max_volumetric_speed.getInt() > 0)
                 vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
             fh << "; support material extrusion width = ";
             fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
             fh << "(" << vol_speed << "mm^3/s)\n";
         }
-        if (print.config.first_layer_extrusion_width.getFloat() > 0) {
-            auto flow {region->flow(frPerimeter, layer_height, false, false, -1, first_object)};
-//          auto vol_speed {flow.mm3_per_mm() * print.config.get_abs_value("first_layer_speed")};
+        if (_print.config.first_layer_extrusion_width.getFloat() > 0) {
+            const Flow flow { region->flow(frPerimeter, layer_height, false, false, -1, first_object) };
+//          auto vol_speed = flow.mm3_per_mm() * _print.config.get_abs_value("first_layer_speed");
 //          if (config.max_volumetric_speed.getInt() > 0)
 //              vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
             fh << "; first layer extrusion width = ";
@@ -99,29 +92,29 @@ PrintGCode::output()
         fh << std::endl;
     }
     // Prepare the helper object for replacing placeholders in custom G-Code and output filename
-    print.placeholder_parser.update_timestamp();
+    _print.placeholder_parser.update_timestamp();
 
     // GCode sets this automatically when change_layer() is called, but needed for skirt/brim as well
-    gcodegen.first_layer = true;
+    _gcodegen.first_layer = true;
 
     // disable fan
     if (config.cooling.getBool() && config.disable_fan_first_layers.getInt() > 0) {
-        fh << gcodegen.writer.set_fan(0,1) << "\n";
+        fh << _gcodegen.writer.set_fan(0,1) << "\n";
     }
 
     // set bed temperature
-    auto temp{config.first_layer_bed_temperature.getFloat()};
+    const auto temp = config.first_layer_bed_temperature.getFloat();
     if (config.has_heatbed && temp > 0 && std::regex_search(config.start_gcode.getString(), bed_temp_regex)) {
-        fh << gcodegen.writer.set_bed_temperature(temp, 1);
+        fh << _gcodegen.writer.set_bed_temperature(temp, 1);
     }
     
     // Set extruder(s) temperature before and after start gcode.
-    auto include_start_extruder_temp {!std::regex_search(config.start_gcode.getString(), ex_temp_regex)};
+    auto include_start_extruder_temp = !std::regex_search(config.start_gcode.getString(), ex_temp_regex);
     for(const auto& start_gcode : config.start_filament_gcode.values) {
         include_start_extruder_temp = include_start_extruder_temp && !std::regex_search(start_gcode, ex_temp_regex);
     }
 
-    auto include_end_extruder_temp {!std::regex_search(config.end_gcode.getString(), ex_temp_regex)};
+    auto include_end_extruder_temp = !std::regex_search(config.end_gcode.getString(), ex_temp_regex);
     for(const auto& end_gcode : config.end_filament_gcode.values) {
         include_end_extruder_temp = include_end_extruder_temp && !std::regex_search(end_gcode, ex_temp_regex);
     }
@@ -129,12 +122,12 @@ PrintGCode::output()
     if (include_start_extruder_temp) this->_print_first_layer_temperature(0);
 
     // Apply gcode math to start gcode
-    fh << apply_math(gcodegen.placeholder_parser->process(config.start_gcode.value));
+    fh << apply_math(_gcodegen.placeholder_parser->process(config.start_gcode.value));
     {
-        auto filament_extruder {0U};
+        auto filament_extruder = 0U;
         for(const auto& start_gcode : config.start_filament_gcode.values) {
-            gcodegen.placeholder_parser->set("filament_extruder_id", filament_extruder++);
-            fh << apply_math(gcodegen.placeholder_parser->process(start_gcode));
+            _gcodegen.placeholder_parser->set("filament_extruder_id", filament_extruder++);
+            fh << apply_math(_gcodegen.placeholder_parser->process(start_gcode));
         }
     }
     
@@ -142,7 +135,7 @@ PrintGCode::output()
 
 
     // Set other general things (preamble)
-    fh << gcodegen.preamble();
+    fh << _gcodegen.preamble();
 
     // initialize motion planner for object-to-object travel moves
     if (config.avoid_crossing_perimeters.getBool()) {
@@ -153,7 +146,7 @@ PrintGCode::output()
             Polygons polygons {};
             // Add polygons that aren't just thin walls.
             for (auto layer : object->layers) {
-                const auto& slice {ExPolygons(layer->slices)};
+                const ExPolygons& slice { layer->slices };
                 std::for_each(slice.cbegin(), slice.cend(), [&polygons] (const ExPolygon& a) { polygons.emplace_back(a.contour); });
             }
             
@@ -166,39 +159,70 @@ PrintGCode::output()
             }
         }
         
-        gcodegen.avoid_crossing_perimeters.init_external_mp(union_ex(islands_p));
+        _gcodegen.avoid_crossing_perimeters.init_external_mp(union_ex(islands_p));
     }
+    
+    const auto extruders = _print.extruders();
 
     // Calculate wiping points if needed.
     if (config.ooze_prevention && extruders.size() > 1) {
+        /*
+        TODO: PORT THIS!
+        my @skirt_points = map @$_, map @$_, @{$self->print->skirt};
+        if (@skirt_points) {
+            my $outer_skirt = convex_hull(\@skirt_points);
+            my @skirts = ();
+            foreach my $extruder_id (@extruders) {
+                my $extruder_offset = $self->config->get_at('extruder_offset', $extruder_id);
+                push @skirts, my $s = $outer_skirt->clone;
+                $s->translate(-scale($extruder_offset->x), -scale($extruder_offset->y));  #)
+            }
+            my $convex_hull = convex_hull([ map @$_, @skirts ]);
+            
+            $gcodegen->ooze_prevention->set_enable(1);
+            $gcodegen->ooze_prevention->set_standby_points(
+                [ map @{$_->equally_spaced_points(scale 10)}, @{offset([$convex_hull], scale 3)} ]
+            );
+            
+            if (0) {
+                require "Slic3r/SVG.pm";
+                Slic3r::SVG::output(
+                    "ooze_prevention.svg",
+                    red_polygons    => \@skirts,
+                    polygons        => [$outer_skirt],
+                    points          => $gcodegen->ooze_prevention->standby_points,
+                );
+            }
+        }
+        */
     }
 
     // Set initial extruder only after custom start gcode
-    fh << gcodegen.set_extruder(*(extruders.begin()));
+    fh << _gcodegen.set_extruder( *(extruders.begin()) );
 
     // Do all objects for each layer.
 
     if (config.complete_objects) {
         // print objects from the smallest to the tallest to avoid collisions
         // when moving onto next object starting point
-        std::sort(print.objects.begin(), print.objects.end(), [] (const PrintObject* a, const PrintObject* b) {
+        std::sort(_print.objects.begin(), _print.objects.end(), [] (const PrintObject* a, const PrintObject* b) {
             return (a->config.sequential_print_priority < a->config.sequential_print_priority) || (a->size.z < b->size.z);
         });
         size_t finished_objects {0};
         
-        for (size_t obj_idx {0}; obj_idx < print.objects.size(); ++obj_idx) {
+        for (size_t obj_idx {0}; obj_idx < _print.objects.size(); ++obj_idx) {
             PrintObject& object {*(this->objects.at(obj_idx))};
             for (const Point& copy : object._shifted_copies) {
                 if (finished_objects > 0) {
-                    gcodegen.set_origin(Pointf::new_unscale(copy));
-                    gcodegen.enable_cooling_markers = false;
-                    gcodegen.avoid_crossing_perimeters.use_external_mp_once = true;
-                    fh << gcodegen.retract();
-                    fh << gcodegen.travel_to(Point(0,0), erNone, "move to origin position for next object");
+                    _gcodegen.set_origin(Pointf::new_unscale(copy));
+                    _gcodegen.enable_cooling_markers = false;
+                    _gcodegen.avoid_crossing_perimeters.use_external_mp_once = true;
+                    fh << _gcodegen.retract();
+                    fh << _gcodegen.travel_to(Point(0,0), erNone, "move to origin position for next object");
 
-                    gcodegen.enable_cooling_markers = true;
+                    _gcodegen.enable_cooling_markers = true;
                     // disable motion planner when traveling to first object point
-                    gcodegen.avoid_crossing_perimeters.disable_once = true;
+                    _gcodegen.avoid_crossing_perimeters.disable_once = true;
                 }
                 std::vector<Layer*> layers;
                 layers.reserve(object.layers.size() + object.support_layers.size());
@@ -218,7 +242,7 @@ PrintGCode::output()
                                 config.has_heatbed &&
                                 std::regex_search(config.between_objects_gcode.getString(), bed_temp_regex)) 
                         {
-                            fh << gcodegen.writer.set_bed_temperature(config.first_layer_bed_temperature);
+                            fh << _gcodegen.writer.set_bed_temperature(config.first_layer_bed_temperature);
                         }
                         if (std::regex_search(config.between_objects_gcode.getString(), ex_temp_regex)) {
                             _print_first_layer_temperature(false);
@@ -242,8 +266,8 @@ PrintGCode::output()
         std::vector<size_t> z;
         z.reserve(100); // preallocate with 100 layers
         std::map<coord_t, std::map<size_t, LayerPtrs > > layers {};
-        for (size_t idx = 0U; idx < print.objects.size(); ++idx) {
-            const auto& object {*(objects.at(idx))};
+        for (size_t idx = 0U; idx < _print.objects.size(); ++idx) {
+            const PrintObject& object { *objects.at(idx) };
             // sort layers by Z into buckets
             for (Layer* layer : object.layers) {
                 if (layers.count(scale_(layer->print_z)) == 0) { // initialize bucket if empty
@@ -272,47 +296,47 @@ PrintGCode::output()
                     this->process_layer(idx, layer, layer->object()->_shifted_copies);
                 }
             }
-            gcodegen.placeholder_parser->set("layer_z", unscale(print_z));
-            gcodegen.placeholder_parser->set("layer_num", gcodegen.layer_index);
+            _gcodegen.placeholder_parser->set("layer_z", unscale(print_z));
+            _gcodegen.placeholder_parser->set("layer_num", _gcodegen.layer_index);
         }
         
         this->flush_filters();
     }
 
     // Write end commands to file.
-    fh << gcodegen.retract(); // TODO: process this retract through PressureRegulator in order to discharge fully
+    fh << _gcodegen.retract(); // TODO: process this retract through PressureRegulator in order to discharge fully
 
     {
-        auto filament_extruder {0U};
+        auto filament_extruder = 0U;
         for(const auto& end_gcode : config.end_filament_gcode.values) {
-            gcodegen.placeholder_parser->set("filament_extruder_id", filament_extruder++);
-            fh << apply_math(gcodegen.placeholder_parser->process(end_gcode));
+            _gcodegen.placeholder_parser->set("filament_extruder_id", filament_extruder++);
+            fh << apply_math(_gcodegen.placeholder_parser->process(end_gcode));
         }
     }
 
-    fh << apply_math(gcodegen.placeholder_parser->process(config.end_gcode));
+    fh << apply_math(_gcodegen.placeholder_parser->process(config.end_gcode));
 
     // set bed temperature
     if (config.has_heatbed && temp > 0 && std::regex_search(config.end_gcode.getString(), bed_temp_regex)) {
-        fh << gcodegen.writer.set_bed_temperature(0, 0);
+        fh << _gcodegen.writer.set_bed_temperature(0, 0);
     }
 
     // Get filament stats
-    print.filament_stats.clear();
-    print.total_used_filament = 0.0;
-    print.total_extruded_volume = 0.0;
-    print.total_weight = 0.0;
-    print.total_cost = 0.0;
+    _print.filament_stats.clear();
+    _print.total_used_filament = 0.0;
+    _print.total_extruded_volume = 0.0;
+    _print.total_weight = 0.0;
+    _print.total_cost = 0.0;
 
     
-    for (auto extruder_pair : gcodegen.writer.extruders) {
-        const auto& extruder {extruder_pair.second};
-        auto used_material {extruder.used_filament()};
-        auto extruded_volume {extruder.extruded_volume()};
-        auto material_weight {extruded_volume * extruder.filament_density() / 1000.0};
-        auto material_cost { material_weight * (extruder.filament_cost() / 1000.0)};
+    for (auto extruder_pair : _gcodegen.writer.extruders) {
+        const Extruder& extruder { extruder_pair.second };
+        const auto used_material   = extruder.used_filament();
+        const auto extruded_volume = extruder.extruded_volume();
+        const auto material_weight = extruded_volume * extruder.filament_density() / 1000.0;
+        const auto material_cost   = material_weight * (extruder.filament_cost() / 1000.0);
 
-        print.filament_stats[extruder.id] = used_material;
+        _print.filament_stats[extruder.id] = used_material;
 
         fh << "; material used = ";
         fh << std::fixed << std::setprecision(2) << used_material << "mm ";
@@ -321,28 +345,28 @@ PrintGCode::output()
            << used_material << "cm3)\n";
 
         if (material_weight > 0) {
-            print.total_weight += material_weight;
+            _print.total_weight += material_weight;
             fh << "; material used = " 
                << std::fixed << std::setprecision(2) << material_weight << "g\n";
             if (material_cost > 0) {
-                print.total_cost += material_cost;
+                _print.total_cost += material_cost;
                 fh << "; material cost = " 
                    << std::fixed << std::setprecision(2) << material_weight << "g\n";
             }
         }
-        print.total_used_filament += used_material;
-        print.total_extruded_volume += extruded_volume;
+        _print.total_used_filament += used_material;
+        _print.total_extruded_volume += extruded_volume;
     }
     fh << "; total filament cost = " 
-       << std::fixed << std::setprecision(2) << print.total_cost << "\n";
+       << std::fixed << std::setprecision(2) << _print.total_cost << "\n";
 
     // Append full config
     fh << std::endl;
 
     // print config
-    _print_config(print.config);
-    _print_config(print.default_object_config);
-    _print_config(print.default_region_config);
+    _print_config(_print.config);
+    _print_config(_print.default_object_config);
+    _print_config(_print.default_region_config);
 }
 
 std::string 
@@ -355,17 +379,14 @@ void
 PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
 {
     std::string gcode {""};
-    auto& gcodegen {this->_gcodegen};
-    const auto& print {this->_print};
-    const auto& config {this->config};
 
-    const auto& obj {*(layer->object())};
-    gcodegen.config.apply(obj.config, true);
+    const PrintObject& obj { *layer->object() };
+    _gcodegen.config.apply(obj.config, true);
 
     // check for usage of spiralvase logic.
     this->_spiral_vase.enable = (
             layer->id() > 0 
-            && (print.config.skirts == 0 || (layer->id() >= print.config.skirt_height && !print.has_infinite_skirt()))
+            && (_print.config.skirts == 0 || (layer->id() >= _print.config.skirt_height && !_print.has_infinite_skirt()))
             && std::find_if(layer->regions.cbegin(), layer->regions.cend(), [layer] (const LayerRegion* l) 
                 { return    l->region()->config.bottom_solid_layers > layer->id() 
                          || l->perimeters.items_count() > 1 
@@ -382,9 +403,9 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
     {
         // get the minimum cross-section used in the layer.
         std::vector<double> mm3_per_mm;
-        for (auto region_id = 0U; region_id < print.regions.size(); ++region_id) {
-            const auto& region {print.regions.at(region_id)};
-            const auto& layerm {layer->get_region(region_id)};
+        for (auto region_id = 0U; region_id < _print.regions.size(); ++region_id) {
+            const PrintRegion* region = _print.get_region(region_id);
+            const LayerRegion* layerm = layer->get_region(region_id);
 
             if (!(region->config.get_abs_value("perimeter_speed") > 0 &&
                 region->config.get_abs_value("small_perimeter_speed") > 0 &&
@@ -417,53 +438,53 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
         // TODO make the definition of "too thin" based on a config somewhere
         mm3_per_mm.erase(std::remove_if(mm3_per_mm.begin(), mm3_per_mm.end(), [] (const double& vol) { return vol <= 0.01;} ), mm3_per_mm.end());
         if (mm3_per_mm.size() > 0) {
-            const auto min_mm3_per_mm {*(std::min_element(mm3_per_mm.begin(), mm3_per_mm.end()))};
+            const double min_mm3_per_mm { *(std::min_element(mm3_per_mm.begin(), mm3_per_mm.end())) };
             // In order to honor max_print_speed we need to find a target volumetric
-            // speed that we can use throughout the print. So we define this target 
+            // speed that we can use throughout the _print. So we define this target 
             // volumetric speed as the volumetric speed produced by printing the 
             // smallest cross-section at the maximum speed: any larger cross-section
             // will need slower feedrates.
-            auto volumetric_speed {min_mm3_per_mm * config.max_print_speed};
+            double volumetric_speed { min_mm3_per_mm * config.max_print_speed };
             if (config.max_volumetric_speed > 0) {
                 volumetric_speed = std::min(volumetric_speed, config.max_volumetric_speed.getFloat());
             }
-            gcodegen.volumetric_speed = volumetric_speed;
+            _gcodegen.volumetric_speed = volumetric_speed;
         }
     }
     // set the second layer + temp
     if (!this->_second_layer_things_done && layer->id() == 1) {
-        for (const auto& extruder_ref : gcodegen.writer.extruders) {
-            const auto& extruder { extruder_ref.second };
-            auto temp { config.temperature.get_at(extruder.id) };
+        for (const auto& extruder_ref : _gcodegen.writer.extruders) {
+            const Extruder& extruder { extruder_ref.second };
+            auto temp = config.temperature.get_at(extruder.id);
 
             if (temp > 0 && temp != config.first_layer_temperature.get_at(extruder.id) )
-                gcode += gcodegen.writer.set_temperature(temp, 0, extruder.id);
+                gcode += _gcodegen.writer.set_temperature(temp, 0, extruder.id);
 
         }
-        if (config.has_heatbed && print.config.first_layer_bed_temperature > 0 && print.config.bed_temperature != print.config.first_layer_bed_temperature) {
-            gcode += gcodegen.writer.set_bed_temperature(print.config.bed_temperature);
+        if (config.has_heatbed && _print.config.first_layer_bed_temperature > 0 && _print.config.bed_temperature != _print.config.first_layer_bed_temperature) {
+            gcode += _gcodegen.writer.set_bed_temperature(_print.config.bed_temperature);
         }
         this->_second_layer_things_done = true;
     }
 
     // set new layer - this will change Z and force a retraction if retract_layer_change is enabled
-    if (print.config.before_layer_gcode.getString().size() > 0) {
-        auto pp {*(gcodegen.placeholder_parser)};
-        pp.set("layer_num", gcodegen.layer_index);
+    if (_print.config.before_layer_gcode.getString().size() > 0) {
+        PlaceholderParser pp { *_gcodegen.placeholder_parser };
+        pp.set("layer_num", _gcodegen.layer_index);
         pp.set("layer_z", layer->print_z);
-        pp.set("current_retraction", gcodegen.writer.extruder()->retracted);
+        pp.set("current_retraction", _gcodegen.writer.extruder()->retracted);
 
-        gcode += apply_math(pp.process(print.config.before_layer_gcode.getString()));
+        gcode += apply_math(pp.process(_print.config.before_layer_gcode.getString()));
         gcode += "\n";
     }
-    gcode += gcodegen.change_layer(*layer);
-    if (print.config.layer_gcode.getString().size() > 0) {
-        auto pp {*(gcodegen.placeholder_parser)};
-        pp.set("layer_num", gcodegen.layer_index);
+    gcode += _gcodegen.change_layer(*layer);
+    if (_print.config.layer_gcode.getString().size() > 0) {
+        PlaceholderParser pp { *_gcodegen.placeholder_parser };
+        pp.set("layer_num", _gcodegen.layer_index);
         pp.set("layer_z", layer->print_z);
-        pp.set("current_retraction", gcodegen.writer.extruder()->retracted);
+        pp.set("current_retraction", _gcodegen.writer.extruder()->retracted);
 
-        gcode += apply_math(pp.process(print.config.layer_gcode.getString()));
+        gcode += apply_math(pp.process(_print.config.layer_gcode.getString()));
         gcode += "\n";
     }
 
@@ -471,73 +492,73 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
     // extrude skirt along raft layers and normal obj layers
     // (not along interlaced support material layers)
     if (layer->id() < static_cast<size_t>(obj.config.raft_layers)
-        || ((print.has_infinite_skirt() || _skirt_done.size() == 0 || (_skirt_done.rbegin())->first < print.config.skirt_height)
+        || ((_print.has_infinite_skirt() || _skirt_done.size() == 0 || (_skirt_done.rbegin())->first < _print.config.skirt_height)
         && _skirt_done.count(scale_(layer->print_z)) == 0
         && typeid(layer) != typeid(SupportLayer*)) ) {
 
 
-        gcodegen.set_origin(Pointf(0,0));
-        gcodegen.avoid_crossing_perimeters.use_external_mp = true;
+        _gcodegen.set_origin(Pointf(0,0));
+        _gcodegen.avoid_crossing_perimeters.use_external_mp = true;
         
         /// data load 
         std::vector<size_t> extruder_ids;
-        extruder_ids.reserve(gcodegen.writer.extruders.size());
-        std::transform(gcodegen.writer.extruders.cbegin(), gcodegen.writer.extruders.cend(), std::back_inserter(extruder_ids), 
+        extruder_ids.reserve(_gcodegen.writer.extruders.size());
+        std::transform(_gcodegen.writer.extruders.cbegin(), _gcodegen.writer.extruders.cend(), std::back_inserter(extruder_ids), 
                        [] (const std::pair<unsigned int, Extruder>& z) -> std::size_t { return z.second.id; } );
-        gcode += gcodegen.set_extruder(extruder_ids.at(0));
+        gcode += _gcodegen.set_extruder(extruder_ids.at(0));
 
         // skip skirt if a large brim
-        if (print.has_infinite_skirt() || layer->id() < static_cast<size_t>(print.config.skirt_height)) {
-            const auto& skirt_flow {print.skirt_flow()};
+        if (_print.has_infinite_skirt() || layer->id() < static_cast<size_t>(_print.config.skirt_height)) {
+            const Flow skirt_flow { _print.skirt_flow() };
 
             // distribute skirt loops across all extruders in layer 0
-            auto skirt_loops {print.skirt.flatten().entities};
+            const auto skirt_loops = _print.skirt.flatten().entities;
             for (size_t i = 0; i < skirt_loops.size(); ++i) {
                 
                 // when printing layers > 0 ignore 'min_skirt_length' and 
                 // just use the 'skirts' setting; also just use the current extruder
-                if (layer->id() > 0 && i >= static_cast<size_t>(print.config.skirts)) break; 
-                const auto extruder_id { extruder_ids.at((i / extruder_ids.size()) % extruder_ids.size()) };
+                if (layer->id() > 0 && i >= static_cast<size_t>(_print.config.skirts)) break; 
+                const size_t extruder_id { extruder_ids.at((i / extruder_ids.size()) % extruder_ids.size()) };
                 if (layer->id() == 0)
-                    gcode += gcodegen.set_extruder(extruder_id);
+                    gcode += _gcodegen.set_extruder(extruder_id);
 
                 // adjust flow according to layer height
-                auto& loop {*(dynamic_cast<ExtrusionLoop*>(skirt_loops.at(i)))};
+                auto& loop = *dynamic_cast<ExtrusionLoop*>(skirt_loops.at(i));
                 {
                     Flow layer_skirt_flow(skirt_flow);
                     layer_skirt_flow.height = layer->height;
 
-                    auto mm3_per_mm {layer_skirt_flow.mm3_per_mm()};
+                    const auto mm3_per_mm = layer_skirt_flow.mm3_per_mm();
 
                     for (auto& path : loop.paths) {
                         path.height = layer->height;
                         path.mm3_per_mm = mm3_per_mm;
                     }
                 }
-                gcode += gcodegen.extrude(loop, "skirt", obj.config.support_material_speed);
+                gcode += _gcodegen.extrude(loop, "skirt", obj.config.support_material_speed);
             }
 
         }
 
         this->_skirt_done[scale_(layer->print_z)] = true; 
-        gcodegen.avoid_crossing_perimeters.use_external_mp = false;
+        _gcodegen.avoid_crossing_perimeters.use_external_mp = false;
 
-        if (layer->id() == 0) gcodegen.avoid_crossing_perimeters.disable_once = true;
+        if (layer->id() == 0) _gcodegen.avoid_crossing_perimeters.disable_once = true;
     }
 
     // extrude brim
     if (this->_brim_done) {
-        gcode += gcodegen.set_extruder(print.brim_extruder() - 1);
-        gcodegen.set_origin(Pointf(0,0));
-        gcodegen.avoid_crossing_perimeters.use_external_mp = true;
-        for (const auto& b : print.brim.entities) {
-            gcode += gcodegen.extrude(*b, "brim", obj.config.get_abs_value("support_material_speed"));
+        gcode += _gcodegen.set_extruder(_print.brim_extruder() - 1);
+        _gcodegen.set_origin(Pointf(0,0));
+        _gcodegen.avoid_crossing_perimeters.use_external_mp = true;
+        for (const auto& b : _print.brim.entities) {
+            gcode += _gcodegen.extrude(*b, "brim", obj.config.get_abs_value("support_material_speed"));
         }
         this->_brim_done = true;
-        gcodegen.avoid_crossing_perimeters.use_external_mp = false;
+        _gcodegen.avoid_crossing_perimeters.use_external_mp = false;
         
         // allow a straight travel move to the first object point
-        gcodegen.avoid_crossing_perimeters.disable_once = true;
+        _gcodegen.avoid_crossing_perimeters.disable_once = true;
     }
 
     auto copy_idx = 0U;
@@ -548,10 +569,10 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
 
         // when starting a new object, use the external motion planner for the first travel move
         if (this->_last_obj_copy.first != copy && this->_last_obj_copy.second )
-            gcodegen.avoid_crossing_perimeters.use_external_mp = true;
+            _gcodegen.avoid_crossing_perimeters.use_external_mp = true;
         this->_last_obj_copy.first = copy;
         this->_last_obj_copy.second = true;
-        gcodegen.set_origin(Pointf::new_unscale(copy));
+        _gcodegen.set_origin(Pointf::new_unscale(copy));
 
         // extrude support material before other things because it might use a lower Z
         // and also because we avoid travelling on other things when printing it
@@ -559,17 +580,17 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
             const SupportLayer* slayer = dynamic_cast<const SupportLayer*>(layer);
             ExtrusionEntityCollection paths; 
             if (slayer->support_interface_fills.size() > 0) {
-                gcode += gcodegen.set_extruder(obj.config.support_material_interface_extruder - 1);
-                slayer->support_interface_fills.chained_path_from(gcodegen.last_pos(), &paths, false);
+                gcode += _gcodegen.set_extruder(obj.config.support_material_interface_extruder - 1);
+                slayer->support_interface_fills.chained_path_from(_gcodegen.last_pos(), &paths, false);
                 for (const auto& path : paths) {
-                    gcode += gcodegen.extrude(*path, "support material interface", obj.config.get_abs_value("support_material_interface_speed"));
+                    gcode += _gcodegen.extrude(*path, "support material interface", obj.config.get_abs_value("support_material_interface_speed"));
                 }
             }
             if (slayer->support_fills.size() > 0) {
-                gcode += gcodegen.set_extruder(obj.config.support_material_extruder - 1);
-                slayer->support_fills.chained_path_from(gcodegen.last_pos(), &paths, false);
+                gcode += _gcodegen.set_extruder(obj.config.support_material_extruder - 1);
+                slayer->support_fills.chained_path_from(_gcodegen.last_pos(), &paths, false);
                 for (const auto& path : paths) {
-                    gcode += gcodegen.extrude(*path, "support material", obj.config.get_abs_value("support_material_speed"));
+                    gcode += _gcodegen.extrude(*path, "support material", obj.config.get_abs_value("support_material_speed"));
                 }
             }
         }
@@ -594,25 +615,25 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
         // cache bounding boxes of layer slices
         std::vector<BoundingBox> layer_slices_bb;
         std::transform(layer->slices.cbegin(), layer->slices.cend(), std::back_inserter(layer_slices_bb), [] (const ExPolygon& s)-> BoundingBox { return s.bounding_box(); });
-        auto point_inside_surface { [&layer_slices_bb, &layer] (size_t i, Point point) -> bool {
-            const auto& bbox {layer_slices_bb.at(i)};
+        auto point_inside_surface = [&layer_slices_bb, &layer] (size_t i, Point point) -> bool {
+            const BoundingBox& bbox { layer_slices_bb.at(i) };
             return bbox.contains(point) && layer->slices.at(i).contour.contains(point);
-        }};
-        const auto n_slices {layer->slices.size()};
+        };
+        const size_t n_slices { layer->slices.size() };
 
-        for (auto region_id = 0U; region_id < print.regions.size(); ++region_id) {
+        for (auto region_id = 0U; region_id < _print.regions.size(); ++region_id) {
             const LayerRegion* layerm;
             try {
                 layerm = layer->get_region(region_id); // we promise to be good and not give this to anyone who will modify it
             } catch (std::out_of_range &e) {
                 continue; // if no regions, bail;
             }
-            auto* region {print.get_region(region_id)};
+            const PrintRegion* region { _print.get_region(region_id) };
             // process perimeters
             {
                 auto extruder_id = region->config.perimeter_extruder-1;
                 // Casting away const just to avoid double dereferences
-                for(auto* perimeter_coll : layerm->perimeters.flatten().entities) {
+                for(const auto* perimeter_coll : layerm->perimeters.flatten().entities) {
 
                     if(perimeter_coll->length() == 0) continue;  // this shouldn't happen but first_point() would fail
                     
@@ -654,10 +675,10 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
         
         // tweak extruder ordering to save toolchanges
         
-        auto last_extruder = gcodegen.writer.extruder()->id;
+        auto last_extruder = _gcodegen.writer.extruder()->id;
         if (by_extruder.count(last_extruder)) {
             for(auto &island : by_extruder[last_extruder]) {
-               if (print.config.infill_first()) {
+               if (_print.config.infill_first()) {
                     gcode += this->_extrude_infill(std::get<1>(island.second));
                     gcode += this->_extrude_perimeters(std::get<0>(island.second));
                 } else {
@@ -668,9 +689,9 @@ PrintGCode::process_layer(size_t idx, const Layer* layer, const Points& copies)
         }
         for(auto &pair : by_extruder) {
             if(pair.first == last_extruder)continue;
-            gcode += gcodegen.set_extruder(pair.first);
+            gcode += _gcodegen.set_extruder(pair.first);
             for(auto &island : pair.second) {
-               if (print.config.infill_first()) {
+               if (_print.config.infill_first()) {
                     gcode += this->_extrude_infill(std::get<1>(island.second));
                     gcode += this->_extrude_perimeters(std::get<0>(island.second));
                 } else {
@@ -733,16 +754,10 @@ PrintGCode::_extrude_infill(std::map<size_t,ExtrusionEntityCollection> &by_regio
 void
 PrintGCode::_print_first_layer_temperature(bool wait) 
 {
-    auto& gcodegen {this->_gcodegen};
-    auto& fh {this->fh};
-    const auto& print {this->_print};
-    const auto& config {this->config};
-    const auto extruders {print.extruders()};
-
-    for (auto& t : extruders) {
-        auto temp { config.first_layer_temperature.get_at(t) };
+    for (auto& t : _print.extruders()) {
+        auto temp = config.first_layer_temperature.get_at(t);
         if (config.ooze_prevention.value) temp += config.standby_temperature_delta.value;
-        if (temp > 0) fh << gcodegen.writer.set_temperature(temp, wait, t);
+        if (temp > 0) fh << _gcodegen.writer.set_temperature(temp, wait, t);
     }
 }
 
@@ -758,9 +773,9 @@ PrintGCode::_print_config(const ConfigBase& config)
 
 PrintGCode::PrintGCode(Slic3r::Print& print, std::ostream& _fh) : 
         _print(print), 
-        config(print.config), 
+        config(_print.config), 
         _gcodegen(Slic3r::GCode()),
-        objects(print.objects),
+        objects(_print.objects),
         fh(_fh),
         _cooling_buffer(Slic3r::CoolingBuffer(this->_gcodegen)),
         _spiral_vase(Slic3r::SpiralVase(this->config))
@@ -771,16 +786,16 @@ PrintGCode::PrintGCode(Slic3r::Print& print, std::ostream& _fh) :
     } else {
         layer_count = std::accumulate(objects.cbegin(), objects.cend(), layer_count, [](const size_t& ret, const PrintObject* obj){ return ret + obj->total_layer_count(); });
     }
-    _gcodegen.placeholder_parser = &(print.placeholder_parser); // initialize 
+    _gcodegen.placeholder_parser = &(_print.placeholder_parser); // initialize 
     _gcodegen.layer_count = layer_count;
     _gcodegen.enable_cooling_markers = true;
     _gcodegen.apply_print_config(config);
     
     if (config.spiral_vase) _spiral_vase.enable = true;
 
-    auto extruders {print.extruders()}; 
+    const auto extruders = _print.extruders();
     _gcodegen.set_extruders(extruders.cbegin(), extruders.cend());
 }
 
 } // namespace Slic3r
-#endif //SLIC3RXS
+

+ 0 - 2
xs/src/libslic3r/PrintGCode.hpp

@@ -1,4 +1,3 @@
-#ifndef SLIC3RXS
 #ifndef slic3r_PrintGCode_hpp
 #define slic3r_PrintGCode_hpp
 
@@ -77,4 +76,3 @@ private:
 } // namespace Slic3r
 
 #endif // slic3r_PrintGCode_hpp
-#endif // SLIC3RXS

+ 44 - 65
xs/src/libslic3r/PrintObject.cpp

@@ -38,12 +38,6 @@ PrintObject::~PrintObject()
 {
 }
 
-Print*
-PrintObject::print()
-{
-    return this->_print;
-}
-
 Points
 PrintObject::copies() const
 {
@@ -952,7 +946,6 @@ PrintObject::_slice_region(size_t region_id, std::vector<float> z, bool modifier
     return layers;
 }
 
-#ifndef SLIC3RXS
 void
 PrintObject::make_perimeters()
 {
@@ -966,28 +959,22 @@ PrintObject::make_perimeters()
 void
 PrintObject::slice()
 {
-    auto* print {this->print()};
     if (this->state.is_done(posSlice)) return;
     this->state.set_started(posSlice);
-    if (print->status_cb != nullptr) {
-        print->status_cb(10, "Processing triangulated mesh");
+    if (_print->status_cb != nullptr) {
+        _print->status_cb(10, "Processing triangulated mesh");
     }
 
 
     this->_slice(); 
 
     // detect slicing errors
-    bool warning_thrown = false;
-    for (size_t i = 0U; i < this->layer_count(); ++i) {
-        auto* layer {this->get_layer(i)};
-        if (!layer->slicing_errors) continue;
-        if (!warning_thrown) {
-            Slic3r::Log::warn("PrintObject") << "The model has overlapping or self-intersecting facets. " 
-                                             << "I tried to repair it, however you might want to check " 
-                                             << "the results or repair the input file and retry.\n";
-            warning_thrown = true;
-        }
-    }
+    if (std::any_of(this->layers.cbegin(), this->layers.cend(),
+        [](const Layer* l){ return l->slicing_errors; }))
+        Slic3r::Log::warn("PrintObject") << "The model has overlapping or self-intersecting facets. " 
+                                         << "I tried to repair it, however you might want to check " 
+                                         << "the results or repair the input file and retry.\n";
+    
     if (this->layers.size() == 0) {
         Slic3r::Log::error("PrintObject") << "slice(): " << "No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n";
         return; // make this throw an exception instead?
@@ -998,7 +985,6 @@ PrintObject::slice()
     this->state.set_done(posSlice);
 }
 
-#endif // SLIC3RXS
 void
 PrintObject::_make_perimeters()
 {
@@ -1142,7 +1128,6 @@ PrintObject::_infill()
     this->state.set_done(posInfill);
 }
 
-#ifndef SLIC3RXS
 void
 PrintObject::prepare_infill()
 {
@@ -1304,8 +1289,6 @@ PrintObject::infill()
     this->_infill();
 }
 
-#endif //SLIC3RXS
-
 SupportMaterial *
 PrintObject::_support_material()
 {
@@ -1357,12 +1340,10 @@ PrintObject::_support_material_flow(FlowRole role)
 
     return support_flow;
 }
-#ifndef SLIC3RXS
+
 void
 PrintObject::generate_support_material() 
 {
-    auto* print { this->_print };
-    const auto& config { this->config };
     //prereqs 
     this->slice();
     if (this->state.is_done(posSupportMaterial)) { return; }
@@ -1379,8 +1360,8 @@ PrintObject::generate_support_material()
         this->state.set_done(posSupportMaterial);
         return;
     }
-    if (print->status_cb != nullptr)
-        print->status_cb(85, "Generating support material");
+    if (_print->status_cb != nullptr)
+        _print->status_cb(85, "Generating support material");
 
     this->_support_material()->generate(this);
 
@@ -1388,8 +1369,8 @@ PrintObject::generate_support_material()
 
     std::stringstream stats {""};
 
-    if (print->status_cb != nullptr)
-        print->status_cb(85, stats.str().c_str());
+    if (_print->status_cb != nullptr)
+        _print->status_cb(85, stats.str().c_str());
 
 }
 
@@ -1397,15 +1378,14 @@ PrintObject::generate_support_material()
 void 
 PrintObject::discover_horizontal_shells()
 {
-    auto* print {this->print()};
-    for (size_t region_id = 0U; region_id < print->regions.size(); ++region_id) {
+    for (size_t region_id = 0U; region_id < _print->regions.size(); ++region_id) {
         for (size_t i = 0; i < this->layer_count(); ++i) {
-            auto* layerm {this->get_layer(i)->regions.at(region_id)};
-            const auto& region_config {layerm->region()->config};
+            auto* layerm = this->get_layer(i)->get_region(region_id);
+            const auto& region_config = layerm->region()->config;
 
             if (region_config.solid_infill_every_layers() > 0 && region_config.fill_density() > 0
                 && (i % region_config.solid_infill_every_layers()) == 0) {
-                const auto type {region_config.fill_density() == 100 ? stInternalSolid : stInternalBridge };
+                const auto type = region_config.fill_density() == 100 ? stInternalSolid : stInternalBridge;
                 // set the surface type to internal for the types
                 std::for_each(layerm->fill_surfaces.begin(), layerm->fill_surfaces.end(), [type] (Surface& s) { s.surface_type = (s.surface_type == type ? stInternal : s.surface_type); });
             }
@@ -1417,7 +1397,7 @@ PrintObject::discover_horizontal_shells()
 void
 PrintObject::_discover_external_horizontal_shells(LayerRegion* layerm, const size_t& i, const size_t& region_id)
 {
-    const auto& region_config {layerm->region()->config};
+    const auto& region_config = layerm->region()->config;
     for (auto& type : { stTop, stBottom, stBottomBridge }) {
         // find slices of current type for current layer
         // use slices instead of fill_surfaces because they also include the perimeter area
@@ -1430,7 +1410,7 @@ PrintObject::_discover_external_horizontal_shells(LayerRegion* layerm, const siz
         // too much solid infill inside nearly-vertical slopes.
       
         Polygons solid; 
-        auto tmp {layerm->slices.filter_by_type(type)};
+        auto tmp = layerm->slices.filter_by_type(type);
         polygons_append(solid, tmp);
         tmp.clear();
         tmp = layerm->fill_surfaces.filter_by_type(type);
@@ -1438,11 +1418,11 @@ PrintObject::_discover_external_horizontal_shells(LayerRegion* layerm, const siz
 
         if (solid.size() == 0) continue;
 
-        auto solid_layers { type == stTop ? region_config.top_solid_layers() : region_config.bottom_solid_layers() };
+        auto solid_layers = type == stTop ? region_config.top_solid_layers() : region_config.bottom_solid_layers();
 
         if (region_config.min_top_bottom_shell_thickness() > 0) {
-            auto current_shell_thick { static_cast<coordf_t>(solid_layers) * this->get_layer(i)->height };
-            const auto& min_shell_thick { region_config.min_top_bottom_shell_thickness() };
+            auto current_shell_thick = static_cast<coordf_t>(solid_layers) * this->get_layer(i)->height;
+            const auto min_shell_thick = region_config.min_top_bottom_shell_thickness();
             while (std::abs(min_shell_thick - current_shell_thick) > Slic3r::Geometry::epsilon) {
                 solid_layers++;
                 current_shell_thick = static_cast<coordf_t>(solid_layers) * this->get_layer(i)->height;
@@ -1455,19 +1435,19 @@ PrintObject::_discover_external_horizontal_shells(LayerRegion* layerm, const siz
 void
 PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const size_t& i, const size_t& region_id, const SurfaceType& type, Polygons& solid, const size_t& solid_layers)
 {
-    const auto& region_config {layerm->region()->config};
+    const auto& region_config = layerm->region()->config;
 
     for (int n = (type == stTop ? i-1 : i+1); std::abs(n-int(i)) < solid_layers; (type == stTop ? n-- : n++)) {
         if (n < 0 || static_cast<size_t>(n) >= this->layer_count()) continue;
 
-        auto* neighbor_layerm { this->get_layer(n)->regions.at(region_id) };
+        LayerRegion* neighbor_layerm { this->get_layer(n)->get_region(region_id) };
         // make a copy so we can use them even after clearing the original collection
-        auto  neighbor_fill_surfaces{ SurfaceCollection(neighbor_layerm->fill_surfaces) };
+        SurfaceCollection neighbor_fill_surfaces{ neighbor_layerm->fill_surfaces };
         // find intersection between neighbor and current layer's surfaces
         // intersections have contours and holes
         Polygons filtered_poly;
         polygons_append(filtered_poly, neighbor_fill_surfaces.filter_by_type({stInternal, stInternalSolid}));
-        auto new_internal_solid { intersection(solid, filtered_poly , 1 ) };
+        auto new_internal_solid = intersection(solid, filtered_poly , 1 );
         if (new_internal_solid.size() == 0) {
             // No internal solid needed on this layer. In order to decide whether to continue
             // searching on the next neighbor (thus enforcing the configured number of solid
@@ -1490,8 +1470,8 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
             // than a perimeter width, since it's probably just crossing a sloping wall
             // and it's not wanted in a hollow print even if it would make sense when
             // obeying the solid shell count option strictly (DWIM!)
-            auto margin { neighbor_layerm->flow(frExternalPerimeter).scaled_width()};
-            auto too_narrow { diff(new_internal_solid, offset2(new_internal_solid, -margin, +margin, CLIPPER_OFFSET_SCALE, ClipperLib::jtMiter, 5), 1)}; 
+            const auto margin = neighbor_layerm->flow(frExternalPerimeter).scaled_width();
+            const auto too_narrow = diff(new_internal_solid, offset2(new_internal_solid, -margin, +margin, CLIPPER_OFFSET_SCALE, ClipperLib::jtMiter, 5), 1); 
             if (too_narrow.size() > 0) 
                 new_internal_solid = solid = diff(new_internal_solid, too_narrow);
         }
@@ -1499,16 +1479,16 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
         // make sure the new internal solid is wide enough, as it might get collapsed
         // when spacing is added in Slic3r::Fill
         {
-            auto margin {3 * layerm->flow(frSolidInfill).scaled_width()};
+            const auto margin = 3 * layerm->flow(frSolidInfill).scaled_width();
 
             // we use a higher miterLimit here to handle areas with acute angles
             // in those cases, the default miterLimit would cut the corner and we'd
             // get a triangle in $too_narrow; if we grow it below then the shell
             // would have a different shape from the external surface and we'd still
             // have the same angle, so the next shell would be grown even more and so on.
-            auto too_narrow { diff(new_internal_solid, offset2(new_internal_solid, -margin, +margin, CLIPPER_OFFSET_SCALE, ClipperLib::jtMiter, 5), 1) };
+            const auto too_narrow = diff(new_internal_solid, offset2(new_internal_solid, -margin, +margin, CLIPPER_OFFSET_SCALE, ClipperLib::jtMiter, 5), 1);
 
-            if (too_narrow.size() > 0) {
+            if (!too_narrow.empty()) {
                 // grow the collapsing parts and add the extra area to  the neighbor layer 
                 // as well as to our original surfaces so that we support this 
                 // additional area in the next shell too
@@ -1518,16 +1498,16 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
                 for (auto& s : neighbor_fill_surfaces) {
                     if (s.is_internal() && !s.is_bridge()) tmp_internal.emplace_back(Polygon(s.expolygon)); 
                 }
-                auto grown {intersection(
-                offset(too_narrow, +margin),
-                // Discard bridges as they are grown for anchoring and we cant
-                // remove such anchors. (This may happen when a bridge is being 
-                // anchored onto a wall where little space remains after the bridge
-                // is grown, and that little space is an internal solid shell so 
-                // it triggers this too_narrow logic.)
-                tmp_internal)
-                };
-                new_internal_solid = solid = diff(new_internal_solid, too_narrow);
+                const auto grown = intersection(
+                    offset(too_narrow, +margin),
+                    // Discard bridges as they are grown for anchoring and we cant
+                    // remove such anchors. (This may happen when a bridge is being 
+                    // anchored onto a wall where little space remains after the bridge
+                    // is grown, and that little space is an internal solid shell so 
+                    // it triggers this too_narrow logic.)
+                    tmp_internal
+                );
+                new_internal_solid = solid = diff(grown, new_internal_solid);
             }
         }
         // internal-solid are the union of the existing internal-solid surfaces
@@ -1535,11 +1515,11 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
         
         Polygons tmp_internal { to_polygons(neighbor_fill_surfaces.filter_by_type(stInternalSolid)) };
         polygons_append(tmp_internal, neighbor_fill_surfaces.surfaces);
-        auto internal_solid {union_ex(tmp_internal)};
+        const auto internal_solid = union_ex(tmp_internal);
 
         // subtract intersections from layer surfaces to get resulting internal surfaces
         tmp_internal = to_polygons(neighbor_fill_surfaces.filter_by_type(stInternal));
-        auto internal { diff_ex(tmp_internal, to_polygons(internal_solid), 1) };
+        const auto internal = diff_ex(tmp_internal, to_polygons(internal_solid), 1);
 
         // assign resulting internal surfaces to layer
         neighbor_fill_surfaces.clear();
@@ -1563,7 +1543,7 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
             both_solids.insert(both_solids.end(), internal_solid.begin(), internal_solid.end());
             both_solids.insert(both_solids.end(), internal.begin(), internal.end());
 
-            auto solid_surfaces { diff_ex(pp, to_polygons(both_solids), 1) };
+            const auto solid_surfaces = diff_ex(pp, to_polygons(both_solids), 1);
             for (auto exp : solid_surfaces) 
                 neighbor_fill_surfaces.surfaces.emplace_back(Surface(s.surface_type, exp));
         }
@@ -1645,5 +1625,4 @@ PrintObject::clip_fill_surfaces()
     }
 }
 
-#endif // SLIC3RXS
 }

Some files were not shown because too many files changed in this diff