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:
Diffstat (limited to 'src/libslic3r/Format/AMF.cpp')
-rw-r--r--src/libslic3r/Format/AMF.cpp82
1 files changed, 61 insertions, 21 deletions
diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp
index 2dc4ea0ba..07095d10b 100644
--- a/src/libslic3r/Format/AMF.cpp
+++ b/src/libslic3r/Format/AMF.cpp
@@ -7,6 +7,7 @@
#include <boost/nowide/cstdio.hpp>
#include "../libslic3r.h"
+#include "../Exception.hpp"
#include "../Model.hpp"
#include "../GCode.hpp"
#include "../PrintConfig.hpp"
@@ -240,7 +241,7 @@ struct AMFParserContext
// Current instance allocated for an amf/constellation/instance subtree.
Instance *m_instance;
// Generic string buffer for vertices, face indices, metadata etc.
- std::string m_value[4];
+ std::string m_value[5];
// Pointer to config to update if config data are stored inside the amf file
DynamicPrintConfig *m_config;
@@ -314,9 +315,26 @@ void AMFParserContext::startElement(const char *name, const char **atts)
if (strcmp(name, "code") == 0) {
node_type_new = NODE_TYPE_GCODE_PER_HEIGHT;
m_value[0] = get_attribute(atts, "print_z");
- m_value[1] = get_attribute(atts, "gcode");
- m_value[2] = get_attribute(atts, "extruder");
- m_value[3] = get_attribute(atts, "color");
+ m_value[1] = get_attribute(atts, "extruder");
+ m_value[2] = get_attribute(atts, "color");
+ if (get_attribute(atts, "type"))
+ {
+ m_value[3] = get_attribute(atts, "type");
+ m_value[4] = get_attribute(atts, "extra");
+ }
+ else
+ {
+ // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer
+ // read old data ...
+ std::string gcode = get_attribute(atts, "gcode");
+ // ... and interpret them to the new data
+ CustomGCode::Type type= gcode == "M600" ? CustomGCode::ColorChange :
+ gcode == "M601" ? CustomGCode::PausePrint :
+ gcode == "tool_change" ? CustomGCode::ToolChange : CustomGCode::Custom;
+ m_value[3] = std::to_string(static_cast<int>(type));
+ m_value[4] = type == CustomGCode::PausePrint ? m_value[2] :
+ type == CustomGCode::Custom ? gcode : "";
+ }
}
else if (strcmp(name, "mode") == 0) {
node_type_new = NODE_TYPE_CUSTOM_GCODE_MODE;
@@ -640,12 +658,13 @@ void AMFParserContext::endElement(const char * /* name */)
break;
case NODE_TYPE_GCODE_PER_HEIGHT: {
- double print_z = double(atof(m_value[0].c_str()));
- const std::string& gcode = m_value[1];
- int extruder = atoi(m_value[2].c_str());
- const std::string& color = m_value[3];
+ double print_z = double(atof(m_value[0].c_str()));
+ int extruder = atoi(m_value[1].c_str());
+ const std::string& color= m_value[2];
+ CustomGCode::Type type = static_cast<CustomGCode::Type>(atoi(m_value[3].c_str()));
+ const std::string& extra= m_value[4];
- m_model.custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, gcode, extruder, color});
+ m_model.custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, type, extruder, color, extra});
for (std::string& val: m_value)
val.clear();
@@ -669,7 +688,7 @@ void AMFParserContext::endElement(const char * /* name */)
else if (strncmp(m_value[0].c_str(), "slic3r.", 7) == 0) {
const char *opt_key = m_value[0].c_str() + 7;
if (print_config_def.options.find(opt_key) != print_config_def.options.end()) {
- DynamicPrintConfig *config = nullptr;
+ ModelConfig *config = nullptr;
if (m_path.size() == 3) {
if (m_path[1] == NODE_TYPE_MATERIAL && m_material)
config = &m_material->config;
@@ -687,15 +706,17 @@ void AMFParserContext::endElement(const char * /* name */)
} else if (m_path.size() == 3 && m_path[1] == NODE_TYPE_OBJECT && m_object && strcmp(opt_key, "layer_height_profile") == 0) {
// Parse object's layer height profile, a semicolon separated list of floats.
char *p = m_value[1].data();
+ std::vector<coordf_t> data;
for (;;) {
char *end = strchr(p, ';');
if (end != nullptr)
*end = 0;
- m_object->layer_height_profile.push_back(float(atof(p)));
+ data.emplace_back(float(atof(p)));
if (end == nullptr)
break;
p = end + 1;
}
+ m_object->layer_height_profile.set(std::move(data));
}
else if (m_path.size() == 3 && m_path[1] == NODE_TYPE_OBJECT && m_object && strcmp(opt_key, "sla_support_points") == 0) {
// Parse object's layer height profile, a semicolon separated list of floats.
@@ -757,6 +778,9 @@ void AMFParserContext::endElement(const char * /* name */)
else if (strcmp(opt_key, "source_offset_z") == 0) {
m_volume->source.mesh_offset(2) = ::atof(m_value[1].c_str());
}
+ else if (strcmp(opt_key, "source_in_inches") == 0) {
+ m_volume->source.is_converted_from_inches = m_value[1] == "1";
+ }
}
} else if (m_path.size() == 3) {
if (m_path[1] == NODE_TYPE_MATERIAL) {
@@ -905,7 +929,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
{
char error_buf[1024];
::sprintf(error_buf, "Error (%s) while parsing '%s' at line %d", XML_ErrorString(XML_GetErrorCode(data->parser)), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser));
- throw std::runtime_error(error_buf);
+ throw Slic3r::FileIOError(error_buf);
}
return n;
@@ -930,9 +954,9 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
if (check_version && (ctx.m_version > VERSION_AMF_COMPATIBLE))
{
// std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible."));
- // throw std::runtime_error(msg.c_str());
+ // throw Slic3r::FileIOError(msg.c_str());
const std::string msg = (boost::format(_(L("The selected amf file has been saved with a newer version of %1% and is not compatible."))) % std::string(SLIC3R_APP_NAME)).str();
- throw std::runtime_error(msg);
+ throw Slic3r::FileIOError(msg);
}
return true;
@@ -976,7 +1000,7 @@ bool load_amf_archive(const char* path, DynamicPrintConfig* config, Model* model
{
// ensure the zip archive is closed and rethrow the exception
close_zip_reader(&archive);
- throw std::runtime_error(e.what());
+ throw Slic3r::FileIOError(e.what());
}
break;
@@ -996,6 +1020,12 @@ bool load_amf_archive(const char* path, DynamicPrintConfig* config, Model* model
#endif // forward compatibility
close_zip_reader(&archive);
+
+ for (ModelObject *o : model->objects)
+ for (ModelVolume *v : o->volumes)
+ if (v->source.input_file.empty() && (v->type() == ModelVolumeType::MODEL_PART))
+ v->source.input_file = path;
+
return true;
}
@@ -1076,7 +1106,7 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config,
stream << " <metadata type=\"slic3r." << key << "\">" << object->config.opt_serialize(key) << "</metadata>\n";
if (!object->name.empty())
stream << " <metadata type=\"name\">" << xml_escape(object->name) << "</metadata>\n";
- const std::vector<double> &layer_height_profile = object->layer_height_profile;
+ const std::vector<double> &layer_height_profile = object->layer_height_profile.get();
if (layer_height_profile.size() >= 4 && (layer_height_profile.size() % 2) == 0) {
// Store the layer height profile as a single semicolon separated list.
stream << " <metadata type=\"slic3r.layer_height_profile\">";
@@ -1093,7 +1123,7 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config,
// Store the layer config range as a single semicolon separated list.
stream << " <layer_config_ranges>\n";
size_t layer_counter = 0;
- for (auto range : config_ranges) {
+ for (const auto &range : config_ranges) {
stream << " <range id=\"" << layer_counter << "\">\n";
stream << " <metadata type=\"slic3r.layer_height_range\">";
@@ -1129,9 +1159,9 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config,
for (ModelVolume *volume : object->volumes) {
vertices_offsets.push_back(num_vertices);
if (! volume->mesh().repaired)
- throw std::runtime_error("store_amf() requires repair()");
+ throw Slic3r::FileIOError("store_amf() requires repair()");
if (! volume->mesh().has_shared_vertices())
- throw std::runtime_error("store_amf() requires shared vertices");
+ throw Slic3r::FileIOError("store_amf() requires shared vertices");
const indexed_triangle_set &its = volume->mesh().its;
const Transform3d& matrix = volume->get_matrix();
for (size_t i = 0; i < its.vertices.size(); ++i) {
@@ -1184,6 +1214,8 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config,
stream << " <metadata type=\"slic3r.source_offset_y\">" << volume->source.mesh_offset(1) << "</metadata>\n";
stream << " <metadata type=\"slic3r.source_offset_z\">" << volume->source.mesh_offset(2) << "</metadata>\n";
}
+ if (volume->source.is_converted_from_inches)
+ stream << " <metadata type=\"slic3r.source_in_inches\">1</metadata>\n";
stream << std::setprecision(std::numeric_limits<float>::max_digits10);
const indexed_triangle_set &its = volume->mesh().its;
for (size_t i = 0; i < its.indices.size(); ++i) {
@@ -1200,7 +1232,7 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config,
for (ModelInstance *instance : object->instances) {
char buf[512];
sprintf(buf,
- " <instance objectid=\"" PRINTF_ZU "\">\n"
+ " <instance objectid=\"%zu\">\n"
" <deltax>%lf</deltax>\n"
" <deltay>%lf</deltay>\n"
" <deltaz>%lf</deltaz>\n"
@@ -1253,9 +1285,17 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config,
pt::ptree& code_tree = main_tree.add("code", "");
// store custom_gcode_per_print_z gcodes information
code_tree.put("<xmlattr>.print_z" , code.print_z );
- code_tree.put("<xmlattr>.gcode" , code.gcode );
+ code_tree.put("<xmlattr>.type" , static_cast<int>(code.type));
code_tree.put("<xmlattr>.extruder" , code.extruder );
code_tree.put("<xmlattr>.color" , code.color );
+ code_tree.put("<xmlattr>.extra" , code.extra );
+
+ // add gcode field data for the old version of the PrusaSlicer
+ std::string gcode = code.type == CustomGCode::ColorChange ? config->opt_string("color_change_gcode") :
+ code.type == CustomGCode::PausePrint ? config->opt_string("pause_print_gcode") :
+ code.type == CustomGCode::Template ? config->opt_string("template_custom_gcode") :
+ code.type == CustomGCode::ToolChange ? "tool_change" : code.extra;
+ code_tree.put("<xmlattr>.gcode" , gcode );
}
pt::ptree& mode_tree = main_tree.add("mode", "");