$darkmode
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/space/triangle3.h>
28 #include <vcg/complex/base.h>
29 
30 #include <vcg/complex/algorithms/polygon_support.h>
31 
32 #include "flag.h"
33 
34 namespace vcg {
35 namespace tri {
36 
38 
40 
42 
49 template <class ComputeMeshType>
51 {
52 public:
53 typedef ComputeMeshType MeshType;
54 typedef typename MeshType::VertexType VertexType;
55 typedef typename MeshType::CoordType CoordType;
56 typedef typename VertexType::NormalType NormalType;
57 typedef typename VertexType::ScalarType ScalarType;
58 typedef typename MeshType::VertexPointer VertexPointer;
59 typedef typename MeshType::VertexIterator VertexIterator;
60 typedef typename MeshType::FaceType FaceType;
61 typedef typename MeshType::FacePointer FacePointer;
62 typedef typename MeshType::FaceIterator FaceIterator;
63 
65 
69 static void PerVertexClear(ComputeMeshType &m, bool ClearAllVertNormal=false)
70 {
71  RequirePerVertexNormal(m);
72  if(ClearAllVertNormal)
74  else
75  {
77  for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
78  if( !(*f).IsD() )
79  for(int i=0;i<3;++i) (*f).V(i)->ClearV();
80  }
81  VertexIterator vi;
82  for(vi=m.vert.begin();vi!=m.vert.end();++vi)
83  if( !(*vi).IsD() && (*vi).IsRW() && (!(*vi).IsV()) )
84  (*vi).N() = NormalType((ScalarType)0,(ScalarType)0,(ScalarType)0);
85 }
86 
88 
91 static void PerVertex(ComputeMeshType &m)
92 {
93  PerVertexClear(m);
94  for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
95  if( !(*f).IsD() && (*f).IsR() )
96  {
97  typename VertexType::NormalType t = vcg::TriangleNormal(*f);
98 
99  for(int j=0; j<(*f).VN(); ++j)
100  if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() )
101  (*f).V(j)->N() += t;
102  }
103 }
104 
105 static void PerFacePolygonal(ComputeMeshType &m)
106 {
107  RequirePerFaceNormal(m);
108  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
109  {
110  if( !(*fi).IsD() )
111  fi->N() = PolygonNormal(*fi).Normalize();
112  }
113 }
114 
116 
124 static void PerVertexAngleWeighted(ComputeMeshType &m)
125 {
126  PerVertexClear(m);
127  FaceIterator f;
128  for(f=m.face.begin();f!=m.face.end();++f)
129  if( !(*f).IsD() && (*f).IsR() )
130  {
131  NormalType t = TriangleNormal(*f).Normalize();
132  NormalType e0 = ((*f).V1(0)->cP()-(*f).V0(0)->cP()).Normalize();
133  NormalType e1 = ((*f).V1(1)->cP()-(*f).V0(1)->cP()).Normalize();
134  NormalType e2 = ((*f).V1(2)->cP()-(*f).V0(2)->cP()).Normalize();
135 
136  (*f).V(0)->N() += t*AngleN(e0,-e2);
137  (*f).V(1)->N() += t*AngleN(-e0,e1);
138  (*f).V(2)->N() += t*AngleN(-e1,e2);
139  }
140 }
141 
143 
150 static void PerVertexNelsonMaxWeighted(ComputeMeshType &m)
151 {
152  PerVertexClear(m);
153  FaceIterator f;
154  for(f=m.face.begin();f!=m.face.end();++f)
155  if( !(*f).IsD() && (*f).IsR() )
156  {
157  typename FaceType::NormalType t = TriangleNormal(*f);
158  ScalarType e0 = SquaredDistance((*f).V0(0)->cP(),(*f).V1(0)->cP());
159  ScalarType e1 = SquaredDistance((*f).V0(1)->cP(),(*f).V1(1)->cP());
160  ScalarType e2 = SquaredDistance((*f).V0(2)->cP(),(*f).V1(2)->cP());
161 
162  (*f).V(0)->N() += t/(e0*e2);
163  (*f).V(1)->N() += t/(e0*e1);
164  (*f).V(2)->N() += t/(e1*e2);
165  }
166 }
167 
171 static void PerFace(ComputeMeshType &m)
172 {
173  RequirePerFaceNormal(m);
174  for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
175  if( !(*f).IsD() )
176  f->N() = TriangleNormal(*f);
177 }
178 
179 
183 static void PerPolygonalFace(ComputeMeshType &m) {
184  tri::RequirePerFaceNormal(m);
185  tri::RequirePolygonalMesh(m);
186  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); fi++)
187  if (!fi->IsD()) {
188  fi->N().SetZero();
189  for (int i = 0; i < fi->VN(); i++)
190  fi->N() += fi->V0(i)->P() ^ fi->V1(i)->P();
191  }
192 }
193 
194 
196 
199 static void PerVertexFromCurrentFaceNormal(ComputeMeshType &m)
200 {
201  tri::RequirePerVertexNormal(m);
202 
203  VertexIterator vi;
204  for(vi=m.vert.begin();vi!=m.vert.end();++vi)
205  if( !(*vi).IsD() && (*vi).IsRW() )
206  (*vi).N()=CoordType(0,0,0);
207 
208  FaceIterator fi;
209  for(fi=m.face.begin();fi!=m.face.end();++fi)
210  if( !(*fi).IsD())
211  {
212  for(int j=0; j<(*fi).VN(); ++j)
213  if( !(*fi).V(j)->IsD())
214  (*fi).V(j)->N() += (*fi).cN();
215  }
216 }
217 
219 
222 static void PerFaceFromCurrentVertexNormal(ComputeMeshType &m)
223 {
224  tri::RequirePerVertexNormal(m);
225  tri::RequirePerFaceNormal(m);
226  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
227  if( !(*fi).IsD())
228  {
229  NormalType n;
230  n.SetZero();
231  for(int j=0; j<3; ++j)
232  n += fi->V(j)->cN();
233  n.Normalize();
234  fi->N() = n;
235  }
236 }
237 
239 static void NormalizePerVertex(ComputeMeshType &m)
240 {
241  tri::RequirePerVertexNormal(m);
242  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
243  if( !(*vi).IsD() && (*vi).IsRW() )
244  (*vi).N().Normalize();
245 }
246 
248 static void NormalizePerFace(ComputeMeshType &m)
249 {
250  tri::RequirePerFaceNormal(m);
251  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
252  if( !(*fi).IsD() ) (*fi).N().Normalize();
253 }
254 
256 static void NormalizePerFaceByArea(ComputeMeshType &m)
257 {
258  tri::RequirePerFaceNormal(m);
259  FaceIterator fi;
260  for(fi=m.face.begin();fi!=m.face.end();++fi)
261  if( !(*fi).IsD() )
262  {
263  (*fi).N().Normalize();
264  (*fi).N() = (*fi).N() * DoubleArea(*fi);
265  }
266 }
267 
269 static void PerVertexNormalized(ComputeMeshType &m)
270 {
271  PerVertex(m);
273 }
274 
276 static void PerFaceNormalized(ComputeMeshType &m)
277 {
278  PerFace(m);
279  NormalizePerFace(m);
280 }
281 
283 static void PerPolygonalFaceNormalized(ComputeMeshType &m) {
284  PerPolygonalFace(m);
285  NormalizePerFace(m);
286 }
287 
289 static void PerVertexPerFace(ComputeMeshType &m)
290 {
291  PerFace(m);
292  PerVertex(m);
293 }
294 
296 static void PerVertexNormalizedPerFace(ComputeMeshType &m)
297 {
298  PerVertexPerFace(m);
300 }
301 
303 static void PerVertexNormalizedPerFaceNormalized(ComputeMeshType &m)
304 {
306  NormalizePerFace(m);
307 }
308 
310 static void PerBitQuadFaceNormalized(ComputeMeshType &m)
311 {
312  PerFace(m);
313  for(FaceIterator f=m.face.begin();f!=m.face.end();++f) {
314  if( !(*f).IsD() ) {
315  for (int k=0; k<3; k++) if (f->IsF(k))
316  if (&*f < f->FFp(k)) {
317  f->N() = f->FFp(k)->N() = (f->FFp(k)->N() + f->N()).Normalize();
318  }
319  }
320  }
321 }
322 
323 
325 static void PerBitPolygonFaceNormalized(ComputeMeshType &m)
326 {
327  PerFace(m);
328  tri::RequireCompactness(m);
329  tri::RequireTriangularMesh(m);
331  std::vector<VertexPointer> vertVec;
332  std::vector<FacePointer> faceVec;
333  for(size_t i=0;i<m.face.size();++i)
334  if(!m.face[i].IsV())
335  {
336  tri::PolygonSupport<MeshType,MeshType>::ExtractPolygon(&(m.face[i]),vertVec,faceVec);
337  CoordType nf(0,0,0);
338  for(size_t j=0;j<faceVec.size();++j)
339  nf+=faceVec[j]->N().Normalize() * DoubleArea(*faceVec[j]);
340 
341  nf.Normalize();
342 
343  for(size_t j=0;j<faceVec.size();++j)
344  faceVec[j]->N()=nf;
345  }
346 }
348 static void PerVertexMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
349 {
350  tri::RequirePerVertexNormal(m);
351  ScalarType scale;
352 
353  Matrix33<ScalarType> mat33(mat,3);
354 
355 
356  if(remove_scaling){
357  scale = pow(mat33.Determinant(),(ScalarType)(1.0/3.0));
358  Point3<ScalarType> scaleV(scale,scale,scale);
359  Matrix33<ScalarType> S;
360  S.SetDiagonal(scaleV.V());
361  mat33*=S;
362  }
363 
364  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
365  if( !(*vi).IsD() && (*vi).IsRW() )
366  (*vi).N() = mat33*(*vi).N();
367 }
368 
370 static void PerFaceMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
371 {
372  tri::RequirePerFaceNormal(m);
373  ScalarType scale;
374 
375  Matrix33<ScalarType> mat33(mat,3);
376 
377  if( !HasPerFaceNormal(m)) return;
378 
379  if(remove_scaling){
380  scale = pow(mat33.Determinant(),ScalarType(1.0/3.0));
381  mat33[0][0]/=scale;
382  mat33[1][1]/=scale;
383  mat33[2][2]/=scale;
384  }
385 
386  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
387  if( !(*fi).IsD() && (*fi).IsRW() )
388  (*fi).N() = mat33* (*fi).N();
389 }
390 
395 static void PerWedgeCrease(ComputeMeshType &m, ScalarType angleRad)
396 {
397  tri::RequirePerFaceWedgeNormal(m);
398  tri::RequireFFAdjacency(m);
399 
400  ScalarType cosangle=math::Cos(angleRad);
401 
402  // Clear the per wedge normals
403  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
404  {
405  (*fi).WN(0)=NormalType(0,0,0);
406  (*fi).WN(1)=NormalType(0,0,0);
407  (*fi).WN(2)=NormalType(0,0,0);
408  }
409 
410  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
411  {
412  NormalType nn= TriangleNormal(*fi);
413  for(int i=0;i<3;++i)
414  {
415  const NormalType &na=TriangleNormal(*(*fi).FFp(i));
416  if(nn*na > cosangle )
417  {
418  fi->WN((i+0)%3) +=na;
419  fi->WN((i+1)%3) +=na;
420  }
421  }
422  }
423 }
424 
425 
426 static void PerFaceRW(ComputeMeshType &m, bool normalize=false)
427 {
428  tri::RequirePerFaceNormal(m);
429  FaceIterator f;
430  bool cn = true;
431 
432  if(normalize)
433  {
434  for(f=m.m.face.begin();f!=m.m.face.end();++f)
435  if( !(*f).IsD() && (*f).IsRW() )
436  {
437  for(int j=0; j<3; ++j)
438  if( !(*f).V(j)->IsR()) cn = false;
439  if( cn ) f->N() = TriangleNormal(*f).Normalize();
440  cn = true;
441  }
442  }
443  else
444  {
445  for(f=m.m.face.begin();f!=m.m.face.end();++f)
446  if( !(*f).IsD() && (*f).IsRW() )
447  {
448  for(int j=0; j<3; ++j)
449  if( !(*f).V(j)->IsR()) cn = false;
450 
451  if( cn )
452  f->N() = TriangleNormal(*f).Normalize();
453  cn = true;
454  }
455  }
456 }
457 
458 
459 }; // end class
460 
461 } // End namespace
462 } // End namespace
463 
464 #endif
Definition: point3.h:43
Management, updating and computation of per-vertex and per-face flags (like border flags).
Definition: flag.h:44
Management, updating and computation of per-vertex, per-face, and per-wedge normals.
Definition: normal.h:51
static void PerWedgeCrease(ComputeMeshType &m, ScalarType angleRad)
Compute per wedge normals taking into account the angle between adjacent faces.
Definition: normal.h:395
static void NormalizePerVertex(ComputeMeshType &m)
Normalize the length of the vertex normals.
Definition: normal.h:239
static void PerVertexAngleWeighted(ComputeMeshType &m)
Calculates the vertex normal as an angle weighted average. It does not need or exploit current face n...
Definition: normal.h:124
static void PerVertexMatrix(ComputeMeshType &m, const Matrix44< ScalarType > &mat, bool remove_scaling=true)
Multiply the vertex normals by the matrix passed. By default, the scale component is removed.
Definition: normal.h:348
static void PerBitQuadFaceNormalized(ComputeMeshType &m)
Exploit bitquads to compute a per-polygon face normal.
Definition: normal.h:310
static void PerVertexNelsonMaxWeighted(ComputeMeshType &m)
Calculates the vertex normal using the Max et al. weighting scheme. It does not need or exploit curre...
Definition: normal.h:150
static void PerFaceNormalized(ComputeMeshType &m)
Equivalent to PerFace() and NormalizePerFace()
Definition: normal.h:276
static void PerVertex(ComputeMeshType &m)
Calculates the vertex normal as the classic area weighted average. It does not need or exploit curren...
Definition: normal.h:91
static void PerVertexNormalized(ComputeMeshType &m)
Equivalent to PerVertex() and NormalizePerVertex()
Definition: normal.h:269
static void PerFaceFromCurrentVertexNormal(ComputeMeshType &m)
Calculates the face normal by averaging the current per-vertex normals.
Definition: normal.h:222
static void PerVertexClear(ComputeMeshType &m, bool ClearAllVertNormal=false)
Set to zero all the PerVertex normals.
Definition: normal.h:69
static void PerVertexFromCurrentFaceNormal(ComputeMeshType &m)
Calculates the vertex normal by averaging the current per-face normals.
Definition: normal.h:199
static void PerBitPolygonFaceNormalized(ComputeMeshType &m)
Exploit bitquads to compute a per-polygon face normal.
Definition: normal.h:325
static void PerPolygonalFaceNormalized(ComputeMeshType &m)
Equivalent to PerPolygonalFace() and NormalizePerFace()
Definition: normal.h:283
static void PerVertexPerFace(ComputeMeshType &m)
Equivalent to PerVertex() and PerFace().
Definition: normal.h:289
static void PerFace(ComputeMeshType &m)
Calculates the face normal.
Definition: normal.h:171
static void PerVertexNormalizedPerFaceNormalized(ComputeMeshType &m)
Equivalent to PerVertexNormalizedPerFace() and NormalizePerFace().
Definition: normal.h:303
static void PerPolygonalFace(ComputeMeshType &m)
computePerPolygonalFace computes the normal of each polygonal face.
Definition: normal.h:183
static void PerFaceMatrix(ComputeMeshType &m, const Matrix44< ScalarType > &mat, bool remove_scaling=true)
Multiply the face normals by the matrix passed. By default, the scale component is removed.
Definition: normal.h:370
static void PerVertexNormalizedPerFace(ComputeMeshType &m)
Equivalent to PerVertexNormalized() and PerFace().
Definition: normal.h:296
static void NormalizePerFace(ComputeMeshType &m)
Normalize the length of the face normals.
Definition: normal.h:248
static void NormalizePerFaceByArea(ComputeMeshType &m)
Set the length of the face normals to their area (without recomputing their directions).
Definition: normal.h:256
Definition: namespaces.dox:6