mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-15 10:47:50 -06:00
Merge branch 'tm_miniz_zipper' into tm_sla_png_minz
This commit is contained in:
commit
24145cc14f
6 changed files with 296 additions and 56 deletions
|
@ -161,6 +161,8 @@ add_library(libslic3r STATIC
|
||||||
utils.cpp
|
utils.cpp
|
||||||
Utils.hpp
|
Utils.hpp
|
||||||
MTUtils.hpp
|
MTUtils.hpp
|
||||||
|
Zipper.hpp
|
||||||
|
Zipper.cpp
|
||||||
SLA/SLABoilerPlate.hpp
|
SLA/SLABoilerPlate.hpp
|
||||||
SLA/SLABasePool.hpp
|
SLA/SLABasePool.hpp
|
||||||
SLA/SLABasePool.cpp
|
SLA/SLABasePool.cpp
|
||||||
|
|
|
@ -97,7 +97,7 @@ public:
|
||||||
|
|
||||||
bool is_ok() { return false; }
|
bool is_ok() { return false; }
|
||||||
|
|
||||||
template<class T> LayerWriter& operator<<(const T& /*arg*/) {
|
template<class T> LayerWriter& operator<<(T&& /*arg*/) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "PrintExport.hpp"
|
#include "PrintExport.hpp"
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
#include "MTUtils.hpp"
|
#include "MTUtils.hpp"
|
||||||
|
#include "Zipper.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
@ -200,6 +201,32 @@ struct SLAPrintStatistics
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SLAminzZipper {};
|
||||||
|
|
||||||
|
// The implementation of creating zipped archives with wxWidgets
|
||||||
|
template<> class LayerWriter<SLAminzZipper> {
|
||||||
|
Zipper m_zip;
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline LayerWriter(const std::string& zipfile_path): m_zip(zipfile_path) {}
|
||||||
|
|
||||||
|
inline void next_entry(const std::string& fname) { m_zip.add_entry(fname); }
|
||||||
|
|
||||||
|
inline std::string get_name() const {
|
||||||
|
return m_zip.get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline LayerWriter& operator<<(T&& arg) {
|
||||||
|
m_zip << std::forward<T>(arg); return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_ok() const {
|
||||||
|
return true; // m_zip blows up if something goes wrong...
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void close() { /* m_zip closes upon destruction */ }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class is the high level FSM for the SLA printing process.
|
* @brief This class is the high level FSM for the SLA printing process.
|
||||||
*
|
*
|
||||||
|
@ -231,9 +258,11 @@ public:
|
||||||
// Returns true if the last step was finished with success.
|
// Returns true if the last step was finished with success.
|
||||||
bool finished() const override { return this->is_step_done(slaposIndexSlices) && this->Inherited::is_step_done(slapsRasterize); }
|
bool finished() const override { return this->is_step_done(slaposIndexSlices) && this->Inherited::is_step_done(slapsRasterize); }
|
||||||
|
|
||||||
template<class Fmt> void export_raster(const std::string& fname) {
|
template<class Fmt = SLAminzZipper>
|
||||||
|
void export_raster(const std::string& fname) {
|
||||||
if(m_printer) m_printer->save<Fmt>(fname);
|
if(m_printer) m_printer->save<Fmt>(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrintObjects& objects() const { return m_objects; }
|
const PrintObjects& objects() const { return m_objects; }
|
||||||
|
|
||||||
std::string output_filename() const override;
|
std::string output_filename() const override;
|
||||||
|
|
177
src/libslic3r/Zipper.cpp
Normal file
177
src/libslic3r/Zipper.cpp
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
#include <exception>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Zipper.hpp"
|
||||||
|
#include "miniz/miniz_zip.h"
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
#include "I18N.hpp"
|
||||||
|
|
||||||
|
//! macro used to mark string used at localization,
|
||||||
|
//! return same string
|
||||||
|
#define L(s) Slic3r::I18N::translate(s)
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1800 || __cplusplus < 201103L
|
||||||
|
#define SLIC3R_NORETURN
|
||||||
|
#elif __cplusplus >= 201103L
|
||||||
|
#define SLIC3R_NORETURN [[noreturn]]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Zipper::Impl {
|
||||||
|
public:
|
||||||
|
mz_zip_archive arch;
|
||||||
|
std::string m_zipname;
|
||||||
|
|
||||||
|
std::string get_errorstr(mz_zip_error mz_err)
|
||||||
|
{
|
||||||
|
switch (mz_err)
|
||||||
|
{
|
||||||
|
case MZ_ZIP_NO_ERROR:
|
||||||
|
return "no error";
|
||||||
|
case MZ_ZIP_UNDEFINED_ERROR:
|
||||||
|
return L("undefined error");
|
||||||
|
case MZ_ZIP_TOO_MANY_FILES:
|
||||||
|
return L("too many files");
|
||||||
|
case MZ_ZIP_FILE_TOO_LARGE:
|
||||||
|
return L("file too large");
|
||||||
|
case MZ_ZIP_UNSUPPORTED_METHOD:
|
||||||
|
return L("unsupported method");
|
||||||
|
case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
|
||||||
|
return L("unsupported encryption");
|
||||||
|
case MZ_ZIP_UNSUPPORTED_FEATURE:
|
||||||
|
return L("unsupported feature");
|
||||||
|
case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
|
||||||
|
return L("failed finding central directory");
|
||||||
|
case MZ_ZIP_NOT_AN_ARCHIVE:
|
||||||
|
return L("not a ZIP archive");
|
||||||
|
case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
|
||||||
|
return L("invalid header or archive is corrupted");
|
||||||
|
case MZ_ZIP_UNSUPPORTED_MULTIDISK:
|
||||||
|
return L("unsupported multidisk archive");
|
||||||
|
case MZ_ZIP_DECOMPRESSION_FAILED:
|
||||||
|
return L("decompression failed or archive is corrupted");
|
||||||
|
case MZ_ZIP_COMPRESSION_FAILED:
|
||||||
|
return L("compression failed");
|
||||||
|
case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
|
||||||
|
return L("unexpected decompressed size");
|
||||||
|
case MZ_ZIP_CRC_CHECK_FAILED:
|
||||||
|
return L("CRC-32 check failed");
|
||||||
|
case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
|
||||||
|
return L("unsupported central directory size");
|
||||||
|
case MZ_ZIP_ALLOC_FAILED:
|
||||||
|
return L("allocation failed");
|
||||||
|
case MZ_ZIP_FILE_OPEN_FAILED:
|
||||||
|
return L("file open failed");
|
||||||
|
case MZ_ZIP_FILE_CREATE_FAILED:
|
||||||
|
return L("file create failed");
|
||||||
|
case MZ_ZIP_FILE_WRITE_FAILED:
|
||||||
|
return L("file write failed");
|
||||||
|
case MZ_ZIP_FILE_READ_FAILED:
|
||||||
|
return L("file read failed");
|
||||||
|
case MZ_ZIP_FILE_CLOSE_FAILED:
|
||||||
|
return L("file close failed");
|
||||||
|
case MZ_ZIP_FILE_SEEK_FAILED:
|
||||||
|
return L("file seek failed");
|
||||||
|
case MZ_ZIP_FILE_STAT_FAILED:
|
||||||
|
return L("file stat failed");
|
||||||
|
case MZ_ZIP_INVALID_PARAMETER:
|
||||||
|
return L("invalid parameter");
|
||||||
|
case MZ_ZIP_INVALID_FILENAME:
|
||||||
|
return L("invalid filename");
|
||||||
|
case MZ_ZIP_BUF_TOO_SMALL:
|
||||||
|
return L("buffer too small");
|
||||||
|
case MZ_ZIP_INTERNAL_ERROR:
|
||||||
|
return L("internal error");
|
||||||
|
case MZ_ZIP_FILE_NOT_FOUND:
|
||||||
|
return L("file not found");
|
||||||
|
case MZ_ZIP_ARCHIVE_TOO_LARGE:
|
||||||
|
return L("archive is too large");
|
||||||
|
case MZ_ZIP_VALIDATION_FAILED:
|
||||||
|
return L("validation failed");
|
||||||
|
case MZ_ZIP_WRITE_CALLBACK_FAILED:
|
||||||
|
return L("write calledback failed");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown error";
|
||||||
|
}
|
||||||
|
|
||||||
|
SLIC3R_NORETURN void blow_up() {
|
||||||
|
std::string prefix(L("Error with zip archive"));
|
||||||
|
throw std::runtime_error(prefix + " " + m_zipname + ": " +
|
||||||
|
get_errorstr(arch.m_last_error) + "!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Zipper::Zipper(const std::string &zipfname, e_compression compression)
|
||||||
|
{
|
||||||
|
m_impl.reset(new Impl());
|
||||||
|
|
||||||
|
m_compression = compression;
|
||||||
|
m_impl->m_zipname = zipfname;
|
||||||
|
|
||||||
|
memset(&m_impl->arch, 0, sizeof(m_impl->arch));
|
||||||
|
|
||||||
|
// Initialize the archive data
|
||||||
|
if(!mz_zip_writer_init_file(&m_impl->arch, zipfname.c_str(), 0))
|
||||||
|
m_impl->blow_up();
|
||||||
|
}
|
||||||
|
|
||||||
|
Zipper::~Zipper()
|
||||||
|
{
|
||||||
|
finish_entry();
|
||||||
|
|
||||||
|
if(!mz_zip_writer_finalize_archive(&m_impl->arch)) m_impl->blow_up();
|
||||||
|
if(!mz_zip_writer_end(&m_impl->arch)) m_impl->blow_up();
|
||||||
|
}
|
||||||
|
|
||||||
|
Zipper::Zipper(Zipper &&m):
|
||||||
|
m_impl(std::move(m.m_impl)),
|
||||||
|
m_data(std::move(m.m_data)),
|
||||||
|
m_entry(std::move(m.m_entry)),
|
||||||
|
m_compression(m.m_compression) {}
|
||||||
|
|
||||||
|
Zipper &Zipper::operator=(Zipper &&m) {
|
||||||
|
m_impl = std::move(m.m_impl);
|
||||||
|
m_data = std::move(m.m_data);
|
||||||
|
m_entry = std::move(m.m_entry);
|
||||||
|
m_compression = m.m_compression;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Zipper::add_entry(const std::string &name)
|
||||||
|
{
|
||||||
|
finish_entry(); // finish previous business
|
||||||
|
m_entry = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Zipper::finish_entry()
|
||||||
|
{
|
||||||
|
if(!m_data.empty() > 0 && !m_entry.empty()) {
|
||||||
|
mz_uint compression = MZ_NO_COMPRESSION;
|
||||||
|
|
||||||
|
switch (m_compression) {
|
||||||
|
case NO_COMPRESSION: compression = MZ_NO_COMPRESSION; break;
|
||||||
|
case FAST_COMPRESSION: compression = MZ_BEST_SPEED; break;
|
||||||
|
case TIGHT_COMPRESSION: compression = MZ_BEST_COMPRESSION; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mz_zip_writer_add_mem(&m_impl->arch, m_entry.c_str(),
|
||||||
|
m_data.c_str(),
|
||||||
|
m_data.size(),
|
||||||
|
compression)) m_impl->blow_up();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data.clear();
|
||||||
|
m_entry.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Zipper::get_name() const {
|
||||||
|
return boost::filesystem::path(m_impl->m_zipname).stem().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
83
src/libslic3r/Zipper.hpp
Normal file
83
src/libslic3r/Zipper.hpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#ifndef ZIPPER_HPP
|
||||||
|
#define ZIPPER_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Class for creating zip archives.
|
||||||
|
class Zipper {
|
||||||
|
public:
|
||||||
|
// Three compression levels supported
|
||||||
|
enum e_compression {
|
||||||
|
NO_COMPRESSION,
|
||||||
|
FAST_COMPRESSION,
|
||||||
|
TIGHT_COMPRESSION
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> m_impl;
|
||||||
|
std::string m_data;
|
||||||
|
std::string m_entry;
|
||||||
|
e_compression m_compression;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Will blow up in a runtime exception if the file cannot be created.
|
||||||
|
explicit Zipper(const std::string& zipfname,
|
||||||
|
e_compression level = NO_COMPRESSION);
|
||||||
|
~Zipper();
|
||||||
|
|
||||||
|
// No copies allwed, this is a file resource...
|
||||||
|
Zipper(const Zipper&) = delete;
|
||||||
|
Zipper& operator=(const Zipper&) = delete;
|
||||||
|
|
||||||
|
// Moving is fine.
|
||||||
|
// Zipper(Zipper&&) = default;
|
||||||
|
// Zipper& operator=(Zipper&&) = default;
|
||||||
|
// All becouse of VS2013:
|
||||||
|
Zipper(Zipper &&m);
|
||||||
|
Zipper& operator=(Zipper &&m);
|
||||||
|
|
||||||
|
/// Adding an entry means a file inside the new archive. Name param is the
|
||||||
|
/// name of the new file. To create directories, append a forward slash.
|
||||||
|
/// The previous entry is finished (see finish_entry)
|
||||||
|
void add_entry(const std::string& name);
|
||||||
|
|
||||||
|
// Writing data to the archive works like with standard streams. The target
|
||||||
|
// within the zip file is the entry created with the add_entry method.
|
||||||
|
|
||||||
|
// Template taking only arithmetic values, that std::to_string can handle.
|
||||||
|
template<class T> inline
|
||||||
|
typename std::enable_if<std::is_arithmetic<T>::value, Zipper&>::type
|
||||||
|
operator<<(T &&val) {
|
||||||
|
return this->operator<<(std::to_string(std::forward<T>(val)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template applied only for types that std::string can handle for append
|
||||||
|
// and copy. This includes c style strings...
|
||||||
|
template<class T> inline
|
||||||
|
typename std::enable_if<!std::is_arithmetic<T>::value, Zipper&>::type
|
||||||
|
operator<<(T &&val) {
|
||||||
|
if(m_data.empty()) m_data = std::forward<T>(val);
|
||||||
|
else m_data.append(val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finishing an entry means that subsequent writes will no longer be
|
||||||
|
/// appended to the previous entry. They will be written into the internal
|
||||||
|
/// buffer and ones an entry is added, the buffer will bind to the new entry
|
||||||
|
/// If the buffer was written, but no entry was added, the buffer will be
|
||||||
|
/// cleared after this call.
|
||||||
|
void finish_entry();
|
||||||
|
|
||||||
|
/// Gets the name of the archive without the path or extension.
|
||||||
|
std::string get_name() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ZIPPER_HPP
|
|
@ -92,64 +92,13 @@ void BackgroundSlicingProcess::process_fff()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pseudo type for specializing LayerWriter trait class
|
|
||||||
struct SLAZipFmt {};
|
|
||||||
|
|
||||||
// The implementation of creating zipped archives with wxWidgets
|
|
||||||
template<> class LayerWriter<SLAZipFmt> {
|
|
||||||
wxFileName fpath;
|
|
||||||
wxFFileOutputStream zipfile;
|
|
||||||
wxZipOutputStream zipstream;
|
|
||||||
wxStdOutputStream pngstream;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
inline LayerWriter(const std::string& zipfile_path):
|
|
||||||
fpath(zipfile_path),
|
|
||||||
zipfile(zipfile_path),
|
|
||||||
zipstream(zipfile),
|
|
||||||
pngstream(zipstream)
|
|
||||||
{
|
|
||||||
if(!is_ok())
|
|
||||||
throw std::runtime_error("Cannot create zip file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
~LayerWriter() {
|
|
||||||
// In case of an error (disk space full) zipstream destructor would
|
|
||||||
// crash.
|
|
||||||
pngstream.clear();
|
|
||||||
zipstream.CloseEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void next_entry(const std::string& fname) {
|
|
||||||
zipstream.PutNextEntry(fname);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string get_name() const {
|
|
||||||
return fpath.GetName().ToUTF8().data();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline LayerWriter& operator<<(const T& arg) {
|
|
||||||
pngstream << arg; return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_ok() const {
|
|
||||||
return pngstream.good() && zipstream.IsOk() && zipfile.IsOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void close() {
|
|
||||||
zipstream.Close();
|
|
||||||
zipfile.Close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void BackgroundSlicingProcess::process_sla()
|
void BackgroundSlicingProcess::process_sla()
|
||||||
{
|
{
|
||||||
assert(m_print == m_sla_print);
|
assert(m_print == m_sla_print);
|
||||||
m_print->process();
|
m_print->process();
|
||||||
if (this->set_step_started(bspsGCodeFinalize)) {
|
if (this->set_step_started(bspsGCodeFinalize)) {
|
||||||
if (! m_export_path.empty()) {
|
if (! m_export_path.empty()) {
|
||||||
m_sla_print->export_raster<SLAZipFmt>(m_export_path);
|
m_sla_print->export_raster(m_export_path);
|
||||||
m_print->set_status(100, "Masked SLA file exported to " + m_export_path);
|
m_print->set_status(100, "Masked SLA file exported to " + m_export_path);
|
||||||
} else if (! m_upload_job.empty()) {
|
} else if (! m_upload_job.empty()) {
|
||||||
prepare_upload();
|
prepare_upload();
|
||||||
|
@ -449,8 +398,8 @@ void BackgroundSlicingProcess::prepare_upload()
|
||||||
}
|
}
|
||||||
run_post_process_scripts(source_path.string(), m_fff_print->config());
|
run_post_process_scripts(source_path.string(), m_fff_print->config());
|
||||||
m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
|
m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
|
||||||
} else {
|
} else {
|
||||||
m_sla_print->export_raster<SLAZipFmt>(source_path.string());
|
m_sla_print->export_raster(source_path.string());
|
||||||
// TODO: Also finalize upload path like with FFF when there are statistics for SLA print
|
// TODO: Also finalize upload path like with FFF when there are statistics for SLA print
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue