From af69a4f2def1108d3ce281e10ad1c241f0fdfcab Mon Sep 17 00:00:00 2001 From: Filip Sykala Date: Mon, 31 Jan 2022 13:17:24 +0100 Subject: [PATCH] create emboss text mesh on same place as update fix: Un Itelic redraw ../src/slic3r/Utils/WxFontUtils.hpp:49:77: error: non-const lvalue reference to type 'shared_ptr<...>' cannot bind to a temporary of type 'shared_ptr<...>' ../src/slic3r/Utils/WxFontUtils.hpp:55:75: error: non-const lvalue reference to type 'shared_ptr<...>' cannot bind to a temporary of type 'shared_ptr<...>' --- src/libslic3r/Emboss.hpp | 5 ++ src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 56 ++++++++++++------- src/slic3r/GUI/Jobs/EmbossJob.cpp | 46 +++++---------- src/slic3r/GUI/Jobs/EmbossJob.hpp | 12 ++-- src/slic3r/Utils/WxFontUtils.cpp | 42 +++++++------- src/slic3r/Utils/WxFontUtils.hpp | 28 ++++++---- .../libslic3r/test_quadric_edge_collapse.cpp | 6 +- 7 files changed, 105 insertions(+), 90 deletions(-) diff --git a/src/libslic3r/Emboss.hpp b/src/libslic3r/Emboss.hpp index d15db8ddf..f18f123bb 100644 --- a/src/libslic3r/Emboss.hpp +++ b/src/libslic3r/Emboss.hpp @@ -82,6 +82,11 @@ public: , descent(descent) , linegap(linegap) {} + bool operator==(const FontFile &other) const { + return index == other.index && + buffer.size() == other.buffer.size() && + buffer == other.buffer; + } }; /// diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index cc91d7100..1e4bf44ee 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -738,7 +738,8 @@ void GLGizmoEmboss::draw_font_list() wxFontEnumerator::IsValidFacename(face_name)) { // Select font wxFont wx_font(wxFontInfo().FaceName(face_name).Encoding(encoding)); - m_font_manager.set_wx_font(wx_font); + if(m_font_manager.set_wx_font(wx_font)) + process(); } ImGui::PopID(); } @@ -963,10 +964,11 @@ void GLGizmoEmboss::draw_style_list() { //store_font_item_to_app_config(); } if (ImGui::IsItemHovered()) - if (is_changed) + if (is_changed) { ImGui::SetTooltip("%s", _u8L("Save current settings to selected style").c_str()); - else + } else { ImGui::SetTooltip("%s", _u8L("No changes to save into style").c_str()); + } if (is_changed) { ImGui::SameLine(); @@ -981,7 +983,8 @@ void GLGizmoEmboss::draw_style_list() { bool GLGizmoEmboss::italic_button() { std::optional &wx_font = m_font_manager.get_wx_font(); - if (!wx_font.has_value()) { + std::shared_ptr &font_file = m_font_manager.get_font_file(); + if (!wx_font.has_value() || font_file == nullptr) { draw_icon(IconType::italic, IconState::disabled); return false; } @@ -991,18 +994,24 @@ bool GLGizmoEmboss::italic_button() if (is_font_italic) { if (draw_button(IconType::unitalic)) { skew.reset(); - wx_font->SetStyle(wxFontStyle::wxFONTSTYLE_NORMAL); + if (wx_font->GetStyle() != wxFontStyle::wxFONTSTYLE_NORMAL) { + wx_font->SetStyle(wxFontStyle::wxFONTSTYLE_NORMAL); + font_file = WxFontUtils::create_font_file(*wx_font); + } return true; } if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _u8L("Unset italic").c_str()); } else { if (draw_button(IconType::italic)) { - std::shared_ptr &font_file = - m_font_manager.get_font_file(); - bool is_set = WxFontUtils::set_italic(*wx_font, font_file); - // add skew when wxFont can't set it - if (!is_set) skew = 0.2f; + auto new_ff = WxFontUtils::set_italic(*wx_font, *font_file); + if (new_ff) { + font_file = std::move(new_ff); + } else { + // italic font doesn't exist + // add skew when wxFont can't set it + skew = 0.2f; + } return true; } if (ImGui::IsItemHovered()) @@ -1013,7 +1022,8 @@ bool GLGizmoEmboss::italic_button() bool GLGizmoEmboss::bold_button() { std::optional &wx_font = m_font_manager.get_wx_font(); - if (!wx_font.has_value()) { + std::shared_ptr &font_file = m_font_manager.get_font_file(); + if (!wx_font.has_value() || font_file==nullptr) { draw_icon(IconType::bold, IconState::disabled); return false; } @@ -1023,18 +1033,24 @@ bool GLGizmoEmboss::bold_button() { if (is_font_bold) { if (draw_button(IconType::unbold)) { boldness.reset(); - wx_font->SetWeight(wxFontWeight::wxFONTWEIGHT_NORMAL); + if (wx_font->GetWeight() != wxFontWeight::wxFONTWEIGHT_NORMAL) { + wx_font->SetWeight(wxFontWeight::wxFONTWEIGHT_NORMAL); + font_file = WxFontUtils::create_font_file(*wx_font); + } return true; } if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _u8L("Unset bold").c_str()); } else { if (draw_button(IconType::bold)) { - std::shared_ptr &font_file = - m_font_manager.get_font_file(); - bool is_set = WxFontUtils::set_bold(*wx_font, font_file); - // add boldness when wxFont can't set it - if (!is_set) boldness = 20.f; + auto new_ff = WxFontUtils::set_bold(*wx_font, *font_file); + if (new_ff) { + font_file = std::move(new_ff); + } else { + // bold font can't be loaded + // set up boldness + boldness = 20.f; + } return true; } if (ImGui::IsItemHovered()) @@ -1182,13 +1198,13 @@ void GLGizmoEmboss::set_minimal_window_size(bool is_edit_style, { ImVec2 window_size = ImGui::GetWindowSize(); const ImVec2& min_win_size_prev = get_minimal_window_size(); - ImVec2 diff(window_size.x - min_win_size_prev.x, - window_size.y - min_win_size_prev.y); + //ImVec2 diff(window_size.x - min_win_size_prev.x, + // window_size.y - min_win_size_prev.y); float diff_y = ImGui::GetWindowSize().y - get_minimal_window_size().y; m_is_edit_style = is_edit_style; m_is_advanced_edit_style = is_advance_edit_style; const ImVec2 &min_win_size = get_minimal_window_size(); - ImGui::SetWindowSize(ImVec2(0.f, min_win_size.y + diff.y), + ImGui::SetWindowSize(ImVec2(0.f, min_win_size.y + diff_y), ImGuiCond_Always); } diff --git a/src/slic3r/GUI/Jobs/EmbossJob.cpp b/src/slic3r/GUI/Jobs/EmbossJob.cpp index 9082568c3..1abbe118d 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.cpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.cpp @@ -20,36 +20,13 @@ using namespace GUI; void EmbossUpdateJob::process(Ctl &ctl) { - // Changing cursor to busy must be inside main thread - // GTK is not thread safe. - //wxBeginBusyCursor(); - //ScopeGuard sg([]() { wxEndBusyCursor(); }); - - // only for sure - assert(m_input != nullptr); - // check if exist valid font if (m_input->font_file == nullptr) return; const TextConfiguration &cfg = m_input->text_configuration; - const std::string & text = cfg.text; - // Do NOT process empty string - if (text.empty()) return; - - const FontProp &prop = cfg.font_item.prop; - ExPolygons shapes = Emboss::text2shapes(*m_input->font_file, text.c_str(), prop); - - if (ctl.was_canceled()) return; - - // exist 2d shape made by text ? - // (no shape means that font hasn't any of text symbols) - if (shapes.empty()) return; - - float scale = prop.size_in_mm / m_input->font_file->ascent; - auto projectZ = std::make_unique(prop.emboss / scale); - Emboss::ProjectScale project(std::move(projectZ), scale); - m_result = TriangleMesh(Emboss::polygons2model(shapes, project)); - + m_result = EmbossCreateJob::create_mesh( + cfg.text.c_str(), *m_input->font_file, cfg.font_item.prop, ctl); + if (m_result.its.empty()) return; if (ctl.was_canceled()) return; // center triangle mesh @@ -121,7 +98,7 @@ void EmbossCreateJob::process(Ctl &ctl) { create_default_mesh() : create_mesh(m_input->text_configuration.text.c_str(), *m_input->font_file, - m_input->text_configuration.font_item.prop); + m_input->text_configuration.font_item.prop, ctl); if (m_result.its.empty()) m_result = create_default_mesh(); if (ctl.was_canceled()) return; @@ -258,12 +235,17 @@ TriangleMesh EmbossCreateJob::create_default_mesh() TriangleMesh EmbossCreateJob::create_mesh(const char * text, Emboss::FontFile &font, - const FontProp & font_prop) + const FontProp & font_prop, + Ctl & ctl) { - ExPolygons shapes = Emboss::text2shapes(font, text, font_prop); - float scale = font_prop.size_in_mm / font.ascent; - float depth = font_prop.emboss / scale; - auto projectZ = std::make_unique(depth); + ExPolygons shapes = Emboss::text2shapes(font, text, font_prop); + if (shapes.empty()) return {}; + if (ctl.was_canceled()) return {}; + + float scale = font_prop.size_in_mm / font.ascent; + float depth = font_prop.emboss / scale; + auto projectZ = std::make_unique(depth); Emboss::ProjectScale project(std::move(projectZ), scale); + if (ctl.was_canceled()) return {}; return TriangleMesh(Emboss::polygons2model(shapes, project)); } \ No newline at end of file diff --git a/src/slic3r/GUI/Jobs/EmbossJob.hpp b/src/slic3r/GUI/Jobs/EmbossJob.hpp index 6ec2d35df..08bf3d888 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.hpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.hpp @@ -36,20 +36,22 @@ public: void process(Ctl &ctl) override; void finalize(bool canceled, std::exception_ptr &) override; -private: - static TriangleMesh create_default_mesh(); - - /// + // /// Create mesh from text /// /// Text to convert on mesh /// Define shape of characters. /// NOTE: Can't be const cache glyphs /// Property of font + /// Control for job, check of cancelation /// Triangle mesh model static TriangleMesh create_mesh(const char * text, Emboss::FontFile &font, - const FontProp & font_prop); + const FontProp & font_prop, + Ctl & ctl); + +private: + static TriangleMesh create_default_mesh(); }; diff --git a/src/slic3r/Utils/WxFontUtils.cpp b/src/slic3r/Utils/WxFontUtils.cpp index e2abd7c61..24d57154f 100644 --- a/src/slic3r/Utils/WxFontUtils.cpp +++ b/src/slic3r/Utils/WxFontUtils.cpp @@ -239,31 +239,30 @@ bool WxFontUtils::is_bold(const wxFont &font) { return wx_weight != wxFONTWEIGHT_NORMAL; } -bool WxFontUtils::set_italic(wxFont &font, std::shared_ptr& font_file) +std::unique_ptr WxFontUtils::set_italic(wxFont &font, const Emboss::FontFile &font_file) { static std::vector italic_styles = { wxFontStyle::wxFONTSTYLE_ITALIC, wxFontStyle::wxFONTSTYLE_SLANT }; - if (font_file == nullptr) - font_file = WxFontUtils::create_font_file(font); for (wxFontStyle style : italic_styles) { font.SetStyle(style); - std::unique_ptr act_font_file = WxFontUtils::create_font_file(font); - if (act_font_file == nullptr) continue; + std::unique_ptr new_font_file = + WxFontUtils::create_font_file(font); + + // can create italic font? + if (new_font_file == nullptr) continue; // is still same font file pointer? - if (font_file != nullptr) - if (act_font_file->buffer == font_file->buffer) continue; + if (font_file == *new_font_file) continue; - font_file = std::move(act_font_file); - return true; + return new_font_file; } - return false; + return nullptr; } -bool WxFontUtils::set_bold(wxFont &font, std::shared_ptr& font_file) +std::unique_ptr WxFontUtils::set_bold(wxFont &font, const Emboss::FontFile& font_file) { static std::vector bold_weight = { wxFontWeight::wxFONTWEIGHT_BOLD, @@ -271,18 +270,19 @@ bool WxFontUtils::set_bold(wxFont &font, std::shared_ptr& font wxFontWeight::wxFONTWEIGHT_EXTRABOLD, wxFontWeight::wxFONTWEIGHT_EXTRAHEAVY }; - if (font_file == nullptr) - font_file = WxFontUtils::create_font_file(font); for (wxFontWeight weight : bold_weight) { font.SetWeight(weight); - std::unique_ptr act_font_file = WxFontUtils::create_font_file(font); - if (act_font_file == nullptr) continue; - if (font_file != nullptr) - // is still same font? - if (act_font_file->buffer == font_file->buffer) continue; - font_file = std::move(act_font_file); - return true; + std::unique_ptr new_font_file = + WxFontUtils::create_font_file(font); + + // can create bold font file? + if (new_font_file == nullptr) continue; + + // is still same font file pointer? + if (font_file == *new_font_file) continue; + + return new_font_file; } - return false; + return nullptr; } \ No newline at end of file diff --git a/src/slic3r/Utils/WxFontUtils.hpp b/src/slic3r/Utils/WxFontUtils.hpp index a59c55d54..79fb2bc45 100644 --- a/src/slic3r/Utils/WxFontUtils.hpp +++ b/src/slic3r/Utils/WxFontUtils.hpp @@ -42,17 +42,25 @@ public: static bool is_italic(const wxFont &font); static bool is_bold(const wxFont &font); - // Font could not support italic than return FALSE. - // For check of support is neccessary font file pointer. - // Font file is optional it could be created inside of function, but it slow down. - // To not load font file twice on success font_file contain new created font file. - static bool set_italic(wxFont &font, std::shared_ptr& font_file = std::shared_ptr()); + /// + /// Set italic into wx font + /// When italic font is same as original return nullptr. + /// To not load font file twice on success is font_file returned. + /// + /// wx descriptor of font + /// file described in wx font + /// New created font fileon success otherwise nullptr + static std::unique_ptr set_italic(wxFont &font, const Emboss::FontFile& prev_font_file); - // Font could not support bold than return FALSE. - // For check of support is neccessary font file pointer. - // Font file is optional it could be created inside of function, but it slow down. - // To not load font file twice on success font_file contain new created font file. - static bool set_bold(wxFont &font, std::shared_ptr& font_file = std::shared_ptr()); + /// + /// Set boldness into wx font + /// When bolded font is same as original return nullptr. + /// To not load font file twice on success is font_file returned. + /// + /// wx descriptor of font + /// file described in wx font + /// New created font fileon success otherwise nullptr + static std::unique_ptr set_bold(wxFont &font, const Emboss::FontFile& font_file); // map to convert wxFont type to string and vice versa static const std::map from_family; diff --git a/tests/libslic3r/test_quadric_edge_collapse.cpp b/tests/libslic3r/test_quadric_edge_collapse.cpp index 65ae1e8a4..19b7dede7 100644 --- a/tests/libslic3r/test_quadric_edge_collapse.cpp +++ b/tests/libslic3r/test_quadric_edge_collapse.cpp @@ -272,9 +272,11 @@ TEST_CASE("Simplify frog_legs.obj to 5% by IGL/qslim", "[]") indexed_triangle_set its_out; its_out.vertices.reserve(U.size()/3); its_out.indices.reserve(G.size()/3); - for (size_t i = 0; i < U.size()/3; i++) + size_t U_size = U.size() / 3; + for (size_t i = 0; i < U_size; i++) its_out.vertices.emplace_back(U(i, 0), U(i, 1), U(i, 2)); - for (size_t i = 0; i < G.size()/3; i++) + size_t G_size = G.size() / 3; + for (size_t i = 0; i < G_size; i++) its_out.indices.emplace_back(G(i, 0), G(i, 1), G(i, 2)); // check if algorithm is still worse than our