WIP Undo / Redo: Serialization of the Model / ModelObject / Model instance

using the cereal framework.
This commit is contained in:
bubnikv 2019-06-26 16:29:12 +02:00
parent a710e7e7e4
commit d99e932ee8
7 changed files with 139 additions and 22 deletions

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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),
@ -324,6 +341,14 @@ private:
mutable bool m_raw_bounding_box_valid;
mutable BoundingBoxf3 m_raw_mesh_bounding_box;
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.
@ -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.
@ -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

View File

@ -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

View File

@ -102,6 +102,13 @@
#include <Eigen/Dense>
#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"
#include "Config.hpp"