Fix of SPE-691 Slicer crash after extruder change

Added synchronization of GCodePreviewData between the front end / back end
(GCodePreview data is only used if PrintStep psGCodeExport is finished).
Added reset of GCodePreviewData on Print::apply() to conserve RAM.
This commit is contained in:
bubnikv 2018-12-19 14:47:16 +01:00
parent 354458ae73
commit e9990ed79e
12 changed files with 46 additions and 40 deletions

View file

@ -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 = rhs.options.begin();
t_options_map::const_iterator it2_end = rhs.options.end(); t_options_map::const_iterator it2_end = rhs.options.end();
for (; it1 != it1_end && it2 != it2_end; ++ it1, ++ it2) for (; it1 != it1_end && it2 != it2_end; ++ it1, ++ it2)
if (*it1->second != *it2->second) if (it1->first != it2->first || *it1->second != *it2->second)
return false; // key or value differ
return false;
return it1 == it1_end && it2 == it2_end; return it1 == it1_end && it2 == it2_end;
} }

View file

@ -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) 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) for (GCodePreviewData::Extrusion::Layer& layer : layers)
{ {
// if layer found, return it // if layer found, return it
@ -863,20 +864,4 @@ size_t GCodeAnalyzer::memory_used() const
return out; 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 } // namespace Slic3r

View file

@ -521,4 +521,20 @@ size_t GCodePreviewData::memory_used() const
sizeof(shell) + sizeof(ranges); 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 } // namespace Slic3r

View file

@ -22,6 +22,7 @@ public:
static const Color Dummy; static const Color Dummy;
}; };
// Color mapping from a <min, max> range into a smooth rainbow of 10 colors.
struct Range struct Range
{ {
static const unsigned int Colors_Count = 10; static const unsigned int Colors_Count = 10;
@ -45,9 +46,13 @@ public:
struct Ranges struct Ranges
{ {
// Color mapping by layer height.
Range height; Range height;
// Color mapping by extrusion width.
Range width; Range width;
// Color mapping by feedrate.
Range feedrate; Range feedrate;
// Color mapping by volumetric extrusion rate.
Range volumetric_rate; Range volumetric_rate;
}; };

View file

@ -18,7 +18,6 @@ class SLAPrintObject;
enum SLAPrintObjectStep : unsigned int; enum SLAPrintObjectStep : unsigned int;
class Model; class Model;
class ModelObject; class ModelObject;
class GCodePreviewData;
class DynamicPrintConfig; class DynamicPrintConfig;
class ExtrusionPath; class ExtrusionPath;
class ExtrusionMultiPath; class ExtrusionMultiPath;

View file

@ -15,8 +15,8 @@
#include "libslic3r/SLAPrint.hpp" #include "libslic3r/SLAPrint.hpp"
#include "libslic3r/Utils.hpp" #include "libslic3r/Utils.hpp"
#include "libslic3r/GCode/PostProcessor.hpp" #include "libslic3r/GCode/PostProcessor.hpp"
#include "libslic3r/GCode/PreviewData.hpp"
//#undef NDEBUG
#include <cassert> #include <cassert>
#include <stdexcept> #include <stdexcept>
#include <cctype> #include <cctype>
@ -367,6 +367,13 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn
assert(m_print != nullptr); assert(m_print != nullptr);
assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology()); assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology());
Print::ApplyStatus invalidated = m_print->apply(model, config); 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; 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. // Guard against entering the export step before changing the export path.
tbb::mutex::scoped_lock lock(m_print->state_mutex()); tbb::mutex::scoped_lock lock(m_print->state_mutex());
this->invalidate_step(bspsGCodeFinalize); this->invalidate_step(bspsGCodeFinalize);
m_export_path = std::string(); m_export_path.clear();
m_upload_job = std::move(upload_job); m_upload_job = std::move(upload_job);
} }

View file

@ -28,6 +28,7 @@ namespace Slic3r {
class GLShader; class GLShader;
class ExPolygon; class ExPolygon;
class BackgroundSlicingProcess; class BackgroundSlicingProcess;
class GCodePreviewData;
namespace GUI { namespace GUI {

View file

@ -19,7 +19,6 @@ class ExPolygon;
typedef std::vector<ExPolygon> ExPolygons; typedef std::vector<ExPolygon> ExPolygons;
class ModelObject; class ModelObject;
class PrintObject; class PrintObject;
class GCodePreviewData;
namespace GUI { namespace GUI {

View file

@ -16,7 +16,6 @@ namespace Slic3r {
class AppConfig; class AppConfig;
class DynamicPrintConfig; class DynamicPrintConfig;
class Print; class Print;
class GCodePreviewData;
namespace GUI { namespace GUI {

View file

@ -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() void Preview::set_canvas_as_dirty()
{ {
m_canvas->set_as_dirty(); m_canvas->set_as_dirty();
@ -451,6 +445,7 @@ void Preview::load_print()
void Preview::reload_print(bool force) void Preview::reload_print(bool force)
{ {
m_canvas->reset_volumes(); m_canvas->reset_volumes();
m_canvas->reset_legend_texture();
m_loaded = false; m_loaded = false;
if (!IsShown() && !force) if (!IsShown() && !force)
@ -759,7 +754,8 @@ void Preview::load_print_as_fff()
// Collect colors per extruder. // Collect colors per extruder.
std::vector<std::string> colors; std::vector<std::string> 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<const ConfigOptionStrings*>(m_config->option("extruder_colour")); const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("extruder_colour"));
const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("filament_colour")); const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(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 // used to set the sliders to the extremes of the current zs range
m_force_sliders_full_range = false; m_force_sliders_full_range = false;
if (m_gcode_preview_data->empty()) if (gcode_preview_data_valid)
{
// load skirt and brim
m_canvas->load_preview(colors);
show_hide_ui_elements("simple");
}
else
{ {
m_force_sliders_full_range = (m_canvas->get_volumes_count() == 0); m_force_sliders_full_range = (m_canvas->get_volumes_count() == 0);
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
@ -805,8 +795,15 @@ void Preview::load_print_as_fff()
reset_sliders(); reset_sliders();
m_canvas_widget->Refresh(); m_canvas_widget->Refresh();
} }
}
else
{
// load skirt and brim
m_canvas->load_preview(colors);
show_hide_ui_elements("simple");
} }
if (n_layers > 0) if (n_layers > 0)
update_sliders(m_canvas->get_current_print_zs(true)); update_sliders(m_canvas->get_current_print_zs(true));

View file

@ -140,7 +140,6 @@ public:
#endif // ENABLE_REMOVE_TABS_FROM_PLATER #endif // ENABLE_REMOVE_TABS_FROM_PLATER
void set_number_extruders(unsigned int number_extruders); void set_number_extruders(unsigned int number_extruders);
void reset_gcode_preview_data();
void set_canvas_as_dirty(); void set_canvas_as_dirty();
void set_enabled(bool enabled); void set_enabled(bool enabled);
void set_bed_shape(const Pointfs& shape); void set_bed_shape(const Pointfs& shape);

View file

@ -1273,7 +1273,6 @@ void Plater::priv::update(bool force_full_scene_refresh)
#else #else
this->canvas3D->reload_scene(false, force_full_scene_refresh); this->canvas3D->reload_scene(false, force_full_scene_refresh);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER #endif // ENABLE_REMOVE_TABS_FROM_PLATER
preview->reset_gcode_preview_data();
preview->reload_print(); preview->reload_print();
this->schedule_background_process(); this->schedule_background_process();
@ -2010,7 +2009,6 @@ unsigned int Plater::priv::update_background_process()
this->sidebar->show_sliced_info_sizer(false); this->sidebar->show_sliced_info_sizer(false);
// Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared.
// Otherwise they will be just refreshed. // Otherwise they will be just refreshed.
this->gcode_preview_data.reset();
switch (this->printer_technology) { switch (this->printer_technology) {
case ptFFF: case ptFFF:
if (this->preview != nullptr) if (this->preview != nullptr)