00001 #include <vector>
00002
00003 using namespace std;
00004
00005
00006 #include<vcg/simplex/edge/base.h>
00007 #include<vcg/simplex/vertex/base.h>
00008 #include<vcg/simplex/face/base.h>
00009 #include <vcg/complex/trimesh/base.h>
00010 #include <vcg/complex/trimesh/update/topology.h>
00011 #include <vcg/complex/trimesh/update/edges.h>
00012 #include <vcg/complex/trimesh/update/bounding.h>
00013 #include <vcg/complex/trimesh/update/quality.h>
00014 #include <vcg/complex/trimesh/update/color.h>
00015 #include <vcg/complex/trimesh/update/flag.h>
00016 #include <vcg/complex/trimesh/stat.h>
00017 #include <vcg/complex/trimesh/clean.h>
00018 #include <vcg/complex/intersection.h>
00019 #include <vcg/space/index/grid_static_ptr.h>
00020 #include <vcg/space/index/spatial_hashing.h>
00021 #include <vcg/complex/trimesh/closest.h>
00022
00023
00024 #include <wrap/io_trimesh/import.h>
00025 #include <wrap/io_trimesh/export_ply.h>
00026
00027 using namespace vcg;
00028
00029 class MyFace;
00030 class MyEdge;
00031 class MyVertex;
00032
00033 struct MyUsedTypes : public UsedTypes< Use<MyVertex> ::AsVertexType,
00034 Use<MyEdge> ::AsEdgeType,
00035 Use<MyFace> ::AsFaceType>{};
00036
00037
00038 class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::Normal3f, vertex::Mark,vertex::Color4b, vertex::Qualityf>{};
00039 class MyFace : public Face <MyUsedTypes, face::VertexRef,face::BitFlags,face::Mark, face::Normal3f> {};
00040
00041 class MyMesh : public tri::TriMesh< vector<MyVertex>, vector<MyFace > >{};
00042
00043
00044 typedef vcg::GridStaticPtr<MyMesh::FaceType, MyMesh::ScalarType> TriMeshGrid;
00045
00046
00047 int main(int argc,char ** argv)
00048 {
00049 if (argc<2)
00050 {
00051 printf("\n");
00052 printf(" Compute an approximation of the shape diameter function\n");
00053 printf(" Usage: trimesh_intersection <filename> [angle samplenum]\n\n");
00054 printf(" <filename> Mesh model for which to compute the sdf (PLY format).\n");
00055 printf(" angle the wideness (degree) of the cone of ray that must be shot from each vertex (default 45)\n");
00056 printf(" samplenum the oversampling factor (0 -> one ray, 1, 9 ray, 2-> 25 rays (default 2)\n");
00057
00058 return 0;
00059 }
00060
00061 MyMesh m;
00062 int t0=clock();
00063
00064 int err = tri::io::Importer<MyMesh>::Open(m,argv[1]);
00065 if(err) {
00066 printf("Error in reading %s: '%s'\n",argv[1],tri::io::Importer<MyMesh>::ErrorMsg(err));
00067 exit(-1);
00068 }
00069
00070 float widenessRad = math::ToRad(20.0);
00071
00072 if(argc>2) {
00073 widenessRad = math::ToRad(atof(argv[2]));
00074 printf("Setting wideness to %f degree\n",atof(argv[2]));
00075 }
00076 int n_samples=2;
00077 if(argc>3) n_samples = atoi(argv[3]);
00078 int samplePerVert = (n_samples*2+ 1)*(n_samples*2+ 1);
00079 printf("Using oversampling to %i (%i sample per vertex)\n",n_samples,samplePerVert);
00080
00081
00082
00083 int dup = tri::Clean<MyMesh>::RemoveDuplicateVertex(m);
00084 int unref = tri::Clean<MyMesh>::RemoveUnreferencedVertex(m);
00085
00086 if (dup > 0 || unref > 0)
00087 printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]);
00088
00089
00090 tri::UpdateBounding<MyMesh>::Box(m);
00091 tri::UpdateNormals<MyMesh>::PerFaceNormalized(m);
00092 tri::UpdateNormals<MyMesh>::PerVertexAngleWeighted(m);
00093 tri::UpdateNormals<MyMesh>::NormalizeVertex(m);
00094 tri::UpdateFlags<MyMesh>::FaceProjection(m);
00095
00096 TriMeshGrid static_grid;
00097 static_grid.Set(m.face.begin(), m.face.end());
00098
00099 typedef MyMesh::ScalarType ScalarType;
00100 int t1=clock();
00101 float t;
00102 MyMesh::FaceType *rf;
00103 MyMesh::VertexIterator vi;
00104 float maxDist=m.bbox.Diag();
00105 float offset= maxDist / 10000.0;
00106 int totRay=0;
00107
00108 ScalarType deltaRad=widenessRad/(ScalarType)(n_samples*2);
00109 if(n_samples==0) deltaRad=0;
00110
00111 tri::UpdateQuality<MyMesh>::VertexConstant(m,0);
00112 for(vi=m.vert.begin();vi!=m.vert.end();++vi)
00113 {
00114 vcg::Ray3f ray;
00115 ray.SetOrigin((*vi).cP()-((*vi).cN()*offset));
00116 Point3f dir0 = -(*vi).cN();
00117 int cnt=0;
00118 ScalarType theta_init,phi_init,ro;
00119 dir0.ToPolarRad(ro,theta_init,phi_init);
00120 for (int x=-n_samples;x<=n_samples;x++)
00121 for (int y=-n_samples;y<=n_samples;y++)
00122 {
00123 ScalarType theta=theta_init+x*deltaRad;
00124 ScalarType phi=phi_init+y*deltaRad;
00125
00126 if (theta<0) theta=2.0*M_PI+theta;
00127
00128 Point3f dir;
00129 dir.FromPolarRad(ro,theta,phi);
00130 dir.Normalize();
00131 ray.SetDirection(dir);
00132
00133 rf = tri::DoRay<MyMesh,TriMeshGrid>(m,static_grid,ray,maxDist,t);
00134 if(rf)
00135 {
00136 (*vi).Q()+=t;
00137 cnt++;
00138 }
00139 }
00140 if(cnt>0){
00141 (*vi).Q()/=cnt;
00142 totRay+=cnt;
00143 }
00144 }
00145 int t2 = clock();
00146 tri::UpdateColor<MyMesh>::VertexQualityRamp(m);
00147 tri::io::ExporterPLY<MyMesh>::Save(m,"SDF.ply",tri::io::Mask::IOM_VERTCOLOR+tri::io::Mask::IOM_VERTQUALITY);
00148
00149 printf("Initializated in %i msec\n",t1-t0);
00150 printf("Completed in %i msec\n",t2-t1);
00151 printf("Shoot %i rays and found %i intersections\n",m.vn*samplePerVert,totRay);
00152
00153 return 0;
00154 }
00155