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