3DScene layer editing overlay completely moved to c++

This commit is contained in:
Enrico Turri 2018-05-25 15:56:14 +02:00
parent 455076231b
commit c51ce63b9b
10 changed files with 331 additions and 146 deletions

View file

@ -200,8 +200,8 @@ sub new {
# $self->_camera_target(Slic3r::Pointf3->new(0,0,0)); # $self->_camera_target(Slic3r::Pointf3->new(0,0,0));
# $self->_camera_distance(0.); # $self->_camera_distance(0.);
# $self->layer_editing_enabled(0); # $self->layer_editing_enabled(0);
# $self->{layer_height_edit_band_width} = 2.;
#============================================================================================================================== #==============================================================================================================================
$self->{layer_height_edit_band_width} = 2.;
$self->{layer_height_edit_strength} = 0.005; $self->{layer_height_edit_strength} = 0.005;
$self->{layer_height_edit_last_object_id} = -1; $self->{layer_height_edit_last_object_id} = -1;
$self->{layer_height_edit_last_z} = 0.; $self->{layer_height_edit_last_z} = 0.;
@ -446,7 +446,10 @@ sub _variable_layer_thickness_action {
$self->{print}->get_object($self->{layer_height_edit_last_object_id})->adjust_layer_height_profile( $self->{print}->get_object($self->{layer_height_edit_last_object_id})->adjust_layer_height_profile(
$self->{layer_height_edit_last_z}, $self->{layer_height_edit_last_z},
$self->{layer_height_edit_strength}, $self->{layer_height_edit_strength},
$self->{layer_height_edit_band_width}, #==============================================================================================================================
Slic3r::GUI::_3DScene::get_layers_editing_band_width($self),
# $self->{layer_height_edit_band_width},
#==============================================================================================================================
$self->{layer_height_edit_last_action}); $self->{layer_height_edit_last_action});
$self->volumes->[$self->{layer_height_edit_last_object_id}]->generate_layer_height_texture( $self->volumes->[$self->{layer_height_edit_last_object_id}]->generate_layer_height_texture(
$self->{print}->get_object($self->{layer_height_edit_last_object_id}), 1); $self->{print}->get_object($self->{layer_height_edit_last_object_id}), 1);
@ -700,7 +703,10 @@ sub mouse_wheel_event {
# A volume is selected. Test, whether hovering over a layer thickness bar. # A volume is selected. Test, whether hovering over a layer thickness bar.
if ($self->_variable_layer_thickness_bar_rect_mouse_inside($e)) { if ($self->_variable_layer_thickness_bar_rect_mouse_inside($e)) {
# Adjust the width of the selection. # Adjust the width of the selection.
$self->{layer_height_edit_band_width} = max(min($self->{layer_height_edit_band_width} * (1 + 0.1 * $e->GetWheelRotation() / $e->GetWheelDelta()), 10.), 1.5); #==============================================================================================================================
Slic3r::GUI::_3DScene::set_layers_editing_band_width($self, max(min(Slic3r::GUI::_3DScene::get_layers_editing_band_width($self) * (1 + 0.1 * $e->GetWheelRotation() / $e->GetWheelDelta()), 10.), 1.5));
# $self->{layer_height_edit_band_width} = max(min($self->{layer_height_edit_band_width} * (1 + 0.1 * $e->GetWheelRotation() / $e->GetWheelDelta()), 10.), 1.5);
#==============================================================================================================================
$self->Refresh; $self->Refresh;
return; return;
} }
@ -1471,6 +1477,7 @@ sub Render {
Slic3r::GUI::_3DScene::render_cutting_plane($self); Slic3r::GUI::_3DScene::render_cutting_plane($self);
Slic3r::GUI::_3DScene::render_warning_texture($self); Slic3r::GUI::_3DScene::render_warning_texture($self);
Slic3r::GUI::_3DScene::render_legend_texture($self); Slic3r::GUI::_3DScene::render_legend_texture($self);
Slic3r::GUI::_3DScene::render_layer_editing_overlay($self, $self->{print});
# if ($self->enable_picking && !$self->_mouse_dragging) { # if ($self->enable_picking && !$self->_mouse_dragging) {
# if (my $pos = $self->_mouse_pos) { # if (my $pos = $self->_mouse_pos) {
@ -1651,10 +1658,10 @@ sub Render {
# #
# # draw gcode preview legend # # draw gcode preview legend
# $self->draw_legend; # $self->draw_legend;
#
# $self->draw_active_object_annotations;
#============================================================================================================================== #==============================================================================================================================
$self->draw_active_object_annotations;
$self->SwapBuffers(); $self->SwapBuffers();
} }
@ -1711,7 +1718,7 @@ sub mark_volumes_for_layer_height {
if (Slic3r::GUI::_3DScene::is_layers_editing_enabled($self) && $shader && $volume->selected && if (Slic3r::GUI::_3DScene::is_layers_editing_enabled($self) && $shader && $volume->selected &&
$volume->has_layer_height_texture && $object_id < $self->{print}->object_count) { $volume->has_layer_height_texture && $object_id < $self->{print}->object_count) {
$volume->set_layer_height_texture_data(Slic3r::GUI::_3DScene::get_layers_editing_z_texture_id($self), $shader->shader_program_id, $volume->set_layer_height_texture_data(Slic3r::GUI::_3DScene::get_layers_editing_z_texture_id($self), $shader->shader_program_id,
$self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, $self->{layer_height_edit_band_width}); $self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, Slic3r::GUI::_3DScene::get_layers_editing_band_width($self));
# if ($self->layer_editing_enabled && $volume->selected && $self->{layer_height_edit_shader} && # if ($self->layer_editing_enabled && $volume->selected && $self->{layer_height_edit_shader} &&
# $volume->has_layer_height_texture && $object_id < $self->{print}->object_count) { # $volume->has_layer_height_texture && $object_id < $self->{print}->object_count) {
@ -1724,42 +1731,42 @@ sub mark_volumes_for_layer_height {
} }
} }
sub _load_image_set_texture {
my ($self, $file_name) = @_;
# Load a PNG with an alpha channel.
my $img = Wx::Image->new;
$img->LoadFile(Slic3r::var($file_name), wxBITMAP_TYPE_PNG);
# Get RGB & alpha raw data from wxImage, interleave them into a Perl array.
my @rgb = unpack 'C*', $img->GetData();
my @alpha = $img->HasAlpha ? unpack 'C*', $img->GetAlpha() : (255) x (int(@rgb) / 3);
my $n_pixels = int(@alpha);
my @data = (0)x($n_pixels * 4);
for (my $i = 0; $i < $n_pixels; $i += 1) {
$data[$i*4 ] = $rgb[$i*3];
$data[$i*4+1] = $rgb[$i*3+1];
$data[$i*4+2] = $rgb[$i*3+2];
$data[$i*4+3] = $alpha[$i];
}
# Initialize a raw bitmap data.
my $params = {
loaded => 1,
valid => $n_pixels > 0,
width => $img->GetWidth,
height => $img->GetHeight,
data => OpenGL::Array->new_list(GL_UNSIGNED_BYTE, @data),
texture_id => glGenTextures_p(1)
};
# Create and initialize a texture with the raw data.
glBindTexture(GL_TEXTURE_2D, $params->{texture_id});
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);
glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $params->{width}, $params->{height}, 0, GL_RGBA, GL_UNSIGNED_BYTE, $params->{data}->ptr);
glBindTexture(GL_TEXTURE_2D, 0);
return $params;
}
#============================================================================================================================== #==============================================================================================================================
#sub _load_image_set_texture {
# my ($self, $file_name) = @_;
# # Load a PNG with an alpha channel.
# my $img = Wx::Image->new;
# $img->LoadFile(Slic3r::var($file_name), wxBITMAP_TYPE_PNG);
# # Get RGB & alpha raw data from wxImage, interleave them into a Perl array.
# my @rgb = unpack 'C*', $img->GetData();
# my @alpha = $img->HasAlpha ? unpack 'C*', $img->GetAlpha() : (255) x (int(@rgb) / 3);
# my $n_pixels = int(@alpha);
# my @data = (0)x($n_pixels * 4);
# for (my $i = 0; $i < $n_pixels; $i += 1) {
# $data[$i*4 ] = $rgb[$i*3];
# $data[$i*4+1] = $rgb[$i*3+1];
# $data[$i*4+2] = $rgb[$i*3+2];
# $data[$i*4+3] = $alpha[$i];
# }
# # Initialize a raw bitmap data.
# my $params = {
# loaded => 1,
# valid => $n_pixels > 0,
# width => $img->GetWidth,
# height => $img->GetHeight,
# data => OpenGL::Array->new_list(GL_UNSIGNED_BYTE, @data),
# texture_id => glGenTextures_p(1)
# };
# # Create and initialize a texture with the raw data.
# glBindTexture(GL_TEXTURE_2D, $params->{texture_id});
# 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);
# glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $params->{width}, $params->{height}, 0, GL_RGBA, GL_UNSIGNED_BYTE, $params->{data}->ptr);
# glBindTexture(GL_TEXTURE_2D, 0);
# return $params;
#}
#
#sub _variable_layer_thickness_load_overlay_image { #sub _variable_layer_thickness_load_overlay_image {
# my ($self) = @_; # my ($self) = @_;
# $self->{layer_preview_annotation} = $self->_load_image_set_texture('variable_layer_height_tooltip.png') # $self->{layer_preview_annotation} = $self->_load_image_set_texture('variable_layer_height_tooltip.png')
@ -1800,92 +1807,69 @@ sub _load_image_set_texture {
# glDisable(GL_BLEND); # glDisable(GL_BLEND);
# glEnable(GL_LIGHTING); # glEnable(GL_LIGHTING);
#} #}
#============================================================================================================================== #
#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. # my ($self) = @_;
my ($self) = @_; #
#==============================================================================================================================
return if (!Slic3r::GUI::_3DScene::is_layers_editing_enabled($self));
# return if (! $self->{layer_height_edit_shader} || ! $self->layer_editing_enabled); # return if (! $self->{layer_height_edit_shader} || ! $self->layer_editing_enabled);
#============================================================================================================================== #
# # Find the selected volume, over which the layer editing is active.
# Find the selected volume, over which the layer editing is active. # my $volume;
my $volume; # foreach my $volume_idx (0..$#{$self->volumes}) {
foreach my $volume_idx (0..$#{$self->volumes}) { # my $v = $self->volumes->[$volume_idx];
my $v = $self->volumes->[$volume_idx]; # if ($v->selected && $v->has_layer_height_texture) {
if ($v->selected && $v->has_layer_height_texture) { # $volume = $v;
$volume = $v; # last;
last; # }
} # }
} # return if (! $volume);
return if (! $volume); #
# # If the active object was not allocated at the Print, go away. This should only be a momentary case between an object addition / deletion
# If the active object was not allocated at the Print, go away. This should only be a momentary case between an object addition / deletion # # and an update by Platter::async_apply_config.
# and an update by Platter::async_apply_config. # my $object_idx = int($volume->select_group_id / 1000000);
my $object_idx = int($volume->select_group_id / 1000000); # return if $object_idx >= $self->{print}->object_count;
return if $object_idx >= $self->{print}->object_count; #
# # The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth),
# The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth), # # where x, y is the window size divided by $self->_zoom.
# where x, y is the window size divided by $self->_zoom. # my ($bar_left, $bar_bottom, $bar_right, $bar_top) = $self->_variable_layer_thickness_bar_rect_viewport;
my ($bar_left, $bar_bottom, $bar_right, $bar_top) = $self->_variable_layer_thickness_bar_rect_viewport; # my ($reset_left, $reset_bottom, $reset_right, $reset_top) = $self->_variable_layer_thickness_reset_rect_viewport;
my ($reset_left, $reset_bottom, $reset_right, $reset_top) = $self->_variable_layer_thickness_reset_rect_viewport; # my $z_cursor_relative = $self->_variable_layer_thickness_bar_mouse_cursor_z_relative;
my $z_cursor_relative = $self->_variable_layer_thickness_bar_mouse_cursor_z_relative; #
# my $print_object = $self->{print}->get_object($object_idx);
my $print_object = $self->{print}->get_object($object_idx); # my $z_max = $print_object->model_object->bounding_box->z_max;
my $z_max = $print_object->model_object->bounding_box->z_max; #
#==============================================================================================================================
my $shader = Slic3r::GUI::_3DScene::get_layers_editing_shader($self);
$shader->enable;
$shader->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id);
$shader->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height);
$shader->set_uniform('z_cursor', $z_max * $z_cursor_relative);
$shader->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width});
# $self->{layer_height_edit_shader}->enable; # $self->{layer_height_edit_shader}->enable;
# $self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id); # $self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id);
# $self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height); # $self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height);
# $self->{layer_height_edit_shader}->set_uniform('z_cursor', $z_max * $z_cursor_relative); # $self->{layer_height_edit_shader}->set_uniform('z_cursor', $z_max * $z_cursor_relative);
# $self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width}); # $self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width});
#==============================================================================================================================
#==============================================================================================================================
glBindTexture(GL_TEXTURE_2D, Slic3r::GUI::_3DScene::get_layers_editing_z_texture_id($self));
# glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id}); # glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id});
#============================================================================================================================== # glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $volume->layer_height_texture_width, $volume->layer_height_texture_height, # 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
0, GL_RGBA, GL_UNSIGNED_BYTE, 0); # glTexImage2D_c(GL_TEXTURE_2D, 1, GL_RGBA8, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
glTexImage2D_c(GL_TEXTURE_2D, 1, GL_RGBA8, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2, # 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
0, GL_RGBA, GL_UNSIGNED_BYTE, 0); # glTexSubImage2D_c(GL_TEXTURE_2D, 0, 0, 0, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
glTexSubImage2D_c(GL_TEXTURE_2D, 0, 0, 0, $volume->layer_height_texture_width, $volume->layer_height_texture_height, # GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level0);
GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level0); # glTexSubImage2D_c(GL_TEXTURE_2D, 1, 0, 0, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
glTexSubImage2D_c(GL_TEXTURE_2D, 1, 0, 0, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2, # GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level1);
GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level1); #
# # Render the color bar.
# Render the color bar. # glDisable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST); # # The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth),
# The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth), # # where x, y is the window size divided by $self->_zoom.
# where x, y is the window size divided by $self->_zoom. # glPushMatrix();
glPushMatrix(); # glLoadIdentity();
glLoadIdentity(); # # Paint the overlay.
# Paint the overlay. # glBegin(GL_QUADS);
glBegin(GL_QUADS); # glVertex3f($bar_left, $bar_bottom, 0);
glVertex3f($bar_left, $bar_bottom, 0); # glVertex3f($bar_right, $bar_bottom, 0);
glVertex3f($bar_right, $bar_bottom, 0); # glVertex3f($bar_right, $bar_top, $z_max);
glVertex3f($bar_right, $bar_top, $z_max); # glVertex3f($bar_left, $bar_top, $z_max);
glVertex3f($bar_left, $bar_top, $z_max); # glEnd();
glEnd(); # glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_2D, 0);
#==============================================================================================================================
$shader->disable;
# $self->{layer_height_edit_shader}->disable; # $self->{layer_height_edit_shader}->disable;
#============================================================================================================================== #
#==============================================================================================================================
Slic3r::GUI::_3DScene::render_layer_editing_textures($self, $print_object);
# # Paint the tooltip. # # Paint the tooltip.
# if ($self->_variable_layer_thickness_load_overlay_image) # if ($self->_variable_layer_thickness_load_overlay_image)
# my $gap = 10/$self->_zoom; # my $gap = 10/$self->_zoom;
@ -1933,13 +1917,11 @@ sub draw_active_object_annotations {
# glVertex3f($bar_left + $h * ($bar_right - $bar_left) / $layer_height_max, $bar_bottom + $z * ($bar_top - $bar_bottom) / $max_z, $z); # glVertex3f($bar_left + $h * ($bar_right - $bar_left) / $layer_height_max, $bar_bottom + $z * ($bar_top - $bar_bottom) / $max_z, $z);
# } # }
# glEnd(); # glEnd();
#============================================================================================================================== # # Revert the matrices.
# Revert the matrices. # glPopMatrix();
glPopMatrix(); # glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_TEST); #}
} #
#==============================================================================================================================
#sub draw_legend { #sub draw_legend {
# my ($self) = @_; # my ($self) = @_;
# #

View file

@ -603,7 +603,10 @@ void ModelObject::clear_instances()
// Returns the bounding box of the transformed instances. // Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug. // This bounding box is approximate and not snug.
const BoundingBoxf3& ModelObject::bounding_box() //========================================================================================================
const BoundingBoxf3& ModelObject::bounding_box() const
//const BoundingBoxf3& ModelObject::bounding_box()
//========================================================================================================
{ {
if (! m_bounding_box_valid) { if (! m_bounding_box_valid) {
BoundingBoxf3 raw_bbox; BoundingBoxf3 raw_bbox;

View file

@ -103,7 +103,10 @@ public:
// Returns the bounding box of the transformed instances. // Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug. // This bounding box is approximate and not snug.
// This bounding box is being cached. // This bounding box is being cached.
const BoundingBoxf3& bounding_box(); //========================================================================================================
const BoundingBoxf3& bounding_box() const;
// const BoundingBoxf3& bounding_box();
//========================================================================================================
void invalidate_bounding_box() { m_bounding_box_valid = false; } void invalidate_bounding_box() { m_bounding_box_valid = false; }
// Returns a snug bounding box of the transformed instances. // Returns a snug bounding box of the transformed instances.
// This bounding box is not being cached. // This bounding box is not being cached.
@ -145,8 +148,10 @@ private:
// Parent object, owning this ModelObject. // Parent object, owning this ModelObject.
Model *m_model; Model *m_model;
// Bounding box, cached. // Bounding box, cached.
BoundingBoxf3 m_bounding_box; //========================================================================================================
bool m_bounding_box_valid; mutable BoundingBoxf3 m_bounding_box;
mutable bool m_bounding_box_valid;
//========================================================================================================
}; };
// An object STL, or a modifier volume, over which a different set of parameters shall be applied. // An object STL, or a modifier volume, over which a different set of parameters shall be applied.

View file

@ -2010,6 +2010,16 @@ unsigned int _3DScene::get_layers_editing_z_texture_id(wxGLCanvas* canvas)
return s_canvas_mgr.get_layers_editing_z_texture_id(canvas); return s_canvas_mgr.get_layers_editing_z_texture_id(canvas);
} }
float _3DScene::get_layers_editing_band_width(wxGLCanvas* canvas)
{
return s_canvas_mgr.get_layers_editing_band_width(canvas);
}
void _3DScene::set_layers_editing_band_width(wxGLCanvas* canvas, float band_width)
{
s_canvas_mgr.set_layers_editing_band_width(canvas, band_width);
}
GLShader* _3DScene::get_layers_editing_shader(wxGLCanvas* canvas) GLShader* _3DScene::get_layers_editing_shader(wxGLCanvas* canvas)
{ {
return s_canvas_mgr.get_layers_editing_shader(canvas); return s_canvas_mgr.get_layers_editing_shader(canvas);
@ -2085,10 +2095,10 @@ void _3DScene::render_legend_texture(wxGLCanvas* canvas)
s_canvas_mgr.render_legend_texture(canvas); s_canvas_mgr.render_legend_texture(canvas);
} }
void _3DScene::render_layer_editing_textures(wxGLCanvas* canvas, const PrintObject* print_object) void _3DScene::render_layer_editing_overlay(wxGLCanvas* canvas, const Print* print)
{ {
if (print_object != nullptr) if (print != nullptr)
s_canvas_mgr.render_layer_editing_textures(canvas, *print_object); s_canvas_mgr.render_layer_editing_overlay(canvas, *print);
} }
void _3DScene::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) void _3DScene::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top)

View file

@ -617,6 +617,10 @@ public:
static void set_hover_volume_id(wxGLCanvas* canvas, int id); static void set_hover_volume_id(wxGLCanvas* canvas, int id);
static unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas); static unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas);
static float get_layers_editing_band_width(wxGLCanvas* canvas);
static void set_layers_editing_band_width(wxGLCanvas* canvas, float band_width);
static GLShader* get_layers_editing_shader(wxGLCanvas* canvas); static GLShader* get_layers_editing_shader(wxGLCanvas* canvas);
static void zoom_to_bed(wxGLCanvas* canvas); static void zoom_to_bed(wxGLCanvas* canvas);
@ -636,7 +640,7 @@ public:
static void render_cutting_plane(wxGLCanvas* canvas); static void render_cutting_plane(wxGLCanvas* canvas);
static void render_warning_texture(wxGLCanvas* canvas); static void render_warning_texture(wxGLCanvas* canvas);
static void render_legend_texture(wxGLCanvas* canvas); static void render_legend_texture(wxGLCanvas* canvas);
static void render_layer_editing_textures(wxGLCanvas* canvas, const PrintObject* print_object); static void render_layer_editing_overlay(wxGLCanvas* canvas, const Print* print);
static void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top); static void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top);

View file

@ -553,6 +553,12 @@ void GLCanvas3D::Shader::stop_using() const
m_shader->disable(); m_shader->disable();
} }
void GLCanvas3D::Shader::set_uniform(const std::string& name, float value) const
{
if (m_shader != nullptr)
m_shader->set_uniform(name.c_str(), value);
}
GLShader* GLCanvas3D::Shader::get_shader() GLShader* GLCanvas3D::Shader::get_shader()
{ {
return m_shader; return m_shader;
@ -586,6 +592,7 @@ GLCanvas3D::LayersEditing::LayersEditing()
: m_allowed(false) : m_allowed(false)
, m_enabled(false) , m_enabled(false)
, m_z_texture_id(0) , m_z_texture_id(0)
, m_band_width(2.0f)
{ {
} }
@ -652,13 +659,40 @@ unsigned int GLCanvas3D::LayersEditing::get_z_texture_id() const
return m_z_texture_id; return m_z_texture_id;
} }
void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObject& print_object) const float GLCanvas3D::LayersEditing::get_band_width() const
{ {
return m_band_width;
}
void GLCanvas3D::LayersEditing::set_band_width(float band_width)
{
m_band_width = band_width;
}
void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObject& print_object, const GLVolume& volume) const
{
if (!m_enabled)
return;
const Rect& bar_rect = _get_bar_rect_viewport(canvas); const Rect& bar_rect = _get_bar_rect_viewport(canvas);
const Rect& reset_rect = _get_reset_rect_viewport(canvas); const Rect& reset_rect = _get_reset_rect_viewport(canvas);
::glDisable(GL_DEPTH_TEST);
// The viewport and camera are set to complete view and glOrtho(-$x / 2, $x / 2, -$y / 2, $y / 2, -$depth, $depth),
// where x, y is the window size divided by $self->_zoom.
::glPushMatrix();
::glLoadIdentity();
_render_tooltip_texture(canvas, bar_rect, reset_rect); _render_tooltip_texture(canvas, bar_rect, reset_rect);
_render_reset_texture(canvas, reset_rect); _render_reset_texture(canvas, reset_rect);
_render_active_object_annotations(canvas, volume, print_object, bar_rect);
_render_profile(print_object, bar_rect); _render_profile(print_object, bar_rect);
// Revert the matrices.
glPopMatrix();
glEnable(GL_DEPTH_TEST);
} }
GLShader* GLCanvas3D::LayersEditing::get_shader() GLShader* GLCanvas3D::LayersEditing::get_shader()
@ -754,6 +788,45 @@ void GLCanvas3D::LayersEditing::_render_reset_texture(const GLCanvas3D& canvas,
canvas.render_texture(m_reset_texture.id, reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top()); canvas.render_texture(m_reset_texture.id, reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top());
} }
void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const
{
float max_z = print_object.model_object()->bounding_box().max.z;
m_shader.start_using();
m_shader.set_uniform("z_to_texture_row", (float)volume.layer_height_texture_z_to_row_id());
m_shader.set_uniform("z_texture_row_to_normalized", 1.0f / (float)volume.layer_height_texture_height());
m_shader.set_uniform("z_cursor", max_z * _cursor_z_relative(canvas));
m_shader.set_uniform("z_cursor_band_width", get_band_width());
GLsizei w = (GLsizei)volume.layer_height_texture_width();
GLsizei h = (GLsizei)volume.layer_height_texture_height();
GLsizei half_w = w / 2;
GLsizei half_h = h / 2;
::glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, volume.layer_height_texture_data_ptr_level0());
::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, volume.layer_height_texture_data_ptr_level1());
// Render the color bar
float l = bar_rect.get_left();
float r = bar_rect.get_right();
float t = bar_rect.get_top();
float b = bar_rect.get_bottom();
::glBegin(GL_QUADS);
::glVertex3f(l, b, 0.0f);
::glVertex3f(r, b, 0.0f);
::glVertex3f(r, t, max_z);
::glVertex3f(l, t, max_z);
::glEnd();
::glBindTexture(GL_TEXTURE_2D, 0);
m_shader.stop_using();
}
void GLCanvas3D::LayersEditing::_render_profile(const PrintObject& print_object, const Rect& bar_rect) const void GLCanvas3D::LayersEditing::_render_profile(const PrintObject& print_object, const Rect& bar_rect) const
{ {
// FIXME show some kind of legend. // FIXME show some kind of legend.
@ -851,6 +924,21 @@ Rect GLCanvas3D::LayersEditing::_get_reset_rect_viewport(const GLCanvas3D& canva
return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
} }
float GLCanvas3D::LayersEditing::_cursor_z_relative(const GLCanvas3D& canvas) const
{
const Point& mouse_pos = canvas.get_local_mouse_position();
const Rect& bar_rect = _get_bar_rect_screen(canvas);
float x = (float)mouse_pos.x;
float y = (float)mouse_pos.y;
float t = bar_rect.get_top();
float b = bar_rect.get_bottom();
return ((bar_rect.get_left() <= x) && (x <= bar_rect.get_right()) && (t <= y) && (y <= b)) ?
// Inside the bar.
(b - y - 1.0f) / (b - t - 1.0f) :
// Outside the bar.
- 1000.0f;
}
GLCanvas3D::Mouse::Mouse() GLCanvas3D::Mouse::Mouse()
: m_dragging(false) : m_dragging(false)
{ {
@ -1456,6 +1544,16 @@ unsigned int GLCanvas3D::get_layers_editing_z_texture_id() const
return m_layers_editing.get_z_texture_id(); return m_layers_editing.get_z_texture_id();
} }
float GLCanvas3D::get_layers_editing_band_width() const
{
return m_layers_editing.get_band_width();
}
void GLCanvas3D::set_layers_editing_band_width(float band_width)
{
m_layers_editing.set_band_width(band_width);
}
GLShader* GLCanvas3D::get_layers_editing_shader() GLShader* GLCanvas3D::get_layers_editing_shader()
{ {
return m_layers_editing.get_shader(); return m_layers_editing.get_shader();
@ -1635,9 +1733,36 @@ void GLCanvas3D::render_legend_texture() const
} }
} }
void GLCanvas3D::render_layer_editing_textures(const PrintObject& print_object) const void GLCanvas3D::render_layer_editing_overlay(const Print& print) const
{ {
m_layers_editing.render(*this, print_object); if (m_volumes == nullptr)
return;
GLVolume* volume = nullptr;
for (GLVolume* vol : m_volumes->volumes)
{
if ((vol != nullptr) && vol->selected && vol->has_layer_height_texture())
{
volume = vol;
break;
}
}
if (volume == nullptr)
return;
// If the active object was not allocated at the Print, go away.This should only be a momentary case between an object addition / deletion
// and an update by Platter::async_apply_config.
int object_idx = int(volume->select_group_id / 1000000);
if ((int)print.objects.size() < object_idx)
return;
const PrintObject* print_object = print.get_object(object_idx);
if (print_object == nullptr)
return;
m_layers_editing.render(*this, *print_object, *volume);
} }
void GLCanvas3D::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const void GLCanvas3D::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const
@ -1741,6 +1866,15 @@ Size GLCanvas3D::get_canvas_size() const
return Size(w, h); return Size(w, h);
} }
Point GLCanvas3D::get_local_mouse_position() const
{
if (m_canvas == nullptr)
return Point();
wxPoint mouse_pos = m_canvas->ScreenToClient(wxGetMousePosition());
return Point(mouse_pos.x, mouse_pos.x);
}
void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox) void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox)
{ {
// Calculate the zoom factor needed to adjust viewport to bounding box. // Calculate the zoom factor needed to adjust viewport to bounding box.

View file

@ -14,9 +14,11 @@ class wxKeyEvent;
namespace Slic3r { namespace Slic3r {
class GLVolumeCollection; class GLVolumeCollection;
class GLVolume;
class DynamicPrintConfig; class DynamicPrintConfig;
class GLShader; class GLShader;
class ExPolygon; class ExPolygon;
class Print;
class PrintObject; class PrintObject;
namespace GUI { namespace GUI {
@ -189,6 +191,8 @@ public:
bool start_using() const; bool start_using() const;
void stop_using() const; void stop_using() const;
void set_uniform(const std::string& name, float value) const;
GLShader* get_shader(); GLShader* get_shader();
private: private:
@ -213,6 +217,7 @@ public:
unsigned int m_z_texture_id; unsigned int m_z_texture_id;
mutable GLTextureData m_tooltip_texture; mutable GLTextureData m_tooltip_texture;
mutable GLTextureData m_reset_texture; mutable GLTextureData m_reset_texture;
float m_band_width;
public: public:
LayersEditing(); LayersEditing();
@ -228,7 +233,10 @@ public:
unsigned int get_z_texture_id() const; unsigned int get_z_texture_id() const;
void render(const GLCanvas3D& canvas, const PrintObject& print_object) const; float get_band_width() const;
void set_band_width(float band_width);
void render(const GLCanvas3D& canvas, const PrintObject& print_object, const GLVolume& volume) const;
GLShader* get_shader(); GLShader* get_shader();
@ -237,11 +245,13 @@ public:
GLTextureData _load_texture_from_file(const std::string& filename) const; GLTextureData _load_texture_from_file(const std::string& filename) const;
void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const; void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const;
void _render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const; void _render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const;
void _render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const;
void _render_profile(const PrintObject& print_object, const Rect& bar_rect) const; void _render_profile(const PrintObject& print_object, const Rect& bar_rect) const;
Rect _get_bar_rect_screen(const GLCanvas3D& canvas) const; Rect _get_bar_rect_screen(const GLCanvas3D& canvas) const;
Rect _get_reset_rect_screen(const GLCanvas3D& canvas) const; Rect _get_reset_rect_screen(const GLCanvas3D& canvas) const;
Rect _get_bar_rect_viewport(const GLCanvas3D& canvas) const; Rect _get_bar_rect_viewport(const GLCanvas3D& canvas) const;
Rect _get_reset_rect_viewport(const GLCanvas3D& canvas) const; Rect _get_reset_rect_viewport(const GLCanvas3D& canvas) const;
float _cursor_z_relative(const GLCanvas3D& canvas) const;
}; };
class Mouse class Mouse
@ -369,6 +379,10 @@ public:
void set_hover_volume_id(int id); void set_hover_volume_id(int id);
unsigned int get_layers_editing_z_texture_id() const; unsigned int get_layers_editing_z_texture_id() const;
float get_layers_editing_band_width() const;
void set_layers_editing_band_width(float band_width);
GLShader* get_layers_editing_shader(); GLShader* get_layers_editing_shader();
void zoom_to_bed(); void zoom_to_bed();
@ -388,7 +402,7 @@ public:
void render_cutting_plane() const; void render_cutting_plane() const;
void render_warning_texture() const; void render_warning_texture() const;
void render_legend_texture() const; void render_legend_texture() const;
void render_layer_editing_textures(const PrintObject& print_object) const; void render_layer_editing_overlay(const Print& print) const;
void render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const; void render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const;
@ -400,6 +414,7 @@ public:
void on_char(wxKeyEvent& evt); void on_char(wxKeyEvent& evt);
Size get_canvas_size() const; Size get_canvas_size() const;
Point get_local_mouse_position() const;
private: private:
void _zoom_to_bounding_box(const BoundingBoxf3& bbox); void _zoom_to_bounding_box(const BoundingBoxf3& bbox);

View file

@ -473,6 +473,19 @@ unsigned int GLCanvas3DManager::get_layers_editing_z_texture_id(wxGLCanvas* canv
return (it != m_canvases.end()) ? it->second->get_layers_editing_z_texture_id() : 0; return (it != m_canvases.end()) ? it->second->get_layers_editing_z_texture_id() : 0;
} }
float GLCanvas3DManager::get_layers_editing_band_width(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->get_layers_editing_band_width() : 0.0f;
}
void GLCanvas3DManager::set_layers_editing_band_width(wxGLCanvas* canvas, float band_width)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_layers_editing_band_width(band_width);
}
GLShader* GLCanvas3DManager::get_layers_editing_shader(wxGLCanvas* canvas) GLShader* GLCanvas3DManager::get_layers_editing_shader(wxGLCanvas* canvas)
{ {
CanvasesMap::const_iterator it = _get_canvas(canvas); CanvasesMap::const_iterator it = _get_canvas(canvas);
@ -576,11 +589,11 @@ void GLCanvas3DManager::render_legend_texture(wxGLCanvas* canvas) const
it->second->render_legend_texture(); it->second->render_legend_texture();
} }
void GLCanvas3DManager::render_layer_editing_textures(wxGLCanvas* canvas, const PrintObject& print_object) const void GLCanvas3DManager::render_layer_editing_overlay(wxGLCanvas* canvas, const Print& print) const
{ {
CanvasesMap::const_iterator it = _get_canvas(canvas); CanvasesMap::const_iterator it = _get_canvas(canvas);
if (it != m_canvases.end()) if (it != m_canvases.end())
it->second->render_layer_editing_textures(print_object); it->second->render_layer_editing_overlay(print);
} }
void GLCanvas3DManager::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const void GLCanvas3DManager::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const

View file

@ -117,6 +117,10 @@ public:
void set_hover_volume_id(wxGLCanvas* canvas, int id); void set_hover_volume_id(wxGLCanvas* canvas, int id);
unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas) const; unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas) const;
float get_layers_editing_band_width(wxGLCanvas* canvas) const;
void set_layers_editing_band_width(wxGLCanvas* canvas, float band_width);
GLShader* get_layers_editing_shader(wxGLCanvas* canvas); GLShader* get_layers_editing_shader(wxGLCanvas* canvas);
void zoom_to_bed(wxGLCanvas* canvas); void zoom_to_bed(wxGLCanvas* canvas);
@ -136,7 +140,7 @@ public:
void render_cutting_plane(wxGLCanvas* canvas) const; void render_cutting_plane(wxGLCanvas* canvas) const;
void render_warning_texture(wxGLCanvas* canvas) const; void render_warning_texture(wxGLCanvas* canvas) const;
void render_legend_texture(wxGLCanvas* canvas) const; void render_legend_texture(wxGLCanvas* canvas) const;
void render_layer_editing_textures(wxGLCanvas* canvas, const PrintObject& print_object) const; void render_layer_editing_overlay(wxGLCanvas* canvas, const Print& print) const;
void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const; void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const;

View file

@ -571,6 +571,21 @@ get_layers_editing_z_texture_id(canvas)
OUTPUT: OUTPUT:
RETVAL RETVAL
float
get_layers_editing_band_width(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::get_layers_editing_band_width((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
void
set_layers_editing_band_width(canvas, band_width)
SV *canvas;
float band_width;
CODE:
_3DScene::set_layers_editing_band_width((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), band_width);
Ref<GLShader> Ref<GLShader>
get_layers_editing_shader(canvas) get_layers_editing_shader(canvas)
SV *canvas; SV *canvas;
@ -669,11 +684,11 @@ render_legend_texture(canvas)
_3DScene::render_legend_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); _3DScene::render_legend_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void void
render_layer_editing_textures(canvas, print_object) render_layer_editing_overlay(canvas, print)
SV *canvas; SV *canvas;
PrintObject *print_object; Print *print;
CODE: CODE:
_3DScene::render_layer_editing_textures((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print_object); _3DScene::render_layer_editing_overlay((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print);
void void
render_texture(canvas, tex_id, left, right, bottom, top) render_texture(canvas, tex_id, left, right, bottom, top)