Skip to content

Commit

Permalink
Add a Basic VHACD Convex Hull to Manifold
Browse files Browse the repository at this point in the history
  • Loading branch information
zalo committed Mar 11, 2024
1 parent 22d94d5 commit 9c72757
Show file tree
Hide file tree
Showing 4 changed files with 8,472 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/manifold/include/manifold.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,11 @@ class Manifold {
*/
///@{
Manifold Hull() const;
Manifold Hull2() const;
static Manifold Hull(const std::vector<Manifold>& manifolds);
static Manifold Hull(const std::vector<glm::vec3>& pts);
static Manifold Hull2(const std::vector<Manifold>& manifolds);
static Manifold Hull2(const std::vector<glm::vec3>& pts);
///@}

/** @name Testing hooks
Expand Down
60 changes: 60 additions & 0 deletions src/manifold/src/manifold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "csg_tree.h"
#include "impl.h"
#include "par.h"
#define ENABLE_VHACD_IMPLEMENTATION 1
#include "VHACD.h"

namespace {
using namespace manifold;
Expand Down Expand Up @@ -868,11 +870,60 @@ Manifold Manifold::Hull(const std::vector<glm::vec3>& pts) {
return Manifold(mesh);
}

/**
* Compute the convex hull of a set of points using VHACD's Convex Hull
* Implementation. If the given points are fewer than 4, or they are all
* coplanar, an empty Manifold will be returned.
*
* @param pts A vector of 3-dimensional points over which to compute a convex
* hull.
*/
Manifold Manifold::Hull2(const std::vector<glm::vec3>& pts) {
ZoneScoped;
const int numVert = pts.size();
if (numVert < 4) return Manifold();

std::vector<VHACD::Vertex> vertices(numVert);
for (int i = 0; i < numVert; i++) {
vertices[i].mX = pts[i].x;
vertices[i].mY = pts[i].y;
vertices[i].mZ = pts[i].z;
}

// Compute the Convex Hull
VHACD::ConvexHull hull(vertices, double(0.0000001));

Mesh mesh;

auto& vlist = hull.GetVertexPool();
if (!vlist.empty()) {
mesh.vertPos.resize(vlist.size());
for (int i = 0; i < vlist.size(); i++) {
mesh.vertPos[i] = {vlist[i].GetX(), vlist[i].GetY(), vlist[i].GetZ()};
}
}

auto outputVertices = hull.GetList();
mesh.triVerts.reserve(outputVertices.size());
for (std::list<VHACD::ConvexHullFace>::const_iterator node = outputVertices.begin();
node != outputVertices.end(); ++node) {
const VHACD::ConvexHullFace& face = *node;
mesh.triVerts.push_back({face.m_index[0], face.m_index[1], face.m_index[2]});
}

return Manifold(mesh);
}

/**
* Compute the convex hull of this manifold.
*/
Manifold Manifold::Hull() const { return Hull(GetMesh().vertPos); }

/**
* Compute the convex hull of this manifold.
*/
Manifold Manifold::Hull2() const { return Hull2(GetMesh().vertPos); }

/**
* Compute the convex hull enveloping a set of manifolds.
*
Expand All @@ -881,4 +932,13 @@ Manifold Manifold::Hull() const { return Hull(GetMesh().vertPos); }
Manifold Manifold::Hull(const std::vector<Manifold>& manifolds) {
return Compose(manifolds).Hull();
}

/**
* Compute the convex hull enveloping a set of manifolds.
*
* @param manifolds A vector of manifolds over which to compute a convex hull.
*/
Manifold Manifold::Hull2(const std::vector<Manifold>& manifolds) {
return Compose(manifolds).Hull2();
}
} // namespace manifold
Loading

0 comments on commit 9c72757

Please sign in to comment.