New config field extruder_color for preview of extruder assignment.

This commit is contained in:
bubnikv 2017-05-24 15:20:20 +02:00
parent 2713aa1772
commit 7d64c465c0
13 changed files with 284 additions and 64 deletions

View file

@ -1871,10 +1871,10 @@ sub load_object {
# Create 3D thick extrusion lines for a skirt and brim.
# Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes.
sub load_print_toolpaths {
my ($self, $print) = @_;
my ($self, $print, $colors) = @_;
$self->SetCurrent($self->GetContext) if $self->UseVBOs;
Slic3r::GUI::_3DScene::_load_print_toolpaths($print, $self->volumes, $self->UseVBOs)
Slic3r::GUI::_3DScene::_load_print_toolpaths($print, $self->volumes, $colors, $self->UseVBOs)
if ($print->step_done(STEP_SKIRT) && $print->step_done(STEP_BRIM));
}
@ -1882,10 +1882,10 @@ sub load_print_toolpaths {
# Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
# one for perimeters, one for infill and one for supports.
sub load_print_object_toolpaths {
my ($self, $object) = @_;
my ($self, $object, $colors) = @_;
$self->SetCurrent($self->GetContext) if $self->UseVBOs;
Slic3r::GUI::_3DScene::_load_print_object_toolpaths($object, $self->volumes, $self->UseVBOs);
Slic3r::GUI::_3DScene::_load_print_object_toolpaths($object, $self->volumes, $colors, $self->UseVBOs);
}
sub set_toolpaths_range {

View file

@ -280,6 +280,7 @@ has 'label_tooltip' => (is => 'rw', default => sub { "" });
has 'sizer' => (is => 'rw');
has 'widget' => (is => 'rw');
has '_options' => (is => 'ro', default => sub { [] });
# Extra UI components after the label and the edit widget of the option.
has '_extra_widgets' => (is => 'ro', default => sub { [] });
# this method accepts a Slic3r::GUI::OptionsGroup::Option object
@ -304,6 +305,8 @@ sub get_extra_widgets {
}
# Configuration of an option.
# This very much reflects the content of the C++ ConfigOptionDef class.
package Slic3r::GUI::OptionsGroup::Option;
use Moo;
@ -349,6 +352,8 @@ sub get_option {
my $opt_id = ($opt_index == -1 ? $opt_key : "${opt_key}#${opt_index}");
$self->_opt_map->{$opt_id} = [ $opt_key, $opt_index ];
# Slic3r::Config::Options is a C++ Slic3r::PrintConfigDef exported as a Perl hash of hashes.
# The C++ counterpart is a constant singleton.
my $optdef = $Slic3r::Config::Options->{$opt_key}; # we should access this from $self->config
my $default_value = $self->_get_config_value($opt_key, $opt_index, $optdef->{gui_flags} =~ /\bserialized\b/);
@ -463,6 +468,8 @@ sub _on_kill_focus {
$self->reload_config;
}
# Static text shown among the options.
# Currently used for the filament cooling legend only.
package Slic3r::GUI::OptionsGroup::StaticText;
use Wx qw(:misc :systemsettings);
use base 'Wx::StaticText';

View file

@ -423,8 +423,10 @@ sub get_value {
sub _string_to_colour {
my ($self, $string) = @_;
$string =~ s/^#//;
# If the color is in an invalid format, set it to white.
$string = 'FFFFFF' if ($string !~ m/^[[:xdigit:]]{6}/);
return Wx::Colour->new(unpack 'C*', pack 'H*', $string);
}

View file

@ -10,10 +10,10 @@ use List::Util qw(sum first max);
use Slic3r::Geometry qw(X Y Z MIN MAX scale unscale deg2rad rad2deg);
use LWP::UserAgent;
use threads::shared qw(shared_clone);
use Wx qw(:button :cursor :dialog :filedialog :keycode :icon :font :id :listctrl :misc
use Wx qw(:button :colour :cursor :dialog :filedialog :keycode :icon :font :id :listctrl :misc
:panel :sizer :toolbar :window wxTheApp :notebook :combobox wxNullBitmap);
use Wx::Event qw(EVT_BUTTON EVT_TOGGLEBUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED
EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL
EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_LEFT_DOWN EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL
EVT_CHOICE EVT_COMBOBOX EVT_TIMER EVT_NOTEBOOK_PAGE_CHANGED);
use base 'Wx::Panel';
@ -54,7 +54,7 @@ sub new {
bed_shape complete_objects extruder_clearance_radius skirts skirt_distance brim_width variable_layer_height
serial_port serial_speed octoprint_host octoprint_apikey
nozzle_diameter single_extruder_multi_material
wipe_tower wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe
wipe_tower wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe extruder_colour filament_colour
));
# C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm
$self->{model} = Slic3r::Model->new;
@ -138,7 +138,7 @@ sub new {
# Initialize 3D toolpaths preview
if ($Slic3r::GUI::have_OpenGL) {
$self->{preview3D} = Slic3r::GUI::Plater::3DPreview->new($self->{preview_notebook}, $self->{print});
$self->{preview3D} = Slic3r::GUI::Plater::3DPreview->new($self->{preview_notebook}, $self->{print}, $self->{config});
$self->{preview3D}->canvas->on_viewport_changed(sub {
$self->{canvas3D}->set_viewport_from_scene($self->{preview3D}->canvas);
});
@ -378,6 +378,7 @@ sub new {
my $text = Wx::StaticText->new($self, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
$text->SetFont($Slic3r::GUI::small_font);
my $choice = Wx::BitmapComboBox->new($self, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY);
EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down(0, @_); } );
$self->{preset_choosers}{$group} = [$choice];
$self->{preset_choosers_default_suppressed}{$group} = 0;
# setup the listener
@ -524,12 +525,12 @@ sub _on_select_preset {
$Slic3r::GUI::Settings->{presets}{"filament_${_}"} = $choice->GetString($filament_presets[$_] - $default_suppressed)
for 1 .. $#filament_presets;
wxTheApp->save_settings;
return;
}
# call GetSelection() in scalar context as it's context-aware
$self->{on_select_preset}->($group, scalar($choice->GetSelection) + $default_suppressed)
if $self->{on_select_preset};
$self->update_filament_colors_preview($choice);
} else {
# call GetSelection() in scalar context as it's context-aware
$self->{on_select_preset}->($group, scalar($choice->GetSelection) + $default_suppressed)
if $self->{on_select_preset};
}
# get new config and generate on_config_change() event for updating plater and other things
$self->on_config_change($self->GetFrame->config);
@ -584,6 +585,7 @@ sub update_presets {
my ($group, $presets, $default_suppressed, $selected, $is_dirty) = @_;
my @choosers = @{ $self->{preset_choosers}{$group} };
my $choice_idx = 0;
foreach my $choice (@choosers) {
if ($group eq 'filament' && @choosers > 1) {
# if we have more than one filament chooser, keep our selection
@ -596,17 +598,7 @@ sub update_presets {
next if ($preset->default && $default_suppressed);
my $bitmap;
if ($group eq 'filament') {
my $config = $preset->config(['filament_colour']);
my $rgb_hex = $config->filament_colour->[0];
if ($preset->default) {
$bitmap = Wx::Bitmap->new($Slic3r::var->("spool.png"), wxBITMAP_TYPE_PNG);
} else {
$rgb_hex =~ s/^#//;
my @rgb = unpack 'C*', pack 'H*', $rgb_hex;
my $image = Wx::Image->new(16,16);
$image->SetRGB(Wx::Rect->new(0,0,16,16), @rgb);
$bitmap = Wx::Bitmap->new($image);
}
$bitmap = Wx::Bitmap->new($Slic3r::var->("spool.png"), wxBITMAP_TYPE_PNG);
} elsif ($group eq 'print') {
$bitmap = Wx::Bitmap->new($Slic3r::var->("cog.png"), wxBITMAP_TYPE_PNG);
} elsif ($group eq 'printer') {
@ -626,9 +618,76 @@ sub update_presets {
$choice->SetSelection($idx);
}
}
$choice_idx += 1;
}
$self->{preset_choosers_default_suppressed}{$group} = $default_suppressed;
$self->update_filament_colors_preview;
}
# Update the color icon in front of each filament selection on the platter.
# If the extruder has a preview color assigned, apply the extruder color to the active selection.
# Always apply the filament color to the non-active selections.
sub update_filament_colors_preview {
my ($self, $extruder_idx) = shift;
my @choosers = @{$self->{preset_choosers}{filament}};
if (ref $extruder_idx) {
# $extruder_idx is the chooser.
foreach my $chooser (@choosers) {
if ($extruder_idx == $chooser) {
$extruder_idx = $chooser;
last;
}
}
}
my @extruder_colors = @{$self->{config}->extruder_colour};
my @extruder_list;
if (defined $extruder_idx) {
@extruder_list = ($extruder_idx);
} else {
# Collect extruder indices.
@extruder_list = (0..$#extruder_colors);
}
my $filament_tab = $self->GetFrame->{options_tabs}{filament};
my $presets = $filament_tab->{presets};
my $default_suppressed = $filament_tab->{default_suppressed};
foreach my $extruder_idx (@extruder_list) {
my $chooser = $choosers[$extruder_idx];
my $extruder_color = $self->{config}->extruder_colour->[$extruder_idx];
my $preset_idx = 0;
my $selection_idx = $chooser->GetSelection;
foreach my $preset (@$presets) {
my $bitmap;
if ($preset->default) {
next if $default_suppressed;
} else {
# Assign an extruder color to the selected item if the extruder color is defined.
my $filament_rgb = $preset->config(['filament_colour'])->filament_colour->[0];
my $extruder_rgb = ($preset_idx == $selection_idx && $extruder_color =~ m/^#[[:xdigit:]]{6}/) ? $extruder_color : $filament_rgb;
$filament_rgb =~ s/^#//;
$extruder_rgb =~ s/^#//;
my $image = Wx::Image->new(24,16);
if ($filament_rgb ne $extruder_rgb) {
my @rgb = unpack 'C*', pack 'H*', $extruder_rgb;
$image->SetRGB(Wx::Rect->new(0,0,16,16), @rgb);
@rgb = unpack 'C*', pack 'H*', $filament_rgb;
$image->SetRGB(Wx::Rect->new(16,0,8,16), @rgb);
} else {
my @rgb = unpack 'C*', pack 'H*', $filament_rgb;
$image->SetRGB(Wx::Rect->new(0,0,24,16), @rgb);
}
$bitmap = Wx::Bitmap->new($image);
}
$chooser->SetItemBitmap($preset_idx, $bitmap) if $bitmap;
$preset_idx += 1;
}
}
}
# Return a vector of indices of filaments selected by the $self->{preset_choosers}{filament} combo boxes.
@ -1675,6 +1734,8 @@ sub on_extruders_change {
# initialize new choice
my $choice = Wx::BitmapComboBox->new($self, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY);
my $extruder_idx = scalar @$choices;
EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down($extruder_idx, @_); } );
push @$choices, $choice;
# copy icons from first choice
@ -1756,6 +1817,8 @@ sub on_config_change {
$self->{"btn_layer_editing"}->Enable;
}
}
} elsif ($opt_key eq 'extruder_color') {
}
}
@ -1793,6 +1856,33 @@ sub list_item_activated {
$self->object_settings_dialog($obj_idx);
}
# Called when clicked on the filament preset combo box.
# When clicked on the icon, show the color picker.
sub filament_color_box_lmouse_down
{
my ($self, $extruder_idx, $combobox, $event) = @_;
my $pos = $event->GetLogicalPosition(Wx::ClientDC->new($combobox));
my( $x, $y ) = ( $pos->x, $pos->y );
if ($x > 24) {
# Let the combo box process the mouse click.
$event->Skip;
} else {
# Swallow the mouse click and open the color picker.
my $data = Wx::ColourData->new;
$data->SetChooseFull(1);
my $dialog = Wx::ColourDialog->new($self->GetFrame, $data);
if ($dialog->ShowModal == wxID_OK) {
my $cfg = Slic3r::Config->new;
my $colors = $self->GetFrame->config->get('extruder_colour');
$colors->[$extruder_idx] = $dialog->GetColourData->GetColour->GetAsString(wxC2S_HTML_SYNTAX);
$cfg->set('extruder_colour', $colors);
$self->GetFrame->{options_tabs}{printer}->load_config($cfg);
$self->update_filament_colors_preview($extruder_idx);
}
$dialog->Destroy();
}
}
sub object_cut_dialog {
my $self = shift;
my ($obj_idx) = @_;

View file

@ -8,14 +8,15 @@ use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE);
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX);
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 color_by_extruder));
sub new {
my $class = shift;
my ($parent, $print) = @_;
my ($parent, $print, $config) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition);
$self->{config} = $config;
# init GUI elements
my $canvas = Slic3r::GUI::3DScene->new($self);
$canvas->use_plain_shader(1);
@ -53,7 +54,9 @@ 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 $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
@ -67,6 +70,7 @@ 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 $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$sizer->Add($canvas, 1, wxALL | wxEXPAND, 0);
@ -107,6 +111,10 @@ 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->reload_print;
});
$self->SetSizer($sizer);
$self->SetMinSize($self->GetSize);
@ -180,13 +188,27 @@ sub load_print {
$self->slider_low->Show;
$self->slider_high->Show;
$self->Layout;
# Collect colors per extruder.
# Leave it empty, if the print should be colored by a feature.
my @colors = ();
if ($self->color_by_extruder) {
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 ($color !~ m/^#[[:xdigit:]]{6}/);
$color = '#FFFFFF' if ($color !~ m/^#[[:xdigit:]]{6}/);
push @colors, $color;
}
}
if ($self->IsShown) {
# load skirt and brim
$self->canvas->load_print_toolpaths($self->print);
$self->canvas->load_print_toolpaths($self->print, \@colors);
foreach my $object (@{$self->print->objects}) {
$self->canvas->load_print_object_toolpaths($object);
$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);

View file

@ -1164,7 +1164,7 @@ sub build {
nozzle_diameter extruder_offset
retract_length retract_lift retract_speed deretract_speed retract_before_wipe retract_restart_extra retract_before_travel retract_layer_change wipe
retract_length_toolchange retract_restart_extra_toolchange
printer_notes
extruder_colour printer_notes
));
$self->{config}->set('printer_settings_id', '');
@ -1455,7 +1455,7 @@ sub _extruder_options {
qw(nozzle_diameter min_layer_height max_layer_height extruder_offset
retract_length retract_lift retract_lift_above retract_lift_below retract_speed deretract_speed
retract_before_wipe retract_restart_extra retract_before_travel wipe
retract_layer_change retract_length_toolchange retract_restart_extra_toolchange) }
retract_layer_change retract_length_toolchange retract_restart_extra_toolchange extruder_colour) }
sub _build_extruder_pages {
my $self = shift;
@ -1514,6 +1514,10 @@ sub _build_extruder_pages {
$optgroup->append_single_option_line($_, $extruder_idx)
for qw(retract_length_toolchange retract_restart_extra_toolchange);
}
{
my $optgroup = $page->new_optgroup('Preview');
$optgroup->append_single_option_line('extruder_colour', $extruder_idx);
}
}
# remove extra pages
@ -1765,6 +1769,7 @@ sub get_name {
package Slic3r::GUI::Tab::Preset;
use Moo;
# The preset represents a "default" set of properties.
has 'default' => (is => 'ro', default => sub { 0 });
has 'external' => (is => 'ro', default => sub { 0 });
has 'name' => (is => 'rw', required => 1);