27 #include <vcg/math/histogram.h> 
   29 #include <vcg/simplex/face/jumping_pos.h> 
   30 #include <vcg/complex/algorithms/update/normal.h> 
   31 #include <vcg/complex/algorithms/update/curvature.h> 
   32 #include <vcg/complex/algorithms/update/topology.h> 
   33 #include <vcg/complex/algorithms/update/bounding.h> 
   34 #include "vcg/complex/algorithms/update/curvature_fitting.h" 
   41 #include <vcg/complex/algorithms/nring.h> 
   43 #include <vcg/complex/algorithms/smooth.h> 
   45 namespace vcg { 
namespace tri {
 
   47 template<
class MeshType>
 
   52     typedef typename MeshType::FaceType   FaceType;
 
   53     typedef typename MeshType::VertexType VertexType;
 
   54     typedef typename MeshType::ScalarType ScalarType;
 
   55     typedef typename MeshType::FaceIterator FaceIterator;
 
   56     typedef typename MeshType::VertexIterator VertexIterator;
 
   57     typedef typename MeshType::CoordType CoordType;
 
   59     typedef vcg::tri::Nring<MeshType> RingWalker;
 
   71             if (input.size() != 16)
 
   96         double& a() { 
return data[0];}
 
   97         double& b() { 
return data[1];}
 
   98         double& c() { 
return data[2];}
 
   99         double& d() { 
return data[3];}
 
  100         double& e() { 
return data[4];}
 
  101         double& f() { 
return data[5];}
 
  102         double& g() { 
return data[6];}
 
  103         double& h() { 
return data[7];}
 
  104         double& i() { 
return data[8];}
 
  105         double& l() { 
return data[9];}
 
  106         double& m() { 
return data[10];}
 
  107         double& n() { 
return data[11];}
 
  108         double& o() { 
return data[12];}
 
  109         double& p() { 
return data[13];}
 
  110         double& q() { 
return data[14];}
 
  111         double& r() { 
return data[15];}
 
  115         double evaluate(
double u, 
double v)
 
  119                     a() * u*u*u * v*v*v    +
 
  138         double distanceRMS(std::vector<CoordType>& VV)
 
  141             for(
typename std::vector<CoordType>::iterator it = VV.begin(); it != VV.end(); ++it)
 
  147                 double temp = evaluate(u,v);
 
  148                 error += (n - temp)*(n - temp);
 
  150             error /= (double) VV.size();
 
  154         static Bicubic fit(std::vector<CoordType> VV)
 
  156             assert(VV.size() >= 16);
 
  157             Eigen::MatrixXf A(VV.size(),16);
 
  158             Eigen::MatrixXf b(VV.size(),1);
 
  159             Eigen::MatrixXf sol(16,1);
 
  161             for(
unsigned int c=0; c < VV.size(); ++c)
 
  163                 double u = VV[c].X();
 
  164                 double v = VV[c].Y();
 
  165                 double n = VV[c].Z();
 
  167                 A(c,0)  = u*u*u * v*v*v;
 
  168                 A(c,1)  = u*u*u * v*v;
 
  171                 A(c,4)  = u*u   * v*v*v;
 
  188             Eigen::JacobiSVD<Eigen::MatrixXd> svd(A);
 
  192             vector<double> r(16);
 
  194             for (
int i=0; i < 16; ++i)
 
  215         bool operator() (VertexType* v1, VertexType* v2)
 
  217             return (v1->P() - origin->P()).SquaredNorm() < (v2->P() - origin->P()).SquaredNorm();
 
  221     float getMeanCurvature(VertexType* vp)
 
  223         return (vp->K1() + vp->K2())/2.0;
 
  226     static bool fitBicubicPoints(VertexType* v, std::vector<CoordType>& ref, Bicubic& ret, std::vector<CoordType>& points, std::vector<VertexType*>& ring)
 
  230         if (ring.size() < 16)
 
  235         typename std::vector<VertexType*>::iterator b = ring.begin();
 
  236         typename std::vector<VertexType*>::iterator e = ring.end();
 
  240             CoordType vT = (*b)->P() - v->P();
 
  242             double x = vT * ref[0];
 
  243             double y = vT * ref[1];
 
  244             double z = vT * ref[2];
 
  246             points.push_back(CoordType(x,y,z));
 
  249         ret = Bicubic::fit(points);
 
  253     static double AverageEdgeLenght(MeshType& m)
 
  256       for (FaceIterator fi = m.face.begin();  fi!=m.face.end(); fi++) 
if (!fi->IsD()) {
 
  257         doubleA+=vcg::DoubleArea(*fi);
 
  259       int nquads = m.fn / 2;
 
  260       return sqrt( doubleA/(2*nquads) );
 
  263     static void computeMFitmap(MeshType& m, 
float perc, 
int ringMax = 50)
 
  275         RingWalker::clearFlags(&m);
 
  277         for(VertexIterator it=m.vert.begin(); it!=m.vert.end();++it)
 
  279             if ((countTemp++ % 100) == 0)
 
  280                 cerr << countTemp << 
"/" << m.vert.size() << endl;
 
  282             RingWalker rw(&*it,&m);
 
  284             CoordType nor = it->N();
 
  294                 for(
unsigned i=0; i<rw.lastF.size();++i)
 
  296                     CoordType vet1 = nor;
 
  297                     CoordType vet2 = rw.lastF[i]->N();
 
  303                     double scal = vet1 * vet2;
 
  305                         okfaces +=   (vcg::DoubleArea(*rw.lastF[i]));
 
  307                         flipfaces += (vcg::DoubleArea(*rw.lastF[i]));
 
  309             } 
while ((((flipfaces)/(okfaces + flipfaces))*100.0 < perc) && (count < ringMax));
 
  311             std::sort(rw.lastV.begin(),rw.lastV.end(),radSorter(&*it));
 
  313             it->Q() = ((*rw.lastV.begin())->P() - it->P()).Norm();
 
  318         vcg::tri::Smooth<MeshType>::VertexQualityLaplacian(m,2);
 
  321     static vector<VertexType*> gatherNeighsSurface(VertexType* vt, 
float sigma, MeshType& m)
 
  323         vector<VertexType*> current;
 
  325         RingWalker rw(vt,&m);
 
  335             for(
typename vector<VertexType*>::iterator it = rw.lastV.begin(); it != rw.lastV.end(); ++it)
 
  337                 if (((*it)->P() - vt->P()).Norm() < sigma)
 
  339                     current.push_back(*it);
 
  350     static void computeSFitmap(MeshType& m)
 
  364             double e = AverageEdgeLenght(m);
 
  368             for(VertexIterator it=m.vert.begin(); it!=m.vert.end();++it)
 
  370                 if ((countTemp++ % 100) == 0)
 
  371                     cerr << countTemp << 
"/" << m.vert.size() << endl;
 
  376                 for (
int iteration = 0; iteration<iteraz; ++iteration)
 
  378                     oneX.push_back((iteration+1)*(e));
 
  381                 std::vector<CoordType> ref(3);
 
  384                 ref[2] = it->PD1() ^ it->PD2();
 
  392                 RingWalker::clearFlags(&m);
 
  394                 std::vector<VertexType*> pointsGlobal = gatherNeighsSurface(&*it,oneX.at(iteraz-1),m);
 
  396                 vector<float> onedimensional;
 
  398                 for (
int iteration = 0; iteration<iteraz; ++iteration)
 
  400                     std::vector<VertexType*> points; 
 
  402                     std::vector<CoordType> projected; 
 
  403                     for (
typename std::vector<VertexType*>::iterator it2 = pointsGlobal.begin(); it2 != pointsGlobal.end(); ++it2)
 
  405                         if (((*it).P() - (*it2)->P()).Norm() < oneX.at(iteration))
 
  406                             points.push_back(*it2);
 
  409                     std::vector<VertexType*>& pointsFitting = points;
 
  412                     if (!fitBicubicPoints(&*it, ref, b, projected,pointsFitting))
 
  414                         onedimensional.push_back(0);
 
  418                         onedimensional.push_back(b.distanceRMS(projected));
 
  425                 Eigen::MatrixXf Am(onedimensional.size(),1);
 
  426                 Eigen::MatrixXf bm(onedimensional.size(),1);
 
  427                 Eigen::MatrixXf sol(1,1);
 
  429                 for(
unsigned int c=0; c < onedimensional.size(); ++c)
 
  431                     double x = oneX.at(c);
 
  434                     bm[c] = onedimensional[c];
 
  439                 Eigen::JacobiSVD<Eigen::MatrixXd> svd(Am);
 
  442                 it->Q() = pow((
double)sol[0],0.25);
 
  474             vcg::tri::Smooth<MeshType>::VertexQualityLaplacian(m,1);
 
Definition: fitmaps.h:205
 
static void Box(ComputeMeshType &m)
Calculates the bounding box of the given mesh m.
Definition: bounding.h:45
 
Computation of per-vertex directions and values of curvature.
Definition: curvature_fitting.h:62
 
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 VertexFace(MeshType &m)
Update the Vertex-Face topological relation.
Definition: topology.h:467
 
static void FaceFace(MeshType &m)
Update the Face-Face topological relation by allowing to retrieve for each face what other faces shar...
Definition: topology.h:395
 
Definition: namespaces.dox:6