From 1259b878fbaec1cf7acf8f738f6800a903c4bf42 Mon Sep 17 00:00:00 2001 From: Filip Sykala Date: Mon, 20 Dec 2021 21:58:21 +0100 Subject: [PATCH] add NSVG utils into cmakelists Move trunc to ImGuiWrapper --- src/libslic3r/CMakeLists.txt | 2 + src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 115 +----------------------- src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp | 26 ------ src/slic3r/GUI/ImGuiWrapper.cpp | 39 ++++++++ src/slic3r/GUI/ImGuiWrapper.hpp | 13 +++ 5 files changed, 57 insertions(+), 138 deletions(-) diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index ca0976de6a..bcbda4fcff 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -166,6 +166,8 @@ add_library(libslic3r STATIC MultiPoint.cpp MultiPoint.hpp MutablePriorityQueue.hpp + NSVGUtils.cpp + NSVGUtils.hpp ObjectID.cpp ObjectID.hpp PerimeterGenerator.cpp diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 37dc50b19d..8bf483e7f2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -47,12 +47,6 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent) , m_exist_notification(false) , m_is_initialized(false) // initialize on first opening gizmo , m_rotate_gizmo(parent, GLGizmoRotate::Axis::Z) // grab id = 2 (Z axis) - , m_move_grabber( - GLModel(), - 0, // grab id - DEFAULT_BASE_COLOR, - DEFAULT_DRAG_COLOR - ) { m_rotate_gizmo.set_group_id(0); // TODO: add suggestion to use https://fontawesome.com/ @@ -135,7 +129,7 @@ void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mous int instance_idx = selection.get_instance_idx(); if (instance_idx < 0) return; - assert(instance_idx < mo->instances.size()); + assert(static_cast(instance_idx) < mo->instances.size()); const ModelInstance *mi = mo->instances[instance_idx]; const Transform3d instance_trafo = mi->get_transformation().get_matrix(); @@ -252,8 +246,6 @@ bool GLGizmoEmboss::on_init() std::array gray_color = {.6f, .6f, .6f, .3f}; m_rotate_gizmo.set_highlight_color(gray_color); - m_move_grabber.shape.init_from(its_make_cube(1., 1., 1.)); - m_shortcut_key = WXK_CONTROL_T; return true; } @@ -267,7 +259,6 @@ void GLGizmoEmboss::on_render() { glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); m_rotate_gizmo.render(); - m_move_grabber.shape.render(); if (!m_preview.is_initialized()) return; @@ -844,7 +835,7 @@ void GLGizmoEmboss::draw_font_list() { const float & max_width = m_gui_cfg->max_font_name_width; std::optional rename_index; - std::string current_name = imgui_trunc(m_font_list[m_font_selected].name, + std::string current_name = ImGuiWrapper::trunc(m_font_list[m_font_selected].name, max_width); ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width); if (ImGui::BeginCombo("##font_selector", current_name.c_str())) { @@ -872,7 +863,7 @@ void GLGizmoEmboss::draw_font_list() for (FontItem &f : m_font_list) { ImGui::PushID(f.name.c_str()); - std::string name = imgui_trunc(f.name, max_width); + std::string name = ImGuiWrapper::trunc(f.name, max_width); size_t index = &f - &m_font_list.front(); bool is_selected = index == m_font_selected; auto flags = @@ -1544,36 +1535,6 @@ std::string GLGizmoEmboss::get_file_name(const std::string &file_path) return file_path.substr(offset, count); } -std::string GLGizmoEmboss::imgui_trunc(const std::string &text, float width) -{ - static const char *tail = " .."; - float tail_width = ImGui::CalcTextSize(tail).x; - float text_width = ImGui::CalcTextSize(text.c_str()).x; - if (text_width < width) return text; - float letter_width = ImGui::CalcTextSize("n").x; - float allowed_width = width - tail_width; - unsigned count_letter = static_cast(allowed_width / - letter_width); - text_width = ImGui::CalcTextSize(text.substr(0, count_letter).c_str()).x; - if (text_width < allowed_width) { - // increase letter count - do { - ++count_letter; - text_width = - ImGui::CalcTextSize(text.substr(0, count_letter).c_str()).x; - } while (text_width < allowed_width); - --count_letter; - } else { - // decrease letter count - do { - --count_letter; - text_width = - ImGui::CalcTextSize(text.substr(0, count_letter).c_str()).x; - } while (text_width > allowed_width); - } - return text.substr(0, count_letter) + tail; -} - namespace Slic3r::GUI { class Priv @@ -1782,75 +1743,5 @@ void GLGizmoEmboss::update_emboss_volume(TriangleMesh && mesh, canvas->reload_scene(true); } -void NSVGUtils::flatten_cubic_bez(Polygon &polygon, - float tessTol, - Vec2f p1, - Vec2f p2, - Vec2f p3, - Vec2f p4, - int level) -{ - Vec2f p12 = (p1 + p2) * 0.5f; - Vec2f p23 = (p2 + p3) * 0.5f; - Vec2f p34 = (p3 + p4) * 0.5f; - Vec2f p123 = (p12 + p23) * 0.5f; - - Vec2f pd = p4 - p1; - Vec2f pd2 = p2 - p4; - float d2 = std::abs(pd2.x() * pd.y() - pd2.y() * pd.x()); - Vec2f pd3 = p3 - p4; - float d3 = std::abs(pd3.x() * pd.y() - pd3.y() * pd.x()); - float d23 = d2 + d3; - - if ((d23 * d23) < tessTol * (pd.x() * pd.x() + pd.y() * pd.y())) { - polygon.points.emplace_back(p4.x(), p4.y()); - return; - } - - --level; - if (level == 0) return; - Vec2f p234 = (p23 + p34) * 0.5f; - Vec2f p1234 = (p123 + p234) * 0.5f; - flatten_cubic_bez(polygon, tessTol, p1, p12, p123, p1234, level); - flatten_cubic_bez(polygon, tessTol, p1234, p234, p34, p4, level); -} - -ExPolygons NSVGUtils::to_ExPolygons(NSVGimage *image, - float tessTol, - int max_level) -{ - Polygons polygons; - for (NSVGshape *shape = image->shapes; shape != NULL; - shape = shape->next) { - if (!(shape->flags & NSVG_FLAGS_VISIBLE)) continue; - Slic3r::Polygon polygon; - if (shape->fill.type != NSVG_PAINT_NONE) { - for (NSVGpath *path = shape->paths; path != NULL; - path = path->next) { - // Flatten path - polygon.points.emplace_back(path->pts[0], path->pts[1]); - for (size_t i = 0; i < path->npts - 1; i += 3) { - float *p = &path->pts[i * 2]; - Vec2f p1(p[0], p[1]), p2(p[2], p[3]), p3(p[4], p[5]), - p4(p[6], p[7]); - flatten_cubic_bez(polygon, tessTol, p1, p2, p3, p4, - max_level); - } - if (path->closed) { - polygons.push_back(polygon); - polygon = Slic3r::Polygon(); - } - } - } - polygons.push_back(polygon); - } - - // Fix Y axis - for (Polygon &polygon : polygons) - for (Point &p : polygon.points) p.y() *= -1; - - return Slic3r::union_ex(polygons); -} - // any existing icon filename to not influence GUI const std::string GLGizmoEmboss::M_ICON_FILENAME = "cut.svg"; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 8d72000df8..bd32767ee9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -158,30 +158,6 @@ private: // Rotation gizmo GLGizmoRotate m_rotate_gizmo; - - struct MyGrabber - { - GLModel shape; - int grab_id; - std::array color; - std::array hovered_color; - - MyGrabber(GLModel shape, - int grab_id, - std::array color, - std::array hovered_color) - : shape(shape) - , grab_id(grab_id) - , color(color) - , hovered_color(hovered_color) - {} - - void render() { - - } - }; - // Translate on surface of model - MyGrabber m_move_grabber; // preview position GLModel m_preview; @@ -234,8 +210,6 @@ public: // TODO: move to file utils static std::string get_file_name(const std::string &file_path); - // TODO: Move to imgui utils - std::string imgui_trunc(const std::string &text, float width); }; } // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index b46a566e3d..dcdcffa48c 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1041,6 +1041,45 @@ bool ImGuiWrapper::want_any_input() const return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput; } +std::string ImGuiWrapper::trunc(const std::string &text, + float width, + const char * tail) +{ + float text_width = ImGui::CalcTextSize(text.c_str()).x; + if (text_width < width) return text; + float letter_width = ImGui::CalcTextSize("n").x; // average letter width + assert(width > letter_width); + if (width < letter_width) return "Error: too small widht to trunc"; + float tail_width = ImGui::CalcTextSize(tail).x; + assert(width > tail_width); + if (width < tail_width) return "Error: Can't add tail and not be under wanted width."; + float allowed_width = width - tail_width; + unsigned count_letter = static_cast(allowed_width / letter_width); + std::string result_text = text.substr(0, count_letter); + text_width = ImGui::CalcTextSize(result_text.c_str()).x; + if (text_width < allowed_width) { + // increase letter count + while (true) { + ++count_letter; + std::string act_text = text.substr(0, count_letter); + text_width = ImGui::CalcTextSize(act_text.c_str()).x; + if (text_width < allowed_width) return result_text; + result_text = std::move(act_text); + } + } else { + // decrease letter count + while (true) { + --count_letter; + result_text = text.substr(0, count_letter); + text_width = ImGui::CalcTextSize(result_text.c_str()).x; + if (text_width > allowed_width) return result_text; + } + } + + assert(false); + return "Should not be accessible"; +} + ImVec2 ImGuiWrapper::suggest_location(const ImVec2 & dialog_size, const Slic3r::Polygon &interest) { diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 604b67bf66..fcad7819e5 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -128,6 +128,19 @@ public: bool want_text_input() const; bool want_any_input() const; + /// + /// Truncate text by ImGui draw function to specific width + /// NOTE 1: ImGui must be initialized + /// NOTE 2: Calculation for actual acive imgui font + /// + /// text to be truncated + /// maximal widht before truncate + /// strung put on end of text to be visible truncation + /// Truncated text + static std::string trunc(const std::string &text, + float width, + const char * tail = " .."); + /// /// Suggest loacation of dialog window, /// dependent on actual visible thing on platter