diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 88e0c76646..2f61cc0082 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -483,8 +483,9 @@ bool DynamicConfig::operator==(const DynamicConfig &rhs) const t_options_map::const_iterator it2 = rhs.options.begin(); t_options_map::const_iterator it2_end = rhs.options.end(); for (; it1 != it1_end && it2 != it2_end; ++ it1, ++ it2) - if (*it1->second != *it2->second) - return false; + if (it1->first != it2->first || *it1->second != *it2->second) + // key or value differ + return false; return it1 == it1_end && it2 == it2_end; } diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 8212b1703d..c32acd4e98 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -668,6 +668,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ { static GCodePreviewData::Extrusion::Layer& get_layer_at_z(GCodePreviewData::Extrusion::LayersList& layers, float z) { + //FIXME this has a terrible time complexity for (GCodePreviewData::Extrusion::Layer& layer : layers) { // if layer found, return it @@ -863,20 +864,4 @@ size_t GCodeAnalyzer::memory_used() const return out; } -GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2) -{ - return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]), - clamp(0.0f, 1.0f, c1.rgba[1] + c2.rgba[1]), - clamp(0.0f, 1.0f, c1.rgba[2] + c2.rgba[2]), - clamp(0.0f, 1.0f, c1.rgba[3] + c2.rgba[3])); -} - -GCodePreviewData::Color operator * (float f, const GCodePreviewData::Color& color) -{ - return GCodePreviewData::Color(clamp(0.0f, 1.0f, f * color.rgba[0]), - clamp(0.0f, 1.0f, f * color.rgba[1]), - clamp(0.0f, 1.0f, f * color.rgba[2]), - clamp(0.0f, 1.0f, f * color.rgba[3])); -} - } // namespace Slic3r diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index d4aa9bc021..e99eeac027 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -521,4 +521,20 @@ size_t GCodePreviewData::memory_used() const sizeof(shell) + sizeof(ranges); } +GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2) +{ + return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]), + clamp(0.0f, 1.0f, c1.rgba[1] + c2.rgba[1]), + clamp(0.0f, 1.0f, c1.rgba[2] + c2.rgba[2]), + clamp(0.0f, 1.0f, c1.rgba[3] + c2.rgba[3])); +} + +GCodePreviewData::Color operator * (float f, const GCodePreviewData::Color& color) +{ + return GCodePreviewData::Color(clamp(0.0f, 1.0f, f * color.rgba[0]), + clamp(0.0f, 1.0f, f * color.rgba[1]), + clamp(0.0f, 1.0f, f * color.rgba[2]), + clamp(0.0f, 1.0f, f * color.rgba[3])); +} + } // namespace Slic3r diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 8ed5e91c73..4ca579d9a5 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -22,6 +22,7 @@ public: static const Color Dummy; }; + // Color mapping from a range into a smooth rainbow of 10 colors. struct Range { static const unsigned int Colors_Count = 10; @@ -45,9 +46,13 @@ public: struct Ranges { + // Color mapping by layer height. Range height; + // Color mapping by extrusion width. Range width; + // Color mapping by feedrate. Range feedrate; + // Color mapping by volumetric extrusion rate. Range volumetric_rate; }; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 97b0310e5e..62fd8730e8 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -18,7 +18,6 @@ class SLAPrintObject; enum SLAPrintObjectStep : unsigned int; class Model; class ModelObject; -class GCodePreviewData; class DynamicPrintConfig; class ExtrusionPath; class ExtrusionMultiPath; diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index d748919c95..66a0884a42 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -15,8 +15,8 @@ #include "libslic3r/SLAPrint.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/GCode/PostProcessor.hpp" +#include "libslic3r/GCode/PreviewData.hpp" -//#undef NDEBUG #include #include #include @@ -367,6 +367,13 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn assert(m_print != nullptr); assert(config.opt_enum("printer_technology") == m_print->technology()); Print::ApplyStatus invalidated = m_print->apply(model, config); + if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF && + m_gcode_preview_data != nullptr && ! this->m_fff_print->is_step_done(psGCodeExport)) { + // Some FFF status was invalidated, and the G-code was not exported yet. + // Let the G-code preview UI know that the final G-code preview is not valid. + // In addition, this early memory deallocation reduces memory footprint. + m_gcode_preview_data->reset(); + } return invalidated; } @@ -392,7 +399,7 @@ void BackgroundSlicingProcess::schedule_upload(Slic3r::PrintHostJob upload_job) // Guard against entering the export step before changing the export path. tbb::mutex::scoped_lock lock(m_print->state_mutex()); this->invalidate_step(bspsGCodeFinalize); - m_export_path = std::string(); + m_export_path.clear(); m_upload_job = std::move(upload_job); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 08368a1316..7dd8c54a02 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -28,6 +28,7 @@ namespace Slic3r { class GLShader; class ExPolygon; class BackgroundSlicingProcess; +class GCodePreviewData; namespace GUI { diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index 1ed4a8251c..64301c73d2 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -19,7 +19,6 @@ class ExPolygon; typedef std::vector ExPolygons; class ModelObject; class PrintObject; -class GCodePreviewData; namespace GUI { diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index e7ab0443d6..3ca4292a9f 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -16,7 +16,6 @@ namespace Slic3r { class AppConfig; class DynamicPrintConfig; class Print; -class GCodePreviewData; namespace GUI { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 71c92f2d1d..735b55125c 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -395,12 +395,6 @@ void Preview::set_number_extruders(unsigned int number_extruders) } } -void Preview::reset_gcode_preview_data() -{ - m_gcode_preview_data->reset(); - m_canvas->reset_legend_texture(); -} - void Preview::set_canvas_as_dirty() { m_canvas->set_as_dirty(); @@ -451,6 +445,7 @@ void Preview::load_print() void Preview::reload_print(bool force) { m_canvas->reset_volumes(); + m_canvas->reset_legend_texture(); m_loaded = false; if (!IsShown() && !force) @@ -759,7 +754,8 @@ void Preview::load_print_as_fff() // Collect colors per extruder. std::vector colors; - if (!m_gcode_preview_data->empty() || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool)) + bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); + if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool)) { const ConfigOptionStrings* extruders_opt = dynamic_cast(m_config->option("extruder_colour")); const ConfigOptionStrings* filamemts_opt = dynamic_cast(m_config->option("filament_colour")); @@ -785,13 +781,7 @@ void Preview::load_print_as_fff() // used to set the sliders to the extremes of the current zs range m_force_sliders_full_range = false; - if (m_gcode_preview_data->empty()) - { - // load skirt and brim - m_canvas->load_preview(colors); - show_hide_ui_elements("simple"); - } - else + if (gcode_preview_data_valid) { m_force_sliders_full_range = (m_canvas->get_volumes_count() == 0); m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); @@ -805,8 +795,15 @@ void Preview::load_print_as_fff() reset_sliders(); m_canvas_widget->Refresh(); } + } + else + { + // load skirt and brim + m_canvas->load_preview(colors); + show_hide_ui_elements("simple"); } + if (n_layers > 0) update_sliders(m_canvas->get_current_print_zs(true)); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 23e6a682f6..534191633d 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -140,7 +140,6 @@ public: #endif // ENABLE_REMOVE_TABS_FROM_PLATER void set_number_extruders(unsigned int number_extruders); - void reset_gcode_preview_data(); void set_canvas_as_dirty(); void set_enabled(bool enabled); void set_bed_shape(const Pointfs& shape); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ea8a83871d..c3f0565c86 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1273,7 +1273,6 @@ void Plater::priv::update(bool force_full_scene_refresh) #else this->canvas3D->reload_scene(false, force_full_scene_refresh); #endif // ENABLE_REMOVE_TABS_FROM_PLATER - preview->reset_gcode_preview_data(); preview->reload_print(); this->schedule_background_process(); @@ -2010,7 +2009,6 @@ unsigned int Plater::priv::update_background_process() this->sidebar->show_sliced_info_sizer(false); // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Otherwise they will be just refreshed. - this->gcode_preview_data.reset(); switch (this->printer_technology) { case ptFFF: if (this->preview != nullptr)