Add emboss SVG configuration to model

add Cereal serialization of Polygons and ExPolygons
This commit is contained in:
Filip Sykala - NTB T15p 2023-03-07 09:20:52 +01:00
parent 706d70f370
commit ae0f4a7c8b
6 changed files with 166 additions and 5 deletions

View File

@ -56,9 +56,11 @@ set(SLIC3R_SOURCES
ElephantFootCompensation.hpp
Emboss.cpp
Emboss.hpp
EmbossShape.hpp
enum_bitmask.hpp
ExPolygon.cpp
ExPolygon.hpp
ExPolygonSerialize.hpp
ExPolygonsIndex.cpp
ExPolygonsIndex.hpp
Extruder.cpp

View File

@ -0,0 +1,64 @@
#ifndef slic3r_EmbossShape_hpp_
#define slic3r_EmbossShape_hpp_
#include <string>
#include <cereal/cereal.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/optional.hpp>
#include <cereal/archives/binary.hpp>
#include "Point.hpp" // Transform3d
#include "ExPolygon.hpp"
#include "ExPolygonSerialize.hpp"
namespace Slic3r {
/// <summary>
/// Contain plane shape information to be able emboss it and edit it
/// </summary>
struct EmbossShape
{
// shape defined by integer point consist only by lines not curves
ExPolygons shape;
// scale of shape, multiplier to get 3d point in mm from integer shape
double shape_scale;
// Emboss depth
double depth; // [in world mm]
// Flag that result volume use surface cutted from source objects
bool use_surface = false;
// distance from surface point
// used for move over model surface
// When not set value is zero and is not stored
std::optional<float> distance; // [in mm]
// !!! Volume stored in .3mf has transformed vertices.
// (baked transformation into vertices position)
// Only place for fill this is when load from .3mf
// This is correction for volume transformation
// Stored_Transform3d * fix_3mf_tr = Transform3d_before_store_to_3mf
std::optional<Slic3r::Transform3d> fix_3mf_tr;
// file(.svg) path to source of shape
std::string svg_file_path;
// undo / redo stack recovery
template<class Archive> void save(Archive &ar) const
{
ar(shape, shape_scale, depth, use_surface, svg_file_path);
cereal::save(ar, distance);
cereal::save(ar, fix_3mf_tr);
}
template<class Archive> void load(Archive &ar)
{
ar(shape, shape_scale, depth, use_surface, svg_file_path);
cereal::load(ar, distance);
cereal::load(ar, fix_3mf_tr);
}
};
} // namespace Slic3r
#endif // slic3r_EmbossShape_hpp_

View File

@ -0,0 +1,28 @@
#ifndef slic3r_ExPolygonSerialize_hpp_
#define slic3r_ExPolygonSerialize_hpp_
#include "ExPolygon.hpp"
#include "Point.hpp" // Cereal serialization of Point
#include <cereal/cereal.hpp>
#include <cereal/types/vector.hpp>
/// <summary>
/// External Cereal serialization of ExPolygons
/// </summary>
// Serialization through the Cereal library
#include <cereal/access.hpp>
namespace cereal {
template<class Archive>
void serialize(Archive &archive, Slic3r::Polygon &polygon) {
archive(polygon.points);
}
template<class Archive>
void serialize(Archive &archive, Slic3r::ExPolygon &expoly) {
archive(expoly.contour, expoly.holes);
}
} // namespace Slic3r
#endif // slic3r_ExPolygonSerialize_hpp_

View File

@ -15,6 +15,7 @@
#include "CustomGCode.hpp"
#include "enum_bitmask.hpp"
#include "TextConfiguration.hpp"
#include "EmbossShape.hpp"
#include <map>
#include <memory>
@ -824,6 +825,10 @@ public:
// Contain information how to re-create volume
std::optional<TextConfiguration> text_configuration;
// Is set only when volume is Embossed Shape
// Contain 2d information about embossed shape to be editabled
std::optional<EmbossShape> emboss_shape;
// A parent object owning this modifier volume.
ModelObject* get_object() const { return this->object; }
ModelVolumeType type() const { return m_type; }
@ -1011,8 +1016,7 @@ private:
name(other.name), source(other.source), m_mesh(other.m_mesh), m_convex_hull(other.m_convex_hull),
config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation),
supported_facets(other.supported_facets), seam_facets(other.seam_facets), mmu_segmentation_facets(other.mmu_segmentation_facets),
cut_info(other.cut_info),
text_configuration(other.text_configuration)
cut_info(other.cut_info), text_configuration(other.text_configuration), emboss_shape(other.emboss_shape)
{
assert(this->id().valid());
assert(this->config.id().valid());
@ -1033,8 +1037,7 @@ private:
// Providing a new mesh, therefore this volume will get a new unique ID assigned.
ModelVolume(ModelObject *object, const ModelVolume &other, TriangleMesh &&mesh) :
name(other.name), source(other.source), config(other.config), object(object), m_mesh(new TriangleMesh(std::move(mesh))), m_type(other.m_type), m_transformation(other.m_transformation),
cut_info(other.cut_info),
text_configuration(other.text_configuration)
cut_info(other.cut_info), text_configuration(other.text_configuration), emboss_shape(other.emboss_shape)
{
assert(this->id().valid());
assert(this->config.id().valid());
@ -1082,6 +1085,7 @@ private:
cereal::load_by_value(ar, mmu_segmentation_facets);
cereal::load_by_value(ar, config);
cereal::load(ar, text_configuration);
cereal::load(ar, emboss_shape);
assert(m_mesh);
if (has_convex_hull) {
cereal::load_optional(ar, m_convex_hull);
@ -1099,6 +1103,7 @@ private:
cereal::save_by_value(ar, mmu_segmentation_facets);
cereal::save_by_value(ar, config);
cereal::save(ar, text_configuration);
cereal::save(ar, emboss_shape);
if (has_convex_hull)
cereal::save_optional(ar, m_convex_hull);
}

View File

@ -491,7 +491,7 @@ TEST_CASE("Cut surface", "[]")
#include <sstream>
#include <cereal/cereal.hpp>
#include <cereal/archives/binary.hpp>
TEST_CASE("UndoRedo serialization", "[Emboss]")
TEST_CASE("UndoRedo TextConfiguration serialization", "[Emboss]")
{
TextConfiguration tc;
tc.text = "Dovede-li se člověk zasmát sám sobě, nevyjde ze smíchu po celý život.";
@ -523,6 +523,39 @@ TEST_CASE("UndoRedo serialization", "[Emboss]")
CHECK(tc.fix_3mf_tr.has_value() == tc_loaded.fix_3mf_tr.has_value());
}
#include "libslic3r/EmbossShape.hpp"
TEST_CASE("UndoRedo EmbossShape serialization", "[Emboss]")
{
EmbossShape emboss;
emboss.shape = {{{0, 0}, {10, 0}, {10, 10}, {0, 10}}, {{5, 5}, {6, 5}, {6, 6}, {5, 6}}};
emboss.shape_scale = 2.;
emboss.depth = 5.;
emboss.use_surface = true;
emboss.distance = 3.f;
emboss.fix_3mf_tr = Transform3d::Identity();
emboss.svg_file_path = "Everything starts somewhere, though many physicists disagree.\
But people have always been dimly aware of the problem with the start of things.\
They wonder how the snowplough driver gets to work,\
or how the makers of dictionaries look up the spelling of words.";
std::stringstream ss; // any stream can be used
{
cereal::BinaryOutputArchive oarchive(ss); // Create an output archive
oarchive(emboss);
} // archive goes out of scope, ensuring all contents are flushed
EmbossShape emboss_loaded;
{
cereal::BinaryInputArchive iarchive(ss); // Create an input archive
iarchive(emboss_loaded);
}
CHECK(emboss.shape == emboss_loaded.shape);
CHECK(emboss.shape_scale == emboss_loaded.shape_scale);
CHECK(emboss.depth == emboss_loaded.depth);
CHECK(emboss.use_surface == emboss_loaded.use_surface);
CHECK(emboss.distance == emboss_loaded.distance);
}
#include <CGAL/Polygon_mesh_processing/corefinement.h>
#include <CGAL/Exact_integer.h>

View File

@ -65,3 +65,32 @@ SCENARIO("Basics", "[ExPolygon]") {
}
}
}
#include <sstream>
#include <cereal/cereal.hpp>
#include <cereal/archives/binary.hpp>
#include "libslic3r/ExPolygonSerialize.hpp"
TEST_CASE("Serialization of expolygons", "[ExPolygon, Cereal, serialization]")
{
ExPolygons expolys{{
// expolygon 1 - without holes
{{0,0}, {10,0}, {10,10}, {0,10}}, // contour
// expolygon 2 - with rect 1px hole
{{{0,0}, {10,0}, {10,10}, {0,10}},
{{5, 5}, {6, 5}, {6, 6}, {5, 6}}}
}};
std::stringstream ss; // any stream can be used
{
cereal::BinaryOutputArchive oarchive(ss); // Create an output archive
oarchive(expolys);
} // archive goes out of scope, ensuring all contents are flushed
ExPolygons expolys_loaded;
{
cereal::BinaryInputArchive iarchive(ss); // Create an input archive
iarchive(expolys_loaded);
}
CHECK(expolys == expolys_loaded);
}