From fd4c28ed91c3d095c6ee296b55904b22c3e51759 Mon Sep 17 00:00:00 2001 From: bubnikv <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 15:55:03 +0200 Subject: [PATCH 01/15] WIP: G-code viewer menu, refactoring of starting a background process. --- src/slic3r/CMakeLists.txt | 2 ++ src/slic3r/GUI/MainFrame.cpp | 25 ++++++------------------- src/slic3r/Utils/Thread.hpp | 6 +++--- 3 files changed, 11 insertions(+), 22 deletions(-) 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/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 From b0bedf33c0d145f2f6494c6e540668a1d49e5e68 Mon Sep 17 00:00:00 2001 From: bubnikv <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 15:55:03 +0200 Subject: [PATCH 02/15] WIP: G-code viewer menu, refactoring of starting a background process. --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/MainFrame.cpp | 25 ++------- src/slic3r/Utils/Process.cpp | 105 +++++++++++++++++++++++++++++++++++ src/slic3r/Utils/Process.hpp | 19 +++++++ src/slic3r/Utils/Thread.hpp | 6 +- 5 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 src/slic3r/Utils/Process.cpp create mode 100644 src/slic3r/Utils/Process.hpp 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..17e3d6fed --- /dev/null +++ b/src/slic3r/Utils/Process.cpp @@ -0,0 +1,105 @@ +#include "Process.hpp" + +#include <libslic3r/AppConfig.hpp> + +#include "../GUI/GUI.hpp" +// for file_wildcards() +#include "../GUI/GUI_App.hpp" +// localization +#include "../GUI/I18N.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); + wxExecute(const_cast<wchar_t**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); +#else + // Own executable path. + boost::filesystem::path own_path = into_path(wxStandardPaths::Get().GetExecutablePath()); + #if defined(__APPLE__) + { + own_path /= (instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer"; + // On Apple the wxExecute fails, thus we use boost::process instead. + path_to_open ? boost::process::spawn(path.string(), into_u8(*path_to_open)) : boost::process::spawn(path.string()); + } + #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); + if () + } + } + #endif // __linux + 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); + wxExecute(const_cast<char**>(&args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); + } + #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 From 9473ae8fe2fcac9394f85cb3267d8acf62540906 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 16:56:22 +0200 Subject: [PATCH 03/15] Fix of previous commit, added symlinks to gcodeviewer on Linux & OSX --- src/CMakeLists.txt | 29 ++++++++++++++++++++--------- src/slic3r/Utils/Process.cpp | 11 ++++++++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0b0b3c0ee..8b9462cb2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -209,20 +209,31 @@ 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 (XCODE) + add_custom_command(TARGET PrusaSlicer POST_BUILD + COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer" "${CMAKE_CURRENT_BINARY_DIR}/prusa-slicer" + COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer" "${CMAKE_CURRENT_BINARY_DIR}/prusa-gcodeviewer" + COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer" "${CMAKE_CURRENT_BINARY_DIR}/PrusaGCodeViewer" + COMMENT "Symlinking the G-code viewer to PrusaSlicer, symlinking to prusa-slicer and prusa-gcodeviewer" + VERBATIM + ) + # 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 () + add_custom_command(TARGET PrusaSlicer POST_BUILD + COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/prusa-slicer" "${CMAKE_CURRENT_BINARY_DIR}/prusa-gcodeviewer" + COMMENT "Symlinking the G-code viewer to PrusaSlicer" + VERBATIM + ) + 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() +endif () # Slic3r binary install target if (WIN32) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index 17e3d6fed..ad3730dd8 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -53,7 +53,7 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance { std::vector<const char*> args; args.reserve(3); - #ifdef(__linux) + #ifdef __linux static const char *gcodeviewer_param = "--gcodeviewer"; { // If executed by an AppImage, start the AppImage, not the main process. @@ -63,17 +63,22 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance args.emplace_back(appimage_binary); if (instance_type == NewSlicerInstanceType::GCodeViewer) args.emplace_back(gcodeviewer_param); - if () } } #endif // __linux + std::string bin_path; + if (args.empty()) { + // Binary path was not set to the AppImage in the Linux specific block above, call the application directly. + bin_path = (own_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer" : "prusa-gcodeviewer")).string(); + args.emplace_back(bin_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); - wxExecute(const_cast<char**>(&args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); + wxExecute(const_cast<char**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); } #endif // Linux or Unix #endif // Win32 From 1221c67d7f9bdb40de5cee3518036511b9f9e8c4 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 17:09:27 +0200 Subject: [PATCH 04/15] Fix for OSX --- src/slic3r/Utils/Process.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index ad3730dd8..596b73ff8 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -42,12 +42,12 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance wxExecute(const_cast<wchar_t**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); #else // Own executable path. - boost::filesystem::path own_path = into_path(wxStandardPaths::Get().GetExecutablePath()); + boost::filesystem::path bin_path = into_path(wxStandardPaths::Get().GetExecutablePath()); #if defined(__APPLE__) { - own_path /= (instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer"; + bin_path /= (instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer"; // On Apple the wxExecute fails, thus we use boost::process instead. - path_to_open ? boost::process::spawn(path.string(), into_u8(*path_to_open)) : boost::process::spawn(path.string()); + path_to_open ? boost::process::spawn(bin_path.string(), into_u8(*path_to_open)) : boost::process::spawn(bin_path.string()); } #else // Linux or Unix { From ae0e576c32b360314a962ddc0eef645c3cc3fe2e Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 17:41:16 +0200 Subject: [PATCH 05/15] Fixing Linux build --- src/slic3r/Utils/Process.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index 596b73ff8..83438390c 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -66,11 +66,11 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance } } #endif // __linux - std::string bin_path; + 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. - bin_path = (own_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "prusa-slicer" : "prusa-gcodeviewer")).string(); - args.emplace_back(bin_path.c_str()); + 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) { From 8622437c12d21ca402cc7cd1cf8fb54a603ab62a Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 18:09:51 +0200 Subject: [PATCH 06/15] fixing symlinks --- src/CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b9462cb2..e80349f84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,9 +212,10 @@ if (WIN32) else () if (XCODE) add_custom_command(TARGET PrusaSlicer POST_BUILD - COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer" "${CMAKE_CURRENT_BINARY_DIR}/prusa-slicer" - COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer" "${CMAKE_CURRENT_BINARY_DIR}/prusa-gcodeviewer" - COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer" "${CMAKE_CURRENT_BINARY_DIR}/PrusaGCodeViewer" + 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 ) @@ -222,7 +223,8 @@ else () set(BIN_RESOURCES_DIR "${CMAKE_CURRENT_BINARY_DIR}/resources") else () add_custom_command(TARGET PrusaSlicer POST_BUILD - COMMAND ln -sf "${CMAKE_CURRENT_BINARY_DIR}/prusa-slicer" "${CMAKE_CURRENT_BINARY_DIR}/prusa-gcodeviewer" + COMMAND ln -sf prusa-slicer prusa-gcodeviewer + WORKING_DIRECTORY "$<TARGET_FILE_DIR:PrusaSlicer>" COMMENT "Symlinking the G-code viewer to PrusaSlicer" VERBATIM ) From 889f05167af523da4f0c8d8028049e970ea91358 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 21:36:51 +0200 Subject: [PATCH 07/15] Changing the binary name on OSX to PrusaSlicer. --- src/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e80349f84..c0137502a 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) From 620c85f264f8175552aab041b4ced2d39c132cbb Mon Sep 17 00:00:00 2001 From: test <test@SlicerOSXbot.local> Date: Mon, 7 Sep 2020 22:00:01 +0200 Subject: [PATCH 08/15] Fix on OSX --- src/slic3r/Utils/Process.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index 83438390c..e29160870 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -45,7 +45,7 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance boost::filesystem::path bin_path = into_path(wxStandardPaths::Get().GetExecutablePath()); #if defined(__APPLE__) { - bin_path /= (instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer"; + bin_path = bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer"); // On Apple the wxExecute fails, thus we use boost::process instead. path_to_open ? boost::process::spawn(bin_path.string(), into_u8(*path_to_open)) : boost::process::spawn(bin_path.string()); } From f237b33515b25833bae40e96c11565564f4ee400 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 22:26:58 +0200 Subject: [PATCH 09/15] Yet another fix on OSX. --- src/CMakeLists.txt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0137502a..ca57ca553 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -210,31 +210,32 @@ if (WIN32) prusaslicer_copy_dlls(PrusaSlicerDllsCopy) else () - if (XCODE) + 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 - ) - # 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") + 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 - ) + 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}" "${BIN_RESOURCES_DIR}" COMMENT "Symlinking the resources directory into the build tree" - VERBATIM - ) + VERBATIM) endif () # Slic3r binary install target From d830e1c970f8562ca862759cf3bcb6c4f80c9c54 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Mon, 7 Sep 2020 22:37:55 +0200 Subject: [PATCH 10/15] Run PrusaSlicer as G-code viewer based on argv[0] name on Unix systems. --- src/PrusaSlicer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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 From 663f17a0e3de953dde239ed65dec59eca198a7fc Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Tue, 8 Sep 2020 09:57:17 +0200 Subject: [PATCH 11/15] Improved logging of spawning a subprocess. --- src/slic3r/Utils/Process.cpp | 40 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index e29160870..4347f6682 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -8,6 +8,11 @@ // localization #include "../GUI/I18N.hpp" +#include <iostream> +#include <fstream> + +#include <boost/log/trivial.hpp> + // For starting another PrusaSlicer instance on OSX. // Fails to compile on Windows on the build server. #ifdef __APPLE__ @@ -29,17 +34,19 @@ enum class NewSlicerInstanceType { 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); - wxExecute(const_cast<wchar_t**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); + 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()); @@ -47,7 +54,12 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance { bin_path = bin_path.parent_path() / ((instance_type == NewSlicerInstanceType::Slicer) ? "PrusaSlicer" : "PrusaGCodeViewer"); // On Apple the wxExecute fails, thus we use boost::process instead. - path_to_open ? boost::process::spawn(bin_path.string(), into_u8(*path_to_open)) : boost::process::spawn(bin_path.string()); + BOOST_LOG_TRIVIAL(info) << "Trying to spawn a new slicer \"" << bin_path.string() << "\""; + try { + path_to_open ? boost::process::spawn(bin_path.string(), into_u8(*path_to_open)) : boost::process::spawn(bin_path.string()); + } catch (const std::exception &ex) { + BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what(); + } } #else // Linux or Unix { @@ -78,7 +90,9 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance args.emplace_back(to_open.c_str()); } args.emplace_back(nullptr); - wxExecute(const_cast<char**>(args.data()), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); + 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 From 77ba284a59b782c9898cd6eeb1867ba69cbcf8c3 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Tue, 8 Sep 2020 11:22:27 +0200 Subject: [PATCH 12/15] Trying to fix spawn on OSX --- src/slic3r/Utils/Process.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index 4347f6682..3ee141e80 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -56,7 +56,7 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance // 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.string(), into_u8(*path_to_open)) : boost::process::spawn(bin_path.string()); + path_to_open ? boost::process::spawn(bin_path, into_u8(*path_to_open)) : boost::process::spawn(bin_path, boost::path::args()); } catch (const std::exception &ex) { BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what(); } From 3c51581e92f7ec88ac82007d5e6ffd2eca8840e5 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Tue, 8 Sep 2020 11:36:00 +0200 Subject: [PATCH 13/15] Another fix --- src/slic3r/Utils/Process.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index 3ee141e80..ab5a9b1e9 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -11,6 +11,7 @@ #include <iostream> #include <fstream> +#include <boost/filesystem.hpp> #include <boost/log/trivial.hpp> // For starting another PrusaSlicer instance on OSX. @@ -56,7 +57,7 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance // 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::path::args()); + path_to_open ? boost::process::spawn(bin_path, into_u8(*path_to_open)) : boost::process::spawn(bin_path, boost::filesystem::path::args()); } catch (const std::exception &ex) { BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what(); } From 0fde670fd654b794c49b462bd140c48f46af6d58 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik <bubnikv@gmail.com> Date: Tue, 8 Sep 2020 11:49:02 +0200 Subject: [PATCH 14/15] osx fix --- src/slic3r/Utils/Process.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index ab5a9b1e9..2301cd250 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -57,7 +57,7 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance // 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::filesystem::path::args()); + 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(); } From 0f64b67ffa9f88055150b59c6314ec7d15377963 Mon Sep 17 00:00:00 2001 From: test <test@SlicerOSXbot.local> Date: Tue, 8 Sep 2020 12:39:11 +0200 Subject: [PATCH 15/15] osx fix --- src/slic3r/Utils/Process.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index 2301cd250..fa5ecb1f0 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -18,6 +18,7 @@ // Fails to compile on Windows on the build server. #ifdef __APPLE__ #include <boost/process/spawn.hpp> + #include <boost/process/args.hpp> #endif #include <wx/stdpaths.h> @@ -57,7 +58,10 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance // 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()); + std::vector<std::string> args; + if (path_to_open) + args.emplace_back(into_u8(*path_to_open)); + boost::process::spawn(bin_path, args); } catch (const std::exception &ex) { BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what(); }