diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index e95c7f1226..6024cd7754 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1309,7 +1309,7 @@ indexed_triangle_set ModelObject::get_connector_mesh(CutConnectorAttributes conn 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_cone(1.0, 1.0, (2 * PI / sectorCount)); + connector_mesh = its_make_frustum(1.0, 1.0, (2 * PI / sectorCount)); else connector_mesh = its_make_frustum_dowel(1.0, 1.0, sectorCount); diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index cf0d29eb8f..4d9dff3452 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -965,6 +965,51 @@ indexed_triangle_set its_make_cylinder(double r, double h, double fa) return mesh; } +indexed_triangle_set its_make_frustum(double r, double h, double fa) +{ + indexed_triangle_set mesh; + size_t n_steps = (size_t)ceil(2. * PI / fa); + double angle_step = 2. * PI / n_steps; + + auto &vertices = mesh.vertices; + auto &facets = mesh.indices; + vertices.reserve(2 * n_steps + 2); + facets.reserve(4 * n_steps); + + // 2 special vertices, top and bottom center, rest are relative to this + vertices.emplace_back(Vec3f(0.f, 0.f, 0.f)); + vertices.emplace_back(Vec3f(0.f, 0.f, float(h))); + + // for each line along the polygon approximating the top/bottom of the + // circle, generate four points and four facets (2 for the wall, 2 for the + // top and bottom. + // Special case: Last line shares 2 vertices with the first line. + Vec2f vec_top = Eigen::Rotation2Df(0.f) * Eigen::Vector2f(0, 0.5f*r); + Vec2f vec_botton = Eigen::Rotation2Df(0.f) * Eigen::Vector2f(0, r); + + vertices.emplace_back(Vec3f(vec_botton(0), vec_botton(1), 0.f)); + vertices.emplace_back(Vec3f(vec_top(0), vec_top(1), float(h))); + for (size_t i = 1; i < n_steps; ++i) { + vec_top = Eigen::Rotation2Df(angle_step * i) * Eigen::Vector2f(0, 0.5f*float(r)); + vec_botton = Eigen::Rotation2Df(angle_step * i) * Eigen::Vector2f(0, float(r)); + vertices.emplace_back(Vec3f(vec_botton(0), vec_botton(1), 0.f)); + vertices.emplace_back(Vec3f(vec_top(0), vec_top(1), float(h))); + int id = (int)vertices.size() - 1; + facets.emplace_back( 0, id - 1, id - 3); // top + facets.emplace_back(id, 1, id - 2); // bottom + facets.emplace_back(id, id - 2, id - 3); // upper-right of side + facets.emplace_back(id, id - 3, id - 1); // bottom-left of side + } + // Connect the last set of vertices with the first. + int id = (int)vertices.size() - 1; + facets.emplace_back( 0, 2, id - 1); + facets.emplace_back( 3, 1, id); + facets.emplace_back(id, 2, 3); + facets.emplace_back(id, id - 1, 2); + + return mesh; +} + indexed_triangle_set its_make_cone(double r, double h, double fa) { indexed_triangle_set mesh; diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 6473f77837..0f43f9d58d 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -317,6 +317,7 @@ indexed_triangle_set its_make_cube(double x, double y, double z); indexed_triangle_set its_make_prism(float width, float length, float height); indexed_triangle_set its_make_cylinder(double r, double h, double fa=(2*PI/360)); indexed_triangle_set its_make_cone(double r, double h, double fa=(2*PI/360)); +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); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 6ea5df22fd..820e35a375 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -2274,13 +2274,16 @@ void GLGizmoCut3D::reset_connectors() void GLGizmoCut3D::init_connector_shapes() { for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug}) - for (const CutConnectorStyle& style : {CutConnectorStyle::Frustum, CutConnectorStyle::Prism}) + 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}) { const CutConnectorAttributes attribs = { type, style, shape }; const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs); m_shapes[attribs].model.init_from(its); m_shapes[attribs].mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); } + } } void GLGizmoCut3D::update_connector_shape()