25 #include <vcg/complex/complex.h>
26 #include <vcg/simplex/face/component_ep.h>
27 #include <vcg/complex/algorithms/update/component_ep.h>
28 #include <vcg/complex/algorithms/point_sampling.h>
30 #include <wrap/io_trimesh/import.h>
31 #include <wrap/io_trimesh/export_ply.h>
38 struct BaseUsedTypes:
public vcg::UsedTypes<vcg::Use<BaseVertex>::AsVertexType,vcg::Use<BaseEdge>::AsEdgeType,vcg::Use<BaseFace>::AsFaceType>{};
40 class BaseVertex :
public vcg::Vertex< BaseUsedTypes,
41 vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags > {};
43 class BaseEdge :
public vcg::Edge< BaseUsedTypes> {};
45 class BaseFace :
public vcg::Face< BaseUsedTypes,
46 vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::BitFlags, vcg::face::Mark, vcg::face::EmptyEdgePlane > {};
48 class BaseMesh :
public vcg::tri::TriMesh<std::vector<BaseVertex>, std::vector<BaseFace> > {};
55 struct RTUsedTypes:
public vcg::UsedTypes<vcg::Use<RTVertex>::AsVertexType,vcg::Use<RTEdge>::AsEdgeType,vcg::Use<RTFace>::AsFaceType>{};
57 class RTVertex :
public vcg::Vertex< RTUsedTypes,
58 vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags > {};
60 class RTEdge :
public vcg::Edge< RTUsedTypes> {};
62 class RTFace :
public vcg::Face< RTUsedTypes,
63 vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::EdgePlane, vcg::face::Mark, vcg::face::BitFlags > {};
65 class RTMesh :
public vcg::tri::TriMesh<std::vector<RTVertex>, std::vector<RTFace> > {};
72 printf(
"\nUsage: trimesh_closest mesh.ply samplenum sampledistance(as fraction of bboxdiag)");
82 template <
class MeshType,
bool useEdge,
bool useWrap,
bool useFaceNumForGr
id>
83 bool UnitTest_Closest(
const char *filename1,
int sampleNum,
float dispPerc, std::vector<int> resultVec)
86 typedef typename MeshType::ScalarType ScalarType;
87 typedef typename MeshType::CoordType CoordType;
88 typedef typename MeshType::FaceType FaceType;
89 typedef GridStaticPtr<FaceType, ScalarType> TriMeshGrid;
91 int startOpen=clock();
92 int err=vcg::tri::io::Importer<MeshType>::Open(mr,filename1);
96 float dispAbs = mr.bbox.Diag()*dispPerc;
99 std::cerr <<
"Unable to open mesh " << filename1 <<
" : " << vcg::tri::io::Importer<MeshType>::ErrorMsg(err) << std::endl;
102 int endOpen = clock();
103 printf(
"Loading %6.3f - ",
float(endOpen-startOpen)/CLOCKS_PER_SEC);
105 int startSampling = clock();
107 std::vector<Point3f> MontecarloSamples;
110 BaseSampler mcSampler(MontecarloSamples);
113 math::MarsenneTwisterRNG rnd;
115 for(
size_t i=0;i<MontecarloSamples.size();++i)
117 Point3f pp(rnd.generate01(),rnd.generate01(),rnd.generate01());
118 pp = (pp+Point3f(-0.5f,-0.5f,-0.5f))*2.0f;
119 pp*=rnd.generate01()*dispAbs;
120 MontecarloSamples[i]+=pp;
122 int endSampling = clock();
124 printf(
"Sampling %6.3f - ",
float(endSampling-startSampling)/CLOCKS_PER_SEC);
126 int startGridInit = clock();
128 if(useFaceNumForGrid)
130 TRGrid.Set(mr.face.begin(),mr.face.end(),mr.FN()*2);
134 float avgEdge = tri::Stat<MeshType>::ComputeEdgeLengthAverage(mr);
135 TRGrid.SetWithRadius(mr.face.begin(),mr.face.end(),avgEdge*2);
141 int endGridInit = clock();
142 printf(
"Grid Init %6.3f - ",
float(endGridInit-startGridInit)/CLOCKS_PER_SEC);
144 const ScalarType maxDist=std::max(dispAbs*10.0f,mr.bbox.Diag()/1000.f);
147 int startGridQuery = clock();
149 resultVec.resize(MontecarloSamples.size());
150 if(useEdge && useWrap)
151 for(
size_t i=0;i<MontecarloSamples.size();++i)
153 resultVec[i]=tri::Index(mr,tri::GetClosestFaceEP(mr,TRGrid,MontecarloSamples[i], maxDist,dist,closest));
154 if(resultVec[i]) avgDist += double(dist);
156 if(!useEdge && useWrap)
157 for(
size_t i=0;i<MontecarloSamples.size();++i)
159 resultVec[i]=tri::Index(mr,tri::GetClosestFaceBase(mr,TRGrid,MontecarloSamples[i], maxDist,dist,closest));
160 if(resultVec[i]) avgDist += double(dist);
162 if(useEdge && !useWrap)
164 typedef tri::FaceTmark<MeshType> MarkerFace;
167 face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
168 for(
size_t i=0;i<MontecarloSamples.size();++i)
170 resultVec[i]=tri::Index(mr,TRGrid.GetClosest(PDistFunct,mf,MontecarloSamples[i],maxDist,dist,closest));
171 if(resultVec[i]) avgDist += double(dist);
174 if(!useEdge && !useWrap)
176 typedef tri::FaceTmark<MeshType> MarkerFace;
179 face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
180 for(
size_t i=0;i<MontecarloSamples.size();++i)
182 resultVec[i]=tri::Index(mr,TRGrid.GetClosest(PDistFunct,mf,MontecarloSamples[i],maxDist,dist,closest));
183 if(resultVec[i]) avgDist += double(dist);
187 int endGridQuery = clock();
188 printf(
"Grid Size %3i %3i %3i - ",TRGrid.siz[0],TRGrid.siz[1],TRGrid.siz[2]);
189 printf(
"Avg dist %6.9lf - ",avgDist /
float(MontecarloSamples.size()));
190 printf(
"Grid Query %6.3f \n",
float(endGridQuery-startGridQuery)/CLOCKS_PER_SEC);
194 int main(
int argc ,
char**argv)
197 float dispPerc = atof(argv[3]);
198 int sampleNum = atoi(argv[2]);
199 std::vector<int> resultVecRT11;
200 std::vector<int> resultVecRT01;
201 std::vector<int> resultVecRT00;
202 std::vector<int> resultVecRT10;
203 std::vector<int> resultVecBS01;
204 std::vector<int> resultVecBS00;
205 UnitTest_Closest<RTMesh, true, true, true> (argv[1],sampleNum,dispPerc,resultVecRT11);
206 UnitTest_Closest<RTMesh, true, true, false> (argv[1],sampleNum,dispPerc,resultVecRT11);
207 UnitTest_Closest<RTMesh, true, false, true> (argv[1],sampleNum,dispPerc,resultVecRT01);
208 UnitTest_Closest<RTMesh, true, false, false> (argv[1],sampleNum,dispPerc,resultVecRT00);
209 UnitTest_Closest<RTMesh, false, true, true> (argv[1],sampleNum,dispPerc,resultVecRT10);
210 UnitTest_Closest<RTMesh, false, true, false> (argv[1],sampleNum,dispPerc,resultVecRT10);
211 UnitTest_Closest<RTMesh, false, false, true> (argv[1],sampleNum,dispPerc,resultVecRT10);
212 UnitTest_Closest<RTMesh, false, false, false> (argv[1],sampleNum,dispPerc,resultVecRT10);
214 UnitTest_Closest<BaseMesh,false, true, true> (argv[1],sampleNum,dispPerc,resultVecBS01);
215 UnitTest_Closest<BaseMesh,false, true, false> (argv[1],sampleNum,dispPerc,resultVecBS01);
216 UnitTest_Closest<BaseMesh,false, false, true>(argv[1],sampleNum,dispPerc,resultVecBS01);
217 UnitTest_Closest<BaseMesh,false, false, false>(argv[1],sampleNum,dispPerc,resultVecBS01);
219 for(
size_t i=0;i<resultVecRT11.size();++i)
221 if(resultVecRT11[i]!=resultVecRT01[i]) printf(
"%lu is diff",i);
222 if(resultVecRT11[i]!=resultVecRT00[i]) printf(
"%lu is diff",i);
223 if(resultVecRT11[i]!=resultVecRT10[i]) printf(
"%lu is diff",i);
224 if(resultVecRT11[i]!=resultVecBS00[i]) printf(
"%lu is diff",i);
225 if(resultVecRT11[i]!=resultVecBS01[i]) printf(
"%lu is diff",i);