diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 56a94b28c..28bcdf50c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6,9 +6,6 @@ #include "Geometry.hpp" #include "GCode/PrintExtents.hpp" #include "GCode/WipeTower.hpp" -#if ENABLE_THUMBNAIL_GENERATOR -#include "GCode/ThumbnailData.hpp" -#endif // ENABLE_THUMBNAIL_GENERATOR #include "ShortestPath.hpp" #include "Utils.hpp" @@ -695,7 +692,7 @@ std::vector>> GCode::collec } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const std::vector* thumbnail_data) +void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #else void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -725,7 +722,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ try { m_placeholder_parser_failed_templates.clear(); #if ENABLE_THUMBNAIL_GENERATOR - this->_do_export(*print, file, thumbnail_data); + this->_do_export(*print, file, thumbnail_cb); #else this->_do_export(*print, file); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -793,9 +790,9 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::_do_export(Print& print, FILE* file, const std::vector* thumbnail_data) +void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thumbnail_cb) #else -void GCode::_do_export(Print &print, FILE *file) +void GCode::_do_export(Print& print, FILE* file) #endif // ENABLE_THUMBNAIL_GENERATOR { PROFILE_FUNC(); @@ -812,46 +809,46 @@ void GCode::_do_export(Print &print, FILE *file) // shall be adjusted as well to produce a G-code block compatible with the particular firmware flavor. if (print.config().gcode_flavor.value == gcfMarlin) { m_normal_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values[0]); - m_normal_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values[0]); - m_normal_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values[0]); - m_normal_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values[0]); + m_normal_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values[0]); + m_normal_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values[0]); + m_normal_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values[0]); if (m_silent_time_estimator_enabled) { m_silent_time_estimator.reset(); m_silent_time_estimator.set_dialect(print.config().gcode_flavor); - /* "Stealth mode" values can be just a copy of "normal mode" values + /* "Stealth mode" values can be just a copy of "normal mode" values * (when they aren't input for a printer preset). * Thus, use back value from values, instead of second one, which could be absent */ - m_silent_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values.back()); - m_silent_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values.back()); - m_silent_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values.back()); - m_silent_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values.back()); + m_silent_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values.back()); + m_silent_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values.back()); + m_silent_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values.back()); + m_silent_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values.back()); if (print.config().single_extruder_multi_material) { // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they // are considered to be active for the single extruder multi-material printers only. @@ -909,7 +906,8 @@ void GCode::_do_export(Print &print, FILE *file) std::sort(zs.begin(), zs.end()); m_layer_count += (unsigned int)(object->copies().size() * (std::unique(zs.begin(), zs.end()) - zs.begin())); } - } else { + } + else { // Print all objects with the same print_z together. std::vector zs; for (auto object : print.objects()) { @@ -927,7 +925,7 @@ void GCode::_do_export(Print &print, FILE *file) m_enable_cooling_markers = true; this->apply_print_config(print.config()); this->set_extruders(print.extruders()); - + // Initialize colorprint. m_colorprint_heights = cast(print.config().colorprint_heights.values); @@ -936,31 +934,31 @@ void GCode::_do_export(Print &print, FILE *file) // get the minimum cross-section used in the print std::vector mm3_per_mm; for (auto object : print.objects()) { - for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < object->region_volumes.size(); ++region_id) { const PrintRegion* region = print.regions()[region_id]; for (auto layer : object->layers()) { const LayerRegion* layerm = layer->regions()[region_id]; - if (region->config().get_abs_value("perimeter_speed" ) == 0 || - region->config().get_abs_value("small_perimeter_speed" ) == 0 || - region->config().get_abs_value("external_perimeter_speed" ) == 0 || - region->config().get_abs_value("bridge_speed" ) == 0) + if (region->config().get_abs_value("perimeter_speed") == 0 || + region->config().get_abs_value("small_perimeter_speed") == 0 || + region->config().get_abs_value("external_perimeter_speed") == 0 || + region->config().get_abs_value("bridge_speed") == 0) mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm()); - if (region->config().get_abs_value("infill_speed" ) == 0 || - region->config().get_abs_value("solid_infill_speed" ) == 0 || - region->config().get_abs_value("top_solid_infill_speed" ) == 0 || - region->config().get_abs_value("bridge_speed" ) == 0) + if (region->config().get_abs_value("infill_speed") == 0 || + region->config().get_abs_value("solid_infill_speed") == 0 || + region->config().get_abs_value("top_solid_infill_speed") == 0 || + region->config().get_abs_value("bridge_speed") == 0) mm3_per_mm.push_back(layerm->fills.min_mm3_per_mm()); } } - if (object->config().get_abs_value("support_material_speed" ) == 0 || - object->config().get_abs_value("support_material_interface_speed" ) == 0) + if (object->config().get_abs_value("support_material_speed") == 0 || + object->config().get_abs_value("support_material_interface_speed") == 0) for (auto layer : object->support_layers()) mm3_per_mm.push_back(layer->support_fills.min_mm3_per_mm()); } print.throw_if_canceled(); // filter out 0-width segments mm3_per_mm.erase(std::remove_if(mm3_per_mm.begin(), mm3_per_mm.end(), [](double v) { return v < 0.000001; }), mm3_per_mm.end()); - if (! mm3_per_mm.empty()) { + if (!mm3_per_mm.empty()) { // In order to honor max_print_speed we need to find a target volumetric // speed that we can use throughout the print. So we define this target // volumetric speed as the volumetric speed produced by printing the @@ -973,7 +971,7 @@ void GCode::_do_export(Print &print, FILE *file) } } print.throw_if_canceled(); - + m_cooling_buffer = make_unique(*this); if (print.config().spiral_vase.value) m_spiral_vase = make_unique(print.config()); @@ -991,11 +989,12 @@ void GCode::_do_export(Print &print, FILE *file) #if ENABLE_THUMBNAIL_GENERATOR // Write thumbnails using base64 encoding - if (thumbnail_data != nullptr) + if (thumbnail_cb != nullptr) { const size_t max_row_length = 78; - - for (const ThumbnailData& data : *thumbnail_data) + ThumbnailsList thumbnails; + thumbnail_cb(thumbnails, print.full_print_config().option("thumbnails")->values, true, true, false); + for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 19ec5be3c..40794986a 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -17,6 +17,9 @@ #include "GCodeTimeEstimator.hpp" #include "EdgeGrid.hpp" #include "GCode/Analyzer.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include #include @@ -30,9 +33,6 @@ namespace Slic3r { // Forward declarations. class GCode; class GCodePreviewData; -#if ENABLE_THUMBNAIL_GENERATOR -struct ThumbnailData; -#endif // ENABLE_THUMBNAIL_GENERATOR class AvoidCrossingPerimeters { public: @@ -167,7 +167,7 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). #if ENABLE_THUMBNAIL_GENERATOR - void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, const std::vector* thumbnail_data = nullptr); + void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -199,7 +199,7 @@ public: protected: #if ENABLE_THUMBNAIL_GENERATOR - void _do_export(Print& print, FILE* file, const std::vector* thumbnail_data); + void _do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thumbnail_cb); #else void _do_export(Print &print, FILE *file); #endif //ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/GCode/ThumbnailData.hpp b/src/libslic3r/GCode/ThumbnailData.hpp index 9823ffd31..efe875e15 100644 --- a/src/libslic3r/GCode/ThumbnailData.hpp +++ b/src/libslic3r/GCode/ThumbnailData.hpp @@ -4,6 +4,7 @@ #if ENABLE_THUMBNAIL_GENERATOR #include +#include "libslic3r/Point.hpp" namespace Slic3r { @@ -20,6 +21,9 @@ struct ThumbnailData bool is_valid() const; }; +typedef std::vector ThumbnailsList; +typedef std::function ThumbnailsGeneratorCallback; + } // namespace Slic3r #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 78a09c511..8b79f5367 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1538,7 +1538,7 @@ void Print::process() // write error into the G-code, cannot execute post-processing scripts). // It is up to the caller to show an error message. #if ENABLE_THUMBNAIL_GENERATOR -std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data) +std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #else std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -1559,7 +1559,7 @@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewDa // The following line may die for multiple reasons. GCode gcode; #if ENABLE_THUMBNAIL_GENERATOR - gcode.do_export(this, path.c_str(), preview_data, thumbnail_data); + gcode.do_export(this, path.c_str(), preview_data, thumbnail_cb); #else gcode.do_export(this, path.c_str(), preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 4fcd67166..1649f3c04 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -11,6 +11,9 @@ #include "Slicing.hpp" #include "GCode/ToolOrdering.hpp" #include "GCode/WipeTower.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR namespace Slic3r { @@ -19,9 +22,6 @@ class PrintObject; class ModelObject; class GCode; class GCodePreviewData; -#if ENABLE_THUMBNAIL_GENERATOR -struct ThumbnailData; -#endif // ENABLE_THUMBNAIL_GENERATOR // Print step IDs for keeping track of the print state. enum PrintStep { @@ -311,7 +311,7 @@ public: // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). #if ENABLE_THUMBNAIL_GENERATOR - std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data = nullptr); + std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 5ab65f340..570841a45 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -20,9 +20,6 @@ #include "libslic3r/Utils.hpp" #include "libslic3r/GCode/PostProcessor.hpp" #include "libslic3r/GCode/PreviewData.hpp" -#if ENABLE_THUMBNAIL_GENERATOR -#include "libslic3r/GCode/ThumbnailData.hpp" -#endif // ENABLE_THUMBNAIL_GENERATOR #include "libslic3r/libslic3r.h" #include @@ -91,7 +88,7 @@ void BackgroundSlicingProcess::process_fff() m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); #if ENABLE_THUMBNAIL_GENERATOR - m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_data); + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_cb); #else m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -139,9 +136,12 @@ void BackgroundSlicingProcess::process_sla() m_sla_print->export_raster(zipper); #if ENABLE_THUMBNAIL_GENERATOR - if (m_thumbnail_data != nullptr) + if (m_thumbnail_cb != nullptr) { - for (const ThumbnailData& data : *m_thumbnail_data) + ThumbnailsList thumbnails; + m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, false); +// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, false); // renders also supports and pad + for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) write_thumbnail(zipper, data); @@ -461,9 +461,12 @@ void BackgroundSlicingProcess::prepare_upload() Zipper zipper{source_path.string()}; m_sla_print->export_raster(zipper, m_upload_job.upload_data.upload_path.string()); #if ENABLE_THUMBNAIL_GENERATOR - if (m_thumbnail_data != nullptr) + if (m_thumbnail_cb != nullptr) { - for (const ThumbnailData& data : *m_thumbnail_data) + ThumbnailsList thumbnails; + m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, false); +// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, false); // renders also supports and pad + for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) write_thumbnail(zipper, data); diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index a603d52ac..984686e35 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,9 +17,6 @@ namespace Slic3r { class DynamicPrintConfig; class GCodePreviewData; -#if ENABLE_THUMBNAIL_GENERATOR -struct ThumbnailData; -#endif // ENABLE_THUMBNAIL_GENERATOR class Model; class SLAPrint; @@ -53,7 +50,7 @@ public: void set_sla_print(SLAPrint *print) { m_sla_print = print; } void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; } #if ENABLE_THUMBNAIL_GENERATOR - void set_thumbnail_data(const std::vector* data) { m_thumbnail_data = data; } + void set_thumbnail_cb(ThumbnailsGeneratorCallback cb) { m_thumbnail_cb = cb; } #endif // ENABLE_THUMBNAIL_GENERATOR // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished @@ -159,8 +156,8 @@ private: // Data structure, to which the G-code export writes its annotations. GCodePreviewData *m_gcode_preview_data = nullptr; #if ENABLE_THUMBNAIL_GENERATOR - // Data structures, used to write thumbnails into gcode. - const std::vector* m_thumbnail_data = nullptr; + // Callback function, used to write thumbnails into gcode. + ThumbnailsGeneratorCallback m_thumbnail_cb = nullptr; #endif // ENABLE_THUMBNAIL_GENERATOR // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. std::string m_temp_output_path; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 563bb5133..2a908fd0f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1387,9 +1387,6 @@ struct Plater::priv Slic3r::Model model; PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; -#if ENABLE_THUMBNAIL_GENERATOR - std::vector thumbnail_data; -#endif // ENABLE_THUMBNAIL_GENERATOR // GUI elements wxSizer* panel_sizer{ nullptr }; @@ -1946,6 +1943,7 @@ struct Plater::priv #if ENABLE_THUMBNAIL_GENERATOR void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); + void generate_thumbnails(ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void msw_rescale_object_menu(); @@ -2016,7 +2014,15 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_sla_print(&sla_print); background_process.set_gcode_preview_data(&gcode_preview_data); #if ENABLE_THUMBNAIL_GENERATOR - background_process.set_thumbnail_data(&thumbnail_data); + background_process.set_thumbnail_cb([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background) + { + std::packaged_task task([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background) { + generate_thumbnails(thumbnails, sizes, printable_only, parts_only, transparent_background); + }); + std::future result = task.get_future(); + wxTheApp->CallAfter([&]() { task(thumbnails, sizes, printable_only, parts_only, transparent_background); }); + result.wait(); + }); #endif // ENABLE_THUMBNAIL_GENERATOR background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); @@ -3067,37 +3073,6 @@ bool Plater::priv::restart_background_process(unsigned int state) ( ((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0 && ! this->background_process.finished()) || (state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 || (state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) { -#if ENABLE_THUMBNAIL_GENERATOR - if (((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) && - (this->background_process.state() != BackgroundSlicingProcess::STATE_RUNNING)) - { - // update thumbnail data - const std::vector &thumbnail_sizes = this->background_process.current_print()->full_print_config().option("thumbnails")->values; - if (this->printer_technology == ptFFF) - { - // for ptFFF we need to generate the thumbnails before the export of gcode starts - this->thumbnail_data.clear(); - for (const Vec2d &sized : thumbnail_sizes) - { - this->thumbnail_data.push_back(ThumbnailData()); - Point size(sized); // round to ints - generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false); - } - } - else if (this->printer_technology == ptSLA) - { - // for ptSLA generate thumbnails without supports and pad (not yet calculated) - // to render also supports and pad see on_slicing_update() - this->thumbnail_data.clear(); - for (const Vec2d &sized : thumbnail_sizes) - { - this->thumbnail_data.push_back(ThumbnailData()); - Point size(sized); // round to ints - generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false); - } - } - } -#endif // ENABLE_THUMBNAIL_GENERATOR // The print is valid and it can be started. if (this->background_process.start()) { this->statusbar()->set_cancel_callback([this]() { @@ -3435,25 +3410,6 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) } else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) { // Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways. this->preview->reload_print(); - - // uncomment the following lines if you want to render into the thumbnail also supports and pad for SLA printer -/* -#if ENABLE_THUMBNAIL_GENERATOR - // update thumbnail data - // for ptSLA generate the thumbnail after supports and pad have been calculated to have them rendered - if ((this->printer_technology == ptSLA) && (evt.status.percent == -3)) - { - const std::vector& thumbnail_sizes = this->background_process.current_print()->full_print_config().option("thumbnails")->values; - this->thumbnail_data.clear(); - for (const Vec2d &sized : thumbnail_sizes) - { - this->thumbnail_data.push_back(ThumbnailData()); - Point size(sized); // round to ints - generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, false, false); - } - } -#endif // ENABLE_THUMBNAIL_GENERATOR -*/ } } @@ -3684,6 +3640,19 @@ void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsig { view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only, transparent_background); } + +void Plater::priv::generate_thumbnails(ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background) +{ + thumbnails.clear(); + for (const Vec2d& size : sizes) + { + thumbnails.push_back(ThumbnailData()); + Point isize(size); // round to ints + generate_thumbnail(thumbnails.back(), isize.x(), isize.y(), printable_only, parts_only, transparent_background); + if (!thumbnails.back().is_valid()) + thumbnails.pop_back(); + } +} #endif // ENABLE_THUMBNAIL_GENERATOR void Plater::priv::msw_rescale_object_menu()