From 16c5a87997e6ce1cea09cda8e2ca4aaf06676092 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 11 Jun 2019 09:50:58 +0200 Subject: [PATCH] Import/export of the Layers information to/from AMF --- src/libslic3r/Format/AMF.cpp | 57 ++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index d26b5f3ed..ed9c8f445 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -106,6 +106,9 @@ struct AMFParserContext // amf/material/metadata NODE_TYPE_OBJECT, // amf/object // amf/object/metadata + NODE_TYPE_LAYER_CONFIG, // amf/object/layer_config_ranges + NODE_TYPE_RANGE, // amf/object/layer_config_ranges/range + // amf/object/layer_config_ranges/range/metadata NODE_TYPE_MESH, // amf/object/mesh NODE_TYPE_VERTICES, // amf/object/mesh/vertices NODE_TYPE_VERTEX, // amf/object/mesh/vertices/vertex @@ -260,7 +263,9 @@ void AMFParserContext::startElement(const char *name, const char **atts) m_value[0] = get_attribute(atts, "type"); node_type_new = NODE_TYPE_METADATA; } - } else if (strcmp(name, "mesh") == 0) { + } else if (strcmp(name, "layer_config_ranges") == 0 && m_path[1] == NODE_TYPE_OBJECT) + node_type_new = NODE_TYPE_LAYER_CONFIG; + else if (strcmp(name, "mesh") == 0) { if (m_path[1] == NODE_TYPE_OBJECT) node_type_new = NODE_TYPE_MESH; } else if (strcmp(name, "instance") == 0) { @@ -317,6 +322,10 @@ void AMFParserContext::startElement(const char *name, const char **atts) else if (strcmp(name, "mirrorz") == 0) node_type_new = NODE_TYPE_MIRRORZ; } + else if (m_path[2] == NODE_TYPE_LAYER_CONFIG && strcmp(name, "range") == 0) { + assert(m_object); + node_type_new = NODE_TYPE_RANGE; + } break; case 4: if (m_path[3] == NODE_TYPE_VERTICES) { @@ -334,6 +343,10 @@ void AMFParserContext::startElement(const char *name, const char **atts) } else if (strcmp(name, "triangle") == 0) node_type_new = NODE_TYPE_TRIANGLE; } + else if (m_path[3] == NODE_TYPE_RANGE && strcmp(name, "metadata") == 0) { + m_value[0] = get_attribute(atts, "type"); + node_type_new = NODE_TYPE_METADATA; + } break; case 5: if (strcmp(name, "coordinates") == 0) { @@ -569,8 +582,13 @@ void AMFParserContext::endElement(const char * /* name */) config = &m_material->config; else if (m_path[1] == NODE_TYPE_OBJECT && m_object) config = &m_object->config; - } else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_VOLUME && m_volume) + } + else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_VOLUME && m_volume) config = &m_volume->config; + else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_RANGE && m_object && !m_object->layer_config_ranges.empty()) { + auto it = --m_object->layer_config_ranges.end(); + config = &it->second; + } if (config) config->set_deserialize(opt_key, m_value[1]); } else if (m_path.size() == 3 && m_path[1] == NODE_TYPE_OBJECT && m_object && strcmp(opt_key, "layer_height_profile") == 0) { @@ -607,6 +625,16 @@ void AMFParserContext::endElement(const char * /* name */) } m_object->sla_points_status = sla::PointsStatus::UserModified; } + else if (m_path.size() == 5 && m_path[1] == NODE_TYPE_OBJECT && m_path[3] == NODE_TYPE_RANGE && + m_object && strcmp(opt_key, "layer_height_ranges") == 0) { + // Parse object's layer_height_ranges, a semicolon separated doubles. + char* p = const_cast(m_value[1].c_str()); + char* end = strchr(p, ';'); + *end = 0; + + const t_layer_height_range range = {double(atof(p)), double(atof(end + 1))}; + m_object->layer_config_ranges[range]; + } else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_VOLUME && m_volume) { if (strcmp(opt_key, "modifier") == 0) { // Is this volume a modifier volume? @@ -905,6 +933,31 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) } //FIXME Store the layer height ranges (ModelObject::layer_height_ranges) + + // #ys_FIXME_experiment : Try to export layer config range + const t_layer_config_ranges& config_ranges = object->layer_config_ranges; + if (!config_ranges.empty()) + { + // Store the layer config range as a single semicolon separated list. + stream << " \n"; + size_t layer_counter = 0; + for (auto range : config_ranges) { + stream << " \n"; + + stream << " "; + stream << range.first.first << ";" << range.first.second << "\n"; + + for (const std::string& key : range.second.keys()) + stream << " " << range.second.serialize(key) << "\n"; + + stream << " \n"; + layer_counter++; + } + + stream << " \n"; + } + + const std::vector& sla_support_points = object->sla_support_points; if (!sla_support_points.empty()) { // Store the SLA supports as a single semicolon separated list.