update to the latest version of HACD (hierarchical approximate convex decomposition, http://sourceforge.net/projects/hacd)

Thanks to Khaled Mammou for the fix.
This commit is contained in:
erwin.coumans
2011-07-24 02:01:32 +00:00
parent c7b8035556
commit cf0d948d97
7 changed files with 165 additions and 44 deletions

View File

@@ -20,6 +20,7 @@
#include <string.h>
#include <algorithm>
#include <iterator>
#include <limits>
namespace HACD
{
@@ -61,13 +62,13 @@ namespace HACD
vertexToTriangles.resize(m_nPoints);
for(size_t t = 0; t < m_nTriangles; ++t)
{
vertexToTriangles[m_triangles[t].X()].insert(t);
vertexToTriangles[m_triangles[t].Y()].insert(t);
vertexToTriangles[m_triangles[t].Z()].insert(t);
vertexToTriangles[m_triangles[t].X()].insert(static_cast<long>(t));
vertexToTriangles[m_triangles[t].Y()].insert(static_cast<long>(t));
vertexToTriangles[m_triangles[t].Z()].insert(static_cast<long>(t));
}
m_graph.Clear();
m_graph.Allocate(m_nTriangles, 3 * m_nTriangles);
m_graph.Allocate(m_nTriangles, 5 * m_nTriangles);
unsigned long long tr1[3];
unsigned long long tr2[3];
long i1, j1, k1, i2, j2, k2;
@@ -112,6 +113,65 @@ namespace HACD
}
}
}
if (m_ccConnectDist >= 0.0)
{
m_graph.ExtractCCs();
if (m_graph.m_nCCs > 1)
{
std::vector< std::set<long> > cc2V;
cc2V.resize(m_graph.m_nCCs);
long cc;
for(size_t t = 0; t < m_nTriangles; ++t)
{
cc = m_graph.m_vertices[t].m_cc;
cc2V[cc].insert(m_triangles[t].X());
cc2V[cc].insert(m_triangles[t].Y());
cc2V[cc].insert(m_triangles[t].Z());
}
for(size_t cc1 = 0; cc1 < m_graph.m_nCCs; ++cc1)
{
for(size_t cc2 = cc1+1; cc2 < m_graph.m_nCCs; ++cc2)
{
std::set<long>::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end());
for(; itV1 != itVEnd1; ++itV1)
{
double distC1C2 = std::numeric_limits<double>::max();
double dist;
t1 = -1;
t2 = -1;
std::set<long>::const_iterator itV2(cc2V[cc2].begin()), itVEnd2(cc2V[cc2].end());
for(; itV2 != itVEnd2; ++itV2)
{
dist = (m_points[*itV1] - m_points[*itV2]).GetNorm();
if (dist < distC1C2)
{
distC1C2 = dist;
t1 = *vertexToTriangles[*itV1].begin();
std::set<long>::const_iterator it2(vertexToTriangles[*itV2].begin()),
it2End(vertexToTriangles[*itV2].end());
t2 = -1;
for(; it2 != it2End; ++it2)
{
if (*it2 != t1)
{
t2 = *it2;
break;
}
}
}
}
if (distC1C2 < m_ccConnectDist && t1 > 0 && t2 > 0)
{
m_graph.AddEdge(t1, t2);
}
}
}
}
}
}
}
void HACD::InitializeDualGraph()
{
@@ -294,6 +354,7 @@ namespace HACD
m_nMinClusters = 3;
m_facePoints = 0;
m_faceNormals = 0;
m_ccConnectDist = 30;
}
HACD::~HACD(void)
{
@@ -479,8 +540,8 @@ namespace HACD
m_pqueue.reserve(m_graph.m_nE + 100);
for (size_t e=0; e < m_graph.m_nE; ++e)
{
ComputeEdgeCost(e);
m_pqueue.push(GraphEdgePriorityQueue(e, m_graph.m_edges[e].m_error));
ComputeEdgeCost(static_cast<long>(e));
m_pqueue.push(GraphEdgePriorityQueue(static_cast<long>(e), m_graph.m_edges[e].m_error));
}
return true;
}
@@ -495,7 +556,7 @@ namespace HACD
double ptgStep = 1.0;
while ( (globalConcavity < m_concavity) &&
(m_graph.GetNVertices() > m_nMinClusters) &&
(m_graph.GetNEdges()> 1))
(m_graph.GetNEdges() > 0))
{
progress = 100.0-m_graph.GetNVertices() * 100.0 / m_nTriangles;
if (fabs(progress-progressOld) > ptgStep && m_callBack)
@@ -520,18 +581,16 @@ namespace HACD
done = false;
if (m_pqueue.size() == 0)
{
done = true;
break;
}
else
{
currentEdge = m_pqueue.top();
m_pqueue.pop();
done = true;
break;
}
currentEdge = m_pqueue.top();
m_pqueue.pop();
}
while ( m_graph.m_edges[currentEdge.m_name].m_deleted ||
m_graph.m_edges[currentEdge.m_name].m_error != currentEdge.m_priority);
if (m_graph.m_edges[currentEdge.m_name].m_concavity < m_concavity && !done)
{
globalConcavity = std::max<double>(globalConcavity ,m_graph.m_edges[currentEdge.m_name].m_concavity);
@@ -557,8 +616,8 @@ namespace HACD
for(; itE != itEEnd; ++itE)
{
size_t e = *itE;
ComputeEdgeCost(e);
m_pqueue.push(GraphEdgePriorityQueue(e, m_graph.m_edges[e].m_error));
ComputeEdgeCost(static_cast<long>(e));
m_pqueue.push(GraphEdgePriorityQueue(static_cast<long>(e), m_graph.m_edges[e].m_error));
}
}
else
@@ -570,10 +629,10 @@ namespace HACD
{
m_pqueue.pop();
}
m_cVertices.clear();
m_cVertices.reserve(m_nClusters);
m_nClusters = m_graph.GetNVertices();
m_cVertices.reserve(m_nClusters);
for (size_t p=0, v = 0; v != m_graph.m_vertices.size(); ++v)
{
if (!m_graph.m_vertices[v].m_deleted)
@@ -585,7 +644,7 @@ namespace HACD
(*m_callBack)(msg, 0.0, 0.0, m_nClusters);
p++;
}
m_cVertices.push_back(v);
m_cVertices.push_back(static_cast<long>(v));
}
}
if (m_callBack)
@@ -595,6 +654,7 @@ namespace HACD
}
}
bool HACD::Compute(bool fullCH, bool exportDistPoints)
{
if ( !m_points || !m_triangles || !m_nPoints || !m_nTriangles)
@@ -614,11 +674,12 @@ namespace HACD
msg << "\t compacity weigth \t" << m_alpha << std::endl;
msg << "\t volume weigth \t" << m_beta << std::endl;
msg << "\t # vertices per convex-hull \t" << m_nVerticesPerCH << std::endl;
msg << "\t Scale \t" << m_scale << std::endl;
msg << "\t Add extra distance points \t" << m_addExtraDistPoints << std::endl;
msg << "\t Add neighbours distance points \t" << m_addNeighboursDistPoints << std::endl;
msg << "\t Add face distance points \t" << m_addFacesPoints << std::endl;
msg << "\t Produce full convex-hulls \t" << fullCH << std::endl;
msg << "\t scale \t" << m_scale << std::endl;
msg << "\t add extra distance points \t" << m_addExtraDistPoints << std::endl;
msg << "\t add neighbours distance points \t" << m_addNeighboursDistPoints << std::endl;
msg << "\t add face distance points \t" << m_addFacesPoints << std::endl;
msg << "\t produce full convex-hulls \t" << fullCH << std::endl;
msg << "\t max. distance to connect CCs \t" << m_ccConnectDist << std::endl;
(*m_callBack)(msg.str().c_str(), 0.0, 0.0, nV);
}
if (m_callBack) (*m_callBack)("+ Normalizing Data\n", 0.0, 0.0, nV);
@@ -643,10 +704,10 @@ namespace HACD
for (size_t p = 0; p != m_cVertices.size(); ++p)
{
size_t v = m_cVertices[p];
m_partition[v] = p;
m_partition[v] = static_cast<long>(p);
for(size_t a = 0; a < m_graph.m_vertices[v].m_ancestors.size(); a++)
{
m_partition[m_graph.m_vertices[v].m_ancestors[a]] = p;
m_partition[m_graph.m_vertices[v].m_ancestors[a]] = static_cast<long>(p);
}
// compute the convex-hull
const std::map<long, DPoint> & pointsCH = m_graph.m_vertices[v].m_distPoints;
@@ -666,7 +727,7 @@ namespace HACD
}
else
{
m_convexHulls[p].Process(m_nVerticesPerCH);
m_convexHulls[p].Process(static_cast<unsigned long>(m_nVerticesPerCH));
}
if (exportDistPoints)
{