From d3dd0258331f789e27bf7fea3a60c7a1b4f14871 Mon Sep 17 00:00:00 2001 From: Filip Sykala Date: Thu, 4 Nov 2021 12:41:53 +0100 Subject: [PATCH] Draw text convex hull --- src/slic3r/GUI/Camera.cpp | 29 +++++++ src/slic3r/GUI/Camera.hpp | 2 + src/slic3r/GUI/GLSelectionRectangle.cpp | 19 +---- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 81 +++++++++++++------ .../libslic3r/test_quadric_edge_collapse.cpp | 2 +- 5 files changed, 93 insertions(+), 40 deletions(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 44b0cd84a1..b7aaf19998 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -9,6 +9,7 @@ #endif // ENABLE_CAMERA_STATISTICS #include +#include // projecting points namespace Slic3r { namespace GUI { @@ -492,6 +493,34 @@ void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up update_zenit(); } +Points Camera::project(const std::vector &points) const +{ + Vec4i viewport(m_viewport.data()); + + // Convert our std::vector to Eigen dynamic matrix. + Eigen::Matrix + pts(points.size(), 3); + for (size_t i = 0; i < points.size(); ++i) + pts.block<1, 3>(i, 0) = points[i]; + + // Get the projections. + Eigen::Matrix projections; + igl::project(pts, m_view_matrix.matrix(), m_projection_matrix.matrix(), viewport, projections); + + Points result; + result.reserve(points.size()); + int window_height = viewport[3]; + + // Iterate over all points and determine whether they're in the rectangle. + for (int i = 0; i < projections.rows(); ++i) { + double x = projections(i, 0); + double y = projections(i, 1); + // opposit direction o Y + result.emplace_back(x, window_height - y); + } + return result; +} + void Camera::set_default_orientation() { m_zenit = 45.0f; diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index a61eb44ec5..c6727ba54d 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -129,6 +129,8 @@ public: double max_zoom() const { return 250.0; } double min_zoom() const { return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box); } + // project point throw camera to 2d coordinate + Points project(const std::vector &points) const; private: // returns tight values for nearZ and farZ plane around the given bounding box // the camera MUST be outside of the bounding box in eye coordinate of the given box diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index 13467499a1..a9a12d4b3b 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -38,26 +38,13 @@ namespace GUI { m_state = Off; - const Camera& camera = wxGetApp().plater()->get_camera(); - Matrix4d modelview = camera.get_view_matrix().matrix(); - Matrix4d projection= camera.get_projection_matrix().matrix(); - Vec4i viewport(camera.get_viewport().data()); - - // Convert our std::vector to Eigen dynamic matrix. - Eigen::Matrix pts(points.size(), 3); - for (size_t i=0; i(i, 0) = points[i]; - - // Get the projections. - Eigen::Matrix projections; - igl::project(pts, modelview, projection, viewport, projections); - // bounding box created from the rectangle corners - will take care of order of the corners BoundingBox rectangle(Points{ Point(m_start_corner.cast()), Point(m_end_corner.cast()) }); // Iterate over all points and determine whether they're in the rectangle. - for (int i = 0; iget_camera().project(points); + for (int i = 0; i ClearActiveID @@ -457,6 +455,48 @@ void GLGizmoEmboss::close() { m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss); } +static void draw(const Slic3r::Polygon &polygon, + ImU32 color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 0.65f)), + float thickness = 1.f) +{ + // minimal one line + if (polygon.size()<2) return; + + auto dl = ImGui::GetOverlayDrawList(); + //auto dl = ImGui::GetWindowDrawList(); + const Point* prev_point = &polygon.points.back(); + for (const Point &point : polygon.points) { + ImVec2 p1(prev_point->x(), prev_point->y()); + ImVec2 p2(point.x(), point.y()); + dl->AddLine(p1, p2, color, thickness); + prev_point = &point; + } +} + +#include "libslic3r/Geometry.hpp" +static void draw_hull(const GLVolume& volume) +{ + const TriangleMesh &tm = *volume.convex_hull(); + ImGui::Text("hull size %d", (int) tm.its.vertices.size()); + + //Slic3r::Polygon test_triangle({Point(100, 100), Point(200, 150), Point(120, 210)}); + //draw(test_triangle); + + // transform 3d hull + Geometry::Transformation trafo = volume.get_instance_transformation(); + const Transform3d & trafoMat = trafo.get_matrix(); + std::vector vertices; + vertices.reserve(tm.its.vertices.size()); + for (const Vec3f &vertex : tm.its.vertices) + vertices.emplace_back(trafoMat * vertex.cast()); + + const Camera camera = wxGetApp().plater()->get_camera(); + Points vertices_2d = camera.project(vertices); + Slic3r::Polygon chull = Geometry::convex_hull(vertices_2d); + draw(chull, ImGui::GetColorU32(ImVec4(0.7f, 0.1f, 0.2f, 0.75f)), 3.f); +} + + void GLGizmoEmboss::draw_window() { #ifdef ALLOW_DEBUG_MODE @@ -467,11 +507,14 @@ void GLGizmoEmboss::draw_window() m_font_list.emplace_back(WxFontUtils::get_os_font()); bool loaded = load_font(font_index); } + + const Selection &selection = m_parent.get_selection(); + const GLVolume * volume = selection.get_volume( + *selection.get_volume_idxs().begin()); + if (volume != nullptr) draw_hull(*volume); + + #endif // ALLOW_DEBUG_MODE - - std::string descriptor = m_font_list[m_font_selected].path; - ImGui::Text("actual descriptor is %s", descriptor.c_str()); - if (!m_font.has_value()) { ImGui::Text(_u8L("Warning: No font is selected. Select correct one.").c_str()); } @@ -592,10 +635,6 @@ void GLGizmoEmboss::draw_text_input() // imgui_font has to be unused if (exist_change) check_imgui_font_range(); - -#ifdef ALLOW_DEBUG_MODE - ImGui::Image(m_imgui_font_atlas.TexID, ImVec2(m_imgui_font_atlas.TexWidth, m_imgui_font_atlas.TexHeight)); -#endif // ALLOW_DEBUG_MODE } void GLGizmoEmboss::draw_advanced() { @@ -636,14 +675,15 @@ void GLGizmoEmboss::draw_advanced() { ImGui::EndCombo(); } } - + +#ifdef ALLOW_DEBUG_MODE + std::string descriptor = m_font_list[m_font_selected].path; + ImGui::Text("descriptor = %s", descriptor.c_str()); ImGui::Text("style = %s", (m_font_prop.style.has_value()?m_font_prop.style->c_str() : " --- ")); ImGui::Text("weight = %s", (m_font_prop.weight.has_value()? m_font_prop.weight->c_str() : " --- ")); ImGui::Text("face name = %s", (m_font_prop.face_name.has_value()?m_font_prop.face_name->c_str() : " --- ")); - - // ImGui::InputFloat3("Origin", m_orientation.origin.data()); - // if (ImGui::InputFloat3("Normal", m_normal.data())) m_normal.normalize(); - // if (ImGui::InputFloat3("Up", m_up.data())) m_up.normalize(); + ImGui::Image(m_imgui_font_atlas.TexID, ImVec2(m_imgui_font_atlas.TexWidth, m_imgui_font_atlas.TexHeight)); +#endif // ALLOW_DEBUG_MODE } bool GLGizmoEmboss::create_default_model_object() @@ -733,11 +773,7 @@ bool GLGizmoEmboss::load_font(const wxFont& font) auto font_opt = WxFontUtils::load_font(font); if (!font_opt.has_value()) return false; m_font = font_opt; - - FontProp old_font_prop = m_font_prop; // copy - WxFontUtils::update_property(m_font_prop, font); - m_font_prop.emboss = m_font_prop.size_in_mm / 2.f; load_imgui_font(); return true; @@ -818,9 +854,8 @@ void GLGizmoEmboss::load_imgui_font() { GLuint font_texture; glsafe(::glGenTextures(1, &font_texture)); glsafe(::glBindTexture(GL_TEXTURE_2D, font_texture)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR)); glsafe(::glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels)); diff --git a/tests/libslic3r/test_quadric_edge_collapse.cpp b/tests/libslic3r/test_quadric_edge_collapse.cpp index b3e4c61087..edde39aa15 100644 --- a/tests/libslic3r/test_quadric_edge_collapse.cpp +++ b/tests/libslic3r/test_quadric_edge_collapse.cpp @@ -192,7 +192,7 @@ TEST_CASE("Reduce to one triangle by Quadric Edge Collapse", "[its]") //CHECK(is_equal(its.vertices, triangle_vertices)); } -TEST_CASE("Reduce to one triangle by Quadric Edge Collapse", "[its]") +TEST_CASE("Reduce to one tetrahedron by Quadric Edge Collapse", "[its]") { // Extend previous test to tetrahedron to make it manifold indexed_triangle_set its;