diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 7bf8608dde..e57d576ff2 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1303,7 +1303,7 @@ indexed_triangle_set ModelObject::get_connector_mesh(CutConnectorAttributes conn } if (connector_attributes.type == CutConnectorType::Rivet) - connector_mesh = its_make_rivet(1.0, 1.0, (2 * PI / /*sectorCount*/10)); + connector_mesh = its_make_rivet(1.0, 1.0); 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) @@ -1415,7 +1415,8 @@ void ModelVolume::apply_tolerance() rot_norm.normalize(); double z_offset = 0.5 * static_cast(cut_info.height_tolerance); - if (cut_info.connector_type == CutConnectorType::Plug) + if (cut_info.connector_type == CutConnectorType::Plug || + cut_info.connector_type == CutConnectorType::Rivet) z_offset -= 0.05; // add small Z offset to better preview set_offset(get_offset() + rot_norm * z_offset); @@ -1452,7 +1453,20 @@ void ModelObject::process_connector_cut(ModelVolume* volume, const Transform3d& // This transformation is already there if (volume->cut_info.connector_type != CutConnectorType::Dowel) { if (attributes.has(ModelObjectCutAttribute::KeepUpper)) { - ModelVolume* vol = upper->add_volume(*volume); + ModelVolume* vol = nullptr; + if (volume->cut_info.connector_type == CutConnectorType::Rivet) { + TriangleMesh mesh = TriangleMesh(its_make_cylinder(1.0, 1.0, PI / 180.)); + + vol = upper->add_volume(std::move(mesh)); + vol->set_transformation(volume->get_transformation()); + vol->set_type(ModelVolumeType::NEGATIVE_VOLUME); + + vol->cut_info = volume->cut_info; + vol->name = volume->name; + } + else + vol = upper->add_volume(*volume); + vol->set_transformation(volume_matrix); vol->apply_tolerance(); } diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 374387273f..4d1d163851 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -1262,17 +1262,17 @@ 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) +indexed_triangle_set its_make_rivet(double r, double h, float space_proportion) { const float radius = (float)r; const float height = (float)h; - const size_t sectors_cnt = 10;//(float)fa; + const size_t sectors_cnt = 10; //(float)fa; const float halfPI = 0.5f * (float)PI; - const float space_len = 0.2f * radius; + const float space_len = space_proportion * radius; - const float b_len = 0.75f * radius; - const float m_len = radius; + const float b_len = radius; + const float m_len = (1 + 0.5f*space_proportion) * radius; const float t_len = 0.5f * radius; const float b_height = 0.f; @@ -1280,46 +1280,18 @@ indexed_triangle_set its_make_rivet(double r, double h, double fa) 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) { + auto add_side_vertices = [b_vec, t_vec, b_height, m_height, t_height](std::vector& vertices, float b_angle, float t_angle, const Vec2f& m_vec) { Vec2f b_pt = Eigen::Rotation2Df(b_angle) * b_vec; - Vec2f m_pt = Eigen::Rotation2Df(m_angle) * m_vec; + Vec2f m_pt = Eigen::Rotation2Df(b_angle) * m_vec; Vec2f t_pt = Eigen::Rotation2Df(t_angle) * t_vec; vertices.emplace_back(Vec3f(b_pt(0), b_pt(1), b_height)); @@ -1327,25 +1299,8 @@ indexed_triangle_set its_make_rivet(double r, double h, double fa) 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; + auto add_side_facets = [](std::vector& facets, int vertices_cnt, int frst_id, int scnd_id) { + int id = vertices_cnt - 1; facets.emplace_back(frst_id, id - 2, id - 5); @@ -1355,84 +1310,75 @@ indexed_triangle_set its_make_rivet(double r, double h, double fa) 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; + const float f = (b_len - m_len) / m_len; // Flattening - 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); - } + auto get_m_len = [b_len, f](float angle) { + const float rad_sqr = b_len * b_len; + const float sin_sqr = sin(angle) * sin(angle); + const float f_sqr = (1-f)*(1-f); + return sqrtf(rad_sqr / (1 + (1 / f_sqr - 1) * sin_sqr)); + }; + + auto add_sub_mesh = [add_side_vertices, add_side_facets, get_m_len, + b_height, t_height, b_angle, t_angle, b_angle_step, t_angle_step] + (indexed_triangle_set& mesh, float center_x, float angle_rotation, int frst_vertex_id) { + auto& vertices = mesh.vertices; + auto& facets = mesh.indices; + + // 2 special vertices, top and bottom center, rest are relative to this + vertices.emplace_back(Vec3f(center_x, 0.f, b_height)); + vertices.emplace_back(Vec3f(center_x, 0.f, t_height)); + + float b_angle_start = angle_rotation - b_angle; + float t_angle_start = angle_rotation - t_angle; + const float b_angle_stop = angle_rotation + b_angle; + + const int frst_id = frst_vertex_id; + const int scnd_id = frst_id + 1; + + // add first side vertices and internal facets + { + const Vec2f m_vec = Eigen::Vector2f(0, get_m_len(b_angle_start)); + add_side_vertices(vertices, b_angle_start, t_angle_start, m_vec); + + int id = (int)vertices.size() - 1; + + facets.emplace_back(frst_id, id - 2, id - 1); + facets.emplace_back(frst_id, id - 1, id); + facets.emplace_back(frst_id, id, scnd_id); + } + + // add d side vertices and facets + while (b_angle_start < b_angle_stop) { + b_angle_start += b_angle_step; + t_angle_start += t_angle_step; + + const Vec2f m_vec = Eigen::Vector2f(0, get_m_len(b_angle_start)); + add_side_vertices(vertices, b_angle_start, t_angle_start, m_vec); + + add_side_facets(facets, (int)vertices.size(), frst_id, scnd_id); + } + + // add last internal 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); + } + }; + indexed_triangle_set mesh; + mesh.vertices.reserve(2 * (3 * (2 * sectors_cnt + 1) + 2)); + mesh.indices.reserve(2 * (6 * 2 * sectors_cnt + 6)); - 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); - } - + add_sub_mesh(mesh, -space_len, halfPI , 0); + add_sub_mesh(mesh, space_len, 3 * halfPI, (int)mesh.vertices.size()); return mesh; } diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index f6a18f59ce..d56f868637 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -321,7 +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_make_rivet(double r, double h, float space_proportion = 0.25f); 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); }