diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index 45e4b6f5dc..197b4d488d 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -1,6 +1,9 @@ #include "TriangleMesh.hpp" #include "ClipperUtils.hpp" #include "Geometry.hpp" +#include "qhull/src/libqhullcpp/Qhull.h" +#include "qhull/src/libqhullcpp/QhullFacetList.h" +#include "qhull/src/libqhullcpp/QhullVertexSet.h" #include #include #include @@ -10,6 +13,7 @@ #include #include #include +#include #include @@ -597,6 +601,50 @@ TriangleMesh::bounding_box() const return bb; } + +TriangleMesh TriangleMesh::convex_hull3d() const +{ + // qhull's realT is assumed to be a typedef for float - let's better check it first: + static_assert(std::is_same::value, "Internal type realT in the qhull library must be float!"); + + // Helper struct for qhull: + struct PointForQHull{ + PointForQHull(float x_p, float y_p, float z_p) : x(x_p), y(y_p), z(z_p) {} + float x,y,z; + }; + std::vector input_verts; + + // We will now fill the vector with input points for computation: + stl_facet* facet_ptr = stl.facet_start; + while (facet_ptr < stl.facet_start+stl.stats.number_of_facets) { + for (int j=0;j<3;++j) + input_verts.emplace_back(PointForQHull(facet_ptr->vertex[j].x, facet_ptr->vertex[j].y, facet_ptr->vertex[j].z)); + facet_ptr+=1; + } + + // The qhull call: + orgQhull::Qhull qhull; + qhull.disableOutputStream(); // we want qhull to be quiet + qhull.runQhull("", 3, input_verts.size(), (const realT*)(input_verts.data()), "Qt" ); + + // Let's collect results: + Pointf3s vertices; + std::vector facets; + auto facet_list = qhull.facetList().toStdVector(); + for (const orgQhull::QhullFacet& facet : facet_list) { // iterate through facets + for (unsigned char i=0; i<3; ++i) { // iterate through facet's vertices + orgQhull::QhullPoint p = (facet.vertices())[i].point(); + const float* coords = p.coordinates(); + Pointf3 vert((float)coords[0], (float)coords[1], (float)coords[2]); + vertices.emplace_back(vert); + } + facets.emplace_back(Point3(vertices.size()-3, vertices.size()-2, vertices.size()-1)); + } + TriangleMesh output_mesh(vertices, facets); + output_mesh.repair(); + return output_mesh; +} + void TriangleMesh::require_shared_vertices() { diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp index c700784a51..14fdba6c35 100644 --- a/xs/src/libslic3r/TriangleMesh.hpp +++ b/xs/src/libslic3r/TriangleMesh.hpp @@ -55,6 +55,7 @@ public: ExPolygons horizontal_projection() const; Polygon convex_hull(); BoundingBoxf3 bounding_box() const; + TriangleMesh convex_hull3d() const; void reset_repair_stats(); bool needed_repair() const; size_t facets_count() const;