From f342bfae4e3d09a2c6dbd873e0ed7c821988a897 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 7 Nov 2022 16:00:13 +0100 Subject: [PATCH] Improved const correctness of ToolOrdering. --- src/libslic3r/GCode.cpp | 6 ++---- src/libslic3r/GCode/ToolOrdering.cpp | 28 ++++++++++++++++++---------- src/libslic3r/GCode/ToolOrdering.hpp | 26 ++++++++++++-------------- src/libslic3r/Print.cpp | 4 ++-- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index bc3027cac0..46dcccd21a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2208,8 +2208,7 @@ LayerResult GCode::process_layer( std::vector instances_to_print = sort_print_object_instances(layers, ordering, single_object_instance_idx); // 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): - //FIXME const_cast - bool is_anything_overridden = const_cast(layer_tools).wiping_extrusions().is_anything_overridden(); + bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden(); if (is_anything_overridden) { // Extrude wipes. size_t gcode_size_old = gcode.size(); @@ -2349,8 +2348,7 @@ void GCode::process_layer_single_object( // by last extruder on this layer (could happen e.g. when a wiping object is taller than others - dontcare extruders are eradicated from layer_tools) correct_extruder_id = layer_tools.extruders.back(); } - //FIXME const_cast! - int extruder_override_id = is_anything_overridden ? const_cast(layer_tools).wiping_extrusions().get_extruder_override(eec, instance_id) : -1; + int extruder_override_id = is_anything_overridden ? layer_tools.wiping_extrusions().get_extruder_override(eec, instance_id) : -1; return print_wipe_extrusions ? extruder_override_id == int(extruder_id) : extruder_override_id < 0 && extruder_id == correct_extruder_id; diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 7f14203a9d..84e80a07f8 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -232,12 +232,14 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto if (m_print_config_ptr) { // in this case complete_objects is false (see ToolOrdering constructors) something_nonoverriddable = false; for (const ExtrusionEntity *eec : layerm->perimeters()) // let's check if there are nonoverriddable entities - if (!layer_tools.wiping_extrusions().is_overriddable_and_mark(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)) + layer_tools.wiping_extrusions_nonconst().set_something_overridable(); + else something_nonoverriddable = true; } if (something_nonoverriddable) - layer_tools.extruders.emplace_back((extruder_override == 0) ? region.config().perimeter_extruder.value : extruder_override); + layer_tools.extruders.emplace_back(extruder_override == 0 ? region.config().perimeter_extruder.value : extruder_override); layer_tools.has_object = true; } @@ -255,7 +257,9 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto has_infill = true; if (m_print_config_ptr) { - if (! layer_tools.wiping_extrusions().is_overriddable_and_mark(*fill, *m_print_config_ptr, object, region)) + if (layer_tools.wiping_extrusions().is_overriddable(*fill, *m_print_config_ptr, object, region)) + layer_tools.wiping_extrusions_nonconst().set_something_overridable(); + else something_nonoverriddable = true; } } @@ -595,6 +599,12 @@ const LayerTools& ToolOrdering::tools_for_layer(coordf_t print_z) const return *it_layer_tools; } +static const LayerTools& layer_tools(const WipingExtrusions *self) +{ + char *ptr = (char*)(self) - offsetof(LayerTools, m_wiping_extrusions); + return *reinterpret_cast(ptr); +} + // This function is called from Print::mark_wiping_extrusions and sets extruder this entity should be printed with (-1 .. as usual) void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, size_t copy_id, int extruder, size_t num_of_copies) { @@ -614,8 +624,7 @@ void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, size // Finds first non-soluble extruder on the layer 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) + for (auto extruders_it = layer_tools(this).extruders.begin(); extruders_it != layer_tools(this).extruders.end(); ++extruders_it) if (!print_config.filament_soluble.get_at(*extruders_it)) return (*extruders_it); @@ -625,8 +634,7 @@ 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 { - const LayerTools& lt = *m_layer_tools; - for (auto extruders_it = lt.extruders.rbegin(); extruders_it != lt.extruders.rend(); ++extruders_it) + for (auto extruders_it = layer_tools(this).extruders.rbegin(); extruders_it != layer_tools(this).extruders.rend(); ++extruders_it) if (!print_config.filament_soluble.get_at(*extruders_it)) return (*extruders_it); @@ -636,7 +644,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(m_layer_tools->extruder(eec, region))) + if (print_config.filament_soluble.get_at(layer_tools(this).extruder(eec, region))) return false; if (object.config().wipe_into_objects) @@ -653,7 +661,7 @@ bool WipingExtrusions::is_overriddable(const ExtrusionEntityCollection& eec, con // Switching from old_extruder to new_extruder, trying to wipe volume_to_wipe into not yet extruded extrusions, that may change material (overridable). float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int old_extruder, unsigned int new_extruder, float volume_to_wipe) { - const LayerTools& lt = *m_layer_tools; + const LayerTools& lt = layer_tools(this); const float min_infill_volume = 0.f; // ignore infill with smaller volume than this if (! m_something_overridable || volume_to_wipe <= 0. || @@ -752,7 +760,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) if (! m_something_overridable) return; - const LayerTools& lt = *m_layer_tools; + const LayerTools& lt = layer_tools(this); unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config()); unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config()); diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index d043c48ad7..d0357baa0a 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -6,6 +6,7 @@ #include "../libslic3r.h" #include +#include #include @@ -14,6 +15,7 @@ namespace Slic3r { class Print; class PrintObject; class LayerTools; +class ToolOrdering; namespace CustomGCode { struct Item; } class PrintRegion; @@ -45,13 +47,7 @@ public: 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; - bool is_overriddable_and_mark(const ExtrusionEntityCollection& ee, const PrintConfig& print_config, const PrintObject& object, const PrintRegion& region) { - bool out = this->is_overriddable(ee, print_config, object, region); - m_something_overridable |= out; - return out; - } - - void set_layer_tools_ptr(const LayerTools* lt) { m_layer_tools = lt; } + void set_something_overridable() { m_something_overridable = true; } private: int first_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const; @@ -69,14 +65,11 @@ private: std::map m_entity_map; // to keep track of who prints what bool m_something_overridable = false; bool m_something_overridden = false; - const LayerTools* m_layer_tools = nullptr; // so we know which LayerTools object this belongs to }; class LayerTools { public: - LayerTools(const coordf_t z) : print_z(z) {} - // Changing these operators to epsilon version can make a problem in cases where support and object layers get close to each other. // In case someone tries to do it, make sure you know what you're doing and test it properly (slice multiple objects at once with supports). bool operator< (const LayerTools &rhs) const { return print_z < rhs.print_z; } @@ -114,12 +107,17 @@ public: // Custom G-code (color change, extruder switch, pause) to be performed before this layer starts to print. const CustomGCode::Item *custom_gcode = nullptr; - WipingExtrusions& wiping_extrusions() { - m_wiping_extrusions.set_layer_tools_ptr(this); - return m_wiping_extrusions; - } + WipingExtrusions& wiping_extrusions_nonconst() { return m_wiping_extrusions; } + const WipingExtrusions& wiping_extrusions() const { return m_wiping_extrusions; } private: + // to access LayerTools private constructor + friend class ToolOrdering; + LayerTools(const coordf_t z) : print_z(z) {} + + // for calculating offset of m_wiping_extrusions in LayerTools. + friend const LayerTools& layer_tools(const WipingExtrusions *self); + // This object holds list of extrusion that will be used for extruder wiping WipingExtrusions m_wiping_extrusions; }; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 2979b3557b..8f32b6c316 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1208,7 +1208,7 @@ void Print::_make_wipe_tower() volume_to_wipe -= (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id); // try to assign some infills/objects for the wiping: - volume_to_wipe = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_wipe); + volume_to_wipe = layer_tools.wiping_extrusions_nonconst().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_wipe); // add back the minimal amount toforce on the wipe tower: volume_to_wipe += (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id); @@ -1219,7 +1219,7 @@ void Print::_make_wipe_tower() current_extruder_id = extruder_id; } } - layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this); + layer_tools.wiping_extrusions_nonconst().ensure_perimeters_infills_order(*this); if (&layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0) break; }