1 /****************************************************************************
2 * VCGLib                                                            o o     *
3 * Visual and Computer Graphics Library                            o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2004-2016                                           \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 
24 #include <vcg/complex/complex.h>
25 #include <vcg/complex/algorithms/update/component_ep.h>
26 #include <vcg/complex/algorithms/update/quality.h>
27 #include <vcg/complex/algorithms/update/color.h>
28 #include <vcg/complex/algorithms/stat.h>
29 #include <vcg/complex/algorithms/clean.h>
30 #include <vcg/complex/algorithms/intersection.h>
31 #include <vcg/space/index/grid_static_ptr.h>
32 #include <vcg/space/index/spatial_hashing.h>
33 #include <vcg/complex/algorithms/closest.h>
34 
35 // VCG File Format Importer/Exporter
36 #include <wrap/io_trimesh/import.h>
37 #include <wrap/io_trimesh/export_ply.h>
38 
39 using namespace std;
40 using namespace vcg;
41 
42 class MyFace;
43 class MyEdge;
44 class MyVertex;
45 
46 struct MyUsedTypes : public UsedTypes<	Use<MyVertex>		::AsVertexType,
47                                         Use<MyEdge>			::AsEdgeType,
48 																				Use<MyFace>			::AsFaceType>{};
49 
50 
51 class MyVertex  : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::Normal3f, vertex::Mark,vertex::Color4b, vertex::Qualityf>{};
52 class MyEdge    : public Edge<MyUsedTypes>{};
53 class MyFace    : public Face  <MyUsedTypes, face::VertexRef,face::BitFlags,face::Mark, face::Normal3f> {};
54 
55 class MyMesh : public tri::TriMesh< vector<MyVertex>, vector<MyFace > >{};
56 
57 // Uncomment only one of the two following lines to test different data structures
58 typedef vcg::GridStaticPtr<MyMesh::FaceType, MyMesh::ScalarType> TriMeshGrid;
59 //typedef vcg::SpatialHashTable<MyMesh::FaceType, MyMesh::ScalarType> TriMeshGrid;
60 
main(int argc,char ** argv)61 int main(int argc,char ** argv)
62 {
63   if (argc<2)
64 	{
65 		printf("\n");
66     printf("    Compute an approximation of the shape diameter function\n");
67     printf("    Usage: trimesh_intersection <filename> [angle samplenum]\n\n");
68     printf("       <filename>        Mesh model for which to compute the sdf (PLY format).\n");
69     printf("       angle             the wideness (degree) of the cone of ray that must be shot from each vertex (default 45)\n");
70     printf("       samplenum         the oversampling factor (0 -> one ray, 1, 9 ray, 2-> 25 rays (default 2)\n");
71 
72 		return 0;
73 	}
74 
75 	MyMesh m;
76  int t0=clock();
77 	// open a mesh
78 	int err = tri::io::Importer<MyMesh>::Open(m,argv[1]);
79   if(err) {
80 		printf("Error in reading %s: '%s'\n",argv[1],tri::io::Importer<MyMesh>::ErrorMsg(err));
81 		exit(-1);
82 	}
83  // the other parameters
84   float widenessRad = math::ToRad(20.0);
85 
86   if(argc>2) {
87     widenessRad = math::ToRad(atof(argv[2]));
88     printf("Setting wideness to %f degree\n",atof(argv[2]));
89   }
90   int n_samples=2;
91   if(argc>3) n_samples = atoi(argv[3]);
92   int samplePerVert = (n_samples*2+ 1)*(n_samples*2+ 1);
93   printf("Using oversampling to %i  (%i sample per vertex)\n",n_samples,samplePerVert);
94 
95 
96   // some cleaning to get rid of bad stuff
97 	int dup = tri::Clean<MyMesh>::RemoveDuplicateVertex(m);
98 	int unref =  tri::Clean<MyMesh>::RemoveUnreferencedVertex(m);
99 
100 	if (dup > 0 || unref > 0)
101 		printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]);
102 
103   // updating
104   tri::UpdateBounding<MyMesh>::Box(m);
105   tri::UpdateNormal<MyMesh>::PerFaceNormalized(m);
106   tri::UpdateNormal<MyMesh>::PerVertexAngleWeighted(m);
107   tri::UpdateNormal<MyMesh>::NormalizePerVertex(m);
108 	// Create a static grid (for fast indexing) and fill it
109 	TriMeshGrid static_grid;
110 	static_grid.Set(m.face.begin(), m.face.end());
111 
112   typedef MyMesh::ScalarType ScalarType;
113   int t1=clock();
114   float t;
115   MyMesh::FaceType *rf;
116   MyMesh::VertexIterator vi;
117   float maxDist=m.bbox.Diag();
118   float offset= maxDist / 10000.0;
119   int totRay=0;
120 
121   ScalarType deltaRad=widenessRad/(ScalarType)(n_samples*2);
122   if(n_samples==0) deltaRad=0;
123 
124   tri::UpdateQuality<MyMesh>::VertexConstant(m,0);
125   for(vi=m.vert.begin();vi!=m.vert.end();++vi)
126   {
127     vcg::Ray3f ray;
128     ray.SetOrigin((*vi).cP()-((*vi).cN()*offset));
129     Point3f dir0 = -(*vi).cN();
130     int cnt=0;
131     ScalarType theta_init,phi_init,ro;
132     dir0.ToPolarRad(ro,theta_init,phi_init);
133     for (int x=-n_samples;x<=n_samples;x++)
134       for (int y=-n_samples;y<=n_samples;y++)
135       {
136         ScalarType theta=theta_init+x*deltaRad;
137         ScalarType phi=phi_init+y*deltaRad;
138 
139         if (theta<0) theta=2.0*M_PI+theta;
140 
141         Point3f dir;
142         dir.FromPolarRad(ro,theta,phi);
143         dir.Normalize();
144         ray.SetDirection(dir);
145 
146         rf = tri::DoRay<MyMesh,TriMeshGrid>(m,static_grid,ray,maxDist,t);
147         if(rf)
148         {
149           (*vi).Q()+=t;
150           cnt++;
151         }
152       }
153     if(cnt>0){
154       (*vi).Q()/=cnt;
155       totRay+=cnt;
156     }
157   }
158   int t2 = clock();
159   tri::UpdateColor<MyMesh>::PerVertexQualityRamp(m);
160   tri::io::ExporterPLY<MyMesh>::Save(m,"SDF.ply",tri::io::Mask::IOM_VERTCOLOR+tri::io::Mask::IOM_VERTQUALITY);
161 
162   printf("Initializated in %i msec\n",t1-t0);
163   printf("Completed in %i msec\n",t2-t1);
164   printf("Shoot %i rays and found %i intersections\n",m.VN()*samplePerVert,totRay);
165 
166 return 0;
167 }
168 
169