VCG Library
Loading...
Searching...
No Matches
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
34namespace vcg {
35namespace tri {
36
38
40
42
49template <class ComputeMeshType>
51{
52public:
53typedef ComputeMeshType MeshType;
54typedef typename MeshType::VertexType VertexType;
55typedef typename MeshType::CoordType CoordType;
56typedef typename VertexType::NormalType NormalType;
57typedef typename VertexType::ScalarType ScalarType;
58typedef typename MeshType::VertexPointer VertexPointer;
59typedef typename MeshType::VertexIterator VertexIterator;
60typedef typename MeshType::FaceType FaceType;
61typedef typename MeshType::FacePointer FacePointer;
62typedef typename MeshType::FaceIterator FaceIterator;
63
65
69static 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
91static void PerVertex(ComputeMeshType &m)
92{
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
105static 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
124static void PerVertexAngleWeighted(ComputeMeshType &m)
125{
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
150static void PerVertexNelsonMaxWeighted(ComputeMeshType &m)
151{
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
171static 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
183static 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
199static 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
222static 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
239static 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
248static 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
256static 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
269static void PerVertexNormalized(ComputeMeshType &m)
270{
271 PerVertex(m);
273}
274
276static void PerFaceNormalized(ComputeMeshType &m)
277{
278 PerFace(m);
280}
281
283static void PerPolygonalFaceNormalized(ComputeMeshType &m) {
286}
287
289static void PerVertexPerFace(ComputeMeshType &m)
290{
291 PerFace(m);
292 PerVertex(m);
293}
294
296static void PerVertexNormalizedPerFace(ComputeMeshType &m)
297{
300}
301
303static void PerVertexNormalizedPerFaceNormalized(ComputeMeshType &m)
304{
307}
308
310static 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
325static 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}
348static 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
370static 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
395static 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
426static 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: color4.h:30