From 714149dab2466e5f1a9e26a0efa0b3daaf425d89 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Wed, 5 May 2021 16:21:55 +0200 Subject: [PATCH] WIP: Moving ownership of PrintRegions to PrintObjects. --- src/libslic3r/Fill/FillAdaptive.cpp | 6 +- src/libslic3r/GCode.cpp | 43 ++++---- src/libslic3r/GCode/ToolOrdering.cpp | 12 +-- src/libslic3r/Print.cpp | 43 +++----- src/libslic3r/Print.hpp | 38 ++++--- src/libslic3r/PrintApply.cpp | 46 ++++---- src/libslic3r/PrintObject.cpp | 152 +++++++++++++++------------ src/libslic3r/SupportMaterial.cpp | 15 ++- xs/xsp/Print.xsp | 4 +- 9 files changed, 184 insertions(+), 175 deletions(-) diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp index 6b303e636..3eabc6106 100644 --- a/src/libslic3r/Fill/FillAdaptive.cpp +++ b/src/libslic3r/Fill/FillAdaptive.cpp @@ -291,13 +291,13 @@ std::pair adaptive_fill_line_spacing(const PrintObject &print_ob double extrusion_width; }; std::vector region_fill_data; - region_fill_data.reserve(print_object.print()->regions().size()); + region_fill_data.reserve(print_object.num_printing_regions()); bool build_octree = false; const std::vector &nozzle_diameters = print_object.print()->config().nozzle_diameter.values; double max_nozzle_diameter = *std::max_element(nozzle_diameters.begin(), nozzle_diameters.end()); double default_infill_extrusion_width = Flow::auto_extrusion_width(FlowRole::frInfill, float(max_nozzle_diameter)); - for (const PrintRegion *region : print_object.print()->regions()) { - const PrintRegionConfig &config = region->config(); + for (size_t region_id = 0; region_id < print_object.num_printing_regions(); ++ region_id) { + const PrintRegionConfig &config = print_object.printing_region(region_id).config(); bool nonempty = config.fill_density > 0; bool has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic; bool has_support_infill = nonempty && config.fill_pattern == ipSupportCubic; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3b1575f8f..5e5d2957a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -796,19 +796,19 @@ namespace DoExport { // get the minimum cross-section used in the print std::vector mm3_per_mm; for (auto object : print.objects()) { - for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) { - const PrintRegion* region = print.regions()[region_id]; + for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = object->printing_region(region_id); for (auto layer : object->layers()) { const LayerRegion* layerm = layer->regions()[region_id]; - if (region->config().get_abs_value("perimeter_speed") == 0 || - region->config().get_abs_value("small_perimeter_speed") == 0 || - region->config().get_abs_value("external_perimeter_speed") == 0 || - region->config().get_abs_value("bridge_speed") == 0) + if (region.config().get_abs_value("perimeter_speed") == 0 || + region.config().get_abs_value("small_perimeter_speed") == 0 || + region.config().get_abs_value("external_perimeter_speed") == 0 || + region.config().get_abs_value("bridge_speed") == 0) mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm()); - if (region->config().get_abs_value("infill_speed") == 0 || - region->config().get_abs_value("solid_infill_speed") == 0 || - region->config().get_abs_value("top_solid_infill_speed") == 0 || - region->config().get_abs_value("bridge_speed") == 0) + if (region.config().get_abs_value("infill_speed") == 0 || + region.config().get_abs_value("solid_infill_speed") == 0 || + region.config().get_abs_value("top_solid_infill_speed") == 0 || + region.config().get_abs_value("bridge_speed") == 0) { // Minimal volumetric flow should not be calculated over ironing extrusions. // Use following lambda instead of the built-it method. @@ -1112,16 +1112,17 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu const double layer_height = first_object->config().layer_height.value; assert(! print.config().first_layer_height.percent); const double first_layer_height = print.config().first_layer_height.value; - for (const PrintRegion* region : print.regions()) { - _write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width()); - _write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width()); - _write_format(file, "; infill extrusion width = %.2fmm\n", region->flow(*first_object, frInfill, layer_height).width()); - _write_format(file, "; solid infill extrusion width = %.2fmm\n", region->flow(*first_object, frSolidInfill, layer_height).width()); - _write_format(file, "; top infill extrusion width = %.2fmm\n", region->flow(*first_object, frTopSolidInfill, layer_height).width()); + for (size_t region_id = 0; region_id < print.num_print_regions(); ++ region_id) { + const PrintRegion ®ion = *print.get_print_region(region_id); + _write_format(file, "; external perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frExternalPerimeter, layer_height).width()); + _write_format(file, "; perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, layer_height).width()); + _write_format(file, "; infill extrusion width = %.2fmm\n", region.flow(*first_object, frInfill, layer_height).width()); + _write_format(file, "; solid infill extrusion width = %.2fmm\n", region.flow(*first_object, frSolidInfill, layer_height).width()); + _write_format(file, "; top infill extrusion width = %.2fmm\n", region.flow(*first_object, frTopSolidInfill, layer_height).width()); if (print.has_support_material()) _write_format(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width()); if (print.config().first_layer_extrusion_width.value > 0) - _write_format(file, "; first layer extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, first_layer_height, true).width()); + _write_format(file, "; first layer extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, first_layer_height, true).width()); _write_format(file, "\n"); } print.throw_if_canceled(); @@ -2109,7 +2110,7 @@ void GCode::process_layer( const LayerRegion *layerm = layer.regions()[region_id]; if (layerm == nullptr) continue; - const PrintRegion ®ion = *print.regions()[region_id]; + const PrintRegion ®ion = *layerm->region(); // Now we must process perimeters and infills and create islands of extrusions in by_region std::map. // It is also necessary to save which extrusions are part of MM wiping and which are not. @@ -2167,7 +2168,7 @@ void GCode::process_layer( // extrusions->first_point fits inside ith slice point_inside_surface(island_idx, extrusions->first_point())) { if (islands[island_idx].by_region.empty()) - islands[island_idx].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region()); + islands[island_idx].by_region.assign(print.num_print_regions(), ObjectByExtruder::Island::Region()); islands[island_idx].by_region[region_id].append(entity_type, extrusions, entity_overrides); break; } @@ -2570,7 +2571,7 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vectorconfig()); + m_config.apply(print.get_print_region(®ion - &by_region.front())->config()); for (const ExtrusionEntity *ee : region.perimeters) gcode += this->extrude_entity(*ee, "perimeter", -1., &lower_layer_edge_grid); } @@ -2591,7 +2592,7 @@ std::string GCode::extrude_infill(const Print &print, const std::vectorrole() == erIroning) == ironing) extrusions.emplace_back(ee); if (! extrusions.empty()) { - m_config.apply(print.regions()[®ion - &by_region.front()]->config()); + m_config.apply(print.get_print_region(®ion - &by_region.front())->config()); chain_and_reorder_extrusion_entities(extrusions, &m_last_pos); for (const ExtrusionEntity *fill : extrusions) { auto *eec = dynamic_cast(fill); diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index c45e26015..8005e57bf 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -223,11 +223,11 @@ 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.region_volumes.size(); ++ region_id) { + 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; - const PrintRegion ®ion = *object.print()->regions()[region_id]; + const PrintRegion ®ion = *layerm->region(); if (! layerm->perimeters.entities.empty()) { bool something_nonoverriddable = true; @@ -689,8 +689,8 @@ 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->region_volumes.size(); ++ region_id) { - const auto& region = *object->print()->regions()[region_id]; + for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = object->printing_region(region_id); if (!region.config().wipe_into_infill && !object->config().wipe_into_objects) continue; @@ -762,8 +762,8 @@ 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->region_volumes.size(); ++ region_id) { - const auto& region = *object->print()->regions()[region_id]; + for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) { + const auto& region = object->printing_region(region_id); if (!region.config().wipe_into_infill && !object->config().wipe_into_objects) continue; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index caf827702..77ac3ee7b 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -39,22 +39,22 @@ void Print::clear() for (PrintObject *object : m_objects) delete object; m_objects.clear(); - for (PrintRegion *region : m_regions) + for (PrintRegion *region : m_print_regions) delete region; - m_regions.clear(); + m_print_regions.clear(); m_model.clear_objects(); } -PrintRegion* Print::add_region() +PrintRegion* Print::add_print_region() { - m_regions.emplace_back(new PrintRegion()); - return m_regions.back(); + m_print_regions.emplace_back(new PrintRegion()); + return m_print_regions.back(); } -PrintRegion* Print::add_region(const PrintRegionConfig &config) +PrintRegion* Print::add_print_region(const PrintRegionConfig &config) { - m_regions.emplace_back(new PrintRegion(config)); - return m_regions.back(); + m_print_regions.emplace_back(new PrintRegion(config)); + return m_print_regions.back(); } // Called by Print::apply(). @@ -273,15 +273,10 @@ bool Print::is_step_done(PrintObjectStep step) const std::vector Print::object_extruders() const { std::vector extruders; - extruders.reserve(m_regions.size() * 3); - std::vector region_used(m_regions.size(), false); + extruders.reserve(m_print_regions.size() * m_objects.size() * 3); for (const PrintObject *object : m_objects) - for (const std::vector> &volumes_per_region : object->region_volumes) - if (! volumes_per_region.empty()) - region_used[&volumes_per_region - &object->region_volumes.front()] = true; - for (size_t idx_region = 0; idx_region < m_regions.size(); ++ idx_region) - if (region_used[idx_region]) - m_regions[idx_region]->collect_object_printing_extruders(*this, extruders); + for (const auto *region : object->all_regions()) + region->collect_object_printing_extruders(*this, extruders); sort_remove_duplicates(extruders); return extruders; } @@ -451,11 +446,7 @@ std::string Print::validate(std::string* warning) const return L("Only a single object may be printed at a time in Spiral Vase mode. " "Either remove all but the last object, or enable sequential mode by \"complete_objects\"."); assert(m_objects.size() == 1); - size_t num_regions = 0; - for (const std::vector> &volumes_per_region : m_objects.front()->region_volumes) - if (! volumes_per_region.empty()) - ++ num_regions; - if (num_regions > 1) + if (m_objects.front()->all_regions().size() > 1) return L("The Spiral Vase option can only be used when printing single material objects."); } @@ -670,8 +661,8 @@ std::string Print::validate(std::string* warning) const if ((object->has_support() || object->has_raft()) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg)) return err_msg; for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" }) - for (size_t i = 0; i < object->region_volumes.size(); ++ i) - if (! object->region_volumes[i].empty() && ! validate_extrusion_width(this->get_region(i)->config(), opt_key, layer_height, err_msg)) + for (const PrintRegion *region : object->all_regions()) + if (! validate_extrusion_width(region->config(), opt_key, layer_height, err_msg)) return err_msg; } } @@ -746,7 +737,7 @@ Flow Print::brim_flow() const { ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width; if (width.value == 0) - width = m_regions.front()->config().perimeter_extrusion_width; + width = m_print_regions.front()->config().perimeter_extrusion_width; if (width.value == 0) width = m_objects.front()->config().extrusion_width; @@ -758,7 +749,7 @@ Flow Print::brim_flow() const return Flow::new_from_config_width( frPerimeter, width, - (float)m_config.nozzle_diameter.get_at(m_regions.front()->config().perimeter_extruder-1), + (float)m_config.nozzle_diameter.get_at(m_print_regions.front()->config().perimeter_extruder-1), (float)this->skirt_first_layer_height()); } @@ -766,7 +757,7 @@ Flow Print::skirt_flow() const { ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width; if (width.value == 0) - width = m_regions.front()->config().perimeter_extrusion_width; + width = m_print_regions.front()->config().perimeter_extrusion_width; if (width.value == 0) width = m_objects.front()->config().extrusion_width; diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 9677a585a..2a9f3fe6e 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -148,9 +148,6 @@ private: // Prevents erroneous use by other classes. typedef PrintObjectBaseWithState Inherited; public: - // vector of (layer height ranges and vectors of volume ids), indexed by region_id - std::vector>> region_volumes; - // Size of an object: XYZ in scaled coordinates. The size might not be quite snug in XY plane. const Vec3crd& size() const { return m_size; } const PrintObjectConfig& config() const { return m_config; } @@ -177,9 +174,9 @@ public: // adds region_id, too, if necessary void add_region_volume(unsigned int region_id, int volume_id, const t_layer_height_range &layer_range) { - if (region_id >= region_volumes.size()) - region_volumes.resize(region_id + 1); - region_volumes[region_id].emplace_back(layer_range, volume_id); + if (region_id >= m_region_volumes.size()) + m_region_volumes.resize(region_id + 1); + m_region_volumes[region_id].emplace_back(layer_range, volume_id); } // This is the *total* layer count (including support layers) // this value is not supposed to be compared with Layer::id @@ -210,7 +207,7 @@ public: // Initialize the layer_height_profile from the model_object's layer_height_profile, from model_object's layer height table, or from slicing parameters. // Returns true, if the layer_height_profile was changed. - static bool update_layer_height_profile(const ModelObject &model_object, const SlicingParameters &slicing_parameters, std::vector &layer_height_profile); + static bool update_layer_height_profile(const ModelObject &model_object, const SlicingParameters &slicing_parameters, std::vector &layer_height_profile); // Collect the slicing parameters, to be used by variable layer thickness algorithm, // by the interactive layer height editor and by the printing process itself. @@ -219,6 +216,11 @@ public: const SlicingParameters& slicing_parameters() const { return m_slicing_params; } static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z); + size_t num_printing_regions() const throw() { return m_region_volumes.size(); } + const PrintRegion& printing_region(size_t idx) const throw(); + //FIXME returing all possible regions before slicing, thus some of the regions may not be slicing at the end. + std::vector all_regions() const; + bool has_support() const { return m_config.support_material || m_config.support_material_enforce_layers > 0; } bool has_raft() const { return m_config.raft_layers > 0; } bool has_support_material() const { return this->has_support() || this->has_raft(); } @@ -293,6 +295,9 @@ private: // This is the adjustment of the the Object's coordinate system towards PrintObject's coordinate system. Point m_center_offset; + // vector of (layer height ranges and vectors of volume ids), indexed by region_id + std::vector>> m_region_volumes; + SlicingParameters m_slicing_params; LayerPtrs m_layers; SupportLayerPtrs m_support_layers; @@ -392,11 +397,13 @@ class ConstPrintObjectPtrsAdaptor : public ConstVectorOfPtrsAdaptor }; typedef std::vector PrintRegionPtrs; +/* typedef std::vector ConstPrintRegionPtrs; class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor { friend Print; ConstPrintRegionPtrsAdaptor(const PrintRegionPtrs *data) : ConstVectorOfPtrsAdaptor(data) {} }; +*/ // The complete print tray with possibly multiple objects. class Print : public PrintBaseWithState @@ -467,14 +474,14 @@ public: [object_id](const PrintObject *obj) { return obj->id() == object_id; }); return (it == m_objects.end()) ? nullptr : *it; } - ConstPrintRegionPtrsAdaptor regions() const { return ConstPrintRegionPtrsAdaptor(&m_regions); } +// ConstPrintRegionPtrsAdaptor regions() const { return ConstPrintRegionPtrsAdaptor(&m_regions); } // How many of PrintObject::copies() over all print objects are there? // If zero, then the print is empty and the print shall not be executed. unsigned int num_object_instances() const; // For Perl bindings. PrintObjectPtrs& objects_mutable() { return m_objects; } - PrintRegionPtrs& regions_mutable() { return m_regions; } + PrintRegionPtrs& print_regions_mutable() { return m_print_regions; } const ExtrusionEntityCollection& skirt() const { return m_skirt; } const ExtrusionEntityCollection& brim() const { return m_brim; } @@ -496,14 +503,15 @@ public: std::string output_filename(const std::string &filename_base = std::string()) const override; // Accessed by SupportMaterial - const PrintRegion* get_region(size_t idx) const { return m_regions[idx]; } - const ToolOrdering& get_tool_ordering() const { return m_wipe_tower_data.tool_ordering; } // #ys_FIXME just for testing + size_t num_print_regions() const throw() { return m_print_regions.size(); } + const PrintRegion* get_print_region(size_t idx) const { return m_print_regions[idx]; } + const ToolOrdering& get_tool_ordering() const { return m_wipe_tower_data.tool_ordering; } // #ys_FIXME just for testing protected: // methods for handling regions - PrintRegion* get_region(size_t idx) { return m_regions[idx]; } - PrintRegion* add_region(); - PrintRegion* add_region(const PrintRegionConfig &config); + PrintRegion* get_print_region(size_t idx) { return m_print_regions[idx]; } + PrintRegion* add_print_region(); + PrintRegion* add_print_region(const PrintRegionConfig &config); // Invalidates the step, and its depending steps in Print. bool invalidate_step(PrintStep step); @@ -524,7 +532,7 @@ private: PrintObjectConfig m_default_object_config; PrintRegionConfig m_default_region_config; PrintObjectPtrs m_objects; - PrintRegionPtrs m_regions; + PrintRegionPtrs m_print_regions; // Ordered collections of extrusion paths to build skirt loops and brim. ExtrusionEntityCollection m_skirt; diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index df576fe42..630d3a999 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -383,9 +383,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ delete object; } m_objects.clear(); - for (PrintRegion *region : m_regions) + for (PrintRegion *region : m_print_regions) delete region; - m_regions.clear(); + m_print_regions.clear(); m_model.assign_copy(model); for (const ModelObject *model_object : m_model.objects) model_object_status.emplace(model_object->id(), ModelObjectStatus::New); @@ -682,21 +682,21 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // 5) Synchronize configs of ModelVolumes, synchronize AMF / 3MF materials (and their configs), refresh PrintRegions. // Update reference counts of regions from the remaining PrintObjects and their volumes. // Regions with zero references could and should be reused. - for (PrintRegion *region : m_regions) + for (PrintRegion *region : m_print_regions) region->m_refcnt = 0; for (PrintObject *print_object : m_objects) { int idx_region = 0; - for (const auto &volumes : print_object->region_volumes) { + for (const auto &volumes : print_object->m_region_volumes) { if (! volumes.empty()) - ++ m_regions[idx_region]->m_refcnt; + ++ m_print_regions[idx_region]->m_refcnt; ++ idx_region; } } // All regions now have distinct settings. // Check whether applying the new region config defaults we'd get different regions. - for (size_t region_id = 0; region_id < m_regions.size(); ++ region_id) { - PrintRegion ®ion = *m_regions[region_id]; + for (size_t region_id = 0; region_id < m_print_regions.size(); ++ region_id) { + PrintRegion ®ion = *m_print_regions[region_id]; PrintRegionConfig this_region_config; bool this_region_config_set = false; for (PrintObject *print_object : m_objects) { @@ -707,8 +707,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ assert(it_status->status != ModelObjectStatus::Deleted); layer_ranges = &it_status->layer_ranges; } - if (region_id < print_object->region_volumes.size()) { - for (const std::pair &volume_and_range : print_object->region_volumes[region_id]) { + if (region_id < print_object->m_region_volumes.size()) { + for (const std::pair &volume_and_range : print_object->m_region_volumes[region_id]) { const ModelVolume &volume = *print_object->model_object()->volumes[volume_and_range.second]; const DynamicPrintConfig *layer_range_config = layer_ranges->config(volume_and_range.first); if (this_region_config_set) { @@ -721,7 +721,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ } else { this_region_config = PrintObject::region_config_from_model_volume(m_default_region_config, layer_range_config, volume, num_extruders); for (size_t i = 0; i < region_id; ++ i) { - const PrintRegion ®ion_other = *m_regions[i]; + const PrintRegion ®ion_other = *m_print_regions[i]; if (region_other.m_refcnt != 0 && region_other.config().equals(this_region_config)) // Regions were merged. Reset this print_object. goto print_object_end; @@ -735,19 +735,19 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ update_apply_status(print_object->invalidate_all_steps()); // Decrease the references to regions from this volume. int ireg = 0; - for (const std::vector> &volumes : print_object->region_volumes) { + for (const std::vector> &volumes : print_object->m_region_volumes) { if (! volumes.empty()) - -- m_regions[ireg]->m_refcnt; + -- m_print_regions[ireg]->m_refcnt; ++ ireg; } - print_object->region_volumes.clear(); + print_object->m_region_volumes.clear(); } if (this_region_config_set) { t_config_option_keys diff = region.config().diff(this_region_config); if (! diff.empty()) { // Stop the background process before assigning new configuration to the regions. for (PrintObject *print_object : m_objects) - if (region_id < print_object->region_volumes.size() && ! print_object->region_volumes[region_id].empty()) + if (region_id < print_object->m_region_volumes.size() && ! print_object->m_region_volumes[region_id].empty()) update_apply_status(print_object->invalidate_state_by_config_options(region.config(), this_region_config, diff)); region.config_apply_only(this_region_config, diff, false); } @@ -769,7 +769,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ regions_in_object.reserve(64); for (size_t i = idx_print_object; i < m_objects.size() && m_objects[i]->model_object() == &model_object; ++ i) { PrintObject &print_object = *m_objects[i]; - bool fresh = print_object.region_volumes.empty(); + bool fresh = print_object.m_region_volumes.empty(); unsigned int volume_id = 0; unsigned int idx_region_in_object = 0; for (const ModelVolume *volume : model_object.volumes) { @@ -786,11 +786,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ PrintRegionConfig config = PrintObject::region_config_from_model_volume(m_default_region_config, it_range->second, *volume, num_extruders); // Find an existing print region with the same config. int idx_empty_slot = -1; - for (int i = 0; i < (int)m_regions.size(); ++ i) { - if (m_regions[i]->m_refcnt == 0) { + for (int i = 0; i < int(m_print_regions.size()); ++ i) { + if (m_print_regions[i]->m_refcnt == 0) { if (idx_empty_slot == -1) idx_empty_slot = i; - } else if (config.equals(m_regions[i]->config())) { + } else if (config.equals(m_print_regions[i]->config())) { region_id = i; break; } @@ -798,11 +798,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // If no region exists with the same config, create a new one. if (region_id == -1) { if (idx_empty_slot == -1) { - region_id = (int)m_regions.size(); - this->add_region(config); + region_id = int(m_print_regions.size()); + this->add_print_region(config); } else { region_id = idx_empty_slot; - m_regions[region_id]->set_config(std::move(config)); + m_print_regions[region_id]->set_config(std::move(config)); } } regions_in_object.emplace_back(region_id); @@ -810,8 +810,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ region_id = regions_in_object[idx_region_in_object ++]; // Assign volume to a region. if (fresh) { - if ((size_t)region_id >= print_object.region_volumes.size() || print_object.region_volumes[region_id].empty()) - ++ m_regions[region_id]->m_refcnt; + if ((size_t)region_id >= print_object.m_region_volumes.size() || print_object.m_region_volumes[region_id].empty()) + ++ m_print_regions[region_id]->m_refcnt; print_object.add_region_volume(region_id, volume_id, it_range->first); } } diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 10eaf7c1f..c7339fb5d 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -97,6 +97,21 @@ PrintBase::ApplyStatus PrintObject::set_instances(PrintInstances &&instances) return status; } +const PrintRegion& PrintObject::printing_region(size_t idx) const throw() +{ + return *m_print->get_print_region(idx); +} + +std::vector PrintObject::all_regions() const +{ + std::vector out; + out.reserve(m_region_volumes.size()); + for (size_t i = 0; i < m_region_volumes.size(); ++ i) + if (! m_region_volumes[i].empty()) + out.emplace_back(m_print->get_print_region(i)); + return out; +} + // Called by make_perimeters() // 1) Decides Z positions of the layers, // 2) Initializes layers and their regions @@ -173,8 +188,8 @@ void PrintObject::make_perimeters() // but we don't generate any extra perimeter if fill density is zero, as they would be floating // inside the object - infill_only_where_needed should be the method of choice for printing // hollow objects - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { - const PrintRegion ®ion = *m_print->regions()[region_id]; + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = this->printing_region(region_id); if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2) continue; @@ -294,7 +309,7 @@ void PrintObject::prepare_infill() // Debugging output. #ifdef SLIC3R_DEBUG_SLICE_PROCESSING - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { for (const Layer *layer : m_layers) { LayerRegion *layerm = layer->m_regions[region_id]; layerm->export_region_slices_to_svg_debug("6_discover_vertical_shells-final"); @@ -313,7 +328,7 @@ void PrintObject::prepare_infill() m_print->throw_if_canceled(); #ifdef SLIC3R_DEBUG_SLICE_PROCESSING - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { for (const Layer *layer : m_layers) { LayerRegion *layerm = layer->m_regions[region_id]; layerm->export_region_slices_to_svg_debug("7_discover_horizontal_shells-final"); @@ -332,7 +347,7 @@ void PrintObject::prepare_infill() m_print->throw_if_canceled(); #ifdef SLIC3R_DEBUG_SLICE_PROCESSING - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { for (const Layer *layer : m_layers) { LayerRegion *layerm = layer->m_regions[region_id]; layerm->export_region_slices_to_svg_debug("8_clip_surfaces-final"); @@ -351,7 +366,7 @@ void PrintObject::prepare_infill() m_print->throw_if_canceled(); #ifdef SLIC3R_DEBUG_SLICE_PROCESSING - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { for (const Layer *layer : m_layers) { LayerRegion *layerm = layer->m_regions[region_id]; layerm->export_region_slices_to_svg_debug("9_prepare_infill-final"); @@ -736,19 +751,11 @@ bool PrintObject::invalidate_all_steps() // First call the "invalidate" functions, which may cancel background processing. bool result = Inherited::invalidate_all_steps() | m_print->invalidate_all_steps(); // Then reset some of the depending values. - this->m_slicing_params.valid = false; - this->region_volumes.clear(); + m_slicing_params.valid = false; + m_region_volumes.clear(); return result; } -static const PrintRegion* first_printing_region(const PrintObject &print_object) -{ - for (size_t idx_region = 0; idx_region < print_object.region_volumes.size(); ++ idx_region) - if (!print_object.region_volumes.empty()) - return print_object.print()->regions()[idx_region]; - return nullptr; -} - // This function analyzes slices of a region (SurfaceCollection slices). // Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface. // Initially all slices are of type stInternal. @@ -769,9 +776,9 @@ void PrintObject::detect_surfaces_type() // should be visible. bool spiral_vase = this->print()->config().spiral_vase.value; bool interface_shells = ! spiral_vase && m_config.interface_shells.value; - size_t num_layers = spiral_vase ? std::min(size_t(first_printing_region(*this)->config().bottom_solid_layers), m_layers.size()) : m_layers.size(); + 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->region_volumes.size(); ++ idx_region) { + 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"; #ifdef SLIC3R_DEBUG_SLICE_PROCESSING for (Layer *layer : m_layers) @@ -966,8 +973,8 @@ void PrintObject::process_external_surfaces() // Is there any printing region, that has zero infill? If so, then we don't want the expansion to be performed over the complete voids, but only // over voids, which are supported by the layer below. bool has_voids = false; - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) - if (! this->region_volumes.empty() && this->print()->regions()[region_id]->config().fill_density == 0) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) + if (this->printing_region(region_id).config().fill_density == 0) { has_voids = true; break; } @@ -1016,7 +1023,7 @@ void PrintObject::process_external_surfaces() BOOST_LOG_TRIVIAL(debug) << "Collecting surfaces covered with extrusions in parallel - end"; } - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++region_id) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id) { BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start"; tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), @@ -1024,7 +1031,7 @@ void PrintObject::process_external_surfaces() for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { m_print->throw_if_canceled(); // BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << m_layers[layer_idx]->print_z; - m_layers[layer_idx]->get_region((int)region_id)->process_external_surfaces( + m_layers[layer_idx]->get_region(int(region_id))->process_external_surfaces( (layer_idx == 0) ? nullptr : m_layers[layer_idx - 1], (layer_idx == 0 || surfaces_covered.empty() || surfaces_covered[layer_idx - 1].empty()) ? nullptr : &surfaces_covered[layer_idx - 1]); } @@ -1049,7 +1056,7 @@ void PrintObject::discover_vertical_shells() Polygons holes; }; bool spiral_vase = this->print()->config().spiral_vase.value; - size_t num_layers = spiral_vase ? std::min(size_t(first_printing_region(*this)->config().bottom_solid_layers), m_layers.size()) : m_layers.size(); + size_t num_layers = spiral_vase ? std::min(size_t(this->printing_region(0).config().bottom_solid_layers), m_layers.size()) : m_layers.size(); coordf_t min_layer_height = this->slicing_parameters().min_layer_height; // Does this region possibly produce more than 1 top or bottom layer? auto has_extra_layers_fn = [min_layer_height](const PrintRegionConfig &config) { @@ -1064,14 +1071,14 @@ void PrintObject::discover_vertical_shells() num_extra_layers(config.bottom_solid_layers, config.bottom_solid_min_thickness) > 0; }; std::vector cache_top_botom_regions(num_layers, DiscoverVerticalShellsCacheEntry()); - bool top_bottom_surfaces_all_regions = this->region_volumes.size() > 1 && ! m_config.interface_shells.value; + bool top_bottom_surfaces_all_regions = this->num_printing_regions() > 1 && ! m_config.interface_shells.value; if (top_bottom_surfaces_all_regions) { // This is a multi-material print and interface_shells are disabled, meaning that the vertical shell thickness // 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->region_volumes.size(); ++idx_region) { - const PrintRegionConfig &config = m_print->get_region(idx_region)->config(); + for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++idx_region) { + const PrintRegionConfig &config = this->printing_region(idx_region).config(); if (config.ensure_vertical_shell_thickness.value && has_extra_layers_fn(config)) { has_extra_layers = true; break; @@ -1087,7 +1094,7 @@ void PrintObject::discover_vertical_shells() tbb::blocked_range(0, num_layers, grain_size), [this, &cache_top_botom_regions](const tbb::blocked_range& range) { const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge }; - const size_t num_regions = this->region_volumes.size(); + const size_t num_regions = this->num_printing_regions(); for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { m_print->throw_if_canceled(); const Layer &layer = *m_layers[idx_layer]; @@ -1148,10 +1155,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->region_volumes.size(); ++ idx_region) { + for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++ idx_region) { PROFILE_BLOCK(discover_vertical_shells_region); - const PrintRegion ®ion = *m_print->get_region(idx_region); + const PrintRegion ®ion = this->printing_region(idx_region); if (! region.config().ensure_vertical_shell_thickness.value) // This region will be handled by discover_horizontal_shells(). continue; @@ -1445,8 +1452,8 @@ void PrintObject::bridge_over_infill() { BOOST_LOG_TRIVIAL(info) << "Bridge over infill..." << log_memory_info(); - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { - const PrintRegion ®ion = *m_print->regions()[region_id]; + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = this->printing_region(region_id); // skip bridging in case there are no voids if (region.config().fill_density.value == 100) @@ -1672,10 +1679,9 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full std::vector PrintObject::object_extruders() const { std::vector extruders; - extruders.reserve(this->region_volumes.size() * 3); - for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region) - if (! this->region_volumes[idx_region].empty()) - m_print->get_region(idx_region)->collect_object_printing_extruders(*this->print(), extruders); + extruders.reserve(this->all_regions().size() * 3); + for (const PrintRegion *region : this->all_regions()) + region->collect_object_printing_extruders(*this->print(), extruders); sort_remove_duplicates(extruders); return extruders; } @@ -1743,8 +1749,8 @@ void PrintObject::_slice(const std::vector &layer_height_profile) layer->lower_layer = prev; } // Make sure all layers contain layer region objects for all regions. - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) - layer->add_region(this->print()->get_region(region_id)); + for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) + layer->add_region(this->print()->get_print_region(region_id)); prev = layer; } } @@ -1754,9 +1760,9 @@ void PrintObject::_slice(const std::vector &layer_height_profile) bool has_z_ranges = false; size_t num_volumes = 0; size_t num_modifiers = 0; - for (int region_id = 0; region_id < (int)this->region_volumes.size(); ++ region_id) { + for (int region_id = 0; region_id < int(m_region_volumes.size()); ++ region_id) { int last_volume_id = -1; - for (const std::pair &volume_and_range : this->region_volumes[region_id]) { + for (const std::pair &volume_and_range : m_region_volumes[region_id]) { const int volume_id = volume_and_range.second; const ModelVolume *model_volume = this->model_object()->volumes[volume_id]; if (model_volume->is_model_part()) { @@ -1786,14 +1792,14 @@ void PrintObject::_slice(const std::vector &layer_height_profile) if (! has_z_ranges && (! m_config.clip_multipart_objects.value || all_volumes_single_region >= 0)) { // Cheap path: Slice regions without mutual clipping. // The cheap path is possible if no clipping is allowed or if slicing volumes of just a single region. - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) { BOOST_LOG_TRIVIAL(debug) << "Slicing objects - region " << region_id; // slicing in parallel size_t slicing_mode_normal_below_layer = 0; if (spiral_vase) { // Slice the bottom layers with SlicingMode::Regular. // This needs to be in sync with LayerRegion::make_perimeters() spiral_vase! - const PrintRegionConfig &config = this->print()->regions()[region_id]->config(); + const PrintRegionConfig &config = this->print()->get_print_region(region_id)->config(); slicing_mode_normal_below_layer = size_t(config.bottom_solid_layers.value); for (; slicing_mode_normal_below_layer < slice_zs.size() && slice_zs[slicing_mode_normal_below_layer] < config.bottom_solid_min_thickness - EPSILON; ++ slicing_mode_normal_below_layer); @@ -1819,8 +1825,8 @@ void PrintObject::_slice(const std::vector &layer_height_profile) }; std::vector sliced_volumes; sliced_volumes.reserve(num_volumes); - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { - const std::vector> &volumes_and_ranges = this->region_volumes[region_id]; + for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) { + const std::vector> &volumes_and_ranges = m_region_volumes[region_id]; for (size_t i = 0; i < volumes_and_ranges.size(); ) { int volume_id = volumes_and_ranges[i].second; const ModelVolume *model_volume = this->model_object()->volumes[volume_id]; @@ -1871,7 +1877,7 @@ void PrintObject::_slice(const std::vector &layer_height_profile) } } // Collect and union volumes of a single region. - for (int region_id = 0; region_id < (int)this->region_volumes.size(); ++ region_id) { + for (int region_id = 0; region_id < int(m_region_volumes.size()); ++ region_id) { ExPolygons expolygons; size_t num_volumes = 0; for (SlicedVolume &sliced_volume : sliced_volumes) @@ -1892,8 +1898,8 @@ void PrintObject::_slice(const std::vector &layer_height_profile) } // Slice all modifier volumes. - if (this->region_volumes.size() > 1) { - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + if (m_region_volumes.size() > 1) { + for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) { BOOST_LOG_TRIVIAL(debug) << "Slicing modifier volumes - region " << region_id; // slicing in parallel std::vector expolygons_by_layer = this->slice_modifiers(region_id, slice_zs); @@ -1906,7 +1912,7 @@ void PrintObject::_slice(const std::vector &layer_height_profile) tbb::blocked_range(0, m_layers.size()), [this, &expolygons_by_layer, region_id](const tbb::blocked_range& range) { for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { - for (size_t other_region_id = 0; other_region_id < this->region_volumes.size(); ++ other_region_id) { + for (size_t other_region_id = 0; other_region_id < m_region_volumes.size(); ++ other_region_id) { if (region_id == other_region_id) continue; Layer *layer = m_layers[layer_id]; @@ -2046,8 +2052,8 @@ end: std::vector PrintObject::slice_region(size_t region_id, const std::vector &z, SlicingMode mode, size_t slicing_mode_normal_below_layer, SlicingMode mode_below) const { std::vector volumes; - if (region_id < this->region_volumes.size()) { - for (const std::pair &volume_and_range : this->region_volumes[region_id]) { + if (region_id < m_region_volumes.size()) { + for (const std::pair &volume_and_range : m_region_volumes[region_id]) { const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second]; if (volume->is_model_part()) volumes.emplace_back(volume); @@ -2060,10 +2066,10 @@ std::vector PrintObject::slice_region(size_t region_id, const std::v std::vector PrintObject::slice_modifiers(size_t region_id, const std::vector &slice_zs) const { std::vector out; - if (region_id < this->region_volumes.size()) + if (region_id < m_region_volumes.size()) { std::vector> volume_ranges; - const std::vector> &volumes_and_ranges = this->region_volumes[region_id]; + const std::vector> &volumes_and_ranges = m_region_volumes[region_id]; volume_ranges.reserve(volumes_and_ranges.size()); for (size_t i = 0; i < volumes_and_ranges.size(); ) { int volume_id = volumes_and_ranges[i].second; @@ -2098,7 +2104,7 @@ std::vector PrintObject::slice_modifiers(size_t region_id, const std if (equal_ranges && volume_ranges.front().size() == 1 && volume_ranges.front().front() == t_layer_height_range(0, DBL_MAX)) { // No modifier in this region was split to layer spans. std::vector volumes; - for (const std::pair &volume_and_range : this->region_volumes[region_id]) { + for (const std::pair &volume_and_range : m_region_volumes[region_id]) { const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second]; if (volume->is_modifier()) volumes.emplace_back(volume); @@ -2107,8 +2113,8 @@ std::vector PrintObject::slice_modifiers(size_t region_id, const std } else { // Some modifier in this region was split to layer spans. std::vector merge; - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { - const std::vector> &volumes_and_ranges = this->region_volumes[region_id]; + for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) { + const std::vector> &volumes_and_ranges = m_region_volumes[region_id]; for (size_t i = 0; i < volumes_and_ranges.size(); ) { int volume_id = volumes_and_ranges[i].second; const ModelVolume *model_volume = this->model_object()->volumes[volume_id]; @@ -2395,9 +2401,15 @@ void PrintObject::simplify_slices(double distance) // fill_surfaces but we only turn them into VOID surfaces, thus preserving the boundaries. void PrintObject::clip_fill_surfaces() { - if (! m_config.infill_only_where_needed.value || - ! std::any_of(this->print()->regions().begin(), this->print()->regions().end(), - [](const PrintRegion *region) { return region->config().fill_density > 0; })) + if (! m_config.infill_only_where_needed.value) + return; + bool has_infill = false; + for (size_t i = 0; i < this->num_printing_regions(); ++ i) + if (this->printing_region(i).config().fill_density > 0) { + has_infill = true; + break; + } + if (! has_infill) return; // We only want infill under ceilings; this is almost like an @@ -2475,7 +2487,7 @@ void PrintObject::discover_horizontal_shells() { BOOST_LOG_TRIVIAL(trace) << "discover_horizontal_shells()"; - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { for (size_t i = 0; i < m_layers.size(); ++ i) { m_print->throw_if_canceled(); Layer *layer = m_layers[i]; @@ -2656,7 +2668,7 @@ void PrintObject::discover_horizontal_shells() } // for each region #ifdef SLIC3R_DEBUG_SLICE_PROCESSING - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { for (const Layer *layer : m_layers) { const LayerRegion *layerm = layer->m_regions[region_id]; layerm->export_region_slices_to_svg_debug("5_discover_horizontal_shells"); @@ -2672,16 +2684,16 @@ void PrintObject::discover_horizontal_shells() void PrintObject::combine_infill() { // Work on each region separately. - for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) { - const PrintRegion *region = this->print()->regions()[region_id]; - const size_t every = region->config().infill_every_layers.value; - if (every < 2 || region->config().fill_density == 0.) + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = this->printing_region(region_id); + const size_t every = region.config().infill_every_layers.value; + if (every < 2 || region.config().fill_density == 0.) continue; // Limit the number of combined layers to the maximum height allowed by this regions' nozzle. //FIXME limit the layer height to max_layer_height double nozzle_diameter = std::min( - this->print()->config().nozzle_diameter.get_at(region->config().infill_extruder.value - 1), - this->print()->config().nozzle_diameter.get_at(region->config().solid_infill_extruder.value - 1)); + this->print()->config().nozzle_diameter.get_at(region.config().infill_extruder.value - 1), + this->print()->config().nozzle_diameter.get_at(region.config().solid_infill_extruder.value - 1)); // define the combinations std::vector combine(m_layers.size(), 0); { @@ -2745,11 +2757,11 @@ void PrintObject::combine_infill() 0.5f * layerms.back()->flow(frPerimeter).scaled_width() + // Because fill areas for rectilinear and honeycomb are grown // later to overlap perimeters, we need to counteract that too. - ((region->config().fill_pattern == ipRectilinear || - region->config().fill_pattern == ipMonotonic || - region->config().fill_pattern == ipGrid || - region->config().fill_pattern == ipLine || - region->config().fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) * + ((region.config().fill_pattern == ipRectilinear || + region.config().fill_pattern == ipMonotonic || + region.config().fill_pattern == ipGrid || + region.config().fill_pattern == ipLine || + region.config().fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) * layerms.back()->flow(frSolidInfill).scaled_width(); for (ExPolygon &expoly : intersection) polygons_append(intersection_with_clearance, offset(expoly, clearance_offset)); diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index ca5657618..63ce31bd9 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -345,17 +345,14 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object // Evaluate the XY gap between the object outer perimeters and the support structures. // Evaluate the XY gap between the object outer perimeters and the support structures. coordf_t external_perimeter_width = 0.; - size_t num_nonempty_regions = 0; coordf_t bridge_flow_ratio = 0; - for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) - if (! object->region_volumes[region_id].empty()) { - ++ num_nonempty_regions; - const PrintRegion ®ion = *object->print()->get_region(region_id); - external_perimeter_width = std::max(external_perimeter_width, coordf_t(region.flow(*object, frExternalPerimeter, slicing_params.layer_height).width())); - bridge_flow_ratio += region.config().bridge_flow_ratio; - } + for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = object->printing_region(region_id); + external_perimeter_width = std::max(external_perimeter_width, coordf_t(region.flow(*object, frExternalPerimeter, slicing_params.layer_height).width())); + bridge_flow_ratio += region.config().bridge_flow_ratio; + } m_support_params.gap_xy = m_object_config->support_material_xy_spacing.get_abs_value(external_perimeter_width); - bridge_flow_ratio /= num_nonempty_regions; + bridge_flow_ratio /= object->num_printing_regions(); m_support_params.support_material_bottom_interface_flow = m_slicing_params.soluble_interface || ! m_object_config->thick_bridges ? m_support_params.support_material_interface_flow.with_flow_ratio(bridge_flow_ratio) : diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index a7b4e562f..6ac387b60 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -98,9 +98,9 @@ _constant() %code%{ RETVAL = THIS->objects().size(); %}; PrintRegionPtrs* regions() - %code%{ RETVAL = const_cast(&THIS->regions_mutable()); %}; + %code%{ RETVAL = const_cast(&THIS->print_regions_mutable()); %}; Ref get_region(int idx) - %code%{ RETVAL = THIS->regions_mutable()[idx]; %}; + %code%{ RETVAL = THIS->print_regions_mutable()[idx]; %}; size_t region_count() %code%{ RETVAL = THIS->regions().size(); %};