Ability to select object parts by clicking in the 3D view in the object editor

This commit is contained in:
Alessandro Ranellucci 2015-01-13 19:07:25 +01:00
parent d46d5c955b
commit 3ee0fc5b1c
2 changed files with 41 additions and 27 deletions

View file

@ -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] ]; 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( __PACKAGE__->mk_accessors(qw(
color_by
select_by select_by
drag_by drag_by
volumes_by_object volumes_by_object
@ -961,7 +962,8 @@ sub new {
my $class = shift; my $class = shift;
my $self = $class->SUPER::new(@_); 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->drag_by('instance'); # object | instance
$self->volumes_by_object({}); # obj_idx => [ volume_idx, volume_idx ... ] $self->volumes_by_object({}); # obj_idx => [ volume_idx, volume_idx ... ]
$self->_objects_by_volumes({}); # volume_idx => [ obj_idx, instance_idx ] $self->_objects_by_volumes({}); # volume_idx => [ obj_idx, instance_idx ]
@ -983,24 +985,19 @@ sub load_object {
$instance_idxs ||= [0..$#{$model_object->instances}]; $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 = (); 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) { foreach my $instance_idx (@$instance_idxs) {
my $instance = $model_object->instances->[$instance_idx]; my $instance = $model_object->instances->[$instance_idx];
my $mesh = $volume->mesh->clone; my $mesh = $volume->mesh->clone;
$instance->transform_mesh($mesh); $instance->transform_mesh($mesh);
my $material_id = $volume->material_id // '_'; my $color_idx;
my $color_idx = first { $materials[$_] eq $material_id } 0..$#materials; if ($self->color_by eq 'volume') {
if (!defined $color_idx) { $color_idx = $volume_idx;
push @materials, $material_id; } elsif ($self->color_by eq 'object') {
$color_idx = $#materials; $color_idx = $obj_idx;
} }
my $color = [ @{COLORS->[ $color_idx % scalar(@{&COLORS}) ]} ]; my $color = [ @{COLORS->[ $color_idx % scalar(@{&COLORS}) ]} ];
@ -1011,9 +1008,11 @@ sub load_object {
); );
$v->mesh($mesh) if $self->enable_cutting; $v->mesh($mesh) if $self->enable_cutting;
if ($self->select_by eq 'object') { 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') { } 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') { if ($self->drag_by eq 'object') {
$v->drag_group_id($obj_idx*1000); $v->drag_group_id($obj_idx*1000);
@ -1021,7 +1020,7 @@ sub load_object {
$v->drag_group_id($obj_idx*1000 + $instance_idx); $v->drag_group_id($obj_idx*1000 + $instance_idx);
} }
push @volumes_idx, my $scene_volume_idx = $#{$self->volumes}; 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; my $vertices = $mesh->vertices;
@ -1045,9 +1044,14 @@ sub object_idx {
return $self->_objects_by_volumes->{$volume_idx}[0]; return $self->_objects_by_volumes->{$volume_idx}[0];
} }
sub instance_idx { sub volume_idx {
my ($self, $volume_idx) = @_; my ($self, $volume_idx) = @_;
return $self->_objects_by_volumes->{$volume_idx}[1]; return $self->_objects_by_volumes->{$volume_idx}[1];
} }
sub instance_idx {
my ($self, $volume_idx) = @_;
return $self->_objects_by_volumes->{$volume_idx}[2];
}
1; 1;

View file

@ -69,6 +69,16 @@ sub new {
my $canvas; my $canvas;
if ($Slic3r::GUI::have_OpenGL) { if ($Slic3r::GUI::have_OpenGL) {
$canvas = $self->{canvas} = Slic3r::GUI::3DScene->new($self); $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->load_object($self->{model_object});
$canvas->set_auto_bed_shape; $canvas->set_auto_bed_shape;
$canvas->SetSize([500,500]); $canvas->SetSize([500,500]);
@ -101,20 +111,24 @@ sub new {
} }
sub reload_tree { sub reload_tree {
my ($self) = @_; my ($self, $selected_volume_idx) = @_;
$selected_volume_idx //= -1;
my $object = $self->{model_object}; my $object = $self->{model_object};
my $tree = $self->{tree}; my $tree = $self->{tree};
my $rootId = $tree->GetRootItem; my $rootId = $tree->GetRootItem;
$tree->DeleteChildren($rootId); $tree->DeleteChildren($rootId);
my $itemId; my $selectedId = $rootId;
foreach my $volume_id (0..$#{$object->volumes}) { foreach my $volume_id (0..$#{$object->volumes}) {
my $volume = $object->volumes->[$volume_id]; my $volume = $object->volumes->[$volume_id];
my $icon = $volume->modifier ? ICON_MODIFIERMESH : ICON_SOLIDMESH; 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, { $tree->SetPlData($itemId, {
type => 'volume', type => 'volume',
volume_id => $volume_id, volume_id => $volume_id,
@ -122,10 +136,9 @@ sub reload_tree {
} }
$tree->ExpandAll; $tree->ExpandAll;
# select last appended part
# This will trigger the selection_changed() event # This will trigger the selection_changed() event
Slic3r::GUI->CallAfter(sub { Slic3r::GUI->CallAfter(sub {
$self->{tree}->SelectItem($itemId); $self->{tree}->SelectItem($selectedId);
}); });
} }
@ -144,7 +157,7 @@ sub selection_changed {
# deselect all meshes # deselect all meshes
if ($self->{canvas}) { if ($self->{canvas}) {
$_->{selected} = 0 for @{$self->{canvas}->volumes}; $_->selected(0) for @{$self->{canvas}->volumes};
} }
# disable things as if nothing is selected # disable things as if nothing is selected
@ -169,10 +182,7 @@ sub selection_changed {
# get default values # get default values
@opt_keys = @{Slic3r::Config::PrintRegion->new->get_keys}; @opt_keys = @{Slic3r::Config::PrintRegion->new->get_keys};
} elsif ($itemData->{type} eq 'object') { } elsif ($itemData->{type} eq 'object') {
# select all object volumes in 3D preview # select nothing in 3D preview
if ($self->{canvas}) {
$_->{selected} = 1 for @{$self->{canvas}->volumes};
}
# attach object config to settings panel # attach object config to settings panel
$self->{staticbox}->SetLabel('Object Settings'); $self->{staticbox}->SetLabel('Object Settings');