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/PrusaSlicer.cpp3
-rw-r--r--src/libslic3r/CMakeLists.txt2
-rw-r--r--src/libslic3r/Platform.cpp (renamed from src/slic3r/Utils/Platform.cpp)8
-rw-r--r--src/libslic3r/Platform.hpp (renamed from src/slic3r/Utils/Platform.hpp)9
-rw-r--r--src/libslic3r/utils.cpp148
-rw-r--r--src/slic3r/CMakeLists.txt2
-rw-r--r--src/slic3r/GUI/GUI_Init.cpp3
-rw-r--r--src/slic3r/GUI/MainFrame.cpp6
-rw-r--r--src/slic3r/GUI/OpenGLManager.cpp5
-rw-r--r--src/slic3r/GUI/Plater.cpp5
-rw-r--r--src/slic3r/GUI/PresetHints.cpp1
-rw-r--r--src/slic3r/GUI/RemovableDriveManager.cpp6
12 files changed, 168 insertions, 30 deletions
diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp
index ed2d70272..10da1cb07 100644
--- a/src/PrusaSlicer.cpp
+++ b/src/PrusaSlicer.cpp
@@ -38,6 +38,7 @@
#include "libslic3r/GCode/PostProcessor.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/ModelArrange.hpp"
+#include "libslic3r/Platform.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/SLAPrint.hpp"
#include "libslic3r/TriangleMesh.hpp"
@@ -68,6 +69,8 @@ int CLI::run(int argc, char **argv)
{
// Mark the main thread for the debugger and for runtime checks.
set_current_thread_name("slic3r_main");
+ // Detect the operating system flavor.
+ detect_platform();
#ifdef __WXGTK__
// On Linux, wxGTK has no support for Wayland, and the app crashes on
diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index 6159b2c5c..4a762f7e1 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -141,6 +141,8 @@ add_library(libslic3r STATIC
PerimeterGenerator.hpp
PlaceholderParser.cpp
PlaceholderParser.hpp
+ Platform.cpp
+ Platform.hpp
Point.cpp
Point.hpp
Polygon.cpp
diff --git a/src/slic3r/Utils/Platform.cpp b/src/libslic3r/Platform.cpp
index 3d101d662..4c8805149 100644
--- a/src/slic3r/Utils/Platform.cpp
+++ b/src/libslic3r/Platform.cpp
@@ -1,15 +1,8 @@
#include "Platform.hpp"
-
-// For starting another PrusaSlicer instance on OSX.
-// Fails to compile on Windows on the build server.
-
-#include <wx/stdpaths.h>
-
#include <boost/log/trivial.hpp>
namespace Slic3r {
-namespace GUI {
static auto s_platform = Platform::Uninitialized;
static auto s_platform_flavor = PlatformFlavor::Uninitialized;
@@ -74,5 +67,4 @@ PlatformFlavor platform_flavor()
return s_platform_flavor;
}
-} // namespace GUI
} // namespace Slic3r
diff --git a/src/slic3r/Utils/Platform.hpp b/src/libslic3r/Platform.hpp
index c0ee3541d..735728e89 100644
--- a/src/slic3r/Utils/Platform.hpp
+++ b/src/libslic3r/Platform.hpp
@@ -1,8 +1,7 @@
-#ifndef SLIC3R_GUI_Utils_Platform_HPP
-#define SLIC3R_GUI_Utils_Platform_HPP
+#ifndef SLIC3R_Platform_HPP
+#define SLIC3R_Platform_HPP
namespace Slic3r {
-namespace GUI {
enum class Platform
{
@@ -37,8 +36,6 @@ void detect_platform();
Platform platform();
PlatformFlavor platform_flavor();
-
-} // namespace GUI
} // namespace Slic3r
-#endif // SLIC3R_GUI_Utils_Platform_HPP
+#endif // SLIC3R_Platform_HPP
diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp
index 0c26d42c8..1ac45f1b5 100644
--- a/src/libslic3r/utils.cpp
+++ b/src/libslic3r/utils.cpp
@@ -6,6 +6,7 @@
#include <cstdarg>
#include <stdio.h>
+#include "Platform.hpp"
#include "Time.hpp"
#ifdef WIN32
@@ -19,9 +20,14 @@
#ifdef BSD
#include <sys/sysctl.h>
#endif
- #ifdef __APPLE__
+ #ifdef __APPLE__
#include <mach/mach.h>
#endif
+ #ifdef __linux__
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <sys/sendfile.h>
+ #endif
#endif
#include <boost/log/core.hpp>
@@ -417,6 +423,140 @@ std::error_code rename_file(const std::string &from, const std::string &to)
#endif
}
+#ifdef __linux__
+// Copied from boost::filesystem, to support copying a file to a weird filesystem, which does not support changing file attributes,
+// for example ChromeOS Linux integration or FlashAIR WebDAV.
+// Copied and simplified from boost::filesystem::detail::copy_file() with option = overwrite_if_exists and with just the Linux path kept,
+// and only features supported by Linux 3.10 (on our build server with CentOS 7) are kept, namely sendfile with ranges and statx() are not supported.
+bool copy_file_linux(const boost::filesystem::path &from, const boost::filesystem::path &to, boost::system::error_code &ec)
+{
+ using namespace boost::filesystem;
+
+ struct fd_wrapper
+ {
+ int fd { -1 };
+ fd_wrapper() = default;
+ explicit fd_wrapper(int fd) throw() : fd(fd) {}
+ ~fd_wrapper() throw() { if (fd >= 0) ::close(fd); }
+ };
+
+ ec.clear();
+ int err = 0;
+
+ // Note: Declare fd_wrappers here so that errno is not clobbered by close() that may be called in fd_wrapper destructors
+ fd_wrapper infile, outfile;
+
+ while (true) {
+ infile.fd = ::open(from.c_str(), O_RDONLY | O_CLOEXEC);
+ if (infile.fd < 0) {
+ err = errno;
+ if (err == EINTR)
+ continue;
+ fail:
+ ec.assign(err, boost::system::system_category());
+ return false;
+ }
+ break;
+ }
+
+ struct ::stat from_stat;
+ if (::fstat(infile.fd, &from_stat) != 0) {
+ fail_errno:
+ err = errno;
+ goto fail;
+ }
+
+ const mode_t from_mode = from_stat.st_mode;
+ if (!S_ISREG(from_mode)) {
+ err = ENOSYS;
+ goto fail;
+ }
+
+ // Enable writing for the newly created files. Having write permission set is important e.g. for NFS,
+ // which checks the file permission on the server, even if the client's file descriptor supports writing.
+ mode_t to_mode = from_mode | S_IWUSR;
+ int oflag = O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC;
+
+ while (true) {
+ outfile.fd = ::open(to.c_str(), oflag, to_mode);
+ if (outfile.fd < 0) {
+ err = errno;
+ if (err == EINTR)
+ continue;
+ goto fail;
+ }
+ break;
+ }
+
+ struct ::stat to_stat;
+ if (::fstat(outfile.fd, &to_stat) != 0)
+ goto fail_errno;
+
+ to_mode = to_stat.st_mode;
+ if (!S_ISREG(to_mode)) {
+ err = ENOSYS;
+ goto fail;
+ }
+
+ if (from_stat.st_dev == to_stat.st_dev && from_stat.st_ino == to_stat.st_ino) {
+ err = EEXIST;
+ goto fail;
+ }
+
+ //! copy_file implementation that uses sendfile loop. Requires sendfile to support file descriptors.
+ //FIXME Vojtech: This is a copy loop valid for Linux 2.6.33 and newer.
+ // copy_file_data_copy_file_range() supports cross-filesystem copying since 5.3, but Vojtech did not want to polute this
+ // function with that, we don't think the performance gain is worth it for the types of files we are copying,
+ // and our build server based on CentOS 7 with Linux 3.10 does not support that anyways.
+ {
+ // sendfile will not send more than this amount of data in one call
+ constexpr std::size_t max_send_size = 0x7ffff000u;
+ uintmax_t offset = 0u;
+ while (off_t(offset) < from_stat.st_size) {
+ uintmax_t size_left = from_stat.st_size - offset;
+ std::size_t size_to_copy = max_send_size;
+ if (size_left < static_cast<uintmax_t>(max_send_size))
+ size_to_copy = static_cast<std::size_t>(size_left);
+ ssize_t sz = ::sendfile(outfile.fd, infile.fd, nullptr, size_to_copy);
+ if (sz < 0) {
+ err = errno;
+ if (err == EINTR)
+ continue;
+ if (err == 0)
+ break;
+ goto fail; // err already contains the error code
+ }
+ offset += sz;
+ }
+ }
+
+ // If we created a new file with an explicitly added S_IWUSR permission,
+ // we may need to update its mode bits to match the source file.
+ if (to_mode != from_mode && ::fchmod(outfile.fd, from_mode) != 0) {
+ if (platform_flavor() == PlatformFlavor::LinuxOnChromium) {
+ // Ignore that. 9p filesystem does not allow fmod().
+ BOOST_LOG_TRIVIAL(info) << "copy_file_linux() failed to fchmod() the output file \"" << to.string() << "\" to " << from_mode << ": " << ec.message() <<
+ " This may be expected when writing to a 9p filesystem.";
+ } else {
+ // Generic linux. Write out an error to console. At least we may get some feedback.
+ BOOST_LOG_TRIVIAL(error) << "copy_file_linux() failed to fchmod() the output file \"" << to.string() << "\" to " << from_mode << ": " << ec.message();
+ }
+ }
+
+ // Note: Use fsync/fdatasync followed by close to avoid dealing with the possibility of close failing with EINTR.
+ // Even if close fails, including with EINTR, most operating systems (presumably, except HP-UX) will close the
+ // file descriptor upon its return. This means that if an error happens later, when the OS flushes data to the
+ // underlying media, this error will go unnoticed and we have no way to receive it from close. Calling fsync/fdatasync
+ // ensures that all data have been written, and even if close fails for some unfathomable reason, we don't really
+ // care at that point.
+ err = ::fdatasync(outfile.fd);
+ if (err != 0)
+ goto fail_errno;
+
+ return true;
+}
+#endif // __linux__
+
CopyFileResult copy_file_inner(const std::string& from, const std::string& to, std::string& error_message)
{
const boost::filesystem::path source(from);
@@ -434,7 +574,13 @@ CopyFileResult copy_file_inner(const std::string& from, const std::string& to, s
if (ec)
BOOST_LOG_TRIVIAL(debug) << "boost::filesystem::permisions before copy error message (this could be irrelevant message based on file system): " << ec.message();
ec.clear();
+#ifdef __linux__
+ // We want to allow copying files on Linux to succeed even if changing the file attributes fails.
+ // That may happen when copying on some exotic file system, for example Linux on Chrome.
+ copy_file_linux(source, target, ec);
+#else // __linux__
boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, ec);
+#endif // __linux__
if (ec) {
error_message = ec.message();
return FAIL_COPY_FILE;
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 6436de2ca..4b3a1c6ca 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -209,8 +209,6 @@ set(SLIC3R_GUI_SOURCES
Utils/Bonjour.hpp
Utils/PresetUpdater.cpp
Utils/PresetUpdater.hpp
- Utils/Platform.cpp
- Utils/Platform.hpp
Utils/Process.cpp
Utils/Process.hpp
Utils/Profile.hpp
diff --git a/src/slic3r/GUI/GUI_Init.cpp b/src/slic3r/GUI/GUI_Init.cpp
index 3c77f3335..839782741 100644
--- a/src/slic3r/GUI/GUI_Init.cpp
+++ b/src/slic3r/GUI/GUI_Init.cpp
@@ -9,7 +9,6 @@
#include "slic3r/GUI/format.hpp"
#include "slic3r/GUI/MainFrame.hpp"
#include "slic3r/GUI/Plater.hpp"
-#include "slic3r/Utils/Platform.hpp"
// To show a message box if GUI initialization ends up with an exception thrown.
#include <wx/msgdlg.h>
@@ -37,8 +36,6 @@ int GUI_Run(GUI_InitParams &params)
signal(SIGCHLD, SIG_DFL);
#endif // __APPLE__
- detect_platform();
-
try {
GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor);
if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index f50c7e356..ad4468683 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -1218,8 +1218,10 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { m_plater->collapse_sidebar(!m_plater->is_sidebar_collapsed()); }, this,
[]() { return true; }, [this]() { return m_plater->is_sidebar_collapsed(); }, this);
append_menu_check_item(viewMenu, wxID_ANY, _L("&Full screen") + "\t" + "F11", _L("Full screen"),
- [this](wxCommandEvent&) { this->ShowFullScreen(!this->IsFullScreen()); }, this,
- []() { return true; }, [this]() { return this->IsFullScreen(); }, this);
+ [this](wxCommandEvent&) { this->ShowFullScreen(!this->IsFullScreen(),
+ // wxFULLSCREEN_ALL: wxFULLSCREEN_NOMENUBAR | wxFULLSCREEN_NOTOOLBAR | wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION
+ wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION); },
+ this, []() { return true; }, [this]() { return this->IsFullScreen(); }, this);
}
// Help menu
diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp
index 8e8774036..c843da460 100644
--- a/src/slic3r/GUI/OpenGLManager.cpp
+++ b/src/slic3r/GUI/OpenGLManager.cpp
@@ -4,7 +4,8 @@
#include "GUI.hpp"
#include "I18N.hpp"
#include "3DScene.hpp"
-#include "slic3r/Utils/Platform.hpp"
+
+#include "libslic3r/Platform.hpp"
#include <GL/glew.h>
@@ -324,7 +325,7 @@ void OpenGLManager::detect_multisample(int* attribList)
enable_multisample &&
// Disable multi-sampling on ChromeOS, as the OpenGL virtualization swaps Red/Blue channels with multi-sampling enabled,
// at least on some platforms.
- (platform() != Platform::Linux || platform_flavor() != PlatformFlavor::LinuxOnChromium) &&
+ platform_flavor() != PlatformFlavor::LinuxOnChromium &&
wxGLCanvas::IsDisplaySupported(attribList)
? EMultisampleState::Enabled : EMultisampleState::Disabled;
// Alternative method: it was working on previous version of wxWidgets but not with the latest, at least on Windows
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 15e89168a..273f39b1e 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -76,7 +76,6 @@
#include "../Utils/FixModelByWin10.hpp"
#include "../Utils/UndoRedo.hpp"
#include "../Utils/PresetUpdater.hpp"
-#include "../Utils/Platform.hpp"
#include "../Utils/Process.hpp"
#include "RemovableDriveManager.hpp"
#include "InstanceCheck.hpp"
@@ -89,7 +88,9 @@
#include <wx/glcanvas.h> // Needs to be last because reasons :-/
#include "WipeTowerDialog.hpp"
+
#include "libslic3r/CustomGCode.hpp"
+#include "libslic3r/Platform.hpp"
using boost::optional;
namespace fs = boost::filesystem;
@@ -3660,7 +3661,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
show_action_buttons(false);
notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path,
// Don't offer the "Eject" button on ChromeOS, the Linux side has no control over it.
- platform() != Platform::Linux || platform_flavor() != PlatformFlavor::LinuxOnChromium);
+ platform_flavor() != PlatformFlavor::LinuxOnChromium);
wxGetApp().removable_drive_manager()->set_exporting_finished(true);
}else if (exporting_status == ExportingStatus::EXPORTING_TO_LOCAL && !has_error)
notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, false);
diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp
index 0e5e10d45..181dcfda4 100644
--- a/src/slic3r/GUI/PresetHints.cpp
+++ b/src/slic3r/GUI/PresetHints.cpp
@@ -139,7 +139,6 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
const ConfigOptionFloatOrPercent *first_layer_extrusion_width_ptr = (first_layer && first_layer_extrusion_width.value > 0) ?
&first_layer_extrusion_width : nullptr;
const float lh = float(first_layer ? first_layer_height : layer_height);
- const float bfr = bridging ? bridge_flow_ratio : 0.f;
double max_flow = 0.;
std::string max_flow_extrusion_type;
auto limit_by_first_layer_speed = [&first_layer_speed, first_layer](double speed_normal, double speed_max) {
diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp
index c200956e1..33e61ab90 100644
--- a/src/slic3r/GUI/RemovableDriveManager.cpp
+++ b/src/slic3r/GUI/RemovableDriveManager.cpp
@@ -1,5 +1,5 @@
#include "RemovableDriveManager.hpp"
-#include "slic3r/Utils/Platform.hpp"
+#include "libslic3r/Platform.hpp"
#include <libslic3r/libslic3r.h>
#include <boost/nowide/convert.hpp>
@@ -232,7 +232,7 @@ std::vector<DriveData> RemovableDriveManager::search_for_removable_drives() cons
#else
- if (platform() == Platform::Linux && platform_flavor() == PlatformFlavor::LinuxOnChromium) {
+ if (platform_flavor() == PlatformFlavor::LinuxOnChromium) {
// ChromeOS specific: search /mnt/chromeos/removable/* folder
search_for_drives_internal::search_path("/mnt/chromeos/removable/*", "/mnt/chromeos/removable", current_drives);
} else {
@@ -452,7 +452,7 @@ RemovableDriveManager::RemovableDrivesStatus RemovableDriveManager::status()
tbb::mutex::scoped_lock lock(m_drives_mutex);
out.has_eject =
// Cannot control eject on Chromium.
- (platform() != Platform::Linux || platform_flavor() != PlatformFlavor::LinuxOnChromium) &&
+ platform_flavor() != PlatformFlavor::LinuxOnChromium &&
this->find_last_save_path_drive_data() != m_current_drives.end();
out.has_removable_drives = ! m_current_drives.empty();
}