void HACD::ComputeEdgeCost(size_t e) { GraphEdge & gE = m_graph.m_edges[e]; long v1 = gE.m_v1; long v2 = gE.m_v2; if (m_graph.m_vertices[v2].m_ancestors.size()>m_graph.m_vertices[v1].m_ancestors.size()) { gE.m_v1 = v2; gE.m_v2 = v1; std::swap(v1, v2); } GraphVertex & gV1 = m_graph.m_vertices[v1]; GraphVertex & gV2 = m_graph.m_vertices[v2]; #ifdef HACD_DEBUG if (v1 == 308 && v2==276) { gV1.m_convexHull->m_mesh.Save("debug1.wrl"); gV2.m_convexHull->m_mesh.Save("debug2.wrl"); } #endif // create the edge's convex-hull ICHull * ch = new ICHull(m_heapManager); (*ch) = (*gV1.m_convexHull); // update distPoints #ifdef HACD_PRECOMPUTE_CHULLS delete gE.m_convexHull; gE.m_convexHull = 0; #endif std::map<long, DPoint> distPoints; for(size_t p = 0; p < gV1.m_distPoints.Size(); ++p) { distPoints[gV1.m_distPoints[p].m_name] = gV1.m_distPoints[p]; } std::map<long, DPoint>::iterator itDP1; for(size_t p = 0; p < gV2.m_distPoints.Size(); ++p) { const DPoint & point = gV2.m_distPoints[p]; itDP1 = distPoints.find(point.m_name); if (itDP1 == distPoints.end()) { DPoint newPoint(point.m_name, 0, false, point.m_distOnly); distPoints.insert(std::pair<long, DPoint>(point.m_name, newPoint)); if ( !point.m_distOnly ) { ch->AddPoint(m_points[point.m_name], point.m_name); } } else { if ( (itDP1->second).m_distOnly && !point.m_distOnly) { (itDP1->second).m_distOnly = false; ch->AddPoint(m_points[point.m_name], point.m_name); } } } ch->SetDistPoints(&distPoints); // create the convex-hull while (ch->Process() == ICHullErrorInconsistent) // if we face problems when constructing the visual-hull. really ugly!!!! { // if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0); ICHull * chOld = ch; ch = new ICHull(m_heapManager); CircularList<TMMVertex> & verticesCH = chOld->GetMesh().m_vertices; size_t nV = verticesCH.GetSize(); long ptIndex = 0; verticesCH.Next(); // add noise to avoid the problem ptIndex = verticesCH.GetHead()->GetData().m_name; ch->AddPoint(m_points[ptIndex]+ m_scale * 0.0001 * Vec3<Real>(rand() % 10 - 5, rand() % 10 - 5, rand() % 10 - 5), ptIndex); for(size_t v = 1; v < nV; ++v) { ptIndex = verticesCH.GetHead()->GetData().m_name; ch->AddPoint(m_points[ptIndex], ptIndex); verticesCH.Next(); } delete chOld; } #ifdef HACD_DEBUG if (v1 == 438 && v2==468) { const long nPoints = static_cast<long>(m_nPoints); std::map<long, DPoint>::iterator itDP(distPoints.begin()); std::map<long, DPoint>::iterator itDPEnd(distPoints.end()); for(; itDP != itDPEnd; ++itDP) { if (itDP->first >= nPoints) { long pt = itDP->first - nPoints; ch->AddPoint(m_extraDistPoints[pt], itDP->first); } else if (itDP->first >= 0) { long pt = itDP->first; ch->AddPoint(m_points[pt], itDP->first); } else { long pt = -itDP->first-1; ch->AddPoint(m_facePoints[pt], itDP->first); ch->AddPoint(m_facePoints[pt] + 10.0 * m_faceNormals[pt] , itDP->first); } } printf("-***->\n"); ch->m_mesh.Save("debug.wrl"); } #endif double surf = gV1.m_surf + gV2.m_surf; double concavity = 0.0; double surfCH = ch->ComputeArea() / 2.0; double volumeCH = ch->ComputeVolume(); double vol2Surf = volumeCH / surfCH; double concavity_flat = sqrt(fabs(surfCH-surf)); double weightFlat = std::max(0.0, 1.0 - pow(- vol2Surf * 100.0 / (m_scale * m_flatRegionThreshold), 2.0)); // concavity_flat *= std::max(exp(- vol2Surf * 100.0 / (m_scale * m_flatRegionThreshold)) - exp(-1.0), 0.0); concavity_flat *= weightFlat; if(!ch->IsFlat()) { concavity = Concavity(*ch, distPoints); } concavity += concavity_flat; #ifdef HACD_PRECOMPUTE_CHULLS gE.m_convexHull = ch; #else delete ch; #endif // compute boudary edges double perimeter = 0.0; if (m_alpha > 0.0) { std::set<unsigned long long> boudaryEdges1; for(size_t edV1 = 0; edV1 < gV1.m_boudaryEdges.Size(); ++edV1) { boudaryEdges1.insert(gV1.m_boudaryEdges[edV1]); } std::set<unsigned long long> boudaryEdges2; for(size_t edV2 = 0; edV2 < gV2.m_boudaryEdges.Size(); ++edV2) { boudaryEdges2.insert(gV2.m_boudaryEdges[edV2]); } std::set<unsigned long long> boudaryEdges; std::set_symmetric_difference (boudaryEdges1.begin(), boudaryEdges1.end(), boudaryEdges2.begin(), boudaryEdges2.end(), std::inserter( boudaryEdges, boudaryEdges.begin() ) ); std::set<unsigned long long>::const_iterator itBE(boudaryEdges.begin()); std::set<unsigned long long>::const_iterator itBEEnd(boudaryEdges.end()); for(; itBE != itBEEnd; ++itBE) { perimeter += (m_points[static_cast<long>((*itBE) >> 32)] - m_points[static_cast<long>((*itBE) & 0xFFFFFFFFULL)]).GetNorm(); } }
void HACD::ComputeEdgeCost(size_t e) { GraphEdge & gE = m_graph.m_edges[e]; long v1 = gE.m_v1; long v2 = gE.m_v2; if (m_graph.m_vertices[v2].m_distPoints.size()>m_graph.m_vertices[v1].m_distPoints.size()) { gE.m_v1 = v2; gE.m_v2 = v1; //std::swap<long>(v1, v2); std::swap(v1, v2); } GraphVertex & gV1 = m_graph.m_vertices[v1]; GraphVertex & gV2 = m_graph.m_vertices[v2]; // delete old convex-hull delete gE.m_convexHull; // create the edge's convex-hull ICHull * ch = new ICHull; gE.m_convexHull = ch; (*ch) = (*gV1.m_convexHull); // update distPoints gE.m_distPoints = gV1.m_distPoints; std::map<long, DPoint>::iterator itDP(gV2.m_distPoints.begin()); std::map<long, DPoint>::iterator itDPEnd(gV2.m_distPoints.end()); std::map<long, DPoint>::iterator itDP1; for(; itDP != itDPEnd; ++itDP) { itDP1 = gE.m_distPoints.find(itDP->first); if (itDP1 == gE.m_distPoints.end()) { gE.m_distPoints[itDP->first].m_distOnly = (itDP->second).m_distOnly; if ( !(itDP->second).m_distOnly ) { ch->AddPoint(m_points[itDP->first], itDP->first); } } else { if ( (itDP1->second).m_distOnly && !(itDP->second).m_distOnly) { gE.m_distPoints[itDP->first].m_distOnly = false; ch->AddPoint(m_points[itDP->first], itDP->first); } } } ch->SetDistPoints(&gE.m_distPoints); // create the convex-hull while (ch->Process() == ICHullErrorInconsistent) // if we face problems when constructing the visual-hull. really ugly!!!! { // if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0); ch = new ICHull; CircularList<TMMVertex> & verticesCH = (gE.m_convexHull)->GetMesh().m_vertices; size_t nV = verticesCH.GetSize(); long ptIndex = 0; verticesCH.Next(); for(size_t v = 1; v < nV; ++v) { ptIndex = verticesCH.GetHead()->GetData().m_name; ch->AddPoint(m_points[ptIndex], ptIndex); verticesCH.Next(); } delete gE.m_convexHull; gE.m_convexHull = ch; } double volume = 0.0; double concavity = 0.0; if (ch->IsFlat()) { bool insideHull; std::map<long, DPoint>::iterator itDP(gE.m_distPoints.begin()); std::map<long, DPoint>::iterator itDPEnd(gE.m_distPoints.end()); for(; itDP != itDPEnd; ++itDP) { if (itDP->first >= 0) { concavity = std::max<double>(concavity, ch->ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], insideHull, false)); } } } else { if (m_addNeighboursDistPoints) { // add distance points from adjacent clusters std::set<long> eEdges; std::set_union(gV1.m_edges.begin(), gV1.m_edges.end(), gV2.m_edges.begin(), gV2.m_edges.end(), std::inserter( eEdges, eEdges.begin() ) ); std::set<long>::const_iterator ed(eEdges.begin()); std::set<long>::const_iterator itEnd(eEdges.end()); long a, b, c; for(; ed != itEnd; ++ed) { a = m_graph.m_edges[*ed].m_v1; b = m_graph.m_edges[*ed].m_v2; if ( a != v2 && a != v1) { c = a; } else if ( b != v2 && b != v1) { c = b; } else { c = -1; } if ( c > 0) { GraphVertex & gVC = m_graph.m_vertices[c]; std::map<long, DPoint>::iterator itDP(gVC.m_distPoints.begin()); std::map<long, DPoint>::iterator itDPEnd(gVC.m_distPoints.end()); std::map<long, DPoint>::iterator itDP1; for(; itDP != itDPEnd; ++itDP) { itDP1 = gE.m_distPoints.find(itDP->first); if (itDP1 == gE.m_distPoints.end()) { if (itDP->first >= 0 && itDP1 == gE.m_distPoints.end() && ch->IsInside(m_points[itDP->first])) { gE.m_distPoints[itDP->first].m_distOnly = true; } else if (itDP->first < 0 && ch->IsInside(m_facePoints[-itDP->first-1])) { gE.m_distPoints[itDP->first].m_distOnly = true; } } } } } } concavity = Concavity(*ch, gE.m_distPoints); } // compute boudary edges double perimeter = 0.0; double surf = 1.0; if (m_alpha > 0.0) { gE.m_boudaryEdges.clear(); std::set_symmetric_difference (gV1.m_boudaryEdges.begin(), gV1.m_boudaryEdges.end(), gV2.m_boudaryEdges.begin(), gV2.m_boudaryEdges.end(), std::inserter( gE.m_boudaryEdges, gE.m_boudaryEdges.begin() ) ); std::set<unsigned long long>::const_iterator itBE(gE.m_boudaryEdges.begin()); std::set<unsigned long long>::const_iterator itBEEnd(gE.m_boudaryEdges.end()); for(; itBE != itBEEnd; ++itBE) { perimeter += (m_points[static_cast<long>((*itBE) >> 32)] - m_points[static_cast<long>((*itBE) & 0xFFFFFFFFULL)]).GetNorm(); } surf = gV1.m_surf + gV2.m_surf; }