ObjectRotateFaceDialog.pm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # Rotate an object such that a face is aligned with a specified plane.
  2. # This dialog gets opened with the "Rotate face" button above the platter.
  3. package Slic3r::GUI::Plater::ObjectRotateFaceDialog;
  4. use strict;
  5. use warnings;
  6. use utf8;
  7. use POSIX qw(ceil);
  8. use Scalar::Util qw(looks_like_number);
  9. use Slic3r::Geometry qw(PI X Y Z);
  10. use Wx qw(wxTheApp :dialog :id :misc :sizer wxTAB_TRAVERSAL);
  11. use Wx::Event qw(EVT_CLOSE EVT_BUTTON);
  12. use base 'Wx::Dialog';
  13. sub new {
  14. my $class = shift;
  15. my ($parent, %params) = @_;
  16. my $self = $class->SUPER::new($parent, -1, $params{object}->name, wxDefaultPosition, [500,500], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
  17. $self->{model_object_idx} = $params{model_object_idx};
  18. $self->{model_object} = $params{model_object};
  19. $self->{normal} = undef;
  20. # Note whether the window was already closed, so a pending update is not executed.
  21. $self->{already_closed} = 0;
  22. $self->{model_object}->transform_by_instance($self->{model_object}->get_instance(0), 1);
  23. # Options
  24. $self->{options} = {
  25. axis => Z,
  26. };
  27. my $optgroup;
  28. $optgroup = $self->{optgroup} = Slic3r::GUI::OptionsGroup->new(
  29. parent => $self,
  30. title => 'Rotate to Align Face with Plane',
  31. on_change => sub {
  32. my ($opt_id) = @_;
  33. if ($self->{options}{$opt_id} != $optgroup->get_value($opt_id)){
  34. $self->{options}{$opt_id} = $optgroup->get_value($opt_id);
  35. }
  36. },
  37. label_width => 120,
  38. );
  39. $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
  40. opt_id => 'axis',
  41. type => 'select',
  42. label => 'Plane',
  43. labels => ['YZ','XZ','XY'],
  44. values => [X,Y,Z],
  45. default => $self->{options}{axis},
  46. ));
  47. {
  48. my $button_sizer = Wx::BoxSizer->new(wxVERTICAL);
  49. $self->{btn_rot} = Wx::Button->new($self, -1, "Rotate to Plane", wxDefaultPosition, wxDefaultSize);
  50. $self->{btn_rot}->SetDefault;
  51. $self->{btn_rot}->Disable;
  52. $button_sizer->Add($self->{btn_rot}, 0, wxALIGN_RIGHT | wxALL, 10);
  53. $optgroup->append_line(Slic3r::GUI::OptionsGroup::Line->new(
  54. sizer => $button_sizer,
  55. ));
  56. }
  57. # left pane with tree
  58. my $left_sizer = Wx::BoxSizer->new(wxVERTICAL);
  59. $left_sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
  60. # right pane with preview canvas
  61. my $canvas;
  62. if ($Slic3r::GUI::have_OpenGL) {
  63. $canvas = $self->{canvas} = Slic3r::GUI::3DScene->new($self);
  64. $canvas->load_object($self->{model_object}, undef, [0]);
  65. $canvas->set_auto_bed_shape;
  66. $canvas->SetSize([500,500]);
  67. $canvas->enable_picking(1);
  68. $canvas->enable_face_select(1);
  69. $canvas->SetMinSize($canvas->GetSize);
  70. $canvas->zoom_to_volumes;
  71. $canvas->on_select(sub {
  72. my ($volume_idx) = @_;
  73. $self->{btn_rot}->Disable;
  74. $self->{normal} = $canvas->calculate_normal($volume_idx);
  75. $self->{btn_rot}->Enable if defined $self->{normal};
  76. });
  77. }
  78. $self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
  79. $self->{sizer}->Add($left_sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
  80. $self->{sizer}->Add($canvas, 1, wxEXPAND | wxALL, 0) if $canvas;
  81. $self->SetSizer($self->{sizer});
  82. $self->SetMinSize($self->GetSize);
  83. $self->{sizer}->SetSizeHints($self);
  84. EVT_BUTTON($self, $self->{btn_rot}, sub {
  85. $self->{already_closed} = 1;
  86. $self->EndModal(wxID_OK);
  87. $self->Destroy();
  88. });
  89. EVT_CLOSE($self, sub {
  90. # Note that the window was already closed, so a pending update will not be executed.
  91. $self->{already_closed} = 1;
  92. $self->EndModal(wxID_CANCEL);
  93. $self->Destroy();
  94. });
  95. return $self;
  96. }
  97. sub SelectedNormal {
  98. my ($self) = @_;
  99. return $self->{normal};
  100. }
  101. sub SelectedAxis {
  102. my ($self) = @_;
  103. return $self->{options}->{axis};
  104. }
  105. 1;