diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 5f4357a95c..f97444139e 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -8,9 +8,11 @@ package Slic3r; use strict; use warnings; +use Config; require v5.10; our $VERSION = VERSION(); +our $BUILD = BUILD(); our $FORK_NAME = FORK_NAME(); our $debug = 0; @@ -341,6 +343,74 @@ sub open { return CORE::open $$fh, $mode, encode_path($filename); } +sub tags { + my ($format) = @_; + $format //= ''; + my %tags; + # End of line + $tags{eol} = ($format eq 'html') ? '
' : "\n"; + # Heading + $tags{h2start} = ($format eq 'html') ? '

' : ''; + $tags{h2end} = ($format eq 'html') ? '

' : ''; + # Bold font + $tags{bstart} = ($format eq 'html') ? '' : ''; + $tags{bend} = ($format eq 'html') ? '' : ''; + # Verbatim + $tags{vstart} = ($format eq 'html') ? '
'  : '';
+    $tags{vend}    = ($format eq 'html') ? '
' : ''; + return %tags; +} + +sub slic3r_info +{ + my (%params) = @_; + my %tag = Slic3r::tags($params{format}); + my $out = ''; + $out .= "$tag{bstart}$Slic3r::FORK_NAME$tag{bend}$tag{eol}"; + $out .= "$tag{bstart}Version: $tag{bend}$Slic3r::VERSION$tag{eol}"; + $out .= "$tag{bstart}Build: $tag{bend}$Slic3r::BUILD$tag{eol}"; + return $out; +} + +sub copyright_info +{ + my (%params) = @_; + my %tag = Slic3r::tags($params{format}); + my $out = + 'Copyright © 2016 Vojtech Bubnik, Prusa Research.
' . + 'Copyright © 2011-2016 Alessandro Ranellucci.
' . + 'Slic3r is licensed under the ' . + 'GNU Affero General Public License, version 3.' . + '


' . + 'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Y. Sapir, Mike Sheldrake and numerous others. ' . + 'Manual by Gary Hodgson. Inspired by the RepRap community.
' . + 'Slic3r logo designed by Corey Daniels, Silk Icon Set designed by Mark James. '; + return $out; +} + +sub system_info +{ + my (%params) = @_; + my %tag = Slic3r::tags($params{format}); + + my $out = ''; + $out .= "$tag{bstart}Operating System: $tag{bend}$Config{osname}$tag{eol}"; + $out .= "$tag{bstart}System Architecture: $tag{bend}$Config{archname}$tag{eol}"; + if ($^O eq 'MSWin32') { + $out .= "$tag{bstart}Windows Version: $tag{bend}" . `ver` . $tag{eol}; + } else { + # Hopefully some kind of unix / linux. + $out .= "$tag{bstart}System Version: $tag{bend}" . `uname -a` . $tag{eol}; + } + $out .= $tag{vstart} . Config::myconfig . $tag{vend}; + $out .= " $tag{bstart}\@INC:$tag{bend}$tag{eol}$tag{vstart}"; + foreach my $i (@INC) { + $out .= " $i\n"; + } + $out .= "$tag{vend}"; + return $out; +} + # this package declaration prevents an ugly fatal warning to be emitted when # spawning a new thread package GLUquadricObjPtr; diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 56cf1a0a1e..b784cf3db5 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -32,6 +32,7 @@ use Slic3r::GUI::Projector; use Slic3r::GUI::OptionsGroup; use Slic3r::GUI::OptionsGroup::Field; use Slic3r::GUI::SimpleTab; +use Slic3r::GUI::SystemInfo; use Slic3r::GUI::Tab; our $have_OpenGL = eval "use Slic3r::GUI::3DScene; 1"; @@ -220,6 +221,31 @@ sub about { $about->Destroy; } +sub system_info { + my ($self) = @_; + + my $slic3r_info = Slic3r::slic3r_info(format => 'html'); + my $copyright_info = Slic3r::copyright_info(format => 'html'); + my $system_info = Slic3r::system_info(format => 'html'); + my $opengl_info; + my $opengl_info_txt = ''; + if (defined($self->{mainframe}) && defined($self->{mainframe}->{plater}) && + defined($self->{mainframe}->{plater}->{canvas3D})) { + $opengl_info = $self->{mainframe}->{plater}->{canvas3D}->opengl_info(format => 'html'); + $opengl_info_txt = $self->{mainframe}->{plater}->{canvas3D}->opengl_info; + } + my $about = Slic3r::GUI::SystemInfo->new( + parent => undef, + slic3r_info => $slic3r_info, +# copyright_info => $copyright_info, + system_info => $system_info, + opengl_info => $opengl_info, + text_info => Slic3r::slic3r_info . Slic3r::system_info . $opengl_info_txt, + ); + $about->ShowModal; + $about->Destroy; +} + # static method accepting a wxWindow object as first parameter sub catch_error { my ($self, $cb, $message_dialog) = @_; diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index e7a3791b88..9c8e1a4402 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -1492,6 +1492,49 @@ sub draw_active_object_annotations { glEnable(GL_DEPTH_TEST); } +sub opengl_info +{ + my ($self, %params) = @_; + my %tag = Slic3r::tags($params{format}); + + my $gl_version = glGetString(GL_VERSION); + my $gl_vendor = glGetString(GL_VENDOR); + my $gl_renderer = glGetString(GL_RENDERER); + my $glsl_version_ARB = glGetString(GL_SHADING_LANGUAGE_VERSION_ARB) // ''; + my $glsl_version = glGetString(GL_SHADING_LANGUAGE_VERSION) // $glsl_version_ARB; + $glsl_version .= 'ARB(' . $glsl_version_ARB . ')' if ($glsl_version_ARB ne '' && $glsl_version ne $glsl_version_ARB); + + my $out = ''; + $out .= "$tag{h2start}OpenGL installation$tag{h2end}$tag{eol}"; + $out .= " $tag{bstart}Using POGL$tag{bend} v$OpenGL::BUILD_VERSION$tag{eol}"; + $out .= " $tag{bstart}GL version: $tag{bend}${gl_version}$tag{eol}"; + $out .= " $tag{bstart}vendor: $tag{bend}${gl_vendor}$tag{eol}"; + $out .= " $tag{bstart}renderer: $tag{bend}${gl_renderer}$tag{eol}"; + $out .= " $tag{bstart}GLSL version: $tag{bend}${glsl_version}$tag{eol}"; + + # Check for required OpenGL extensions + $out .= "$tag{h2start}Required extensions (* implemented):$tag{h2end}$tag{eol}"; + my @extensions_required = qw(GL_ARB_shader_objects GL_ARB_fragment_shader GL_ARB_vertex_shader GL_ARB_shading_language_100); + foreach my $ext (sort @extensions_required) { + my $stat = glpCheckExtension($ext); + $out .= sprintf("%s ${ext}$tag{eol}", $stat?' ':'*'); + $out .= sprintf(" ${stat}$tag{eol}") if ($stat && $stat !~ m|^$ext |); + } + # Check for other OpenGL extensions + $out .= "$tag{h2start}Installed extensions (* implemented in the module):$tag{h2end}$tag{eol}"; + my $extensions = glGetString(GL_EXTENSIONS); + my @extensions = split(' ',$extensions); + foreach my $ext (sort @extensions) { + if(! grep(/^$extensions$/, @extensions_required)) { + my $stat = glpCheckExtension($ext); + $out .= sprintf("%s ${ext}$tag{eol}", $stat?' ':'*'); + $out .= sprintf(" ${stat}$tag{eol}") if ($stat && $stat !~ m|^$ext |); + } + } + + return $out; +} + sub _report_opengl_state { my ($self, $comment) = @_; diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 4fea8f5cc6..1e439963cb 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -331,6 +331,12 @@ sub _init_menubar { Wx::LaunchDefaultBrowser('http://manual.slic3r.org/'); }); $helpMenu->AppendSeparator(); + $self->_append_menu_item($helpMenu, "System Info", 'Show system information', sub { + wxTheApp->system_info; + }); + $self->_append_menu_item($helpMenu, "Report an Issue", 'Report an issue on the Slic3r Prusa Edition', sub { + Wx::LaunchDefaultBrowser('http://github.com/prusa3d/slic3r/issues/new'); + }); $self->_append_menu_item($helpMenu, "&About Slic3r", 'Show about dialog', sub { wxTheApp->about; }); diff --git a/lib/Slic3r/GUI/SystemInfo.pm b/lib/Slic3r/GUI/SystemInfo.pm new file mode 100644 index 0000000000..23a85952cd --- /dev/null +++ b/lib/Slic3r/GUI/SystemInfo.pm @@ -0,0 +1,70 @@ +package Slic3r::GUI::SystemInfo; +use strict; +use warnings; +use utf8; + +use Wx qw(:font :html :misc :dialog :sizer :systemsettings :frame :id wxTheClipboard); +use Wx::Event qw(EVT_HTML_LINK_CLICKED EVT_LEFT_DOWN EVT_BUTTON); +use Wx::Html; +use base 'Wx::Dialog'; + +sub new { + my ($class, %params) = @_; + my $self = $class->SUPER::new($params{parent}, -1, 'Slic3r Prusa Edition - System Information', wxDefaultPosition, [600, 340], + wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxRESIZE_BORDER); + $self->{text_info} = $params{text_info}; + + $self->SetBackgroundColour(Wx::wxWHITE); + my $vsizer = Wx::BoxSizer->new(wxVERTICAL); + $self->SetSizer($vsizer); + + # text + my $text = + '' . + '' . + ($params{slic3r_info} // '') . + ($params{copyright_info} // '') . + ($params{system_info} // '') . + ($params{opengl_info} // '') . + '' . + ''; + my $html = $self->{html} = Wx::HtmlWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + my $font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); +# my $size = &Wx::wxMSW ? 8 : 10; +# $html->SetFonts($font->GetFaceName, $font->GetFaceName, [$size, $size, $size, $size, $size, $size, $size]); + $html->SetBorders(2); + $html->SetPage($text); + $vsizer->Add($html, 1, wxEXPAND | wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 20); + EVT_HTML_LINK_CLICKED($self, $html, \&link_clicked); + + my $buttons = $self->CreateStdDialogButtonSizer(wxOK); + my $btn_copy_to_clipboard = Wx::Button->new($self, -1, "Copy to Clipboard", wxDefaultPosition, wxDefaultSize); + $buttons->Insert(0, $btn_copy_to_clipboard, 0, wxLEFT, 5); + EVT_BUTTON($self, $btn_copy_to_clipboard, \©_to_clipboard); + $self->SetEscapeId(wxID_CLOSE); + EVT_BUTTON($self, wxID_CLOSE, sub { + $self->EndModal(wxID_CLOSE); + $self->Close; + }); +# $vsizer->Add($buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3); + $vsizer->Add($buttons, 0, wxEXPAND | wxALL, 3); + + return $self; +} + +sub link_clicked { + my ($self, $event) = @_; + + Wx::LaunchDefaultBrowser($event->GetLinkInfo->GetHref); + $event->Skip(0); +} + +sub copy_to_clipboard { + my ($self, $event) = @_; + my $data = $self->{text_info}; + wxTheClipboard->Open; + wxTheClipboard->SetData(Wx::TextDataObject->new($data)); + wxTheClipboard->Close; +} + +1; diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index 82d20a8542..c1223f5c27 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -15,6 +15,7 @@ #define SLIC3R_FORK_NAME "Slic3r Prusa Edition" #define SLIC3R_VERSION "1.31.6" +#define SLIC3R_BUILD "UNKNOWN" //FIXME This epsilon value is used for many non-related purposes: // For a threshold of a squared Euclidean distance, diff --git a/xs/xsp/XS.xsp b/xs/xsp/XS.xsp index 20c9d4154f..bf4a3733e0 100644 --- a/xs/xsp/XS.xsp +++ b/xs/xsp/XS.xsp @@ -17,6 +17,12 @@ VERSION() RETVAL = newSVpv(SLIC3R_VERSION, 0); OUTPUT: RETVAL +SV* +BUILD() + CODE: + RETVAL = newSVpv(SLIC3R_BUILD, 0); + OUTPUT: RETVAL + SV* DEBUG_OUT_PATH_PREFIX() CODE: