normal.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 #ifndef __VCG_TRI_UPDATE_NORMALS
00025 #define __VCG_TRI_UPDATE_NORMALS
00026 
00027 #include <vcg/complex/algorithms/update/flag.h>
00028 #include <vcg/complex/algorithms/polygon_support.h>
00029 #include <vcg/math/matrix44.h>
00030 #include <vcg/complex/exception.h>
00031 
00032 namespace vcg {
00033 namespace tri {
00034 
00036 
00038 
00040 
00047 template <class ComputeMeshType>
00048 class   UpdateNormal
00049 {
00050 public:
00051 typedef ComputeMeshType MeshType;
00052 typedef typename MeshType::VertexType     VertexType;
00053 typedef typename MeshType::CoordType     CoordType;
00054 typedef typename VertexType::NormalType     NormalType;
00055 typedef typename VertexType::ScalarType ScalarType;
00056 typedef typename MeshType::VertexPointer  VertexPointer;
00057 typedef typename MeshType::VertexIterator VertexIterator;
00058 typedef typename MeshType::FaceType       FaceType;
00059 typedef typename MeshType::FacePointer    FacePointer;
00060 typedef typename MeshType::FaceIterator   FaceIterator;
00061 
00063 
00067 static void PerVertexClear(ComputeMeshType &m, bool ClearAllVertNormal=false)
00068 {
00069   RequirePerVertexNormal(m);
00070   if(ClearAllVertNormal)
00071     UpdateFlags<ComputeMeshType>::VertexClearV(m);
00072   else
00073   {
00074     UpdateFlags<ComputeMeshType>::VertexSetV(m);
00075     for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
00076      if( !(*f).IsD() )
00077        for(int i=0;i<3;++i) (*f).V(i)->ClearV();
00078    }
00079   VertexIterator vi;
00080   for(vi=m.vert.begin();vi!=m.vert.end();++vi)
00081      if( !(*vi).IsD() && (*vi).IsRW() && (!(*vi).IsV()) )
00082          (*vi).N() = NormalType((ScalarType)0,(ScalarType)0,(ScalarType)0);
00083 }
00084 
00086 
00089 static void PerVertex(ComputeMeshType &m)
00090 {
00091  PerVertexClear(m);
00092  for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
00093    if( !(*f).IsD() && (*f).IsR() )
00094    {
00095     typename FaceType::NormalType t = vcg::TriangleNormal(*f);
00096 
00097     for(int j=0; j<(*f).VN(); ++j)
00098      if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() )
00099       (*f).V(j)->N() += t;
00100    }
00101 }
00102 
00103 static void PerFacePolygonal(ComputeMeshType &m)
00104 {
00105 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00106 {
00107   if( !(*fi).IsD() )
00108     fi->N() = PolygonNormal(*fi).Normalize();
00109 }
00110 }
00111 
00113 
00121  static void PerVertexAngleWeighted(ComputeMeshType &m)
00122 {
00123   PerVertexClear(m);
00124   FaceIterator f;
00125   for(f=m.face.begin();f!=m.face.end();++f)
00126    if( !(*f).IsD() && (*f).IsR() )
00127    {
00128         NormalType t = TriangleNormal(*f).Normalize();
00129         NormalType e0 = ((*f).V1(0)->cP()-(*f).V0(0)->cP()).Normalize();
00130         NormalType e1 = ((*f).V1(1)->cP()-(*f).V0(1)->cP()).Normalize();
00131         NormalType e2 = ((*f).V1(2)->cP()-(*f).V0(2)->cP()).Normalize();
00132 
00133         (*f).V(0)->N() += t*AngleN(e0,-e2);
00134         (*f).V(1)->N() += t*AngleN(-e0,e1);
00135         (*f).V(2)->N() += t*AngleN(-e1,e2);
00136    }
00137 }
00138 
00140 
00147 static void PerVertexNelsonMaxWeighted(ComputeMeshType &m)
00148 {
00149  PerVertexClear(m);
00150  FaceIterator f;
00151  for(f=m.face.begin();f!=m.face.end();++f)
00152    if( !(*f).IsD() && (*f).IsR() )
00153    {
00154     typename FaceType::NormalType t = TriangleNormal(*f);
00155         ScalarType e0 = SquaredDistance((*f).V0(0)->cP(),(*f).V1(0)->cP());
00156         ScalarType e1 = SquaredDistance((*f).V0(1)->cP(),(*f).V1(1)->cP());
00157         ScalarType e2 = SquaredDistance((*f).V0(2)->cP(),(*f).V1(2)->cP());
00158 
00159         (*f).V(0)->N() += t/(e0*e2);
00160         (*f).V(1)->N() += t/(e0*e1);
00161         (*f).V(2)->N() += t/(e1*e2);
00162    }
00163 }
00164 
00168 static void PerFace(ComputeMeshType &m)
00169 {
00170   RequirePerFaceNormal(m);
00171   for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
00172     if( !(*f).IsD() )
00173               f->N() = TriangleNormal(*f).Normalize();
00174 }
00175 
00176 
00180 static void PerPolygonalFace(ComputeMeshType &m) {
00181   tri::RequirePerFaceNormal(m);
00182   tri::RequirePolygonalMesh(m);
00183   for(FaceIterator fi = m.face.begin(); fi != m.face.end(); fi++)
00184     if (!fi->IsD()) {
00185       fi->N().SetZero();
00186       for (int i = 0; i < fi->VN(); i++)
00187         fi->N() += fi->V0(i)->P() ^ fi->V1(i)->P();
00188     }
00189 }
00190 
00191 
00193 
00196 static void PerVertexFromCurrentFaceNormal(ComputeMeshType &m)
00197 {
00198   tri::RequirePerVertexNormal(m);
00199 
00200  VertexIterator vi;
00201  for(vi=m.vert.begin();vi!=m.vert.end();++vi)
00202    if( !(*vi).IsD() && (*vi).IsRW() )
00203      (*vi).N()=CoordType(0,0,0);
00204 
00205  FaceIterator fi;
00206  for(fi=m.face.begin();fi!=m.face.end();++fi)
00207    if( !(*fi).IsD())
00208    {
00209     for(int j=0; j<(*fi).VN(); ++j)
00210             if( !(*fi).V(j)->IsD())
00211                     (*fi).V(j)->N() += (*fi).cN();
00212    }
00213 }
00214 
00216 
00219 static void PerFaceFromCurrentVertexNormal(ComputeMeshType &m)
00220 {
00221   tri::RequirePerVertexNormal(m);
00222   tri::RequirePerFaceNormal(m);
00223   for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
00224    if( !(*fi).IsD())
00225         {
00226         NormalType n;
00227         n.SetZero();
00228         for(int j=0; j<3; ++j)
00229             n += fi->V(j)->cN();
00230         n.Normalize();
00231         fi->N() = n;
00232     }
00233 }
00234 
00236 static void NormalizePerVertex(ComputeMeshType &m)
00237 {
00238   tri::RequirePerVertexNormal(m);
00239   for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00240         if( !(*vi).IsD() && (*vi).IsRW() )
00241             (*vi).N().Normalize();
00242 }
00243 
00245 static void NormalizePerFace(ComputeMeshType &m)
00246 {
00247   tri::RequirePerFaceNormal(m);
00248   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00249       if( !(*fi).IsD() )        (*fi).N().Normalize();
00250 }
00251 
00253 static void NormalizePerFaceByArea(ComputeMeshType &m)
00254 {
00255   tri::RequirePerFaceNormal(m);
00256   FaceIterator fi;
00257   for(fi=m.face.begin();fi!=m.face.end();++fi)
00258     if( !(*fi).IsD() )
00259             {
00260                 (*fi).N().Normalize();
00261                 (*fi).N() = (*fi).N() * DoubleArea(*fi);
00262             }
00263 }
00264 
00266 static void PerVertexNormalized(ComputeMeshType &m)
00267 {
00268   PerVertex(m);
00269   NormalizePerVertex(m);
00270 }
00271 
00273 static void PerFaceNormalized(ComputeMeshType &m)
00274 {
00275   PerFace(m);
00276   NormalizePerFace(m);
00277 }
00278 
00280 static void PerPolygonalFaceNormalized(ComputeMeshType &m) {
00281   PerPolygonalFace(m);
00282   NormalizePerFace(m);
00283 }
00284 
00286 static void PerVertexPerFace(ComputeMeshType &m)
00287 {
00288  PerFace(m);
00289  PerVertex(m);
00290 }
00291 
00293 static void PerVertexNormalizedPerFace(ComputeMeshType &m)
00294 {
00295     PerVertexPerFace(m);
00296     NormalizePerVertex(m);
00297 }
00298 
00300 static void PerVertexNormalizedPerFaceNormalized(ComputeMeshType &m)
00301 {
00302     PerVertexNormalizedPerFace(m);
00303     NormalizePerFace(m);
00304 }
00305 
00307 static void PerBitQuadFaceNormalized(ComputeMeshType &m)
00308 {
00309     PerFace(m);
00310     for(FaceIterator f=m.face.begin();f!=m.face.end();++f) {
00311       if( !(*f).IsD() ) {
00312         for (int k=0; k<3; k++) if (f->IsF(k))
00313         if (&*f < f->FFp(k)) {
00314           f->N() = f->FFp(k)->N() = (f->FFp(k)->N() + f->N()).Normalize();
00315         }
00316       }
00317   }
00318 }
00319 
00320 
00322 static void PerBitPolygonFaceNormalized(ComputeMeshType &m)
00323 {
00324   PerFace(m);
00325   tri::RequireCompactness(m);
00326   tri::RequireTriangularMesh(m);
00327   tri::UpdateFlags<ComputeMeshType>::FaceClearV(m);
00328   std::vector<VertexPointer> vertVec;
00329   std::vector<FacePointer> faceVec;
00330   for(size_t i=0;i<m.face.size();++i)
00331     if(!m.face[i].IsV())
00332     {
00333       tri::PolygonSupport<MeshType,MeshType>::ExtractPolygon(&(m.face[i]),vertVec,faceVec);
00334       CoordType nf(0,0,0);
00335       for(size_t j=0;j<faceVec.size();++j)
00336         nf+=faceVec[j]->N().Normalize() * DoubleArea(*faceVec[j]);
00337 
00338       nf.Normalize();
00339 
00340       for(size_t j=0;j<faceVec.size();++j)
00341         faceVec[j]->N()=nf;
00342     }
00343 }
00345 static void PerVertexMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
00346 {
00347   tri::RequirePerVertexNormal(m);
00348     float scale;
00349 
00350     Matrix33<ScalarType> mat33(mat,3);
00351 
00352 
00353     if(remove_scaling){
00354         scale = pow(mat33.Determinant(),(ScalarType)(1.0/3.0));
00355         Point3<ScalarType> scaleV(scale,scale,scale);
00356         Matrix33<ScalarType> S;
00357         S.SetDiagonal(scaleV.V());
00358         mat33*=S;
00359     }
00360 
00361   for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00362    if( !(*vi).IsD() && (*vi).IsRW() )
00363      (*vi).N()  = mat33*(*vi).N();
00364 }
00365 
00367 static void PerFaceMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
00368 {
00369   tri::RequirePerFaceNormal(m);
00370   float scale;
00371 
00372     Matrix33<ScalarType> mat33(mat,3);
00373 
00374     if( !HasPerFaceNormal(m)) return;
00375 
00376     if(remove_scaling){
00377         scale = pow(mat33.Determinant(),ScalarType(1.0/3.0));
00378         mat33[0][0]/=scale;
00379         mat33[1][1]/=scale;
00380         mat33[2][2]/=scale;
00381     }
00382 
00383   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00384    if( !(*fi).IsD() && (*fi).IsRW() )
00385      (*fi).N() = mat33* (*fi).N();
00386 }
00387 
00392 static void PerWedgeCrease(ComputeMeshType &m, ScalarType angleRad)
00393 {
00394   tri::RequirePerFaceWedgeNormal(m);
00395   tri::RequireFFAdjacency(m);
00396 
00397   ScalarType cosangle=math::Cos(angleRad);
00398 
00399   // Clear the per wedge normals
00400   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
00401   {
00402     (*fi).WN(0)=NormalType(0,0,0);
00403     (*fi).WN(1)=NormalType(0,0,0);
00404     (*fi).WN(2)=NormalType(0,0,0);
00405   }
00406 
00407   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)              if(!(*fi).IsD())
00408   {
00409     NormalType nn= TriangleNormal(*fi);
00410     for(int i=0;i<3;++i)
00411     {
00412       const NormalType &na=TriangleNormal(*(*fi).FFp(i));
00413       if(nn*na > cosangle )
00414       {
00415         fi->WN((i+0)%3) +=na;
00416         fi->WN((i+1)%3) +=na;
00417       }
00418     }
00419   }
00420 }
00421 
00422 
00423 static void PerFaceRW(ComputeMeshType &m, bool normalize=false)
00424 {
00425   tri::RequirePerFaceNormal(m);
00426     FaceIterator f;
00427     bool cn = true;
00428 
00429     if(normalize)
00430     {
00431         for(f=m.m.face.begin();f!=m.m.face.end();++f)
00432         if( !(*f).IsD() && (*f).IsRW() )
00433         {
00434             for(int j=0; j<3; ++j)
00435                 if( !(*f).V(j)->IsR())  cn = false;
00436       if( cn )     f->N() = TriangleNormal(*f).Normalize();
00437             cn = true;
00438         }
00439     }
00440     else
00441     {
00442         for(f=m.m.face.begin();f!=m.m.face.end();++f)
00443             if( !(*f).IsD() && (*f).IsRW() )
00444             {
00445                 for(int j=0; j<3; ++j)
00446                     if( !(*f).V(j)->IsR())      cn = false;
00447 
00448                 if( cn )
00449                   f->N() = TriangleNormal(*f).Normalize();
00450                 cn = true;
00451             }
00452     }
00453 }
00454 
00455 
00456 }; // end class
00457 
00458 }       // End namespace
00459 }       // End namespace
00460 
00461 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:33:31