Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_experiments

This commit is contained in:
Enrico Turri 2019-06-03 12:16:38 +02:00
commit 4a4deef420
5 changed files with 93 additions and 62 deletions

View file

@ -13,6 +13,7 @@
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <boost/nowide/fstream.hpp> #include <boost/nowide/fstream.hpp>
#include <boost/nowide/cstdio.hpp>
#include <expat.h> #include <expat.h>
#include <Eigen/Dense> #include <Eigen/Dense>
@ -187,6 +188,24 @@ bool is_valid_object_type(const std::string& type)
namespace Slic3r { namespace Slic3r {
namespace {
void close_archive_reader(mz_zip_archive *arch) {
if (arch) {
FILE *f = mz_zip_get_cfile(arch);
mz_zip_reader_end(arch);
if (f) fclose(f);
}
}
void close_archive_writer(mz_zip_archive *arch) {
if (arch) {
FILE *f = mz_zip_get_cfile(arch);
mz_zip_writer_end(arch);
if (f) fclose(f);
}
}
}
// Base class with error messages management // Base class with error messages management
class _3MF_Base class _3MF_Base
{ {
@ -502,8 +521,9 @@ namespace Slic3r {
{ {
mz_zip_archive archive; mz_zip_archive archive;
mz_zip_zero_struct(&archive); mz_zip_zero_struct(&archive);
mz_bool res = mz_zip_reader_init_file(&archive, filename.c_str(), 0); FILE *f = boost::nowide::fopen(filename.c_str(), "rb");
auto res = mz_bool(f != nullptr && mz_zip_reader_init_cfile(&archive, f, -1, 0));
if (res == 0) if (res == 0)
{ {
add_error("Unable to open the file"); add_error("Unable to open the file");
@ -529,7 +549,7 @@ namespace Slic3r {
// valid model name -> extract model // valid model name -> extract model
if (!_extract_model_from_archive(archive, stat)) if (!_extract_model_from_archive(archive, stat))
{ {
mz_zip_reader_end(&archive); close_archive_reader(&archive);
add_error("Archive does not contain a valid model"); add_error("Archive does not contain a valid model");
return false; return false;
} }
@ -565,7 +585,7 @@ namespace Slic3r {
// extract slic3r model config file // extract slic3r model config file
if (!_extract_model_config_from_archive(archive, stat, model)) if (!_extract_model_config_from_archive(archive, stat, model))
{ {
mz_zip_reader_end(&archive); close_archive_reader(&archive);
add_error("Archive does not contain a valid model config"); add_error("Archive does not contain a valid model config");
return false; return false;
} }
@ -573,7 +593,7 @@ namespace Slic3r {
} }
} }
mz_zip_reader_end(&archive); close_archive_reader(&archive);
for (const IdToModelObjectMap::value_type& object : m_objects) for (const IdToModelObjectMap::value_type& object : m_objects)
{ {
@ -1639,7 +1659,8 @@ namespace Slic3r {
mz_zip_archive archive; mz_zip_archive archive;
mz_zip_zero_struct(&archive); mz_zip_zero_struct(&archive);
mz_bool res = mz_zip_writer_init_file(&archive, filename.c_str(), 0); FILE *f = boost::nowide::fopen(filename.c_str(), "wb");
auto res = mz_bool(f != nullptr && mz_zip_writer_init_cfile(&archive, f, 0));
if (res == 0) if (res == 0)
{ {
add_error("Unable to open the file"); add_error("Unable to open the file");
@ -1650,7 +1671,7 @@ namespace Slic3r {
// The content of this file is the same for each PrusaSlicer 3mf. // The content of this file is the same for each PrusaSlicer 3mf.
if (!_add_content_types_file_to_archive(archive)) if (!_add_content_types_file_to_archive(archive))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
return false; return false;
} }
@ -1660,7 +1681,7 @@ namespace Slic3r {
// The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA. // The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA.
if (!_add_relationships_file_to_archive(archive)) if (!_add_relationships_file_to_archive(archive))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
return false; return false;
} }
@ -1670,7 +1691,7 @@ namespace Slic3r {
IdToObjectDataMap objects_data; IdToObjectDataMap objects_data;
if (!_add_model_file_to_archive(archive, model, objects_data)) if (!_add_model_file_to_archive(archive, model, objects_data))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
return false; return false;
} }
@ -1680,7 +1701,7 @@ namespace Slic3r {
// The index differes from the index of an object ID of an object instance of a 3MF file! // The index differes from the index of an object ID of an object instance of a 3MF file!
if (!_add_layer_height_profile_file_to_archive(archive, model)) if (!_add_layer_height_profile_file_to_archive(archive, model))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
return false; return false;
} }
@ -1690,7 +1711,7 @@ namespace Slic3r {
// The index differes from the index of an object ID of an object instance of a 3MF file! // The index differes from the index of an object ID of an object instance of a 3MF file!
if (!_add_sla_support_points_file_to_archive(archive, model)) if (!_add_sla_support_points_file_to_archive(archive, model))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
return false; return false;
} }
@ -1701,7 +1722,7 @@ namespace Slic3r {
{ {
if (!_add_print_config_file_to_archive(archive, *config)) if (!_add_print_config_file_to_archive(archive, *config))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
return false; return false;
} }
@ -1713,20 +1734,20 @@ namespace Slic3r {
// is stored here as well. // is stored here as well.
if (!_add_model_config_file_to_archive(archive, model, objects_data)) if (!_add_model_config_file_to_archive(archive, model, objects_data))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
return false; return false;
} }
if (!mz_zip_writer_finalize_archive(&archive)) if (!mz_zip_writer_finalize_archive(&archive))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(filename); boost::filesystem::remove(filename);
add_error("Unable to finalize the archive"); add_error("Unable to finalize the archive");
return false; return false;
} }
mz_zip_writer_end(&archive); close_archive_writer(&archive);
return true; return true;
} }

View file

@ -712,19 +712,37 @@ bool load_amf_file(const char *path, DynamicPrintConfig *config, Model *model)
return result; return result;
} }
namespace {
void close_archive_reader(mz_zip_archive *arch) {
if (arch) {
FILE *f = mz_zip_get_cfile(arch);
mz_zip_reader_end(arch);
if (f) fclose(f);
}
}
void close_archive_writer(mz_zip_archive *arch) {
if (arch) {
FILE *f = mz_zip_get_cfile(arch);
mz_zip_writer_end(arch);
if (f) fclose(f);
}
}
}
bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig* config, Model* model, unsigned int& version) bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig* config, Model* model, unsigned int& version)
{ {
if (stat.m_uncomp_size == 0) if (stat.m_uncomp_size == 0)
{ {
printf("Found invalid size\n"); printf("Found invalid size\n");
mz_zip_reader_end(&archive); close_archive_reader(&archive);
return false; return false;
} }
XML_Parser parser = XML_ParserCreate(nullptr); // encoding XML_Parser parser = XML_ParserCreate(nullptr); // encoding
if (!parser) { if (!parser) {
printf("Couldn't allocate memory for parser\n"); printf("Couldn't allocate memory for parser\n");
mz_zip_reader_end(&archive); close_archive_reader(&archive);
return false; return false;
} }
@ -737,7 +755,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
if (parser_buffer == nullptr) if (parser_buffer == nullptr)
{ {
printf("Unable to create buffer\n"); printf("Unable to create buffer\n");
mz_zip_reader_end(&archive); close_archive_reader(&archive);
return false; return false;
} }
@ -745,14 +763,14 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
if (res == 0) if (res == 0)
{ {
printf("Error while reading model data to buffer\n"); printf("Error while reading model data to buffer\n");
mz_zip_reader_end(&archive); close_archive_reader(&archive);
return false; return false;
} }
if (!XML_ParseBuffer(parser, (int)stat.m_uncomp_size, 1)) if (!XML_ParseBuffer(parser, (int)stat.m_uncomp_size, 1))
{ {
printf("Error (%s) while parsing xml file at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); printf("Error (%s) while parsing xml file at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
mz_zip_reader_end(&archive); close_archive_reader(&archive);
return false; return false;
} }
@ -774,8 +792,10 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model
mz_zip_archive archive; mz_zip_archive archive;
mz_zip_zero_struct(&archive); mz_zip_zero_struct(&archive);
mz_bool res = mz_zip_reader_init_file(&archive, path, 0); FILE * f = boost::nowide::fopen(path, "rb");
if (res == 0) auto res = mz_bool(f == nullptr ? MZ_FALSE : MZ_TRUE);
res = res && mz_zip_reader_init_cfile(&archive, f, -1, 0);
if (res == MZ_FALSE)
{ {
printf("Unable to init zip reader\n"); printf("Unable to init zip reader\n");
return false; return false;
@ -793,7 +813,7 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model
{ {
if (!extract_model_from_archive(archive, stat, config, model, version)) if (!extract_model_from_archive(archive, stat, config, model, version))
{ {
mz_zip_reader_end(&archive); close_archive_reader(&archive);
printf("Archive does not contain a valid model"); printf("Archive does not contain a valid model");
return false; return false;
} }
@ -814,7 +834,7 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model
} }
#endif // forward compatibility #endif // forward compatibility
mz_zip_reader_end(&archive); close_archive_reader(&archive);
return true; return true;
} }
@ -854,7 +874,8 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config)
mz_zip_archive archive; mz_zip_archive archive;
mz_zip_zero_struct(&archive); mz_zip_zero_struct(&archive);
mz_bool res = mz_zip_writer_init_file(&archive, export_path.c_str(), 0); FILE *f = boost::nowide::fopen(export_path.c_str(), "wb");
auto res = mz_bool(f != nullptr && mz_zip_writer_init_cfile(&archive, f, 0));
if (res == 0) if (res == 0)
return false; return false;
@ -1018,19 +1039,20 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config)
if (!mz_zip_writer_add_mem(&archive, internal_amf_filename.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) if (!mz_zip_writer_add_mem(&archive, internal_amf_filename.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
if (f) fclose(f);
boost::filesystem::remove(export_path); boost::filesystem::remove(export_path);
return false; return false;
} }
if (!mz_zip_writer_finalize_archive(&archive)) if (!mz_zip_writer_finalize_archive(&archive))
{ {
mz_zip_writer_end(&archive); close_archive_writer(&archive);
boost::filesystem::remove(export_path); boost::filesystem::remove(export_path);
return false; return false;
} }
mz_zip_writer_end(&archive); close_archive_writer(&archive);
return true; return true;
} }

View file

@ -3,6 +3,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/nowide/convert.hpp> #include <boost/nowide/convert.hpp>
#include <boost/nowide/cstdio.hpp>
#include <miniz.h> #include <miniz.h>
@ -298,7 +299,9 @@ bool load_prus(const char *path, Model *model)
{ {
mz_zip_archive archive; mz_zip_archive archive;
mz_zip_zero_struct(&archive); mz_zip_zero_struct(&archive);
mz_bool res = mz_zip_reader_init_file(&archive, path, 0);
FILE *f = boost::nowide::fopen(path, "rb");
auto res = mz_bool(f != nullptr && mz_zip_reader_init_cfile(&archive, f, -1, 0));
size_t n_models_initial = model->objects.size(); size_t n_models_initial = model->objects.size();
try { try {
if (res == MZ_FALSE) if (res == MZ_FALSE)
@ -327,10 +330,12 @@ bool load_prus(const char *path, Model *model)
} }
} catch (std::exception &ex) { } catch (std::exception &ex) {
mz_zip_reader_end(&archive); mz_zip_reader_end(&archive);
if(f) fclose(f);
throw ex; throw ex;
} }
mz_zip_reader_end(&archive); mz_zip_reader_end(&archive);
if(f) fclose(f);
return model->objects.size() > n_models_initial; return model->objects.size() > n_models_initial;
} }

View file

@ -1,11 +1,9 @@
#include <exception> #include <exception>
#include <sstream>
#include <iostream>
#include "Zipper.hpp" #include "Zipper.hpp"
#include <miniz.h> #include <miniz.h>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <boost/nowide/cstdio.hpp>
#include "I18N.hpp" #include "I18N.hpp"
//! macro used to mark string used at localization, //! macro used to mark string used at localization,
@ -126,8 +124,15 @@ Zipper::Zipper(const std::string &zipfname, e_compression compression)
memset(&m_impl->arch, 0, sizeof(m_impl->arch)); memset(&m_impl->arch, 0, sizeof(m_impl->arch));
FILE *f = boost::nowide::fopen(zipfname.c_str(), "wb");
if (f == nullptr) {
m_impl->arch.m_last_error = MZ_ZIP_FILE_OPEN_FAILED;
m_impl->blow_up();
}
// Initialize the archive data // Initialize the archive data
if(!mz_zip_writer_init_file(&m_impl->arch, zipfname.c_str(), 0)) if(!mz_zip_writer_init_cfile(&m_impl->arch, f, 0))
m_impl->blow_up(); m_impl->blow_up();
} }
@ -143,9 +148,13 @@ Zipper::~Zipper()
BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr(); BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
} }
FILE *f = mz_zip_get_cfile(&m_impl->arch);
// The file should be closed no matter what... // The file should be closed no matter what...
if(!mz_zip_writer_end(&m_impl->arch)) if(!mz_zip_writer_end(&m_impl->arch))
BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr(); BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
if(f != nullptr) fclose(f);
} }
Zipper::Zipper(Zipper &&m): Zipper::Zipper(Zipper &&m):

View file

@ -2987,43 +2987,17 @@ extern "C" {
#include <sys/stat.h> #include <sys/stat.h>
#if defined(_MSC_VER) || defined(__MINGW64__) #if defined(_MSC_VER) || defined(__MINGW64__)
#include <windows.h>
struct WArgs { const wchar_t *fname, *mode; };
static struct WArgs utf8towide(const char* fname_utf8, const char * modestr)
{
static wchar_t buff[4096];
static wchar_t mode[50];
struct WArgs ret = { .fname = NULL, .mode = NULL };
if(MultiByteToWideChar(CP_UTF8, 0, fname_utf8, -1, buff, 4096) == 0)
return ret;
if(MultiByteToWideChar(CP_UTF8, 0, modestr, -1, mode, 50) == 0)
return ret;
ret.fname = buff, ret.mode = mode;
return ret;
}
static FILE *mz_fopen(const char *pFilename, const char *pMode) static FILE *mz_fopen(const char *pFilename, const char *pMode)
{ {
FILE *pFile = NULL; FILE *pFile = NULL;
fopen_s(&pFile, pFilename, pMode);
struct WArgs args = utf8towide(pFilename, pMode);
if(args.fname != NULL && args.mode != NULL)
if(_wfopen_s(&pFile, args.fname, args.mode)) return NULL;
return pFile; return pFile;
} }
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
{ {
FILE *pFile = NULL; FILE *pFile = NULL;
if (freopen_s(&pFile, pPath, pMode, pStream))
struct WArgs args = utf8towide(pPath, pMode); return NULL;
if(args.fname != NULL && args.mode != NULL)
if(_wfreopen_s(&pFile, args.fname, args.mode, pStream)) return NULL;
return pFile; return pFile;
} }
#ifndef MINIZ_NO_TIME #ifndef MINIZ_NO_TIME