2013-03-10 11:33:10 +00:00
package Slic3r::GUI::Plater::ObjectDialog ;
2013-03-10 11:46:54 +00:00
use strict ;
use warnings ;
use utf8 ;
use Wx qw( :dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL ) ;
2013-03-10 13:58:49 +00:00
use Wx::Event qw( EVT_BUTTON ) ;
2013-03-10 11:33:10 +00:00
use base 'Wx::Dialog' ;
sub new {
my $ class = shift ;
my ( $ parent , % params ) = @ _ ;
2013-07-13 18:23:03 +00:00
my $ self = $ class - > SUPER:: new ( $ parent , - 1 , "Object" , wxDefaultPosition , [ 500 , 500 ] , wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) ;
2013-03-10 11:33:10 +00:00
$ self - > { object } = $ params { object } ;
2013-03-10 11:46:54 +00:00
$ self - > { tabpanel } = Wx::Notebook - > new ( $ self , - 1 , wxDefaultPosition , wxDefaultSize , wxNB_TOP | wxTAB_TRAVERSAL ) ;
2013-05-17 12:14:33 +00:00
$ self - > { tabpanel } - > AddPage ( $ self - > { preview } = Slic3r::GUI::Plater::ObjectDialog::PreviewTab - > new ( $ self - > { tabpanel } , object = > $ self - > { object } ) , "Preview" )
if $ Slic3r:: GUI:: have_OpenGL ;
2013-03-10 13:58:49 +00:00
$ self - > { tabpanel } - > AddPage ( $ self - > { info } = Slic3r::GUI::Plater::ObjectDialog::InfoTab - > new ( $ self - > { tabpanel } , object = > $ self - > { object } ) , "Info" ) ;
$ self - > { tabpanel } - > AddPage ( $ self - > { layers } = Slic3r::GUI::Plater::ObjectDialog::LayersTab - > new ( $ self - > { tabpanel } , object = > $ self - > { object } ) , "Layers" ) ;
2013-03-10 11:46:54 +00:00
my $ buttons = $ self - > CreateStdDialogButtonSizer ( wxOK ) ;
2013-03-10 13:58:49 +00:00
EVT_BUTTON ( $ self , wxID_OK , sub {
# validate user input
return if ! $ self - > { layers } - > CanClose ;
# notify tabs
$ self - > { layers } - > Closing ;
$ self - > EndModal ( wxID_OK ) ;
} ) ;
2013-03-10 11:46:54 +00:00
my $ sizer = Wx::BoxSizer - > new ( wxVERTICAL ) ;
$ sizer - > Add ( $ self - > { tabpanel } , 1 , wxEXPAND | wxTOP | wxLEFT | wxRIGHT , 10 ) ;
$ sizer - > Add ( $ buttons , 0 , wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT , 10 ) ;
$ self - > SetSizer ( $ sizer ) ;
2013-05-17 12:14:33 +00:00
$ self - > SetMinSize ( $ self - > GetSize ) ;
2013-03-10 11:46:54 +00:00
return $ self ;
}
2013-03-10 11:33:10 +00:00
2013-03-10 11:46:54 +00:00
package Slic3r::GUI::Plater::ObjectDialog::InfoTab ;
use Wx qw( :dialog :id :misc :sizer :systemsettings ) ;
use base 'Wx::Panel' ;
sub new {
my $ class = shift ;
my ( $ parent , % params ) = @ _ ;
my $ self = $ class - > SUPER:: new ( $ parent , - 1 , wxDefaultPosition , wxDefaultSize ) ;
2013-03-10 13:58:49 +00:00
$ self - > { object } = $ params { object } ;
2013-03-10 11:46:54 +00:00
2013-07-13 18:23:03 +00:00
my $ grid_sizer = Wx::FlexGridSizer - > new ( 3 , 2 , 5 , 5 ) ;
2013-03-10 11:33:10 +00:00
$ grid_sizer - > SetFlexibleDirection ( wxHORIZONTAL ) ;
$ grid_sizer - > AddGrowableCol ( 1 ) ;
my $ label_font = Wx::SystemSettings:: GetFont ( wxSYS_DEFAULT_GUI_FONT ) ;
$ label_font - > SetPointSize ( 10 ) ;
my $ properties = $ self - > get_properties ;
foreach my $ property ( @$ properties ) {
2013-03-10 11:46:54 +00:00
my $ label = Wx::StaticText - > new ( $ self , - 1 , $ property - > [ 0 ] . ":" ) ;
my $ value = Wx::StaticText - > new ( $ self , - 1 , $ property - > [ 1 ] ) ;
2013-03-10 11:33:10 +00:00
$ label - > SetFont ( $ label_font ) ;
$ grid_sizer - > Add ( $ label , 1 , wxALIGN_BOTTOM ) ;
$ grid_sizer - > Add ( $ value , 0 ) ;
}
2013-03-10 11:46:54 +00:00
$ self - > SetSizer ( $ grid_sizer ) ;
$ grid_sizer - > SetSizeHints ( $ self ) ;
2013-03-10 11:33:10 +00:00
return $ self ;
}
sub get_properties {
my $ self = shift ;
2013-03-10 13:58:49 +00:00
my $ object = $ self - > { object } ;
2013-07-13 18:23:03 +00:00
my $ properties = [
2013-03-10 11:46:54 +00:00
[ 'Name' = > $ object - > name ] ,
2013-06-07 21:16:02 +00:00
[ 'Size' = > sprintf "%.2f x %.2f x %.2f" , @ { $ object - > transformed_size } ] ,
2013-03-10 11:46:54 +00:00
[ 'Facets' = > $ object - > facets ] ,
[ 'Vertices' = > $ object - > vertices ] ,
[ 'Materials' = > $ object - > materials ] ,
2013-03-10 11:33:10 +00:00
] ;
2013-07-13 18:23:03 +00:00
if ( my $ stats = $ object - > mesh_stats ) {
push @$ properties ,
[ 'Shells' = > $ stats - > { number_of_parts } ] ,
[ 'Volume' = > sprintf ( '%.2f' , $ stats - > { volume } * ( $ object - > scale ** 3 ) ) ] ,
[ 'Degenerate facets' = > $ stats - > { degenerate_facets } ] ,
[ 'Edges fixed' = > $ stats - > { edges_fixed } ] ,
[ 'Facets removed' = > $ stats - > { facets_removed } ] ,
[ 'Facets added' = > $ stats - > { facets_added } ] ,
[ 'Facets reversed' = > $ stats - > { facets_reversed } ] ,
[ 'Backwards edges' = > $ stats - > { backwards_edges } ] ,
# we don't show normals_fixed because we never provide normals
# to admesh, so it generates normals for all facets
;
} else {
push @$ properties ,
[ 'Two-Manifold' = > $ object - > is_manifold ? 'Yes' : 'No' ] ,
;
}
return $ properties ;
2013-03-10 11:33:10 +00:00
}
2013-05-16 10:01:38 +00:00
package Slic3r::GUI::Plater::ObjectDialog::PreviewTab ;
use Wx qw( :dialog :id :misc :sizer :systemsettings ) ;
use base 'Wx::Panel' ;
sub new {
my $ class = shift ;
my ( $ parent , % params ) = @ _ ;
my $ self = $ class - > SUPER:: new ( $ parent , - 1 , wxDefaultPosition , wxDefaultSize ) ;
$ self - > { object } = $ params { object } ;
my $ sizer = Wx::BoxSizer - > new ( wxVERTICAL ) ;
2013-05-17 12:14:33 +00:00
$ sizer - > Add ( Slic3r::GUI::PreviewCanvas - > new ( $ self , $ self - > { object } - > get_model_object - > mesh ) , 1 , wxEXPAND , 0 ) ;
2013-05-16 10:01:38 +00:00
$ self - > SetSizer ( $ sizer ) ;
$ sizer - > SetSizeHints ( $ self ) ;
return $ self ;
}
2013-03-10 13:58:49 +00:00
package Slic3r::GUI::Plater::ObjectDialog::LayersTab ;
use Wx qw( :dialog :id :misc :sizer :systemsettings ) ;
use Wx::Grid ;
use Wx::Event qw( EVT_GRID_CELL_CHANGED ) ;
use base 'Wx::Panel' ;
sub new {
my $ class = shift ;
my ( $ parent , % params ) = @ _ ;
my $ self = $ class - > SUPER:: new ( $ parent , - 1 , wxDefaultPosition , wxDefaultSize ) ;
$ self - > { object } = $ params { object } ;
my $ sizer = Wx::BoxSizer - > new ( wxVERTICAL ) ;
{
2013-03-24 14:26:55 +00:00
my $ label = Wx::StaticText - > new ( $ self , - 1 , "You can use this section to override the default layer height for parts of this object. Set layer height to zero to skip portions of the input file." ,
2013-03-10 13:58:49 +00:00
wxDefaultPosition , [ - 1 , 25 ] ) ;
$ label - > SetFont ( Wx::SystemSettings:: GetFont ( wxSYS_DEFAULT_GUI_FONT ) ) ;
$ sizer - > Add ( $ label , 0 , wxEXPAND | wxALL , 10 ) ;
}
my $ grid = $ self - > { grid } = Wx::Grid - > new ( $ self , - 1 , wxDefaultPosition , wxDefaultSize ) ;
$ sizer - > Add ( $ grid , 1 , wxEXPAND | wxALL , 10 ) ;
$ grid - > CreateGrid ( 0 , 3 ) ;
$ grid - > DisableDragRowSize ;
2013-03-11 19:00:12 +00:00
$ grid - > HideRowLabels if & Wx:: wxVERSION_STRING !~ / 2\.8\./ ;
2013-03-12 09:28:51 +00:00
$ grid - > SetColLabelValue ( 0 , "Min Z (mm)" ) ;
$ grid - > SetColLabelValue ( 1 , "Max Z (mm)" ) ;
$ grid - > SetColLabelValue ( 2 , "Layer height (mm)" ) ;
$ grid - > SetColSize ( $ _ , 135 ) for 0 .. 2 ;
2013-03-10 13:58:49 +00:00
$ grid - > SetDefaultCellAlignment ( wxALIGN_CENTRE , wxALIGN_CENTRE ) ;
# load data
foreach my $ range ( @ { $ self - > { object } - > layer_height_ranges } ) {
$ grid - > AppendRows ( 1 ) ;
my $ i = $ grid - > GetNumberRows - 1 ;
$ grid - > SetCellValue ( $ i , $ _ , $ range - > [ $ _ ] ) for 0 .. 2 ;
}
$ grid - > AppendRows ( 1 ) ; # append one empty row
EVT_GRID_CELL_CHANGED ( $ grid , sub {
my ( $ grid , $ event ) = @ _ ;
# remove any non-numeric character
my $ value = $ grid - > GetCellValue ( $ event - > GetRow , $ event - > GetCol ) ;
$ value =~ s/,/./g ;
$ value =~ s/[^0-9.]//g ;
$ grid - > SetCellValue ( $ event - > GetRow , $ event - > GetCol , $ value ) ;
# if there's no empty row, let's append one
for my $ i ( 0 .. $ grid - > GetNumberRows - 1 ) {
if ( ! grep $ grid - > GetCellValue ( $ i , $ _ ) , 0 .. 2 ) {
return ;
}
}
$ grid - > AppendRows ( 1 ) ;
} ) ;
$ self - > SetSizer ( $ sizer ) ;
$ sizer - > SetSizeHints ( $ self ) ;
return $ self ;
}
sub CanClose {
my $ self = shift ;
# validate ranges before allowing user to dismiss the dialog
foreach my $ range ( $ self - > _get_ranges ) {
my ( $ min , $ max , $ height ) = @$ range ;
if ( $ max <= $ min ) {
Slic3r::GUI:: show_error ( $ self , "Invalid Z range $min-$max." ) ;
return 0 ;
}
if ( $ min < 0 || $ max < 0 ) {
Slic3r::GUI:: show_error ( $ self , "Invalid Z range $min-$max." ) ;
return 0 ;
}
2013-03-24 14:26:55 +00:00
if ( $ height < 0 ) {
2013-03-10 13:58:49 +00:00
Slic3r::GUI:: show_error ( $ self , "Invalid layer height $height." ) ;
return 0 ;
}
# TODO: check for overlapping ranges
}
return 1 ;
}
sub Closing {
my $ self = shift ;
# save ranges into the plater object
$ self - > { object } - > layer_height_ranges ( [ $ self - > _get_ranges ] ) ;
}
sub _get_ranges {
my $ self = shift ;
my @ ranges = ( ) ;
for my $ i ( 0 .. $ self - > { grid } - > GetNumberRows - 1 ) {
my ( $ min , $ max , $ height ) = map $ self - > { grid } - > GetCellValue ( $ i , $ _ ) , 0 .. 2 ;
next if $ min eq '' || $ max eq '' || $ height eq '' ;
push @ ranges , [ $ min , $ max , $ height ] ;
}
return sort { $ a - > [ 0 ] <=> $ b - > [ 0 ] } @ ranges ;
}
2013-03-10 11:33:10 +00:00
1 ;