00001
00002
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
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
00063
00064
00065
00066
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
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
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 }