GCode Preview - Added legend texture
This commit is contained in:
parent
9e0dd2a96a
commit
c63e6b74fa
@ -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) = @_;
|
||||
|
@ -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
|
||||
|
@ -436,6 +436,16 @@ GCodeAnalyzer::PreviewData::Color::Color(float r, float g, float b, float a)
|
||||
rgba[3] = a;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> GCodeAnalyzer::PreviewData::Color::as_bytes() const
|
||||
{
|
||||
std::vector<unsigned char> 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();
|
||||
|
@ -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<unsigned char> 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<LegendItem> 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:
|
||||
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -23,6 +25,15 @@
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/spin_mutex.h>
|
||||
|
||||
//############################################################################################################
|
||||
#if ENRICO_GCODE_PREVIEW
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/settings.h>
|
||||
#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<unsigned char>& 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<unsigned char> 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
|
||||
//############################################################################################################
|
||||
|
||||
|
@ -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
|
||||
//############################################################################################################
|
||||
};
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user