mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	ENABLE_THUMBNAIL_GENERATOR -> Thumbnail data saved into gcode using base64 encoding + debug code to extract thumbnails from gcode
This commit is contained in:
		
							parent
							
								
									843251c91f
								
							
						
					
					
						commit
						de60b40347
					
				
					 4 changed files with 102 additions and 6 deletions
				
			
		|  | @ -21,6 +21,9 @@ | |||
| #include <boost/foreach.hpp> | ||||
| #include <boost/filesystem.hpp> | ||||
| #include <boost/log/trivial.hpp> | ||||
| #if ENABLE_THUMBNAIL_GENERATOR | ||||
| #include <boost/beast/core/detail/base64.hpp> | ||||
| #endif // ENABLE_THUMBNAIL_GENERATOR
 | ||||
| 
 | ||||
| #include <boost/nowide/iostream.hpp> | ||||
| #include <boost/nowide/cstdio.hpp> | ||||
|  | @ -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"); | ||||
|  |  | |||
|  | @ -51,6 +51,10 @@ | |||
| #include <Shlobj.h> | ||||
| #endif // __WXMSW__
 | ||||
| 
 | ||||
| #if ENABLE_THUMBNAIL_GENERATOR | ||||
| #include <boost/beast/core/detail/base64.hpp> | ||||
| #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<std::string> 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<unsigned char> 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; } | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri