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.
|
# _dirty: boolean flag indicating, that the screen has to be redrawn on EVT_IDLE.
|
||||||
# volumes: reference to vector of Slic3r::GUI::3DScene::Volume.
|
# volumes: reference to vector of Slic3r::GUI::3DScene::Volume.
|
||||||
# _camera_type: 'perspective' or 'ortho'
|
# _camera_type: 'perspective' or 'ortho'
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
__PACKAGE__->mk_accessors( qw(_quat _dirty init
|
__PACKAGE__->mk_accessors( qw(_quat _dirty init
|
||||||
enable_picking
|
enable_picking
|
||||||
enable_moving
|
enable_moving
|
||||||
@ -66,8 +67,51 @@ __PACKAGE__->mk_accessors( qw(_quat _dirty init
|
|||||||
_camera_target
|
_camera_target
|
||||||
_camera_distance
|
_camera_distance
|
||||||
_zoom
|
_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 TRACKBALLSIZE => 0.8;
|
||||||
use constant TURNTABLE_MODE => 1;
|
use constant TURNTABLE_MODE => 1;
|
||||||
use constant GROUND_Z => -0.02;
|
use constant GROUND_Z => -0.02;
|
||||||
@ -137,6 +181,9 @@ sub new {
|
|||||||
$self->_stheta(45);
|
$self->_stheta(45);
|
||||||
$self->_sphi(45);
|
$self->_sphi(45);
|
||||||
$self->_zoom(1);
|
$self->_zoom(1);
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
|
$self->_legend_enabled(0);
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
$self->use_plain_shader(0);
|
$self->use_plain_shader(0);
|
||||||
|
|
||||||
# Collection of GLVolume objects
|
# Collection of GLVolume objects
|
||||||
@ -209,6 +256,13 @@ sub new {
|
|||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
|
sub set_legend_enabled {
|
||||||
|
my ($self, $value) = @_;
|
||||||
|
$self->_legend_enabled($value);
|
||||||
|
}
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
|
|
||||||
sub Destroy {
|
sub Destroy {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
$self->{layer_height_edit_timer}->Stop;
|
$self->{layer_height_edit_timer}->Stop;
|
||||||
@ -1316,6 +1370,11 @@ sub Render {
|
|||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
|
# draw gcode preview legend
|
||||||
|
$self->draw_legend;
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
|
|
||||||
$self->draw_active_object_annotations;
|
$self->draw_active_object_annotations;
|
||||||
|
|
||||||
$self->SwapBuffers();
|
$self->SwapBuffers();
|
||||||
@ -1449,12 +1508,38 @@ sub _variable_layer_thickness_load_reset_image {
|
|||||||
# Paint the tooltip.
|
# Paint the tooltip.
|
||||||
sub _render_image {
|
sub _render_image {
|
||||||
my ($self, $image, $l, $r, $b, $t) = @_;
|
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.);
|
glColor4f(1.,1.,1.,1.);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, $image->{texture_id});
|
glBindTexture(GL_TEXTURE_2D, $tex_id);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2d(0.,1.); glVertex3f($l, $b, 0);
|
glTexCoord2d(0.,1.); glVertex3f($l, $b, 0);
|
||||||
glTexCoord2d(1.,1.); glVertex3f($r, $b, 0);
|
glTexCoord2d(1.,1.); glVertex3f($r, $b, 0);
|
||||||
@ -1466,6 +1551,7 @@ sub _render_image {
|
|||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
# ===================== ENRICO_GCODE_PREVIEW ==================================================
|
||||||
|
|
||||||
sub draw_active_object_annotations {
|
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.
|
# $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);
|
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
|
sub opengl_info
|
||||||
{
|
{
|
||||||
my ($self, %params) = @_;
|
my ($self, %params) = @_;
|
||||||
|
@ -153,7 +153,16 @@ sub new {
|
|||||||
|
|
||||||
EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{preview_notebook}, sub {
|
EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{preview_notebook}, sub {
|
||||||
my $preview = $self->{preview_notebook}->GetCurrentPage;
|
my $preview = $self->{preview_notebook}->GetCurrentPage;
|
||||||
$self->{preview3D}->load_print(1) if ($preview == $self->{preview3D});
|
# ===================== 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');
|
$preview->OnActivate if $preview->can('OnActivate');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -436,6 +436,16 @@ GCodeAnalyzer::PreviewData::Color::Color(float r, float g, float b, float a)
|
|||||||
rgba[3] = 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)
|
GCodeAnalyzer::PreviewData::Extrusion::Layer::Layer(float z, const ExtrusionPaths& paths)
|
||||||
: z(z)
|
: z(z)
|
||||||
, paths(paths)
|
, paths(paths)
|
||||||
@ -491,6 +501,11 @@ void GCodeAnalyzer::PreviewData::Range::set_from(const Range& other)
|
|||||||
max = other.max;
|
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
|
const GCodeAnalyzer::PreviewData::Color& GCodeAnalyzer::PreviewData::Range::get_color_at_max() const
|
||||||
{
|
{
|
||||||
return colors[Colors_Count - 1];
|
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
|
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] =
|
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
|
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;
|
const GCodeAnalyzer::PreviewData::Extrusion::EViewType GCodeAnalyzer::PreviewData::Extrusion::Default_View_Type = GCodeAnalyzer::PreviewData::Extrusion::FeatureType;
|
||||||
|
|
||||||
void GCodeAnalyzer::PreviewData::Extrusion::set_default()
|
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.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));
|
::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;
|
role_flags = 0;
|
||||||
for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
|
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);
|
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()
|
GCodeAnalyzer::GCodeAnalyzer()
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
@ -206,9 +206,9 @@ public:
|
|||||||
ExtrusionRole extrusion_role;
|
ExtrusionRole extrusion_role;
|
||||||
unsigned int extruder_id;
|
unsigned int extruder_id;
|
||||||
double mm3_per_mm;
|
double mm3_per_mm;
|
||||||
float width;
|
float width; // mm
|
||||||
float height;
|
float height; // mm
|
||||||
float feedrate;
|
float feedrate; // mm/s
|
||||||
|
|
||||||
Metadata();
|
Metadata();
|
||||||
Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate);
|
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();
|
||||||
Color(float r, float g, float b, float a);
|
Color(float r, float g, float b, float a);
|
||||||
|
|
||||||
|
std::vector<unsigned char> as_bytes() const;
|
||||||
|
|
||||||
static const Color Dummy;
|
static const Color Dummy;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -282,14 +284,22 @@ public:
|
|||||||
bool empty() const;
|
bool empty() const;
|
||||||
void update_from(float value);
|
void update_from(float value);
|
||||||
void set_from(const Range& other);
|
void set_from(const Range& other);
|
||||||
|
float step_size() const;
|
||||||
|
|
||||||
const Color& get_color_at(float value) const;
|
const Color& get_color_at(float value) const;
|
||||||
const Color& get_color_at_max() 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
|
struct Extrusion
|
||||||
{
|
{
|
||||||
enum EViewType : unsigned char
|
enum EViewType : unsigned char
|
||||||
@ -303,6 +313,7 @@ public:
|
|||||||
|
|
||||||
static const unsigned int Num_Extrusion_Roles = (unsigned int)erMixed + 1;
|
static const unsigned int Num_Extrusion_Roles = (unsigned int)erMixed + 1;
|
||||||
static const Color Default_Extrusion_Role_Colors[Num_Extrusion_Roles];
|
static const Color Default_Extrusion_Role_Colors[Num_Extrusion_Roles];
|
||||||
|
static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles];
|
||||||
static const EViewType Default_View_Type;
|
static const EViewType Default_View_Type;
|
||||||
|
|
||||||
struct Ranges
|
struct Ranges
|
||||||
@ -324,6 +335,7 @@ public:
|
|||||||
|
|
||||||
EViewType view_type;
|
EViewType view_type;
|
||||||
Color role_colors[Num_Extrusion_Roles];
|
Color role_colors[Num_Extrusion_Roles];
|
||||||
|
std::string role_names[Num_Extrusion_Roles];
|
||||||
Ranges ranges;
|
Ranges ranges;
|
||||||
LayersList layers;
|
LayersList layers;
|
||||||
unsigned int role_flags;
|
unsigned int role_flags;
|
||||||
@ -411,6 +423,9 @@ public:
|
|||||||
const Color& get_extrusion_height_color(float height) const;
|
const Color& get_extrusion_height_color(float height) const;
|
||||||
const Color& get_extrusion_width_color(float width) const;
|
const Color& get_extrusion_width_color(float width) const;
|
||||||
const Color& get_extrusion_feedrate_color(float feedrate) const;
|
const Color& get_extrusion_feedrate_color(float feedrate) const;
|
||||||
|
|
||||||
|
std::string get_legend_title() const;
|
||||||
|
LegendItemsList get_legend_items() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
#include "../../libslic3r/Geometry.hpp"
|
#include "../../libslic3r/Geometry.hpp"
|
||||||
#include "../../libslic3r/Print.hpp"
|
#include "../../libslic3r/Print.hpp"
|
||||||
#include "../../libslic3r/Slicing.hpp"
|
#include "../../libslic3r/Slicing.hpp"
|
||||||
|
//############################################################################################################
|
||||||
#if ENRICO_GCODE_PREVIEW
|
#if ENRICO_GCODE_PREVIEW
|
||||||
#include "GCode/Analyzer.hpp"
|
#include "GCode/Analyzer.hpp"
|
||||||
#endif // ENRICO_GCODE_PREVIEW
|
#endif // ENRICO_GCODE_PREVIEW
|
||||||
|
//############################################################################################################
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -23,6 +25,15 @@
|
|||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/spin_mutex.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 {
|
namespace Slic3r {
|
||||||
|
|
||||||
void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh)
|
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::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
|
#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_travel_paths(*print, *volumes, use_VBOs);
|
||||||
_load_gcode_retractions(*print, *volumes, use_VBOs);
|
_load_gcode_retractions(*print, *volumes, use_VBOs);
|
||||||
_load_gcode_unretractions(*print, *volumes, use_VBOs);
|
_load_gcode_unretractions(*print, *volumes, use_VBOs);
|
||||||
|
|
||||||
|
_generate_legend_texture(*print);
|
||||||
}
|
}
|
||||||
|
|
||||||
_update_gcode_volumes_visibility(*print, *volumes);
|
_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
|
#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
|
#endif // ENRICO_GCODE_PREVIEW
|
||||||
//############################################################################################################
|
//############################################################################################################
|
||||||
|
|
||||||
|
@ -7,6 +7,12 @@
|
|||||||
#include "../../libslic3r/TriangleMesh.hpp"
|
#include "../../libslic3r/TriangleMesh.hpp"
|
||||||
#include "../../libslic3r/Utils.hpp"
|
#include "../../libslic3r/Utils.hpp"
|
||||||
|
|
||||||
|
//############################################################################################################
|
||||||
|
#if ENRICO_GCODE_PREVIEW
|
||||||
|
class wxBitmap;
|
||||||
|
#endif // ENRICO_GCODE_PREVIEW
|
||||||
|
//############################################################################################################
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class Print;
|
class Print;
|
||||||
@ -389,6 +395,38 @@ class _3DScene
|
|||||||
};
|
};
|
||||||
|
|
||||||
static GCodePreviewData s_gcode_preview_data;
|
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
|
#endif // ENRICO_GCODE_PREVIEW
|
||||||
//############################################################################################################
|
//############################################################################################################
|
||||||
public:
|
public:
|
||||||
@ -397,6 +435,9 @@ public:
|
|||||||
//############################################################################################################
|
//############################################################################################################
|
||||||
#if ENRICO_GCODE_PREVIEW
|
#if ENRICO_GCODE_PREVIEW
|
||||||
static void load_gcode_preview(const Print* print, GLVolumeCollection* volumes, bool use_VBOs);
|
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
|
#endif // ENRICO_GCODE_PREVIEW
|
||||||
//############################################################################################################
|
//############################################################################################################
|
||||||
|
|
||||||
@ -432,6 +473,8 @@ private:
|
|||||||
static void _load_gcode_unretractions(const Print& print, GLVolumeCollection& volumes, bool use_VBOs);
|
static void _load_gcode_unretractions(const Print& print, GLVolumeCollection& volumes, bool use_VBOs);
|
||||||
// sets gcode geometry visibility according to user selection
|
// sets gcode geometry visibility according to user selection
|
||||||
static void _update_gcode_volumes_visibility(const Print& print, GLVolumeCollection& volumes);
|
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
|
#endif // ENRICO_GCODE_PREVIEW
|
||||||
//############################################################################################################
|
//############################################################################################################
|
||||||
};
|
};
|
||||||
|
@ -141,6 +141,27 @@ _glew_init()
|
|||||||
CODE:
|
CODE:
|
||||||
_3DScene::_glew_init();
|
_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
|
void
|
||||||
_load_print_toolpaths(print, volumes, tool_colors, use_VBOs)
|
_load_print_toolpaths(print, volumes, tool_colors, use_VBOs)
|
||||||
Print *print;
|
Print *print;
|
||||||
|
Loading…
Reference in New Issue
Block a user