From dd72016159a6bd38c715d163908969797dab4550 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Thu, 6 May 2021 15:08:57 +0200 Subject: [PATCH] FDM backend refactoring for const correctness, clarity ... --- src/libslic3r/GCode/ToolOrdering.cpp | 24 ++++------ src/libslic3r/Layer.cpp | 2 +- src/libslic3r/Layer.hpp | 9 ++-- src/libslic3r/Print.cpp | 14 +++--- src/libslic3r/PrintObject.cpp | 71 ++++++++++++++-------------- 5 files changed, 57 insertions(+), 63 deletions(-) diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 728a26957..9dc9f3f96 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -223,10 +223,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto layer_tools.extruder_override = extruder_override; // What extruders are required to print this object layer? - for (size_t region_id = 0; region_id < object.num_printing_regions(); ++ region_id) { - const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr; - if (layerm == nullptr) - continue; + for (const LayerRegion *layerm : layer->regions()) { const PrintRegion ®ion = layerm->region(); if (! layerm->perimeters.entities.empty()) { @@ -688,16 +685,14 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int // iterate through copies (aka PrintObject instances) first, so that we mark neighbouring infills to minimize travel moves for (unsigned int copy = 0; copy < num_of_copies; ++copy) { - - for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) { - const PrintRegion ®ion = object->printing_region(region_id); - + for (const LayerRegion *layerm : this_layer->regions()) { + const auto ®ion = layerm->region(); if (!region.config().wipe_into_infill && !object->config().wipe_into_objects) continue; bool wipe_into_infill_only = ! object->config().wipe_into_objects && region.config().wipe_into_infill; if (print.config().infill_first != perimeters_done || wipe_into_infill_only) { - for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections + for (const ExtrusionEntity* ee : layerm->fills.entities) { // iterate through all infill Collections auto* fill = dynamic_cast(ee); if (!is_overriddable(*fill, print.config(), *object, region)) @@ -721,7 +716,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int // Now the same for perimeters - see comments above for explanation: if (object->config().wipe_into_objects && print.config().infill_first == perimeters_done) { - for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) { + for (const ExtrusionEntity* ee : layerm->perimeters.entities) { auto* fill = dynamic_cast(ee); if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume) { set_extruder_override(fill, copy, new_extruder, num_of_copies); @@ -762,13 +757,12 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) size_t num_of_copies = object->instances().size(); for (size_t copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves - for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) { - const auto& region = object->printing_region(region_id); - + for (const LayerRegion *layerm : this_layer->regions()) { + const auto ®ion = layerm->region(); if (!region.config().wipe_into_infill && !object->config().wipe_into_objects) continue; - for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections + for (const ExtrusionEntity* ee : layerm->fills.entities) { // iterate through all infill Collections auto* fill = dynamic_cast(ee); if (!is_overriddable(*fill, print.config(), *object, region) @@ -791,7 +785,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) } // Now the same for perimeters - see comments above for explanation: - for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) { // iterate through all perimeter Collections + for (const ExtrusionEntity* ee : layerm->perimeters.entities) { // iterate through all perimeter Collections auto* fill = dynamic_cast(ee); if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, copy)) set_extruder_override(fill, copy, (print.config().infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies); diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index c3dcad162..3f2327686 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -27,7 +27,7 @@ bool Layer::empty() const return true; } -LayerRegion* Layer::add_region(PrintRegion* print_region) +LayerRegion* Layer::add_region(const PrintRegion *print_region) { m_regions.emplace_back(new LayerRegion(this, print_region)); return m_regions.back(); diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index f2cce4880..102a991ca 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -22,7 +22,6 @@ class LayerRegion public: Layer* layer() { return m_layer; } const Layer* layer() const { return m_layer; } - PrintRegion& region() { return *m_region; } const PrintRegion& region() const { return *m_region; } // collection of surfaces generated by slicing the original geometry @@ -86,12 +85,12 @@ public: protected: friend class Layer; - LayerRegion(Layer *layer, PrintRegion *region) : m_layer(layer), m_region(region) {} + LayerRegion(Layer *layer, const PrintRegion *region) : m_layer(layer), m_region(region) {} ~LayerRegion() {} private: - Layer *m_layer; - PrintRegion *m_region; + Layer *m_layer; + const PrintRegion *m_region; }; @@ -128,7 +127,7 @@ public: size_t region_count() const { return m_regions.size(); } const LayerRegion* get_region(int idx) const { return m_regions[idx]; } LayerRegion* get_region(int idx) { return m_regions[idx]; } - LayerRegion* add_region(PrintRegion* print_region); + LayerRegion* add_region(const PrintRegion *print_region); const LayerRegionPtrs& regions() const { return m_regions; } // Test whether whether there are any slices assigned to this layer. bool empty() const; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index d0235c40e..538ee6009 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -413,10 +413,12 @@ static inline bool sequential_print_vertical_clearance_valid(const Print &print) // Precondition: Print::validate() requires the Print::apply() to be called its invocation. std::string Print::validate(std::string* warning) const { + std::vector extruders = this->extruders(); + if (m_objects.empty()) return L("All objects are outside of the print volume."); - if (extruders().empty()) + if (extruders.empty()) return L("The supplied settings will cause an empty print."); if (m_config.complete_objects) { @@ -442,9 +444,9 @@ std::string Print::validate(std::string* warning) const if (this->has_wipe_tower() && ! m_objects.empty()) { // Make sure all extruders use same diameter filament and have the same nozzle diameter // EPSILON comparison is used for nozzles and 10 % tolerance is used for filaments - double first_nozzle_diam = m_config.nozzle_diameter.get_at(extruders().front()); - double first_filament_diam = m_config.filament_diameter.get_at(extruders().front()); - for (const auto& extruder_idx : extruders()) { + double first_nozzle_diam = m_config.nozzle_diameter.get_at(extruders.front()); + double first_filament_diam = m_config.filament_diameter.get_at(extruders.front()); + for (const auto& extruder_idx : extruders) { double nozzle_diam = m_config.nozzle_diameter.get_at(extruder_idx); double filament_diam = m_config.filament_diameter.get_at(extruder_idx); if (nozzle_diam - EPSILON > first_nozzle_diam || nozzle_diam + EPSILON < first_nozzle_diam @@ -462,7 +464,7 @@ std::string Print::validate(std::string* warning) const return L("Ooze prevention is currently not supported with the wipe tower enabled."); if (m_config.use_volumetric_e) return L("The Wipe Tower currently does not support volumetric E (use_volumetric_e=0)."); - if (m_config.complete_objects && extruders().size() > 1) + if (m_config.complete_objects && extruders.size() > 1) return L("The Wipe Tower is currently not supported for multimaterial sequential prints."); if (m_objects.size() > 1) { @@ -542,8 +544,6 @@ std::string Print::validate(std::string* warning) const } { - std::vector extruders = this->extruders(); - // Find the smallest used nozzle diameter and the number of unique nozzle diameters. double min_nozzle_diameter = std::numeric_limits::max(); double max_nozzle_diameter = 0; diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index e8f2284fb..33e961dbe 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -772,11 +772,11 @@ void PrintObject::detect_surfaces_type() bool interface_shells = ! spiral_vase && m_config.interface_shells.value; size_t num_layers = spiral_vase ? std::min(size_t(this->printing_region(0).config().bottom_solid_layers), m_layers.size()) : m_layers.size(); - for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++ idx_region) { - BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start"; + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << region_id << " in parallel - start"; #ifdef SLIC3R_DEBUG_SLICE_PROCESSING for (Layer *layer : m_layers) - layer->m_regions[idx_region]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial"); + layer->m_regions[region_id]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial"); #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ // If interface shells are allowed, the region->surfaces cannot be overwritten as they may be used by other threads. @@ -792,7 +792,7 @@ void PrintObject::detect_surfaces_type() ((num_layers > 1) ? num_layers - 1 : num_layers) : // In non-spiral vase mode, go over all layers. m_layers.size()), - [this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range& range) { + [this, region_id, interface_shells, &surfaces_new](const tbb::blocked_range& range) { // If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating // the support from the print. SurfaceType surface_type_bottom_other = @@ -800,9 +800,9 @@ void PrintObject::detect_surfaces_type() stBottom : stBottomBridge; for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { m_print->throw_if_canceled(); - // BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << idx_region << " and layer " << layer->print_z; + // BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << region_id << " and layer " << layer->print_z; Layer *layer = m_layers[idx_layer]; - LayerRegion *layerm = layer->m_regions[idx_region]; + LayerRegion *layerm = layer->m_regions[region_id]; // comparison happens against the *full* slices (considering all regions) // unless internal shells are requested Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? m_layers[idx_layer + 1] : nullptr; @@ -815,7 +815,7 @@ void PrintObject::detect_surfaces_type() Surfaces top; if (upper_layer) { ExPolygons upper_slices = interface_shells ? - diff_ex(layerm->slices.surfaces, upper_layer->m_regions[idx_region]->slices.surfaces, ApplySafetyOffset::Yes) : + diff_ex(layerm->slices.surfaces, upper_layer->m_regions[region_id]->slices.surfaces, ApplySafetyOffset::Yes) : diff_ex(layerm->slices.surfaces, upper_layer->lslices, ApplySafetyOffset::Yes); surfaces_append(top, offset2_ex(upper_slices, -offset, offset), stTop); } else { @@ -832,7 +832,7 @@ void PrintObject::detect_surfaces_type() #if 0 //FIXME Why is this branch failing t\multi.t ? Polygons lower_slices = interface_shells ? - to_polygons(lower_layer->get_region(idx_region)->slices.surfaces) : + to_polygons(lower_layer->get_region(region_id)->slices.surfaces) : to_polygons(lower_layer->slices); surfaces_append(bottom, offset2_ex(diff(layerm->slices.surfaces, lower_slices, true), -offset, offset), @@ -855,7 +855,7 @@ void PrintObject::detect_surfaces_type() offset2_ex( diff_ex( intersection(layerm->slices.surfaces, lower_layer->lslices), // supported - lower_layer->m_regions[idx_region]->slices.surfaces, + lower_layer->m_regions[region_id]->slices.surfaces, ApplySafetyOffset::Yes), -offset, offset), stBottom); @@ -888,7 +888,7 @@ void PrintObject::detect_surfaces_type() expolygons_with_attributes.emplace_back(std::make_pair(union_ex(top), SVG::ExPolygonAttributes("green"))); expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottom), SVG::ExPolygonAttributes("brown"))); expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices.surfaces), SVG::ExPolygonAttributes("black"))); - SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, idx_region, layer->print_z).c_str(), expolygons_with_attributes); + SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, region_id, layer->print_z).c_str(), expolygons_with_attributes); } #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ @@ -925,25 +925,25 @@ void PrintObject::detect_surfaces_type() if (interface_shells) { // Move surfaces_new to layerm->slices.surfaces for (size_t idx_layer = 0; idx_layer < num_layers; ++ idx_layer) - m_layers[idx_layer]->m_regions[idx_region]->slices.surfaces = std::move(surfaces_new[idx_layer]); + m_layers[idx_layer]->m_regions[region_id]->slices.surfaces = std::move(surfaces_new[idx_layer]); } if (spiral_vase) { if (num_layers > 1) // Turn the last bottom layer infill to a top infill, so it will be extruded with a proper pattern. - m_layers[num_layers - 1]->m_regions[idx_region]->slices.set_type(stTop); + m_layers[num_layers - 1]->m_regions[region_id]->slices.set_type(stTop); for (size_t i = num_layers; i < m_layers.size(); ++ i) - m_layers[i]->m_regions[idx_region]->slices.set_type(stInternal); + m_layers[i]->m_regions[region_id]->slices.set_type(stInternal); } - BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " - clipping in parallel - start"; + BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << region_id << " - clipping in parallel - start"; // Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces. tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), - [this, idx_region](const tbb::blocked_range& range) { + [this, region_id](const tbb::blocked_range& range) { for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { m_print->throw_if_canceled(); - LayerRegion *layerm = m_layers[idx_layer]->m_regions[idx_region]; + LayerRegion *layerm = m_layers[idx_layer]->m_regions[region_id]; layerm->slices_to_fill_surfaces_clipped(); #ifdef SLIC3R_DEBUG_SLICE_PROCESSING layerm->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-final"); @@ -951,7 +951,7 @@ void PrintObject::detect_surfaces_type() } // for each layer of a region }); m_print->throw_if_canceled(); - BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " - clipping in parallel - end"; + BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << region_id << " - clipping in parallel - end"; } // for each this->print->region_count // Mark the object to have the region slices classified (typed, which also means they are split based on whether they are supported, bridging, top layers etc.) @@ -1071,8 +1071,8 @@ void PrintObject::discover_vertical_shells() // is calculated over all materials. // Is the "ensure vertical wall thickness" applicable to any region? bool has_extra_layers = false; - for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++idx_region) { - const PrintRegionConfig &config = this->printing_region(idx_region).config(); + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id) { + const PrintRegionConfig &config = this->printing_region(region_id).config(); if (config.ensure_vertical_shell_thickness.value && has_extra_layers_fn(config)) { has_extra_layers = true; break; @@ -1100,8 +1100,8 @@ void PrintObject::discover_vertical_shells() static size_t debug_idx = 0; ++ debug_idx; #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ - for (size_t idx_region = 0; idx_region < num_regions; ++ idx_region) { - LayerRegion &layerm = *layer.m_regions[idx_region]; + for (size_t region_id = 0; region_id < num_regions; ++ region_id) { + LayerRegion &layerm = *layer.m_regions[region_id]; float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f; // Top surfaces. append(cache.top_surfaces, offset(layerm.slices.filter_by_type(stTop), min_perimeter_infill_spacing)); @@ -1149,10 +1149,10 @@ void PrintObject::discover_vertical_shells() BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - end : cache top / bottom"; } - for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++ idx_region) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { PROFILE_BLOCK(discover_vertical_shells_region); - const PrintRegion ®ion = this->printing_region(idx_region); + const PrintRegion ®ion = this->printing_region(region_id); if (! region.config().ensure_vertical_shell_thickness.value) // This region will be handled by discover_horizontal_shells(). continue; @@ -1166,15 +1166,15 @@ void PrintObject::discover_vertical_shells() if (! top_bottom_surfaces_all_regions) { // This is either a single material print, or a multi-material print and interface_shells are enabled, meaning that the vertical shell thickness // is calculated over a single material. - BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - start : cache top / bottom"; + BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - start : cache top / bottom"; tbb::parallel_for( tbb::blocked_range(0, num_layers, grain_size), - [this, idx_region, &cache_top_botom_regions](const tbb::blocked_range& range) { + [this, region_id, &cache_top_botom_regions](const tbb::blocked_range& range) { const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge }; for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { m_print->throw_if_canceled(); Layer &layer = *m_layers[idx_layer]; - LayerRegion &layerm = *layer.m_regions[idx_region]; + LayerRegion &layerm = *layer.m_regions[region_id]; float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f; // Top surfaces. auto &cache = cache_top_botom_regions[idx_layer]; @@ -1183,21 +1183,21 @@ void PrintObject::discover_vertical_shells() // Bottom surfaces. cache.bottom_surfaces = offset(layerm.slices.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing); append(cache.bottom_surfaces, offset(layerm.fill_surfaces.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing)); - // Holes over all regions. Only collect them once, they are valid for all idx_region iterations. + // Holes over all regions. Only collect them once, they are valid for all region_id iterations. if (cache.holes.empty()) { - for (size_t idx_region = 0; idx_region < layer.regions().size(); ++ idx_region) - polygons_append(cache.holes, to_polygons(layer.regions()[idx_region]->fill_expolygons)); + for (size_t region_id = 0; region_id < layer.regions().size(); ++ region_id) + polygons_append(cache.holes, to_polygons(layer.regions()[region_id]->fill_expolygons)); } } }); m_print->throw_if_canceled(); - BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - end : cache top / bottom"; + BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - end : cache top / bottom"; } - BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - start : ensure vertical wall thickness"; + BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - start : ensure vertical wall thickness"; tbb::parallel_for( tbb::blocked_range(0, num_layers, grain_size), - [this, idx_region, &cache_top_botom_regions] + [this, region_id, &cache_top_botom_regions] (const tbb::blocked_range& range) { // printf("discover_vertical_shells from %d to %d\n", range.begin(), range.end()); for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { @@ -1209,7 +1209,7 @@ void PrintObject::discover_vertical_shells() #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ Layer *layer = m_layers[idx_layer]; - LayerRegion *layerm = layer->m_regions[idx_region]; + LayerRegion *layerm = layer->m_regions[region_id]; const PrintRegionConfig ®ion_config = layerm->region().config(); #ifdef SLIC3R_DEBUG_SLICE_PROCESSING @@ -1424,11 +1424,11 @@ void PrintObject::discover_vertical_shells() } // for each layer }); m_print->throw_if_canceled(); - BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - end"; + BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - end"; #ifdef SLIC3R_DEBUG_SLICE_PROCESSING for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++idx_layer) { - LayerRegion *layerm = m_layers[idx_layer]->get_region(idx_region); + LayerRegion *layerm = m_layers[idx_layer]->get_region(region_id); layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells-final"); layerm->export_region_fill_surfaces_to_svg_debug("4_discover_vertical_shells-final"); } @@ -1663,6 +1663,7 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full object_extruders); } sort_remove_duplicates(object_extruders); + //FIXME add painting extruders if (object_max_z <= 0.f) object_max_z = (float)model_object.raw_bounding_box().size().z();