diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index fbec5b00b..494da5fe6 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -32,7 +32,7 @@ namespace pt = boost::property_tree; // 0 : .3mf, files saved by older slic3r or other applications. No version definition in them. // 1 : Introduction of 3mf versioning. No other change in data saved into 3mf files. #if ENABLE_ENHANCED_RELOAD_FROM_DISK -// 2 : Meshes saved in their local system and volumes matrices added to Metadata/Slic3r_PE_model.config file. +// 2 : Meshes saved in their local system; Volumes' matrices and source data added to Metadata/Slic3r_PE_model.config file. const unsigned int VERSION_3MF = 2; #else const unsigned int VERSION_3MF = 1; @@ -208,35 +208,6 @@ Slic3r::Transform3d get_transform_from_string(const std::string& mat_str) return ret; } -#if ENABLE_ENHANCED_RELOAD_FROM_DISK -Slic3r::Transform3d get_transform_from_string(const std::string& mat_str) -{ - Slic3r::Transform3d ret = Slic3r::Transform3d::Identity(); - - if (mat_str.empty()) - // empty string means default identity matrix - return ret; - - std::vector mat_elements_str; - boost::split(mat_elements_str, mat_str, boost::is_any_of(" "), boost::token_compress_on); - - unsigned int size = (unsigned int)mat_elements_str.size(); - if (size != 16) - // invalid data, return identity matrix - return ret; - - unsigned int i = 0; - for (unsigned int r = 0; r < 4; ++r) - { - for (unsigned int c = 0; c < 4; ++c) - { - ret(r, c) = ::atof(mat_elements_str[i++].c_str()); - } - } - return ret; -} -#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK - float get_unit_factor(const std::string& unit) { const char* text = unit.c_str(); @@ -1744,7 +1715,11 @@ namespace Slic3r { volume->set_type(ModelVolume::type_from_string(metadata.value)); #if ENABLE_ENHANCED_RELOAD_FROM_DISK else if (metadata.key == MATRIX_KEY) - volume->set_transformation(Slic3r::Geometry::Transformation(get_transform_from_string(metadata.value))); + { + Slic3r::Geometry::Transformation transform; + transform.set_from_string(metadata.value); + volume->set_transformation(transform); + } else if (metadata.key == SOURCE_FILE_KEY) volume->source.input_file = metadata.value; else if (metadata.key == SOURCE_OBJECT_ID_KEY) diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index 92c958d8a..3f85b4b60 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -12,6 +12,9 @@ #include "../PrintConfig.hpp" #include "../Utils.hpp" #include "../I18N.hpp" +#if ENABLE_ENHANCED_RELOAD_FROM_DISK +#include "../Geometry.hpp" +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK #include "AMF.hpp" @@ -36,7 +39,12 @@ // Added x and y components of rotation // Added x, y and z components of scale // Added x, y and z components of mirror +#if ENABLE_ENHANCED_RELOAD_FROM_DISK +// 3 : Meshes saved in their local system; Added volumes' matrices and source data +const unsigned int VERSION_AMF = 3; +#else const unsigned int VERSION_AMF = 2; +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK const char* SLIC3RPE_AMF_VERSION = "slic3rpe_amf_version"; const char* SLIC3R_CONFIG_TYPE = "slic3rpe_config"; @@ -568,7 +576,12 @@ void AMFParserContext::endElement(const char * /* name */) stl_get_size(&stl); mesh.repair(); m_volume->set_mesh(std::move(mesh)); +#if ENABLE_ENHANCED_RELOAD_FROM_DISK + // pass false if the mesh offset has been already taken from the data + m_volume->center_geometry_after_creation(m_volume->source.input_file.empty()); +#else m_volume->center_geometry_after_creation(); +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK m_volume->calculate_convex_hull(); m_volume_facets.clear(); m_volume = nullptr; @@ -664,6 +677,31 @@ void AMFParserContext::endElement(const char * /* name */) } else if (strcmp(opt_key, "volume_type") == 0) { m_volume->set_type(ModelVolume::type_from_string(m_value[1])); } +#if ENABLE_ENHANCED_RELOAD_FROM_DISK + else if (strcmp(opt_key, "matrix") == 0) { + Geometry::Transformation transform; + transform.set_from_string(m_value[1]); + m_volume->set_transformation(transform); + } + else if (strcmp(opt_key, "source_file") == 0) { + m_volume->source.input_file = m_value[1]; + } + else if (strcmp(opt_key, "source_object_id") == 0) { + m_volume->source.object_idx = ::atoi(m_value[1].c_str()); + } + else if (strcmp(opt_key, "source_volume_id") == 0) { + m_volume->source.volume_idx = ::atoi(m_value[1].c_str()); + } + else if (strcmp(opt_key, "source_offset_x") == 0) { + m_volume->source.mesh_offset(0) = ::atof(m_value[1].c_str()); + } + else if (strcmp(opt_key, "source_offset_y") == 0) { + m_volume->source.mesh_offset(1) = ::atof(m_value[1].c_str()); + } + else if (strcmp(opt_key, "source_offset_z") == 0) { + m_volume->source.mesh_offset(2) = ::atof(m_value[1].c_str()); + } +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK } } else if (m_path.size() == 3) { if (m_path[1] == NODE_TYPE_MATERIAL) { @@ -1029,6 +1067,18 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) if (! volume->mesh().has_shared_vertices()) throw std::runtime_error("store_amf() requires shared vertices"); const indexed_triangle_set &its = volume->mesh().its; +#if ENABLE_ENHANCED_RELOAD_FROM_DISK + for (const Vec3f& v : its.vertices) + { + stream << " \n"; + stream << " \n"; + stream << " " << v(0) << "\n"; + stream << " " << v(1) << "\n"; + stream << " " << v(2) << "\n"; + stream << " \n"; + stream << " \n"; + } +#else const Transform3d& matrix = volume->get_matrix(); for (size_t i = 0; i < its.vertices.size(); ++i) { stream << " \n"; @@ -1040,6 +1090,7 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) stream << " \n"; stream << " \n"; } +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK num_vertices += (int)its.vertices.size(); } stream << " \n"; @@ -1057,7 +1108,30 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) if (volume->is_modifier()) stream << " 1\n"; stream << " " << ModelVolume::type_to_string(volume->type()) << "\n"; - const indexed_triangle_set &its = volume->mesh().its; +#if ENABLE_ENHANCED_RELOAD_FROM_DISK + stream << " "; + const Transform3d& matrix = volume->get_matrix(); + for (int r = 0; r < 4; ++r) + { + for (int c = 0; c < 4; ++c) + { + stream << matrix(r, c); + if ((r != 3) || (c != 3)) + stream << " "; + } + } + stream << "\n"; + if (!volume->source.input_file.empty()) + { + stream << " " << xml_escape(volume->source.input_file) << "\n"; + stream << " " << volume->source.object_idx << "\n"; + stream << " " << volume->source.volume_idx << "\n"; + stream << " " << volume->source.mesh_offset(0) << "\n"; + stream << " " << volume->source.mesh_offset(1) << "\n"; + stream << " " << volume->source.mesh_offset(2) << "\n"; + } +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK + const indexed_triangle_set &its = volume->mesh().its; for (size_t i = 0; i < its.indices.size(); ++i) { stream << " \n"; for (int j = 0; j < 3; ++j) diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index cc8a86a96..280233b2a 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -15,6 +15,11 @@ #include #include +#if ENABLE_ENHANCED_RELOAD_FROM_DISK +#include +#include +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK + #ifdef SLIC3R_DEBUG #include "SVG.hpp" #endif @@ -1376,6 +1381,34 @@ void Transformation::set_from_transform(const Transform3d& transform) // std::cout << "something went wrong in extracting data from matrix" << std::endl; } +#if ENABLE_ENHANCED_RELOAD_FROM_DISK +void Transformation::set_from_string(const std::string& transform_str) +{ + Transform3d transform = Transform3d::Identity(); + + if (!transform_str.empty()) + { + std::vector mat_elements_str; + boost::split(mat_elements_str, transform_str, boost::is_any_of(" "), boost::token_compress_on); + + unsigned int size = (unsigned int)mat_elements_str.size(); + if (size == 16) + { + unsigned int i = 0; + for (unsigned int r = 0; r < 4; ++r) + { + for (unsigned int c = 0; c < 4; ++c) + { + transform(r, c) = ::atof(mat_elements_str[i++].c_str()); + } + } + } + } + + set_from_transform(transform); +} +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK + void Transformation::reset() { m_offset = Vec3d::Zero(); diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index eec267322..43f791723 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -278,6 +278,9 @@ public: void set_mirror(Axis axis, double mirror); void set_from_transform(const Transform3d& transform); +#if ENABLE_ENHANCED_RELOAD_FROM_DISK + void set_from_string(const std::string& transform_str); +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK void reset(); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index d36f5b7ac..ffc4c2454 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1555,7 +1555,11 @@ bool ModelVolume::is_splittable() const return m_is_splittable == 1; } +#if ENABLE_ENHANCED_RELOAD_FROM_DISK +void ModelVolume::center_geometry_after_creation(bool update_source_offset) +#else void ModelVolume::center_geometry_after_creation() +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK { Vec3d shift = this->mesh().bounding_box().center(); if (!shift.isApprox(Vec3d::Zero())) @@ -1566,9 +1570,10 @@ void ModelVolume::center_geometry_after_creation() const_cast(m_convex_hull.get())->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2)); translate(shift); } -//================================================================================================================================================================================================ - source.mesh_offset = shift; -//================================================================================================================================================================================================ +#if ENABLE_ENHANCED_RELOAD_FROM_DISK + if (update_source_offset) + source.mesh_offset = shift; +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK } void ModelVolume::calculate_convex_hull() diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index c91f72a95..6a9bc82fa 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -453,7 +453,11 @@ public: // Translates the mesh and the convex hull so that the origin of their vertices is in the center of this volume's bounding box. // Attention! This method may only be called just after ModelVolume creation! It must not be called once the TriangleMesh of this ModelVolume is shared! +#if ENABLE_ENHANCED_RELOAD_FROM_DISK + void center_geometry_after_creation(bool update_source_offset = true); +#else void center_geometry_after_creation(); +#endif // ENABLE_ENHANCED_RELOAD_FROM_DISK void calculate_convex_hull(); const TriangleMesh& get_convex_hull() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 32ee6d57a..4db8d6858 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3188,6 +3188,7 @@ void Plater::priv::reload_from_disk() new_volume->set_new_unique_id(); new_volume->config.apply(old_volume->config); new_volume->set_type(old_volume->type()); + new_volume->set_material_id(old_volume->material_id()); new_volume->set_transformation(old_volume->get_transformation()); new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); std::swap(old_model_object->volumes[old_v.volume_idx], old_model_object->volumes.back());