From 5c0b925ef86dd4cbae926f5036a525a7224a1798 Mon Sep 17 00:00:00 2001 From: cignoni Date: Fri, 5 Mar 2004 10:59:24 +0000 Subject: [PATCH] Changed name from plural to singular (normals->normal) --- vcg/complex/trimesh/update/color.h | 232 ++++++++++++++++++++++++++++ vcg/complex/trimesh/update/flag.h | 137 ++++++++++++++++ vcg/complex/trimesh/update/normal.h | 182 ++++++++++++++++++++++ 3 files changed, 551 insertions(+) create mode 100644 vcg/complex/trimesh/update/color.h create mode 100644 vcg/complex/trimesh/update/flag.h create mode 100644 vcg/complex/trimesh/update/normal.h diff --git a/vcg/complex/trimesh/update/color.h b/vcg/complex/trimesh/update/color.h new file mode 100644 index 00000000..6e39365c --- /dev/null +++ b/vcg/complex/trimesh/update/color.h @@ -0,0 +1,232 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ + +****************************************************************************/ +#ifndef __VCG_TRI_UPDATE_COLOR +#define __VCG_TRI_UPDATE_COLOR + +namespace vcg { +namespace tri { + +template +class UpdateColor +{ +public: +typedef UpdateMeshType MeshType; +typedef typename MeshType::VertexType VertexType; +typedef typename MeshType::VertexPointer VertexPointer; +typedef typename MeshType::VertexIterator VertexIterator; +typedef typename MeshType::FaceType FaceType; +typedef typename MeshType::FacePointer FacePointer; +typedef typename MeshType::FaceIterator FaceIterator; + +static void VertexBorderFlag(MeshType &m, Color4b vb=Color4b::Blue) +{ + MeshType::VertexIterator vi; + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) + (*vi).C()=Color4b::White; + + MeshType::FaceIterator fi; + for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + for(int j=0;j<3;++j) + if((*fi).IsB(j)){ + (*fi).V(j)->C() = vb; + (*fi).V1(j)->C() = vb; + (*fi).C() = vb; + } +} + +static void FaceBF(MeshType &m, Color4b vn=Color4b::White, Color4b vb=Color4b::Blue, + Color4b vc=Color4b::Red, Color4b vs=Color4b::LightBlue) +{ + MeshType::FaceIterator fi; + for(fi=m.face.begin();fi!=m.face.end();++fi) + if(!(*fi).IsD()) + (*fi).C() = vn; + + for(fi=m.face.begin();fi!=m.face.end();++fi) + if(!(*fi).IsD()) + { + if((*fi).IsS()) + (*fi).C() = vs; + else + { + for(int j=0;j<3;++j) + if((*fi).IsManifold(j)){ + if((*fi).IsB(j)){ + (*fi).C() = vb; + (*fi).C() = vb; + } + } + else + { + (*fi).C() = vc; + (*fi).C() = vc; + } + } + } +} + + +static int FaceSelected(MeshType &m, Color4b vs=Color4b::LightBlue) +{ + int cnt=0; + MeshType::FaceIterator fi; + for(fi=m.face.begin();fi!=m.face.end();++fi) + if(!(*fi).IsD()) + if((*fi).IsS()) { (*fi).C() = vs; ++cnt; } + else (*fi).C() = Color4b::White; + return cnt; +} + +static void FaceColorStrip(MeshType &m, std::vector &TStripF) +{ + Color4b::Color4b cc[7]={Color4b::White ,Color4b::Red ,Color4b::Green ,Color4b::Blue ,Color4b::Cyan ,Color4b::Yellow ,Color4b::Magenta}; + int cnt=0; + + vector::iterator fi; + for(fi=TStripF.begin();fi!=TStripF.end();++fi) + if(*fi) (**fi).C().ColorRamp(0,16,cnt); + else cnt=(cnt+1)%16; + // if(*fi) (**fi).C()=cc[cnt]; + // else cnt=(cnt+1)%7; + +} + + +static int VertexSelected(MeshType &m, Color4b vs=Color4b::LightBlue) +{ + int cnt=0; + MeshType::VertexIterator vi; + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) + if((*vi).IsS()) {(*vi).C() = vs; ++cnt; } + else (*vi).C() = Color4b::White; + + return cnt; +} + +static void VertexBorderManifoldFlag(MeshType &m, Color4b vn=Color4b::White, Color4b vb=Color4b::Blue, Color4b vc=Color4b::Red) +{ + MeshType::VertexIterator vi; + for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).C()=vn; + + MeshType::FaceIterator fi; + for(fi=m.face.begin();fi!=m.face.end();++fi) + if(!(*fi).IsD()) + for(int j=0;j<3;++j) + if((*fi).IsManifold(j)){ + if((*fi).IsB(j)){ + (*fi).V(j)->C()=vb; + (*fi).V1(j)->C()=vb; + } + } + else + { + (*fi).V(j)->C()=vc; + (*fi).V1(j)->C()=vc; + } +} + + + +static void FaceQuality(MeshType &m) +{ + // step 1: find the range + MeshType::FaceIterator fi; + float minq=m.face[0].Q(), + maxq=m.face[0].Q(); + for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + if(!(*fi).IsD()) + { + minq=min(minq,(*fi).Q()); + maxq=max(maxq,(*fi).Q()); + } + + FaceQuality(m,minq,maxq); +} + +static void FaceQuality(MeshType &m, float minq, float maxq) +{ + MeshType::FaceIterator fi; + + for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + (*fi).C().ColorRamp(minq,maxq,(*fi).Q()); +} + +static void VertexQuality(MeshType &m, float minq, float maxq) +{ + MeshType::VertexIterator vi; + + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) + (*vi).C().ColorRamp(minq,maxq,(*vi).Q()); +} + +static void VertexQuality(MeshType &m) +{ + // step 1: find the range + MeshType::VertexIterator vi; + float minq=MaxVal(0.0f), + maxq=-MaxVal(0.0f); + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) + { + minq=min(minq,(*vi).Q()); + maxq=max(maxq,(*vi).Q()); + } + VertexQuality(m,minq,maxq); +} + +static void VertexQualityHistEq(MeshType &m) +{ + // step 1: find the range + MeshType::VertexIterator vi; + float minq=MaxVal(0.0f), + maxq=-MaxVal(0.0f); + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) + { + minq=min(minq,(*vi).Q()); + maxq=max(maxq,(*vi).Q()); + } + // step 2; Get the distribution + Hist H; + H.SetRange(minq,maxq,1024); + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) H.Add((*vi).Q()); + + VertexQuality(m,H.Percentile(.05f),H.Percentile(.95f)); +} + +}; + +}// end namespace +}// end namespace +#endif \ No newline at end of file diff --git a/vcg/complex/trimesh/update/flag.h b/vcg/complex/trimesh/update/flag.h new file mode 100644 index 00000000..bfbc5be3 --- /dev/null +++ b/vcg/complex/trimesh/update/flag.h @@ -0,0 +1,137 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.1 2004/03/04 00:37:56 cignoni +First working version! + + +****************************************************************************/ +#ifndef __VCG_TRI_UPDATE_FLAGS +#define __VCG_TRI_UPDATE_FLAGS + +namespace vcg { +namespace tri { + +template +class UpdateFlags +{ + +public: +typedef UpdateMeshType MeshType; +typedef typename MeshType::VertexType VertexType; +typedef typename MeshType::VertexPointer VertexPointer; +typedef typename MeshType::VertexIterator VertexIterator; +typedef typename MeshType::FaceType FaceType; +typedef typename MeshType::FacePointer FacePointer; +typedef typename MeshType::FaceIterator FaceIterator; + + +static void FaceBorderFromFF(MeshType &m) +{ + const int BORDERFLAG[3]={FaceType::BORDER0,FaceType::BORDER1,FaceType::BORDER2}; + FaceIterator fi; + for(fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD()) + for(int j=0;j<3;++j) + { + //if(!(*fi).IsManifold(j)) (*fi).SetCF(j); + //else + if((*fi).IsBorder(j)) (*fi).SetB(j); + else (*fi).ClearB(j); + } +} + +// versione minimale che non calcola i complex flag. +void FaceBorderFromNone() +{ + typedef PEdge MPEDGE; + vector e; + face_iterator pf; + vector::iterator p; + + if( fn == 0 ) return; + + e.resize(fn*3); // Alloco il vettore ausiliario + p = e.begin(); + for(pf=face.begin();pf!=face.end();++pf) // Lo riempio con i dati delle facce + if( ! (*pf).IsDeleted() ) + for(int j=0;j<3;++j) + { + (*p).Set(&(*pf),j); + (*pf).ClearB(j); + ++p; + } + assert(p==e.end()); + sort(e.begin(), e.end()); // Lo ordino per vertici + + vector::iterator pe,ps; + for(ps = e.begin(), pe=e.begin(); pe<=e.end(); ++pe) // Scansione vettore ausiliario + { + if( pe==e.end() || *pe != *ps ) // Trovo blocco di edge uguali + { + if(pe-ps==1) { + //++nborder; + ps->f->SetB(ps->z); + } else + if(pe-ps!=2) { // Caso complex!! + for(;ps!=pe;++ps) + ps->f->SetB(ps->z); // Si settano border anche i complex. + } + ps = pe; +// ++ne; // Aggiorno il numero di edge + } + } +// TRACE("found %i border (%i complex) on %i edges\n",nborder,ncomplex,ne); + +} + + /// Bisogna carlcolare il border flag delle facce +void VertexBorderFromFace() +{ + vertex_iterator v; + face_iterator f; + + for(v=vert.begin();v!=vert.end();++v) + (*v).ClearB(); + + for(f=face.begin();f!=face.end();++f) + { + for(int z=0;z<3;++z) + if( (*f).IsB(z) ) + { + (*f).V0(z)->SetB(); + (*f).V1(z)->SetB(); + } + } +} + + +}; // end class + +} // End namespace +} // End namespace + + +#endif diff --git a/vcg/complex/trimesh/update/normal.h b/vcg/complex/trimesh/update/normal.h new file mode 100644 index 00000000..47738efd --- /dev/null +++ b/vcg/complex/trimesh/update/normal.h @@ -0,0 +1,182 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.1 2004/03/04 00:05:50 cignoni +First working version! + +Revision 1.1 2004/02/19 13:11:06 cignoni +Initial commit + + +****************************************************************************/ +#ifndef __VCG_TRI_UPDATE_NORMALS +#define __VCG_TRI_UPDATE_NORMALS + +namespace vcg { +namespace tri { +/// Management of updating and computation of per vertex and per face normals +template +class UpdateNormals +{ + +public: +typedef ComputeMeshType MeshType; +typedef typename MeshType::VertexType VertexType; +typedef typename MeshType::VertexPointer VertexPointer; +typedef typename MeshType::VertexIterator VertexIterator; +typedef typename MeshType::FaceType FaceType; +typedef typename MeshType::FacePointer FacePointer; +typedef typename MeshType::FaceIterator FaceIterator; + +/// Calculates the vertex normal (if stored in the current face type) +static void PerFace(ComputeMeshType &m) +{ + if( !m.HasPerFaceNormal()) return; + FaceIterator f; + for(f=m.face.begin();f!=m.face.end();++f) + if( !(*f).IsD() ) (*f).ComputeNormal(); +} + + +/// Calculates the vertex normal. Without exploiting or touching face normals +/// The normal of a vertex v is the weigthed average of the normals of the faces incident on v. +static void PerVertex(ComputeMeshType &m) +{ + if( !m.HasPerVertexNormal()) return; + + VertexIterator vi; + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if( !(*vi).IsD() && (*vi).IsRW() ) + (*vi).N() = VertexType::NormalType(0,0,0); + + FaceIterator f; + + for(f=m.face.begin();f!=m.face.end();++f) + if( !(*f).IsD() && (*f).IsR() ) + { + FaceType::NormalType t = (*f).Normal(); + + for(int j=0; j<3; ++j) + if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() ) + (*f).V(j)->N() += t; + } +} + +/// Calculates both vertex and face normals. +/// The normal of a vertex v is the weigthed average of the normals of the faces incident on v. +static void PerVertexPerFace(ComputeMeshType &m) +{ + if( !m.HasPerVertexNormal() || !m.HasPerFaceNormal()) return; + + PerFace(m); + VertexIterator vi; + for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if( !(*vi).IsD() && (*vi).IsRW() ) + (*vi).N() = VertexType::NormalType(0,0,0); + + FaceIterator f; + + for(f=m.face.begin();f!=m.face.end();++f) + if( !(*f).IsD() && (*f).IsR() ) + { + for(int j=0; j<3; ++j) + if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() ) + (*f).V(j)->N() += (*f).cN(); + } +} + + +static void PerFaceRW(ComputeMeshType &m, bool normalize=false) +{ + if( !m.HasPerFaceNormal()) return; + + FaceIterator f; + bool cn = true; + + if(normalize) + { + for(f=m.m.face.begin();f!=m.m.face.end();++f) + if( !(*f).IsD() && (*f).IsRW() ) + { + for(int j=0; j<3); ++j) + if( !(*f).V(j)->IsR()) cn = false; + if( cn ) (*f).ComputeNormalizedNormal(); + cn = true; + } + } + else + { + for(f=m.m.face.begin();f!=m.m.face.end();++f) + if( !(*f).IsD() && (*f).IsRW() ) + { + for(int j=0; j<3; ++j) + if( !(*f).V(j)->IsR()) cn = false; + + if( cn ) + (*f).ComputeNormal(); + cn = true; + } + } +} + + +static void PerFaceNormalized(ComputeMeshType &m) +{ + if( !m.HasPerFaceNormal()) return; + FaceIterator f; + for(f=m.face.begin();f!=m.face.end();++f) + if( !(*f).IsD() ) (*f).ComputeNormalizedNormal(); +} + + +/// Calculates the vertex normal +static void PerVertexNormalized(ComputeMeshType &m) +{ + if( !m.HasPerVertexNormal()) return; + PerVertex(m); + for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) + if( !(*vi).IsD() && (*vi).IsRW() ) + (*vi).N().Normalize(); +} + + + + +void ComputeE() +{ + FaceIterator f; + + for(f = m.face.begin(); f!=m.face.end(); ++f) + (*f).ComputeE(); +} + +}; // end class + +} // End namespace +} // End namespace + + +#endif