From 121d356fbf03ba313d5e856ad74234b582dfdde2 Mon Sep 17 00:00:00 2001 From: cignoni Date: Thu, 9 Jun 2016 10:46:10 +0000 Subject: [PATCH] Cleaning up sample prog --- apps/sample/common.pri | 4 +- .../polygonmesh_zonohedra.cpp | 2 +- .../test_hash2d.cpp | 0 .../test_hash2d.pro | 0 .../trimesh_indexing/trimesh_indexing.cpp | 809 +++++++++--------- 5 files changed, 412 insertions(+), 403 deletions(-) rename apps/sample/{hashing_2D => space_index_2d}/test_hash2d.cpp (100%) rename apps/sample/{hashing_2D => space_index_2d}/test_hash2d.pro (100%) diff --git a/apps/sample/common.pri b/apps/sample/common.pri index 85c604b2..e908b112 100644 --- a/apps/sample/common.pri +++ b/apps/sample/common.pri @@ -1,6 +1,8 @@ DEPENDPATH += . ../../.. INCLUDEPATH += . ../../.. -CONFIG += console stl +CONFIG += console c++11 TEMPLATE = app # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle + +QMAKE_CXXFLAGS += -std=c++11 diff --git a/apps/sample/polygonmesh_zonohedra/polygonmesh_zonohedra.cpp b/apps/sample/polygonmesh_zonohedra/polygonmesh_zonohedra.cpp index 95246680..ea341378 100644 --- a/apps/sample/polygonmesh_zonohedra/polygonmesh_zonohedra.cpp +++ b/apps/sample/polygonmesh_zonohedra/polygonmesh_zonohedra.cpp @@ -98,7 +98,7 @@ void example2(){ // normally, faces with more than 4sides are split into parallelograms // this merges them (optional, try removing it!) - vcg::tri::PolygonSupport::MergeFlatFaces(m); + vcg::tri::PolygonSupport::MergeFlatFaces(m); int savemask = vcg::tri::io::Mask::IOM_BITPOLYGONAL; vcg::tri::io::ExporterOFF::Save(m,fullMeshFilename,savemask); diff --git a/apps/sample/hashing_2D/test_hash2d.cpp b/apps/sample/space_index_2d/test_hash2d.cpp similarity index 100% rename from apps/sample/hashing_2D/test_hash2d.cpp rename to apps/sample/space_index_2d/test_hash2d.cpp diff --git a/apps/sample/hashing_2D/test_hash2d.pro b/apps/sample/space_index_2d/test_hash2d.pro similarity index 100% rename from apps/sample/hashing_2D/test_hash2d.pro rename to apps/sample/space_index_2d/test_hash2d.pro diff --git a/apps/sample/trimesh_indexing/trimesh_indexing.cpp b/apps/sample/trimesh_indexing/trimesh_indexing.cpp index 8bbf6465..1cbffbac 100644 --- a/apps/sample/trimesh_indexing/trimesh_indexing.cpp +++ b/apps/sample/trimesh_indexing/trimesh_indexing.cpp @@ -1,11 +1,13 @@ #include #include +#ifdef _OPENMP #include +#endif #include "nanoflann.hpp" -#include - +#include + #include #include @@ -22,415 +24,420 @@ float queryDist = 0.0037; float ratio = 1000.0f; -class CVertex; -class CFace; -class CEdge; - -class CUsedTypes : public vcg::UsedTypes < vcg::Use< CVertex >::AsVertexType, vcg::Use< CFace >::AsFaceType>{}; -class CVertex : public vcg::Vertex < CUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::Radiusf, vcg::vertex::BitFlags, vcg::vertex::Qualityf, vcg::vertex::Color4b>{}; -class CFace : public vcg::Face < CUsedTypes, vcg::face::VertexRef>{}; - +class CVertex; +class CFace; +class CEdge; + +class CUsedTypes : public vcg::UsedTypes < vcg::Use< CVertex >::AsVertexType, vcg::Use< CFace >::AsFaceType>{}; +class CVertex : public vcg::Vertex < CUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::Radiusf, vcg::vertex::BitFlags, vcg::vertex::Qualityf, vcg::vertex::Color4b>{}; +class CFace : public vcg::Face < CUsedTypes, vcg::face::VertexRef>{}; + class CMesh : public vcg::tri::TriMesh < std::vector< CVertex >, std::vector< CFace > > {}; -template -struct PointCloud -{ - struct Point - { - T x,y,z; - }; - - std::vector pts; - - inline size_t kdtree_get_point_count() const { return pts.size(); } - - inline T kdtree_distance(const T *p1, const size_t idx_p2,size_t size) const - { - const T d0=p1[0]-pts[idx_p2].x; - const T d1=p1[1]-pts[idx_p2].y; - const T d2=p1[2]-pts[idx_p2].z; - return d0*d0+d1*d1+d2*d2; - } - - inline T kdtree_get_pt(const size_t idx, int dim) const - { - if (dim==0) return pts[idx].x; - else if (dim==1) return pts[idx].y; - else return pts[idx].z; - } - - template - bool kdtree_get_bbox(BBOX &bb) const { return false; } - -}; - - -void testKDTree(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) -{ - std::cout << "==================================================="<< std::endl; - std::cout << "KDTree" << std::endl; - QTime time; - time.start(); - - // Construction of the kdTree - vcg::ConstDataWrapper wrapperVcg(&mesh.vert[0].P(), mesh.vert.size(), size_t(mesh.vert[1].P().V()) - size_t(mesh.vert[0].P().V())); - vcg::KdTree kdTreeVcg(wrapperVcg); - std::cout << "Build: " << time.elapsed() << " ms" << std::endl; - - // Computation of the point radius - float mAveragePointSpacing = 0; - time.restart(); - #pragma omp parallel for reduction(+: mAveragePointSpacing) schedule(dynamic, 10) - for (int i = 0; i < mesh.vert.size(); i++) - { - vcg::KdTree::PriorityQueue queue; - kdTreeVcg.doQueryK(mesh.vert[i].cP(), 16, queue); - float newRadius = 2.0f * sqrt(queue.getWeight(0)/ queue.getNofElements()); - mesh.vert[i].R() -= newRadius; - mAveragePointSpacing += newRadius; - } - mAveragePointSpacing /= mesh.vert.size(); - std::cout << "Average point radius (OpenMP) " << mAveragePointSpacing << std::endl; - std::cout << "Time (OpenMP): " << time.elapsed() << " ms" << std::endl; - - queryDist = mAveragePointSpacing * 150; - - // Test with the radius search - std::cout << "Radius search (" << num_test << " tests)"<< std::endl; - float avgTime = 0.0f; - for (int ii = 0; ii < num_test; ii++) - { - time.restart(); - std::vector indeces; - std::vector dists; - kdTreeVcg.doQueryDist(mesh.vert[test_indeces[ii]].cP(), queryDist, indeces, dists); - avgTime += time.elapsed(); - } - std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; - - // Test with the k-nearest search - std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - vcg::KdTree::PriorityQueue queue; - kdTreeVcg.doQueryK(mesh.vert[test_indeces[ii]].cP(), kNearest, queue); - avgTime += time.elapsed(); - } - std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; - - // Test with the closest search - std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - unsigned int index; - float minDist; - kdTreeVcg.doQueryClosest(randomSamples[ii], index, minDist); - avgTime += time.elapsed(); - } - std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; -} - - -void testNanoFLANN(CMesh& mesh, std::vector& test_indeces, std::vector randomSamples) -{ - std::cout << "==================================================="<< std::endl; - std::cout << "nanoFLANN" << std::endl; - - PointCloud cloud; - cloud.pts.resize(mesh.vert.size()); - for (size_t i=0; i < mesh.vert.size(); i++) - { - cloud.pts[i].x = mesh.vert[i].P().X(); - cloud.pts[i].y = mesh.vert[i].P().Y(); - cloud.pts[i].z = mesh.vert[i].P().Z(); - } - - typedef nanoflann::KDTreeSingleIndexAdaptor< - nanoflann::L2_Simple_Adaptor > , - PointCloud, - 3 /* dim */ - > my_kd_tree_t; - - // Construction of the nanoFLANN KDtree - QTime time; - time.start(); - my_kd_tree_t index(3, cloud, nanoflann::KDTreeSingleIndexAdaptorParams(16) ); - index.buildIndex(); - std::cout << "Build nanoFlann: " << time.elapsed() << " ms" << std::endl; - - // Test with the radius search - std::cout << "Radius search (" << num_test << " tests)"<< std::endl; - float avgTime = 0.0f; - std::vector > ret_matches; - nanoflann::SearchParams params; - for (int ii = 0; ii < num_test; ii++) - { - time.restart(); - const size_t nMatches = index.radiusSearch(mesh.vert[test_indeces[ii]].P().V(), queryDist, ret_matches, params); - avgTime += time.elapsed(); - } - std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; - - // Test with the k-nearest search - std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - std::vector ret_index(kNearest); - std::vector out_dist_sqr(kNearest); - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - index.knnSearch(mesh.vert[test_indeces[ii]].P().V(), kNearest, &ret_index[0], &out_dist_sqr[0]); - avgTime += time.elapsed(); - } - std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; - - // Test with the closest search - std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - std::vector ret_index_clos(1); - std::vector out_dist_sqr_clos(1); - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - index.knnSearch(randomSamples[ii].V(), 1, &ret_index_clos[0], &out_dist_sqr_clos[0]); - avgTime += time.elapsed(); - } - std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; -} - - -void testUniformGrid(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) -{ - std::cout << "==================================================="<< std::endl; - std::cout << "Uniform Grid" << std::endl; - QTime time; - time.start(); - - // Construction of the uniform grid - typedef vcg::GridStaticPtr MeshGrid; - MeshGrid uniformGrid; - uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); - std::cout << "Build: " << time.elapsed() << " ms" << std::endl; - - // Test with the radius search - std::cout << "Radius search (" << num_test << " tests)"<< std::endl; - float avgTime = 0.0f; - for (int ii = 0; ii < num_test; ii++) - { - time.restart(); - std::vector vertexPtr; - std::vector points; - std::vector dists; - vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); - avgTime += time.elapsed(); - } - std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; - - // Test with the k-nearest search - std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - std::vector vertexPtr; - std::vector points; - std::vector dists; - vcg::tri::GetKClosestVertex(mesh, uniformGrid, kNearest, mesh.vert[test_indeces[ii]].cP(), mesh.bbox.Diag(), vertexPtr, dists, points); - avgTime += time.elapsed(); - } - std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; - - // Test with the Closest search - std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - float minDist; - vcg::tri::GetClosestVertex(mesh, uniformGrid, randomSamples[ii], mesh.bbox.Diag(), minDist); - avgTime += time.elapsed(); - } - std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; -} - - - -void testSpatialHashing(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) -{ - std::cout << "==================================================="<< std::endl; - std::cout << "Spatial Hashing" << std::endl; - QTime time; - time.start(); - - // Construction of the uniform grid - typedef vcg::SpatialHashTable MeshGrid; - MeshGrid uniformGrid; - uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); - std::cout << "Build: " << time.elapsed() << " ms" << std::endl; - - // Test with the radius search - std::cout << "Radius search (" << num_test << " tests)"<< std::endl; - float avgTime = 0.0f; - for (int ii = 0; ii < num_test; ii++) - { - time.restart(); - std::vector vertexPtr; - std::vector points; - std::vector dists; - vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); - avgTime += time.elapsed(); - } - std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; - - // Test with the k-nearest search - std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - std::vector vertexPtr; - std::vector points; - std::vector dists; - vcg::tri::GetKClosestVertex(mesh, uniformGrid, kNearest, mesh.vert[test_indeces[ii]].cP(), mesh.bbox.Diag(), vertexPtr, dists, points); - avgTime += time.elapsed(); - } - std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; - - // Test with the Closest search - std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - float minDist; - vcg::tri::GetClosestVertex(mesh, uniformGrid, randomSamples[ii], mesh.bbox.Diag(), minDist); - avgTime += time.elapsed(); - } - std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; -} - - - -void testPerfectSpatialHashing(CMesh& mesh, std::vector& test_indeces) -{ - std::cout << "==================================================="<< std::endl; - std::cout << "Perfect Spatial Hashing" << std::endl; - QTime time; - time.start(); - - // Construction of the uniform grid - typedef vcg::SpatialHashTable MeshGrid; - MeshGrid uniformGrid; - uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); - std::cout << "Build: " << time.elapsed() << " ms" << std::endl; - - // Test with the radius search - std::cout << "Radius search (" << num_test << " tests)"<< std::endl; - float avgTime = 0.0f; - for (int ii = 0; ii < num_test; ii++) - { - time.restart(); - std::vector vertexPtr; - std::vector points; - std::vector dists; - vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); - avgTime += time.elapsed(); - } - std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl << std::endl; -} - - -void testOctree(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) -{ - std::cout << "==================================================="<< std::endl; - std::cout << "Octree" << std::endl; - QTime time; - time.start(); - - // Construction of the uniform grid - typedef vcg::Octree MeshGrid; - MeshGrid uniformGrid; - uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); - std::cout << "Build: " << time.elapsed() << " ms" << std::endl; - - // Test with the radius search - std::cout << "Radius search (" << num_test << " tests)"<< std::endl; - float avgTime = 0.0f; - for (int ii = 0; ii < num_test; ii++) - { - time.restart(); - std::vector vertexPtr; - std::vector points; - std::vector dists; - vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); - avgTime += time.elapsed(); - } - std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; - - // Test with the k-nearest search - std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - std::vector vertexPtr; - std::vector points; - std::vector dists; - vcg::tri::GetKClosestVertex(mesh, uniformGrid, kNearest, mesh.vert[test_indeces[ii]].cP(), mesh.bbox.Diag(), vertexPtr, dists, points); - avgTime += time.elapsed(); - } - std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; - - // Test with the Closest search - std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; - avgTime = 0.0f; - for (int ii = 0; ii < num_test * 10; ii++) - { - time.restart(); - float minDist; - vcg::tri::GetClosestVertex(mesh, uniformGrid, randomSamples[ii], mesh.bbox.Diag(), minDist); - avgTime += time.elapsed(); - } - std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; -} +template +struct PointCloud +{ + struct Point + { + T x,y,z; + }; + + std::vector pts; + + inline size_t kdtree_get_point_count() const { return pts.size(); } + + inline T kdtree_distance(const T *p1, const size_t idx_p2,size_t size) const + { + const T d0=p1[0]-pts[idx_p2].x; + const T d1=p1[1]-pts[idx_p2].y; + const T d2=p1[2]-pts[idx_p2].z; + return d0*d0+d1*d1+d2*d2; + } + + inline T kdtree_get_pt(const size_t idx, int dim) const + { + if (dim==0) return pts[idx].x; + else if (dim==1) return pts[idx].y; + else return pts[idx].z; + } + + template + bool kdtree_get_bbox(BBOX &bb) const { return false; } + +}; + + +void testKDTree(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) +{ + std::cout << "==================================================="<< std::endl; + std::cout << "KDTree" << std::endl; + QTime time; + time.start(); + + // Construction of the kdTree + vcg::ConstDataWrapper wrapperVcg(&mesh.vert[0].P(), mesh.vert.size(), size_t(mesh.vert[1].P().V()) - size_t(mesh.vert[0].P().V())); + vcg::KdTree kdTreeVcg(wrapperVcg); + std::cout << "Build: " << time.elapsed() << " ms" << std::endl; + int nn=1; + // Computation of the point radius + float mAveragePointSpacing = 0; + time.restart(); + #pragma omp parallel for reduction(+: mAveragePointSpacing) schedule(dynamic, 10) + for (int i = 0; i < mesh.vert.size(); i++) + { +#ifdef #ifdef _OPENMP + nn =omp_get_num_threads(); +#endif + vcg::KdTree::PriorityQueue queue; + kdTreeVcg.doQueryK(mesh.vert[i].cP(), 16, queue); + float newRadius = 2.0f * sqrt(queue.getWeight(0)/ queue.getNofElements()); + mesh.vert[i].R() -= newRadius; + mAveragePointSpacing += newRadius; + } + std::cout << "Num trhread " << nn << std::endl; + mAveragePointSpacing /= mesh.vert.size(); + std::cout << "Average point radius (OpenMP with" << nn << " threads) " << mAveragePointSpacing << std::endl; + std::cout << "Time (OpenMP): " << time.elapsed() << " ms" << std::endl; + + queryDist = mAveragePointSpacing * 150; + + // Test with the radius search + std::cout << "Radius search (" << num_test << " tests)"<< std::endl; + float avgTime = 0.0f; + for (int ii = 0; ii < num_test; ii++) + { + time.restart(); + std::vector indeces; + std::vector dists; + kdTreeVcg.doQueryDist(mesh.vert[test_indeces[ii]].cP(), queryDist, indeces, dists); + avgTime += time.elapsed(); + } + std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; + + // Test with the k-nearest search + std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + vcg::KdTree::PriorityQueue queue; + kdTreeVcg.doQueryK(mesh.vert[test_indeces[ii]].cP(), kNearest, queue); + avgTime += time.elapsed(); + } + std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; + + // Test with the closest search + std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + unsigned int index; + float minDist; + kdTreeVcg.doQueryClosest(randomSamples[ii], index, minDist); + avgTime += time.elapsed(); + } + std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; +} + + +void testNanoFLANN(CMesh& mesh, std::vector& test_indeces, std::vector randomSamples) +{ + std::cout << "==================================================="<< std::endl; + std::cout << "nanoFLANN" << std::endl; + + PointCloud cloud; + cloud.pts.resize(mesh.vert.size()); + for (size_t i=0; i < mesh.vert.size(); i++) + { + cloud.pts[i].x = mesh.vert[i].P().X(); + cloud.pts[i].y = mesh.vert[i].P().Y(); + cloud.pts[i].z = mesh.vert[i].P().Z(); + } + + typedef nanoflann::KDTreeSingleIndexAdaptor< + nanoflann::L2_Simple_Adaptor > , + PointCloud, + 3 /* dim */ + > my_kd_tree_t; + + // Construction of the nanoFLANN KDtree + QTime time; + time.start(); + my_kd_tree_t index(3, cloud, nanoflann::KDTreeSingleIndexAdaptorParams(16) ); + index.buildIndex(); + std::cout << "Build nanoFlann: " << time.elapsed() << " ms" << std::endl; + + // Test with the radius search + std::cout << "Radius search (" << num_test << " tests)"<< std::endl; + float avgTime = 0.0f; + std::vector > ret_matches; + nanoflann::SearchParams params; + for (int ii = 0; ii < num_test; ii++) + { + time.restart(); + const size_t nMatches = index.radiusSearch(mesh.vert[test_indeces[ii]].P().V(), queryDist, ret_matches, params); + avgTime += time.elapsed(); + } + std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; + + // Test with the k-nearest search + std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + std::vector ret_index(kNearest); + std::vector out_dist_sqr(kNearest); + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + index.knnSearch(mesh.vert[test_indeces[ii]].P().V(), kNearest, &ret_index[0], &out_dist_sqr[0]); + avgTime += time.elapsed(); + } + std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; + + // Test with the closest search + std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + std::vector ret_index_clos(1); + std::vector out_dist_sqr_clos(1); + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + index.knnSearch(randomSamples[ii].V(), 1, &ret_index_clos[0], &out_dist_sqr_clos[0]); + avgTime += time.elapsed(); + } + std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; +} + + +void testUniformGrid(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) +{ + std::cout << "==================================================="<< std::endl; + std::cout << "Uniform Grid" << std::endl; + QTime time; + time.start(); + + // Construction of the uniform grid + typedef vcg::GridStaticPtr MeshGrid; + MeshGrid uniformGrid; + uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); + std::cout << "Build: " << time.elapsed() << " ms" << std::endl; + + // Test with the radius search + std::cout << "Radius search (" << num_test << " tests)"<< std::endl; + float avgTime = 0.0f; + for (int ii = 0; ii < num_test; ii++) + { + time.restart(); + std::vector vertexPtr; + std::vector points; + std::vector dists; + vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); + avgTime += time.elapsed(); + } + std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; + + // Test with the k-nearest search + std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + std::vector vertexPtr; + std::vector points; + std::vector dists; + vcg::tri::GetKClosestVertex(mesh, uniformGrid, kNearest, mesh.vert[test_indeces[ii]].cP(), mesh.bbox.Diag(), vertexPtr, dists, points); + avgTime += time.elapsed(); + } + std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; + + // Test with the Closest search + std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + float minDist; + vcg::tri::GetClosestVertex(mesh, uniformGrid, randomSamples[ii], mesh.bbox.Diag(), minDist); + avgTime += time.elapsed(); + } + std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; +} + + + +void testSpatialHashing(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) +{ + std::cout << "==================================================="<< std::endl; + std::cout << "Spatial Hashing" << std::endl; + QTime time; + time.start(); + + // Construction of the uniform grid + typedef vcg::SpatialHashTable MeshGrid; + MeshGrid uniformGrid; + uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); + std::cout << "Build: " << time.elapsed() << " ms" << std::endl; + + // Test with the radius search + std::cout << "Radius search (" << num_test << " tests)"<< std::endl; + float avgTime = 0.0f; + for (int ii = 0; ii < num_test; ii++) + { + time.restart(); + std::vector vertexPtr; + std::vector points; + std::vector dists; + vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); + avgTime += time.elapsed(); + } + std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; + + // Test with the k-nearest search + std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + std::vector vertexPtr; + std::vector points; + std::vector dists; + vcg::tri::GetKClosestVertex(mesh, uniformGrid, kNearest, mesh.vert[test_indeces[ii]].cP(), mesh.bbox.Diag(), vertexPtr, dists, points); + avgTime += time.elapsed(); + } + std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; + + // Test with the Closest search + std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + float minDist; + vcg::tri::GetClosestVertex(mesh, uniformGrid, randomSamples[ii], mesh.bbox.Diag(), minDist); + avgTime += time.elapsed(); + } + std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; +} + + + +void testPerfectSpatialHashing(CMesh& mesh, std::vector& test_indeces) +{ + std::cout << "==================================================="<< std::endl; + std::cout << "Perfect Spatial Hashing" << std::endl; + QTime time; + time.start(); + + // Construction of the uniform grid + typedef vcg::SpatialHashTable MeshGrid; + MeshGrid uniformGrid; + uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); + std::cout << "Build: " << time.elapsed() << " ms" << std::endl; + + // Test with the radius search + std::cout << "Radius search (" << num_test << " tests)"<< std::endl; + float avgTime = 0.0f; + for (int ii = 0; ii < num_test; ii++) + { + time.restart(); + std::vector vertexPtr; + std::vector points; + std::vector dists; + vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); + avgTime += time.elapsed(); + } + std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl << std::endl; +} + + +void testOctree(CMesh& mesh, std::vector& test_indeces, std::vector& randomSamples) +{ + std::cout << "==================================================="<< std::endl; + std::cout << "Octree" << std::endl; + QTime time; + time.start(); + + // Construction of the uniform grid + typedef vcg::Octree MeshGrid; + MeshGrid uniformGrid; + uniformGrid.Set(mesh.vert.begin(), mesh.vert.end()); + std::cout << "Build: " << time.elapsed() << " ms" << std::endl; + + // Test with the radius search + std::cout << "Radius search (" << num_test << " tests)"<< std::endl; + float avgTime = 0.0f; + for (int ii = 0; ii < num_test; ii++) + { + time.restart(); + std::vector vertexPtr; + std::vector points; + std::vector dists; + vcg::tri::GetInSphereVertex(mesh, uniformGrid, mesh.vert[test_indeces[ii]].cP(), queryDist, vertexPtr, dists, points); + avgTime += time.elapsed(); + } + std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)" << std::endl; + + // Test with the k-nearest search + std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + std::vector vertexPtr; + std::vector points; + std::vector dists; + vcg::tri::GetKClosestVertex(mesh, uniformGrid, kNearest, mesh.vert[test_indeces[ii]].cP(), mesh.bbox.Diag(), vertexPtr, dists, points); + avgTime += time.elapsed(); + } + std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl; + + // Test with the Closest search + std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl; + avgTime = 0.0f; + for (int ii = 0; ii < num_test * 10; ii++) + { + time.restart(); + float minDist; + vcg::tri::GetClosestVertex(mesh, uniformGrid, randomSamples[ii], mesh.bbox.Diag(), minDist); + avgTime += time.elapsed(); + } + std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)" << std::endl << std::endl; +} int main( int argc, char * argv[] ) { - if (argc < 2) - std::cout << "Invalid arguments" << std::endl; + if (argc < 2) { + std::cout << "Invalid arguments" << std::endl; + exit(-1); + } + CMesh mesh; + if (vcg::tri::io::Importer::Open(mesh, argv[1]) != 0) + std::cout << "Invalid filename" << std::endl; - CMesh mesh; - if (vcg::tri::io::Importer::Open(mesh, argv[1]) != 0) - std::cout << "Invalid filename" << std::endl; + std::cout << "Mesh BBox diagonal: " << mesh.bbox.Diag() << std::endl; + std::cout << "Max point random offset: " << mesh.bbox.Diag() / 1000.0f << std::endl << std::endl; - std::cout << "Mesh BBox diagonal: " << mesh.bbox.Diag() << std::endl; - std::cout << "Max point random offset: " << mesh.bbox.Diag() / 1000.0f << std::endl << std::endl; + vcg::math::MarsenneTwisterRNG randGen; + randGen.initialize(0); + std::vector randomSamples; + for (int i = 0; i < num_test * 10; i++) + randomSamples.push_back(vcg::math::GeneratePointOnUnitSphereUniform(randGen) * randGen.generate01() * mesh.bbox.Diag() / ratio); - vcg::math::MarsenneTwisterRNG randGen; - randGen.initialize(0); - std::vector randomSamples; - for (int i = 0; i < num_test * 10; i++) - randomSamples.push_back(vcg::math::GeneratePointOnUnitSphereUniform(randGen) * randGen.generate01() * mesh.bbox.Diag() / ratio); + std::vector test_indeces; + for (int i = 0; i < num_test * 10; i++) + { + int index = randGen.generate01() * (mesh.vert.size() - 1); + test_indeces.push_back(index); + randomSamples[i] += mesh.vert[i].P(); + } - std::vector test_indeces; - for (int i = 0; i < num_test * 10; i++) - { - int index = randGen.generate01() * (mesh.vert.size() - 1); - test_indeces.push_back(index); - randomSamples[i] += mesh.vert[i].P(); - } - - testKDTree(mesh, test_indeces, randomSamples); - testNanoFLANN(mesh, test_indeces, randomSamples); - testUniformGrid(mesh, test_indeces, randomSamples); - testSpatialHashing(mesh, test_indeces, randomSamples); - testPerfectSpatialHashing(mesh, test_indeces); - testOctree(mesh, test_indeces, randomSamples); + testKDTree(mesh, test_indeces, randomSamples); + testNanoFLANN(mesh, test_indeces, randomSamples); + testUniformGrid(mesh, test_indeces, randomSamples); + testSpatialHashing(mesh, test_indeces, randomSamples); + testPerfectSpatialHashing(mesh, test_indeces); + testOctree(mesh, test_indeces, randomSamples); }