Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt42
-rw-r--r--src/PrusaSlicer.cpp11
-rw-r--r--src/slic3r/CMakeLists.txt2
-rw-r--r--src/slic3r/GUI/MainFrame.cpp25
-rw-r--r--src/slic3r/Utils/Process.cpp125
-rw-r--r--src/slic3r/Utils/Process.hpp19
-rw-r--r--src/slic3r/Utils/Thread.hpp6
7 files changed, 192 insertions, 38 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0b0b3c0ee..ca57ca553 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -106,9 +106,9 @@ if (MINGW)
set_target_properties(PrusaSlicer PROPERTIES PREFIX "")
endif (MINGW)
-if (NOT WIN32)
- # Binary name on unix like systems (OSX, Linux)
- set_target_properties(PrusaSlicer PROPERTIES OUTPUT_NAME "prusa-slicer")
+if (NOT WIN32 AND NOT APPLE)
+ # Binary name on unix like systems (Linux, Unix)
+ set_target_properties(PrusaSlicer PROPERTIES OUTPUT_NAME "prusa-slicer")
endif ()
target_link_libraries(PrusaSlicer libslic3r cereal)
@@ -209,20 +209,34 @@ if (WIN32)
add_custom_target(PrusaSlicerDllsCopy ALL DEPENDS PrusaSlicer)
prusaslicer_copy_dlls(PrusaSlicerDllsCopy)
-elseif (XCODE)
- # Because of Debug/Release/etc. configurations (similar to MSVC) the slic3r binary is located in an extra level
- add_custom_command(TARGET PrusaSlicer POST_BUILD
- COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/resources"
- COMMENT "Symlinking the resources directory into the build tree"
- VERBATIM
- )
else ()
+ if (APPLE)
+ # On OSX, the name of the binary matches the name of the Application.
+ add_custom_command(TARGET PrusaSlicer POST_BUILD
+ COMMAND ln -sf PrusaSlicer prusa-slicer
+ COMMAND ln -sf PrusaSlicer prusa-gcodeviewer
+ COMMAND ln -sf PrusaSlicer PrusaGCodeViewer
+ WORKING_DIRECTORY "$<TARGET_FILE_DIR:PrusaSlicer>"
+ COMMENT "Symlinking the G-code viewer to PrusaSlicer, symlinking to prusa-slicer and prusa-gcodeviewer"
+ VERBATIM)
+ else ()
+ add_custom_command(TARGET PrusaSlicer POST_BUILD
+ COMMAND ln -sf prusa-slicer prusa-gcodeviewer
+ WORKING_DIRECTORY "$<TARGET_FILE_DIR:PrusaSlicer>"
+ COMMENT "Symlinking the G-code viewer to PrusaSlicer"
+ VERBATIM)
+ endif ()
+ if (XCODE)
+ # Because of Debug/Release/etc. configurations (similar to MSVC) the slic3r binary is located in an extra level
+ set(BIN_RESOURCES_DIR "${CMAKE_CURRENT_BINARY_DIR}/resources")
+ else ()
+ set(BIN_RESOURCES_DIR "${CMAKE_CURRENT_BINARY_DIR}/../resources")
+ endif ()
add_custom_command(TARGET PrusaSlicer POST_BUILD
- COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/../resources"
+ COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${BIN_RESOURCES_DIR}"
COMMENT "Symlinking the resources directory into the build tree"
- VERBATIM
- )
-endif()
+ VERBATIM)
+endif ()
# Slic3r binary install target
if (WIN32)
diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp
index 2962f0cdf..94996dc92 100644
--- a/src/PrusaSlicer.cpp
+++ b/src/PrusaSlicer.cpp
@@ -22,6 +22,7 @@
#include <cstring>
#include <iostream>
#include <math.h>
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/nowide/args.hpp>
#include <boost/nowide/cenv.hpp>
@@ -101,8 +102,14 @@ int CLI::run(int argc, char **argv)
std::find(m_transforms.begin(), m_transforms.end(), "cut") == m_transforms.end() &&
std::find(m_transforms.begin(), m_transforms.end(), "cut_x") == m_transforms.end() &&
std::find(m_transforms.begin(), m_transforms.end(), "cut_y") == m_transforms.end();
- bool start_as_gcodeviewer = false;
-
+ bool start_as_gcodeviewer =
+#ifdef _WIN32
+ false;
+#else
+ // On Unix systems, the prusa-slicer binary may be symlinked to give the application a different meaning.
+ boost::algorithm::iends_with(boost::filesystem::path(argv[0]).filename().string(), "gcodeviewer");
+#endif // _WIN32
+
const std::vector<std::string> &load_configs = m_config.option<ConfigOptionStrings>("load", true)->values;
// load config files supplied via --load
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 5681ed66d..1c3007810 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -195,6 +195,8 @@ set(SLIC3R_GUI_SOURCES
Utils/Bonjour.hpp
Utils/PresetUpdater.cpp
Utils/PresetUpdater.hpp
+ Utils/Process.cpp
+ Utils/Process.hpp
Utils/Profile.hpp
Utils/UndoRedo.cpp
Utils/UndoRedo.hpp
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index f6fd939e2..f4d7f03ec 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -9,7 +9,6 @@
#include <wx/tooltip.h>
//#include <wx/glcanvas.h>
#include <wx/filename.h>
-#include <wx/stdpaths.h>
#include <wx/debug.h>
#include <boost/algorithm/string/predicate.hpp>
@@ -31,6 +30,7 @@
#include "I18N.hpp"
#include "GLCanvas3D.hpp"
#include "Plater.hpp"
+#include "../Utils/Process.hpp"
#include <fstream>
#include "GUI_App.hpp"
@@ -40,12 +40,6 @@
#include <shlobj.h>
#endif // _WIN32
-// For starting another PrusaSlicer instance on OSX.
-// Fails to compile on Windows on the build server.
-#ifdef __APPLE__
- #include <boost/process/spawn.hpp>
-#endif
-
namespace Slic3r {
namespace GUI {
@@ -1054,8 +1048,8 @@ void MainFrame::init_menubar()
append_menu_item(fileMenu, wxID_ANY, _L("&Repair STL file") + dots, _L("Automatically repair an STL file"),
[this](wxCommandEvent&) { repair_stl(); }, "wrench", nullptr,
[this]() { return true; }, this);
-#if ENABLE_GCODE_VIEWER
fileMenu->AppendSeparator();
+#if ENABLE_GCODE_VIEWER
append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"),
[this](wxCommandEvent&) {
if (m_plater->model().objects.empty() ||
@@ -1064,6 +1058,8 @@ void MainFrame::init_menubar()
set_mode(EMode::GCodeViewer);
}, "", nullptr);
#endif // ENABLE_GCODE_VIEWER
+ append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview") + dots, _L("Open G-code viewer"),
+ [this](wxCommandEvent&) { start_new_gcodeviewer_open_file(this); }, "", nullptr);
fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME),
[this](wxCommandEvent&) { Close(false); });
@@ -1180,20 +1176,11 @@ void MainFrame::init_menubar()
windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_ANY, _L("Print &Host Upload Queue") + "\tCtrl+J", _L("Display the Print Host Upload Queue window"),
- [this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr,
- [this]() {return true; }, this);
+ [this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr, [this]() {return true; }, this);
windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_ANY, _(L("Open new instance")) + "\tCtrl+I", _(L("Open a new PrusaSlicer instance")),
- [this](wxCommandEvent&) {
- wxString path = wxStandardPaths::Get().GetExecutablePath();
-#ifdef __APPLE__
- boost::process::spawn((const char*)path.c_str());
-#else
- wxExecute(wxStandardPaths::Get().GetExecutablePath(), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER);
-#endif
- }, "upload_queue", nullptr,
- [this]() {return true; }, this);
+ [this](wxCommandEvent&) { start_new_slicer(); }, "", nullptr);
}
// View menu
diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp
new file mode 100644
index 000000000..2301cd250
--- /dev/null
+++ b/src/slic3r/Utils/Process.cpp
@@ -0,0 +1,125 @@
+#include "Process.hpp"
+
+#include <libslic3r/AppConfig.hpp>
+
+#include "../GUI/GUI.hpp"
+// for file_wildcards()
+#include "../GUI/GUI_App.hpp"
+// localization
+#include "../GUI/I18N.hpp"
+
+#include <iostream>
+#include <fstream>
+
+#include <boost/filesystem.hpp>
+#include <boost/log/trivial.hpp>
+
+// For starting another PrusaSlicer instance on OSX.
+// Fails to compile on Windows on the build server.
+#ifdef __APPLE__
+ #include <boost/process/spawn.hpp>
+#endif
+
+#include <wx/stdpaths.h>
+
+namespace Slic3r {
+namespace GUI {
+
+enum class NewSlicerInstanceType {
+ Slicer,
+ GCodeViewer
+};
+
+// Start a new Slicer process instance either in a Slicer mode or in a G-code mode.
+// Optionally load a 3MF, STL or a G-code on start.
+static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance_type, const wxString *path_to_open)
+{
+#ifdef _WIN32
+ wxString path;
+ wxFileName::SplitPath(wxStandardPaths::Get().GetExecutablePath(), &path, nullptr, nullptr, wxPATH_NATIVE);
+ path += "\\";
+ path += (instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer.exe" : "prusa-gcodeviewer.exe";
+ std::vector<const wchar_t*> args;
+ args.reserve(3);
+ args.emplace_back(path.wc_str());
+ if (path_to_open != nullptr)
+ args.emplace_back(path_to_open->wc_str());
+ args.emplace_back(nullptr);
+ BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << to_u8(path) << "\"";
+ if (wxExecute(const_cast<wchar_t**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER) <= 0)
+ BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << to_u8(path);
+#else
+ // Own executable path.
+ boost::filesystem::path bin_path = into_path(wxStandardPaths::Get().GetExecutablePath());
+ #if defined(__APPLE__)
+ {
+ bin_path = bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer");
+ // On Apple the wxExecute fails, thus we use boost::process instead.
+ BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << bin_path.string() << "\"";
+ try {
+ path_to_open ? boost::process::spawn(bin_path, into_u8(*path_to_open)) : boost::process::spawn(bin_path, boost::process::args());
+ } catch (const std::exception &ex) {
+ BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what();
+ }
+ }
+ #else // Linux or Unix
+ {
+ std::vector<const char*> args;
+ args.reserve(3);
+ #ifdef __linux
+ static const char *gcodeviewer_param = "--gcodeviewer";
+ {
+ // If executed by an AppImage, start the AppImage, not the main process.
+ // see https://docs.appimage.org/packaging-guide/environment-variables.html#id2
+ const char *appimage_binary = std::getenv("APPIMAGE");
+ if (appimage_binary) {
+ args.emplace_back(appimage_binary);
+ if (instance_type == NewSlicerInstanceType::GCodeViewer)
+ args.emplace_back(gcodeviewer_param);
+ }
+ }
+ #endif // __linux
+ std::string my_path;
+ if (args.empty()) {
+ // Binary path was not set to the AppImage in the Linux specific block above, call the application directly.
+ my_path = (bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer" : "prusa-gcodeviewer")).string();
+ args.emplace_back(my_path.c_str());
+ }
+ std::string to_open;
+ if (path_to_open) {
+ to_open = into_u8(*path_to_open);
+ args.emplace_back(to_open.c_str());
+ }
+ args.emplace_back(nullptr);
+ BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << args[0] << "\"";
+ if (wxExecute(const_cast<char**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER) <= 0)
+ BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << args[0];
+ }
+ #endif // Linux or Unix
+#endif // Win32
+}
+
+void start_new_slicer(const wxString *path_to_open)
+{
+ start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::Slicer, path_to_open);
+}
+
+void start_new_gcodeviewer(const wxString *path_to_open)
+{
+ start_new_slicer_or_gcodeviewer(NewSlicerInstanceType::GCodeViewer, path_to_open);
+}
+
+void start_new_gcodeviewer_open_file(wxWindow *parent)
+{
+ wxFileDialog dialog(parent ? parent : wxGetApp().GetTopWindow(),
+ _L("Open G-code file:"),
+ from_u8(wxGetApp().app_config->get_last_dir()), wxString(),
+ file_wildcards(FT_GCODE), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
+ if (dialog.ShowModal() == wxID_OK) {
+ wxString path = dialog.GetPath();
+ start_new_gcodeviewer(&path);
+ }
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/src/slic3r/Utils/Process.hpp b/src/slic3r/Utils/Process.hpp
new file mode 100644
index 000000000..c6acaa643
--- /dev/null
+++ b/src/slic3r/Utils/Process.hpp
@@ -0,0 +1,19 @@
+#ifndef GUI_PROCESS_HPP
+#define GUI_PROCESS_HPP
+
+class wxWindow;
+
+namespace Slic3r {
+namespace GUI {
+
+// Start a new slicer instance, optionally with a file to open.
+void start_new_slicer(const wxString *path_to_open = nullptr);
+// Start a new G-code viewer instance, optionally with a file to open.
+void start_new_gcodeviewer(const wxString *path_to_open = nullptr);
+// Open a file dialog, ask the user to select a new G-code to open, start a new G-code viewer.
+void start_new_gcodeviewer_open_file(wxWindow *parent = nullptr);
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // GUI_PROCESS_HPP
diff --git a/src/slic3r/Utils/Thread.hpp b/src/slic3r/Utils/Thread.hpp
index e9c76d2ab..194971c9e 100644
--- a/src/slic3r/Utils/Thread.hpp
+++ b/src/slic3r/Utils/Thread.hpp
@@ -1,5 +1,5 @@
-#ifndef THREAD_HPP
-#define THREAD_HPP
+#ifndef GUI_THREAD_HPP
+#define GUI_THREAD_HPP
#include <utility>
#include <boost/thread.hpp>
@@ -25,4 +25,4 @@ template<class Fn> inline boost::thread create_thread(Fn &&fn)
}
-#endif // THREAD_HPP
+#endif // GUI_THREAD_HPP