trimesh_closest.cpp
Go to the documentation of this file.
00001 
00002 // stuff to define the mesh
00003 #include <vcg/complex/complex.h>
00004 #include <vcg/simplex/face/component_ep.h>
00005 #include <vcg/complex/algorithms/point_sampling.h>
00006 #include <vcg/complex/algorithms/update/component_ep.h>
00007 #include <vcg/complex/algorithms/update/normal.h>
00008 
00009 // io
00010 #include <wrap/io_trimesh/import.h>
00011 #include <wrap/io_trimesh/export_ply.h>
00012 
00013 #include <cstdlib>
00014 
00015 #include <sys/timeb.h>
00016 #include <iostream>
00017 #include <string>
00018 
00019 
00020 class BaseVertex;
00021 class BaseEdge;
00022 class BaseFace;
00023 
00024 struct BaseUsedTypes: public vcg::UsedTypes<vcg::Use<BaseVertex>::AsVertexType,vcg::Use<BaseEdge>::AsEdgeType,vcg::Use<BaseFace>::AsFaceType>{};
00025 
00026 class BaseVertex  : public vcg::Vertex< BaseUsedTypes,
00027         vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags  > {};
00028 
00029 class BaseEdge : public vcg::Edge< BaseUsedTypes> {};
00030 
00031 class BaseFace    : public vcg::Face< BaseUsedTypes,
00032         vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::BitFlags, vcg::face::Mark, vcg::face::EmptyEdgePlane > {};
00033 
00034 class BaseMesh    : public vcg::tri::TriMesh<std::vector<BaseVertex>, std::vector<BaseFace> > {};
00035 
00036 
00037 class RTVertex;
00038 class RTEdge;
00039 class RTFace;
00040 
00041 struct RTUsedTypes: public vcg::UsedTypes<vcg::Use<RTVertex>::AsVertexType,vcg::Use<RTEdge>::AsEdgeType,vcg::Use<RTFace>::AsFaceType>{};
00042 
00043 class RTVertex  : public vcg::Vertex< RTUsedTypes,
00044         vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags  > {};
00045 
00046 class RTEdge : public vcg::Edge< RTUsedTypes> {};
00047 
00048 class RTFace    : public vcg::Face< RTUsedTypes,
00049         vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::EdgePlane, vcg::face::Mark, vcg::face::BitFlags > {};
00050 
00051 class RTMesh    : public vcg::tri::TriMesh<std::vector<RTVertex>, std::vector<RTFace> > {};
00052 
00053 
00054 using namespace vcg;
00055 
00056 void Usage()
00057 {
00058         printf( "\nUsage:  trimesh_closest mesh.ply samplenum sampledistance(as fraction of bboxdiag)");
00059         exit(-1);
00060 }
00061 
00062 // Testing of closest point on a mesh functionalities
00063 // Two main options
00064 // - using or not precomputed edges and planes
00065 // - using the simple wrapper or the basic functions of the grid.
00066 // - using the fn as size of the grid or the edge lenght as cell side
00067 
00068 template <class MeshType, bool useEdge,bool useWrap, bool useFaceNumForGrid>
00069 bool UnitTest_Closest(const char *filename1, int sampleNum, float dispPerc, std::vector<int> resultVec)
00070 {
00071   MeshType mr;
00072   typedef typename MeshType::ScalarType ScalarType;
00073   typedef typename MeshType::CoordType CoordType;
00074   typedef typename MeshType::FaceType FaceType;
00075   typedef GridStaticPtr<FaceType, ScalarType> TriMeshGrid;
00076 
00077   int startOpen=clock();
00078   int err=vcg::tri::io::Importer<MeshType>::Open(mr,filename1);
00079   tri::UpdateBounding<MeshType>::Box(mr);
00080 //  tri::UpdateNormals<MeshType>::PerFaceNormalized(mr);
00081   tri::UpdateNormal<MeshType>::PerFace(mr);
00082   float dispAbs = mr.bbox.Diag()*dispPerc;
00083   if(err)
00084   {
00085       std::cerr << "Unable to open mesh " << filename1 << " : " << vcg::tri::io::Importer<MeshType>::ErrorMsg(err) << std::endl;
00086       exit(-1);
00087   }
00088   int endOpen = clock();
00089   printf("Loading %6.3f - ",float(endOpen-startOpen)/CLOCKS_PER_SEC);
00090 
00091   int startSampling = clock();
00092 
00093   std::vector<Point3f> MontecarloSamples;
00094   // First step build the sampling
00095   typedef tri::TrivialSampler<MeshType> BaseSampler;
00096   BaseSampler mcSampler(MontecarloSamples);
00097   tri::SurfaceSampling<MeshType,BaseSampler>::SamplingRandomGenerator().initialize(123);
00098   tri::SurfaceSampling<MeshType,BaseSampler>::Montecarlo(mr, mcSampler, sampleNum);
00099   math::MarsenneTwisterRNG rnd;
00100   rnd.initialize(123);
00101   for(size_t i=0;i<MontecarloSamples.size();++i)
00102   {
00103     Point3f pp(rnd.generate01(),rnd.generate01(),rnd.generate01());
00104     pp = (pp+Point3f(-0.5f,-0.5f,-0.5f))*2.0f;
00105     pp*=rnd.generate01()*dispAbs;
00106     MontecarloSamples[i]+=pp;
00107   }
00108   int endSampling = clock();
00109 
00110   printf("Sampling  %6.3f - ",float(endSampling-startSampling)/CLOCKS_PER_SEC);
00111 
00112   int startGridInit = clock();
00113   TriMeshGrid TRGrid;
00114   if(useFaceNumForGrid)
00115   {
00116     TRGrid.Set(mr.face.begin(),mr.face.end(),mr.FN()*2);
00117   }
00118   else
00119   {
00120     float avgEdge = tri::Stat<MeshType>::ComputeEdgeLengthAverage(mr);
00121     TRGrid.SetWithRadius(mr.face.begin(),mr.face.end(),avgEdge*2);
00122   }
00123 
00124   if(useEdge)
00125      tri::UpdateComponentEP<MeshType>::Set(mr);
00126 
00127   int endGridInit = clock();
00128   printf("Grid Init %6.3f - ",float(endGridInit-startGridInit)/CLOCKS_PER_SEC);
00129 
00130   const ScalarType maxDist=std::max(dispAbs*10.0f,mr.bbox.Diag()/1000.f);
00131   CoordType closest;
00132   ScalarType dist;
00133   int startGridQuery = clock();
00134   double avgDist=0;
00135   resultVec.resize(MontecarloSamples.size());
00136   if(useEdge && useWrap)
00137     for(size_t i=0;i<MontecarloSamples.size();++i)
00138     {
00139       resultVec[i]=tri::Index(mr,tri::GetClosestFaceEP(mr,TRGrid,MontecarloSamples[i], maxDist,dist,closest));
00140       if(resultVec[i]) avgDist += double(dist);
00141     }
00142   if(!useEdge && useWrap)
00143     for(size_t i=0;i<MontecarloSamples.size();++i)
00144     {
00145       resultVec[i]=tri::Index(mr,tri::GetClosestFaceBase(mr,TRGrid,MontecarloSamples[i], maxDist,dist,closest));
00146       if(resultVec[i]) avgDist += double(dist);
00147     }
00148   if(useEdge && !useWrap)
00149   {
00150     typedef tri::FaceTmark<MeshType> MarkerFace;
00151     MarkerFace mf;
00152     mf.SetMesh(&mr);
00153     face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
00154     for(size_t i=0;i<MontecarloSamples.size();++i)
00155     {
00156       resultVec[i]=tri::Index(mr,TRGrid.GetClosest(PDistFunct,mf,MontecarloSamples[i],maxDist,dist,closest));
00157       if(resultVec[i]) avgDist += double(dist);
00158     }
00159   }
00160   if(!useEdge && !useWrap)
00161   {
00162     typedef tri::FaceTmark<MeshType> MarkerFace;
00163     MarkerFace mf;
00164     mf.SetMesh(&mr);
00165     face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
00166     for(size_t i=0;i<MontecarloSamples.size();++i)
00167     {
00168       resultVec[i]=tri::Index(mr,TRGrid.GetClosest(PDistFunct,mf,MontecarloSamples[i],maxDist,dist,closest));
00169       if(resultVec[i]) avgDist += double(dist);
00170     }
00171   }
00172 
00173   int endGridQuery = clock();
00174   printf("Grid Size %3i %3i %3i - ",TRGrid.siz[0],TRGrid.siz[1],TRGrid.siz[2]);
00175   printf("Avg dist %6.9lf - ",avgDist / float(MontecarloSamples.size()));
00176   printf("Grid Query %6.3f \n", float(endGridQuery-startGridQuery)/CLOCKS_PER_SEC);
00177   return true;
00178 }
00179 
00180 int main(int argc ,char**argv)
00181 {
00182   if(argc<3) Usage();
00183   float dispPerc = atof(argv[3]);
00184   int sampleNum = atoi(argv[2]);
00185   std::vector<int> resultVecRT11;
00186   std::vector<int> resultVecRT01;
00187   std::vector<int> resultVecRT00;
00188   std::vector<int> resultVecRT10;
00189   std::vector<int> resultVecBS01;
00190   std::vector<int> resultVecBS00;
00191   UnitTest_Closest<RTMesh, true,  true,  true>     (argv[1],sampleNum,dispPerc,resultVecRT11);
00192   UnitTest_Closest<RTMesh, true,  true,  false>    (argv[1],sampleNum,dispPerc,resultVecRT11);
00193   UnitTest_Closest<RTMesh, true,  false, true>    (argv[1],sampleNum,dispPerc,resultVecRT01);
00194   UnitTest_Closest<RTMesh, true,  false, false>    (argv[1],sampleNum,dispPerc,resultVecRT00);
00195   UnitTest_Closest<RTMesh, false, true,  true>   (argv[1],sampleNum,dispPerc,resultVecRT10);
00196   UnitTest_Closest<RTMesh, false, true,  false>   (argv[1],sampleNum,dispPerc,resultVecRT10);
00197   UnitTest_Closest<RTMesh, false, false, true>   (argv[1],sampleNum,dispPerc,resultVecRT10);
00198   UnitTest_Closest<RTMesh, false, false, false>   (argv[1],sampleNum,dispPerc,resultVecRT10);
00199 
00200   UnitTest_Closest<BaseMesh,false, true,  true>  (argv[1],sampleNum,dispPerc,resultVecBS01);
00201   UnitTest_Closest<BaseMesh,false, true,  false> (argv[1],sampleNum,dispPerc,resultVecBS01);
00202   UnitTest_Closest<BaseMesh,false, false, true>(argv[1],sampleNum,dispPerc,resultVecBS01);
00203   UnitTest_Closest<BaseMesh,false, false, false>(argv[1],sampleNum,dispPerc,resultVecBS01);
00204 
00205   for(size_t i=0;i<resultVecRT11.size();++i)
00206   {
00207     if(resultVecRT11[i]!=resultVecRT01[i]) printf("%lu is diff",i);
00208     if(resultVecRT11[i]!=resultVecRT00[i]) printf("%lu is diff",i);
00209     if(resultVecRT11[i]!=resultVecRT10[i]) printf("%lu is diff",i);
00210     if(resultVecRT11[i]!=resultVecBS00[i]) printf("%lu is diff",i);
00211     if(resultVecRT11[i]!=resultVecBS01[i]) printf("%lu is diff",i);
00212   }
00213   return 0;
00214 }


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:38:15