mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-07 05:54:03 -06:00
New config field extruder_color for preview of extruder assignment.
This commit is contained in:
parent
2713aa1772
commit
7d64c465c0
13 changed files with 284 additions and 64 deletions
|
@ -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 {
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) = @_;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue