From 32a42f28088edd6663379f0bcde8fcb50d6016f5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 22 Oct 2019 16:02:31 +0200 Subject: [PATCH 01/35] Added tech ENABLE_THUMBNAIL_GENERATOR -> 1st installment of generation of thumbnail from plater (WIP) --- src/libslic3r/CMakeLists.txt | 2 + src/libslic3r/GCode.cpp | 5 ++ src/libslic3r/GCode/ThumbnailData.cpp | 31 +++++++++ src/libslic3r/GCode/ThumbnailData.hpp | 25 +++++++ src/libslic3r/Technologies.hpp | 10 +++ src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/GLCanvas3D.hpp | 7 ++ src/slic3r/GUI/Plater.cpp | 15 +++++ src/slic3r/GUI/ThumbnailGenerator.cpp | 97 +++++++++++++++++++++++++++ src/slic3r/GUI/ThumbnailGenerator.hpp | 37 ++++++++++ 10 files changed, 231 insertions(+) create mode 100644 src/libslic3r/GCode/ThumbnailData.cpp create mode 100644 src/libslic3r/GCode/ThumbnailData.hpp create mode 100644 src/slic3r/GUI/ThumbnailGenerator.cpp create mode 100644 src/slic3r/GUI/ThumbnailGenerator.hpp diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index cbaa24e9c..f7881e5ac 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -71,6 +71,8 @@ add_library(libslic3r STATIC Format/STL.hpp GCode/Analyzer.cpp GCode/Analyzer.hpp + GCode/ThumbnailData.cpp + GCode/ThumbnailData.hpp GCode/CoolingBuffer.cpp GCode/CoolingBuffer.hpp GCode/PostProcessor.cpp diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3a72657c3..fa71ac796 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -945,6 +945,11 @@ void GCode::_do_export(Print &print, FILE *file) } print.throw_if_canceled(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Write some terse information on the slicing parameters. const PrintObject *first_object = print.objects().front(); const double layer_height = first_object->config().layer_height.value; diff --git a/src/libslic3r/GCode/ThumbnailData.cpp b/src/libslic3r/GCode/ThumbnailData.cpp new file mode 100644 index 000000000..17ccbdeb6 --- /dev/null +++ b/src/libslic3r/GCode/ThumbnailData.cpp @@ -0,0 +1,31 @@ +#include "libslic3r/libslic3r.h" +#include "ThumbnailData.hpp" + +#if ENABLE_THUMBNAIL_GENERATOR + +namespace Slic3r { + +void ThumbnailData::set(unsigned int w, unsigned int h) +{ + if (!pixels.empty()) + reset(); + + if ((w == 0) || (h == 0)) + return; + + width = w; + height = h; + // defaults to white texture + pixels = std::vector(width * height * 4, 255); +} + +void ThumbnailData::reset() +{ + width = 0; + height = 0; + pixels.clear(); +} + +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR \ No newline at end of file diff --git a/src/libslic3r/GCode/ThumbnailData.hpp b/src/libslic3r/GCode/ThumbnailData.hpp new file mode 100644 index 000000000..193068ebe --- /dev/null +++ b/src/libslic3r/GCode/ThumbnailData.hpp @@ -0,0 +1,25 @@ +#ifndef slic3r_ThumbnailData_hpp_ +#define slic3r_ThumbnailData_hpp_ + +#if ENABLE_THUMBNAIL_GENERATOR + +#include + +namespace Slic3r { + +struct ThumbnailData +{ + unsigned int width; + unsigned int height; + std::vector pixels; + + ThumbnailData() { reset(); } + void set(unsigned int w, unsigned int h); + void reset(); +}; + +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR + +#endif // slic3r_ThumbnailData_hpp_ \ No newline at end of file diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 51d092094..40e989bb2 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -32,4 +32,14 @@ #define ENABLE_NONCUSTOM_DATA_VIEW_RENDERING (0 && ENABLE_1_42_0_ALPHA1) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//==================== +// 2.2.0.alpha1 techs +//==================== +#define ENABLE_2_2_0_ALPHA1 1 + +// Enable thumbnail generator +#define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #endif // _technologies_h_ diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 17b76e629..0b2dd6702 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -136,6 +136,8 @@ set(SLIC3R_GUI_SOURCES GUI/ProgressStatusBar.cpp GUI/PrintHostDialogs.cpp GUI/PrintHostDialogs.hpp + GUI/ThumbnailGenerator.cpp + GUI/ThumbnailGenerator.hpp Utils/Http.cpp Utils/Http.hpp Utils/FixModelByWin10.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2c2676ae7..2e7fc2d77 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -446,6 +446,13 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } const wxGLCanvas* get_wxglcanvas() const { return m_canvas; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + const GLVolumeCollection& get_volumes() const { return m_volumes; } +// GLVolumeCollection& get_volumes() { return m_volumes; } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool init(); void post_event(wxEvent &&event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cca164ca3..4c44cce75 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -62,6 +62,11 @@ #include "GUI_Preview.hpp" #include "3DBed.hpp" #include "Camera.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include "ThumbnailGenerator.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Tab.hpp" #include "PresetBundle.hpp" #include "BackgroundSlicingProcess.hpp" @@ -1373,6 +1378,11 @@ struct Plater::priv View3D* view3D; GLToolbar view_toolbar; Preview *preview; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + ThumbnailGenerator thumbnail_generator; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BackgroundSlicingProcess background_process; bool suppressed_backround_processing_update { false }; @@ -3060,6 +3070,11 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job) return; if (! output_path.empty()) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + thumbnail_generator.render_to_png_file(*view3D->get_canvas3d(), "C:/prusa/test/test.png", 256, 256, false); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.schedule_export(output_path.string()); } else { background_process.schedule_upload(std::move(upload_job)); diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp new file mode 100644 index 000000000..db823cc0b --- /dev/null +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -0,0 +1,97 @@ +#include "libslic3r/libslic3r.h" +#include "ThumbnailGenerator.hpp" + +#if ENABLE_THUMBNAIL_GENERATOR + +#include "GLCanvas3D.hpp" +#include "3DScene.hpp" + +#include + +namespace Slic3r { +namespace GUI { + +void ThumbnailGenerator::reset() +{ + m_data.reset(); +} + +bool ThumbnailGenerator::render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only) +{ + m_data.set(w, h); + render(canvas, printable_only); + + wxImage image(m_data.width, m_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < m_data.height; ++r) + { + unsigned int rr = (m_data.height - 1 - r) * m_data.width; + for (unsigned int c = 0; c < m_data.width; ++c) + { + unsigned char* px = m_data.pixels.data() + 4 * (rr + c); +// unsigned char* px = m_data.pixels.data() + 4 * (r * m_data.width + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile(filename, wxBITMAP_TYPE_PNG); + + return true; +} + +void ThumbnailGenerator::render(const GLCanvas3D& canvas, bool printable_only) +{ + const GLVolumeCollection& volumes = canvas.get_volumes(); + + std::vector visible_volumes; + + for (const GLVolume* vol : volumes.volumes) + { + if (!printable_only || vol->printable) + visible_volumes.push_back(vol); + } + + if (visible_volumes.empty()) + return; + + BoundingBoxf3 box; + for (const GLVolume* vol : visible_volumes) + { + box.merge(vol->transformed_bounding_box()); + } + + Camera camera; + camera.zoom_to_box(box, m_data.width, m_data.height); + camera.apply_viewport(0, 0, m_data.width, m_data.height); + camera.apply_view_matrix(); + camera.apply_projection(box); + + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + render_objects(visible_volumes); + glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); +} + +void ThumbnailGenerator::render_objects(const std::vector& volumes) const +{ + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; + + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + for (const GLVolume* vol : volumes) + { + glsafe(::glColor3fv(vol->printable ? orange : gray)); + vol->render(); + } + + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_LIGHTING)); +} + +} // namespace GUI +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp new file mode 100644 index 000000000..1c3aef76c --- /dev/null +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -0,0 +1,37 @@ +#ifndef slic3r_GUI_ThumbnailGenerator_hpp_ +#define slic3r_GUI_ThumbnailGenerator_hpp_ + +#if ENABLE_THUMBNAIL_GENERATOR + +#include "../libslic3r/GCode/ThumbnailData.hpp" + +#include + +namespace Slic3r { + class GLVolume; +namespace GUI { + class GLCanvas3D; + + class ThumbnailGenerator + { + ThumbnailData m_data; + + public: + ThumbnailGenerator() { reset(); } + + void reset(); + + bool render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only); + + private: + void render(const GLCanvas3D& canvas, bool printable_only); + void render_objects(const std::vector& volumes) const; + }; + +} // namespace GUI +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR + +#endif // slic3r_GUI_ThumbnailGenerator_hpp_ + From 4d1153c866bef9af7525ea4e1e7616b8e4acc115 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 23 Oct 2019 13:31:24 +0200 Subject: [PATCH 02/35] ENABLE_THUMBNAIL_GENERATOR -> WIP: Refactoring and preparation for adding thumbnails to exported gcode and 3mf files --- src/libslic3r/Format/3mf.cpp | 103 ++++++++++++++++++++ src/libslic3r/Format/3mf.hpp | 13 +++ src/libslic3r/GCode.cpp | 49 +++++++++- src/libslic3r/GCode.hpp | 21 ++++ src/libslic3r/GCode/ThumbnailData.cpp | 19 ++-- src/libslic3r/GCode/ThumbnailData.hpp | 2 + src/libslic3r/Print.cpp | 16 +++ src/libslic3r/Print.hpp | 13 +++ src/slic3r/GUI/BackgroundSlicingProcess.cpp | 12 ++- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 17 ++++ src/slic3r/GUI/GLCanvas3D.cpp | 6 ++ src/slic3r/GUI/Plater.cpp | 53 +++++++++- src/slic3r/GUI/Plater.hpp | 6 ++ src/slic3r/GUI/ThumbnailGenerator.cpp | 45 +++++---- src/slic3r/GUI/ThumbnailGenerator.hpp | 17 ++-- 15 files changed, 346 insertions(+), 46 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 47a8e5280..a981cca61 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -3,6 +3,11 @@ #include "../Utils.hpp" #include "../GCode.hpp" #include "../Geometry.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include "../GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "../I18N.hpp" @@ -40,6 +45,11 @@ const std::string MODEL_EXTENSION = ".model"; const std::string MODEL_FILE = "3D/3dmodel.model"; // << this is the only format of the string which works with CURA const std::string CONTENT_TYPES_FILE = "[Content_Types].xml"; const std::string RELATIONSHIPS_FILE = "_rels/.rels"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +const std::string THUMBNAIL_FILE = "Metadata/thumbnail.png"; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config"; const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; @@ -1806,11 +1816,32 @@ namespace Slic3r { typedef std::map IdToObjectDataMap; public: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_content_types_file_to_archive(mz_zip_archive& archive); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_relationships_file_to_archive(mz_zip_archive& archive); bool _add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data); bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets); @@ -1823,13 +1854,33 @@ namespace Slic3r { bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + { + clear_errors(); + return _save_model_to_file(filename, model, config, thumbnail); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) { clear_errors(); return _save_model_to_file(filename, model, config); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { mz_zip_archive archive; mz_zip_zero_struct(&archive); @@ -1848,6 +1899,21 @@ namespace Slic3r { return false; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + if ((thumbnail != nullptr) && thumbnail->is_valid()) + { + // Adds the file Metadata/thumbnail.png. + if (!_add_thumbnail_file_to_archive(archive, *thumbnail)) + { + close_zip_writer(&archive); + boost::filesystem::remove(filename); + return false; + } + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Adds relationships file ("_rels/.rels"). // The content of this file is the same for each PrusaSlicer 3mf. // The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA. @@ -1941,6 +2007,11 @@ namespace Slic3r { stream << "\n"; stream << " \n"; stream << " \n"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + stream << " \n"; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -1954,12 +2025,28 @@ namespace Slic3r { return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail) + { + // TODO -> add Metadata/thumbnail.png file containing thumbnail_data + + return true; + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool _3MF_Exporter::_add_relationships_file_to_archive(mz_zip_archive& archive) { std::stringstream stream; stream << "\n"; stream << "\n"; stream << " \n"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + stream << " \n"; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -2453,13 +2540,29 @@ namespace Slic3r { return res; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { if ((path == nullptr) || (model == nullptr)) return false; _3MF_Exporter exporter; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool res = exporter.save_model_to_file(path, *model, config, thumbnail); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool res = exporter.save_model_to_file(path, *model, config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!res) exporter.log_errors(); diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index f387192ab..0ce6eb742 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -22,13 +22,26 @@ namespace Slic3r { class Model; class DynamicPrintConfig; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Load the content of a 3mf file into the given model and preset bundle. extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version); // Save the given model and the config data contained in the given Print into a 3mf file. // The model could be modified during the export process if meshes are not repaired or have no shared vertices +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; // namespace Slic3r diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2d14155a3..13b417efa 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6,6 +6,11 @@ #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" @@ -652,7 +657,15 @@ std::vector>> GCode::collec return layers_to_print; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_CLEAR(); @@ -678,7 +691,15 @@ 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); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ this->_do_export(*print, file); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fflush(file); if (ferror(file)) { fclose(file); @@ -742,7 +763,15 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str()); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void GCode::_do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::_do_export(Print &print, FILE *file) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_FUNC(); @@ -934,6 +963,21 @@ void GCode::_do_export(Print &print, FILE *file) // Write information on the generator. _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + // Write thumbnail + if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) + { + _write(file, "\n;\n; thumbnail begin\n"); + + // TODO -> export content of thumbnail_data.pixels + + _write(file, "; thumbnail end\n;\n\n"); + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Write notes (content of the Print Settings tab -> Notes) { std::list lines; @@ -949,11 +993,6 @@ void GCode::_do_export(Print &print, FILE *file) } print.throw_if_canceled(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // Write some terse information on the slicing parameters. const PrintObject *first_object = print.objects().front(); const double layer_height = first_object->config().layer_height.value; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 45ff7eda6..4c5b92bf1 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -30,6 +30,11 @@ namespace Slic3r { // Forward declarations. class GCode; class GCodePreviewData; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class AvoidCrossingPerimeters { public: @@ -162,7 +167,15 @@ 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); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests. const Vec2d& origin() const { return m_origin; } @@ -190,7 +203,15 @@ public: static void append_full_config(const Print& print, std::string& str); protected: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void _do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void _do_export(Print &print, FILE *file); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif //ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Object and support extrusions of the same PrintObject at the same print_z. struct LayerToPrint diff --git a/src/libslic3r/GCode/ThumbnailData.cpp b/src/libslic3r/GCode/ThumbnailData.cpp index 17ccbdeb6..80165916b 100644 --- a/src/libslic3r/GCode/ThumbnailData.cpp +++ b/src/libslic3r/GCode/ThumbnailData.cpp @@ -7,16 +7,16 @@ namespace Slic3r { void ThumbnailData::set(unsigned int w, unsigned int h) { - if (!pixels.empty()) - reset(); - if ((w == 0) || (h == 0)) return; - width = w; - height = h; - // defaults to white texture - pixels = std::vector(width * height * 4, 255); + if ((width != w) || (height != h)) + { + width = w; + height = h; + // defaults to white texture + pixels = std::vector(width * height * 4, 255); + } } void ThumbnailData::reset() @@ -26,6 +26,11 @@ void ThumbnailData::reset() pixels.clear(); } +bool ThumbnailData::is_valid() const +{ + return (width != 0) && (height != 0) && ((unsigned int)pixels.size() == 4 * width * height); +} + } // namespace Slic3r #endif // ENABLE_THUMBNAIL_GENERATOR \ No newline at end of file diff --git a/src/libslic3r/GCode/ThumbnailData.hpp b/src/libslic3r/GCode/ThumbnailData.hpp index 193068ebe..9823ffd31 100644 --- a/src/libslic3r/GCode/ThumbnailData.hpp +++ b/src/libslic3r/GCode/ThumbnailData.hpp @@ -16,6 +16,8 @@ struct ThumbnailData ThumbnailData() { reset(); } void set(unsigned int w, unsigned int h); void reset(); + + bool is_valid() const; }; } // namespace Slic3r diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 88645df15..742a2a960 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1536,7 +1536,15 @@ void Print::process() // The export_gcode may die for various reasons (fails to process output_filename_format, // 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) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // output everything to a G-code file // The following call may die if the output_filename_format template substitution fails. @@ -1553,7 +1561,15 @@ 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); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ gcode.do_export(this, path.c_str(), preview_data); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return path.c_str(); } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 6d94a515f..8dc54ee1d 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -19,6 +19,11 @@ 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 { @@ -305,7 +310,15 @@ public: void process() override; // 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); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // methods for handling state bool is_step_done(PrintStep step) const { return Inherited::is_step_done(step); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index a1db6884e..9d53d60b2 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -82,8 +82,16 @@ void BackgroundSlicingProcess::process_fff() assert(m_print == m_fff_print); m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); - m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); - if (this->set_step_started(bspsGCodeFinalize)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { //FIXME localize the messages // Perform the final post-processing of the export path by applying the print statistics over the file name. diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index cf5edd55f..af20554df 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,6 +17,11 @@ namespace Slic3r { class DynamicPrintConfig; class GCodePreviewData; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class Model; class SLAPrint; @@ -49,6 +54,12 @@ public: void set_fff_print(Print *print) { m_fff_print = print; } 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; } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished // and the background processing will transition into G-code export. // The wxCommandEvent is sent to the UI thread asynchronously without waiting for the event to be processed. @@ -151,6 +162,12 @@ private: SLAPrint *m_sla_print = nullptr; // 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; +#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; // Output path provided by the user. The output path may be set even if the slicing is running, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c55d64b47..4e72d1526 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2108,6 +2108,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re manip->set_dirty(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_THUMBNAIL_GENERATOR +// wxGetApp().plater()->generate_thumbnail(256, 256, true); +//#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // and force this canvas to be redrawn. m_dirty = true; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4c44cce75..66fb72bbc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1926,6 +1926,12 @@ struct Plater::priv bool can_mirror() const; bool can_reload_from_disk() const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void msw_rescale_object_menu(); // returns the path to project file with the given extension (none if extension == wxEmptyString) @@ -1993,6 +1999,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_fff_print(&fff_print); 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_generator.get_data()); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); // Default printer technology for default config. @@ -3037,6 +3048,16 @@ 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) + { + // force update of thumbnail data, so that they can be inserted into the exported gcode + thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); + thumbnail_generator.save_to_png_file("C:/prusa/test/test.png"); + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // The print is valid and it can be started. if (this->background_process.start()) { this->statusbar()->set_cancel_callback([this]() { @@ -3070,11 +3091,6 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job) return; if (! output_path.empty()) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - thumbnail_generator.render_to_png_file(*view3D->get_canvas3d(), "C:/prusa/test/test.png", 256, 256, false); -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.schedule_export(output_path.string()); } else { background_process.schedule_upload(std::move(upload_job)); @@ -3604,6 +3620,15 @@ bool Plater::priv::init_object_menu() return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) +{ + thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, w, h, printable_only); +} +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Plater::priv::msw_rescale_object_menu() { for (MenuWithSeparators* menu : { &object_menu, &sla_object_menu, &part_menu, &default_menu }) @@ -4642,7 +4667,16 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); const std::string path_u8 = into_u8(path); wxBusyCursor wait; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + p->generate_thumbnail(128, 128, false); + if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_generator.get_data())) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Success p->statusbar()->set_status_text(wxString::Format(_(L("3MF file exported to %s")), path)); p->set_project_filename(path); @@ -5139,6 +5173,15 @@ void Plater::paste_from_clipboard() p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void Plater::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) +{ + p->generate_thumbnail(w, h, printable_only); +} +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Plater::msw_rescale() { p->preview->msw_rescale(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 00ceb89bc..b14cff65a 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -240,6 +240,12 @@ public: void copy_selection_to_clipboard(); void paste_from_clipboard(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool can_delete() const; bool can_delete_all() const; bool can_increase_instances() const; diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index db823cc0b..a50c5541c 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -3,9 +3,12 @@ #if ENABLE_THUMBNAIL_GENERATOR -#include "GLCanvas3D.hpp" +#include "Camera.hpp" #include "3DScene.hpp" +#include "GUI.hpp" +#include +#include #include namespace Slic3r { @@ -16,10 +19,18 @@ void ThumbnailGenerator::reset() m_data.reset(); } -bool ThumbnailGenerator::render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only) +void ThumbnailGenerator::generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only) { + std::cout << "Generated thumbnail " << w << "x" << h << std::endl; + m_data.set(w, h); - render(canvas, printable_only); + render_and_store(volumes, printable_only); +} + +bool ThumbnailGenerator::save_to_png_file(const std::string& filename) +{ + if (!m_data.is_valid()) + return false; wxImage image(m_data.width, m_data.height); image.InitAlpha(); @@ -30,24 +41,26 @@ bool ThumbnailGenerator::render_to_png_file(const GLCanvas3D& canvas, const std: for (unsigned int c = 0; c < m_data.width; ++c) { unsigned char* px = m_data.pixels.data() + 4 * (rr + c); -// unsigned char* px = m_data.pixels.data() + 4 * (r * m_data.width + c); image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); image.SetAlpha((int)c, (int)r, px[3]); } } - image.SaveFile(filename, wxBITMAP_TYPE_PNG); + std::string path = filename; + if (!boost::iends_with(path, ".png")) + path = boost::filesystem::path(path).replace_extension(".png").string(); - return true; + return image.SaveFile(from_u8(path), wxBITMAP_TYPE_PNG); } -void ThumbnailGenerator::render(const GLCanvas3D& canvas, bool printable_only) +void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool printable_only) { - const GLVolumeCollection& volumes = canvas.get_volumes(); + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; - std::vector visible_volumes; + GLVolumeConstPtrs visible_volumes; - for (const GLVolume* vol : volumes.volumes) + for (const GLVolume* vol : volumes) { if (!printable_only || vol->printable) visible_volumes.push_back(vol); @@ -69,19 +82,10 @@ void ThumbnailGenerator::render(const GLCanvas3D& canvas, bool printable_only) camera.apply_projection(box); glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - render_objects(visible_volumes); - glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); -} - -void ThumbnailGenerator::render_objects(const std::vector& volumes) const -{ - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; - glsafe(::glEnable(GL_LIGHTING)); glsafe(::glEnable(GL_DEPTH_TEST)); - for (const GLVolume* vol : volumes) + for (const GLVolume* vol : visible_volumes) { glsafe(::glColor3fv(vol->printable ? orange : gray)); vol->render(); @@ -89,6 +93,7 @@ void ThumbnailGenerator::render_objects(const std::vector& volu glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_LIGHTING)); + glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); } } // namespace GUI diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp index 1c3aef76c..e632106cd 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -5,15 +5,15 @@ #include "../libslic3r/GCode/ThumbnailData.hpp" -#include - namespace Slic3r { class GLVolume; -namespace GUI { - class GLCanvas3D; + typedef std::vector GLVolumePtrs; + namespace GUI { class ThumbnailGenerator { + typedef std::vector GLVolumeConstPtrs; + ThumbnailData m_data; public: @@ -21,11 +21,14 @@ namespace GUI { void reset(); - bool render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only); + void generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only); + + const ThumbnailData& get_data() const { return m_data; } + + bool save_to_png_file(const std::string& filename); private: - void render(const GLCanvas3D& canvas, bool printable_only); - void render_objects(const std::vector& volumes) const; + void render_and_store(const GLVolumePtrs& volumes, bool printable_only); }; } // namespace GUI From 16fd2820db44a34acb4f7aee1295c8ce05996530 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 23 Oct 2019 16:01:23 +0200 Subject: [PATCH 03/35] ENABLE_THUMBNAIL_GENERATOR -> WIP: Added missing include and preparation for adding thumbnail to exported sla archive files --- src/libslic3r/SLA/SLARasterWriter.cpp | 16 +++++++++++++++- src/libslic3r/SLA/SLARasterWriter.hpp | 18 ++++++++++++++++++ src/libslic3r/SLAPrint.hpp | 12 ++++++++++++ src/slic3r/GUI/BackgroundSlicingProcess.cpp | 18 +++++++++++++++++- src/slic3r/GUI/GLCanvas3D.cpp | 6 ------ src/slic3r/GUI/Plater.cpp | 5 +++++ src/slic3r/GUI/ThumbnailGenerator.cpp | 2 ++ 7 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/SLA/SLARasterWriter.cpp b/src/libslic3r/SLA/SLARasterWriter.cpp index f80ce01ab..27ffb8392 100644 --- a/src/libslic3r/SLA/SLARasterWriter.cpp +++ b/src/libslic3r/SLA/SLARasterWriter.cpp @@ -28,7 +28,15 @@ RasterWriter::RasterWriter(const Raster::Resolution &res, : m_res(res), m_pxdim(pixdim), m_trafo(trafo), m_gamma(gamma) {} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void RasterWriter::save(const std::string& fpath, const ThumbnailData* thumbnail_data, const std::string& prjname) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void RasterWriter::save(const std::string &fpath, const std::string &prjname) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { try { Zipper zipper(fpath); // zipper with no compression @@ -37,7 +45,13 @@ void RasterWriter::save(const std::string &fpath, const std::string &prjname) boost::filesystem::path(fpath).stem().string() : prjname; zipper.add_entry("config.ini"); - + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + // TODO add thumbnail_data as thumbnail.png file +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + zipper << createIniContent(project); for(unsigned i = 0; i < m_layers_rst.size(); i++) diff --git a/src/libslic3r/SLA/SLARasterWriter.hpp b/src/libslic3r/SLA/SLARasterWriter.hpp index c231655d2..180ea3b8a 100644 --- a/src/libslic3r/SLA/SLARasterWriter.hpp +++ b/src/libslic3r/SLA/SLARasterWriter.hpp @@ -13,7 +13,17 @@ #include "SLARaster.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +namespace Slic3r { +struct ThumbnailData; +namespace sla { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace sla { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // API to write the zipped sla output layers and metadata. // Implementation uses PNG raster output. @@ -111,7 +121,15 @@ public: } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void save(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, const std::string& prjname = ""); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void save(const std::string &fpath, const std::string &prjname = ""); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void set_statistics(const PrintStatistics &statistics); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 2dc2a9040..0c6b93771 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -358,11 +358,23 @@ public: // Returns true if the last step was finished with success. bool finished() const override { return this->is_step_done(slaposSliceSupports) && this->Inherited::is_step_done(slapsRasterize); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + inline void export_raster(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, + const std::string& projectname = "") + { + if (m_printer) m_printer->save(fpath, thumbnail_data, projectname); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ inline void export_raster(const std::string& fpath, const std::string& projectname = "") { if(m_printer) m_printer->save(fpath, projectname); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const PrintObjects& objects() const { return m_objects; } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 9d53d60b2..6def49d69 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -117,7 +117,15 @@ void BackgroundSlicingProcess::process_sla() if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + m_sla_print->export_raster(export_path, m_thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_sla_print->export_raster(export_path); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_print->set_status(100, (boost::format(_utf8(L("Masked SLA file exported to %1%"))) % export_path).str()); } else if (! m_upload_job.empty()) { prepare_upload(); @@ -428,8 +436,16 @@ void BackgroundSlicingProcess::prepare_upload() m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); } else { m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + m_sla_print->export_raster(source_path.string(), m_thumbnail_data, m_upload_job.upload_data.upload_path.string()); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_sla_print->export_raster(source_path.string(), m_upload_job.upload_data.upload_path.string()); - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + } m_print->set_status(100, (boost::format(_utf8(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"))) % m_upload_job.printhost->get_host()).str()); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4e72d1526..c55d64b47 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2108,12 +2108,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re manip->set_dirty(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if ENABLE_THUMBNAIL_GENERATOR -// wxGetApp().plater()->generate_thumbnail(256, 256, true); -//#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // and force this canvas to be redrawn. m_dirty = true; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 66fb72bbc..25331191b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3395,6 +3395,11 @@ 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(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_THUMBNAIL_GENERATOR +// thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); +//#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index a50c5541c..37794dddf 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -11,6 +11,8 @@ #include #include +#include + namespace Slic3r { namespace GUI { From 77c52b748c3843aa1b29733022afeba5d3d0643d Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 23 Oct 2019 17:10:14 +0200 Subject: [PATCH 04/35] Zipper made available for modification after RasterWriter finishes. --- src/libslic3r/SLA/SLARasterWriter.cpp | 41 ++++++++++---------- src/libslic3r/SLA/SLARasterWriter.hpp | 22 ++--------- src/libslic3r/SLAPrint.hpp | 19 ++++------ src/libslic3r/Zipper.cpp | 5 +++ src/libslic3r/Zipper.hpp | 2 + src/slic3r/GUI/BackgroundSlicingProcess.cpp | 42 +++++++++++++-------- 6 files changed, 63 insertions(+), 68 deletions(-) diff --git a/src/libslic3r/SLA/SLARasterWriter.cpp b/src/libslic3r/SLA/SLARasterWriter.cpp index 27ffb8392..6ac86827e 100644 --- a/src/libslic3r/SLA/SLARasterWriter.cpp +++ b/src/libslic3r/SLA/SLARasterWriter.cpp @@ -28,47 +28,44 @@ RasterWriter::RasterWriter(const Raster::Resolution &res, : m_res(res), m_pxdim(pixdim), m_trafo(trafo), m_gamma(gamma) {} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR -void RasterWriter::save(const std::string& fpath, const ThumbnailData* thumbnail_data, const std::string& prjname) -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void RasterWriter::save(const std::string &fpath, const std::string &prjname) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { try { Zipper zipper(fpath); // zipper with no compression - - std::string project = prjname.empty()? - boost::filesystem::path(fpath).stem().string() : prjname; - + save(zipper, prjname); + zipper.finalize(); + } catch(std::exception& e) { + BOOST_LOG_TRIVIAL(error) << e.what(); + // Rethrow the exception + throw; + } +} + +void RasterWriter::save(Zipper &zipper, const std::string &prjname) +{ + try { + std::string project = + prjname.empty() ? + boost::filesystem::path(zipper.get_filename()).stem().string() : + prjname; + zipper.add_entry("config.ini"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - // TODO add thumbnail_data as thumbnail.png file -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - zipper << createIniContent(project); - + for(unsigned i = 0; i < m_layers_rst.size(); i++) { if(m_layers_rst[i].rawbytes.size() > 0) { char lyrnum[6]; std::sprintf(lyrnum, "%.5d", i); auto zfilename = project + lyrnum + ".png"; - + // Add binary entry to the zipper zipper.add_entry(zfilename, m_layers_rst[i].rawbytes.data(), m_layers_rst[i].rawbytes.size()); } } - - zipper.finalize(); } catch(std::exception& e) { BOOST_LOG_TRIVIAL(error) << e.what(); // Rethrow the exception diff --git a/src/libslic3r/SLA/SLARasterWriter.hpp b/src/libslic3r/SLA/SLARasterWriter.hpp index 180ea3b8a..93a315c82 100644 --- a/src/libslic3r/SLA/SLARasterWriter.hpp +++ b/src/libslic3r/SLA/SLARasterWriter.hpp @@ -12,18 +12,9 @@ #include "libslic3r/PrintConfig.hpp" #include "SLARaster.hpp" +#include "libslic3r/Zipper.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR -namespace Slic3r { -struct ThumbnailData; -namespace sla { -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace sla { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // API to write the zipped sla output layers and metadata. // Implementation uses PNG raster output. @@ -121,18 +112,11 @@ public: } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - void save(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, const std::string& prjname = ""); -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void save(const std::string &fpath, const std::string &prjname = ""); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void save(Zipper &zipper, const std::string &prjname = ""); void set_statistics(const PrintStatistics &statistics); - + void set_config(const DynamicPrintConfig &cfg); }; diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 0c6b93771..8f386d407 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -7,6 +7,7 @@ #include "SLA/SLARasterWriter.hpp" #include "Point.hpp" #include "MTUtils.hpp" +#include "Zipper.hpp" #include namespace Slic3r { @@ -358,23 +359,17 @@ public: // Returns true if the last step was finished with success. bool finished() const override { return this->is_step_done(slaposSliceSupports) && this->Inherited::is_step_done(slapsRasterize); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - inline void export_raster(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, - const std::string& projectname = "") - { - if (m_printer) m_printer->save(fpath, thumbnail_data, projectname); - } -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ inline void export_raster(const std::string& fpath, const std::string& projectname = "") { if(m_printer) m_printer->save(fpath, projectname); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + inline void export_raster(Zipper &zipper, + const std::string& projectname = "") + { + if(m_printer) m_printer->save(zipper, projectname); + } const PrintObjects& objects() const { return m_objects; } diff --git a/src/libslic3r/Zipper.cpp b/src/libslic3r/Zipper.cpp index 348be49cc..a5b53584d 100644 --- a/src/libslic3r/Zipper.cpp +++ b/src/libslic3r/Zipper.cpp @@ -217,4 +217,9 @@ void Zipper::finalize() m_impl->blow_up(); } +const std::string &Zipper::get_filename() const +{ + return m_impl->m_zipname; +} + } diff --git a/src/libslic3r/Zipper.hpp b/src/libslic3r/Zipper.hpp index a574de959..be1e69b5c 100644 --- a/src/libslic3r/Zipper.hpp +++ b/src/libslic3r/Zipper.hpp @@ -83,6 +83,8 @@ public: void finish_entry(); void finalize(); + + const std::string & get_filename() const; }; diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 6def49d69..39c6e47ef 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -107,25 +107,37 @@ void BackgroundSlicingProcess::process_fff() m_print->set_status(100, _utf8(L("Slicing complete"))); } this->set_step_done(bspsGCodeFinalize); - } + } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +static void write_thumbnail(Zipper &zipper, const ThumbnailData &data) +{ + // TODO add thumbnail_data as thumbnail.png file to the zipper with + // void Zipper::add_entry(const std::string& name, const std::uint8_t* data, size_t l); +} +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void BackgroundSlicingProcess::process_sla() { assert(m_print == m_sla_print); m_print->process(); if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { - const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path); + const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path); + + Zipper zipper(export_path); + m_sla_print->export_raster(zipper); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - m_sla_print->export_raster(export_path, m_thumbnail_data); -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - m_sla_print->export_raster(export_path); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if(m_thumbnail_data) write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + zipper.finalize(); + m_print->set_status(100, (boost::format(_utf8(L("Masked SLA file exported to %1%"))) % export_path).str()); } else if (! m_upload_job.empty()) { prepare_upload(); @@ -433,21 +445,21 @@ void BackgroundSlicingProcess::prepare_upload() throw std::runtime_error(_utf8(L("Copying of the temporary G-code to the output G-code failed"))); } run_post_process_scripts(source_path.string(), m_fff_print->config()); - m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); } else { - m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + + Zipper zipper{source_path.string()}; + m_sla_print->export_raster(zipper, m_upload_job.upload_data.upload_path.string()); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - m_sla_print->export_raster(source_path.string(), m_thumbnail_data, m_upload_job.upload_data.upload_path.string()); -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - m_sla_print->export_raster(source_path.string(), m_upload_job.upload_data.upload_path.string()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (m_thumbnail_data) write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + zipper.finalize(); } - m_print->set_status(100, (boost::format(_utf8(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"))) % m_upload_job.printhost->get_host()).str()); + m_print->set_status(100, (boost::format(_utf8(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"))) % m_upload_job.printhost->get_host()).str()); m_upload_job.upload_data.source_path = std::move(source_path); From ad0a9cf4390944deff74a45de65df2604c89dd18 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 08:46:39 +0200 Subject: [PATCH 05/35] ENABLE_THUMBNAIL_GENERATOR -> Add file thumbnail/thumbnail.png into sla output --- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 30 +++++++++++++++------ src/slic3r/GUI/Plater.cpp | 6 ++--- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 39c6e47ef..3ef32ad64 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -10,12 +10,23 @@ #include #include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx. #include "libslic3r/Print.hpp" #include "libslic3r/SLAPrint.hpp" #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 @@ -110,15 +121,18 @@ void BackgroundSlicingProcess::process_fff() } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR -static void write_thumbnail(Zipper &zipper, const ThumbnailData &data) +static void write_thumbnail(Zipper& zipper, const ThumbnailData& data) { - // TODO add thumbnail_data as thumbnail.png file to the zipper with - // void Zipper::add_entry(const std::string& name, const std::uint8_t* data, size_t l); + size_t png_size = 0; + 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); + mz_free(png_data); + } } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void BackgroundSlicingProcess::process_sla() { @@ -130,11 +144,11 @@ void BackgroundSlicingProcess::process_sla() Zipper zipper(export_path); m_sla_print->export_raster(zipper); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #if ENABLE_THUMBNAIL_GENERATOR - if(m_thumbnail_data) write_thumbnail(zipper, *m_thumbnail_data); + if (m_thumbnail_data!= nullptr) + write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ zipper.finalize(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 25331191b..71249bd90 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3396,9 +3396,9 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) // 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(); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if ENABLE_THUMBNAIL_GENERATOR -// thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); -//#endif // ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_THUMBNAIL_GENERATOR + thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); +#endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } From 4517fcd997e0495045be6466bf11edad0ff9449c Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 09:20:33 +0200 Subject: [PATCH 06/35] ENABLE_THUMBNAIL_GENERATOR -> Add file Metadata/thumbnail.png into 3mf output --- src/libslic3r/Format/3mf.cpp | 75 +++++++-------------- src/libslic3r/Format/3mf.hpp | 8 +-- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 2 +- 3 files changed, 26 insertions(+), 59 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index a981cca61..ff3cf777d 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -3,11 +3,9 @@ #include "../Utils.hpp" #include "../GCode.hpp" #include "../Geometry.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include "../GCode/ThumbnailData.hpp" #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "../I18N.hpp" @@ -45,11 +43,9 @@ const std::string MODEL_EXTENSION = ".model"; const std::string MODEL_FILE = "3D/3dmodel.model"; // << this is the only format of the string which works with CURA const std::string CONTENT_TYPES_FILE = "[Content_Types].xml"; const std::string RELATIONSHIPS_FILE = "_rels/.rels"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR const std::string THUMBNAIL_FILE = "Metadata/thumbnail.png"; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config"; const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; @@ -1816,32 +1812,22 @@ namespace Slic3r { typedef std::map IdToObjectDataMap; public: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); + bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data = nullptr); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail); + bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_content_types_file_to_archive(mz_zip_archive& archive); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail); + bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_relationships_file_to_archive(mz_zip_archive& archive); bool _add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data); bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets); @@ -1854,33 +1840,25 @@ namespace Slic3r { bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data) { clear_errors(); - return _save_model_to_file(filename, model, config, thumbnail); + return _save_model_to_file(filename, model, config, thumbnail_data); } #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) { clear_errors(); return _save_model_to_file(filename, model, config); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { mz_zip_archive archive; mz_zip_zero_struct(&archive); @@ -1899,12 +1877,11 @@ namespace Slic3r { return false; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - if ((thumbnail != nullptr) && thumbnail->is_valid()) + if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { // Adds the file Metadata/thumbnail.png. - if (!_add_thumbnail_file_to_archive(archive, *thumbnail)) + if (!_add_thumbnail_file_to_archive(archive, *thumbnail_data)) { close_zip_writer(&archive); boost::filesystem::remove(filename); @@ -1912,7 +1889,6 @@ namespace Slic3r { } } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Adds relationships file ("_rels/.rels"). // The content of this file is the same for each PrusaSlicer 3mf. @@ -2007,11 +1983,9 @@ namespace Slic3r { stream << "\n"; stream << " \n"; stream << " \n"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR stream << " \n"; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -2025,16 +1999,25 @@ namespace Slic3r { return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail) + bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data) { - // TODO -> add Metadata/thumbnail.png file containing thumbnail_data + bool res = false; - return true; + size_t png_size = 0; + void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)thumbnail_data.pixels.data(), thumbnail_data.width, thumbnail_data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1); + if (png_data != nullptr) + { + res = mz_zip_writer_add_mem(&archive, THUMBNAIL_FILE.c_str(), (const void*)png_data, png_size, MZ_DEFAULT_COMPRESSION); + mz_free(png_data); + } + + if (!res) + add_error("Unable to add thumbnail file to archive"); + + return res; } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::_add_relationships_file_to_archive(mz_zip_archive& archive) { @@ -2042,11 +2025,9 @@ namespace Slic3r { stream << "\n"; stream << "\n"; stream << " \n"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR stream << " \n"; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -2540,29 +2521,21 @@ namespace Slic3r { return res; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { if ((path == nullptr) || (model == nullptr)) return false; _3MF_Exporter exporter; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool res = exporter.save_model_to_file(path, *model, config, thumbnail); + bool res = exporter.save_model_to_file(path, *model, config, thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool res = exporter.save_model_to_file(path, *model, config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!res) exporter.log_errors(); diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index 0ce6eb742..2e85b7f59 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -22,26 +22,20 @@ namespace Slic3r { class Model; class DynamicPrintConfig; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR struct ThumbnailData; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Load the content of a 3mf file into the given model and preset bundle. extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version); // Save the given model and the config data contained in the given Print into a 3mf file. // The model could be modified during the export process if meshes are not repaired or have no shared vertices -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); + extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data = nullptr); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; // namespace Slic3r diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 3ef32ad64..67860138a 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -146,7 +146,7 @@ void BackgroundSlicingProcess::process_sla() m_sla_print->export_raster(zipper); #if ENABLE_THUMBNAIL_GENERATOR - if (m_thumbnail_data!= nullptr) + if ((m_thumbnail_data != nullptr) && m_thumbnail_data->is_valid()) write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR From 5609f537979878673275ca30dd6e122e197b38ca Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 10:06:31 +0200 Subject: [PATCH 07/35] ENABLE_THUMBNAIL_GENERATOR -> Add thumbnail data into gcode output --- src/libslic3r/GCode.cpp | 25 ++++++++----------------- src/libslic3r/GCode.hpp | 10 ---------- src/slic3r/GUI/Plater.cpp | 27 ++++++++++++++++++--------- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 13b417efa..2ea8eae1d 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6,11 +6,9 @@ #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" @@ -657,15 +655,11 @@ std::vector>> GCode::collec return layers_to_print; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_CLEAR(); @@ -691,15 +685,11 @@ 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); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ this->_do_export(*print, file); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fflush(file); if (ferror(file)) { fclose(file); @@ -763,15 +753,11 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str()); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void GCode::_do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::_do_export(Print &print, FILE *file) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_FUNC(); @@ -964,19 +950,24 @@ void GCode::_do_export(Print &print, FILE *file) // Write information on the generator. _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR // Write thumbnail if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { _write(file, "\n;\n; thumbnail begin\n"); - // TODO -> export content of thumbnail_data.pixels + size_t row_size = 4 * thumbnail_data->width; + for (int r = (int)thumbnail_data->height - 1; r >= 0 ; --r) + { + _write(file, "; "); + const void* data_ptr = thumbnail_data->pixels.data() + r * row_size; + ::fwrite((const void*)data_ptr, 1, row_size, file); + _write(file, "\n"); + } _write(file, "; thumbnail end\n;\n\n"); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Write notes (content of the Print Settings tab -> Notes) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 4c5b92bf1..8116d06fc 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -30,11 +30,9 @@ namespace Slic3r { // Forward declarations. class GCode; class GCodePreviewData; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR struct ThumbnailData; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class AvoidCrossingPerimeters { public: @@ -167,15 +165,11 @@ 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); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests. const Vec2d& origin() const { return m_origin; } @@ -203,15 +197,11 @@ public: static void append_full_config(const Print& print, std::string& str); protected: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void _do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void _do_export(Print &print, FILE *file); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif //ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Object and support extrusions of the same PrintObject at the same print_z. struct LayerToPrint diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 71249bd90..22edfcab2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -87,6 +87,13 @@ using Slic3r::_3DScene; 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::pair THUMBNAIL_SIZE_3MF = { 256, 256 }; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace GUI { @@ -3052,9 +3059,11 @@ bool Plater::priv::restart_background_process(unsigned int state) #if ENABLE_THUMBNAIL_GENERATOR if ((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) { - // force update of thumbnail data, so that they can be inserted into the exported gcode - thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); - thumbnail_generator.save_to_png_file("C:/prusa/test/test.png"); + // update thumbnail data + if (this->printer_technology == ptFFF) + generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); + else if (this->printer_technology == ptSLA) + generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); } #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -3397,7 +3406,11 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) this->preview->reload_print(); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); + // update thumbnail data + if (this->printer_technology == ptFFF) + generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); + else if (this->printer_technology == ptSLA) + generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } @@ -4672,16 +4685,12 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); const std::string path_u8 = into_u8(path); wxBusyCursor wait; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - p->generate_thumbnail(128, 128, false); + p->generate_thumbnail(THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false); if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_generator.get_data())) { #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Success p->statusbar()->set_status_text(wxString::Format(_(L("3MF file exported to %s")), path)); p->set_project_filename(path); From 6d5572ae4739cb2e21744e736c247c5990311fad Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 10:25:40 +0200 Subject: [PATCH 08/35] ENABLE_THUMBNAIL_GENERATOR -> Code cleanup --- src/libslic3r/Print.cpp | 8 -------- src/libslic3r/Print.hpp | 6 ------ src/libslic3r/Technologies.hpp | 2 -- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 13 ++----------- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 6 ------ src/slic3r/GUI/GLCanvas3D.hpp | 3 --- src/slic3r/GUI/Plater.cpp | 18 ------------------ src/slic3r/GUI/Plater.hpp | 2 -- src/slic3r/GUI/ThumbnailGenerator.hpp | 4 +++- 9 files changed, 5 insertions(+), 57 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 742a2a960..b2ed87ca0 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1536,15 +1536,11 @@ void Print::process() // The export_gcode may die for various reasons (fails to process output_filename_format, // 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) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // output everything to a G-code file // The following call may die if the output_filename_format template substitution fails. @@ -1561,15 +1557,11 @@ 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); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ gcode.do_export(this, path.c_str(), preview_data); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return path.c_str(); } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 8dc54ee1d..aedeeff18 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -19,11 +19,9 @@ 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 { @@ -310,15 +308,11 @@ public: void process() override; // 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); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // methods for handling state bool is_step_done(PrintStep step) const { return Inherited::is_step_done(step); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 40e989bb2..4b351adb2 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -32,7 +32,6 @@ #define ENABLE_NONCUSTOM_DATA_VIEW_RENDERING (0 && ENABLE_1_42_0_ALPHA1) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //==================== // 2.2.0.alpha1 techs //==================== @@ -40,6 +39,5 @@ // Enable thumbnail generator #define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // _technologies_h_ diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 67860138a..cedeab910 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -10,11 +10,9 @@ #include #include -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx. #include "libslic3r/Print.hpp" @@ -22,11 +20,9 @@ #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 @@ -93,15 +89,11 @@ void BackgroundSlicingProcess::process_fff() assert(m_print == m_fff_print); 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); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { //FIXME localize the messages @@ -465,11 +457,10 @@ 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) write_thumbnail(zipper, *m_thumbnail_data); + if ((m_thumbnail_data != nullptr) && m_thumbnail_data->is_valid()) + write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ zipper.finalize(); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index af20554df..e51a4e961 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,11 +17,9 @@ namespace Slic3r { class DynamicPrintConfig; class GCodePreviewData; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR struct ThumbnailData; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class Model; class SLAPrint; @@ -54,11 +52,9 @@ public: void set_fff_print(Print *print) { m_fff_print = print; } 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; } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished // and the background processing will transition into G-code export. @@ -162,12 +158,10 @@ private: SLAPrint *m_sla_print = nullptr; // 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; #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; // Output path provided by the user. The output path may be set even if the slicing is running, diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2e7fc2d77..eb3c60bd1 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -446,12 +446,9 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } const wxGLCanvas* get_wxglcanvas() const { return m_canvas; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR const GLVolumeCollection& get_volumes() const { return m_volumes; } -// GLVolumeCollection& get_volumes() { return m_volumes; } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init(); void post_event(wxEvent &&event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 22edfcab2..f9167cec9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -62,11 +62,9 @@ #include "GUI_Preview.hpp" #include "3DBed.hpp" #include "Camera.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include "ThumbnailGenerator.hpp" #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Tab.hpp" #include "PresetBundle.hpp" #include "BackgroundSlicingProcess.hpp" @@ -87,13 +85,11 @@ using Slic3r::_3DScene; 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::pair THUMBNAIL_SIZE_3MF = { 256, 256 }; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace GUI { @@ -1385,11 +1381,9 @@ struct Plater::priv View3D* view3D; GLToolbar view_toolbar; Preview *preview; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR ThumbnailGenerator thumbnail_generator; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BackgroundSlicingProcess background_process; bool suppressed_backround_processing_update { false }; @@ -1933,11 +1927,9 @@ struct Plater::priv bool can_mirror() const; bool can_reload_from_disk() const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void msw_rescale_object_menu(); @@ -2006,11 +1998,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_fff_print(&fff_print); 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_generator.get_data()); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); // Default printer technology for default config. @@ -3055,7 +3045,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) { @@ -3066,7 +3055,6 @@ bool Plater::priv::restart_background_process(unsigned int state) generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // The print is valid and it can be started. if (this->background_process.start()) { this->statusbar()->set_cancel_callback([this]() { @@ -3404,7 +3392,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(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR // update thumbnail data if (this->printer_technology == ptFFF) @@ -3412,7 +3399,6 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) else if (this->printer_technology == ptSLA) generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } @@ -3638,14 +3624,12 @@ bool Plater::priv::init_object_menu() return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) { thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, w, h, printable_only); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Plater::priv::msw_rescale_object_menu() { @@ -5187,14 +5171,12 @@ void Plater::paste_from_clipboard() p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void Plater::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) { p->generate_thumbnail(w, h, printable_only); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Plater::msw_rescale() { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index b14cff65a..7c671f669 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -240,11 +240,9 @@ public: void copy_selection_to_clipboard(); void paste_from_clipboard(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool can_delete() const; bool can_delete_all() const; diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp index e632106cd..ae7509b3c 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -6,9 +6,11 @@ #include "../libslic3r/GCode/ThumbnailData.hpp" namespace Slic3r { + class GLVolume; typedef std::vector GLVolumePtrs; - namespace GUI { + +namespace GUI { class ThumbnailGenerator { From a1f2ecb285daebbac4271a6b145ead6433affcd7 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 10:38:30 +0200 Subject: [PATCH 09/35] ENABLE_THUMBNAIL_GENERATOR -> Fixed color of non printable volumes into thumbnail --- src/slic3r/GUI/ThumbnailGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index 37794dddf..f2a74cae9 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -89,7 +89,7 @@ void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool prin for (const GLVolume* vol : visible_volumes) { - glsafe(::glColor3fv(vol->printable ? orange : gray)); + glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); vol->render(); } From a417da8fea69547009ddb5994c44ade60c5fa9ac Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 11:08:39 +0200 Subject: [PATCH 10/35] ENABLE_THUMBNAIL_GENERATOR -> Fixed volumes visibility test to render them into thumbnail --- src/slic3r/GUI/ThumbnailGenerator.cpp | 34 ++++++--------------------- src/slic3r/GUI/ThumbnailGenerator.hpp | 2 -- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index f2a74cae9..634f9e61c 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -29,34 +29,14 @@ void ThumbnailGenerator::generate(const GLVolumePtrs& volumes, unsigned int w, u render_and_store(volumes, printable_only); } -bool ThumbnailGenerator::save_to_png_file(const std::string& filename) -{ - if (!m_data.is_valid()) - return false; - - wxImage image(m_data.width, m_data.height); - image.InitAlpha(); - - for (unsigned int r = 0; r < m_data.height; ++r) - { - unsigned int rr = (m_data.height - 1 - r) * m_data.width; - for (unsigned int c = 0; c < m_data.width; ++c) - { - unsigned char* px = m_data.pixels.data() + 4 * (rr + c); - image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); - image.SetAlpha((int)c, (int)r, px[3]); - } - } - - std::string path = filename; - if (!boost::iends_with(path, ".png")) - path = boost::filesystem::path(path).replace_extension(".png").string(); - - return image.SaveFile(from_u8(path), wxBITMAP_TYPE_PNG); -} - void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool printable_only) { + auto is_visible = [] (const GLVolume& v) -> bool { + bool ret = v.printable; + ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); + return ret; + }; + static const float orange[] = { 0.99f, 0.49f, 0.26f }; static const float gray[] = { 0.64f, 0.64f, 0.64f }; @@ -64,7 +44,7 @@ void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool prin for (const GLVolume* vol : volumes) { - if (!printable_only || vol->printable) + if (!printable_only || is_visible(*vol)) visible_volumes.push_back(vol); } diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp index ae7509b3c..20087b79b 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -27,8 +27,6 @@ namespace GUI { const ThumbnailData& get_data() const { return m_data; } - bool save_to_png_file(const std::string& filename); - private: void render_and_store(const GLVolumePtrs& volumes, bool printable_only); }; From 29fd0ef7c6d2fdc1dcca6d599ba128d48615e232 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 12:09:09 +0200 Subject: [PATCH 11/35] ENABLE_THUMBNAIL_GENERATOR -> Refactoring to simplify code --- src/slic3r/CMakeLists.txt | 2 -- src/slic3r/GUI/GLCanvas3D.cpp | 61 +++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 10 +++--- src/slic3r/GUI/Plater.cpp | 25 ++++++-------- src/slic3r/GUI/Plater.hpp | 4 --- 5 files changed, 76 insertions(+), 26 deletions(-) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 0b2dd6702..17b76e629 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -136,8 +136,6 @@ set(SLIC3R_GUI_SOURCES GUI/ProgressStatusBar.cpp GUI/PrintHostDialogs.cpp GUI/PrintHostDialogs.hpp - GUI/ThumbnailGenerator.cpp - GUI/ThumbnailGenerator.hpp Utils/Http.cpp Utils/Http.hpp Utils/FixModelByWin10.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c55d64b47..8d16187cb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7,6 +7,9 @@ #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/GCode/PreviewData.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "libslic3r/GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include "libslic3r/Geometry.hpp" #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/Utils.hpp" @@ -1643,6 +1646,64 @@ void GLCanvas3D::render() #endif // ENABLE_RENDER_STATISTICS } +#if ENABLE_THUMBNAIL_GENERATOR +void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only) +{ + auto is_visible = [](const GLVolume& v) -> bool { + bool ret = v.printable; + ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); + return ret; + }; + + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; + + thumbnail_data.set(w, h); + + GLVolumePtrs visible_volumes; + + for (GLVolume* vol : m_volumes.volumes) + { + if (!printable_only || is_visible(*vol)) + visible_volumes.push_back(vol); + } + + if (visible_volumes.empty()) + return; + + BoundingBoxf3 box; + for (const GLVolume* vol : visible_volumes) + { + box.merge(vol->transformed_bounding_box()); + } + + Camera camera; + camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); + camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); + camera.apply_view_matrix(); + camera.apply_projection(box); + + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + for (const GLVolume* vol : visible_volumes) + { + glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); + vol->render(); + } + + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_LIGHTING)); + glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + + std::cout << "Generated thumbnail " << thumbnail_data.width << "x" << thumbnail_data.height << std::endl; + + // force a frame render to restore the default framebuffer + render(); +} +#endif // ENABLE_THUMBNAIL_GENERATOR + void GLCanvas3D::select_all() { m_selection.add_all(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index eb3c60bd1..611e9a932 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -36,6 +36,9 @@ class GLShader; class ExPolygon; class BackgroundSlicingProcess; class GCodePreviewData; +#if ENABLE_THUMBNAIL_GENERATOR +struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR struct SlicingParameters; enum LayerHeightEditActionType : unsigned int; @@ -446,10 +449,6 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } const wxGLCanvas* get_wxglcanvas() const { return m_canvas; } -#if ENABLE_THUMBNAIL_GENERATOR - const GLVolumeCollection& get_volumes() const { return m_volumes; } -#endif // ENABLE_THUMBNAIL_GENERATOR - bool init(); void post_event(wxEvent &&event); @@ -523,6 +522,9 @@ public: bool is_dragging() const { return m_gizmos.is_dragging() || m_moving; } void render(); +#if ENABLE_THUMBNAIL_GENERATOR + void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only); +#endif // ENABLE_THUMBNAIL_GENERATOR void select_all(); void deselect_all(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f9167cec9..0ebd208fa 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -32,6 +32,9 @@ #include "libslic3r/Format/AMF.hpp" #include "libslic3r/Format/3mf.hpp" #include "libslic3r/GCode/PreviewData.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "libslic3r/GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include "libslic3r/Model.hpp" #include "libslic3r/Polygon.hpp" #include "libslic3r/Print.hpp" @@ -62,9 +65,6 @@ #include "GUI_Preview.hpp" #include "3DBed.hpp" #include "Camera.hpp" -#if ENABLE_THUMBNAIL_GENERATOR -#include "ThumbnailGenerator.hpp" -#endif // ENABLE_THUMBNAIL_GENERATOR #include "Tab.hpp" #include "PresetBundle.hpp" #include "BackgroundSlicingProcess.hpp" @@ -1370,6 +1370,9 @@ struct Plater::priv Slic3r::Model model; PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; +#if ENABLE_THUMBNAIL_GENERATOR + Slic3r::ThumbnailData thumbnail_data; +#endif // ENABLE_THUMBNAIL_GENERATOR // GUI elements wxSizer* panel_sizer{ nullptr }; @@ -1381,9 +1384,6 @@ struct Plater::priv View3D* view3D; GLToolbar view_toolbar; Preview *preview; -#if ENABLE_THUMBNAIL_GENERATOR - ThumbnailGenerator thumbnail_generator; -#endif // ENABLE_THUMBNAIL_GENERATOR BackgroundSlicingProcess background_process; bool suppressed_backround_processing_update { false }; @@ -1999,7 +1999,7 @@ 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_generator.get_data()); + background_process.set_thumbnail_data(&thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); @@ -3627,7 +3627,7 @@ bool Plater::priv::init_object_menu() #if ENABLE_THUMBNAIL_GENERATOR void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) { - thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, w, h, printable_only); + view3D->get_canvas3d()->render_thumbnail(thumbnail_data, w, h, printable_only); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -4671,7 +4671,7 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) wxBusyCursor wait; #if ENABLE_THUMBNAIL_GENERATOR p->generate_thumbnail(THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false); - if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_generator.get_data())) { + if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_data)) { #else if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { #endif // ENABLE_THUMBNAIL_GENERATOR @@ -5171,13 +5171,6 @@ void Plater::paste_from_clipboard() p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } -#if ENABLE_THUMBNAIL_GENERATOR -void Plater::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) -{ - p->generate_thumbnail(w, h, printable_only); -} -#endif // ENABLE_THUMBNAIL_GENERATOR - void Plater::msw_rescale() { p->preview->msw_rescale(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 7c671f669..00ceb89bc 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -240,10 +240,6 @@ public: void copy_selection_to_clipboard(); void paste_from_clipboard(); -#if ENABLE_THUMBNAIL_GENERATOR - void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); -#endif // ENABLE_THUMBNAIL_GENERATOR - bool can_delete() const; bool can_delete_all() const; bool can_increase_instances() const; From d01532f4c682abd16a37cd0bff1f330911114d2b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 12:11:24 +0200 Subject: [PATCH 12/35] ENABLE_THUMBNAIL_GENERATOR -> Removed obsolete files --- src/slic3r/GUI/ThumbnailGenerator.cpp | 84 --------------------------- src/slic3r/GUI/ThumbnailGenerator.hpp | 40 ------------- 2 files changed, 124 deletions(-) delete mode 100644 src/slic3r/GUI/ThumbnailGenerator.cpp delete mode 100644 src/slic3r/GUI/ThumbnailGenerator.hpp diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp deleted file mode 100644 index 634f9e61c..000000000 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "libslic3r/libslic3r.h" -#include "ThumbnailGenerator.hpp" - -#if ENABLE_THUMBNAIL_GENERATOR - -#include "Camera.hpp" -#include "3DScene.hpp" -#include "GUI.hpp" - -#include -#include -#include - -#include - -namespace Slic3r { -namespace GUI { - -void ThumbnailGenerator::reset() -{ - m_data.reset(); -} - -void ThumbnailGenerator::generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only) -{ - std::cout << "Generated thumbnail " << w << "x" << h << std::endl; - - m_data.set(w, h); - render_and_store(volumes, printable_only); -} - -void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool printable_only) -{ - auto is_visible = [] (const GLVolume& v) -> bool { - bool ret = v.printable; - ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); - return ret; - }; - - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; - - GLVolumeConstPtrs visible_volumes; - - for (const GLVolume* vol : volumes) - { - if (!printable_only || is_visible(*vol)) - visible_volumes.push_back(vol); - } - - if (visible_volumes.empty()) - return; - - BoundingBoxf3 box; - for (const GLVolume* vol : visible_volumes) - { - box.merge(vol->transformed_bounding_box()); - } - - Camera camera; - camera.zoom_to_box(box, m_data.width, m_data.height); - camera.apply_viewport(0, 0, m_data.width, m_data.height); - camera.apply_view_matrix(); - camera.apply_projection(box); - - glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - for (const GLVolume* vol : visible_volumes) - { - glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); - vol->render(); - } - - glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); -} - -} // namespace GUI -} // namespace Slic3r - -#endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp deleted file mode 100644 index 20087b79b..000000000 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef slic3r_GUI_ThumbnailGenerator_hpp_ -#define slic3r_GUI_ThumbnailGenerator_hpp_ - -#if ENABLE_THUMBNAIL_GENERATOR - -#include "../libslic3r/GCode/ThumbnailData.hpp" - -namespace Slic3r { - - class GLVolume; - typedef std::vector GLVolumePtrs; - -namespace GUI { - - class ThumbnailGenerator - { - typedef std::vector GLVolumeConstPtrs; - - ThumbnailData m_data; - - public: - ThumbnailGenerator() { reset(); } - - void reset(); - - void generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only); - - const ThumbnailData& get_data() const { return m_data; } - - private: - void render_and_store(const GLVolumePtrs& volumes, bool printable_only); - }; - -} // namespace GUI -} // namespace Slic3r - -#endif // ENABLE_THUMBNAIL_GENERATOR - -#endif // slic3r_GUI_ThumbnailGenerator_hpp_ - From 1baa3336633bd4b596179310c4e0306e94155e36 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 12:30:19 +0200 Subject: [PATCH 13/35] ENABLE_THUMBNAIL_GENERATOR -> Fixed flickering of 3D view when generating thumbnail --- src/slic3r/GUI/GLCanvas3D.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8d16187cb..a99b210ac 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1697,10 +1697,9 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, glsafe(::glDisable(GL_LIGHTING)); glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - std::cout << "Generated thumbnail " << thumbnail_data.width << "x" << thumbnail_data.height << std::endl; - - // force a frame render to restore the default framebuffer - render(); + // restore the framebuffer size to avoid flickering on the 3D scene + const Size& cnv_size = get_canvas_size(); + m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); } #endif // ENABLE_THUMBNAIL_GENERATOR From 296d79abf7458719d51569fe785e519c32d57fec Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 15:56:10 +0200 Subject: [PATCH 14/35] ENABLE_THUMBNAIL_GENERATOR -> Fixed thumbnail generation for SLA and 3mf --- src/libslic3r/SLAPrint.cpp | 5 +++++ src/slic3r/GUI/GLCanvas3D.cpp | 28 +++++++++++++++++++++++++--- src/slic3r/GUI/GLCanvas3D.hpp | 4 +++- src/slic3r/GUI/Plater.cpp | 27 ++++++++++++++++----------- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 2a1ae74d7..2c080ec3d 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1372,7 +1372,12 @@ void SLAPrint::process() m_print_statistics.fast_layers_count = fast_layers; m_print_statistics.slow_layers_count = slow_layers; +#if ENABLE_THUMBNAIL_GENERATOR + // second argument set to -3 to differentiate it from the same call made into slice_supports() + m_report_status(*this, -3, "", SlicingStatus::RELOAD_SLA_PREVIEW); +#else m_report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); +#endif // ENABLE_THUMBNAIL_GENERATOR }; // Rasterizing the model objects, and their supports diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a99b210ac..914084bb6 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1647,7 +1647,7 @@ void GLCanvas3D::render() } #if ENABLE_THUMBNAIL_GENERATOR -void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only) +void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) { auto is_visible = [](const GLVolume& v) -> bool { bool ret = v.printable; @@ -1664,8 +1664,11 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, for (GLVolume* vol : m_volumes.volumes) { - if (!printable_only || is_visible(*vol)) - visible_volumes.push_back(vol); + if (!vol->is_modifier && (!parts_only || (vol->composite_id.volume_id >= 0))) + { + if (!printable_only || is_visible(*vol)) + visible_volumes.push_back(vol); + } } if (visible_volumes.empty()) @@ -1697,6 +1700,25 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, glsafe(::glDisable(GL_LIGHTING)); glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); +#if 0 + // debug export of generated image + wxImage image(thumbnail_data.width, thumbnail_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < thumbnail_data.height; ++r) + { + unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; + for (unsigned int c = 0; c < thumbnail_data.width; ++c) + { + unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile("C:/test.png", wxBITMAP_TYPE_PNG); +#endif + // restore the framebuffer size to avoid flickering on the 3D scene const Size& cnv_size = get_canvas_size(); m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 611e9a932..5b06b6311 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -523,7 +523,9 @@ public: void render(); #if ENABLE_THUMBNAIL_GENERATOR - void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only); + // printable_only == false -> render also non printable volumes as grayed + // parts_only == false -> render also sla support and pad + void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); #endif // ENABLE_THUMBNAIL_GENERATOR void select_all(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0ebd208fa..008a6eaa3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1928,7 +1928,7 @@ struct Plater::priv bool can_reload_from_disk() const; #if ENABLE_THUMBNAIL_GENERATOR - void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); + void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); #endif // ENABLE_THUMBNAIL_GENERATOR void msw_rescale_object_menu(); @@ -3050,9 +3050,12 @@ bool Plater::priv::restart_background_process(unsigned int state) { // update thumbnail data if (this->printer_technology == ptFFF) - generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); + // 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); else if (this->printer_technology == ptSLA) - generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); + // for ptSLA generate thumbnail 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); } #endif // ENABLE_THUMBNAIL_GENERATOR // The print is valid and it can be started. @@ -3392,13 +3395,14 @@ 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(); +/* #if ENABLE_THUMBNAIL_GENERATOR // update thumbnail data - if (this->printer_technology == ptFFF) - generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); - else if (this->printer_technology == ptSLA) - generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); + // 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); #endif // ENABLE_THUMBNAIL_GENERATOR +*/ } } @@ -3625,9 +3629,9 @@ bool Plater::priv::init_object_menu() } #if ENABLE_THUMBNAIL_GENERATOR -void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) +void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) { - view3D->get_canvas3d()->render_thumbnail(thumbnail_data, w, h, printable_only); + view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -4670,8 +4674,9 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) const std::string path_u8 = into_u8(path); wxBusyCursor wait; #if ENABLE_THUMBNAIL_GENERATOR - p->generate_thumbnail(THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false); - if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_data)) { + ThumbnailData thumbnail_data; + p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true); + if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &thumbnail_data)) { #else if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { #endif // ENABLE_THUMBNAIL_GENERATOR From f7d3cf063bdae284989286ef84e07869c42b9382 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 08:19:02 +0200 Subject: [PATCH 15/35] ENABLE_THUMBNAIL_GENERATOR -> Added a comment --- src/slic3r/GUI/Plater.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 008a6eaa3..60a90f1f1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3395,6 +3395,8 @@ 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 From 982ed95a3560a9e7212efa7c0eaf5f764a2096ea Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 08:57:13 +0200 Subject: [PATCH 16/35] ENABLE_THUMBNAIL_GENERATOR -> Save thumbnail size into gcode --- src/libslic3r/GCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2ea8eae1d..c96468415 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -954,7 +954,7 @@ void GCode::_do_export(Print &print, FILE *file) // Write thumbnail if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { - _write(file, "\n;\n; thumbnail begin\n"); + _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) From 843251c91fd802a9a27e71b9e03c2e2bb5c518c5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 09:04:58 +0200 Subject: [PATCH 17/35] ENABLE_THUMBNAIL_GENERATOR -> Do not render wipe tower into thumbnail --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 914084bb6..703321c3c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1664,7 +1664,7 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, for (GLVolume* vol : m_volumes.volumes) { - if (!vol->is_modifier && (!parts_only || (vol->composite_id.volume_id >= 0))) + if (!vol->is_modifier && !vol->is_wipe_tower && (!parts_only || (vol->composite_id.volume_id >= 0))) { if (!printable_only || is_visible(*vol)) visible_volumes.push_back(vol); From de60b403471bbfc510c54dae78757131e5de3ed2 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 12:18:10 +0200 Subject: [PATCH 18/35] ENABLE_THUMBNAIL_GENERATOR -> Thumbnail data saved into gcode using base64 encoding + debug code to extract thumbnails from gcode --- src/libslic3r/GCode.cpp | 12 ++--- src/slic3r/GUI/GUI_App.cpp | 86 ++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GUI_App.hpp | 5 +++ src/slic3r/GUI/MainFrame.cpp | 5 +++ 4 files changed, 102 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c96468415..db493270a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -21,6 +21,9 @@ #include #include #include +#if ENABLE_THUMBNAIL_GENERATOR +#include +#endif // ENABLE_THUMBNAIL_GENERATOR #include #include @@ -951,18 +954,15 @@ 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 + // Write thumbnail using base64 encoding if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { _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 (int r = (int)thumbnail_data->height - 1; r >= 0; --r) { - _write(file, "; "); - const void* data_ptr = thumbnail_data->pixels.data() + r * row_size; - ::fwrite((const void*)data_ptr, 1, row_size, file); - _write(file, "\n"); + _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()); } _write(file, "; thumbnail end\n;\n\n"); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b5e70c0a1..0b2244d65 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -51,6 +51,10 @@ #include #endif // __WXMSW__ +#if ENABLE_THUMBNAIL_GENERATOR +#include +#endif // ENABLE_THUMBNAIL_GENERATOR + namespace Slic3r { namespace GUI { @@ -1082,6 +1086,88 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage return res; } +#if ENABLE_THUMBNAIL_GENERATOR +void GUI_App::gcode_thumbnails_debug() +{ + const std::string BEGIN_MASK = "; thumbnail begin"; + const std::string END_MASK = "; thumbnail end"; + std::string gcode_line; + bool reading_image = false; + unsigned int width = 0; + unsigned int height = 0; + + wxFileDialog dialog(GetTopWindow(), _(L("Select a gcode file:")), "", "", "G-code files (*.gcode)|*.gcode;*.GCODE;", wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (dialog.ShowModal() != wxID_OK) + return; + + std::string in_filename = into_u8(dialog.GetPath()); + std::string out_path = boost::filesystem::path(in_filename).remove_filename().append(L"thumbnail").string(); + + boost::nowide::ifstream file(in_filename.c_str()); + std::vector rows; + if (file.good()) + { + while (std::getline(file, gcode_line)) + { + if (file.good()) + { + if (boost::starts_with(gcode_line, BEGIN_MASK)) + { + reading_image = true; + gcode_line = gcode_line.substr(BEGIN_MASK.length() + 1); + std::string::size_type x_pos = gcode_line.find('x'); + std::string width_str = gcode_line.substr(0, x_pos); + width = (unsigned int)::atoi(width_str.c_str()); + std::string height_str = gcode_line.substr(x_pos + 1); + height = (unsigned int)::atoi(height_str.c_str()); + } + else if (reading_image && boost::starts_with(gcode_line, END_MASK)) + { + if ((unsigned int)rows.size() == height) + { + std::vector thumbnail(4 * width * height, 0); + for (unsigned int r = 0; r < (unsigned int)rows.size(); ++r) + { + std::string decoded_row = boost::beast::detail::base64_decode(rows[r]); + if ((unsigned int)decoded_row.length() == width * 4) + { + void* image_ptr = (void*)(thumbnail.data() + r * width * 4); + ::memcpy(image_ptr, (const void*)decoded_row.c_str(), width * 4); + } + } + + wxImage image(width, height); + image.InitAlpha(); + + for (unsigned int r = 0; r < height; ++r) + { + unsigned int rr = r * width; + for (unsigned int c = 0; c < width; ++c) + { + unsigned char* px = thumbnail.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile(out_path + std::to_string(width) + "x" + std::to_string(height) + ".png", wxBITMAP_TYPE_PNG); + } + + reading_image = false; + width = 0; + height = 0; + rows.clear(); + } + else if (reading_image) + rows.push_back(gcode_line.substr(2)); + } + } + + file.close(); + } +} +#endif // ENABLE_THUMBNAIL_GENERATOR + void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) { if (name.empty()) { return; } diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index c5ddc0152..f9f907e42 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -189,6 +189,11 @@ public: void open_web_page_localized(const std::string &http_address); bool run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page = ConfigWizard::SP_WELCOME); +#if ENABLE_THUMBNAIL_GENERATOR + // temporary and debug only -> extract thumbnails from selected gcode and save them as png files + void gcode_thumbnails_debug(); +#endif // ENABLE_THUMBNAIL_GENERATOR + private: bool on_init_inner(); void window_pos_save(wxTopLevelWindow* window, const std::string &name); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6f39db86d..56eda2c0d 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -682,6 +682,11 @@ void MainFrame::init_menubar() helpMenu->AppendSeparator(); append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")), [this](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); }); +#if ENABLE_THUMBNAIL_GENERATOR + helpMenu->AppendSeparator(); + append_menu_item(helpMenu, wxID_ANY, _(L("DEBUG gcode thumbnails")), _(L("DEBUG ONLY - read the selected gcode file and generates png for the contained thumbnails")), + [this](wxCommandEvent&) { wxGetApp().gcode_thumbnails_debug(); }); +#endif // ENABLE_THUMBNAIL_GENERATOR } // menubar From 2d5c28d6d16b05cde3112b3ee4e92db634c975e0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 13:59:13 +0200 Subject: [PATCH 19/35] ENABLE_THUMBNAIL_GENERATOR -> Allow for multiple thumbnails into gcode and sl1 files --- src/libslic3r/GCode.cpp | 28 ++++++++++------ src/libslic3r/GCode.hpp | 4 +-- src/libslic3r/Print.cpp | 2 +- src/libslic3r/Print.hpp | 2 +- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 22 +++++++++--- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 6 ++-- src/slic3r/GUI/Plater.cpp | 37 ++++++++++++++++----- 7 files changed, 70 insertions(+), 31 deletions(-) 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 */ } From 24aed8eb71ab3d983589d42fba347664466b223d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 14:32:31 +0200 Subject: [PATCH 20/35] ENABLE_THUMBNAIL_GENERATOR -> Added missing include --- src/slic3r/GUI/GUI_App.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 0b2244d65..c35985f11 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -53,6 +53,7 @@ #if ENABLE_THUMBNAIL_GENERATOR #include +#include #endif // ENABLE_THUMBNAIL_GENERATOR namespace Slic3r { From f36dd833d2fecebe86d351fe0f2933e1c920673c Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Oct 2019 07:32:15 +0100 Subject: [PATCH 21/35] ENABLE_THUMBNAIL_GENERATOR -> Reduce thumbnail size if exceeding 3D scene canvas size --- src/slic3r/GUI/GLCanvas3D.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 703321c3c..139ee5fa4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1658,6 +1658,16 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, static const float orange[] = { 0.99f, 0.49f, 0.26f }; static const float gray[] = { 0.64f, 0.64f, 0.64f }; + const Size& cnv_size = get_canvas_size(); + unsigned int cnv_w = (unsigned int)cnv_size.get_width(); + unsigned int cnv_h = (unsigned int)cnv_size.get_height(); + if ((w > cnv_w) || (h > cnv_h)) + { + float ratio = std::min((float)cnv_w / (float)w, (float)cnv_h / (float)h); + w = (unsigned int)(ratio * (float)w); + h = (unsigned int)(ratio * (float)h); + } + thumbnail_data.set(w, h); GLVolumePtrs visible_volumes; @@ -1720,7 +1730,6 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, #endif // restore the framebuffer size to avoid flickering on the 3D scene - const Size& cnv_size = get_canvas_size(); m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); } #endif // ENABLE_THUMBNAIL_GENERATOR From 3ff3eed2b1e0751e823559542975e63d51f62010 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Oct 2019 10:27:51 +0100 Subject: [PATCH 22/35] ENABLE_THUMBNAIL_GENERATOR -> Use off-screen framebuffer to render the thumbnail on graphic cards supporting it --- src/slic3r/GUI/GLCanvas3D.cpp | 219 +++++++++++++++++---------- src/slic3r/GUI/GLCanvas3D.hpp | 6 + src/slic3r/GUI/GLCanvas3DManager.cpp | 6 + src/slic3r/GUI/GLCanvas3DManager.hpp | 2 + 4 files changed, 151 insertions(+), 82 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 139ee5fa4..b40a83682 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1649,88 +1649,10 @@ void GLCanvas3D::render() #if ENABLE_THUMBNAIL_GENERATOR void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) { - auto is_visible = [](const GLVolume& v) -> bool { - bool ret = v.printable; - ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); - return ret; - }; - - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; - - const Size& cnv_size = get_canvas_size(); - unsigned int cnv_w = (unsigned int)cnv_size.get_width(); - unsigned int cnv_h = (unsigned int)cnv_size.get_height(); - if ((w > cnv_w) || (h > cnv_h)) - { - float ratio = std::min((float)cnv_w / (float)w, (float)cnv_h / (float)h); - w = (unsigned int)(ratio * (float)w); - h = (unsigned int)(ratio * (float)h); - } - - thumbnail_data.set(w, h); - - GLVolumePtrs visible_volumes; - - for (GLVolume* vol : m_volumes.volumes) - { - if (!vol->is_modifier && !vol->is_wipe_tower && (!parts_only || (vol->composite_id.volume_id >= 0))) - { - if (!printable_only || is_visible(*vol)) - visible_volumes.push_back(vol); - } - } - - if (visible_volumes.empty()) - return; - - BoundingBoxf3 box; - for (const GLVolume* vol : visible_volumes) - { - box.merge(vol->transformed_bounding_box()); - } - - Camera camera; - camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); - camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); - camera.apply_view_matrix(); - camera.apply_projection(box); - - glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - for (const GLVolume* vol : visible_volumes) - { - glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); - vol->render(); - } - - glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - -#if 0 - // debug export of generated image - wxImage image(thumbnail_data.width, thumbnail_data.height); - image.InitAlpha(); - - for (unsigned int r = 0; r < thumbnail_data.height; ++r) - { - unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; - for (unsigned int c = 0; c < thumbnail_data.width; ++c) - { - unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); - image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); - image.SetAlpha((int)c, (int)r, px[3]); - } - } - - image.SaveFile("C:/test.png", wxBITMAP_TYPE_PNG); -#endif - - // restore the framebuffer size to avoid flickering on the 3D scene - m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); + if (GLCanvas3DManager::are_framebuffers_supported()) + _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only); + else + _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3644,6 +3566,139 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) imgui->end(); } +#if ENABLE_THUMBNAIL_GENERATOR +static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) +{ + auto is_visible = [](const GLVolume& v) -> bool + { + bool ret = v.printable; + ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); + return ret; + }; + + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; + + GLVolumePtrs visible_volumes; + + for (GLVolume* vol : volumes) + { + if (!vol->is_modifier && !vol->is_wipe_tower && (!parts_only || (vol->composite_id.volume_id >= 0))) + { + if (!printable_only || is_visible(*vol)) + visible_volumes.push_back(vol); + } + } + + if (visible_volumes.empty()) + return; + + BoundingBoxf3 box; + for (const GLVolume* vol : visible_volumes) + { + box.merge(vol->transformed_bounding_box()); + } + + Camera camera; + camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); + camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); + camera.apply_view_matrix(); + camera.apply_projection(box); + + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + for (const GLVolume* vol : visible_volumes) + { + glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); + vol->render(); + } + + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_LIGHTING)); + glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + +#if 0 + // debug export of generated image + wxImage image(thumbnail_data.width, thumbnail_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < thumbnail_data.height; ++r) + { + unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; + for (unsigned int c = 0; c < thumbnail_data.width; ++c) + { + unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile("C:/prusa/test/test.png", wxBITMAP_TYPE_PNG); +#endif +} + +void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +{ + thumbnail_data.set(w, h); + if (!thumbnail_data.is_valid()) + return; + + GLuint fbo; + glsafe(::glGenFramebuffers(1, &fbo)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, fbo)); + + GLuint tex; + glsafe(::glGenTextures(1, &tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0)); + + GLuint depth; + glsafe(::glGenRenderbuffers(1, &depth)); + glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, depth)); + glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h)); + glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth)); + + GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 }; + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) + render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0)); + glsafe(::glDeleteRenderbuffers(1, &depth)); + glsafe(::glDeleteTextures(1, &tex)); + glsafe(::glDeleteFramebuffers(1, &fbo)); +} + +void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +{ + // check that thumbnail size does not exceed the default framebuffer size + const Size& cnv_size = get_canvas_size(); + unsigned int cnv_w = (unsigned int)cnv_size.get_width(); + unsigned int cnv_h = (unsigned int)cnv_size.get_height(); + if ((w > cnv_w) || (h > cnv_h)) + { + float ratio = std::min((float)cnv_w / (float)w, (float)cnv_h / (float)h); + w = (unsigned int)(ratio * (float)w); + h = (unsigned int)(ratio * (float)h); + } + + thumbnail_data.set(w, h); + if (!thumbnail_data.is_valid()) + return; + + render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + + // restore the default framebuffer size to avoid flickering on the 3D scene + m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); +} +#endif // ENABLE_THUMBNAIL_GENERATOR + bool GLCanvas3D::_init_toolbars() { if (!_init_main_toolbar()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 5b06b6311..fce4661a4 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -674,6 +674,12 @@ private: void _render_sla_slices() const; void _render_selection_sidebar_hints() const; void _render_undo_redo_stack(const bool is_undo, float pos_x); +#if ENABLE_THUMBNAIL_GENERATOR + // render thumbnail using an off-screen framebuffer + void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + // render thumbnail using the default framebuffer + void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); +#endif // ENABLE_THUMBNAIL_GENERATOR void _update_volumes_hover_state() const; diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 9690e8a8d..03daa0b00 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -189,6 +189,7 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown; bool GLCanvas3DManager::s_compressed_textures_supported = false; +bool GLCanvas3DManager::s_framebuffers_supported = false; GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info; GLCanvas3DManager::GLCanvas3DManager() @@ -269,6 +270,11 @@ void GLCanvas3DManager::init_gl() else s_compressed_textures_supported = false; + if (s_gl_info.is_version_greater_or_equal_to(3, 0) && GLEW_ARB_framebuffer_object) + s_framebuffers_supported = true; + else + s_framebuffers_supported = false; + if (! s_gl_info.is_version_greater_or_equal_to(2, 0)) { // Complain about the OpenGL version. wxString message = wxString::Format( diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index 760266a27..a2e35f811 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -77,6 +77,7 @@ private: bool m_gl_initialized; static EMultisampleState s_multisample; static bool s_compressed_textures_supported; + static bool s_framebuffers_supported; public: GLCanvas3DManager(); @@ -97,6 +98,7 @@ public: static bool can_multisample() { return s_multisample == MS_Enabled; } static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } + static bool are_framebuffers_supported() { return s_framebuffers_supported; } static wxGLCanvas* create_wxglcanvas(wxWindow *parent); From a7b4b232e95bbe2751631dcf2ef1bd192c4a18cf Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Oct 2019 14:45:15 +0100 Subject: [PATCH 23/35] ENABLE_THUMBNAIL_GENERATOR -> Use multisampling when generating thumbnail using off-screen framebuffer --- src/slic3r/GUI/GLCanvas3D.cpp | 152 +++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 38 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b40a83682..ae2f4989f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3567,6 +3567,29 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) } #if ENABLE_THUMBNAIL_GENERATOR +#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0 +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT +static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) +{ + // debug export of generated image + wxImage image(thumbnail_data.width, thumbnail_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < thumbnail_data.height; ++r) + { + unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; + for (unsigned int c = 0; c < thumbnail_data.width; ++c) + { + unsigned char* px = (unsigned char*)thumbnail_data.pixels.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile("C:/prusa/test/test.png", wxBITMAP_TYPE_PNG); +} +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) { auto is_visible = [](const GLVolume& v) -> bool @@ -3617,26 +3640,6 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - -#if 0 - // debug export of generated image - wxImage image(thumbnail_data.width, thumbnail_data.height); - image.InitAlpha(); - - for (unsigned int r = 0; r < thumbnail_data.height; ++r) - { - unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; - for (unsigned int c = 0; c < thumbnail_data.width; ++c) - { - unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); - image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); - image.SetAlpha((int)c, (int)r, px[3]); - } - } - - image.SaveFile("C:/prusa/test/test.png", wxBITMAP_TYPE_PNG); -#endif } void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) @@ -3645,34 +3648,102 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un if (!thumbnail_data.is_valid()) return; - GLuint fbo; - glsafe(::glGenFramebuffers(1, &fbo)); - glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, fbo)); + bool multisample = m_multisample_allowed; + if (multisample) + glsafe(::glEnable(GL_MULTISAMPLE)); - GLuint tex; - glsafe(::glGenTextures(1, &tex)); - glsafe(::glBindTexture(GL_TEXTURE_2D, tex)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0)); + GLint max_samples; + glsafe(::glGetIntegerv(GL_MAX_SAMPLES, &max_samples)); + GLsizei num_samples = max_samples / 2; - GLuint depth; - glsafe(::glGenRenderbuffers(1, &depth)); - glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, depth)); - glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h)); - glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth)); + GLuint render_fbo; + glsafe(::glGenFramebuffers(1, &render_fbo)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, render_fbo)); + + GLuint render_tex = 0; + GLuint render_tex_buffer = 0; + if (multisample) + { + // use renderbuffer instead of texture to avoid the need to use glTexImage2DMultisample which is available only since OpenGL 3.2 + glsafe(::glGenRenderbuffers(1, &render_tex_buffer)); + glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_tex_buffer)); + glsafe(::glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_RGBA8, w, h)); + glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, render_tex_buffer)); + } + else + { + glsafe(::glGenTextures(1, &render_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, render_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0)); + } + + GLuint render_depth; + glsafe(::glGenRenderbuffers(1, &render_depth)); + glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_depth)); + if (multisample) + glsafe(::glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_DEPTH_COMPONENT24, w, h)); + else + glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h)); + + glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth)); GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 }; glsafe(::glDrawBuffers(1, drawBufs)); if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) + { render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + if (multisample) + { + GLuint resolve_fbo; + glsafe(::glGenFramebuffers(1, &resolve_fbo)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, resolve_fbo)); + + GLuint resolve_tex; + glsafe(::glGenTextures(1, &resolve_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, resolve_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolve_tex, 0)); + + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) + { + glsafe(::glBindFramebuffer(GL_READ_FRAMEBUFFER, render_fbo)); + glsafe(::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo)); + glsafe(::glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR)); + + glsafe(::glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo)); + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + } + + glsafe(::glDeleteTextures(1, &resolve_tex)); + glsafe(::glDeleteFramebuffers(1, &resolve_fbo)); + } + else + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + debug_output_thumbnail(thumbnail_data); +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + } + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0)); - glsafe(::glDeleteRenderbuffers(1, &depth)); - glsafe(::glDeleteTextures(1, &tex)); - glsafe(::glDeleteFramebuffers(1, &fbo)); + glsafe(::glDeleteRenderbuffers(1, &render_depth)); + if (render_tex_buffer != 0) + glsafe(::glDeleteRenderbuffers(1, &render_tex_buffer)); + if (render_tex != 0) + glsafe(::glDeleteTextures(1, &render_tex)); + glsafe(::glDeleteFramebuffers(1, &render_fbo)); + + if (multisample) + glsafe(::glDisable(GL_MULTISAMPLE)); } void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) @@ -3694,6 +3765,11 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + debug_output_thumbnail(thumbnail_data); +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + // restore the default framebuffer size to avoid flickering on the 3D scene m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); } From f6453aab1b1569fd5ac7df02232ff4dff37159a7 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 30 Oct 2019 10:09:58 +0100 Subject: [PATCH 24/35] ENABLE_THUMBNAIL_GENERATOR -> Fixed potential race condition when generating thumbnails --- src/libslic3r/GCode.cpp | 1 + src/slic3r/GUI/Plater.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 92f733787..ebb82cfb2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -971,6 +971,7 @@ void GCode::_do_export(Print &print, FILE *file) _write(file, "; thumbnail end\n;\n\n"); } + print.throw_if_canceled(); } } #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f56d6fc27..464093712 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3046,7 +3046,8 @@ bool Plater::priv::restart_background_process(unsigned int state) (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) + if (((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) && + (this->background_process.state() != BackgroundSlicingProcess::STATE_RUNNING)) { // update thumbnail data if (this->printer_technology == ptFFF) From 636e446da169940956a27e1d2fa0f240c8929adb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Oct 2019 16:40:38 +0100 Subject: [PATCH 25/35] ENABLE_THUMBNAIL_GENERATOR -> Changes to zoom factor and centering algorithm when rendering thumbnails --- src/slic3r/GUI/Camera.cpp | 102 +++++++++++++++++++++++++++++++++- src/slic3r/GUI/Camera.hpp | 17 ++++++ src/slic3r/GUI/GLCanvas3D.cpp | 15 ++++- src/slic3r/GUI/GLCanvas3D.hpp | 8 +++ 4 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 8e3a6d1f1..b5aac32ed 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -1,7 +1,9 @@ #include "libslic3r/libslic3r.h" #include "Camera.hpp" +#if !ENABLE_THUMBNAIL_GENERATOR #include "3DScene.hpp" +#endif // !ENABLE_THUMBNAIL_GENERATOR #include "GUI_App.hpp" #include "AppConfig.hpp" @@ -22,6 +24,10 @@ namespace Slic3r { namespace GUI { const double Camera::DefaultDistance = 1000.0; +#if ENABLE_THUMBNAIL_GENERATOR +const double Camera::DefaultZoomToBoxMarginFactor = 1.0; +const double Camera::DefaultZoomToVolumesMarginFactor = 1.1; +#endif // ENABLE_THUMBNAIL_GENERATOR double Camera::FrustrumMinZRange = 50.0; double Camera::FrustrumMinNearZ = 100.0; double Camera::FrustrumZMargin = 10.0; @@ -266,10 +272,18 @@ void Camera::apply_projection(const BoundingBoxf3& box) const glsafe(::glMatrixMode(GL_MODELVIEW)); } +#if ENABLE_THUMBNAIL_GENERATOR +void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor) +#else void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h) +#endif // ENABLE_THUMBNAIL_GENERATOR { // Calculate the zoom factor needed to adjust the view around the given box. +#if ENABLE_THUMBNAIL_GENERATOR + double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h, margin_factor); +#else double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h); +#endif // ENABLE_THUMBNAIL_GENERATOR if (zoom > 0.0) { m_zoom = zoom; @@ -278,6 +292,20 @@ void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h) } } +#if ENABLE_THUMBNAIL_GENERATOR +void Camera::zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor) +{ + Vec3d center; + double zoom = calc_zoom_to_volumes_factor(volumes, canvas_w, canvas_h, center, margin_factor); + if (zoom > 0.0) + { + m_zoom = zoom; + // center view around the calculated center + m_target = center; + } +} +#endif // ENABLE_THUMBNAIL_GENERATOR + #if ENABLE_CAMERA_STATISTICS void Camera::debug_render() const { @@ -372,7 +400,11 @@ std::pair Camera::calc_tight_frustrum_zs_around(const BoundingBo return ret; } +#if ENABLE_THUMBNAIL_GENERATOR +double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor) const +#else double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const +#endif // ENABLE_THUMBNAIL_GENERATOR { double max_bb_size = box.max_size(); if (max_bb_size == 0.0) @@ -405,13 +437,15 @@ double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int ca double max_x = 0.0; double max_y = 0.0; +#if !ENABLE_THUMBNAIL_GENERATOR // margin factor to give some empty space around the box double margin_factor = 1.25; +#endif // !ENABLE_THUMBNAIL_GENERATOR for (const Vec3d& v : vertices) { // project vertex on the plane perpendicular to camera forward axis - Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2)); + Vec3d pos = v - bb_center; Vec3d proj_on_plane = pos - pos.dot(forward) * forward; // calculates vertex coordinate along camera xy axes @@ -431,6 +465,72 @@ double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int ca return std::min((double)canvas_w / (2.0 * max_x), (double)canvas_h / (2.0 * max_y)); } +#if ENABLE_THUMBNAIL_GENERATOR +double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor) const +{ + if (volumes.empty()) + return -1.0; + + // project the volumes vertices on a plane perpendicular to the camera forward axis + // then calculates the vertices coordinate on this plane along the camera xy axes + + // ensure that the view matrix is updated + apply_view_matrix(); + + Vec3d right = get_dir_right(); + Vec3d up = get_dir_up(); + Vec3d forward = get_dir_forward(); + + BoundingBoxf3 box; + for (const GLVolume* volume : volumes) + { + box.merge(volume->transformed_bounding_box()); + } + center = box.center(); + + double min_x = DBL_MAX; + double min_y = DBL_MAX; + double max_x = -DBL_MAX; + double max_y = -DBL_MAX; + + for (const GLVolume* volume : volumes) + { + const Transform3d& transform = volume->world_matrix(); + const TriangleMesh* hull = volume->convex_hull(); + if (hull == nullptr) + continue; + + for (const Vec3f& vertex : hull->its.vertices) + { + Vec3d v = transform * vertex.cast(); + + // project vertex on the plane perpendicular to camera forward axis + Vec3d pos = v - center; + Vec3d proj_on_plane = pos - pos.dot(forward) * forward; + + // calculates vertex coordinate along camera xy axes + double x_on_plane = proj_on_plane.dot(right); + double y_on_plane = proj_on_plane.dot(up); + + min_x = std::min(min_x, x_on_plane); + min_y = std::min(min_y, y_on_plane); + max_x = std::max(max_x, x_on_plane); + max_y = std::max(max_y, y_on_plane); + } + } + + center += 0.5 * (max_x + min_x) * right + 0.5 * (max_y + min_y) * up; + + double dx = margin_factor * (max_x - min_x); + double dy = margin_factor * (max_y - min_y); + + if ((dx == 0.0) || (dy == 0.0)) + return -1.0f; + + return std::min((double)canvas_w / dx, (double)canvas_h / dy); +} +#endif // ENABLE_THUMBNAIL_GENERATOR + void Camera::set_distance(double distance) const { m_distance = distance; diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index 839d0d6cf..cb634138f 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -2,6 +2,9 @@ #define slic3r_Camera_hpp_ #include "libslic3r/BoundingBox.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "3DScene.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include namespace Slic3r { @@ -10,6 +13,10 @@ namespace GUI { struct Camera { static const double DefaultDistance; +#if ENABLE_THUMBNAIL_GENERATOR + static const double DefaultZoomToBoxMarginFactor; + static const double DefaultZoomToVolumesMarginFactor; +#endif // ENABLE_THUMBNAIL_GENERATOR static double FrustrumMinZRange; static double FrustrumMinNearZ; static double FrustrumZMargin; @@ -90,7 +97,12 @@ public: void apply_view_matrix() const; void apply_projection(const BoundingBoxf3& box) const; +#if ENABLE_THUMBNAIL_GENERATOR + void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor); + void zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToVolumesMarginFactor); +#else void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h); +#endif // ENABLE_THUMBNAIL_GENERATOR #if ENABLE_CAMERA_STATISTICS void debug_render() const; @@ -100,7 +112,12 @@ private: // returns tight values for nearZ and farZ plane around the given bounding box // the camera MUST be outside of the bounding box in eye coordinate of the given box std::pair calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const; +#if ENABLE_THUMBNAIL_GENERATOR + double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor) const; + double calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor = DefaultZoomToVolumesMarginFactor) const; +#else double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const; +#endif // ENABLE_THUMBNAIL_GENERATOR void set_distance(double distance) const; }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index cddae1f86..a49c772d3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1119,6 +1119,10 @@ wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); +#if ENABLE_THUMBNAIL_GENERATOR +const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25; +#endif // ENABLE_THUMBNAIL_GENERATOR + GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar) : m_canvas(canvas) , m_context(nullptr) @@ -3623,7 +3627,7 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa } Camera camera; - camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); + camera.zoom_to_volumes(visible_volumes, thumbnail_data.width, thumbnail_data.height); camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); camera.apply_view_matrix(); camera.apply_projection(box); @@ -4086,12 +4090,21 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be return bb; } +#if ENABLE_THUMBNAIL_GENERATOR +void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box, double margin_factor) +{ + const Size& cnv_size = get_canvas_size(); + m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height(), margin_factor); + m_dirty = true; +} +#else void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box) { const Size& cnv_size = get_canvas_size(); m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height()); m_dirty = true; } +#endif // ENABLE_THUMBNAIL_GENERATOR void GLCanvas3D::_refresh_if_shown_on_screen() { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index fce4661a4..850e851fa 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -107,6 +107,10 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); class GLCanvas3D { +#if ENABLE_THUMBNAIL_GENERATOR + static const double DefaultCameraZoomToBoxMarginFactor; +#endif // ENABLE_THUMBNAIL_GENERATOR + public: struct GCodePreviewVolumeIndex { @@ -646,7 +650,11 @@ private: BoundingBoxf3 _max_bounding_box(bool include_gizmos, bool include_bed_model) const; +#if ENABLE_THUMBNAIL_GENERATOR + void _zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultCameraZoomToBoxMarginFactor); +#else void _zoom_to_box(const BoundingBoxf3& box); +#endif // ENABLE_THUMBNAIL_GENERATOR void _refresh_if_shown_on_screen(); From bf8fcabb29836321dc5252439cd1b4ead0e2537f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Oct 2019 17:03:33 +0100 Subject: [PATCH 26/35] ENABLE_THUMBNAIL_GENERATOR -> Use orthographic camera when rendering thumbnails --- src/slic3r/GUI/Camera.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index b5aac32ed..94d673e82 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -26,7 +26,7 @@ namespace GUI { const double Camera::DefaultDistance = 1000.0; #if ENABLE_THUMBNAIL_GENERATOR const double Camera::DefaultZoomToBoxMarginFactor = 1.0; -const double Camera::DefaultZoomToVolumesMarginFactor = 1.1; +const double Camera::DefaultZoomToVolumesMarginFactor = 1.0; #endif // ENABLE_THUMBNAIL_GENERATOR double Camera::FrustrumMinZRange = 50.0; double Camera::FrustrumMinNearZ = 100.0; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a49c772d3..4e36739ac 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3627,6 +3627,7 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa } Camera camera; + camera.set_type(Camera::Ortho); camera.zoom_to_volumes(visible_volumes, thumbnail_data.width, thumbnail_data.height); camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); camera.apply_view_matrix(); From f94f75d481c5739ceae297aa76aa5602920c642d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 1 Nov 2019 12:19:27 +0100 Subject: [PATCH 27/35] ENABLE_THUMBNAIL_GENERATOR -> Render thumbnails using shader --- src/slic3r/GUI/Camera.cpp | 4 ++-- src/slic3r/GUI/GLCanvas3D.cpp | 35 +++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 94d673e82..9fbabe930 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -25,8 +25,8 @@ namespace GUI { const double Camera::DefaultDistance = 1000.0; #if ENABLE_THUMBNAIL_GENERATOR -const double Camera::DefaultZoomToBoxMarginFactor = 1.0; -const double Camera::DefaultZoomToVolumesMarginFactor = 1.0; +const double Camera::DefaultZoomToBoxMarginFactor = 1.025; +const double Camera::DefaultZoomToVolumesMarginFactor = 1.025; #endif // ENABLE_THUMBNAIL_GENERATOR double Camera::FrustrumMinZRange = 50.0; double Camera::FrustrumMinNearZ = 100.0; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4e36739ac..f8e7b1f94 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3594,7 +3594,8 @@ static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) } #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT -static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) + +static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) { auto is_visible = [](const GLVolume& v) -> bool { @@ -3603,8 +3604,8 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa return ret; }; - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; + static const GLfloat orange[] = { 0.923f, 0.504f, 0.264f, 1.0f }; + static const GLfloat gray[] = { 0.64f, 0.64f, 0.64f, 1.0f }; GLVolumePtrs visible_volumes; @@ -3634,17 +3635,31 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa camera.apply_projection(box); glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_LIGHTING)); glsafe(::glEnable(GL_DEPTH_TEST)); + shader.start_using(); + + GLint shader_id = shader.get_shader_program_id(); + GLint color_id = ::glGetUniformLocation(shader_id, "uniform_color"); + GLint print_box_detection_id = ::glGetUniformLocation(shader_id, "print_box.volume_detection"); + glcheck(); + + if (print_box_detection_id != -1) + glsafe(::glUniform1i(print_box_detection_id, 0)); + for (const GLVolume* vol : visible_volumes) { - glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (vol->printable && !vol->is_outside) ? orange : gray)); + else + glsafe(::glColor4fv((vol->printable && !vol->is_outside) ? orange : gray)); + vol->render(); } + shader.stop_using(); + glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glDisable(GL_LIGHTING)); } void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) @@ -3700,7 +3715,7 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); if (multisample) { @@ -3768,7 +3783,7 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne if (!thumbnail_data.is_valid()) return; - render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); #if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT @@ -4302,7 +4317,9 @@ void GLCanvas3D::_render_objects() const if (m_volumes.empty()) return; +#if !ENABLE_THUMBNAIL_GENERATOR glsafe(::glEnable(GL_LIGHTING)); +#endif // !ENABLE_THUMBNAIL_GENERATOR glsafe(::glEnable(GL_DEPTH_TEST)); m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane(); @@ -4346,7 +4363,9 @@ void GLCanvas3D::_render_objects() const m_shader.stop_using(); m_camera_clipping_plane = ClippingPlane::ClipsNothing(); +#if !ENABLE_THUMBNAIL_GENERATOR glsafe(::glDisable(GL_LIGHTING)); +#endif // !ENABLE_THUMBNAIL_GENERATOR } void GLCanvas3D::_render_selection() const From 3d450df680eee9a9e5fd786fc3ea436be03f2eff Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 4 Nov 2019 11:59:23 +0100 Subject: [PATCH 28/35] ENABLE_THUMBNAIL_GENERATOR -> Transparent background for thumbnails saved into .3mf --- src/slic3r/GUI/GLCanvas3D.cpp | 22 ++++++++++++++-------- src/slic3r/GUI/GLCanvas3D.hpp | 8 ++++---- src/slic3r/GUI/Plater.cpp | 14 +++++++------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f8e7b1f94..7d58f3c09 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1651,12 +1651,12 @@ void GLCanvas3D::render() } #if ENABLE_THUMBNAIL_GENERATOR -void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { if (GLCanvas3DManager::are_framebuffers_supported()) - _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only); + _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, transparent_background); else - _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only); + _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, transparent_background); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3595,7 +3595,7 @@ static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT -static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) +static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool transparent_background) { auto is_visible = [](const GLVolume& v) -> bool { @@ -3634,6 +3634,9 @@ static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volu camera.apply_view_matrix(); camera.apply_projection(box); + if (transparent_background) + glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 0.0f)); + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); @@ -3660,9 +3663,12 @@ static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volu shader.stop_using(); glsafe(::glDisable(GL_DEPTH_TEST)); + + if (transparent_background) + glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f)); } -void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { thumbnail_data.set(w, h); if (!thumbnail_data.is_valid()) @@ -3715,7 +3721,7 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only, transparent_background); if (multisample) { @@ -3766,7 +3772,7 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un glsafe(::glDisable(GL_MULTISAMPLE)); } -void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { // check that thumbnail size does not exceed the default framebuffer size const Size& cnv_size = get_canvas_size(); @@ -3783,7 +3789,7 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne if (!thumbnail_data.is_valid()) return; - render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only, transparent_background); glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); #if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 850e851fa..9f8d9d228 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -529,7 +529,7 @@ public: #if ENABLE_THUMBNAIL_GENERATOR // printable_only == false -> render also non printable volumes as grayed // parts_only == false -> render also sla support and pad - void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void select_all(); @@ -684,9 +684,9 @@ private: void _render_undo_redo_stack(const bool is_undo, float pos_x); #if ENABLE_THUMBNAIL_GENERATOR // render thumbnail using an off-screen framebuffer - void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); - // render thumbnail using the default framebuffer - void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); + // render thumbnail using the default framebuffer + void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void _update_volumes_hover_state() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 464093712..939af1652 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1928,7 +1928,7 @@ struct Plater::priv bool can_reload_from_disk() const; #if ENABLE_THUMBNAIL_GENERATOR - void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void msw_rescale_object_menu(); @@ -3057,7 +3057,7 @@ bool Plater::priv::restart_background_process(unsigned int state) 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); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true, false); } } else if (this->printer_technology == ptSLA) @@ -3068,7 +3068,7 @@ bool Plater::priv::restart_background_process(unsigned int state) 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); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true, false); } } } @@ -3422,7 +3422,7 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) 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); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, false, false); } } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3653,9 +3653,9 @@ bool Plater::priv::init_object_menu() } #if ENABLE_THUMBNAIL_GENERATOR -void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { - view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only); + view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only, transparent_background); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -4699,7 +4699,7 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) wxBusyCursor wait; #if ENABLE_THUMBNAIL_GENERATOR ThumbnailData thumbnail_data; - p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true); + p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true, true); if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &thumbnail_data)) { #else if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { From 64d5ac0d20b4dc7bb2213bfc33e1631bbd3d3e4d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 4 Nov 2019 14:00:26 +0100 Subject: [PATCH 29/35] ENABLE_THUMBNAIL_GENERATOR -> Export thumbnails to gcode: max length of gcode lines set to 80 characters --- src/libslic3r/GCode.cpp | 22 ++++++++++++++++++++-- src/slic3r/GUI/GUI_App.cpp | 18 +++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 481e82da1..df3225f81 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -957,6 +957,8 @@ void GCode::_do_export(Print &print, FILE *file) // Write thumbnails using base64 encoding if (thumbnail_data != nullptr) { + const unsigned int max_row_length = 78; + for (const ThumbnailData& data : *thumbnail_data) { if (data.is_valid()) @@ -966,10 +968,26 @@ void GCode::_do_export(Print &print, FILE *file) 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()); + std::string encoded = boost::beast::detail::base64_encode((const std::uint8_t*)(data.pixels.data() + r * row_size), row_size); + unsigned int row_count = 0; + while (encoded.length() > max_row_length) + { + if (row_count == 0) + _write_format(file, "; %s\n", encoded.substr(0, max_row_length).c_str()); + else + _write_format(file, ";>%s\n", encoded.substr(0, max_row_length).c_str()); + + encoded = encoded.substr(max_row_length); + ++row_count; + } + + if (row_count == 0) + _write_format(file, "; %s\n", encoded.c_str()); + else + _write_format(file, ";>%s\n", encoded.c_str()); } - _write(file, "; thumbnail end\n;\n\n"); + _write(file, "; thumbnail end\n;\n"); } print.throw_if_canceled(); } diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index c35985f11..8f0014a05 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1106,6 +1106,7 @@ void GUI_App::gcode_thumbnails_debug() boost::nowide::ifstream file(in_filename.c_str()); std::vector rows; + std::string row; if (file.good()) { while (std::getline(file, gcode_line)) @@ -1121,9 +1122,16 @@ void GUI_App::gcode_thumbnails_debug() width = (unsigned int)::atoi(width_str.c_str()); std::string height_str = gcode_line.substr(x_pos + 1); height = (unsigned int)::atoi(height_str.c_str()); + row.clear(); } else if (reading_image && boost::starts_with(gcode_line, END_MASK)) { + if (!row.empty()) + { + rows.push_back(row); + row.clear(); + } + if ((unsigned int)rows.size() == height) { std::vector thumbnail(4 * width * height, 0); @@ -1160,7 +1168,15 @@ void GUI_App::gcode_thumbnails_debug() rows.clear(); } else if (reading_image) - rows.push_back(gcode_line.substr(2)); + { + if (!row.empty() && (gcode_line[1] == ' ')) + { + rows.push_back(row); + row.clear(); + } + + row += gcode_line.substr(2); + } } } From 76377ee0fe334ad3957556ede6d1a8b84d4ed6e1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 4 Nov 2019 15:38:15 +0100 Subject: [PATCH 30/35] ENABLE_THUMBNAIL_GENERATOR -> Export thumbnails to gcode as png data in lines with max 80 characters length --- src/libslic3r/GCode.cpp | 41 ++++++++++++++++++++++++++++++---- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GUI_App.cpp | 23 ++++++++++++++----- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index df3225f81..6b773f4d3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -35,6 +35,10 @@ #include +#if ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE +#include "miniz_extension.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE + #if 0 // Enable debugging and asserts, even in the release build. #define DEBUG @@ -963,6 +967,31 @@ void GCode::_do_export(Print &print, FILE *file) { if (data.is_valid()) { +#if ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE + size_t png_size = 0; + 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) + { + _write_format(file, "\n;\n; thumbnail begin %dx%d\n", data.width, data.height); + + std::string encoded = boost::beast::detail::base64_encode((const std::uint8_t*)png_data, png_size); + + unsigned int row_count = 0; + while (encoded.length() > max_row_length) + { + _write_format(file, "; %s\n", encoded.substr(0, max_row_length).c_str()); + encoded = encoded.substr(max_row_length); + ++row_count; + } + + if (encoded.length() > 0) + _write_format(file, "; %s\n", encoded.c_str()); + + _write(file, "; thumbnail end\n;\n"); + + mz_free(png_data); + } +#else _write_format(file, "\n;\n; thumbnail begin %dx%d\n", data.width, data.height); size_t row_size = 4 * data.width; @@ -981,13 +1010,17 @@ void GCode::_do_export(Print &print, FILE *file) ++row_count; } - if (row_count == 0) - _write_format(file, "; %s\n", encoded.c_str()); - else - _write_format(file, ";>%s\n", encoded.c_str()); + if (encoded.length() > 0) + { + if (row_count == 0) + _write_format(file, "; %s\n", encoded.c_str()); + else + _write_format(file, ";>%s\n", encoded.c_str()); + } } _write(file, "; thumbnail end\n;\n"); +#endif // ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE } print.throw_if_canceled(); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 4b351adb2..15cbd3827 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -39,5 +39,6 @@ // Enable thumbnail generator #define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) +#define ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE (1 && ENABLE_THUMBNAIL_GENERATOR) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 8f0014a05..07deff54e 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1104,14 +1104,14 @@ void GUI_App::gcode_thumbnails_debug() std::string in_filename = into_u8(dialog.GetPath()); std::string out_path = boost::filesystem::path(in_filename).remove_filename().append(L"thumbnail").string(); - boost::nowide::ifstream file(in_filename.c_str()); + boost::nowide::ifstream in_file(in_filename.c_str()); std::vector rows; std::string row; - if (file.good()) + if (in_file.good()) { - while (std::getline(file, gcode_line)) + while (std::getline(in_file, gcode_line)) { - if (file.good()) + if (in_file.good()) { if (boost::starts_with(gcode_line, BEGIN_MASK)) { @@ -1126,6 +1126,16 @@ void GUI_App::gcode_thumbnails_debug() } else if (reading_image && boost::starts_with(gcode_line, END_MASK)) { +#if ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE + std::string out_filename = out_path + std::to_string(width) + "x" + std::to_string(height) + ".png"; + boost::nowide::ofstream out_file(out_filename.c_str(), std::ios::binary); + if (out_file.good()) + { + std::string decoded = boost::beast::detail::base64_decode(row); + out_file.write(decoded.c_str(), decoded.length()); + out_file.close(); + } +#else if (!row.empty()) { rows.push_back(row); @@ -1161,6 +1171,7 @@ void GUI_App::gcode_thumbnails_debug() image.SaveFile(out_path + std::to_string(width) + "x" + std::to_string(height) + ".png", wxBITMAP_TYPE_PNG); } +#endif // ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE reading_image = false; width = 0; @@ -1169,18 +1180,20 @@ void GUI_App::gcode_thumbnails_debug() } else if (reading_image) { +#if !ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE if (!row.empty() && (gcode_line[1] == ' ')) { rows.push_back(row); row.clear(); } +#endif // !ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE row += gcode_line.substr(2); } } } - file.close(); + in_file.close(); } } #endif // ENABLE_THUMBNAIL_GENERATOR From 41dadfdfcfc1c74ca23169ffc0819a2b12d43321 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 5 Nov 2019 14:50:58 +0100 Subject: [PATCH 31/35] ENABLE_THUMBNAIL_GENERATOR -> Generate thumbnails using GLEW_EXT_framebuffer_object on graphic cards supporting it --- src/slic3r/GUI/GLCanvas3D.cpp | 114 ++++++++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 4 +- src/slic3r/GUI/GLCanvas3DManager.cpp | 10 ++- src/slic3r/GUI/GLCanvas3DManager.hpp | 12 ++- 4 files changed, 129 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7d58f3c09..99f61e51e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1653,10 +1653,12 @@ void GLCanvas3D::render() #if ENABLE_THUMBNAIL_GENERATOR void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { - if (GLCanvas3DManager::are_framebuffers_supported()) - _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, transparent_background); - else - _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, transparent_background); + switch (GLCanvas3DManager::get_framebuffers_type()) + { + case GLCanvas3DManager::FB_Arb: { _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, transparent_background); break; } + case GLCanvas3DManager::FB_Ext: { _render_thumbnail_framebuffer_ext(thumbnail_data, w, h, printable_only, parts_only, transparent_background); break; } + default: { _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, transparent_background); break; } + } } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3772,6 +3774,110 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un glsafe(::glDisable(GL_MULTISAMPLE)); } +void GLCanvas3D::_render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) +{ + thumbnail_data.set(w, h); + if (!thumbnail_data.is_valid()) + return; + + bool multisample = m_multisample_allowed; + if (multisample) + glsafe(::glEnable(GL_MULTISAMPLE)); + + GLint max_samples; + glsafe(::glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples)); + GLsizei num_samples = max_samples / 2; + + GLuint render_fbo; + glsafe(::glGenFramebuffersEXT(1, &render_fbo)); + glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, render_fbo)); + + GLuint render_tex = 0; + GLuint render_tex_buffer = 0; + if (multisample) + { + // use renderbuffer instead of texture to avoid the need to use glTexImage2DMultisample which is available only since OpenGL 3.2 + glsafe(::glGenRenderbuffersEXT(1, &render_tex_buffer)); + glsafe(::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_tex_buffer)); + glsafe(::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, num_samples, GL_RGBA8, w, h)); + glsafe(::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, render_tex_buffer)); + } + else + { + glsafe(::glGenTextures(1, &render_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, render_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, render_tex, 0)); + } + + GLuint render_depth; + glsafe(::glGenRenderbuffersEXT(1, &render_depth)); + glsafe(::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_depth)); + if (multisample) + glsafe(::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, num_samples, GL_DEPTH_COMPONENT24, w, h)); + else + glsafe(::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, w, h)); + + glsafe(::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render_depth)); + + GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 }; + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) + { + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only, transparent_background); + + if (multisample) + { + GLuint resolve_fbo; + glsafe(::glGenFramebuffersEXT(1, &resolve_fbo)); + glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, resolve_fbo)); + + GLuint resolve_tex; + glsafe(::glGenTextures(1, &resolve_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, resolve_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, resolve_tex, 0)); + + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) + { + glsafe(::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, render_fbo)); + glsafe(::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, resolve_fbo)); + glsafe(::glBlitFramebufferEXT(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR)); + + glsafe(::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, resolve_fbo)); + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + } + + glsafe(::glDeleteTextures(1, &resolve_tex)); + glsafe(::glDeleteFramebuffersEXT(1, &resolve_fbo)); + } + else + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + debug_output_thumbnail(thumbnail_data); +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + } + + glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)); + glsafe(::glDeleteRenderbuffersEXT(1, &render_depth)); + if (render_tex_buffer != 0) + glsafe(::glDeleteRenderbuffersEXT(1, &render_tex_buffer)); + if (render_tex != 0) + glsafe(::glDeleteTextures(1, &render_tex)); + glsafe(::glDeleteFramebuffersEXT(1, &render_fbo)); + + if (multisample) + glsafe(::glDisable(GL_MULTISAMPLE)); +} + void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { // check that thumbnail size does not exceed the default framebuffer size diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9f8d9d228..8c2e6e9a5 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -685,7 +685,9 @@ private: #if ENABLE_THUMBNAIL_GENERATOR // render thumbnail using an off-screen framebuffer void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); - // render thumbnail using the default framebuffer + // render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported + void _render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); + // render thumbnail using the default framebuffer void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 03daa0b00..3594e85a4 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -189,7 +189,7 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown; bool GLCanvas3DManager::s_compressed_textures_supported = false; -bool GLCanvas3DManager::s_framebuffers_supported = false; +GLCanvas3DManager::EFramebufferType GLCanvas3DManager::s_framebuffers_type = GLCanvas3DManager::FB_None; GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info; GLCanvas3DManager::GLCanvas3DManager() @@ -270,10 +270,12 @@ void GLCanvas3DManager::init_gl() else s_compressed_textures_supported = false; - if (s_gl_info.is_version_greater_or_equal_to(3, 0) && GLEW_ARB_framebuffer_object) - s_framebuffers_supported = true; + if (GLEW_ARB_framebuffer_object) + s_framebuffers_type = FB_Arb; + else if (GLEW_EXT_framebuffer_object) + s_framebuffers_type = FB_Ext; else - s_framebuffers_supported = false; + s_framebuffers_type = FB_None; if (! s_gl_info.is_version_greater_or_equal_to(2, 0)) { // Complain about the OpenGL version. diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index a2e35f811..940e0230a 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -30,6 +30,13 @@ struct Camera; class GLCanvas3DManager { public: + enum EFramebufferType : unsigned char + { + FB_None, + FB_Arb, + FB_Ext + }; + class GLInfo { mutable bool m_detected; @@ -77,7 +84,7 @@ private: bool m_gl_initialized; static EMultisampleState s_multisample; static bool s_compressed_textures_supported; - static bool s_framebuffers_supported; + static EFramebufferType s_framebuffers_type; public: GLCanvas3DManager(); @@ -98,7 +105,8 @@ public: static bool can_multisample() { return s_multisample == MS_Enabled; } static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } - static bool are_framebuffers_supported() { return s_framebuffers_supported; } + static bool are_framebuffers_supported() { return (s_framebuffers_type != FB_None); } + static EFramebufferType get_framebuffers_type() { return s_framebuffers_type; } static wxGLCanvas* create_wxglcanvas(wxWindow *parent); From f8785250d67df5eeea5a26f3db52296e19c0c83d Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 5 Nov 2019 18:18:27 +0100 Subject: [PATCH 32/35] Disable test_fill.cpp`"Solid surface fill" test for now due to precission issues --- tests/fff_print/test_fill.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/fff_print/test_fill.cpp b/tests/fff_print/test_fill.cpp index ec8b44a0d..c98cdcf43 100644 --- a/tests/fff_print/test_fill.cpp +++ b/tests/fff_print/test_fill.cpp @@ -138,6 +138,8 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") { REQUIRE(paths.size() == 1); } } + + #if 0 // Disabled temporarily due to precission issues on the Mac VM SECTION("Solid surface fill") { Slic3r::Points points { Point::new_scale(6883102, 9598327.01296997), @@ -154,6 +156,8 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") { REQUIRE(test_if_solid_surface_filled(expolygon, 0.55) == true); } } + #endif + SECTION("Solid surface fill") { Slic3r::Points points { Slic3r::Point(59515297,5422499),Slic3r::Point(59531249,5578697),Slic3r::Point(59695801,6123186), From 1e8aa54559afddf526d86d0c0f58f892209fcf9a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 7 Nov 2019 09:01:28 +0100 Subject: [PATCH 33/35] ENABLE_THUMBNAIL_GENERATOR -> Added ENABLE_THUMBNAIL_GENERATOR_DEBUG (disabled) --- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GUI_App.cpp | 4 ++-- src/slic3r/GUI/MainFrame.cpp | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 15cbd3827..5d0a7592c 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -39,6 +39,7 @@ // Enable thumbnail generator #define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) +#define ENABLE_THUMBNAIL_GENERATOR_DEBUG (0 && ENABLE_THUMBNAIL_GENERATOR) #define ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE (1 && ENABLE_THUMBNAIL_GENERATOR) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 07deff54e..0b24e2215 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1087,7 +1087,7 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage return res; } -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG void GUI_App::gcode_thumbnails_debug() { const std::string BEGIN_MASK = "; thumbnail begin"; @@ -1196,7 +1196,7 @@ void GUI_App::gcode_thumbnails_debug() in_file.close(); } } -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) { diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 56eda2c0d..b76110a87 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -682,11 +682,11 @@ void MainFrame::init_menubar() helpMenu->AppendSeparator(); append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")), [this](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); }); -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG helpMenu->AppendSeparator(); append_menu_item(helpMenu, wxID_ANY, _(L("DEBUG gcode thumbnails")), _(L("DEBUG ONLY - read the selected gcode file and generates png for the contained thumbnails")), [this](wxCommandEvent&) { wxGetApp().gcode_thumbnails_debug(); }); -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG } // menubar From 67f55d3b23c36021f543e74d90d53902a6effed6 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 7 Nov 2019 12:09:04 +0100 Subject: [PATCH 34/35] Change std::async to boost thread in Plater::priv::Job --- src/slic3r/GUI/Plater.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cdd35b720..e2ea9bc1a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -1439,7 +1440,7 @@ struct Plater::priv class Job : public wxEvtHandler { int m_range = 100; - std::future m_ftr; + boost::thread m_thread; priv * m_plater = nullptr; std::atomic m_running{false}, m_canceled{false}; bool m_finalized = false; @@ -1480,7 +1481,8 @@ struct Plater::priv // Do a full refresh of scene tree, including regenerating // all the GLVolumes. FIXME The update function shall just // reload the modified matrices. - if (!was_canceled()) plater().update((unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH); + if (!was_canceled()) + plater().update(unsigned(UpdateParams::FORCE_FULL_SCREEN_REFRESH)); } public: @@ -1509,9 +1511,9 @@ struct Plater::priv } Job(const Job &) = delete; - Job(Job &&) = default; + Job(Job &&) = delete; Job &operator=(const Job &) = delete; - Job &operator=(Job &&) = default; + Job &operator=(Job &&) = delete; virtual void process() = 0; @@ -1535,7 +1537,9 @@ struct Plater::priv wxBeginBusyCursor(); try { // Execute the job - m_ftr = std::async(std::launch::async, &Job::run, this); + boost::thread::attributes attrs; + attrs.set_stack_size((sizeof(void*) == 4) ? (2048 * 1024) : (4096 * 1024)); + m_thread = boost::thread(attrs, [this] { this->run(); }); } catch (std::exception &) { update_status(status_range(), _(L("ERROR: not enough resources to " @@ -1551,16 +1555,15 @@ struct Plater::priv // returned if the timeout has been reached and the job is still // running. Call cancel() before this fn if you want to explicitly // end the job. - bool join(int timeout_ms = 0) const + bool join(int timeout_ms = 0) { - if (!m_ftr.valid()) return true; - + if (!m_thread.joinable()) return true; + if (timeout_ms <= 0) - m_ftr.wait(); - else if (m_ftr.wait_for(std::chrono::milliseconds( - timeout_ms)) == std::future_status::timeout) + m_thread.join(); + else if (!m_thread.try_join_for(boost::chrono::milliseconds(timeout_ms))) return false; - + return true; } From ad0a38e4190ad022b609f294a54c010185b1f676 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 7 Nov 2019 12:57:40 +0100 Subject: [PATCH 35/35] Follow up, unify boost::thread usage. --- src/slic3r/CMakeLists.txt | 1 + src/slic3r/GUI/BackgroundSlicingProcess.cpp | 6 +---- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 6 ++--- src/slic3r/Utils/Thread.hpp | 28 +++++++++++++++++++++ 5 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 src/slic3r/Utils/Thread.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 84a60da6e..9ed7424c0 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -156,6 +156,7 @@ set(SLIC3R_GUI_SOURCES Utils/UndoRedo.hpp Utils/HexFile.cpp Utils/HexFile.hpp + Utils/Thread.hpp ) if (APPLE) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 3f0d87c35..5ab65f340 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -261,11 +261,7 @@ bool BackgroundSlicingProcess::start() if (m_state == STATE_INITIAL) { // The worker thread is not running yet. Start it. assert(! m_thread.joinable()); - boost::thread::attributes attrs; - // Duplicating the stack allocation size of Thread Building Block worker threads of the thread pool: - // allocate 4MB on a 64bit system, allocate 2MB on a 32bit system by default. - attrs.set_stack_size((sizeof(void*) == 4) ? (2048 * 1024) : (4096 * 1024)); - m_thread = boost::thread(attrs, [this]{this->thread_proc_safe();}); + m_thread = create_thread([this]{this->thread_proc_safe();}); // Wait until the worker thread is ready to execute the background processing task. m_condition.wait(lck, [this](){ return m_state == STATE_IDLE; }); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index bf8cbc235..a603d52ac 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -6,12 +6,12 @@ #include #include -#include #include #include "libslic3r/Print.hpp" #include "slic3r/Utils/PrintHost.hpp" +#include "slic3r/Utils/Thread.hpp" namespace Slic3r { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e2ea9bc1a..da3a07a59 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -76,6 +75,7 @@ #include "../Utils/PrintHost.hpp" #include "../Utils/FixModelByWin10.hpp" #include "../Utils/UndoRedo.hpp" +#include "../Utils/Thread.hpp" #include // Needs to be last because reasons :-/ #include "WipeTowerDialog.hpp" @@ -1537,9 +1537,7 @@ struct Plater::priv wxBeginBusyCursor(); try { // Execute the job - boost::thread::attributes attrs; - attrs.set_stack_size((sizeof(void*) == 4) ? (2048 * 1024) : (4096 * 1024)); - m_thread = boost::thread(attrs, [this] { this->run(); }); + m_thread = create_thread([this] { this->run(); }); } catch (std::exception &) { update_status(status_range(), _(L("ERROR: not enough resources to " diff --git a/src/slic3r/Utils/Thread.hpp b/src/slic3r/Utils/Thread.hpp new file mode 100644 index 000000000..e9c76d2ab --- /dev/null +++ b/src/slic3r/Utils/Thread.hpp @@ -0,0 +1,28 @@ +#ifndef THREAD_HPP +#define THREAD_HPP + +#include +#include + +namespace Slic3r { + +template +inline boost::thread create_thread(boost::thread::attributes &attrs, Fn &&fn) +{ + // Duplicating the stack allocation size of Thread Building Block worker + // threads of the thread pool: allocate 4MB on a 64bit system, allocate 2MB + // on a 32bit system by default. + + attrs.set_stack_size((sizeof(void*) == 4) ? (2048 * 1024) : (4096 * 1024)); + return boost::thread{attrs, std::forward(fn)}; +} + +template inline boost::thread create_thread(Fn &&fn) +{ + boost::thread::attributes attrs; + return create_thread(attrs, std::forward(fn)); +} + +} + +#endif // THREAD_HPP