diff --git a/Extras/HACD/hacdGraph.cpp b/Extras/HACD/hacdGraph.cpp index b69270e18..4b2257137 100644 --- a/Extras/HACD/hacdGraph.cpp +++ b/Extras/HACD/hacdGraph.cpp @@ -34,6 +34,7 @@ namespace HACD { m_convexHull = 0; m_name = -1; + m_cc = -1; m_error = 0; m_surf = 0; m_perimeter = 0; @@ -57,6 +58,7 @@ namespace HACD { m_nV = 0; m_nE = 0; + m_nCCs = 0; } Graph::~Graph() @@ -78,7 +80,7 @@ namespace HACD { size_t name = m_vertices.size(); m_vertices.resize(name+1); - m_vertices[name].m_name = name; + m_vertices[name].m_name = static_cast(name); m_nV++; return static_cast(name); } @@ -87,11 +89,11 @@ namespace HACD { size_t name = m_edges.size(); m_edges.push_back(GraphEdge()); - m_edges[name].m_name = name; + m_edges[name].m_name = static_cast(name); m_edges[name].m_v1 = v1; m_edges[name].m_v2 = v2; - m_vertices[v1].AddEdge(name); - m_vertices[v2].AddEdge(name); + m_vertices[v1].AddEdge(static_cast(name)); + m_vertices[v2].AddEdge(static_cast(name)); m_nE++; return static_cast(name); } @@ -236,5 +238,55 @@ namespace HACD m_nV = 0; m_nE = 0; } - + + long Graph::ExtractCCs() + { + // all CCs to -1 + for (size_t v = 0; v < m_vertices.size(); ++v) + { + if (!m_vertices[v].m_deleted) + { + m_vertices[v].m_cc = -1; + } + } + + // we get the CCs + m_nCCs = 0; + long v2 = -1; + std::vector temp; + for (size_t v = 0; v < m_vertices.size(); ++v) + { + if (!m_vertices[v].m_deleted && m_vertices[v].m_cc == -1) + { + m_vertices[v].m_cc = static_cast(m_nCCs); + temp.clear(); + temp.push_back(m_vertices[v].m_name); + while (temp.size()) + { + long vertex = temp[temp.size()-1]; + temp.pop_back(); + std::set::const_iterator ed(m_vertices[vertex].m_edges.begin()); + std::set::const_iterator itEnd(m_vertices[vertex].m_edges.end()); + for(; ed != itEnd; ++ed) + { + if (m_edges[*ed].m_v1 == vertex) + { + v2 = m_edges[*ed].m_v2; + } + else + { + v2 = m_edges[*ed].m_v1; + } + if ( !m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1) + { + m_vertices[v2].m_cc = static_cast(m_nCCs); + temp.push_back(v2); + } + } + } + m_nCCs++; + } + } + return static_cast(m_nCCs); + } } \ No newline at end of file diff --git a/Extras/HACD/hacdGraph.h b/Extras/HACD/hacdGraph.h index 56421624d..8d2d105eb 100644 --- a/Extras/HACD/hacdGraph.h +++ b/Extras/HACD/hacdGraph.h @@ -42,6 +42,7 @@ namespace HACD ~GraphVertex(){ delete m_convexHull;}; private: long m_name; + long m_cc; std::set m_edges; bool m_deleted; std::vector m_ancestors; @@ -100,12 +101,14 @@ namespace HACD long GetEdgeID(long v1, long v2) const; void Clear(); void Print() const; + long ExtractCCs(); Graph(); virtual ~Graph(); void Allocate(size_t nV, size_t nE); private: + size_t m_nCCs; size_t m_nV; size_t m_nE; std::vector m_edges; diff --git a/Extras/HACD/hacdHACD.cpp b/Extras/HACD/hacdHACD.cpp index c24e7a79c..4c17f8e1c 100644 --- a/Extras/HACD/hacdHACD.cpp +++ b/Extras/HACD/hacdHACD.cpp @@ -20,6 +20,7 @@ #include #include #include +#include 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(t)); + vertexToTriangles[m_triangles[t].Y()].insert(static_cast(t)); + vertexToTriangles[m_triangles[t].Z()].insert(static_cast(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 > 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::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end()); + for(; itV1 != itVEnd1; ++itV1) + { + double distC1C2 = std::numeric_limits::max(); + double dist; + t1 = -1; + t2 = -1; + std::set::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::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(e)); + m_pqueue.push(GraphEdgePriorityQueue(static_cast(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(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(e)); + m_pqueue.push(GraphEdgePriorityQueue(static_cast(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(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(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(p); } // compute the convex-hull const std::map & 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(m_nVerticesPerCH)); } if (exportDistPoints) { diff --git a/Extras/HACD/hacdHACD.h b/Extras/HACD/hacdHACD.h index 446719b9a..0f9166f42 100644 --- a/Extras/HACD/hacdHACD.h +++ b/Extras/HACD/hacdHACD.h @@ -65,13 +65,11 @@ namespace HACD }; inline bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs) { - if (lhs.m_priority!=rhs.m_priority) return lhs.m_priority(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs) { - if (lhs.m_priority!=rhs.m_priority) return lhs.m_priority>rhs.m_priority; - return lhs.m_name > rhs.m_name; + return lhs.m_priority>rhs.m_priority; } typedef void (*CallBackFunction)(const char *, double, double, size_t); @@ -150,6 +148,12 @@ namespace HACD //! Gives the maximum allowed concavity. //! @return maximum concavity double GetConcavity() const { return m_concavity;} + //! Sets the maximum allowed distance to get CCs connected. + //! @param concavity maximum distance to get CCs connected + void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist;} + //! Gives the maximum allowed distance to get CCs connected. + //! @return maximum distance to get CCs connected + double GetConnectDist() const { return m_ccConnectDist;} //! Sets the volume weight. //! @param beta volume weight void SetVolumeWeight(double beta) { m_beta = beta;} @@ -252,6 +256,7 @@ namespace HACD size_t m_nPoints; //>! number of vertices in the original mesh size_t m_nClusters; //>! number of clusters size_t m_nMinClusters; //>! minimum number of clusters + double m_ccConnectDist; //>! maximum allowed distance to connect CCs double m_concavity; //>! maximum concavity double m_alpha; //>! compacity weigth double m_beta; //>! volume weigth diff --git a/Extras/HACD/hacdICHull.cpp b/Extras/HACD/hacdICHull.cpp index 1df733673..069581750 100644 --- a/Extras/HACD/hacdICHull.cpp +++ b/Extras/HACD/hacdICHull.cpp @@ -16,7 +16,7 @@ #include namespace HACD { - const long ICHull::sc_dummyIndex = static_cast(-1); + const long ICHull::sc_dummyIndex = std::numeric_limits::max(); ICHull::ICHull(void) { m_distPoints = 0; @@ -36,7 +36,7 @@ namespace HACD vertex->GetData().m_pos.X() = points[i].X(); vertex->GetData().m_pos.Y() = points[i].Y(); vertex->GetData().m_pos.Z() = points[i].Z(); - vertex->GetData().m_name = i; + vertex->GetData().m_name = static_cast(i); } return true; } @@ -788,7 +788,7 @@ namespace HACD bary.Z() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Z(); m_mesh.m_vertices.Next(); } - bary /= nV; + bary /= static_cast(nV); size_t nT = m_mesh.m_triangles.GetSize(); Vec3 ver0, ver1, ver2; diff --git a/Extras/HACD/hacdManifoldMesh.cpp b/Extras/HACD/hacdManifoldMesh.cpp index e3bb55c0c..a92e9fc3e 100644 --- a/Extras/HACD/hacdManifoldMesh.cpp +++ b/Extras/HACD/hacdManifoldMesh.cpp @@ -231,9 +231,9 @@ namespace HACD for(size_t f = 0; f < nT; f++) { TMMTriangle & currentTriangle = m_triangles.GetData(); - triangles[f].X() = currentTriangle.m_vertices[0]->GetData().m_id; - triangles[f].Y() = currentTriangle.m_vertices[1]->GetData().m_id; - triangles[f].Z() = currentTriangle.m_vertices[2]->GetData().m_id; + triangles[f].X() = static_cast(currentTriangle.m_vertices[0]->GetData().m_id); + triangles[f].Y() = static_cast(currentTriangle.m_vertices[1]->GetData().m_id); + triangles[f].Z() = static_cast(currentTriangle.m_vertices[2]->GetData().m_id); m_triangles.Next(); } } @@ -373,7 +373,7 @@ namespace HACD Vec3 s0 = (I-V0) ^ edge3; Vec3 s1 = (I-V1) ^ edge1; Vec3 s2 = (I-V2) ^ edge2; - if (s0*s1 >= 0.0 && s2*s1 >= 0.0) + if (s0*s1 > -1e-9 && s2*s1 > -1e-9) { return 1; } diff --git a/Extras/HACD/hacdVector.h b/Extras/HACD/hacdVector.h index 4f4d3ed79..cb142827d 100644 --- a/Extras/HACD/hacdVector.h +++ b/Extras/HACD/hacdVector.h @@ -21,7 +21,7 @@ namespace HACD { - typedef float Real; + typedef double Real; //! Vector dim 3. template < typename T > class Vec3 {