diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index db493270a..92f733787 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -659,7 +659,7 @@ std::vector>> GCode::collec } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) +void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const std::vector* thumbnail_data) #else void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -757,7 +757,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::_do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data) +void GCode::_do_export(Print& print, FILE* file, const std::vector* thumbnail_data) #else void GCode::_do_export(Print &print, FILE *file) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -954,18 +954,24 @@ void GCode::_do_export(Print &print, FILE *file) _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); #if ENABLE_THUMBNAIL_GENERATOR - // Write thumbnail using base64 encoding - if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) + // Write thumbnails using base64 encoding + if (thumbnail_data != nullptr) { - _write_format(file, "\n;\n; thumbnail begin %dx%d\n", thumbnail_data->width, thumbnail_data->height); - - size_t row_size = 4 * thumbnail_data->width; - for (int r = (int)thumbnail_data->height - 1; r >= 0; --r) + for (const ThumbnailData& data : *thumbnail_data) { - _write_format(file, "; %s\n", boost::beast::detail::base64_encode((const std::uint8_t*)(thumbnail_data->pixels.data() + r * row_size), row_size).c_str()); - } + if (data.is_valid()) + { + _write_format(file, "\n;\n; thumbnail begin %dx%d\n", data.width, data.height); - _write(file, "; thumbnail end\n;\n\n"); + size_t row_size = 4 * data.width; + for (int r = (int)data.height - 1; r >= 0; --r) + { + _write_format(file, "; %s\n", boost::beast::detail::base64_encode((const std::uint8_t*)(data.pixels.data() + r * row_size), row_size).c_str()); + } + + _write(file, "; thumbnail end\n;\n\n"); + } + } } #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 8116d06fc..3183e8883 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -166,7 +166,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 ThumbnailData* thumbnail_data = nullptr); + void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, const std::vector* thumbnail_data = nullptr); #else void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -198,7 +198,7 @@ public: protected: #if ENABLE_THUMBNAIL_GENERATOR - void _do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data); + void _do_export(Print& print, FILE* file, const std::vector* thumbnail_data); #else void _do_export(Print &print, FILE *file); #endif //ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index b2ed87ca0..74e541451 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1537,7 +1537,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 ThumbnailData* thumbnail_data) +std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data) #else std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index aedeeff18..7e7f875b0 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -309,7 +309,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 ThumbnailData* thumbnail_data = nullptr); + std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data = 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 cedeab910..18f593d77 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -120,7 +120,7 @@ static void write_thumbnail(Zipper& zipper, const ThumbnailData& data) void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)data.pixels.data(), data.width, data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1); if (png_data != nullptr) { - zipper.add_entry("thumbnail/thumbnail.png", (const std::uint8_t*)png_data, png_size); + zipper.add_entry("thumbnail/thumbnail" + std::to_string(data.width) + "x" + std::to_string(data.height) + ".png", (const std::uint8_t*)png_data, png_size); mz_free(png_data); } } @@ -138,8 +138,14 @@ void BackgroundSlicingProcess::process_sla() m_sla_print->export_raster(zipper); #if ENABLE_THUMBNAIL_GENERATOR - if ((m_thumbnail_data != nullptr) && m_thumbnail_data->is_valid()) - write_thumbnail(zipper, *m_thumbnail_data); + if (m_thumbnail_data != nullptr) + { + for (const ThumbnailData& data : *m_thumbnail_data) + { + if (data.is_valid()) + write_thumbnail(zipper, data); + } + } #endif // ENABLE_THUMBNAIL_GENERATOR zipper.finalize(); @@ -458,8 +464,14 @@ 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) && m_thumbnail_data->is_valid()) - write_thumbnail(zipper, *m_thumbnail_data); + if (m_thumbnail_data != nullptr) + { + for (const ThumbnailData& data : *m_thumbnail_data) + { + if (data.is_valid()) + write_thumbnail(zipper, data); + } + } #endif // ENABLE_THUMBNAIL_GENERATOR zipper.finalize(); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index e51a4e961..bf8cbc235 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -53,7 +53,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 ThumbnailData* data) { m_thumbnail_data = data; } + void set_thumbnail_data(const std::vector* data) { m_thumbnail_data = data; } #endif // ENABLE_THUMBNAIL_GENERATOR // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished @@ -159,8 +159,8 @@ private: // Data structure, to which the G-code export writes its annotations. GCodePreviewData *m_gcode_preview_data = nullptr; #if ENABLE_THUMBNAIL_GENERATOR - // Data structure, used to write thumbnail into gcode. - const ThumbnailData *m_thumbnail_data = nullptr; + // Data structures, used to write thumbnails into gcode. + const std::vector* m_thumbnail_data = 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 60a90f1f1..ccfa46abe 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -86,8 +86,8 @@ using Slic3r::Preset; using Slic3r::PrintHostJob; #if ENABLE_THUMBNAIL_GENERATOR -static const std::pair THUMBNAIL_SIZE_FFF = { 128, 128 }; -static const std::pair THUMBNAIL_SIZE_SLA = { 256, 256 }; +static const std::vector < std::pair> THUMBNAIL_SIZE_FFF = { { 240, 320 }, { 220, 165 }, { 16, 16 } }; +static const std::vector> THUMBNAIL_SIZE_SLA = { { 800, 480 } }; static const std::pair THUMBNAIL_SIZE_3MF = { 256, 256 }; #endif // ENABLE_THUMBNAIL_GENERATOR @@ -1371,7 +1371,7 @@ struct Plater::priv PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; #if ENABLE_THUMBNAIL_GENERATOR - Slic3r::ThumbnailData thumbnail_data; + std::vector thumbnail_data; #endif // ENABLE_THUMBNAIL_GENERATOR // GUI elements @@ -3050,12 +3050,26 @@ bool Plater::priv::restart_background_process(unsigned int state) { // update thumbnail data if (this->printer_technology == ptFFF) - // for ptFFF we need to generate the thumbnail before the export of gcode starts - generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true, true); + { + // for ptFFF we need to generate the thumbnails before the export of gcode starts + this->thumbnail_data.clear(); + for (const std::pair& size : THUMBNAIL_SIZE_FFF) + { + this->thumbnail_data.push_back(ThumbnailData()); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true); + } + } else if (this->printer_technology == ptSLA) - // for ptSLA generate thumbnail without supports and pad (not yet calculated) + { + // for ptSLA generate thumbnails without supports and pad (not yet calculated) // to render also supports and pad see on_slicing_update() - generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true, true); + this->thumbnail_data.clear(); + for (const std::pair& size : THUMBNAIL_SIZE_SLA) + { + this->thumbnail_data.push_back(ThumbnailData()); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true); + } + } } #endif // ENABLE_THUMBNAIL_GENERATOR // The print is valid and it can be started. @@ -3402,7 +3416,14 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) // 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)) - generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true, false); + { + this->thumbnail_data.clear(); + for (const std::pair& size : THUMBNAIL_SIZE_SLA) + { + this->thumbnail_data.push_back(ThumbnailData()); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, false); + } + } #endif // ENABLE_THUMBNAIL_GENERATOR */ }