VCG Library
normal.h
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 #ifndef __VCG_TRI_UPDATE_NORMALS
25 #define __VCG_TRI_UPDATE_NORMALS
26 
27 #include <vcg/complex/algorithms/polygon_support.h>
28 
29 namespace vcg {
30 namespace tri {
31 
33 
35 
37 
44 template <class ComputeMeshType>
46 {
47 public:
48 typedef ComputeMeshType MeshType;
49 typedef typename MeshType::VertexType VertexType;
50 typedef typename MeshType::CoordType CoordType;
51 typedef typename VertexType::NormalType NormalType;
52 typedef typename VertexType::ScalarType ScalarType;
53 typedef typename MeshType::VertexPointer VertexPointer;
54 typedef typename MeshType::VertexIterator VertexIterator;
55 typedef typename MeshType::FaceType FaceType;
56 typedef typename MeshType::FacePointer FacePointer;
57 typedef typename MeshType::FaceIterator FaceIterator;
58 
60 
64 static void PerVertexClear(ComputeMeshType &m, bool ClearAllVertNormal=false)
65 {
66  RequirePerVertexNormal(m);
67  if(ClearAllVertNormal)
69  else
70  {
72  for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
73  if( !(*f).IsD() )
74  for(int i=0;i<3;++i) (*f).V(i)->ClearV();
75  }
76  VertexIterator vi;
77  for(vi=m.vert.begin();vi!=m.vert.end();++vi)
78  if( !(*vi).IsD() && (*vi).IsRW() && (!(*vi).IsV()) )
79  (*vi).N() = NormalType((ScalarType)0,(ScalarType)0,(ScalarType)0);
80 }
81 
83 
86 static void PerVertex(ComputeMeshType &m)
87 {
88  PerVertexClear(m);
89  for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
90  if( !(*f).IsD() && (*f).IsR() )
91  {
92  typename VertexType::NormalType t = vcg::TriangleNormal(*f);
93 
94  for(int j=0; j<(*f).VN(); ++j)
95  if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() )
96  (*f).V(j)->N() += t;
97  }
98 }
99 
100 static void PerFacePolygonal(ComputeMeshType &m)
101 {
102  RequirePerFaceNormal(m);
103  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
104  {
105  if( !(*fi).IsD() )
106  fi->N() = PolygonNormal(*fi).Normalize();
107  }
108 }
109 
111 
119 static void PerVertexAngleWeighted(ComputeMeshType &m)
120 {
121  PerVertexClear(m);
122  FaceIterator f;
123  for(f=m.face.begin();f!=m.face.end();++f)
124  if( !(*f).IsD() && (*f).IsR() )
125  {
126  NormalType t = TriangleNormal(*f).Normalize();
127  NormalType e0 = ((*f).V1(0)->cP()-(*f).V0(0)->cP()).Normalize();
128  NormalType e1 = ((*f).V1(1)->cP()-(*f).V0(1)->cP()).Normalize();
129  NormalType e2 = ((*f).V1(2)->cP()-(*f).V0(2)->cP()).Normalize();
130 
131  (*f).V(0)->N() += t*AngleN(e0,-e2);
132  (*f).V(1)->N() += t*AngleN(-e0,e1);
133  (*f).V(2)->N() += t*AngleN(-e1,e2);
134  }
135 }
136 
138 
145 static void PerVertexNelsonMaxWeighted(ComputeMeshType &m)
146 {
147  PerVertexClear(m);
148  FaceIterator f;
149  for(f=m.face.begin();f!=m.face.end();++f)
150  if( !(*f).IsD() && (*f).IsR() )
151  {
152  typename FaceType::NormalType t = TriangleNormal(*f);
153  ScalarType e0 = SquaredDistance((*f).V0(0)->cP(),(*f).V1(0)->cP());
154  ScalarType e1 = SquaredDistance((*f).V0(1)->cP(),(*f).V1(1)->cP());
155  ScalarType e2 = SquaredDistance((*f).V0(2)->cP(),(*f).V1(2)->cP());
156 
157  (*f).V(0)->N() += t/(e0*e2);
158  (*f).V(1)->N() += t/(e0*e1);
159  (*f).V(2)->N() += t/(e1*e2);
160  }
161 }
162 
166 static void PerFace(ComputeMeshType &m)
167 {
168  RequirePerFaceNormal(m);
169  for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
170  if( !(*f).IsD() )
171  f->N() = TriangleNormal(*f);
172 }
173 
174 
178 static void PerPolygonalFace(ComputeMeshType &m) {
179  tri::RequirePerFaceNormal(m);
180  tri::RequirePolygonalMesh(m);
181  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); fi++)
182  if (!fi->IsD()) {
183  fi->N().SetZero();
184  for (int i = 0; i < fi->VN(); i++)
185  fi->N() += fi->V0(i)->P() ^ fi->V1(i)->P();
186  }
187 }
188 
189 
191 
194 static void PerVertexFromCurrentFaceNormal(ComputeMeshType &m)
195 {
196  tri::RequirePerVertexNormal(m);
197 
198  VertexIterator vi;
199  for(vi=m.vert.begin();vi!=m.vert.end();++vi)
200  if( !(*vi).IsD() && (*vi).IsRW() )
201  (*vi).N()=CoordType(0,0,0);
202 
203  FaceIterator fi;
204  for(fi=m.face.begin();fi!=m.face.end();++fi)
205  if( !(*fi).IsD())
206  {
207  for(int j=0; j<(*fi).VN(); ++j)
208  if( !(*fi).V(j)->IsD())
209  (*fi).V(j)->N() += (*fi).cN();
210  }
211 }
212 
214 
217 static void PerFaceFromCurrentVertexNormal(ComputeMeshType &m)
218 {
219  tri::RequirePerVertexNormal(m);
220  tri::RequirePerFaceNormal(m);
221  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
222  if( !(*fi).IsD())
223  {
224  NormalType n;
225  n.SetZero();
226  for(int j=0; j<3; ++j)
227  n += fi->V(j)->cN();
228  n.Normalize();
229  fi->N() = n;
230  }
231 }
232 
234 static void NormalizePerVertex(ComputeMeshType &m)
235 {
236  tri::RequirePerVertexNormal(m);
237  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
238  if( !(*vi).IsD() && (*vi).IsRW() )
239  (*vi).N().Normalize();
240 }
241 
243 static void NormalizePerFace(ComputeMeshType &m)
244 {
245  tri::RequirePerFaceNormal(m);
246  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
247  if( !(*fi).IsD() ) (*fi).N().Normalize();
248 }
249 
251 static void NormalizePerFaceByArea(ComputeMeshType &m)
252 {
253  tri::RequirePerFaceNormal(m);
254  FaceIterator fi;
255  for(fi=m.face.begin();fi!=m.face.end();++fi)
256  if( !(*fi).IsD() )
257  {
258  (*fi).N().Normalize();
259  (*fi).N() = (*fi).N() * DoubleArea(*fi);
260  }
261 }
262 
264 static void PerVertexNormalized(ComputeMeshType &m)
265 {
266  PerVertex(m);
268 }
269 
271 static void PerFaceNormalized(ComputeMeshType &m)
272 {
273  PerFace(m);
274  NormalizePerFace(m);
275 }
276 
278 static void PerPolygonalFaceNormalized(ComputeMeshType &m) {
279  PerPolygonalFace(m);
280  NormalizePerFace(m);
281 }
282 
284 static void PerVertexPerFace(ComputeMeshType &m)
285 {
286  PerFace(m);
287  PerVertex(m);
288 }
289 
291 static void PerVertexNormalizedPerFace(ComputeMeshType &m)
292 {
293  PerVertexPerFace(m);
295 }
296 
298 static void PerVertexNormalizedPerFaceNormalized(ComputeMeshType &m)
299 {
301  NormalizePerFace(m);
302 }
303 
305 static void PerBitQuadFaceNormalized(ComputeMeshType &m)
306 {
307  PerFace(m);
308  for(FaceIterator f=m.face.begin();f!=m.face.end();++f) {
309  if( !(*f).IsD() ) {
310  for (int k=0; k<3; k++) if (f->IsF(k))
311  if (&*f < f->FFp(k)) {
312  f->N() = f->FFp(k)->N() = (f->FFp(k)->N() + f->N()).Normalize();
313  }
314  }
315  }
316 }
317 
318 
320 static void PerBitPolygonFaceNormalized(ComputeMeshType &m)
321 {
322  PerFace(m);
323  tri::RequireCompactness(m);
324  tri::RequireTriangularMesh(m);
326  std::vector<VertexPointer> vertVec;
327  std::vector<FacePointer> faceVec;
328  for(size_t i=0;i<m.face.size();++i)
329  if(!m.face[i].IsV())
330  {
331  tri::PolygonSupport<MeshType,MeshType>::ExtractPolygon(&(m.face[i]),vertVec,faceVec);
332  CoordType nf(0,0,0);
333  for(size_t j=0;j<faceVec.size();++j)
334  nf+=faceVec[j]->N().Normalize() * DoubleArea(*faceVec[j]);
335 
336  nf.Normalize();
337 
338  for(size_t j=0;j<faceVec.size();++j)
339  faceVec[j]->N()=nf;
340  }
341 }
343 static void PerVertexMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
344 {
345  tri::RequirePerVertexNormal(m);
346  float scale;
347 
348  Matrix33<ScalarType> mat33(mat,3);
349 
350 
351  if(remove_scaling){
352  scale = pow(mat33.Determinant(),(ScalarType)(1.0/3.0));
353  Point3<ScalarType> scaleV(scale,scale,scale);
354  Matrix33<ScalarType> S;
355  S.SetDiagonal(scaleV.V());
356  mat33*=S;
357  }
358 
359  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
360  if( !(*vi).IsD() && (*vi).IsRW() )
361  (*vi).N() = mat33*(*vi).N();
362 }
363 
365 static void PerFaceMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
366 {
367  tri::RequirePerFaceNormal(m);
368  float scale;
369 
370  Matrix33<ScalarType> mat33(mat,3);
371 
372  if( !HasPerFaceNormal(m)) return;
373 
374  if(remove_scaling){
375  scale = pow(mat33.Determinant(),ScalarType(1.0/3.0));
376  mat33[0][0]/=scale;
377  mat33[1][1]/=scale;
378  mat33[2][2]/=scale;
379  }
380 
381  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
382  if( !(*fi).IsD() && (*fi).IsRW() )
383  (*fi).N() = mat33* (*fi).N();
384 }
385 
390 static void PerWedgeCrease(ComputeMeshType &m, ScalarType angleRad)
391 {
392  tri::RequirePerFaceWedgeNormal(m);
393  tri::RequireFFAdjacency(m);
394 
395  ScalarType cosangle=math::Cos(angleRad);
396 
397  // Clear the per wedge normals
398  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
399  {
400  (*fi).WN(0)=NormalType(0,0,0);
401  (*fi).WN(1)=NormalType(0,0,0);
402  (*fi).WN(2)=NormalType(0,0,0);
403  }
404 
405  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
406  {
407  NormalType nn= TriangleNormal(*fi);
408  for(int i=0;i<3;++i)
409  {
410  const NormalType &na=TriangleNormal(*(*fi).FFp(i));
411  if(nn*na > cosangle )
412  {
413  fi->WN((i+0)%3) +=na;
414  fi->WN((i+1)%3) +=na;
415  }
416  }
417  }
418 }
419 
420 
421 static void PerFaceRW(ComputeMeshType &m, bool normalize=false)
422 {
423  tri::RequirePerFaceNormal(m);
424  FaceIterator f;
425  bool cn = true;
426 
427  if(normalize)
428  {
429  for(f=m.m.face.begin();f!=m.m.face.end();++f)
430  if( !(*f).IsD() && (*f).IsRW() )
431  {
432  for(int j=0; j<3; ++j)
433  if( !(*f).V(j)->IsR()) cn = false;
434  if( cn ) f->N() = TriangleNormal(*f).Normalize();
435  cn = true;
436  }
437  }
438  else
439  {
440  for(f=m.m.face.begin();f!=m.m.face.end();++f)
441  if( !(*f).IsD() && (*f).IsRW() )
442  {
443  for(int j=0; j<3; ++j)
444  if( !(*f).V(j)->IsR()) cn = false;
445 
446  if( cn )
447  f->N() = TriangleNormal(*f).Normalize();
448  cn = true;
449  }
450  }
451 }
452 
453 
454 }; // end class
455 
456 } // End namespace
457 } // End namespace
458 
459 #endif