Use absolute coordinates for the modifier sliders

This commit is contained in:
Alessandro Ranellucci 2016-12-18 12:00:18 +01:00
parent b5940e542a
commit accd174566
2 changed files with 76 additions and 95 deletions

View File

@ -1,4 +1,4 @@
# Generate an anonymous or "lambda" 3D object. This gets used with the Add Generic option in Settings. # Generate an anonymous or "lambda" 3D object. This gets used with the Create Modifier option in Settings.
# #
package Slic3r::GUI::Plater::LambdaObjectDialog; package Slic3r::GUI::Plater::LambdaObjectDialog;
@ -15,40 +15,35 @@ use base 'Wx::Dialog';
sub new { sub new {
my $class = shift; my $class = shift;
my ($parent, %params) = @_; my ($parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, "Lambda Object", wxDefaultPosition, [500,500], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); my $self = $class->SUPER::new($parent, -1, "Create Modifier", wxDefaultPosition, [500,500],
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
# Note whether the window was already closed, so a pending update is not executed. # Note whether the window was already closed, so a pending update is not executed.
$self->{already_closed} = 0; $self->{already_closed} = 0;
$self->{object_parameters} = { $self->{object_parameters} = {
type => "box", type => 'slab',
dim => [1, 1, 1], dim => [1, 1, 1],
cyl_r => 1, cyl_r => 1,
cyl_h => 1, cyl_h => 1,
sph_rho => 1.0, sph_rho => 1.0,
slab_h => 1.0, slab_h => 1.0,
slab_z => 0.0,
}; };
$self->{sizer} = Wx::BoxSizer->new(wxVERTICAL); $self->{sizer} = Wx::BoxSizer->new(wxVERTICAL);
my $button_sizer = Wx::BoxSizer->new(wxHORIZONTAL); my $buttons = $self->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
my $button_ok = $self->CreateStdDialogButtonSizer(wxOK);
my $button_cancel = $self->CreateStdDialogButtonSizer(wxCANCEL);
$button_sizer->Add($button_ok);
$button_sizer->Add($button_cancel);
EVT_BUTTON($self, wxID_OK, sub { EVT_BUTTON($self, wxID_OK, sub {
# validate user input
return if !$self->CanClose;
$self->EndModal(wxID_OK); $self->EndModal(wxID_OK);
$self->Destroy; $self->Destroy;
}); });
EVT_BUTTON($self, wxID_CANCEL, sub { EVT_BUTTON($self, wxID_CANCEL, sub {
# validate user input
return if !$self->CanClose;
$self->EndModal(wxID_CANCEL); $self->EndModal(wxID_CANCEL);
$self->Destroy; $self->Destroy;
}); });
$self->{type} = Wx::ComboBox->new($self, 1, $self->{object_parameters}{type},
wxDefaultPosition, wxDefaultSize,
[qw(slab box cylinder sphere)], wxCB_READONLY);
my $optgroup_box; my $optgroup_box;
$optgroup_box = $self->{optgroup_box} = Slic3r::GUI::OptionsGroup->new( $optgroup_box = $self->{optgroup_box} = Slic3r::GUI::OptionsGroup->new(
parent => $self, parent => $self,
@ -65,26 +60,27 @@ sub new {
}, },
label_width => 100, label_width => 100,
); );
my @options = ("box", "slab", "cylinder", "sphere");
$self->{type} = Wx::ComboBox->new($self, 1, "box", wxDefaultPosition, wxDefaultSize, \@options, wxCB_READONLY);
$optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 0, opt_id => 0,
label => 'L', label => 'L (x)',
type => 'f', type => 'f',
default => '1', default => $self->{object_parameters}{dim}[0],
sidetext => 'mm',
)); ));
$optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 1, opt_id => 1,
label => 'W', label => 'W (x)',
type => 'f', type => 'f',
default => '1', default => $self->{object_parameters}{dim}[1],
sidetext => 'mm',
)); ));
$optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 2, opt_id => 2,
label => 'H', label => 'H (z)',
type => 'f', type => 'f',
default => '1', default => $self->{object_parameters}{dim}[2],
sidetext => 'mm',
)); ));
my $optgroup_cylinder; my $optgroup_cylinder;
@ -108,13 +104,15 @@ sub new {
opt_id => "cyl_r", opt_id => "cyl_r",
label => 'Radius', label => 'Radius',
type => 'f', type => 'f',
default => '1', default => $self->{object_parameters}{cyl_r},
sidetext => 'mm',
)); ));
$optgroup_cylinder->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_cylinder->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "cyl_h", opt_id => "cyl_h",
label => 'Height', label => 'Height',
type => 'f', type => 'f',
default => '1', default => $self->{object_parameters}{cyl_h},
sidetext => 'mm',
)); ));
my $optgroup_sphere; my $optgroup_sphere;
@ -136,9 +134,10 @@ sub new {
$optgroup_sphere->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_sphere->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "sph_rho", opt_id => "sph_rho",
label => 'Rho', label => 'Radius',
type => 'f', type => 'f',
default => '1', default => $self->{object_parameters}{sph_rho},
sidetext => 'mm',
)); ));
my $optgroup_slab; my $optgroup_slab;
@ -148,7 +147,7 @@ sub new {
on_change => sub { on_change => sub {
# Do validation # Do validation
my ($opt_id) = @_; my ($opt_id) = @_;
if ($opt_id eq 'slab_z' || $opt_id eq 'slab_h') { if ($opt_id eq 'slab_h') {
if (!looks_like_number($optgroup_slab->get_value($opt_id))) { if (!looks_like_number($optgroup_slab->get_value($opt_id))) {
return 0; return 0;
} }
@ -159,15 +158,10 @@ sub new {
); );
$optgroup_slab->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_slab->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "slab_h", opt_id => "slab_h",
label => 'H', label => 'Thickness',
type => 'f', type => 'f',
default => '1', default => $self->{object_parameters}{slab_h},
)); sidetext => 'mm',
$optgroup_slab->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "slab_z",
label => 'Initial Z',
type => 'f',
default => '0',
)); ));
@ -182,7 +176,7 @@ sub new {
$self->{sizer}->Add($optgroup_cylinder->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); $self->{sizer}->Add($optgroup_cylinder->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($optgroup_sphere->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); $self->{sizer}->Add($optgroup_sphere->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($optgroup_slab->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); $self->{sizer}->Add($optgroup_slab->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($button_sizer,0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); $self->{sizer}->Add($buttons,0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->_update_ui; $self->_update_ui;
$self->SetSizer($self->{sizer}); $self->SetSizer($self->{sizer});
@ -192,9 +186,7 @@ sub new {
return $self; return $self;
} }
sub CanClose {
return 1;
}
sub ObjectParameter { sub ObjectParameter {
my ($self) = @_; my ($self) = @_;
return $self->{object_parameters}; return $self->{object_parameters};

View File

@ -23,18 +23,6 @@ sub new {
my $object = $self->{model_object} = $params{model_object}; my $object = $self->{model_object} = $params{model_object};
# Save state for sliders.
$self->{move_options} = {
x => 0,
y => 0,
z => 0,
};
$self->{last_coords} = {
x => 0,
y => 0,
z => 0,
};
# create TreeCtrl # create TreeCtrl
my $tree = $self->{tree} = Wx::TreeCtrl->new($self, -1, wxDefaultPosition, [300, 100], my $tree = $self->{tree} = Wx::TreeCtrl->new($self, -1, wxDefaultPosition, [300, 100],
wxTR_NO_BUTTONS | wxSUNKEN_BORDER | wxTR_HAS_VARIABLE_ROW_HEIGHT wxTR_NO_BUTTONS | wxSUNKEN_BORDER | wxTR_HAS_VARIABLE_ROW_HEIGHT
@ -53,7 +41,7 @@ sub new {
# buttons # buttons
$self->{btn_load_part} = 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_load_modifier} = Wx::Button->new($self, -1, "Load modifier…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_load_lambda_modifier} = Wx::Button->new($self, -1, "Load generic…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); $self->{btn_load_lambda_modifier} = Wx::Button->new($self, -1, "Create modifier…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_delete} = Wx::Button->new($self, -1, "Delete part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); $self->{btn_delete} = Wx::Button->new($self, -1, "Delete part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
if ($Slic3r::GUI::have_button_icons) { if ($Slic3r::GUI::have_button_icons) {
$self->{btn_load_part}->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));
@ -88,8 +76,9 @@ sub new {
# genates tens of events for a single value change. # genates tens of events for a single value change.
# Only trigger the recalculation if the value changes # Only trigger the recalculation if the value changes
# or a live preview was activated and the mesh cut is not valid yet. # or a live preview was activated and the mesh cut is not valid yet.
if ($self->{move_options}{$opt_id} != $optgroup_movers->get_value($opt_id)) { my $new = Slic3r::Pointf3->new(map $optgroup_movers->get_value($_), qw(x y z));
$self->{move_options}{$opt_id} = $optgroup_movers->get_value($opt_id); if ($self->{move_target}->distance_to($new) > 0) {
$self->{move_target} = $new;
wxTheApp->CallAfter(sub { wxTheApp->CallAfter(sub {
$self->_update; $self->_update;
}); });
@ -102,8 +91,6 @@ sub new {
type => 'slider', type => 'slider',
label => 'X', label => 'X',
default => 0, default => 0,
min => -($self->{model_object}->bounding_box->size->x)*4,
max => $self->{model_object}->bounding_box->size->x*4,
full_width => 1, full_width => 1,
)); ));
$optgroup_movers->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_movers->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
@ -111,8 +98,6 @@ sub new {
type => 'slider', type => 'slider',
label => 'Y', label => 'Y',
default => 0, default => 0,
min => -($self->{model_object}->bounding_box->size->y)*4,
max => $self->{model_object}->bounding_box->size->y*4,
full_width => 1, full_width => 1,
)); ));
$optgroup_movers->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( $optgroup_movers->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
@ -120,13 +105,11 @@ sub new {
type => 'slider', type => 'slider',
label => 'Z', label => 'Z',
default => 0, default => 0,
min => -($self->{model_object}->bounding_box->size->z)*4,
max => $self->{model_object}->bounding_box->size->z*4,
full_width => 1, full_width => 1,
)); ));
# left pane with tree # left pane with tree
my $left_sizer = Wx::BoxSizer->new(wxVERTICAL); my $left_sizer = $self->{left_sizer} = Wx::BoxSizer->new(wxVERTICAL);
$left_sizer->Add($tree, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10); $left_sizer->Add($tree, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
$left_sizer->Add($buttons_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10); $left_sizer->Add($buttons_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
$left_sizer->Add($settings_sizer, 1, wxEXPAND | wxALL, 0); $left_sizer->Add($settings_sizer, 1, wxEXPAND | wxALL, 0);
@ -249,16 +232,7 @@ sub selection_changed {
$self->{optgroup_movers}->set_value("x", 0); $self->{optgroup_movers}->set_value("x", 0);
$self->{optgroup_movers}->set_value("y", 0); $self->{optgroup_movers}->set_value("y", 0);
$self->{optgroup_movers}->set_value("z", 0); $self->{optgroup_movers}->set_value("z", 0);
$self->{move_options} = { $self->{move_target} = Slic3r::Pointf3->new;
x => 0,
y => 0,
z => 0,
};
$self->{last_coords} = {
x => 0,
y => 0,
z => 0,
};
if (my $itemData = $self->get_selection) { if (my $itemData = $self->get_selection) {
my ($config, @opt_keys); my ($config, @opt_keys);
@ -273,9 +247,21 @@ sub selection_changed {
my $volume = $self->{model_object}->volumes->[ $itemData->{volume_id} ]; my $volume = $self->{model_object}->volumes->[ $itemData->{volume_id} ];
if ($volume->modifier) { if ($volume->modifier) {
$self->{optgroup_movers}->enable; my $movers = $self->{optgroup_movers};
my $obj_bb = $self->{model_object}->raw_bounding_box;
my $vol_bb = $volume->mesh->bounding_box;
my $vol_size = $vol_bb->size;
$movers->get_field('x')->set_range($obj_bb->x_min - $vol_size->x, $obj_bb->x_max);
$movers->get_field('y')->set_range($obj_bb->y_min - $vol_size->y, $obj_bb->y_max); #,,
$movers->get_field('z')->set_range($obj_bb->z_min - $vol_size->z, $obj_bb->z_max);
$movers->get_field('x')->set_value($vol_bb->x_min);
$movers->get_field('y')->set_value($vol_bb->y_min);
$movers->get_field('z')->set_value($vol_bb->z_min);
$self->{left_sizer}->Show($movers->sizer);
} else { } else {
$self->{optgroup_movers}->disable; $self->{left_sizer}->Hide($self->{optgroup_movers}->sizer);
} }
$config = $volume->config; $config = $volume->config;
$self->{staticbox}->SetLabel('Part Settings'); $self->{staticbox}->SetLabel('Part Settings');
@ -286,7 +272,7 @@ sub selection_changed {
# select nothing in 3D preview # select nothing in 3D preview
# attach object config to settings panel # attach object config to settings panel
$self->{optgroup_movers}->disable; $self->{left_sizer}->Hide($self->{optgroup_movers}->sizer);
$self->{staticbox}->SetLabel('Object Settings'); $self->{staticbox}->SetLabel('Object Settings');
@opt_keys = (map @{$_->get_keys}, Slic3r::Config::PrintObject->new, Slic3r::Config::PrintRegion->new); @opt_keys = (map @{$_->get_keys}, Slic3r::Config::PrintObject->new, Slic3r::Config::PrintRegion->new);
$config = $self->{model_object}->config; $config = $self->{model_object}->config;
@ -352,15 +338,24 @@ sub on_btn_lambda {
my $mesh; my $mesh;
if ($type eq "box") { if ($type eq "box") {
$mesh = Slic3r::TriangleMesh::make_cube($params->{"dim"}[0], $params->{"dim"}[1], $params->{"dim"}[2]); $mesh = Slic3r::TriangleMesh::make_cube(@{$params->{"dim"}});
} elsif ($type eq "cylinder") { } elsif ($type eq "cylinder") {
$mesh = Slic3r::TriangleMesh::make_cylinder($params->{"cyl_r"}, $params->{"cyl_h"}); $mesh = Slic3r::TriangleMesh::make_cylinder($params->{"cyl_r"}, $params->{"cyl_h"});
} elsif ($type eq "sphere") { } elsif ($type eq "sphere") {
$mesh = Slic3r::TriangleMesh::make_sphere($params->{"sph_rho"}); $mesh = Slic3r::TriangleMesh::make_sphere($params->{"sph_rho"});
} elsif ($type eq "slab") { } elsif ($type eq "slab") {
$mesh = Slic3r::TriangleMesh::make_cube($self->{model_object}->bounding_box->size->x*1.5, $self->{model_object}->bounding_box->size->y*1.5, $params->{"slab_h"}); #** my $size = $self->{model_object}->bounding_box->size;
# box sets the base coordinate at 0,0, move to center of plate and move it up to initial_z $mesh = Slic3r::TriangleMesh::make_cube(
$mesh->translate(-$self->{model_object}->bounding_box->size->x*1.5/2.0, -$self->{model_object}->bounding_box->size->y*1.5/2.0, $params->{"slab_z"}); #** $size->x*1.5,
$size->y*1.5, #**
$params->{"slab_h"},
);
# box sets the base coordinate at 0,0, move to center of plate
$mesh->translate(
-$size->x*1.5/2.0,
-$size->y*1.5/2.0, #**
0,
);
} else { } else {
return; return;
} }
@ -373,7 +368,7 @@ sub on_btn_lambda {
$new_volume->config->set_ifndef('extruder', 0); $new_volume->config->set_ifndef('extruder', 0);
$self->{parts_changed} = 1; $self->{parts_changed} = 1;
$self->_parts_changed; $self->_parts_changed($self->{model_object}->volumes_count-1);
} }
sub on_btn_delete { sub on_btn_delete {
@ -397,9 +392,9 @@ sub on_btn_delete {
} }
sub _parts_changed { sub _parts_changed {
my ($self) = @_; my ($self, $selected_volume_idx) = @_;
$self->reload_tree; $self->reload_tree($selected_volume_idx);
if ($self->{canvas}) { if ($self->{canvas}) {
$self->{canvas}->reset_objects; $self->{canvas}->reset_objects;
$self->{canvas}->load_object($self->{model_object}); $self->{canvas}->load_object($self->{model_object});
@ -436,17 +431,11 @@ sub PartSettingsChanged {
sub _update { sub _update {
my ($self) = @_; my ($self) = @_;
my ($m_x, $m_y, $m_z) = ($self->{move_options}{x}, $self->{move_options}{y}, $self->{move_options}{z});
my ($l_x, $l_y, $l_z) = ($self->{last_coords}{x}, $self->{last_coords}{y}, $self->{last_coords}{z});
my $itemData = $self->get_selection; my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') { if ($itemData && $itemData->{type} eq 'volume') {
my $d = Slic3r::Pointf3->new($m_x - $l_x, $m_y - $l_y, $m_z - $l_z);
my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}]; my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
$volume->mesh->translate(@{$d}); $volume->mesh->translate(@{ $volume->mesh->bounding_box->min_point->vector_to($self->{move_target}) });
$self->{last_coords}{x} = $m_x;
$self->{last_coords}{y} = $m_y;
$self->{last_coords}{z} = $m_z;
} }
$self->{parts_changed} = 1; $self->{parts_changed} = 1;