diff --git a/src/libslic3r/BoundingBox.hpp b/src/libslic3r/BoundingBox.hpp index 26302f702..b12ed5551 100644 --- a/src/libslic3r/BoundingBox.hpp +++ b/src/libslic3r/BoundingBox.hpp @@ -161,4 +161,15 @@ inline bool empty(const BoundingBox3Base<VT> &bb) } // namespace Slic3r +#include <cereal/types/polymorphic.hpp> +#include <cereal/archives/binary.hpp> + +// Serialization through the Cereal library +namespace cereal { + template<class Archive> void serialize(Archive& archive, Slic3r::BoundingBox &bb) { archive(bb.min, bb.max, bb.defined); } + template<class Archive> void serialize(Archive& archive, Slic3r::BoundingBox3 &bb) { archive(bb.min, bb.max, bb.defined); } + template<class Archive> void serialize(Archive& archive, Slic3r::BoundingBoxf &bb) { archive(bb.min, bb.max, bb.defined); } + template<class Archive> void serialize(Archive& archive, Slic3r::BoundingBoxf3 &bb) { archive(bb.min, bb.max, bb.defined); } +} + #endif diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 7b3c5c73a..d1fb9b7f4 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -744,7 +744,7 @@ public: private: friend class cereal::access; - template<class Archive> void serialize(Archive &ar) { ar(this->value.x(), this->value.y()); } + template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<Vec2d>>(this)); } }; class ConfigOptionPoints : public ConfigOptionVector<Vec2d> @@ -853,7 +853,7 @@ public: private: friend class cereal::access; - template<class Archive> void serialize(Archive &ar) { ar(this->value.x(), this->value.y(), this->value.z()); } + template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<Vec3d>>(this)); } }; class ConfigOptionBool : public ConfigOptionSingle<bool> diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index bcbe80a0d..f1987734f 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -7,6 +7,10 @@ #include "Polygon.hpp" #include "Polyline.hpp" +// Serialization through the Cereal library +#include <cereal/types/polymorphic.hpp> +#include <cereal/archives/binary.hpp> + #include "boost/polygon/voronoi.hpp" using boost::polygon::voronoi_builder; using boost::polygon::voronoi_diagram; @@ -263,6 +267,25 @@ public: // as possible in least squares norm in regard to the 8 corners of bbox. // Bounding box is expected to be centered around zero in all axes. static Transformation volume_to_bed_transformation(const Transformation& instance_transformation, const BoundingBoxf3& bbox); + +private: + template<class Archive> void load(Archive& archive, Slic3r::Geometry::Transformation &t) { + archive.loadBinary((char*)m.data(), sizeof(float) * 4); + } + template<class Archive> void save(Archive& archive, const Slic3r::Geometry::Transformation &t) const { + archive.saveBinary((char*)m.data(), sizeof(float) * 4); + } + +private: + friend class cereal::access; + template<class Archive> void serialize(Archive & ar) { ar(m_offset, m_rotation, m_scaling_factor, m_mirror); } + explicit Transformation(int) : m_dirty(true) {} + template <class Archive> static void load_and_construct(Archive & ar, cereal::construct<Transformation> &construct) + { + // Calling a private constructor with special "int" parameter to indicate that no construction is necessary. + construct(1); + ar(construct.ptr()->m_offset, construct.ptr()->m_rotation, construct.ptr()->m_scaling_factor, m_mirror); + } }; // Rotation when going from the first coordinate system with rotation rot_xyz_from applied diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 596f80671..da7d9e4d3 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1910,3 +1910,16 @@ void check_model_ids_equal(const Model &model1, const Model &model2) #endif /* NDEBUG */ } + +#if 0 +CEREAL_REGISTER_TYPE(Slic3r::ModelBase) +CEREAL_REGISTER_TYPE(Slic3r::ModelObject) +CEREAL_REGISTER_TYPE(Slic3r::ModelVolume) +CEREAL_REGISTER_TYPE(Slic3r::ModelInstance) +CEREAL_REGISTER_TYPE(Slic3r::Model) + +CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ModelBase, Slic3r::ModelObject) +CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ModelBase, Slic3r::ModelVolume) +CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ModelBase, Slic3r::ModelInstance) +CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ModelBase, Slic3r::Model) +#endif \ No newline at end of file diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 0fd1140f0..3330f140d 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -40,8 +40,9 @@ typedef std::vector<ModelInstance*> ModelInstancePtrs; // Valid IDs are strictly positive (non zero). // It is declared as an object, as some compilers (notably msvcc) consider a typedef size_t equivalent to size_t // for parameter overload. -struct ModelID +class ModelID { +public: ModelID(size_t id) : id(id) {} bool operator==(const ModelID &rhs) const { return this->id == rhs.id; } @@ -54,6 +55,12 @@ struct ModelID bool valid() const { return id != 0; } size_t id; + +private: + ModelID() {} + + friend class cereal::access; + template<class Archive> void serialize(Archive &ar) { ar(id); } }; // Unique object / instance ID for the wipe tower. @@ -76,6 +83,8 @@ protected: // Constructor with ignored int parameter to assign an invalid ID, to be replaced // by an existing ID copied from elsewhere. ModelBase(int) : m_id(ModelID(0)) {} + // The class tree will have virtual tables and type information. + virtual ~ModelBase() {} // Use with caution! void set_new_unique_id() { m_id = generate_new_id(); } @@ -94,6 +103,11 @@ private: friend ModelID wipe_tower_object_id(); friend ModelID wipe_tower_instance_id(); + + friend class cereal::access; + template<class Archive> void serialize(Archive &ar) { ar(m_id); } + ModelBase(const ModelID id) : m_id(id) {} + template<class Archive> static void load_and_construct(Archive & ar, cereal::construct<ModelBase> &construct) { ModelID id; ar(id); construct(id); } }; #define MODELBASE_DERIVED_COPY_MOVE_CLONE(TYPE) \ @@ -155,10 +169,13 @@ private: // Parent, owning this material. Model *m_model; - ModelMaterial() = delete; ModelMaterial(ModelMaterial &&rhs) = delete; ModelMaterial& operator=(const ModelMaterial &rhs) = delete; ModelMaterial& operator=(ModelMaterial &&rhs) = delete; + + friend class cereal::access; + ModelMaterial() : m_model(nullptr) {} + template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ModelBase>(this)); ar(attributes, config); } }; // A printable object, possibly having multiple print volumes (each with its own set of parameters and materials), @@ -323,7 +340,15 @@ private: mutable BoundingBoxf3 m_raw_bounding_box; mutable bool m_raw_bounding_box_valid; mutable BoundingBoxf3 m_raw_mesh_bounding_box; - mutable bool m_raw_mesh_bounding_box_valid; + mutable bool m_raw_mesh_bounding_box_valid; + + friend class cereal::access; + ModelObject() : m_model(nullptr), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) {} + template<class Archive> void serialize(Archive &ar) { + ar(cereal::base_class<ModelBase>(this)); + ar(name, input_file, instances, volumes, config, layer_height_ranges, layer_height_profile, sla_support_points, sla_points_status, origin_translation, + m_bounding_box, m_bounding_box_valid, m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid); + } }; // Declared outside of ModelVolume, so it could be forward declared. @@ -459,7 +484,7 @@ private: // -1 -> is unknown value (before first cheking) // 0 -> is not splittable // 1 -> is splittable - mutable int m_is_splittable{ -1 }; + mutable int m_is_splittable{ -1 }; ModelVolume(ModelObject *object, const TriangleMesh &mesh) : m_mesh(new TriangleMesh(mesh)), m_type(ModelVolumeType::MODEL_PART), object(object) { @@ -486,6 +511,13 @@ private: } ModelVolume& operator=(ModelVolume &rhs) = delete; + + friend class cereal::access; + ModelVolume() : object(nullptr) {} + template<class Archive> void serialize(Archive &ar) { + ar(cereal::base_class<ModelBase>(this)); + ar(name, config, m_mesh, m_type, m_material_id, m_convex_hull, m_transformation, m_is_splittable); + } }; // A single instance of a ModelObject. @@ -571,10 +603,16 @@ private: explicit ModelInstance(ModelObject *object, const ModelInstance &other) : m_transformation(other.m_transformation), object(object), print_volume_state(PVS_Inside) {} - ModelInstance() = delete; explicit ModelInstance(ModelInstance &&rhs) = delete; ModelInstance& operator=(const ModelInstance &rhs) = delete; ModelInstance& operator=(ModelInstance &&rhs) = delete; + + friend class cereal::access; + ModelInstance() : object(nullptr) {} + template<class Archive> void serialize(Archive &ar) { + ar(cereal::base_class<ModelBase>(this)); + ar(m_transformation, print_volume_state); + } }; // The print bed content. @@ -633,24 +671,24 @@ public: BoundingBoxf3 bounding_box() const; // Set the print_volume_state of PrintObject::instances, // return total number of printable objects. - unsigned int update_print_volume_state(const BoundingBoxf3 &print_volume); + unsigned int update_print_volume_state(const BoundingBoxf3 &print_volume); // Returns true if any ModelObject was modified. - bool center_instances_around_point(const Vec2d &point); - void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); } - TriangleMesh mesh() const; - bool arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL); + bool center_instances_around_point(const Vec2d &point); + void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); } + TriangleMesh mesh() const; + bool arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL); // Croaks if the duplicated objects do not fit the print bed. - void duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); - void duplicate_objects(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); - void duplicate_objects_grid(size_t x, size_t y, coordf_t dist); + void duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); + void duplicate_objects(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); + void duplicate_objects_grid(size_t x, size_t y, coordf_t dist); - bool looks_like_multipart_object() const; - void convert_multipart_object(unsigned int max_extruders); + bool looks_like_multipart_object() const; + void convert_multipart_object(unsigned int max_extruders); // Ensures that the min z of the model is not negative - void adjust_min_z(); + void adjust_min_z(); - void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); } + void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); } static unsigned int get_auto_extruder_id(unsigned int max_extruders); static std::string get_auto_extruder_id_as_string(unsigned int max_extruders); @@ -663,6 +701,11 @@ public: private: MODELBASE_DERIVED_PRIVATE_COPY_MOVE(Model) + + friend class cereal::access; + template<class Archive> void serialize(Archive &ar) { + ar(cereal::base_class<ModelBase>(this), materials, objects); + } }; #undef MODELBASE_DERIVED_COPY_MOVE_CLONE diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index b02ead299..8979523b7 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -62,8 +62,8 @@ inline Vec2i64 to_2d(const Vec3i64 &pt3) { return Vec2i64(pt3(0), pt3(1)); } inline Vec2f to_2d(const Vec3f &pt3) { return Vec2f (pt3(0), pt3(1)); } inline Vec2d to_2d(const Vec3d &pt3) { return Vec2d (pt3(0), pt3(1)); } -inline Vec3d to_3d(const Vec2d &v, double z) { return Vec3d(v(0), v(1), z); } -inline Vec3f to_3d(const Vec2f &v, float z) { return Vec3f(v(0), v(1), z); } +inline Vec3d to_3d(const Vec2d &v, double z) { return Vec3d(v(0), v(1), z); } +inline Vec3f to_3d(const Vec2f &v, float z) { return Vec3f(v(0), v(1), z); } inline Vec3i64 to_3d(const Vec2i64 &v, float z) { return Vec3i64(int64_t(v(0)), int64_t(v(1)), int64_t(z)); } inline Vec3crd to_3d(const Vec3crd &p, coord_t z) { return Vec3crd(p(0), p(1), z); } @@ -291,4 +291,24 @@ namespace boost { namespace polygon { } } // end Boost +#include <cereal/types/polymorphic.hpp> +#include <cereal/archives/binary.hpp> + +// Serialization through the Cereal library +namespace cereal { +// template<class Archive> void serialize(Archive& archive, Slic3r::Vec2crd &v) { archive(v.x(), v.y()); } +// template<class Archive> void serialize(Archive& archive, Slic3r::Vec3crd &v) { archive(v.x(), v.y(), v.z()); } + template<class Archive> void serialize(Archive& archive, Slic3r::Vec2i &v) { archive(v.x(), v.y()); } + template<class Archive> void serialize(Archive& archive, Slic3r::Vec3i &v) { archive(v.x(), v.y(), v.z()); } +// template<class Archive> void serialize(Archive& archive, Slic3r::Vec2i64 &v) { archive(v.x(), v.y()); } +// template<class Archive> void serialize(Archive& archive, Slic3r::Vec3i64 &v) { archive(v.x(), v.y(), v.z()); } + template<class Archive> void serialize(Archive& archive, Slic3r::Vec2f &v) { archive(v.x(), v.y()); } + template<class Archive> void serialize(Archive& archive, Slic3r::Vec3f &v) { archive(v.x(), v.y(), v.z()); } + template<class Archive> void serialize(Archive& archive, Slic3r::Vec2d &v) { archive(v.x(), v.y()); } + template<class Archive> void serialize(Archive& archive, Slic3r::Vec3d &v) { archive(v.x(), v.y(), v.z()); } + + template<class Archive> void load(Archive& archive, Slic3r::Matrix2f &m) { archive.loadBinary((char*)m.data(), sizeof(float) * 4); } + template<class Archive> void save(Archive& archive, Slic3r::Matrix2f &m) { archive.saveBinary((char*)m.data(), sizeof(float) * 4); } +} + #endif diff --git a/src/libslic3r/pchheader.hpp b/src/libslic3r/pchheader.hpp index b27dfe6a2..54b563def 100644 --- a/src/libslic3r/pchheader.hpp +++ b/src/libslic3r/pchheader.hpp @@ -100,7 +100,14 @@ #include <tbb/task_scheduler_init.h> #include <Eigen/Dense> -#include <Eigen/Geometry> +#include <Eigen/Geometry> + +#include <cereal/types/polymorphic.hpp> +#include <cereal/types/map.hpp> +#include <cereal/types/memory.hpp> +#include <cereal/types/string.hpp> +#include <cereal/types/vector.hpp> +#include <cereal/archives/binary.hpp> #include "BoundingBox.hpp" #include "ClipperUtils.hpp"