diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index baf6fe72ff..937066b4ae 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -1263,17 +1263,14 @@ HealedExPolygons union_with_delta(const ExPolygonsWithIds &shapes, float delta, ExPolygons Slic3r::union_with_delta(EmbossShape &shape, float delta, unsigned max_heal_iteration) { - if (!shape.final_shape.empty()) + if (!shape.final_shape.expolygons.empty()) return shape.final_shape; - HealedExPolygons result = ::union_with_delta(shape.shapes_with_ids, delta, max_heal_iteration); - shape.is_healed = result.is_healed; + shape.final_shape = ::union_with_delta(shape.shapes_with_ids, delta, max_heal_iteration); for (const ExPolygonsWithId &e : shape.shapes_with_ids) if (!e.is_healed) - shape.is_healed = false; - shape.final_shape = std::move(result.expolygons); // cached - - return shape.final_shape; + shape.final_shape.is_healed = false; + return shape.final_shape.expolygons; } void Slic3r::translate(ExPolygonsWithIds &expolygons_with_ids, const Point &p) diff --git a/src/libslic3r/Emboss.hpp b/src/libslic3r/Emboss.hpp index fb1264cfc0..ded2196a7a 100644 --- a/src/libslic3r/Emboss.hpp +++ b/src/libslic3r/Emboss.hpp @@ -18,13 +18,6 @@ namespace Slic3r { -// Extend expolygons with information whether it was successfull healed -struct HealedExPolygons{ - ExPolygons expolygons; - bool is_healed; - operator ExPolygons&() { return expolygons; } -}; - /// /// class with only static function add ability to engraved OR raised /// text OR polygons onto model surface diff --git a/src/libslic3r/EmbossShape.hpp b/src/libslic3r/EmbossShape.hpp index 2d63352044..9094d2ad5d 100644 --- a/src/libslic3r/EmbossShape.hpp +++ b/src/libslic3r/EmbossShape.hpp @@ -16,8 +16,7 @@ namespace Slic3r { -struct EmbossProjection -{ +struct EmbossProjection{ // Emboss depth, Size in local Z direction double depth = 1.; // [in loacal mm] // NOTE: User should see and modify mainly world size not local @@ -25,22 +24,6 @@ struct EmbossProjection // Flag that result volume use surface cutted from source objects bool use_surface = false; - // enum class Align { - // left, - // right, - // center, - // top_left, - // top_right, - // top_center, - // bottom_left, - // bottom_right, - // bottom_center - // }; - //// change pivot of volume - //// When not set, center is used and is not stored - // std::optional align; - - // compare TextStyle bool operator==(const EmbossProjection &other) const { return depth == other.depth && use_surface == other.use_surface; } @@ -49,6 +32,13 @@ struct EmbossProjection template void serialize(Archive &ar) { ar(depth, use_surface); } }; +// Extend expolygons with information whether it was successfull healed +struct HealedExPolygons{ + ExPolygons expolygons; + bool is_healed; + operator ExPolygons&() { return expolygons; } +}; + // Help structure to identify expolygons grups // e.g. emboss -> per glyph -> identify character struct ExPolygonsWithId @@ -74,7 +64,12 @@ struct EmbossShape { // shapes to to emboss separately over surface ExPolygonsWithIds shapes_with_ids; - ExPolygons final_shape; // When not set it is calculated from ExPolygonsWithIds + + // Only cache for final shape + // It is calculated from ExPolygonsWithIds + // Flag is_healed --> whether union of shapes is healed + // Healed mean without selfintersection and point duplication + HealedExPolygons final_shape; // scale of shape, multiplier to get 3d point in mm from integer shape double scale = SCALING_FACTOR; @@ -124,29 +119,25 @@ struct EmbossShape // When embossing shape is made by svg file this is source data std::optional svg_file; - // flag whether during cration of union expolygon final shape was fully correct - // correct mean without selfintersection and duplicate(double) points - bool is_healed = true; - // undo / redo stack recovery template void save(Archive &ar) const { // final_shape is not neccessary to store - it is only cache - ar(shapes_with_ids, scale, projection, is_healed, svg_file); + ar(shapes_with_ids, final_shape, scale, projection, svg_file); cereal::save(ar, fix_3mf_tr); } template void load(Archive &ar) { - ar(shapes_with_ids, scale, projection, is_healed, svg_file); + ar(shapes_with_ids, final_shape, scale, projection, svg_file); cereal::load(ar, fix_3mf_tr); } }; - } // namespace Slic3r // Serialization through the Cereal library namespace cereal { template void serialize(Archive &ar, Slic3r::ExPolygonsWithId &o) { ar(o.id, o.expoly, o.is_healed); } +template void serialize(Archive &ar, Slic3r::HealedExPolygons &o) { ar(o.expolygons, o.is_healed); } }; // namespace cereal #endif // slic3r_EmbossShape_hpp_ diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 5e9d7c1c89..34f2eee4e1 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -3872,7 +3872,7 @@ void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume stream << SHAPE_SCALE_ATTR << "=\"" << es.scale << "\" "; - if (!es.is_healed) + if (!es.final_shape.is_healed) stream << UNHEALED_ATTR << "=\"" << 1 << "\" "; // projection @@ -3912,10 +3912,17 @@ std::optional read_emboss_shape(const char **attributes, unsigned i std::string file_path = get_attribute_value_string(attributes, num_attributes, SVG_FILE_PATH_ATTR); std::string file_path_3mf = get_attribute_value_string(attributes, num_attributes, SVG_FILE_PATH_IN_3MF_ATTR); - ExPolygonsWithIds shapes; // TODO: need to implement + + // MayBe: store also shapes to not store svg + // But be carefull curve will be lost -> scale will not change sampling + // shapes could be loaded from SVG + ExPolygonsWithIds shapes; + // final shape could be calculated from shapes + HealedExPolygons final_shape; + final_shape.is_healed = is_healed; EmbossShape::SvgFile svg{file_path, file_path_3mf}; - return EmbossShape{shapes, {}, scale, std::move(projection), std::move(fix_tr_mat), std::move(svg), is_healed}; + return EmbossShape{std::move(shapes), std::move(final_shape), scale, std::move(projection), std::move(fix_tr_mat), std::move(svg)}; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index 3eb8fd53ff..2930328e82 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -1127,7 +1127,7 @@ std::vector create_shape_warnings(const EmbossShape &shape, float s res += '\n' + message; }; - if (!shape.is_healed) { + if (!shape.final_shape.is_healed) { for (const ExPolygonsWithId &i : shape.shapes_with_ids) if (!i.is_healed) add_warning(i.id, _u8L("Path can't be healed from selfintersection and multiple points.")); @@ -1455,12 +1455,11 @@ void GLGizmoSVG::draw_filename(){ m_filename_preview = get_file_name(svg.path_in_3mf); } - if (m_filename_preview.empty()){ - assert(false); - m_filename_preview = "unknown"; - } else { - m_filename_preview = ImGuiWrapper::trunc(m_filename_preview, m_gui_cfg->input_width); - } + if (m_filename_preview.empty()) + // TRN - Preview of filename after clear local filepath. + m_filename_preview = _u8L("Without filename"); + + m_filename_preview = ImGuiWrapper::trunc(m_filename_preview, m_gui_cfg->input_width); } if (!m_shape_warnings.empty()){ @@ -1539,8 +1538,7 @@ void GLGizmoSVG::draw_filename(){ // set .svg_file.path_in_3mf to remember file name m_volume->emboss_shape->svg_file->path.clear(); m_volume_shape.svg_file->path.clear(); - // TRN - Preview of filename after clear local filepath. - m_filename_preview = _u8L("No-name SVG"); + m_filename_preview.clear(); } else if (ImGui::IsItemHovered()) { ImGui::SetTooltip("%s", _u8L("Do NOT save local path to 3MF file.\n" "Also disables 'reload from disk' option.").c_str()); @@ -1636,6 +1634,7 @@ void GLGizmoSVG::draw_filename(){ EmbossShape es_ = select_shape(m_volume_shape.svg_file->path, tes_tol); m_volume_shape.svg_file = std::move(es_.svg_file); m_volume_shape.shapes_with_ids = std::move(es_.shapes_with_ids); + m_volume_shape.final_shape = {}; // clear cache m_shape_warnings = create_shape_warnings(m_volume_shape, scale); init_texture(m_texture, m_volume_shape.shapes_with_ids, m_gui_cfg->texture_max_size_px, m_shape_warnings); process(); @@ -1805,7 +1804,7 @@ void GLGizmoSVG::draw_size() if (img != NULL){ NSVGLineParams params{get_tesselation_tolerance(get_scale_for_tolerance())}; m_volume_shape.shapes_with_ids = create_shape_with_ids(*img, params); - m_volume_shape.final_shape.clear(); + m_volume_shape.final_shape = {}; // reset cache for final shape process(); } }