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
src
|
@ -21,6 +21,9 @@
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/log/trivial.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/iostream.hpp>
|
||||||
#include <boost/nowide/cstdio.hpp>
|
#include <boost/nowide/cstdio.hpp>
|
||||||
|
@ -951,7 +954,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
||||||
_write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str());
|
_write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str());
|
||||||
|
|
||||||
#if ENABLE_THUMBNAIL_GENERATOR
|
#if ENABLE_THUMBNAIL_GENERATOR
|
||||||
// Write thumbnail
|
// Write thumbnail using base64 encoding
|
||||||
if ((thumbnail_data != nullptr) && thumbnail_data->is_valid())
|
if ((thumbnail_data != nullptr) && thumbnail_data->is_valid())
|
||||||
{
|
{
|
||||||
_write_format(file, "\n;\n; thumbnail begin %dx%d\n", thumbnail_data->width, thumbnail_data->height);
|
_write_format(file, "\n;\n; thumbnail begin %dx%d\n", thumbnail_data->width, thumbnail_data->height);
|
||||||
|
@ -959,10 +962,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
||||||
size_t row_size = 4 * thumbnail_data->width;
|
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, "; ");
|
_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());
|
||||||
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");
|
_write(file, "; thumbnail end\n;\n\n");
|
||||||
|
|
|
@ -51,6 +51,10 @@
|
||||||
#include <Shlobj.h>
|
#include <Shlobj.h>
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
|
|
||||||
|
#if ENABLE_THUMBNAIL_GENERATOR
|
||||||
|
#include <boost/beast/core/detail/base64.hpp>
|
||||||
|
#endif // ENABLE_THUMBNAIL_GENERATOR
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
@ -1082,6 +1086,88 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage
|
||||||
return res;
|
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)
|
void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name)
|
||||||
{
|
{
|
||||||
if (name.empty()) { return; }
|
if (name.empty()) { return; }
|
||||||
|
|
|
@ -189,6 +189,11 @@ public:
|
||||||
void open_web_page_localized(const std::string &http_address);
|
void open_web_page_localized(const std::string &http_address);
|
||||||
bool run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page = ConfigWizard::SP_WELCOME);
|
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:
|
private:
|
||||||
bool on_init_inner();
|
bool on_init_inner();
|
||||||
void window_pos_save(wxTopLevelWindow* window, const std::string &name);
|
void window_pos_save(wxTopLevelWindow* window, const std::string &name);
|
||||||
|
|
|
@ -682,6 +682,11 @@ void MainFrame::init_menubar()
|
||||||
helpMenu->AppendSeparator();
|
helpMenu->AppendSeparator();
|
||||||
append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")),
|
append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")),
|
||||||
[this](wxCommandEvent&) { wxGetApp().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
|
// menubar
|
||||||
|
|
Loading…
Add table
Reference in a new issue