mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-20 01:28:07 +08:00
Merge branch 'master' of https://github.com/Prusa3d/PrusaSlicer
This commit is contained in:
commit
93c6915e9d
@ -350,6 +350,7 @@ namespace Slic3r {
|
|||||||
|
|
||||||
// Version of the 3mf file
|
// Version of the 3mf file
|
||||||
unsigned int m_version;
|
unsigned int m_version;
|
||||||
|
bool m_check_version;
|
||||||
|
|
||||||
XML_Parser m_xml_parser;
|
XML_Parser m_xml_parser;
|
||||||
Model* m_model;
|
Model* m_model;
|
||||||
@ -372,7 +373,7 @@ namespace Slic3r {
|
|||||||
_3MF_Importer();
|
_3MF_Importer();
|
||||||
~_3MF_Importer();
|
~_3MF_Importer();
|
||||||
|
|
||||||
bool load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config);
|
bool load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config, bool check_version);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _destroy_xml_parser();
|
void _destroy_xml_parser();
|
||||||
@ -465,6 +466,7 @@ namespace Slic3r {
|
|||||||
|
|
||||||
_3MF_Importer::_3MF_Importer()
|
_3MF_Importer::_3MF_Importer()
|
||||||
: m_version(0)
|
: m_version(0)
|
||||||
|
, m_check_version(false)
|
||||||
, m_xml_parser(nullptr)
|
, m_xml_parser(nullptr)
|
||||||
, m_model(nullptr)
|
, m_model(nullptr)
|
||||||
, m_unit_factor(1.0f)
|
, m_unit_factor(1.0f)
|
||||||
@ -479,9 +481,10 @@ namespace Slic3r {
|
|||||||
_destroy_xml_parser();
|
_destroy_xml_parser();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _3MF_Importer::load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config)
|
bool _3MF_Importer::load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config, bool check_version)
|
||||||
{
|
{
|
||||||
m_version = 0;
|
m_version = 0;
|
||||||
|
m_check_version = check_version;
|
||||||
m_model = &model;
|
m_model = &model;
|
||||||
m_unit_factor = 1.0f;
|
m_unit_factor = 1.0f;
|
||||||
m_curr_object.reset();
|
m_curr_object.reset();
|
||||||
@ -542,6 +545,8 @@ namespace Slic3r {
|
|||||||
std::replace(name.begin(), name.end(), '\\', '/');
|
std::replace(name.begin(), name.end(), '\\', '/');
|
||||||
|
|
||||||
if (boost::algorithm::istarts_with(name, MODEL_FOLDER) && boost::algorithm::iends_with(name, MODEL_EXTENSION))
|
if (boost::algorithm::istarts_with(name, MODEL_FOLDER) && boost::algorithm::iends_with(name, MODEL_EXTENSION))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// valid model name -> extract model
|
// valid model name -> extract model
|
||||||
if (!_extract_model_from_archive(archive, stat))
|
if (!_extract_model_from_archive(archive, stat))
|
||||||
@ -551,6 +556,13 @@ namespace Slic3r {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
// ensure the zip archive is closed and rethrow the exception
|
||||||
|
close_zip_reader(&archive);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1399,8 +1411,16 @@ namespace Slic3r {
|
|||||||
bool _3MF_Importer::_handle_end_metadata()
|
bool _3MF_Importer::_handle_end_metadata()
|
||||||
{
|
{
|
||||||
if (m_curr_metadata_name == SLIC3RPE_3MF_VERSION)
|
if (m_curr_metadata_name == SLIC3RPE_3MF_VERSION)
|
||||||
|
{
|
||||||
m_version = (unsigned int)atoi(m_curr_characters.c_str());
|
m_version = (unsigned int)atoi(m_curr_characters.c_str());
|
||||||
|
|
||||||
|
if (m_check_version && (m_version > VERSION_3MF))
|
||||||
|
{
|
||||||
|
std::string msg = "The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatibile.";
|
||||||
|
throw std::runtime_error(msg.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2316,13 +2336,13 @@ namespace Slic3r {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model)
|
bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version)
|
||||||
{
|
{
|
||||||
if ((path == nullptr) || (config == nullptr) || (model == nullptr))
|
if ((path == nullptr) || (config == nullptr) || (model == nullptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_3MF_Importer importer;
|
_3MF_Importer importer;
|
||||||
bool res = importer.load_model_from_file(path, *model, *config);
|
bool res = importer.load_model_from_file(path, *model, *config, check_version);
|
||||||
importer.log_errors();
|
importer.log_errors();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace Slic3r {
|
|||||||
class DynamicPrintConfig;
|
class DynamicPrintConfig;
|
||||||
|
|
||||||
// Load the content of a 3mf file into the given model and preset bundle.
|
// Load the content of a 3mf file into the given model and preset bundle.
|
||||||
extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model);
|
extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version);
|
||||||
|
|
||||||
// Save the given model and the config data contained in the given Print into a 3mf file.
|
// Save the given model and the config data contained in the given Print into a 3mf file.
|
||||||
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
|
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
|
||||||
|
@ -44,7 +44,7 @@ namespace Slic3r
|
|||||||
|
|
||||||
struct AMFParserContext
|
struct AMFParserContext
|
||||||
{
|
{
|
||||||
AMFParserContext(XML_Parser parser, DynamicPrintConfig *config, Model *model) :
|
AMFParserContext(XML_Parser parser, DynamicPrintConfig* config, Model* model) :
|
||||||
m_version(0),
|
m_version(0),
|
||||||
m_parser(parser),
|
m_parser(parser),
|
||||||
m_model(*model),
|
m_model(*model),
|
||||||
@ -755,7 +755,7 @@ bool load_amf_file(const char *path, DynamicPrintConfig *config, Model *model)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, bool check_version)
|
||||||
{
|
{
|
||||||
if (stat.m_uncomp_size == 0)
|
if (stat.m_uncomp_size == 0)
|
||||||
{
|
{
|
||||||
@ -801,19 +801,21 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
|
|||||||
|
|
||||||
ctx.endDocument();
|
ctx.endDocument();
|
||||||
|
|
||||||
version = ctx.m_version;
|
if (check_version && (ctx.m_version > VERSION_AMF))
|
||||||
|
{
|
||||||
|
std::string msg = "The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatibile.";
|
||||||
|
throw std::runtime_error(msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load an AMF archive into a provided model.
|
// Load an AMF archive into a provided model.
|
||||||
bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model)
|
bool load_amf_archive(const char* path, DynamicPrintConfig* config, Model* model, bool check_version)
|
||||||
{
|
{
|
||||||
if ((path == nullptr) || (model == nullptr))
|
if ((path == nullptr) || (model == nullptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int version = 0;
|
|
||||||
|
|
||||||
mz_zip_archive archive;
|
mz_zip_archive archive;
|
||||||
mz_zip_zero_struct(&archive);
|
mz_zip_zero_struct(&archive);
|
||||||
|
|
||||||
@ -833,12 +835,21 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model
|
|||||||
{
|
{
|
||||||
if (boost::iends_with(stat.m_filename, ".amf"))
|
if (boost::iends_with(stat.m_filename, ".amf"))
|
||||||
{
|
{
|
||||||
if (!extract_model_from_archive(archive, stat, config, model, version))
|
try
|
||||||
|
{
|
||||||
|
if (!extract_model_from_archive(archive, stat, config, model, check_version))
|
||||||
{
|
{
|
||||||
close_zip_reader(&archive);
|
close_zip_reader(&archive);
|
||||||
printf("Archive does not contain a valid model");
|
printf("Archive does not contain a valid model");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
// ensure the zip archive is closed and rethrow the exception
|
||||||
|
close_zip_reader(&archive);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -862,7 +873,7 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model
|
|||||||
|
|
||||||
// Load an AMF file into a provided model.
|
// Load an AMF file into a provided model.
|
||||||
// If config is not a null pointer, updates it if the amf file/archive contains config data
|
// If config is not a null pointer, updates it if the amf file/archive contains config data
|
||||||
bool load_amf(const char *path, DynamicPrintConfig *config, Model *model)
|
bool load_amf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version)
|
||||||
{
|
{
|
||||||
if (boost::iends_with(path, ".amf.xml"))
|
if (boost::iends_with(path, ".amf.xml"))
|
||||||
// backward compatibility with older slic3r output
|
// backward compatibility with older slic3r output
|
||||||
@ -877,7 +888,7 @@ bool load_amf(const char *path, DynamicPrintConfig *config, Model *model)
|
|||||||
file.read(const_cast<char*>(zip_mask.data()), 2);
|
file.read(const_cast<char*>(zip_mask.data()), 2);
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
return (zip_mask == "PK") ? load_amf_archive(path, config, model) : load_amf_file(path, config, model);
|
return (zip_mask == "PK") ? load_amf_archive(path, config, model, check_version) : load_amf_file(path, config, model);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -7,7 +7,7 @@ class Model;
|
|||||||
class DynamicPrintConfig;
|
class DynamicPrintConfig;
|
||||||
|
|
||||||
// Load the content of an amf file into the given model and configuration.
|
// Load the content of an amf file into the given model and configuration.
|
||||||
extern bool load_amf(const char *path, DynamicPrintConfig *config, Model *model);
|
extern bool load_amf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version);
|
||||||
|
|
||||||
// Save the given model and the config data into an amf file.
|
// Save the given model and the config data into an amf file.
|
||||||
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
|
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
|
||||||
|
@ -84,7 +84,7 @@ void Model::update_links_bottom_up_recursive()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Model Model::read_from_file(const std::string &input_file, DynamicPrintConfig *config, bool add_default_instances)
|
Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* config, bool add_default_instances, bool check_version)
|
||||||
{
|
{
|
||||||
Model model;
|
Model model;
|
||||||
|
|
||||||
@ -98,9 +98,9 @@ Model Model::read_from_file(const std::string &input_file, DynamicPrintConfig *c
|
|||||||
else if (boost::algorithm::iends_with(input_file, ".obj"))
|
else if (boost::algorithm::iends_with(input_file, ".obj"))
|
||||||
result = load_obj(input_file.c_str(), &model);
|
result = load_obj(input_file.c_str(), &model);
|
||||||
else if (boost::algorithm::iends_with(input_file, ".amf") || boost::algorithm::iends_with(input_file, ".amf.xml"))
|
else if (boost::algorithm::iends_with(input_file, ".amf") || boost::algorithm::iends_with(input_file, ".amf.xml"))
|
||||||
result = load_amf(input_file.c_str(), config, &model);
|
result = load_amf(input_file.c_str(), config, &model, check_version);
|
||||||
else if (boost::algorithm::iends_with(input_file, ".3mf"))
|
else if (boost::algorithm::iends_with(input_file, ".3mf"))
|
||||||
result = load_3mf(input_file.c_str(), config, &model);
|
result = load_3mf(input_file.c_str(), config, &model, false);
|
||||||
else if (boost::algorithm::iends_with(input_file, ".prusa"))
|
else if (boost::algorithm::iends_with(input_file, ".prusa"))
|
||||||
result = load_prus(input_file.c_str(), &model);
|
result = load_prus(input_file.c_str(), &model);
|
||||||
else
|
else
|
||||||
@ -121,15 +121,15 @@ Model Model::read_from_file(const std::string &input_file, DynamicPrintConfig *c
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
Model Model::read_from_archive(const std::string &input_file, DynamicPrintConfig *config, bool add_default_instances)
|
Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig* config, bool add_default_instances, bool check_version)
|
||||||
{
|
{
|
||||||
Model model;
|
Model model;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (boost::algorithm::iends_with(input_file, ".3mf"))
|
if (boost::algorithm::iends_with(input_file, ".3mf"))
|
||||||
result = load_3mf(input_file.c_str(), config, &model);
|
result = load_3mf(input_file.c_str(), config, &model, check_version);
|
||||||
else if (boost::algorithm::iends_with(input_file, ".zip.amf"))
|
else if (boost::algorithm::iends_with(input_file, ".zip.amf"))
|
||||||
result = load_amf(input_file.c_str(), config, &model);
|
result = load_amf(input_file.c_str(), config, &model, check_version);
|
||||||
else
|
else
|
||||||
throw std::runtime_error("Unknown file format. Input file must have .3mf or .zip.amf extension.");
|
throw std::runtime_error("Unknown file format. Input file must have .3mf or .zip.amf extension.");
|
||||||
|
|
||||||
|
@ -747,8 +747,8 @@ public:
|
|||||||
|
|
||||||
OBJECTBASE_DERIVED_COPY_MOVE_CLONE(Model)
|
OBJECTBASE_DERIVED_COPY_MOVE_CLONE(Model)
|
||||||
|
|
||||||
static Model read_from_file(const std::string &input_file, DynamicPrintConfig *config = nullptr, bool add_default_instances = true);
|
static Model read_from_file(const std::string& input_file, DynamicPrintConfig* config = nullptr, bool add_default_instances = true, bool check_version = false);
|
||||||
static Model read_from_archive(const std::string &input_file, DynamicPrintConfig *config, bool add_default_instances = true);
|
static Model read_from_archive(const std::string& input_file, DynamicPrintConfig* config, bool add_default_instances = true, bool check_version = false);
|
||||||
|
|
||||||
// Add a new ModelObject to this Model, generate a new ID for this ModelObject.
|
// Add a new ModelObject to this Model, generate a new ID for this ModelObject.
|
||||||
ModelObject* add_object();
|
ModelObject* add_object();
|
||||||
|
@ -9,11 +9,6 @@
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
enum {
|
|
||||||
DLG_WIDTH = 90,
|
|
||||||
DLG_HEIGHT = 60
|
|
||||||
};
|
|
||||||
|
|
||||||
KBShortcutsDialog::KBShortcutsDialog()
|
KBShortcutsDialog::KBShortcutsDialog()
|
||||||
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Keyboard Shortcuts")),
|
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Keyboard Shortcuts")),
|
||||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||||
@ -39,9 +34,7 @@ KBShortcutsDialog::KBShortcutsDialog()
|
|||||||
|
|
||||||
fill_shortcuts();
|
fill_shortcuts();
|
||||||
|
|
||||||
const int em = em_unit();
|
panel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, get_size());
|
||||||
const wxSize& size = wxSize(DLG_WIDTH * em, DLG_HEIGHT * em);
|
|
||||||
panel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, size);
|
|
||||||
panel->SetScrollbars(1, 20, 1, 2);
|
panel->SetScrollbars(1, 20, 1, 2);
|
||||||
|
|
||||||
auto main_grid_sizer = new wxFlexGridSizer(2, 10, 10);
|
auto main_grid_sizer = new wxFlexGridSizer(2, 10, 10);
|
||||||
@ -216,7 +209,7 @@ void KBShortcutsDialog::on_dpi_changed(const wxRect &suggested_rect)
|
|||||||
|
|
||||||
msw_buttons_rescale(this, em, { wxID_OK });
|
msw_buttons_rescale(this, em, { wxID_OK });
|
||||||
|
|
||||||
const wxSize& size = wxSize(DLG_WIDTH * em, DLG_HEIGHT * em);
|
wxSize size = get_size();
|
||||||
|
|
||||||
panel->SetMinSize(size);
|
panel->SetMinSize(size);
|
||||||
|
|
||||||
@ -231,5 +224,30 @@ void KBShortcutsDialog::onCloseDialog(wxEvent &)
|
|||||||
this->EndModal(wxID_CLOSE);
|
this->EndModal(wxID_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxSize KBShortcutsDialog::get_size()
|
||||||
|
{
|
||||||
|
wxTopLevelWindow* window = Slic3r::GUI::find_toplevel_parent(this);
|
||||||
|
const int display_idx = wxDisplay::GetFromWindow(window);
|
||||||
|
wxRect display;
|
||||||
|
if (display_idx == wxNOT_FOUND) {
|
||||||
|
display = wxDisplay(0u).GetClientArea();
|
||||||
|
window->Move(display.GetTopLeft());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
display = wxDisplay(display_idx).GetClientArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
const int em = em_unit();
|
||||||
|
wxSize dialog_size = wxSize(90 * em, 85 * em);
|
||||||
|
|
||||||
|
const int margin = 10 * em;
|
||||||
|
if (dialog_size.x > display.GetWidth())
|
||||||
|
dialog_size.x = display.GetWidth() - margin;
|
||||||
|
if (dialog_size.y > display.GetHeight())
|
||||||
|
dialog_size.y = display.GetHeight() - margin;
|
||||||
|
|
||||||
|
return dialog_size;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -39,6 +39,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void onCloseDialog(wxEvent &);
|
void onCloseDialog(wxEvent &);
|
||||||
|
wxSize get_size();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
@ -2215,7 +2215,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||||||
DynamicPrintConfig config;
|
DynamicPrintConfig config;
|
||||||
{
|
{
|
||||||
DynamicPrintConfig config_loaded;
|
DynamicPrintConfig config_loaded;
|
||||||
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, false);
|
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, false, load_config);
|
||||||
if (load_config && !config_loaded.empty()) {
|
if (load_config && !config_loaded.empty()) {
|
||||||
// Based on the printer technology field found in the loaded config, select the base for the config,
|
// Based on the printer technology field found in the loaded config, select the base for the config,
|
||||||
PrinterTechnology printer_technology = Preset::printer_technology(config_loaded);
|
PrinterTechnology printer_technology = Preset::printer_technology(config_loaded);
|
||||||
@ -2255,7 +2255,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
model = Slic3r::Model::read_from_file(path.string(), nullptr, false);
|
model = Slic3r::Model::read_from_file(path.string(), nullptr, false, load_config);
|
||||||
for (auto obj : model.objects)
|
for (auto obj : model.objects)
|
||||||
if (obj->name.empty())
|
if (obj->name.empty())
|
||||||
obj->name = fs::path(obj->input_file).filename().string();
|
obj->name = fs::path(obj->input_file).filename().string();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user