From 6a2afc915392b1681ff6391d19a057d328ef3b55 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 29 Jun 2023 10:02:18 +0200 Subject: [PATCH] WIP: Add new connector - "Rivet" * Improves for UI * Implemented Rivet mesh --- resources/icons/rivet.svg | 13 ++ src/imgui/imconfig.h | 1 + src/libslic3r/Model.cpp | 4 +- src/libslic3r/Model.hpp | 1 + src/libslic3r/TriangleMesh.cpp | 175 +++++++++++++++++++++++++++ src/libslic3r/TriangleMesh.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 35 ++++-- src/slic3r/GUI/ImGuiWrapper.cpp | 1 + 8 files changed, 217 insertions(+), 14 deletions(-) create mode 100644 resources/icons/rivet.svg diff --git a/resources/icons/rivet.svg b/resources/icons/rivet.svg new file mode 100644 index 0000000000..db4760cb65 --- /dev/null +++ b/resources/icons/rivet.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index 5aed978426..a152252bac 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -152,6 +152,7 @@ namespace ImGui // const wchar_t MmuSegmentationMarker = 0x1F; const wchar_t PlugMarker = 0x1C; const wchar_t DowelMarker = 0x1D; + const wchar_t RivetMarker = 0x1E; // Do not forget use following letters only in wstring const wchar_t DocumentationButton = 0x2600; const wchar_t DocumentationHoverButton = 0x2601; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 5c001e3538..7bf8608dde 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1302,7 +1302,9 @@ indexed_triangle_set ModelObject::get_connector_mesh(CutConnectorAttributes conn break; } - if (connector_attributes.style == CutConnectorStyle::Prism) + if (connector_attributes.type == CutConnectorType::Rivet) + connector_mesh = its_make_rivet(1.0, 1.0, (2 * PI / /*sectorCount*/10)); + else if (connector_attributes.style == CutConnectorStyle::Prism) connector_mesh = its_make_cylinder(1.0, 1.0, (2 * PI / sectorCount)); else if (connector_attributes.type == CutConnectorType::Plug) connector_mesh = its_make_frustum(1.0, 1.0, (2 * PI / sectorCount)); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 2ee48f9917..d0409588ff 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -224,6 +224,7 @@ private: enum class CutConnectorType : int { Plug , Dowel + , Rivet , Undef }; diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 4bf9fd486a..374387273f 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -1262,6 +1262,181 @@ indexed_triangle_set its_make_frustum_dowel(double radius, double h, int sectorC return mesh; } +indexed_triangle_set its_make_rivet(double r, double h, double fa) +{ + const float radius = (float)r; + const float height = (float)h; + const size_t sectors_cnt = 10;//(float)fa; + const float halfPI = 0.5f * (float)PI; + + const float space_len = 0.2f * radius; + + const float b_len = 0.75f * radius; + const float m_len = radius; + const float t_len = 0.5f * radius; + + const float b_height = 0.f; + const float m_height = 0.5f * height; + const float t_height = height; + + const float b_angle = acos(space_len/b_len); + const float m_angle = acos(space_len/m_len); + const float t_angle = acos(space_len/t_len); + + const float b_angle_step = b_angle / (float)sectors_cnt; + const float m_angle_step = m_angle / (float)sectors_cnt; + const float t_angle_step = t_angle / (float)sectors_cnt; + + const Vec2f b_vec = Eigen::Vector2f(0, b_len); + const Vec2f m_vec = Eigen::Vector2f(0, m_len); + const Vec2f t_vec = Eigen::Vector2f(0, t_len); + + const Vec2f space_vec = Eigen::Vector2f(0, space_len); + Vec2f b_pt = Eigen::Rotation2Df(halfPI) * space_vec; + + + indexed_triangle_set mesh; + + auto& vertices = mesh.vertices; + auto& facets = mesh.indices; + + vertices.reserve(2 * 3 * sectors_cnt + 2); + facets.reserve(2 * 6 * sectors_cnt); + + + float b_angle_start = halfPI - b_angle; + float m_angle_start = halfPI - m_angle; + float t_angle_start = halfPI - t_angle; + + float b_angle_stop = halfPI + b_angle; + + // 2 special vertices, top and bottom center, rest are relative to this + vertices.emplace_back(Vec3f(-space_len, 0.f, b_height)); + vertices.emplace_back(Vec3f(-space_len, 0.f, t_height)); + + int frst_id = 0; + int scnd_id = 1; + + auto add_side_vertices = [b_vec, m_vec, t_vec, b_height, m_height, t_height](std::vector& vertices, float b_angle, float m_angle, float t_angle) { + Vec2f b_pt = Eigen::Rotation2Df(b_angle) * b_vec; + Vec2f m_pt = Eigen::Rotation2Df(m_angle) * m_vec; + Vec2f t_pt = Eigen::Rotation2Df(t_angle) * t_vec; + + vertices.emplace_back(Vec3f(b_pt(0), b_pt(1), b_height)); + vertices.emplace_back(Vec3f(m_pt(0), m_pt(1), m_height)); + vertices.emplace_back(Vec3f(t_pt(0), t_pt(1), t_height)); + }; + + // add first vertices and facets + { + add_side_vertices(vertices, b_angle_start, m_angle_start, t_angle_start); + + int id = (int)vertices.size() - 1; + + facets.emplace_back(id - 4, id - 2, id - 1); + facets.emplace_back(id - 4, id - 1, id); + facets.emplace_back(id - 4, id, id - 3); + } + + while (b_angle_start < b_angle_stop) { + b_angle_start += b_angle_step; + m_angle_start += m_angle_step; + t_angle_start += t_angle_step; + + add_side_vertices(vertices, b_angle_start, m_angle_start, t_angle_start); + + int id = (int)vertices.size() - 1; + + facets.emplace_back(frst_id, id - 2, id - 5); + + facets.emplace_back(id - 2, id - 1, id - 5); + facets.emplace_back(id - 1, id - 4, id - 5); + facets.emplace_back(id - 4, id - 1, id); + facets.emplace_back(id, id - 3, id - 4); + + facets.emplace_back(id, scnd_id, id - 3); + } + + // add facets to close the mesh + { + int id = (int)vertices.size() - 1; + + facets.emplace_back(frst_id, scnd_id, id); + facets.emplace_back(frst_id, id, id - 1); + facets.emplace_back(frst_id, id - 1, id - 2); + } + + + + + b_angle_start = 3 * halfPI - b_angle; + m_angle_start = 3 * halfPI - m_angle; + t_angle_start = 3 * halfPI - t_angle; + + b_angle_stop = 3 * halfPI + b_angle; + + frst_id = (int)vertices.size(); + scnd_id = frst_id+1; + + // 2 special vertices, top and bottom center, rest are relative to this + vertices.emplace_back(Vec3f(space_len, 0.f, b_height)); + vertices.emplace_back(Vec3f(space_len, 0.f, t_height)); + + // add first vertices and facets + { + Vec2f b_pt = Eigen::Rotation2Df(b_angle_start) * b_vec; + Vec2f m_pt = Eigen::Rotation2Df(m_angle_start) * m_vec; + Vec2f t_pt = Eigen::Rotation2Df(t_angle_start) * t_vec; + + vertices.emplace_back(Vec3f(b_pt(0), b_pt(1), b_height)); + vertices.emplace_back(Vec3f(m_pt(0), m_pt(1), m_height)); + vertices.emplace_back(Vec3f(t_pt(0), t_pt(1), t_height)); + + int id = (int)vertices.size() - 1; + + facets.emplace_back(id - 4, id - 2, id - 1); + facets.emplace_back(id - 4, id - 1, id); + facets.emplace_back(id - 4, id , id - 3); + } + + while (b_angle_start < b_angle_stop) { + b_angle_start += b_angle_step; + m_angle_start += m_angle_step; + t_angle_start += t_angle_step; + + Vec2f b_pt = Eigen::Rotation2Df(b_angle_start) * b_vec; + Vec2f m_pt = Eigen::Rotation2Df(m_angle_start) * m_vec; + Vec2f t_pt = Eigen::Rotation2Df(t_angle_start) * t_vec; + + vertices.emplace_back(Vec3f(b_pt(0), b_pt(1), b_height)); + vertices.emplace_back(Vec3f(m_pt(0), m_pt(1), m_height)); + vertices.emplace_back(Vec3f(t_pt(0), t_pt(1), t_height)); + + int id = (int)vertices.size() - 1; + + facets.emplace_back(frst_id, id - 2, id - 5); + + facets.emplace_back(id - 2, id - 1, id - 5); + facets.emplace_back(id - 1, id - 4, id - 5); + facets.emplace_back(id - 4, id - 1, id); + facets.emplace_back(id, id - 3, id - 4); + + facets.emplace_back(id, scnd_id, id - 3); + } + + // add facets to close the mesh + { + int id = (int)vertices.size() - 1; + + facets.emplace_back(frst_id, scnd_id, id); + facets.emplace_back(frst_id, id, id - 1); + facets.emplace_back(frst_id, id - 1, id - 2); + } + + + return mesh; +} + indexed_triangle_set its_convex_hull(const std::vector &pts) { std::vector dst_vertices; diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 0f43f9d58d..f6a18f59ce 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -321,6 +321,7 @@ indexed_triangle_set its_make_frustum(double r, double h, double fa=(2*PI/360 indexed_triangle_set its_make_frustum_dowel(double r, double h, int sectorCount); indexed_triangle_set its_make_pyramid(float base, float height); indexed_triangle_set its_make_sphere(double radius, double fa); +indexed_triangle_set its_make_rivet(double r, double h, double fa=(2*PI/360)); indexed_triangle_set its_convex_hull(const std::vector &pts); inline indexed_triangle_set its_convex_hull(const indexed_triangle_set &its) { return its_convex_hull(its.vertices); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 27585aefd4..9a217a461d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -186,8 +186,7 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, , m_connector_style (int(CutConnectorStyle::Prism)) , m_connector_shape_id (int(CutConnectorShape::Circle)) { - m_mode = size_t(CutMode::cutTongueAndGroove); - m_contour_width = .0f; + m_connector_type = CutConnectorType::Rivet; m_modes = { _u8L("Planar"), _u8L("Tongue and Groove")//, _u8L("Grid") // , _u8L("Radial"), _u8L("Modular") @@ -197,7 +196,8 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, std::map connetor_types = { {ImGui::PlugMarker , _u8L("Plug") }, - {ImGui::DowelMarker, _u8L("Dowel") }, + {ImGui::DowelMarker, _u8L("Dowel") }, + {ImGui::RivetMarker, _u8L("Rivet") }, }; for (auto connector : connetor_types) { std::string type_label = " " + connector.second + " "; @@ -1986,20 +1986,27 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors) m_imgui->text(m_labels_map["Type"]); bool type_changed = render_connect_type_radio_button(CutConnectorType::Plug); type_changed |= render_connect_type_radio_button(CutConnectorType::Dowel); + type_changed |= render_connect_type_radio_button(CutConnectorType::Rivet); if (type_changed) apply_selected_connectors([this, &connectors] (size_t idx) { connectors[idx].attribs.type = CutConnectorType(m_connector_type); }); - m_imgui->disabled_begin(m_connector_type == CutConnectorType::Dowel); - if (type_changed && m_connector_type == CutConnectorType::Dowel) { - m_connector_style = int(CutConnectorStyle::Prism); - apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); }); - } - if (render_combo(m_labels_map["Style"], m_connector_styles, m_connector_style)) - apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); }); + m_imgui->disabled_begin(m_connector_type != CutConnectorType::Plug); + if (type_changed && m_connector_type == CutConnectorType::Dowel) { + m_connector_style = int(CutConnectorStyle::Prism); + apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); }); + } + if (render_combo(m_labels_map["Style"], m_connector_styles, m_connector_style)) + apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); }); m_imgui->disabled_end(); - if (render_combo(m_labels_map["Shape"], m_connector_shapes, m_connector_shape_id)) - apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); }); + m_imgui->disabled_begin(m_connector_type == CutConnectorType::Rivet); + if (type_changed && m_connector_type == CutConnectorType::Rivet) { + m_connector_shape_id = int(CutConnectorShape::Circle); + apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); }); + } + if (render_combo(m_labels_map["Shape"], m_connector_shapes, m_connector_shape_id)) + apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); }); + m_imgui->disabled_end(); if (render_slider_double_input(m_labels_map["Depth"], m_connector_depth_ratio, m_connector_depth_ratio_tolerance)) apply_selected_connectors([this, &connectors](size_t idx) { @@ -3232,11 +3239,13 @@ void GLGizmoCut3D::reset_connectors() void GLGizmoCut3D::init_connector_shapes() { - for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug}) + for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug, CutConnectorType::Rivet}) for (const CutConnectorStyle& style : {CutConnectorStyle::Frustum, CutConnectorStyle::Prism}) { if (type == CutConnectorType::Dowel && style == CutConnectorStyle::Frustum) continue; for (const CutConnectorShape& shape : {CutConnectorShape::Circle, CutConnectorShape::Hexagon, CutConnectorShape::Square, CutConnectorShape::Triangle}) { + if (type == CutConnectorType::Rivet && shape != CutConnectorShape::Circle) + continue; const CutConnectorAttributes attribs = { type, style, shape }; indexed_triangle_set its = ModelObject::get_connector_mesh(attribs); m_shapes[attribs].model.init_from(its); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 1a800eee42..ec1d039888 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -67,6 +67,7 @@ static const std::map font_icons = { {ImGui::InfoMarkerSmall , "notification_info" }, {ImGui::PlugMarker , "plug" }, {ImGui::DowelMarker , "dowel" }, + {ImGui::RivetMarker , "rivet" }, }; static const std::map font_icons_large = {