mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 00:37:51 -06:00
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:
parent
354458ae73
commit
e9990ed79e
12 changed files with 46 additions and 40 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace Slic3r {
|
||||||
class GLShader;
|
class GLShader;
|
||||||
class ExPolygon;
|
class ExPolygon;
|
||||||
class BackgroundSlicingProcess;
|
class BackgroundSlicingProcess;
|
||||||
|
class GCodePreviewData;
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ namespace Slic3r {
|
||||||
class AppConfig;
|
class AppConfig;
|
||||||
class DynamicPrintConfig;
|
class DynamicPrintConfig;
|
||||||
class Print;
|
class Print;
|
||||||
class GCodePreviewData;
|
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue