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