Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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 };
00457
00458 }
00459 }
00460
00461 #endif