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