stat.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) 2006                                                \/)\/    *
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 __VCGLIB_TRIMESH_STAT
00025 #define __VCGLIB_TRIMESH_STAT
00026 
00027 // Standard headers
00028 // VCG headers
00029 
00030 #include <vcg/math/histogram.h>
00031 #include <vcg/simplex/face/pos.h>
00032 #include <vcg/simplex/face/topology.h>
00033 #include <vcg/complex/algorithms/closest.h>
00034 #include <vcg/space/index/grid_static_ptr.h>
00035 #include <vcg/complex/algorithms/update/topology.h>
00036 #include <vcg/complex/algorithms/inertia.h>
00037 
00038 
00039 namespace vcg {
00040 namespace tri{
00041 template <class StatMeshType>
00042 class Stat
00043 {
00044 public:
00045   typedef StatMeshType MeshType;
00046   typedef typename MeshType::VertexType     VertexType;
00047   typedef typename MeshType::VertexPointer  VertexPointer;
00048   typedef typename MeshType::VertexIterator VertexIterator;
00049   typedef typename MeshType::ScalarType                 ScalarType;
00050   typedef typename MeshType::FaceType       FaceType;
00051   typedef typename MeshType::FacePointer    FacePointer;
00052   typedef typename MeshType::FaceIterator   FaceIterator;
00053   typedef typename MeshType::EdgeIterator   EdgeIterator;
00054   typedef typename MeshType::FaceContainer  FaceContainer;
00055   typedef typename vcg::Box3<ScalarType>  Box3Type;
00056 
00057   static void ComputePerVertexQualityMinMax( MeshType & m, float &minV, float &maxV)
00058   {
00059     std::pair<float,float> pp=ComputePerVertexQualityMinMax(m);
00060     minV=pp.first; maxV=pp.second;
00061   }
00062   static std::pair<float,float> ComputePerVertexQualityMinMax( MeshType & m)
00063   {
00064 //    assert(0);
00065     tri::RequirePerVertexQuality(m);
00066     typename MeshType::template PerMeshAttributeHandle  < std::pair<float,float> > mmqH;
00067     mmqH = tri::Allocator<MeshType>::template GetPerMeshAttribute <std::pair<float,float> >(m,"minmaxQ");
00068 
00069     std::pair<float,float> minmax = std::make_pair(std::numeric_limits<float>::max(),-std::numeric_limits<float>::max());
00070 
00071     for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00072       if(!(*vi).IsD())
00073       {
00074         if( (*vi).Q() < minmax.first) minmax.first=(*vi).Q();
00075         if( (*vi).Q() > minmax.second) minmax.second=(*vi).Q();
00076       }
00077 
00078     mmqH() = minmax;
00079     return minmax;
00080   }
00081 
00082   static void ComputePerFaceQualityMinMax( MeshType & m, float &minV, float &maxV)
00083   {
00084     std::pair<float,float> pp=ComputePerFaceQualityMinMax(m);
00085     minV=pp.first; maxV=pp.second;
00086   }
00087 
00088   static std::pair<ScalarType,ScalarType> ComputePerFaceQualityMinMax( MeshType & m)
00089   {
00090     tri::RequirePerFaceQuality(m);
00091     std::pair<ScalarType,ScalarType> minmax = std::make_pair(std::numeric_limits<ScalarType>::max(),-std::numeric_limits<ScalarType>::max());
00092 
00093     FaceIterator fi;
00094     for(fi = m.face.begin(); fi != m.face.end(); ++fi)
00095       if(!(*fi).IsD())
00096       {
00097         if( (*fi).Q() < minmax.first)  minmax.first =(*fi).Q();
00098         if( (*fi).Q() > minmax.second) minmax.second=(*fi).Q();
00099       }
00100     return minmax;
00101   }
00102 
00103   static std::pair<ScalarType,ScalarType> ComputePerEdgeQualityMinMax( MeshType & m)
00104   {
00105     tri::RequirePerEdgeQuality(m);
00106     std::pair<ScalarType,ScalarType> minmax = std::make_pair(std::numeric_limits<ScalarType>::max(),-std::numeric_limits<ScalarType>::max());
00107 
00108     EdgeIterator ei;
00109     for(ei = m.edge.begin(); ei != m.edge.end(); ++ei)
00110       if(!(*ei).IsD())
00111       {
00112         if( (*ei).Q() < minmax.first)  minmax.first =(*ei).Q();
00113         if( (*ei).Q() > minmax.second) minmax.second=(*ei).Q();
00114       }
00115     return minmax;
00116   }
00117 
00122   static Point3<ScalarType> ComputeCloudBarycenter(MeshType & m, bool useQualityAsWeight=false)
00123   {
00124           if (useQualityAsWeight)
00125                 tri::RequirePerVertexQuality(m);
00126 
00127           Point3<ScalarType> barycenter(0, 0, 0);
00128           Point3d accumulator(0.0, 0.0, 0.0);
00129           double weightSum = 0;
00130           VertexIterator vi;
00131           for (vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00132           if (!(*vi).IsD())
00133           {
00134                   ScalarType weight = useQualityAsWeight ? (*vi).Q() : 1.0;
00135                   accumulator[0] += (double)((*vi).P()[0] * weight);
00136                   accumulator[1] += (double)((*vi).P()[1] * weight);
00137                   accumulator[2] += (double)((*vi).P()[2] * weight);
00138                   weightSum += weight;
00139           }
00140           barycenter[0] = (ScalarType)(accumulator[0] / weightSum);
00141           barycenter[1] = (ScalarType)(accumulator[1] / weightSum);
00142           barycenter[2] = (ScalarType)(accumulator[2] / weightSum);
00143           return barycenter;
00144   }
00145 
00152   static Point3<ScalarType> ComputeShellBarycenter(MeshType & m)
00153   {
00154     Point3<ScalarType> barycenter(0,0,0);
00155     ScalarType areaSum=0;
00156     FaceIterator fi;
00157     for(fi = m.face.begin(); fi != m.face.end(); ++fi)
00158       if(!(*fi).IsD())
00159       {
00160         ScalarType area=DoubleArea(*fi);
00161         barycenter += Barycenter(*fi)*area;
00162         areaSum+=area;
00163       }
00164     return barycenter/areaSum;
00165   }
00166 
00167   static ScalarType ComputeMeshVolume(MeshType & m)
00168   {
00169     Inertia<MeshType> I(m);
00170     return I.Mass();
00171   }
00172 
00173   static ScalarType ComputeMeshArea(MeshType & m)
00174   {
00175     ScalarType area=0;
00176 
00177     for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00178       if(!(*fi).IsD())
00179         area += DoubleArea(*fi);
00180 
00181     return area/ScalarType(2.0);
00182   }
00183 
00184   static void ComputePerVertexQualityDistribution( MeshType & m, Distribution<float> &h, bool selectionOnly = false)    // V1.0
00185   {
00186     tri::RequirePerVertexQuality(m);
00187     for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00188       if(!(*vi).IsD() &&  ((!selectionOnly) || (*vi).IsS()) )
00189       {
00190         assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)");
00191         h.Add((*vi).Q());
00192       }
00193   }
00194 
00195   static void ComputePerFaceQualityDistribution( MeshType & m,  Distribution<typename MeshType::ScalarType> &h,
00196                                                  bool selectionOnly = false)    // V1.0
00197   {
00198     tri::RequirePerFaceQuality(m);
00199     for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00200       if(!(*fi).IsD() &&  ((!selectionOnly) || (*fi).IsS()) )
00201       {
00202         assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)");
00203         h.Add((*fi).Q());
00204       }
00205   }
00206 
00207   static void ComputePerFaceQualityHistogram( MeshType & m, Histogramf &h, bool selectionOnly=false,int HistSize=10000 )
00208   {
00209     tri::RequirePerFaceQuality(m);
00210     std::pair<float,float> minmax = tri::Stat<MeshType>::ComputePerFaceQualityMinMax(m);
00211     h.Clear();
00212     h.SetRange( minmax.first,minmax.second, HistSize );
00213     for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00214       if(!(*fi).IsD() &&  ((!selectionOnly) || (*fi).IsS()) ){
00215         assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)");
00216         h.Add((*fi).Q());
00217       }
00218   }
00219 
00220   static void ComputePerVertexQualityHistogram( MeshType & m, Histogramf &h, bool selectionOnly = false, int HistSize=10000 )    // V1.0
00221   {
00222     tri::RequirePerVertexQuality(m);
00223     std::pair<float,float> minmax = ComputePerVertexQualityMinMax(m);
00224 
00225     h.Clear();
00226     h.SetRange( minmax.first,minmax.second, HistSize);
00227     for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00228       if(!(*vi).IsD() &&  ((!selectionOnly) || (*vi).IsS()) )
00229       {
00230         assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)");
00231         h.Add((*vi).Q());
00232       }
00233     // Sanity check; If some very wrong value has happened in the Q value,
00234     // the histogram is messed. If a significant percentage (20% )of the values are all in a single bin
00235     // we should try to solve the problem. No easy solution here.
00236     // We choose to compute the get the 1percentile and 99 percentile values as new mixmax ranges
00237     // and just to be sure enlarge the Histogram.
00238 
00239     if(h.MaxCount() > HistSize/5)
00240     {
00241       std::vector<float> QV;
00242       QV.reserve(m.vn);
00243       for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00244         if(!(*vi).IsD()) QV.push_back((*vi).Q());
00245 
00246       std::nth_element(QV.begin(),QV.begin()+m.vn/100,QV.end());
00247       float newmin=*(QV.begin()+m.vn/100);
00248       std::nth_element(QV.begin(),QV.begin()+m.vn-m.vn/100,QV.end());
00249       float newmax=*(QV.begin()+m.vn-m.vn/100);
00250 
00251       h.Clear();
00252       h.SetRange(newmin, newmax, HistSize*50);
00253       for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00254         if(!(*vi).IsD() && ((!selectionOnly) || (*vi).IsS()) )
00255           h.Add((*vi).Q());
00256     }
00257   }
00258 
00259   static void ComputeEdgeLengthHistogram( MeshType & m, Histogramf &h)
00260   {
00261     assert(m.edge.size()>0);
00262     h.Clear();
00263     h.SetRange( 0, m.bbox.Diag(), 10000);
00264     for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
00265     {
00266       if(!(*ei).IsD())
00267       {
00268         h.Add(Distance<float>((*ei).V(0)->P(),(*ei).V(1)->P()));
00269       }
00270     }
00271   }
00272 
00273   static ScalarType ComputeEdgeLengthAverage(MeshType & m)
00274   {
00275     Histogramf h;
00276     ComputeEdgeLengthHistogram(m,h);
00277     return h.Avg();
00278   }
00279 
00280   static void ComputeFaceEdgeLengthDistribution( MeshType & m, Distribution<float> &h, bool includeFauxEdge=false)
00281   {
00282     std::vector< typename tri::UpdateTopology<MeshType>::PEdge > edgeVec;
00283     tri::UpdateTopology<MeshType>::FillUniqueEdgeVector(m,edgeVec,includeFauxEdge);
00284     h.Clear();
00285     tri::UpdateFlags<MeshType>::FaceBorderFromNone(m);
00286     for(size_t i=0;i<edgeVec.size();++i)
00287       h.Add(Distance(edgeVec[i].v[0]->P(),edgeVec[i].v[1]->P()));
00288   }
00289 
00290   static ScalarType ComputeFaceEdgeLengthAverage(MeshType & m)
00291   {
00292     double sum=0;
00293     for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00294       if(!(*fi).IsD())
00295       {
00296         for(int i=0;i<3;++i)
00297           sum+=double(Distance(fi->P0(i),fi->P1(i)));
00298       }
00299     return sum/(m.fn*3.0);
00300   }
00301 
00302 }; // end class
00303 
00304 } //End Namespace tri
00305 } // End Namespace vcg
00306 
00307 #endif
00308 


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