From b5b8fb606fa2e067bfeb653ff930724db6f2c28f Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 22 Jan 2014 21:09:32 +0100 Subject: [PATCH] Basic functionality of the Parts tab is complete --- lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm | 59 +++++++++++++++---- lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm | 4 ++ lib/Slic3r/GUI/PreviewCanvas.pm | 18 ++++-- lib/Slic3r/Model.pm | 5 ++ 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index ef4582b31..4ac74bda7 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -34,16 +34,19 @@ sub new { $self->reload_tree; } - $self->{btn_load} = Wx::Button->new($self, -1, "Load part…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + $self->{btn_load_part} = Wx::Button->new($self, -1, "Load part…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + $self->{btn_load_modifier} = Wx::Button->new($self, -1, "Load modifier…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); $self->{btn_delete} = Wx::Button->new($self, -1, "Delete part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); # left pane with tree my $left_sizer = Wx::BoxSizer->new(wxVERTICAL); $left_sizer->Add($tree, 0, wxEXPAND | wxALL, 10); - $left_sizer->Add($self->{btn_load}, 0); + $left_sizer->Add($self->{btn_load_part}, 0); + $left_sizer->Add($self->{btn_load_modifier}, 0); $left_sizer->Add($self->{btn_delete}, 0); if ($Slic3r::GUI::have_button_icons) { - $self->{btn_load}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/brick_add.png", wxBITMAP_TYPE_PNG)); + $self->{btn_load_part}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/brick_add.png", wxBITMAP_TYPE_PNG)); + $self->{btn_load_modifier}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/brick_add.png", wxBITMAP_TYPE_PNG)); $self->{btn_delete}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/brick_delete.png", wxBITMAP_TYPE_PNG)); } @@ -67,7 +70,9 @@ sub new { my ($self, $event) = @_; $self->selection_changed; }); - EVT_BUTTON($self, $self->{btn_load}, \&on_btn_load); + EVT_BUTTON($self, $self->{btn_load_part}, sub { $self->on_btn_load(0) }); + EVT_BUTTON($self, $self->{btn_load_modifier}, sub { $self->on_btn_load(1) }); + EVT_BUTTON($self, $self->{btn_delete}, \&on_btn_delete); $self->selection_changed; @@ -106,6 +111,16 @@ sub reload_tree { $tree->ExpandAll; } +sub get_selection { + my ($self) = @_; + + my $nodeId = $self->{tree}->GetSelection; + if ($nodeId->IsOk) { + return $self->{tree}->GetPlData($nodeId); + } + return undef; +} + sub selection_changed { my ($self) = @_; @@ -115,20 +130,17 @@ sub selection_changed { # disable buttons $self->{btn_delete}->Disable; - my $nodeId = $self->{tree}->GetSelection; - if ($nodeId->IsOk) { - my $itemData = $self->{tree}->GetPlData($nodeId); - if ($itemData && $itemData->{type} eq 'volume') { - $self->{canvas}->volumes->[ $itemData->{volume_id} ]{selected} = 1; - $self->{btn_delete}->Enable; - } + my $itemData = $self->get_selection; + if ($itemData && $itemData->{type} eq 'volume') { + $self->{canvas}->volumes->[ $itemData->{volume_id} ]{selected} = 1; + $self->{btn_delete}->Enable; } $self->{canvas}->Render; } sub on_btn_load { - my ($self) = @_; + my ($self, $is_modifier) = @_; my @input_files = Slic3r::GUI::open_model($self); foreach my $input_file (@input_files) { @@ -141,6 +153,7 @@ sub on_btn_load { foreach my $object (@{$model->objects}) { foreach my $volume (@{$object->volumes}) { my $new_volume = $self->{model_object}->add_volume($volume); + $new_volume->modifier($is_modifier); if (!defined $new_volume->material_id) { my $material_name = basename($input_file); $material_name =~ s/\.(stl|obj)$//i; @@ -153,6 +166,28 @@ sub on_btn_load { $self->reload_tree; $self->{canvas}->load_object($self->{model_object}); + $self->{canvas}->Render; +} + +sub on_btn_delete { + my ($self) = @_; + + my $itemData = $self->get_selection; + if ($itemData && $itemData->{type} eq 'volume') { + my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}]; + + # if user is deleting the last solid part, throw error + if (!$volume->modifier && scalar(grep !$_->modifier, @{$self->{model_object}->volumes}) == 1) { + Slic3r::GUI::show_error($self, "You can't delete the last solid part from this object."); + return; + } + + $self->{model_object}->delete_volume($itemData->{volume_id}); + } + + $self->reload_tree; + $self->{canvas}->load_object($self->{model_object}); + $self->{canvas}->Render; } 1; diff --git a/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm b/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm index 9422ab547..b97207c39 100644 --- a/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm +++ b/lib/Slic3r/GUI/Plater/ObjectSettingsDialog.pm @@ -338,6 +338,10 @@ sub Closing { foreach my $volume (@{$self->model_object->volumes}) { if (defined $volume->material_id) { my $config = $self->model_object->model->materials->{ $volume->material_id }->config; + + # temporary hack for handling volumes added after the window was launched + $self->{mapping}{ $volume->material_id } //= 0; + $config->set('extruder', $self->{mapping}{ $volume->material_id }-1); } } diff --git a/lib/Slic3r/GUI/PreviewCanvas.pm b/lib/Slic3r/GUI/PreviewCanvas.pm index 64d7fb013..a2a0a6c90 100644 --- a/lib/Slic3r/GUI/PreviewCanvas.pm +++ b/lib/Slic3r/GUI/PreviewCanvas.pm @@ -18,7 +18,7 @@ __PACKAGE__->mk_accessors( qw(quat dirty init mview_init use constant TRACKBALLSIZE => 0.8; use constant TURNTABLE_MODE => 1; -use constant SELECTED_COLOR => [0,1,0]; +use constant SELECTED_COLOR => [0,1,0,1]; use constant COLORS => [ [1,1,1], [1,0.5,0.5], [0.5,1,0.5], [0.5,0.5,1] ]; sub new { @@ -81,7 +81,10 @@ sub load_object { # group mesh(es) by material my @materials = (); $self->volumes([]); - foreach my $volume (@{$object->volumes}) { + + # sort volumes: non-modifiers first + my @volumes = sort { ($a->modifier // 0) <=> ($b->modifier // 0) } @{$object->volumes}; + foreach my $volume (@volumes) { my $mesh = $volume->mesh->clone; $mesh->translate(@{ $self->object_shift }); @@ -91,8 +94,11 @@ sub load_object { push @materials, $material_id; $color_idx = $#materials; } + + my $color = [ @{COLORS->[ $color_idx % scalar(@{&COLORS}) ]} ]; + push @$color, $volume->modifier ? 0.5 : 1; push @{$self->volumes}, my $v = { - color => COLORS->[ $color_idx % scalar(@{&COLORS}) ], + color => $color, }; { @@ -445,6 +451,8 @@ sub Render { sub draw_mesh { my $self = shift; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); @@ -455,9 +463,9 @@ sub draw_mesh { glCullFace(GL_BACK); glNormalPointer_p($volume->{norms}); if ($volume->{selected}) { - glColor3f(@{ &SELECTED_COLOR }); + glColor4f(@{ &SELECTED_COLOR }); } else { - glColor3f(@{ $volume->{color} }); + glColor4f(@{ $volume->{color} }); } glDrawArrays(GL_TRIANGLES, 0, $volume->{verts}->elements / 3); } diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index 6e86ed00a..47e83399d 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -351,6 +351,11 @@ sub add_volume { return $new_volume; } +sub delete_volume { + my ($self, $i) = @_; + splice @{$self->volumes}, $i, 1; +} + sub add_instance { my $self = shift; my %params = @_;