Merge branch 'gcode_preview'

This commit is contained in:
bubnikv 2018-02-14 13:29:57 +01:00
commit f38e0f2b4f
32 changed files with 3691 additions and 531 deletions

View file

@ -66,8 +66,11 @@ __PACKAGE__->mk_accessors( qw(_quat _dirty init
_camera_target
_camera_distance
_zoom
_legend_enabled
) );
use constant TRACKBALLSIZE => 0.8;
use constant TURNTABLE_MODE => 1;
use constant GROUND_Z => -0.02;
@ -137,6 +140,7 @@ sub new {
$self->_stheta(45);
$self->_sphi(45);
$self->_zoom(1);
$self->_legend_enabled(0);
$self->use_plain_shader(0);
# Collection of GLVolume objects
@ -209,6 +213,11 @@ sub new {
return $self;
}
sub set_legend_enabled {
my ($self, $value) = @_;
$self->_legend_enabled($value);
}
sub Destroy {
my ($self) = @_;
$self->{layer_height_edit_timer}->Stop;
@ -1316,6 +1325,9 @@ sub Render {
glDisable(GL_BLEND);
}
# draw gcode preview legend
$self->draw_legend;
$self->draw_active_object_annotations;
$self->SwapBuffers();
@ -1449,12 +1461,18 @@ sub _variable_layer_thickness_load_reset_image {
# Paint the tooltip.
sub _render_image {
my ($self, $image, $l, $r, $b, $t) = @_;
$self->_render_texture($image->{texture_id}, $l, $r, $b, $t);
}
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);
@ -1579,6 +1597,37 @@ sub draw_active_object_annotations {
glEnable(GL_DEPTH_TEST);
}
sub draw_legend {
my ($self) = @_;
if ($self->_legend_enabled)
{
my $tex_id = Slic3r::GUI::_3DScene::get_legend_texture_id;
if ($tex_id > 0)
{
my $tex_w = Slic3r::GUI::_3DScene::get_legend_texture_width;
my $tex_h = Slic3r::GUI::_3DScene::get_legend_texture_height;
if (($tex_w > 0) && ($tex_h > 0))
{
glDisable(GL_DEPTH_TEST);
glPushMatrix();
glLoadIdentity();
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);
}
}
}
}
sub opengl_info
{
my ($self, %params) = @_;
@ -1979,9 +2028,20 @@ sub load_wipe_tower_toolpaths {
if ($print->step_done(STEP_WIPE_TOWER));
}
sub load_gcode_preview {
my ($self, $print, $colors) = @_;
$self->SetCurrent($self->GetContext) if $self->UseVBOs;
Slic3r::GUI::_3DScene::load_gcode_preview($print, $self->volumes, $colors, $self->UseVBOs);
}
sub set_toolpaths_range {
my ($self, $min_z, $max_z) = @_;
$self->volumes->set_range($min_z, $max_z);
}
sub reset_legend_texture {
Slic3r::GUI::_3DScene::reset_legend_texture();
}
1;

View file

@ -156,8 +156,15 @@ 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');
if ($preview == $self->{preview3D})
{
$self->{preview3D}->canvas->set_legend_enabled(1);
$self->{preview3D}->load_print(1);
} else {
$self->{preview3D}->canvas->set_legend_enabled(0);
}
$preview->OnActivate if $preview->can('OnActivate');
});
# toolbar for object manipulation
@ -778,6 +785,7 @@ sub remove {
splice @{$self->{objects}}, $obj_idx, 1;
$self->{model}->delete_object($obj_idx);
$self->{print}->delete_object($obj_idx);
$self->{print}->clear_gcode_preview_data;
$self->{list}->DeleteItem($obj_idx);
$self->object_list_changed;
@ -798,6 +806,7 @@ sub reset {
@{$self->{objects}} = ();
$self->{model}->clear_objects;
$self->{print}->clear_objects;
$self->{print}->clear_gcode_preview_data;
$self->{list}->DeleteAllItems;
$self->object_list_changed;
@ -1257,6 +1266,8 @@ sub reslice {
$self->stop_background_process;
# Rather perform one additional unnecessary update of the print object instead of skipping a pending async update.
$self->async_apply_config;
# Reset gcode data
$self->{print}->clear_gcode_preview_data;
$self->statusbar->SetCancelCallback(sub {
$self->stop_background_process;
$self->statusbar->SetStatusText("Slicing cancelled");
@ -1447,6 +1458,10 @@ sub on_export_completed {
# this updates buttons status
$self->object_list_changed;
# refresh preview
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
$self->{preview3D}->reload_print if $self->{preview3D};
}
sub do_print {

View file

@ -4,11 +4,11 @@ use warnings;
use utf8;
use Slic3r::Print::State ':steps';
use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE);
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX);
use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE wxCB_READONLY);
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX EVT_CHOICE EVT_CHECKLISTBOX);
use base qw(Wx::Panel Class::Accessor);
__PACKAGE__->mk_accessors(qw(print enabled _loaded canvas slider_low slider_high single_layer));
__PACKAGE__->mk_accessors(qw(print enabled _loaded canvas slider_low slider_high single_layer auto_zoom));
sub new {
my $class = shift;
@ -17,7 +17,7 @@ sub new {
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition);
$self->{config} = $config;
$self->{number_extruders} = 1;
$self->{preferred_color_mode} = 'feature';
$self->auto_zoom(1);
# init GUI elements
my $canvas = Slic3r::GUI::3DScene->new($self);
@ -56,10 +56,35 @@ sub new {
$z_label_high->SetFont($Slic3r::GUI::small_font);
$self->single_layer(0);
$self->{color_by_extruder} = 0;
my $checkbox_singlelayer = $self->{checkbox_singlelayer} = Wx::CheckBox->new($self, -1, "1 Layer");
my $checkbox_color_by_extruder = $self->{checkbox_color_by_extruder} = Wx::CheckBox->new($self, -1, "Tool");
my $label_view_type = $self->{label_view_type} = Wx::StaticText->new($self, -1, "View");
my $choice_view_type = Wx::Choice->new($self, -1);
$choice_view_type->Append("Feature type");
$choice_view_type->Append("Height");
$choice_view_type->Append("Width");
$choice_view_type->Append("Speed");
$choice_view_type->Append("Tool");
$choice_view_type->SetSelection(0);
my $label_show_features = $self->{label_show_features} = Wx::StaticText->new($self, -1, "Show");
my $combochecklist_features = Wx::ComboCtrl->new();
$combochecklist_features->Create($self, -1, "Feature types", wxDefaultPosition, [200, -1], wxCB_READONLY);
#FIXME If the following line is removed, the combo box popup list will not react to mouse clicks.
# On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10.
$combochecklist_features->UseAltPopupWindow();
$combochecklist_features->EnablePopupAnimation(0);
my $feature_text = "Feature types";
my $feature_items = "Perimeter|External perimeter|Overhang perimeter|Internal infill|Solid infill|Top solid infill|Bridge infill|Gap fill|Skirt|Support material|Support material interface|Wipe tower";
Slic3r::GUI::create_combochecklist($combochecklist_features, $feature_text, $feature_items, 1);
my $checkbox_travel = Wx::CheckBox->new($self, -1, "Travel");
my $checkbox_retractions = Wx::CheckBox->new($self, -1, "Retractions");
my $checkbox_unretractions = Wx::CheckBox->new($self, -1, "Unretractions");
my $checkbox_shells = Wx::CheckBox->new($self, -1, "Shells");
my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
my $vsizer_outer = Wx::BoxSizer->new(wxVERTICAL);
@ -72,11 +97,29 @@ sub new {
$hsizer->Add($vsizer, 0, wxEXPAND, 0);
$vsizer_outer->Add($hsizer, 3, wxALIGN_CENTER_HORIZONTAL, 0);
$vsizer_outer->Add($checkbox_singlelayer, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5);
$vsizer_outer->Add($checkbox_color_by_extruder, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5);
my $bottom_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$bottom_sizer->Add($label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->Add($choice_view_type, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($label_show_features, 0, wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->Add($combochecklist_features, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(20);
$bottom_sizer->Add($checkbox_travel, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($checkbox_retractions, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($checkbox_unretractions, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($checkbox_shells, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$sizer->Add($canvas, 1, wxALL | wxEXPAND, 0);
$sizer->Add($vsizer_outer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5);
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
$main_sizer->Add($sizer, 1, wxALL | wxEXPAND, 0);
$main_sizer->Add($bottom_sizer, 0, wxALL | wxEXPAND, 0);
EVT_SLIDER($self, $slider_low, sub {
$slider_high->SetValue($slider_low->GetValue) if $self->single_layer;
@ -147,18 +190,70 @@ sub new {
$self->set_z_idx_high($slider_high->GetValue);
}
});
EVT_CHECKBOX($self, $checkbox_color_by_extruder, sub {
$self->{color_by_extruder} = $checkbox_color_by_extruder->GetValue();
$self->{preferred_color_mode} = $self->{color_by_extruder} ? 'tool' : 'feature';
EVT_CHOICE($self, $choice_view_type, sub {
my $selection = $choice_view_type->GetCurrentSelection();
$self->print->set_gcode_preview_type($selection);
$self->auto_zoom(0);
$self->reload_print;
$self->auto_zoom(1);
});
EVT_CHECKLISTBOX($self, $combochecklist_features, sub {
my $flags = Slic3r::GUI::combochecklist_get_flags($combochecklist_features);
$self->print->set_gcode_preview_extrusion_flags($flags);
$self->auto_zoom(0);
$self->refresh_print;
$self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_travel, sub {
$self->print->set_gcode_preview_travel_visible($checkbox_travel->IsChecked());
$self->auto_zoom(0);
$self->refresh_print;
$self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_retractions, sub {
$self->print->set_gcode_preview_retractions_visible($checkbox_retractions->IsChecked());
$self->auto_zoom(0);
$self->refresh_print;
$self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_unretractions, sub {
$self->print->set_gcode_preview_unretractions_visible($checkbox_unretractions->IsChecked());
$self->auto_zoom(0);
$self->refresh_print;
$self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_shells, sub {
$self->print->set_gcode_preview_shells_visible($checkbox_shells->IsChecked());
$self->auto_zoom(0);
$self->refresh_print;
$self->auto_zoom(1);
});
$self->SetSizer($sizer);
$self->SetSizer($main_sizer);
$self->SetMinSize($self->GetSize);
$sizer->SetSizeHints($self);
# init canvas
$self->print($print);
# sets colors for gcode preview extrusion roles
my @extrusion_roles_colors = (
'Perimeter' => 'FF0000',
'External perimeter' => '00FF00',
'Overhang perimeter' => '0000FF',
'Internal infill' => 'FFFF00',
'Solid infill' => 'FF00FF',
'Top solid infill' => '00FFFF',
'Bridge infill' => '7F7F7F',
'Gap fill' => 'FFFFFF',
'Skirt' => '7F0000',
'Support material' => '007F00',
'Support material interface' => '00007F',
'Wipe tower' => 'B3E3AB',
);
$self->print->set_gcode_extrusion_paths_colors(\@extrusion_roles_colors);
$self->reload_print;
return $self;
@ -171,7 +266,19 @@ sub reload_print {
$self->_loaded(0);
if (! $self->IsShown && ! $force) {
$self->{reload_delayed} = 1;
# $self->{reload_delayed} = 1;
return;
}
$self->load_print;
}
sub refresh_print {
my ($self) = @_;
$self->_loaded(0);
if (! $self->IsShown) {
return;
}
@ -203,6 +310,9 @@ sub load_print {
$self->set_z_range(0,0);
$self->slider_low->Hide;
$self->slider_high->Hide;
$self->{z_label_low}->SetLabel("");
$self->{z_label_high}->SetLabel("");
$self->canvas->reset_legend_texture();
$self->canvas->Refresh; # clears canvas
return;
}
@ -232,44 +342,35 @@ sub load_print {
$self->slider_high->Show;
$self->Layout;
my $by_tool = $self->{color_by_extruder};
if ($self->{preferred_color_mode} eq 'tool_or_feature') {
# It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature.
# Color by feature if it is a single extruder print.
my $extruders = $self->{print}->extruders;
$by_tool = scalar(@{$extruders}) > 1;
$self->{color_by_extruder} = $by_tool;
$self->{checkbox_color_by_extruder}->SetValue($by_tool);
$self->{preferred_color_mode} = 'tool_or_feature';
}
# Collect colors per extruder.
# Leave it empty, if the print should be colored by a feature.
my @colors = ();
if ($by_tool) {
my @extruder_colors = @{$self->{config}->extruder_colour};
my @filament_colors = @{$self->{config}->filament_colour};
for (my $i = 0; $i <= $#extruder_colors; $i += 1) {
my $color = $extruder_colors[$i];
$color = $filament_colors[$i] if (! defined($color) || $color !~ m/^#[[:xdigit:]]{6}/);
$color = '#FFFFFF' if (! defined($color) || $color !~ m/^#[[:xdigit:]]{6}/);
push @colors, $color;
}
my @extruder_colors = @{$self->{config}->extruder_colour};
my @filament_colors = @{$self->{config}->filament_colour};
for (my $i = 0; $i <= $#extruder_colors; $i += 1) {
my $color = $extruder_colors[$i];
$color = $filament_colors[$i] if (! defined($color) || $color !~ m/^#[[:xdigit:]]{6}/);
$color = '#FFFFFF' if (! defined($color) || $color !~ m/^#[[:xdigit:]]{6}/);
push @colors, $color;
}
if ($self->IsShown) {
# load skirt and brim
$self->canvas->load_print_toolpaths($self->print, \@colors);
$self->canvas->load_wipe_tower_toolpaths($self->print, \@colors);
foreach my $object (@{$self->print->objects}) {
$self->canvas->load_print_object_toolpaths($object, \@colors);
# Show the objects in very transparent color.
#my @volume_ids = $self->canvas->load_object($object->model_object);
#$self->canvas->volumes->[$_]->color->[3] = 0.2 for @volume_ids;
$self->canvas->load_gcode_preview($self->print, \@colors);
# # load skirt and brim
# $self->canvas->load_print_toolpaths($self->print, \@colors);
# $self->canvas->load_wipe_tower_toolpaths($self->print, \@colors);
#
# foreach my $object (@{$self->print->objects}) {
# $self->canvas->load_print_object_toolpaths($object, \@colors);
#
# # Show the objects in very transparent color.
# #my @volume_ids = $self->canvas->load_object($object->model_object);
# #$self->canvas->volumes->[$_]->color->[3] = 0.2 for @volume_ids;
# }
if ($self->auto_zoom)
{
$self->canvas->zoom_to_volumes;
}
$self->canvas->zoom_to_volumes;
$self->_loaded(1);
}
@ -322,17 +423,13 @@ sub set_number_extruders {
my ($self, $number_extruders) = @_;
if ($self->{number_extruders} != $number_extruders) {
$self->{number_extruders} = $number_extruders;
my $by_tool = $number_extruders > 1;
$self->{color_by_extruder} = $by_tool;
$self->{checkbox_color_by_extruder}->SetValue($by_tool);
$self->{preferred_color_mode} = $by_tool ? 'tool_or_feature' : 'feature';
}
}
# Called by the Platter wxNotebook when this page is activated.
sub OnActivate {
my ($self) = @_;
$self->reload_print(1) if ($self->{reload_delayed});
# my ($self) = @_;
# $self->reload_print(1) if ($self->{reload_delayed});
}
1;

View file

@ -122,16 +122,19 @@ sub load_print {
}
if ($self->IsShown) {
# load skirt and brim
$self->canvas->load_print_toolpaths($self->print);
foreach my $object (@{$self->print->objects}) {
$self->canvas->load_print_object_toolpaths($object);
# Show the objects in very transparent color.
#my @volume_ids = $self->canvas->load_object($object->model_object);
#$self->canvas->volumes->[$_]->color->[3] = 0.2 for @volume_ids;
}
$self->canvas->load_gcode_preview($self->print);
# # load skirt and brim
# $self->canvas->load_print_toolpaths($self->print);
#
# foreach my $object (@{$self->print->objects}) {
# $self->canvas->load_print_object_toolpaths($object);
#
# # Show the objects in very transparent color.
# #my @volume_ids = $self->canvas->load_object($object->model_object);
# #$self->canvas->volumes->[$_]->color->[3] = 0.2 for @volume_ids;
# }
$self->canvas->zoom_to_volumes;
$self->_loaded(1);
}