diff --git a/resources/handy_models/helper_disk.stl b/resources/handy_models/helper_disk.stl deleted file mode 100644 index 94ab0739c9..0000000000 Binary files a/resources/handy_models/helper_disk.stl and /dev/null differ diff --git a/resources/handy_models/torus.stl b/resources/handy_models/torus.stl deleted file mode 100644 index 3919fa5b21..0000000000 Binary files a/resources/handy_models/torus.stl and /dev/null differ diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index ecb99bf643..b388d5bd9e 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -1004,6 +1004,62 @@ indexed_triangle_set its_make_frustum(double r, double h, double fa) return mesh; } +// Generate the mesh for a torus +// r: major radius (distance from center of tube to center of torus) +// h: minor radius (radius of the tube) +// fa: angular step in radians (smaller = more segments) +indexed_triangle_set its_make_torus(double r, double h, double fa) +{ + indexed_triangle_set mesh; + auto& vertices = mesh.vertices; + auto& facets = mesh.indices; + + // Number of segments around the main ring and the tube + size_t n_major = (size_t)ceil(2. * PI / fa); + size_t n_minor = (size_t)ceil(2. * PI / fa); + + double major_step = 2. * PI / n_major; + double minor_step = 2. * PI / n_minor; + + // Reserve memory for performance + vertices.reserve(n_major * n_minor); + facets.reserve(n_major * n_minor * 2); + + // Generate vertices + for (size_t i = 0; i < n_major; ++i) { + double major_angle = i * major_step; + double cos_major = cos(major_angle); + double sin_major = sin(major_angle); + for (size_t j = 0; j < n_minor; ++j) { + double minor_angle = j * minor_step; + double cos_minor = cos(minor_angle); + double sin_minor = sin(minor_angle); + // Parametric equation for torus + float x = float((r + h * cos_minor) * cos_major); + float y = float((r + h * cos_minor) * sin_major); + float z = float(h * sin_minor); + vertices.emplace_back(Vec3f(x, y, z)); + } + } + + // Generate faces + for (size_t i = 0; i < n_major; ++i) { + size_t inext = (i + 1) % n_major; + for (size_t j = 0; j < n_minor; ++j) { + size_t jnext = (j + 1) % n_minor; + int v0 = int(i * n_minor + j); + int v1 = int(inext * n_minor + j); + int v2 = int(inext * n_minor + jnext); + int v3 = int(i * n_minor + jnext); + // Two triangles per quad + facets.emplace_back(v0, v1, v2); + facets.emplace_back(v0, v2, v3); + } + } + + 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 a30d8836ea..927dcfebb0 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -335,9 +335,10 @@ inline Vec3f its_face_normal(const indexed_triangle_set &its, const int face_idx 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_cylinder(double r, double h, double fa=(2*PI/180)); +indexed_triangle_set its_make_cone(double r, double h, double fa=(2*PI/180)); +indexed_triangle_set its_make_frustum(double r, double h, double fa=(2*PI/180)); +indexed_triangle_set its_make_torus(double r, double h, double fa); 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); @@ -349,10 +350,11 @@ inline indexed_triangle_set its_convex_hull(const indexed_triangle_set &its) { r inline TriangleMesh make_cube(double x, double y, double z) { return TriangleMesh(its_make_cube(x, y, z)); } inline TriangleMesh make_prism(float width, float length, float height) { return TriangleMesh(its_make_prism(width, length, height)); } -inline TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360)) { return TriangleMesh{its_make_cylinder(r, h, fa)}; } -inline TriangleMesh make_cone(double r, double h, double fa=(2*PI/360)) { return TriangleMesh(its_make_cone(r, h, fa)); } +inline TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/180)) { return TriangleMesh{its_make_cylinder(r, h, fa)}; } +inline TriangleMesh make_cone(double r, double h, double fa=(2*PI/180)) { return TriangleMesh(its_make_cone(r, h, fa)); } inline TriangleMesh make_pyramid(float base, float height) { return TriangleMesh(its_make_pyramid(base, height)); } -inline TriangleMesh make_sphere(double rho, double fa=(2*PI/360)) { return TriangleMesh(its_make_sphere(rho, fa)); } +inline TriangleMesh make_sphere(double rho, double fa=(2*PI/90)) { return TriangleMesh(its_make_sphere(rho, fa)); } +inline TriangleMesh make_torus(double r, double h, double fa=(PI/60)) { return TriangleMesh(its_make_torus(r, h, fa)); } bool its_write_stl_ascii(const char *file, const char *label, const std::vector &indices, const std::vector &vertices); inline bool its_write_stl_ascii(const char *file, const char *label, const indexed_triangle_set &its) { return its_write_stl_ascii(file, label, its.indices, its.vertices); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2be2190577..07d1bbc006 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2147,17 +2147,17 @@ static TriangleMesh create_mesh(const std::string& type_name, const BoundingBoxf else if (type_name == "Sphere") // Centered around 0, half the sphere below the print bed, half above. // The sphere has the same volume as the box above. - mesh = TriangleMesh(its_make_sphere(0.5 * side, PI / 18)); + mesh = TriangleMesh(its_make_sphere(0.5 * side, PI / 90)); else if (type_name == "Slab") // Sitting on the print bed, left front front corner at (0, 0). mesh = TriangleMesh(its_make_cube(bb.size().x() * 1.5, bb.size().y() * 1.5, bb.size().z() * 0.5)); else if (type_name == "Cone") mesh = TriangleMesh(its_make_cone(0.5 * side, side)); else if (type_name == "Disc") - mesh.ReadSTLFile((Slic3r::resources_dir() + "/handy_models/helper_disk.stl").c_str(), true, nullptr); + mesh = TriangleMesh(its_make_cylinder(0.5 * side, 0.2f)); else if (type_name == "Torus") - mesh.ReadSTLFile((Slic3r::resources_dir() + "/handy_models/torus.stl").c_str(), true, nullptr); - return TriangleMesh(mesh); + mesh = TriangleMesh(its_make_torus(0.5 * side, 0.125 * side,(PI / 60))); + return mesh; } void ObjectList::load_generic_subobject(const std::string& type_name, const ModelVolumeType type)