1 #ifndef STAT_REMESHING
2 #define STAT_REMESHING
3
4 #include <vcg/complex/algorithms/update/topology.h>
5 #include <vcg/space/triangle3.h>
6 #include <wrap/io_trimesh/import_ply.h>
7 #include <wrap/io_trimesh/export_ply.h>
8 #include <vcg/simplex/face/pos.h>
9 #include <vcg/math/histogram.h>
10
11 #define PI 3.14159265
12
13
14
15 //return moltiplication of aspect ratio of faces of the mesh
16 ///to see if add + normalize is better
17 template <class MeshType>
MinimumAspectRatio(const MeshType & mesh)18 typename MeshType::ScalarType MinimumAspectRatio(const MeshType &mesh)
19 {
20 typedef typename MeshType::ScalarType ScalarType;
21 ScalarType res=1.f;
22 typename MeshType::ConstFaceIterator Fi;
23 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
24 if ((!(*Fi).IsD()))
25 {
26 ScalarType test=vcg::QualityRadii((*Fi).P(0),(*Fi).P(1),(*Fi).P(2));
27 if (test<res)
28 res=test;
29 }
30 return (res);
31 }
32
33 //return moltiplication of aspect ratio of faces of the mesh
34 ///to see if add + normalize is better
35 template <class MeshType>
MinimumArea(const MeshType & mesh)36 typename MeshType::ScalarType MinimumArea(const MeshType &mesh)
37 {
38 typedef typename MeshType::ScalarType ScalarType;
39 ScalarType res=10000.f;
40 typename MeshType::ConstFaceIterator Fi;
41 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
42 if ((!(*Fi).IsD()))
43 {
44 ScalarType test=vcg::DoubleArea(*Fi)/2.0;
45 if (test<res)
46 res=test;
47 }
48 return (res);
49 }
50
51 //return moltiplication of aspect ratio of faces of the mesh
52 ///to see if add + normalize is better
53 template <class MeshType>
MaximumArea(const MeshType & mesh)54 typename MeshType::ScalarType MaximumArea(const MeshType &mesh)
55 {
56 typedef typename MeshType::ScalarType ScalarType;
57 ScalarType res=0.f;
58 typename MeshType::ConstFaceIterator Fi;
59 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
60 if ((!(*Fi).IsD()))
61 {
62 ScalarType test=vcg::DoubleArea(*Fi)/2.0;
63 if (test>res)
64 res=test;
65 }
66 return (res);
67 }
68
69 //return moltiplication of aspect ratio of faces of the mesh
70 ///to see if add + normalize is better
71 template <class FaceType>
MinAngleFace(const FaceType & f)72 typename FaceType::ScalarType MinAngleFace(const FaceType &f)
73 {
74 typedef typename FaceType::ScalarType ScalarType;
75 typedef typename FaceType::CoordType CoordType;
76 ScalarType res=360.0;
77 for (int i=0;i<3;i++)
78 {
79 CoordType v0=f.cP((i+1)%3)-f.cP(i);
80 CoordType v1=f.cP((i+2)%3)-f.cP(i);
81 v0.Normalize();
82 v1.Normalize();
83 ScalarType angle=acos(v0*v1)* 180.0 / PI;
84 if (angle<res)
85 res=angle;
86 }
87 assert(res<=60.0);
88 return (res);
89 }
90
91 //return moltiplication of aspect ratio of faces of the mesh
92 ///to see if add + normalize is better
93 template <class FaceType>
MaxAngleFace(const FaceType & f)94 typename FaceType::ScalarType MaxAngleFace(const FaceType &f)
95 {
96 typedef typename FaceType::ScalarType ScalarType;
97 typedef typename FaceType::CoordType CoordType;
98 ScalarType res=0;
99 for (int i=0;i<3;i++)
100 {
101 CoordType v0=f.cP((i+1)%3)-f.cP(i);
102 CoordType v1=f.cP((i+2)%3)-f.cP(i);
103 v0.Normalize();
104 v1.Normalize();
105 ScalarType angle=acos(v0*v1)* 180.0 / PI;
106 if (angle>res)
107 res=angle;
108 }
109 return (res);
110 }
111
112 template <class MeshType>
MinAngle(const MeshType & mesh)113 typename MeshType::ScalarType MinAngle(const MeshType &mesh)
114 {
115 typedef typename MeshType::ScalarType ScalarType;
116 ScalarType res=360.0;
117 typename MeshType::ConstFaceIterator Fi;
118 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
119 if ((!(*Fi).IsD()))
120 {
121 ScalarType testAngle=MinAngleFace(*Fi);
122 if (testAngle<res)
123 res=testAngle;
124 }
125 return (res);
126 }
127
128 template <class MeshType>
MaxAngle(const MeshType & mesh)129 typename MeshType::ScalarType MaxAngle(const MeshType &mesh)
130 {
131 typedef typename MeshType::ScalarType ScalarType;
132 ScalarType res=0;
133 typename MeshType::ConstFaceIterator Fi;
134 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
135 if ((!(*Fi).IsD()))
136 {
137 ScalarType testAngle=MaxAngleFace(*Fi);
138 if (testAngle>res)
139 res=testAngle;
140 }
141 return (res);
142 }
143
144 template <class MeshType>
MaxMinEdge(const MeshType & mesh,typename MeshType::ScalarType & min,typename MeshType::ScalarType & max)145 void MaxMinEdge(const MeshType &mesh,typename MeshType::ScalarType &min,
146 typename MeshType::ScalarType &max)
147 {
148 typedef typename MeshType::ScalarType ScalarType;
149 min=10000.0;
150 max=0.0;
151 typename MeshType::ConstFaceIterator Fi;
152 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
153 if ((!(*Fi).IsD()))
154 {
155
156 for (int i=0;i<3;i++)
157 {
158 typename MeshType::VertexType* v0=(*Fi).cV0(i);
159 typename MeshType::VertexType* v1=(*Fi).cV1(i);
160 if (v0>v1)
161 {
162 ScalarType dist=(v0->P()-v1->P()).Norm();
163 if (dist<min)
164 min=dist;
165 if (dist>max)
166 max=dist;
167 }
168 }
169 }
170 }
171 ////return moltiplication of aspect ratio of faces of the mesh
172 /////to see if add + normalize is better
173 //template <class MeshType>
174 //ScalarType AverageMinAngle(const MeshType &mesh)
175 //{
176 // ScalarType res=0;
177 // MeshType::ConstFaceIterator Fi;
178 // for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
179 // if ((!(*Fi).IsD()))
180 // {
181 // ScalarType testAngle=MinAngleFace(*Fi);
182 // res+=testAngle;
183 // }
184 // return (res/((ScalarType)mesh.fn));
185 //}
186
187 template <class MeshType>
StatAspectRatio(MeshType & mesh,typename MeshType::ScalarType & min,typename MeshType::ScalarType & average,typename MeshType::ScalarType & stand_dev)188 void StatAspectRatio(MeshType &mesh,
189 typename MeshType::ScalarType &min,
190 typename MeshType::ScalarType &average,
191 typename MeshType::ScalarType &stand_dev)
192 {
193 typedef typename MeshType::ScalarType ScalarType;
194
195 vcg::Histogram<ScalarType> HAspectRatio;
196
197 ScalarType minRatio=MinimumAspectRatio(mesh);
198 ScalarType maxRatio=1.f;
199 HAspectRatio.SetRange(minRatio,maxRatio,500);
200
201
202 typename MeshType::FaceIterator Fi;
203 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
204 HAspectRatio.Add(vcg::QualityRadii((*Fi).P(0),(*Fi).P(1),(*Fi).P(2)));
205
206 average=HAspectRatio.Avg();
207 stand_dev=HAspectRatio.StandardDeviation();
208 min=minRatio;
209 }
210
211 template <class MeshType>
StatArea(MeshType & mesh,typename MeshType::ScalarType & min,typename MeshType::ScalarType & max,typename MeshType::ScalarType & average,typename MeshType::ScalarType & stand_dev)212 void StatArea(MeshType &mesh,
213 typename MeshType::ScalarType &min,
214 typename MeshType::ScalarType &max,
215 typename MeshType::ScalarType &average,
216 typename MeshType::ScalarType &stand_dev)
217 {
218 typedef typename MeshType::ScalarType ScalarType;
219 typedef typename MeshType::CoordType CoordType;
220
221 vcg::Histogram<ScalarType> HArea;
222
223 ScalarType minArea=MinimumArea(mesh);
224 ScalarType maxArea=MaximumArea(mesh);
225 HArea.SetRange(minArea,maxArea,500);
226
227
228 typename MeshType::FaceIterator Fi;
229 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
230 {
231 CoordType p0=(*Fi).P0(0);
232 CoordType p1=(*Fi).P1(0);
233 CoordType p2=(*Fi).P2(0);
234 ScalarType area=((p1-p0)^(p2-p0)).Norm()/2.0;
235 HArea.Add(area);
236 }
237
238 average=HArea.Avg();
239 stand_dev=HArea.StandardDeviation();
240 min=minArea;
241 max=maxArea;
242 }
243
244 template <class MeshType>
StatAngle(MeshType & mesh,typename MeshType::ScalarType & min,typename MeshType::ScalarType & max,typename MeshType::ScalarType & average,typename MeshType::ScalarType & stand_dev)245 void StatAngle(MeshType &mesh,
246 typename MeshType::ScalarType &min,
247 typename MeshType::ScalarType &max,
248 typename MeshType::ScalarType &average,
249 typename MeshType::ScalarType &stand_dev)
250 {
251
252 typedef typename MeshType::ScalarType ScalarType;
253
254 vcg::Histogram<ScalarType> HAngle;
255
256 ScalarType minAngle=MinAngle(mesh);
257 ScalarType maxAngle=MaxAngle(mesh);
258 HAngle.SetRange(minAngle,maxAngle,500);
259
260
261 typename MeshType::FaceIterator Fi;
262 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
263 HAngle.Add(MinAngleFace((*Fi)));
264
265 average=HAngle.Avg();
266 stand_dev=HAngle.StandardDeviation();
267 min=minAngle;
268 max=maxAngle;
269 }
270
271 template <class MeshType>
StatEdge(MeshType & mesh,typename MeshType::ScalarType & min,typename MeshType::ScalarType & max,typename MeshType::ScalarType & average,typename MeshType::ScalarType & stand_dev)272 void StatEdge(MeshType &mesh,
273 typename MeshType::ScalarType &min,
274 typename MeshType::ScalarType &max,
275 typename MeshType::ScalarType &average,
276 typename MeshType::ScalarType &stand_dev)
277 {
278 typedef typename MeshType::ScalarType ScalarType;
279 typedef typename MeshType::VertexType VertexType;
280
281 vcg::Histogram<ScalarType> HEdge;
282
283 ScalarType minEdge;
284 ScalarType maxEdge;
285 MaxMinEdge(mesh,minEdge,maxEdge);
286 HEdge.SetRange(minEdge,maxEdge,500);
287
288 typedef typename MeshType::ScalarType ScalarType;
289 typename MeshType::FaceIterator Fi;
290 for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++)
291 {
292 for (int i=0;i<3;i++)
293 {
294 VertexType* v0=(*Fi).V(i);
295 VertexType* v1=(*Fi).V((i+1)%3);
296 if ((v0>v1)||((*Fi).FFp(i)==&(*Fi)))
297 {
298 ScalarType dist=(v0->P()-v1->P()).Norm();
299 HEdge.Add(dist);
300 }
301 }
302 }
303
304 average=HEdge.Avg();
305 stand_dev=HEdge.StandardDeviation();
306 min=minEdge;
307 max=maxEdge;
308 }
309
310 template <class MeshType>
NumRegular(MeshType & mesh)311 int NumRegular(MeshType &mesh)
312 {
313 typedef typename MeshType::FaceType FaceType;
314 ///update topology
315 vcg::tri::UpdateTopology<MeshType>::VertexFace(mesh);
316 typename MeshType::VertexIterator Vi;
317 int irregular=0;
318 for (Vi=mesh.vert.begin();Vi!=mesh.vert.end();Vi++)
319 {
320 if ((!(*Vi).IsD())&&(!(*Vi).IsB()))
321 {
322 vcg::face::VFIterator<FaceType> VFI(&(*Vi));
323 int num=0;
324 while (!(VFI.End()))
325 {
326 num++;
327 ++VFI;
328 }
329 if (num!=6)
330 irregular++;
331 }
332 }
333 return irregular;
334 }
335 #endif
336