diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index f97586073..ddd18f88d 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -30,6 +30,7 @@ use Slic3r::Geometry qw(PI); # _dirty: boolean flag indicating, that the screen has to be redrawn on EVT_IDLE. # volumes: reference to vector of Slic3r::GUI::3DScene::Volume. # _camera_type: 'perspective' or 'ortho' +# ===================== ENRICO_GCODE_PREVIEW ================================================== __PACKAGE__->mk_accessors( qw(_quat _dirty init enable_picking enable_moving @@ -66,7 +67,50 @@ __PACKAGE__->mk_accessors( qw(_quat _dirty init _camera_target _camera_distance _zoom + + _legend_enabled + ) ); + +#__PACKAGE__->mk_accessors( qw(_quat _dirty init +# enable_picking +# enable_moving +# use_plain_shader +# on_viewport_changed +# on_hover +# on_select +# on_double_click +# on_right_click +# on_move +# on_model_update +# volumes +# _sphi _stheta +# cutting_plane_z +# cut_lines_vertices +# bed_shape +# bed_triangles +# bed_grid_lines +# bed_polygon +# background +# origin +# _mouse_pos +# _hover_volume_idx +# +# _drag_volume_idx +# _drag_start_pos +# _drag_volume_center_offset +# _drag_start_xy +# _dragged +# +# _layer_height_edited +# +# _camera_type +# _camera_target +# _camera_distance +# _zoom +# +# ) ); +# ===================== ENRICO_GCODE_PREVIEW ================================================== use constant TRACKBALLSIZE => 0.8; use constant TURNTABLE_MODE => 1; @@ -137,6 +181,9 @@ sub new { $self->_stheta(45); $self->_sphi(45); $self->_zoom(1); +# ===================== ENRICO_GCODE_PREVIEW ================================================== + $self->_legend_enabled(0); +# ===================== ENRICO_GCODE_PREVIEW ================================================== $self->use_plain_shader(0); # Collection of GLVolume objects @@ -209,6 +256,13 @@ sub new { return $self; } +# ===================== ENRICO_GCODE_PREVIEW ================================================== +sub set_legend_enabled { + my ($self, $value) = @_; + $self->_legend_enabled($value); +} +# ===================== ENRICO_GCODE_PREVIEW ================================================== + sub Destroy { my ($self) = @_; $self->{layer_height_edit_timer}->Stop; @@ -1316,6 +1370,11 @@ sub Render { glDisable(GL_BLEND); } +# ===================== ENRICO_GCODE_PREVIEW ================================================== + # draw gcode preview legend + $self->draw_legend; +# ===================== ENRICO_GCODE_PREVIEW ================================================== + $self->draw_active_object_annotations; $self->SwapBuffers(); @@ -1449,12 +1508,38 @@ sub _variable_layer_thickness_load_reset_image { # Paint the tooltip. sub _render_image { my ($self, $image, $l, $r, $b, $t) = @_; +# ===================== ENRICO_GCODE_PREVIEW ================================================== + $self->_render_texture($image->{texture_id}, $l, $r, $b, $t); + +# glColor4f(1.,1.,1.,1.); +# glDisable(GL_LIGHTING); +# glEnable(GL_BLEND); +# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +# glEnable(GL_TEXTURE_2D); +# glBindTexture(GL_TEXTURE_2D, $image->{texture_id}); +# glBegin(GL_QUADS); +# glTexCoord2d(0.,1.); glVertex3f($l, $b, 0); +# glTexCoord2d(1.,1.); glVertex3f($r, $b, 0); +# glTexCoord2d(1.,0.); glVertex3f($r, $t, 0); +# glTexCoord2d(0.,0.); glVertex3f($l, $t, 0); +# glEnd(); +# glBindTexture(GL_TEXTURE_2D, 0); +# glDisable(GL_TEXTURE_2D); +# glDisable(GL_BLEND); +# glEnable(GL_LIGHTING); +# ===================== ENRICO_GCODE_PREVIEW ================================================== +} + +# ===================== ENRICO_GCODE_PREVIEW ================================================== +sub _render_texture { + my ($self, $tex_id, $l, $r, $b, $t) = @_; + glColor4f(1.,1.,1.,1.); glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, $image->{texture_id}); + glBindTexture(GL_TEXTURE_2D, $tex_id); glBegin(GL_QUADS); glTexCoord2d(0.,1.); glVertex3f($l, $b, 0); glTexCoord2d(1.,1.); glVertex3f($r, $b, 0); @@ -1466,6 +1551,7 @@ sub _render_image { glDisable(GL_BLEND); glEnable(GL_LIGHTING); } +# ===================== ENRICO_GCODE_PREVIEW ================================================== sub draw_active_object_annotations { # $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking. @@ -1579,6 +1665,37 @@ sub draw_active_object_annotations { glEnable(GL_DEPTH_TEST); } +# ===================== ENRICO_GCODE_PREVIEW ================================================== +sub draw_legend { + my ($self) = @_; + + if ($self->_legend_enabled) + { + my $tex_id = Slic3r::GUI::_3DScene::get_legend_texture_id; + if ($tex_id > 0) + { + glDisable(GL_DEPTH_TEST); + glPushMatrix(); + glLoadIdentity(); + + my $tex_w = Slic3r::GUI::_3DScene::get_legend_texture_width; + my $tex_h = Slic3r::GUI::_3DScene::get_legend_texture_height; + + my ($cw, $ch) = $self->GetSizeWH; + + my $l = (-0.5 * $cw) / $self->_zoom; + my $t = (0.5 * $ch) / $self->_zoom; + my $r = $l + $tex_w / $self->_zoom; + my $b = $t - $tex_h / $self->_zoom; + $self->_render_texture($tex_id, $l, $r, $b, $t); + + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + } + } +} +# ===================== ENRICO_GCODE_PREVIEW ================================================== + sub opengl_info { my ($self, %params) = @_; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 63e628f3e..d7afe0e30 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -153,8 +153,17 @@ sub new { EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{preview_notebook}, sub { my $preview = $self->{preview_notebook}->GetCurrentPage; - $self->{preview3D}->load_print(1) if ($preview == $self->{preview3D}); - $preview->OnActivate if $preview->can('OnActivate'); +# ===================== ENRICO_GCODE_PREVIEW ================================================== + if ($preview == $self->{preview3D}) + { + $self->{preview3D}->canvas->set_legend_enabled(1); + $self->{preview3D}->load_print(1); + } else { + $self->{preview3D}->canvas->set_legend_enabled(0); + } +# $self->{preview3D}->load_print(1) if ($preview == $self->{preview3D}); +# ===================== ENRICO_GCODE_PREVIEW ================================================== + $preview->OnActivate if $preview->can('OnActivate'); }); # toolbar for object manipulation diff --git a/xs/src/libslic3r/GCode/Analyzer.cpp b/xs/src/libslic3r/GCode/Analyzer.cpp index 5372ff302..ae857e37e 100644 --- a/xs/src/libslic3r/GCode/Analyzer.cpp +++ b/xs/src/libslic3r/GCode/Analyzer.cpp @@ -436,6 +436,16 @@ GCodeAnalyzer::PreviewData::Color::Color(float r, float g, float b, float a) rgba[3] = a; } +std::vector GCodeAnalyzer::PreviewData::Color::as_bytes() const +{ + std::vector ret; + for (unsigned int i = 0; i < 4; ++i) + { + ret.push_back((unsigned char)(255.0f * rgba[i])); + } + return ret; +} + GCodeAnalyzer::PreviewData::Extrusion::Layer::Layer(float z, const ExtrusionPaths& paths) : z(z) , paths(paths) @@ -491,6 +501,11 @@ void GCodeAnalyzer::PreviewData::Range::set_from(const Range& other) max = other.max; } +float GCodeAnalyzer::PreviewData::Range::step_size() const +{ + return (max - min) / (float)Colors_Count; +} + const GCodeAnalyzer::PreviewData::Color& GCodeAnalyzer::PreviewData::Range::get_color_at_max() const { return colors[Colors_Count - 1]; @@ -498,12 +513,13 @@ const GCodeAnalyzer::PreviewData::Color& GCodeAnalyzer::PreviewData::Range::get_ const GCodeAnalyzer::PreviewData::Color& GCodeAnalyzer::PreviewData::Range::get_color_at(float value) const { - return empty() ? get_color_at_max() : colors[clamp((unsigned int)0, Colors_Count - 1, (unsigned int)((value - min) / _step()))]; + return empty() ? get_color_at_max() : colors[clamp((unsigned int)0, Colors_Count - 1, (unsigned int)((value - min) / step_size()))]; } -float GCodeAnalyzer::PreviewData::Range::_step() const +GCodeAnalyzer::PreviewData::LegendItem::LegendItem(const std::string& text, const GCodeAnalyzer::PreviewData::Color& color) + : text(text) + , color(color) { - return (max - min) / (float)Colors_Count; } const GCodeAnalyzer::PreviewData::Color GCodeAnalyzer::PreviewData::Extrusion::Default_Extrusion_Role_Colors[Num_Extrusion_Roles] = @@ -523,6 +539,23 @@ const GCodeAnalyzer::PreviewData::Color GCodeAnalyzer::PreviewData::Extrusion::D Color(0.0f, 0.0f, 0.0f, 1.0f) // erMixed }; +const std::string GCodeAnalyzer::PreviewData::Extrusion::Default_Extrusion_Role_Names[Num_Extrusion_Roles] +{ + "None", + "Perimeter", + "External perimeter", + "Overhang perimeter", + "Internal infill", + "Solid infill", + "Top solid infill", + "Bridge infill", + "Gap fill", + "Skirt", + "Support material", + "Support material interface", + "Mixed" +}; + const GCodeAnalyzer::PreviewData::Extrusion::EViewType GCodeAnalyzer::PreviewData::Extrusion::Default_View_Type = GCodeAnalyzer::PreviewData::Extrusion::FeatureType; void GCodeAnalyzer::PreviewData::Extrusion::set_default() @@ -534,6 +567,11 @@ void GCodeAnalyzer::PreviewData::Extrusion::set_default() ::memcpy((void*)ranges.width.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color)); ::memcpy((void*)ranges.feedrate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color)); + for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i) + { + role_names[i] = Default_Extrusion_Role_Names[i]; + } + role_flags = 0; for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i) { @@ -628,6 +666,74 @@ const GCodeAnalyzer::PreviewData::Color& GCodeAnalyzer::PreviewData::get_extrusi return extrusion.ranges.feedrate.get_color_at(feedrate); } +std::string GCodeAnalyzer::PreviewData::get_legend_title() const +{ + switch (extrusion.view_type) + { + case Extrusion::FeatureType: + return "Feature type"; + case Extrusion::Height: + return "Height (mm)"; + case Extrusion::Width: + return "Width (mm)"; + case Extrusion::Feedrate: + return "Speed (mm/min)"; + } + + return ""; +} + +GCodeAnalyzer::PreviewData::LegendItemsList GCodeAnalyzer::PreviewData::get_legend_items() const +{ + struct Helper + { + static void FillListFromRange(LegendItemsList& list, const Range& range, unsigned int decimals, float scale_factor) + { + list.reserve(Range::Colors_Count); + float step = range.step_size(); + for (unsigned int i = 0; i < Range::Colors_Count; ++i) + { + char buf[32]; + sprintf(buf, "%.*f/%.*f", decimals, scale_factor * (range.min + (float)i * step), decimals, scale_factor * (range.min + (float)(i + 1) * step)); + list.emplace_back(buf, range.colors[i]); + } + } + }; + + LegendItemsList items; + + switch (extrusion.view_type) + { + case Extrusion::FeatureType: + { + items.reserve(erMixed - erPerimeter + 1); + for (unsigned int i = (unsigned int)erPerimeter; i < (unsigned int)erMixed; ++i) + { + items.emplace_back(extrusion.role_names[i], extrusion.role_colors[i]); + } + + break; + } + case Extrusion::Height: + { + Helper::FillListFromRange(items, extrusion.ranges.height, 3, 1.0f); + break; + } + case Extrusion::Width: + { + Helper::FillListFromRange(items, extrusion.ranges.width, 3, 1.0f); + break; + } + case Extrusion::Feedrate: + { + Helper::FillListFromRange(items, extrusion.ranges.feedrate, 0, 60.0f); + break; + } + } + + return items; +} + GCodeAnalyzer::GCodeAnalyzer() { reset(); diff --git a/xs/src/libslic3r/GCode/Analyzer.hpp b/xs/src/libslic3r/GCode/Analyzer.hpp index 2f5dafb3c..26c525b4c 100644 --- a/xs/src/libslic3r/GCode/Analyzer.hpp +++ b/xs/src/libslic3r/GCode/Analyzer.hpp @@ -206,9 +206,9 @@ public: ExtrusionRole extrusion_role; unsigned int extruder_id; double mm3_per_mm; - float width; - float height; - float feedrate; + float width; // mm + float height; // mm + float feedrate; // mm/s Metadata(); Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate); @@ -264,6 +264,8 @@ public: Color(); Color(float r, float g, float b, float a); + std::vector as_bytes() const; + static const Color Dummy; }; @@ -282,14 +284,22 @@ public: bool empty() const; void update_from(float value); void set_from(const Range& other); + float step_size() const; const Color& get_color_at(float value) const; const Color& get_color_at_max() const; - - private: - float _step() const; }; + struct LegendItem + { + std::string text; + Color color; + + LegendItem(const std::string& text, const Color& color); + }; + + typedef std::vector LegendItemsList; + struct Extrusion { enum EViewType : unsigned char @@ -303,7 +313,8 @@ public: static const unsigned int Num_Extrusion_Roles = (unsigned int)erMixed + 1; static const Color Default_Extrusion_Role_Colors[Num_Extrusion_Roles]; - static const EViewType Default_View_Type; + static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles]; + static const EViewType Default_View_Type; struct Ranges { @@ -324,6 +335,7 @@ public: EViewType view_type; Color role_colors[Num_Extrusion_Roles]; + std::string role_names[Num_Extrusion_Roles]; Ranges ranges; LayersList layers; unsigned int role_flags; @@ -411,6 +423,9 @@ public: const Color& get_extrusion_height_color(float height) const; const Color& get_extrusion_width_color(float width) const; const Color& get_extrusion_feedrate_color(float feedrate) const; + + std::string get_legend_title() const; + LegendItemsList get_legend_items() const; }; private: diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 60e3ac722..676d75c2f 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -8,9 +8,11 @@ #include "../../libslic3r/Geometry.hpp" #include "../../libslic3r/Print.hpp" #include "../../libslic3r/Slicing.hpp" +//############################################################################################################ #if ENRICO_GCODE_PREVIEW #include "GCode/Analyzer.hpp" #endif // ENRICO_GCODE_PREVIEW +//############################################################################################################ #include #include @@ -23,6 +25,15 @@ #include #include +//############################################################################################################ +#if ENRICO_GCODE_PREVIEW +#include +#include +#include +#include +#endif // ENRICO_GCODE_PREVIEW +//############################################################################################################ + namespace Slic3r { void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh) @@ -1098,6 +1109,197 @@ void _3DScene::GCodePreviewData::reset() } _3DScene::GCodePreviewData _3DScene::s_gcode_preview_data; +_3DScene::LegendTexture _3DScene::s_legend_texture; + +const unsigned char _3DScene::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 }; +const unsigned char _3DScene::LegendTexture::Background_Color[3] = { 9, 91, 134 }; +const unsigned char _3DScene::LegendTexture::Opacity = 255; + +_3DScene::LegendTexture::LegendTexture() + : m_tex_id(0) + , m_tex_width(0) + , m_tex_height(0) +{ +} + +_3DScene::LegendTexture::~LegendTexture() +{ + _destroy_texture(); +} + +bool _3DScene::LegendTexture::generate_texture(const Print& print) +{ + _destroy_texture(); + + // collects items to render + const std::string& title = print.gcode_preview.get_legend_title(); + const GCodeAnalyzer::PreviewData::LegendItemsList& items = print.gcode_preview.get_legend_items(); + + unsigned int items_count = (unsigned int)items.size(); + if (items_count == 0) + // nothing to render, return + return false; + + wxMemoryDC memDC; + // select default font + memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + + // calculates texture size + wxCoord w, h; + memDC.GetTextExtent(title, &w, &h); + unsigned int title_width = (unsigned int)w; + unsigned int title_height = (unsigned int)h; + + unsigned int max_text_width = 0; + unsigned int max_text_height = 0; + for (const GCodeAnalyzer::PreviewData::LegendItem& item : items) + { + memDC.GetTextExtent(item.text, &w, &h); + max_text_width = std::max(max_text_width, (unsigned int)w); + max_text_height = std::max(max_text_height, (unsigned int)h); + } + + m_tex_width = std::max(2 * Px_Border + title_width, 2 * (Px_Border + Px_Square_Contour) + Px_Square + Px_Text_Offset + max_text_width); + m_tex_height = 2 * (Px_Border + Px_Square_Contour) + title_height + Px_Title_Offset + items_count * Px_Square; + if (items_count > 1) + m_tex_height += (items_count - 1) * Px_Square_Contour; + + // generates bitmap + wxBitmap bitmap(m_tex_width, m_tex_height); + +#if defined(__APPLE__) || defined(_MSC_VER) + bitmap.UseAlpha(); +#endif + + memDC.SelectObject(bitmap); + memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2]))); + memDC.Clear(); + + memDC.SetTextForeground(*wxWHITE); + + // draw title + unsigned int title_x = Px_Border; + unsigned int title_y = Px_Border; + memDC.DrawText(title, title_x, title_y); + + // draw icons contours as background + unsigned int squares_contour_x = Px_Border; + unsigned int squares_contour_y = Px_Border + title_height + Px_Title_Offset; + unsigned int squares_contour_width = Px_Square + 2 * Px_Square_Contour; + unsigned int squares_contour_height = items_count * Px_Square + 2 * Px_Square_Contour; + if (items_count > 1) + squares_contour_height += (items_count - 1) * Px_Square_Contour; + + wxColour color(Squares_Border_Color[0], Squares_Border_Color[1], Squares_Border_Color[2]); + wxPen pen(color); + wxBrush brush(color); + memDC.SetPen(pen); + memDC.SetBrush(brush); + memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height)); + + // draw items (colored icon + text) + unsigned int icon_x = squares_contour_x + Px_Square_Contour; + unsigned int icon_x_inner = icon_x + 1; + unsigned int icon_y = squares_contour_y + Px_Square_Contour; + unsigned int icon_y_step = Px_Square + Px_Square_Contour; + + unsigned int text_x = icon_x + Px_Square + Px_Text_Offset; + unsigned int text_y_offset = (Px_Square - max_text_height) / 2; + + unsigned int px_inner_square = Px_Square - 2; + + for (const GCodeAnalyzer::PreviewData::LegendItem& item : items) + { + // draw darker icon perimeter + const std::vector& item_color_bytes = item.color.as_bytes(); + wxImage::HSVValue dark_hsv = wxImage::RGBtoHSV(wxImage::RGBValue(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2])); + dark_hsv.value *= 0.75; + wxImage::RGBValue dark_rgb = wxImage::HSVtoRGB(dark_hsv); + color.Set(dark_rgb.red, dark_rgb.green, dark_rgb.blue, item_color_bytes[3]); + pen.SetColour(color); + brush.SetColour(color); + memDC.SetPen(pen); + memDC.SetBrush(brush); + memDC.DrawRectangle(wxRect(icon_x, icon_y, Px_Square, Px_Square)); + + // draw icon interior + color.Set(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2], item_color_bytes[3]); + pen.SetColour(color); + brush.SetColour(color); + memDC.SetPen(pen); + memDC.SetBrush(brush); + memDC.DrawRectangle(wxRect(icon_x_inner, icon_y + 1, px_inner_square, px_inner_square)); + + // draw text + memDC.DrawText(item.text, text_x, icon_y + text_y_offset); + + // update y + icon_y += icon_y_step; + } + + memDC.SelectObject(wxNullBitmap); + + return _create_texture(print, bitmap); +} + +unsigned int _3DScene::LegendTexture::get_texture_id() const +{ + return m_tex_id; +} + +unsigned int _3DScene::LegendTexture::get_texture_width() const +{ + return m_tex_width; +} + +unsigned int _3DScene::LegendTexture::get_texture_height() const +{ + return m_tex_height; +} + +bool _3DScene::LegendTexture::_create_texture(const Print& print, const wxBitmap& bitmap) +{ + if ((m_tex_width == 0) || (m_tex_height == 0)) + return false; + + wxImage image = bitmap.ConvertToImage(); + image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); + + // prepare buffer + std::vector buffer(4 * m_tex_width * m_tex_height, 0); + for (unsigned int h = 0; h < m_tex_height; ++h) + { + unsigned int hh = h * m_tex_width; + for (unsigned int w = 0; w < m_tex_width; ++w) + { + unsigned char* px_ptr = buffer.data() + 4 * (hh + w); + *px_ptr++ = image.GetRed(w, h); + *px_ptr++ = image.GetGreen(w, h); + *px_ptr++ = image.GetBlue(w, h); + *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; + } + } + + // sends buffer to gpu + ::glGenTextures(1, &m_tex_id); + ::glBindTexture(GL_TEXTURE_2D, m_tex_id); + ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_tex_width, (GLsizei)m_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)buffer.data()); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + ::glBindTexture(GL_TEXTURE_2D, 0); + + return true; +} + +void _3DScene::LegendTexture::_destroy_texture() +{ + if (m_tex_id > 0) + { + ::glDeleteTextures(1, &m_tex_id); + m_tex_id = 0; + } +} #endif // ENRICO_GCODE_PREVIEW //############################################################################################################ @@ -1145,10 +1347,27 @@ void _3DScene::load_gcode_preview(const Print* print, GLVolumeCollection* volume _load_gcode_travel_paths(*print, *volumes, use_VBOs); _load_gcode_retractions(*print, *volumes, use_VBOs); _load_gcode_unretractions(*print, *volumes, use_VBOs); + + _generate_legend_texture(*print); } _update_gcode_volumes_visibility(*print, *volumes); } + +unsigned int _3DScene::get_legend_texture_id() +{ + return s_legend_texture.get_texture_id(); +} + +unsigned int _3DScene::get_legend_texture_width() +{ + return s_legend_texture.get_texture_width(); +} + +unsigned int _3DScene::get_legend_texture_height() +{ + return s_legend_texture.get_texture_height(); +} #endif // ENRICO_GCODE_PREVIEW //############################################################################################################ @@ -1847,6 +2066,11 @@ void _3DScene::_update_gcode_volumes_visibility(const Print& print, GLVolumeColl } } } + +void _3DScene::_generate_legend_texture(const Print& print) +{ + s_legend_texture.generate_texture(print); +} #endif // ENRICO_GCODE_PREVIEW //############################################################################################################ diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 8e16136d5..f869304aa 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -7,6 +7,12 @@ #include "../../libslic3r/TriangleMesh.hpp" #include "../../libslic3r/Utils.hpp" +//############################################################################################################ +#if ENRICO_GCODE_PREVIEW +class wxBitmap; +#endif // ENRICO_GCODE_PREVIEW +//############################################################################################################ + namespace Slic3r { class Print; @@ -389,6 +395,38 @@ class _3DScene }; static GCodePreviewData s_gcode_preview_data; + + class LegendTexture + { + static const unsigned int Px_Title_Offset = 5; + static const unsigned int Px_Text_Offset = 5; + static const unsigned int Px_Square = 20; + static const unsigned int Px_Square_Contour = 1; + static const unsigned int Px_Border = Px_Square / 2; + static const unsigned char Squares_Border_Color[3]; + static const unsigned char Background_Color[3]; + static const unsigned char Opacity; + + unsigned int m_tex_id; + unsigned int m_tex_width; + unsigned int m_tex_height; + + public: + LegendTexture(); + ~LegendTexture(); + + bool generate_texture(const Print& print); + + unsigned int get_texture_id() const; + unsigned int get_texture_width() const; + unsigned int get_texture_height() const; + + private: + bool _create_texture(const Print& print, const wxBitmap& bitmap); + void _destroy_texture(); + }; + + static LegendTexture s_legend_texture; #endif // ENRICO_GCODE_PREVIEW //############################################################################################################ public: @@ -397,6 +435,9 @@ public: //############################################################################################################ #if ENRICO_GCODE_PREVIEW static void load_gcode_preview(const Print* print, GLVolumeCollection* volumes, bool use_VBOs); + static unsigned int get_legend_texture_id(); + static unsigned int get_legend_texture_width(); + static unsigned int get_legend_texture_height(); #endif // ENRICO_GCODE_PREVIEW //############################################################################################################ @@ -432,6 +473,8 @@ private: static void _load_gcode_unretractions(const Print& print, GLVolumeCollection& volumes, bool use_VBOs); // sets gcode geometry visibility according to user selection static void _update_gcode_volumes_visibility(const Print& print, GLVolumeCollection& volumes); + // generates the legend texture in dependence of the current shown view type + static void _generate_legend_texture(const Print& print); #endif // ENRICO_GCODE_PREVIEW //############################################################################################################ }; diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 186511cc4..f6d729f98 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -141,6 +141,27 @@ _glew_init() CODE: _3DScene::_glew_init(); +unsigned int +get_legend_texture_id() + CODE: + RETVAL = _3DScene::get_legend_texture_id(); + OUTPUT: + RETVAL + +unsigned int +get_legend_texture_width() + CODE: + RETVAL = _3DScene::get_legend_texture_width(); + OUTPUT: + RETVAL + +unsigned int +get_legend_texture_height() + CODE: + RETVAL = _3DScene::get_legend_texture_height(); + OUTPUT: + RETVAL + void _load_print_toolpaths(print, volumes, tool_colors, use_VBOs) Print *print;