diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index f3813a56a9..72294b7a33 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -1239,11 +1239,11 @@ void GCode::process_layer( continue; // This extrusion is part of certain Region, which tells us which extruder should be used for it: - int correct_extruder_id = get_extruder(*fill, region); entity_type=="infills" ? std::max(0, (is_solid_infill(fill->entities.front()->role()) ? region.config.solid_infill_extruder : region.config.infill_extruder) - 1) : + int correct_extruder_id = Print::get_extruder(*fill, region); entity_type=="infills" ? std::max(0, (is_solid_infill(fill->entities.front()->role()) ? region.config.solid_infill_extruder : region.config.infill_extruder) - 1) : std::max(region.config.perimeter_extruder.value - 1, 0); // Let's recover vector of extruder overrides: - const ExtruderPerCopy* entity_overrides = const_cast(layer_tools).wiping_extrusions.get_extruder_overrides(fill, correct_extruder_id, layer_to_print.object()->_shifted_copies.size()); + const ExtruderPerCopy* entity_overrides = const_cast(layer_tools).wiping_extrusions().get_extruder_overrides(fill, correct_extruder_id, layer_to_print.object()->_shifted_copies.size()); // Now we must add this extrusion into the by_extruder map, once for each extruder that will print it: for (unsigned int extruder : layer_tools.extruders) @@ -1335,7 +1335,7 @@ void GCode::process_layer( continue; // We are almost ready to print. However, we must go through all the objects twice to print the the overridden extrusions first (infill/perimeter wiping feature): - for (int print_wipe_extrusions=layer_tools.wiping_extrusions.is_anything_overridden(); print_wipe_extrusions>=0; --print_wipe_extrusions) { + for (int print_wipe_extrusions=const_cast(layer_tools).wiping_extrusions().is_anything_overridden(); print_wipe_extrusions>=0; --print_wipe_extrusions) { if (print_wipe_extrusions == 0) gcode+="; PURGING FINISHED\n"; @@ -1373,7 +1373,7 @@ void GCode::process_layer( m_layer = layers[layer_id].layer(); } for (ObjectByExtruder::Island &island : object_by_extruder.islands) { - const auto& by_region_specific = layer_tools.wiping_extrusions.is_anything_overridden() ? island.by_region_per_copy(copy_id, extruder_id, print_wipe_extrusions) : island.by_region; + const auto& by_region_specific = const_cast(layer_tools).wiping_extrusions().is_anything_overridden() ? island.by_region_per_copy(copy_id, extruder_id, print_wipe_extrusions) : island.by_region; if (print.config.infill_first) { gcode += this->extrude_infill(print, by_region_specific); diff --git a/xs/src/libslic3r/GCode/ToolOrdering.cpp b/xs/src/libslic3r/GCode/ToolOrdering.cpp index 219c1adfd1..0fe7b0c4e9 100644 --- a/xs/src/libslic3r/GCode/ToolOrdering.cpp +++ b/xs/src/libslic3r/GCode/ToolOrdering.cpp @@ -143,7 +143,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object) if (m_print_config_ptr) { // in this case complete_objects is false (see ToolOrdering constructors) something_nonoverriddable = false; for (const auto& eec : layerm->perimeters.entities) // let's check if there are nonoverriddable entities - if (!layer_tools.wiping_extrusions.is_overriddable(dynamic_cast(*eec), *m_print_config_ptr, object, region)) { + if (!layer_tools.wiping_extrusions().is_overriddable(dynamic_cast(*eec), *m_print_config_ptr, object, region)) { something_nonoverriddable = true; break; } @@ -169,7 +169,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object) has_infill = true; if (m_print_config_ptr) { - if (!something_nonoverriddable && !layer_tools.wiping_extrusions.is_overriddable(*fill, *m_print_config_ptr, object, region)) + if (!something_nonoverriddable && !layer_tools.wiping_extrusions().is_overriddable(*fill, *m_print_config_ptr, object, region)) something_nonoverriddable = true; } } @@ -382,8 +382,9 @@ void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, unsi // Finds first non-soluble extruder on the layer -int WipingExtrusions::first_nonsoluble_extruder_on_layer(const PrintConfig& print_config, const LayerTools& lt) const +int WipingExtrusions::first_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const { + const LayerTools& lt = *m_layer_tools; for (auto extruders_it = lt.extruders.begin(); extruders_it != lt.extruders.end(); ++extruders_it) if (!print_config.filament_soluble.get_at(*extruders_it)) return (*extruders_it); @@ -392,8 +393,9 @@ int WipingExtrusions::first_nonsoluble_extruder_on_layer(const PrintConfig& prin } // Finds last non-soluble extruder on the layer -int WipingExtrusions::last_nonsoluble_extruder_on_layer(const PrintConfig& print_config, const LayerTools& lt) const +int WipingExtrusions::last_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const { + const LayerTools& lt = *m_layer_tools; for (auto extruders_it = lt.extruders.rbegin(); extruders_it != lt.extruders.rend(); ++extruders_it) if (!print_config.filament_soluble.get_at(*extruders_it)) return (*extruders_it); @@ -405,7 +407,7 @@ int WipingExtrusions::last_nonsoluble_extruder_on_layer(const PrintConfig& print // Decides whether this entity could be overridden bool WipingExtrusions::is_overriddable(const ExtrusionEntityCollection& eec, const PrintConfig& print_config, const PrintObject& object, const PrintRegion& region) const { - if (print_config.filament_soluble.get_at(get_extruder(eec, region))) + if (print_config.filament_soluble.get_at(Print::get_extruder(eec, region))) return false; if (object.config.wipe_into_objects) @@ -420,8 +422,9 @@ bool WipingExtrusions::is_overriddable(const ExtrusionEntityCollection& eec, con // Following function iterates through all extrusions on the layer, remembers those that could be used for wiping after toolchange // and returns volume that is left to be wiped on the wipe tower. -float WipingExtrusions::mark_wiping_extrusions(const Print& print, const LayerTools& layer_tools, unsigned int new_extruder, float volume_to_wipe) +float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int new_extruder, float volume_to_wipe) { + const LayerTools& layer_tools = *m_layer_tools; const float min_infill_volume = 0.f; // ignore infill with smaller volume than this if (print.config.filament_soluble.get_at(new_extruder)) @@ -472,7 +475,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, const LayerTo continue; // What extruder would this normally be printed with? - unsigned int correct_extruder = get_extruder(*fill, region); + unsigned int correct_extruder = Print::get_extruder(*fill, region); if (volume_to_wipe<=0) continue; @@ -529,10 +532,11 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, const LayerTo // that were not actually overridden. If they are part of a dedicated object, printing them with the extruder // they were initially assigned to might mean violating the perimeter-infill order. We will therefore go through // them again and make sure we override it. -void WipingExtrusions::ensure_perimeters_infills_order(const Print& print, const LayerTools& layer_tools) +void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) { - unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config, layer_tools); - unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config, layer_tools); + const LayerTools& layer_tools = *m_layer_tools; + unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config); + unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config); for (const PrintObject* object : print.objects) { // Finds this layer: diff --git a/xs/src/libslic3r/GCode/ToolOrdering.hpp b/xs/src/libslic3r/GCode/ToolOrdering.hpp index ac6bb480c6..34304d7123 100644 --- a/xs/src/libslic3r/GCode/ToolOrdering.hpp +++ b/xs/src/libslic3r/GCode/ToolOrdering.hpp @@ -28,15 +28,17 @@ public: // This function goes through all infill entities, decides which ones will be used for wiping and // marks them by the extruder id. Returns volume that remains to be wiped on the wipe tower: - float mark_wiping_extrusions(const Print& print, const LayerTools& layer_tools, unsigned int new_extruder, float volume_to_wipe); + float mark_wiping_extrusions(const Print& print, unsigned int new_extruder, float volume_to_wipe); - void ensure_perimeters_infills_order(const Print& print, const LayerTools& layer_tools); + void ensure_perimeters_infills_order(const Print& print); bool is_overriddable(const ExtrusionEntityCollection& ee, const PrintConfig& print_config, const PrintObject& object, const PrintRegion& region) const; + void set_layer_tools_ptr(const LayerTools* lt) { m_layer_tools = lt; } + private: - int first_nonsoluble_extruder_on_layer(const PrintConfig& print_config, const LayerTools& lt) const; - int last_nonsoluble_extruder_on_layer(const PrintConfig& print_config, const LayerTools& lt) const; + int first_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const; + int last_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const; // This function is called from mark_wiping_extrusions and sets extruder that it should be printed with (-1 .. as usual) void set_extruder_override(const ExtrusionEntity* entity, unsigned int copy_id, int extruder, unsigned int num_of_copies); @@ -48,6 +50,7 @@ private: std::map> entity_map; // to keep track of who prints what bool something_overridden = false; + const LayerTools* m_layer_tools; // so we know which LayerTools object this belongs to }; @@ -80,8 +83,14 @@ public: size_t wipe_tower_partitions; coordf_t wipe_tower_layer_height; + WipingExtrusions& wiping_extrusions() { + m_wiping_extrusions.set_layer_tools_ptr(this); + return m_wiping_extrusions; + } + +private: // This object holds list of extrusion that will be used for extruder wiping - WipingExtrusions wiping_extrusions; + WipingExtrusions m_wiping_extrusions; }; diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index fbbded7cbf..f8caa47861 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -1137,13 +1137,13 @@ void Print::_make_wipe_tower() float volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id]; // total volume to wipe after this toolchange if (!first_layer) // unless we're on the first layer, try to assign some infills/objects for the wiping: - volume_to_wipe = layer_tools.wiping_extrusions.mark_wiping_extrusions(*this, layer_tools, extruder_id, wipe_volumes[current_extruder_id][extruder_id]); + volume_to_wipe = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, extruder_id, wipe_volumes[current_extruder_id][extruder_id]); wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, extruder_id, first_layer && extruder_id == m_tool_ordering.all_extruders().back(), volume_to_wipe); current_extruder_id = extruder_id; } } - layer_tools.wiping_extrusions.ensure_perimeters_infills_order(*this, layer_tools); + layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this); if (&layer_tools == &m_tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0) break; } @@ -1215,4 +1215,13 @@ void Print::set_status(int percent, const std::string &message) printf("Print::status %d => %s\n", percent, message.c_str()); } + +// Returns extruder this eec should be printed with, according to PrintRegion config +int Print::get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion ®ion) +{ + return is_infill(fill.role()) ? std::max(0, (is_solid_infill(fill.entities.front()->role()) ? region.config.solid_infill_extruder : region.config.infill_extruder) - 1) : + std::max(region.config.perimeter_extruder.value - 1, 0); +} + + } diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index f90fb500fc..3ea7ffb689 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -286,6 +286,9 @@ public: bool has_support_material() const; void auto_assign_extruders(ModelObject* model_object) const; + // Returns extruder this eec should be printed with, according to PrintRegion config: + static int get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion ®ion); + void _make_skirt(); void _make_brim(); @@ -323,14 +326,6 @@ private: }; -// Returns extruder this eec should be printed with, according to PrintRegion config -static int get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion ®ion) { - return is_infill(fill.role()) ? std::max(0, (is_solid_infill(fill.entities.front()->role()) ? region.config.solid_infill_extruder : region.config.infill_extruder) - 1) : - std::max(region.config.perimeter_extruder.value - 1, 0); -} - - - #define FOREACH_BASE(type, container, iterator) for (type::const_iterator iterator = (container).begin(); iterator != (container).end(); ++iterator) #define FOREACH_REGION(print, region) FOREACH_BASE(PrintRegionPtrs, (print)->regions, region) #define FOREACH_OBJECT(print, object) FOREACH_BASE(PrintObjectPtrs, (print)->objects, object)