diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index 1ad9d7610..a05d24153 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -951,6 +951,7 @@ use List::Util qw(first); use constant COLORS => [ [1,1,0], [1,0.5,0.5], [0.5,1,0.5], [0.5,0.5,1] ]; __PACKAGE__->mk_accessors(qw( + color_by select_by drag_by volumes_by_object @@ -961,7 +962,8 @@ sub new { my $class = shift; my $self = $class->SUPER::new(@_); - $self->select_by('object'); # object | instance + $self->color_by('volume'); # object | volume + $self->select_by('object'); # object | volume | instance $self->drag_by('instance'); # object | instance $self->volumes_by_object({}); # obj_idx => [ volume_idx, volume_idx ... ] $self->_objects_by_volumes({}); # volume_idx => [ obj_idx, instance_idx ] @@ -983,24 +985,19 @@ sub load_object { $instance_idxs ||= [0..$#{$model_object->instances}]; - # color mesh(es) by material - my @materials = (); - - # sort volumes: non-modifiers first - my @volumes = sort { ($a->modifier // 0) <=> ($b->modifier // 0) } - @{$model_object->volumes}; my @volumes_idx = (); - foreach my $volume (@volumes) { + foreach my $volume_idx (0..$#{$model_object->volumes}) { + my $volume = $model_object->volumes->[$volume_idx]; foreach my $instance_idx (@$instance_idxs) { my $instance = $model_object->instances->[$instance_idx]; my $mesh = $volume->mesh->clone; $instance->transform_mesh($mesh); - my $material_id = $volume->material_id // '_'; - my $color_idx = first { $materials[$_] eq $material_id } 0..$#materials; - if (!defined $color_idx) { - push @materials, $material_id; - $color_idx = $#materials; + my $color_idx; + if ($self->color_by eq 'volume') { + $color_idx = $volume_idx; + } elsif ($self->color_by eq 'object') { + $color_idx = $obj_idx; } my $color = [ @{COLORS->[ $color_idx % scalar(@{&COLORS}) ]} ]; @@ -1011,9 +1008,11 @@ sub load_object { ); $v->mesh($mesh) if $self->enable_cutting; if ($self->select_by eq 'object') { - $v->select_group_id($obj_idx*1000); + $v->select_group_id($obj_idx*1000000); + } elsif ($self->select_by eq 'volume') { + $v->select_group_id($obj_idx*1000000 + $volume_idx*1000); } elsif ($self->select_by eq 'instance') { - $v->select_group_id($obj_idx*1000 + $instance_idx); + $v->select_group_id($obj_idx*1000000 + $volume_idx*1000 + $instance_idx); } if ($self->drag_by eq 'object') { $v->drag_group_id($obj_idx*1000); @@ -1021,7 +1020,7 @@ sub load_object { $v->drag_group_id($obj_idx*1000 + $instance_idx); } push @volumes_idx, my $scene_volume_idx = $#{$self->volumes}; - $self->_objects_by_volumes->{$scene_volume_idx} = [ $obj_idx, $instance_idx ]; + $self->_objects_by_volumes->{$scene_volume_idx} = [ $obj_idx, $volume_idx, $instance_idx ]; { my $vertices = $mesh->vertices; @@ -1045,9 +1044,14 @@ sub object_idx { return $self->_objects_by_volumes->{$volume_idx}[0]; } -sub instance_idx { +sub volume_idx { my ($self, $volume_idx) = @_; return $self->_objects_by_volumes->{$volume_idx}[1]; } +sub instance_idx { + my ($self, $volume_idx) = @_; + return $self->_objects_by_volumes->{$volume_idx}[2]; +} + 1; diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index ba8003e6e..aa07dae15 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -69,6 +69,16 @@ sub new { my $canvas; if ($Slic3r::GUI::have_OpenGL) { $canvas = $self->{canvas} = Slic3r::GUI::3DScene->new($self); + $canvas->enable_picking(1); + $canvas->select_by('volume'); + + $canvas->on_select(sub { + my ($volume_idx) = @_; + + # convert scene volume to model object volume + $self->reload_tree($canvas->volume_idx($volume_idx)); + }); + $canvas->load_object($self->{model_object}); $canvas->set_auto_bed_shape; $canvas->SetSize([500,500]); @@ -101,20 +111,24 @@ sub new { } sub reload_tree { - my ($self) = @_; + my ($self, $selected_volume_idx) = @_; + $selected_volume_idx //= -1; my $object = $self->{model_object}; my $tree = $self->{tree}; my $rootId = $tree->GetRootItem; $tree->DeleteChildren($rootId); - my $itemId; + my $selectedId = $rootId; foreach my $volume_id (0..$#{$object->volumes}) { my $volume = $object->volumes->[$volume_id]; my $icon = $volume->modifier ? ICON_MODIFIERMESH : ICON_SOLIDMESH; - $itemId = $tree->AppendItem($rootId, $volume->name || $volume_id, $icon); + my $itemId = $tree->AppendItem($rootId, $volume->name || $volume_id, $icon); + if ($volume_id == $selected_volume_idx) { + $selectedId = $itemId; + } $tree->SetPlData($itemId, { type => 'volume', volume_id => $volume_id, @@ -122,10 +136,9 @@ sub reload_tree { } $tree->ExpandAll; - # select last appended part # This will trigger the selection_changed() event Slic3r::GUI->CallAfter(sub { - $self->{tree}->SelectItem($itemId); + $self->{tree}->SelectItem($selectedId); }); } @@ -144,7 +157,7 @@ sub selection_changed { # deselect all meshes if ($self->{canvas}) { - $_->{selected} = 0 for @{$self->{canvas}->volumes}; + $_->selected(0) for @{$self->{canvas}->volumes}; } # disable things as if nothing is selected @@ -169,10 +182,7 @@ sub selection_changed { # get default values @opt_keys = @{Slic3r::Config::PrintRegion->new->get_keys}; } elsif ($itemData->{type} eq 'object') { - # select all object volumes in 3D preview - if ($self->{canvas}) { - $_->{selected} = 1 for @{$self->{canvas}->volumes}; - } + # select nothing in 3D preview # attach object config to settings panel $self->{staticbox}->SetLabel('Object Settings');