DGtal  1.4.beta
PolygonalCalculus.h
1 
17 #pragma once
18 
31 // Inclusions
32 #include <iostream>
33 #include <functional>
34 #include <vector>
35 #include <string>
36 #include <map>
37 #include <unordered_map>
38 #include "DGtal/base/ConstAlias.h"
39 #include "DGtal/base/Common.h"
40 #include "DGtal/shapes/SurfaceMesh.h"
41 #include "DGtal/math/linalg/EigenSupport.h"
43 
44 namespace DGtal
45 {
46 
48 // template class PolygonalCalculus
69 template <typename TRealPoint, typename TRealVector>
71 {
72  // ----------------------- Standard services ------------------------------
73 public:
74 
76  static const Dimension dimension = TRealPoint::dimension;
78 
81 
85  typedef typename MySurfaceMesh::Vertex Vertex;
87  typedef typename MySurfaceMesh::Face Face;
92 
98  typedef Vector Form;
105 
108 
111 
117  bool globalInternalCacheEnabled = false):
118  mySurfaceMesh(&surf), myGlobalCacheEnabled(globalInternalCacheEnabled)
119  {
120  myEmbedder =[&](Face f,Vertex v){ (void)f; return mySurfaceMesh->position(v);};
122  init();
123  };
124 
132  const std::function<Real3dPoint(Face,Vertex)> &embedder,
133  bool globalInternalCacheEnabled = false):
134  mySurfaceMesh(&surf), myEmbedder(embedder), myGlobalCacheEnabled(globalInternalCacheEnabled)
135  {
137  init();
138  };
139 
147  const std::function<Real3dVector(Vertex)> &embedder,
148  bool globalInternalCacheEnabled = false):
149  mySurfaceMesh(&surf), myVertexNormalEmbedder(embedder),
150  myGlobalCacheEnabled(globalInternalCacheEnabled)
151  {
152  myEmbedder = [&](Face f,Vertex v){(void)f; return mySurfaceMesh->position(v); };
153  init();
154  };
155 
167  const std::function<Real3dPoint(Face,Vertex)> &pos_embedder,
168  const std::function<Vector(Vertex)> &normal_embedder,
169  bool globalInternalCacheEnabled = false) :
170  mySurfaceMesh(&surf), myEmbedder(pos_embedder),
171  myVertexNormalEmbedder(normal_embedder),
172  myGlobalCacheEnabled(globalInternalCacheEnabled)
173  {
174  init();
175  };
176 
180  PolygonalCalculus() = delete;
181 
185  ~PolygonalCalculus() = default;
186 
191  PolygonalCalculus ( const PolygonalCalculus & other ) = delete;
192 
197  PolygonalCalculus ( PolygonalCalculus && other ) = delete;
198 
204  PolygonalCalculus & operator= ( const PolygonalCalculus & other ) = delete;
205 
212 
214 
215  // ----------------------- embedding services --------------------------
216  //MARK: Embedding services
219 
222  void setEmbedder(const std::function<Real3dPoint(Face,Vertex)> &externalFunctor)
223  {
224  myEmbedder = externalFunctor;
225  }
226 
227 
228  // ----------------------- Per face operators --------------------------------------
229  //MARK: Per face operator on scalars
232 
236  DenseMatrix X(const Face f) const
237  {
238  if (checkCache(X_,f))
239  return myGlobalCache[X_][f];
240 
241  const auto vertices = mySurfaceMesh->incidentVertices(f);
242  const auto nf = myFaceDegree[f];
243  DenseMatrix Xt(nf,3);
244  size_t cpt=0;
245  for(auto v: vertices)
246  {
247  Xt(cpt,0) = myEmbedder(f,v)[0];
248  Xt(cpt,1) = myEmbedder(f,v)[1];
249  Xt(cpt,2) = myEmbedder(f,v)[2];
250  ++cpt;
251  }
252 
253  setInCache(X_,f,Xt);
254  return Xt;
255  }
256 
257 
261  DenseMatrix D(const Face f) const
262  {
263  if (checkCache(D_,f))
264  return myGlobalCache[D_][f];
265 
266  const auto nf = myFaceDegree[f];
267  DenseMatrix d = DenseMatrix::Zero(nf ,nf);
268  for(auto i=0u; i < nf; ++i)
269  {
270  d(i,i) = -1.;
271  d(i, (i+1)%nf) = 1.;
272  }
273 
274  setInCache(D_,f,d);
275  return d;
276  }
277 
281  DenseMatrix E(const Face f) const
282  {
283  if (checkCache(E_,f))
284  return myGlobalCache[E_][f];
285 
286  DenseMatrix op = D(f)*X(f);
287 
288  setInCache(E_,f,op);
289  return op;
290  }
291 
295  DenseMatrix A(const Face f) const
296  {
297  if (checkCache(A_,f))
298  return myGlobalCache[A_][f];
299 
300  const auto nf = myFaceDegree[f];
301  DenseMatrix a = DenseMatrix::Zero(nf ,nf);
302  for(auto i=0u; i < nf; ++i)
303  {
304  a(i, (i+1)%nf) = 0.5;
305  a(i,i) = 0.5;
306  }
307 
308  setInCache(A_,f,a);
309  return a;
310  }
311 
312 
316  Vector vectorArea(const Face f) const
317  {
318  Real3dPoint af(0.0,0.0,0.0);
319  const auto vertices = mySurfaceMesh->incidentVertices(f);
320  auto it = vertices.cbegin();
321  auto itnext = vertices.cbegin();
322  ++itnext;
323  while (it != vertices.cend())
324  {
325  auto xi = myEmbedder(f,*it);
326  auto xip = myEmbedder(f,*itnext);
327  af += xi.crossProduct(xip);
328  ++it;
329  ++itnext;
330  if (itnext == vertices.cend())
331  itnext = vertices.cbegin();
332  }
333  Eigen::Vector3d output = {af[0],af[1],af[2]};
334  return 0.5*output;
335  }
336 
340  double faceArea(const Face f) const
341  {
342  return vectorArea(f).norm();
343  }
344 
348  Vector faceNormal(const Face f) const
349  {
350  Vector v = vectorArea(f);
351  v.normalize();
352  return v;
353  }
354 
359  {
360  Vector v = faceNormal(f);
361  return {v(0),v(1),v(2)};
362  }
363 
367  DenseMatrix coGradient(const Face f) const
368  {
369  if (checkCache(COGRAD_,f))
370  return myGlobalCache[COGRAD_][f];
371  DenseMatrix op = E(f).transpose() * A(f);
372  setInCache(COGRAD_, f, op);
373  return op;
374  }
375 
378  DenseMatrix bracket(const Vector &n) const
379  {
380  DenseMatrix brack(3,3);
381  brack << 0.0 , -n(2), n(1),
382  n(2), 0.0 , -n(0),
383  -n(1) , n(0),0.0 ;
384  return brack;
385  }
386 
390  DenseMatrix gradient(const Face f) const
391  {
392  if (checkCache(GRAD_,f))
393  return myGlobalCache[GRAD_][f];
394 
395  DenseMatrix op = -1.0/faceArea(f) * bracket( faceNormal(f) ) * coGradient(f);
396 
397  setInCache(GRAD_,f,op);
398  return op;
399  }
400 
404  DenseMatrix flat(const Face f) const
405  {
406  if (checkCache(FLAT_,f))
407  return myGlobalCache[FLAT_][f];
408  DenseMatrix n = faceNormal(f);
409  DenseMatrix op = E(f)*( DenseMatrix::Identity(3,3) - n*n.transpose());
410  setInCache(FLAT_,f,op);
411  return op;
412  }
413 
417  DenseMatrix B(const Face f) const
418  {
419  if (checkCache(B_,f))
420  return myGlobalCache[B_][f];
421  DenseMatrix res = A(f) * X(f);
422  setInCache(B_,f,res);
423  return res;
424  }
425 
428  Vector centroid(const Face f) const
429  {
430  const auto nf = myFaceDegree[f];
431  return 1.0/(double)nf * X(f).transpose() * Vector::Ones(nf);
432  }
433 
437  {
438  const Vector c = centroid(f);
439  return {c(0),c(1),c(2)};
440  }
441 
445  DenseMatrix sharp(const Face f) const
446  {
447  if (checkCache(SHARP_,f))
448  return myGlobalCache[SHARP_][f];
449 
450  const auto nf = myFaceDegree[f];
451  DenseMatrix op = 1.0/faceArea(f) * bracket(faceNormal(f)) *
452  ( B(f).transpose() - centroid(f)* Vector::Ones(nf).transpose() );
453 
454  setInCache(SHARP_,f,op);
455  return op;
456  }
457 
461  DenseMatrix P(const Face f) const
462  {
463  if (checkCache(P_,f))
464  return myGlobalCache[P_][f];
465 
466  const auto nf = myFaceDegree[f];
467  DenseMatrix op = DenseMatrix::Identity(nf,nf) - flat(f)*sharp(f);
468 
469  setInCache(P_, f, op);
470  return op;
471  }
472 
477  DenseMatrix M(const Face f, const double lambda=1.0) const
478  {
479  if (checkCache(M_,f))
480  return myGlobalCache[M_][f];
481 
482  DenseMatrix Uf = sharp(f);
483  DenseMatrix Pf = P(f);
484  DenseMatrix op = faceArea(f) * Uf.transpose()*Uf + lambda * Pf.transpose()*Pf;
485 
486  setInCache(M_,f,op);
487  return op;
488  }
489 
504  DenseMatrix divergence(const Face f) const
505  {
506  if (checkCache(DIVERGENCE_,f))
507  return myGlobalCache[DIVERGENCE_][f];
508 
509  DenseMatrix op = -1.0 * D(f).transpose() * M(f);
510  setInCache(DIVERGENCE_,f,op);
511 
512  return op;
513  }
514 
518  DenseMatrix curl(const Face f) const
519  {
520  if (checkCache(CURL_,f))
521  return myGlobalCache[CURL_][f];
522 
523  DenseMatrix op = DenseMatrix::Identity(myFaceDegree[f],myFaceDegree[f]);
524 
525  setInCache(CURL_,f,op);
526  return op;
527  }
528 
529 
544  DenseMatrix laplaceBeltrami(const Face f, const double lambda=1.0) const
545  {
546  if (checkCache(L_,f))
547  return myGlobalCache[L_][f];
548 
549  DenseMatrix Df = D(f);
550  // Laplacian is a negative operator.
551  DenseMatrix op = -1.0 * Df.transpose() * M(f,lambda) * Df;
552 
553  setInCache(L_, f, op);
554  return op;
555  }
557 
558  // ----------------------- Vector calculus----------------------------------
559  //MARK: Vector Field Calculus
562 
563 public:
566  DenseMatrix Tv(const Vertex & v) const
567  {
568  Eigen::Vector3d nv = n_v(v);
569  ASSERT(std::abs(nv.norm() - 1.0) < 0.001);
570  const auto & N = getSurfaceMeshPtr()->neighborVertices(v);
571  auto neighbor = *N.begin();
572  Real3dPoint tangentVector = getSurfaceMeshPtr()->position(v) -
573  getSurfaceMeshPtr()->position(neighbor);
574  Eigen::Vector3d w = toVec3(tangentVector);
575  Eigen::Vector3d uu = project(w,nv).normalized();
576  Eigen::Vector3d vv = nv.cross(uu);
577 
578  DenseMatrix tanB(3,2);
579  tanB.col(0) = uu;
580  tanB.col(1) = vv;
581  return tanB;
582  }
583 
586  DenseMatrix Tf(const Face & f) const
587  {
588  Eigen::Vector3d nf = faceNormal(f);
589  ASSERT(std::abs(nf.norm() - 1.0) < 0.001);
590  const auto & N = getSurfaceMeshPtr()->incidentVertices(f);
591  auto v1 = *(N.begin());
592  auto v2 = *(N.begin() + 1);
593  Real3dPoint tangentVector =
595  Eigen::Vector3d w = toVec3(tangentVector);
596  Eigen::Vector3d uu = project(w,nf).normalized();
597  Eigen::Vector3d vv = nf.cross(uu);
598 
599  DenseMatrix tanB(3,2);
600  tanB.col(0) = uu;
601  tanB.col(1) = vv;
602  return tanB;
603  }
604 
610  Vector toExtrinsicVector(const Vertex v, const Vector & I) const
611  {
612  DenseMatrix T = Tv(v);
613  return T.col(0) * I(0) + T.col(1) * I(1);
614  }
615 
620  std::vector<Vector> toExtrinsicVectors(const std::vector<Vector> & I) const
621  {
622  std::vector<Vector> ext(mySurfaceMesh->nbVertices());
623  for (auto v = 0; v < mySurfaceMesh->nbVertices(); v++)
624  ext[v] = toExtrinsicVector(v,I[v]);
625  return ext;
626  }
627 
630  DenseMatrix Qvf(const Vertex & v, const Face & f) const
631  {
632  Eigen::Vector3d nf = faceNormal(f);
633  Eigen::Vector3d nv = n_v(v);
634  double c = nv.dot(nf);
635  ASSERT(std::abs( c + 1.0) > 0.0001);
636  //Special case for opposite nv and nf vectors.
637  if (std::abs( c + 1.0) < 0.00001)
638  return -Eigen::Matrix3d::Identity();
639 
640  auto vv = nv.cross(nf);
641  DenseMatrix skew = bracket(vv);
642  return Eigen::Matrix3d::Identity() + skew +
643  1.0 / (1.0 + c) * skew * skew;
644  }
645 
648  DenseMatrix Rvf(const Vertex & v, const Face & f) const
649  {
650  return Tf(f).transpose() * Qvf(v,f) * Tv(v);
651  }
652 
656  {
657  DenseMatrix N(myFaceDegree[f],3);
658  uint cpt = 0;
660  {
661  N.block(cpt,0,3,1) = n_v(v).transpose();
662  cpt++;
663  }
664  DenseMatrix GN = gradient(f) * N, Tf = T_f(f);
665 
666  return 0.5 * Tf.transpose() * (GN + GN.transpose()) * Tf;
667  }
668 
677  {
678  DenseMatrix uf_nabla(myFaceDegree[f], 2);
679  size_t cpt = 0;
680  for (auto v : mySurfaceMesh->incidentVertices(f))
681  {
682  uf_nabla.block(cpt,0,1,2) =
683  (Rvf(v,f) * uf.block(2 * cpt,0,2,1)).transpose();
684  ++cpt;
685  }
686  return uf_nabla;
687  }
688 
699  {
700  return Tf(f).transpose() * gradient(f) *
702  }
703 
715  {
716  return P(f) * D(f) * transportAndFormatVectorField(f,uf);
717  }
718 
725  {
726  return kroneckerWithI2(Tf(f).transpose() * gradient(f)) * blockConnection(f);
727  }
728 
735  {
736  return kroneckerWithI2(P(f) * D(f)) * blockConnection(f);
737  ;
738  }
739 
752  DenseMatrix connectionLaplacian(const Face & f, double lambda = 1.0) const
753  {
754  if (checkCache(CON_L_,f))
755  return myGlobalCache[CON_L_][f];
758  DenseMatrix L = -(faceArea(f) * G.transpose() * G + lambda * P.transpose() * P);
759  setInCache(CON_L_,f,L);
760  return L;
761  }
763 
764  // ----------------------- Global operators --------------------------------------
765  //MARK: Global Operators
768 
770  Form form0() const
771  {
772  return Form::Zero( nbVertices() );
773  }
776  {
777  SparseMatrix Id0( nbVertices(), nbVertices() );
778  Id0.setIdentity();
779  return Id0;
780  }
781 
797  SparseMatrix globalLaplaceBeltrami(const double lambda=1.0) const
798  {
800  std::vector<Triplet> triplets;
801  for( typename MySurfaceMesh::Index f = 0; f < mySurfaceMesh->nbFaces(); ++f )
802  {
803  auto nf = myFaceDegree[f];
804  DenseMatrix Lap = this->laplaceBeltrami(f,lambda);
805  const auto vertices = mySurfaceMesh->incidentVertices(f);
806  for(auto i=0u; i < nf; ++i)
807  for(auto j=0u; j < nf; ++j)
808  {
809  auto v = Lap(i,j);
810  if (v!= 0.0)
811  triplets.emplace_back( Triplet( (SparseMatrix::StorageIndex)vertices[ i ], (SparseMatrix::StorageIndex)vertices[ j ],
812  Lap( i, j ) ) );
813  }
814  }
815  lapGlobal.setFromTriplets(triplets.begin(), triplets.end());
816  return lapGlobal;
817  }
818 
825  {
827  std::vector<Triplet> triplets;
828  for ( typename MySurfaceMesh::Index v = 0; v < mySurfaceMesh->nbVertices(); ++v )
829  {
830  auto faces = mySurfaceMesh->incidentFaces(v);
831  auto varea = 0.0;
832  for(auto f: faces)
833  varea += faceArea(f) /(double)myFaceDegree[f];
834  triplets.emplace_back(Triplet(v,v,varea));
835  }
836  M.setFromTriplets(triplets.begin(),triplets.end());
837  return M;
838  }
839 
845  {
847  for ( int k = 0; k < iM0.outerSize(); ++k )
848  for ( typename SparseMatrix::InnerIterator it( iM0, k ); it; ++it )
849  it.valueRef() = 1.0 / it.value();
850  return iM0;
851  }
852 
870  SparseMatrix globalConnectionLaplace(const double lambda = 1.0) const
871  {
872  auto nv = mySurfaceMesh->nbVertices();
873  SparseMatrix lapGlobal(2 * nv, 2 * nv);
874  SparseMatrix local(2 * nv, 2 * nv);
875  std::vector<Triplet> triplets;
876  for (typename MySurfaceMesh::Index f = 0; f < mySurfaceMesh->nbFaces(); f++)
877  {
878  auto nf = degree(f);
879  DenseMatrix Lap = connectionLaplacian(f,lambda);
880  const auto vertices = mySurfaceMesh->incidentVertices(f);
881  for (auto i = 0u; i < nf; ++i)
882  for (auto j = 0u; j < nf; ++j)
883  for (short k1 = 0; k1 < 2; k1++)
884  for (short k2 = 0; k2 < 2; k2++)
885  {
886  auto v = Lap(2 * i + k1, 2 * j + k2);
887  if (v != 0.0)
888  triplets.emplace_back(Triplet(2 * vertices[i] + k1,
889  2 * vertices[j] + k2, v));
890  }
891  }
892  lapGlobal.setFromTriplets(triplets.begin(), triplets.end());
893  return lapGlobal;
894  }
895 
903  {
904  auto nv = mySurfaceMesh->nbVertices();
905  SparseMatrix M(2 * nv, 2 * nv);
906  std::vector<Triplet> triplets;
907  for (typename MySurfaceMesh::Index v = 0; v < mySurfaceMesh->nbVertices(); ++v)
908  {
909  auto faces = mySurfaceMesh->incidentFaces(v);
910  auto varea = 0.0;
911  for (auto f : faces)
912  varea += faceArea(f) / (double)myFaceDegree[f];
913  triplets.emplace_back(Triplet(2 * v, 2 * v, varea));
914  triplets.emplace_back(Triplet(2 * v + 1, 2 * v + 1, varea));
915  }
916  M.setFromTriplets(triplets.begin(), triplets.end());
917  return M;
918  }
920 
921  // ----------------------- Cache mechanism --------------------------------------
924 
941  std::vector<DenseMatrix> getOperatorCacheMatrix(const std::function<DenseMatrix(Face)> &perFaceOperator) const
942  {
943  std::vector<DenseMatrix> cache;
944  for( typename MySurfaceMesh::Index f=0; f < mySurfaceMesh->nbFaces(); ++f)
945  cache.push_back(perFaceOperator(f));
946  return cache;
947  }
948 
965  std::vector<Vector> getOperatorCacheVector(const std::function<Vector(Face)> &perFaceVectorOperator) const
966  {
967  std::vector<Vector> cache;
968  for( typename MySurfaceMesh::Index f=0; f < mySurfaceMesh->nbFaces(); ++f)
969  cache.push_back(perFaceVectorOperator(f));
970  return cache;
971  }
972 
976  {
977  myGlobalCacheEnabled = true;
978  }
979 
983  {
984  myGlobalCacheEnabled = false;
985  myGlobalCache.clear();
986  }
987 
989 
990  // ----------------------- Common --------------------------------------
991 public:
994 
997  void init()
998  {
1000  }
1001 
1005  size_t faceDegree(Face f) const
1006  {
1007  return myFaceDegree[f];
1008  }
1009 
1011  size_t nbVertices() const
1012  {
1013  return mySurfaceMesh->nbVertices();
1014  }
1015 
1017  size_t nbFaces() const
1018  {
1019  return mySurfaceMesh->nbFaces();
1020  }
1021 
1024  size_t degree(const Face f) const
1025  {
1026  return myFaceDegree[f];
1027  }
1028 
1031  {
1032  return mySurfaceMesh;
1033  }
1034 
1039  void selfDisplay ( std::ostream & out ) const
1040  {
1041  out << "[PolygonalCalculus]: ";
1043  out<< "internal cache enabled, ";
1044  else
1045  out<<"internal cache disabled, ";
1046  out <<"SurfaceMesh="<<*mySurfaceMesh;
1047  }
1048 
1053  bool isValid() const
1054  {
1055  return true;
1056  }
1057 
1059 
1060  // ------------------------- Protected Datas ------------------------------
1061  //MARK: Protected
1062 
1063 protected:
1066 
1069 
1072  {
1073  myFaceDegree.resize(mySurfaceMesh->nbFaces());
1074  for(typename MySurfaceMesh::Index f = 0; f < mySurfaceMesh->nbFaces(); ++f)
1075  {
1076  auto vertices = mySurfaceMesh->incidentVertices(f);
1077  auto nf = vertices.size();
1078  myFaceDegree[f] = nf;
1079  }
1080  }
1081 
1086  bool checkCache(OPERATOR key, const Face f) const
1087  {
1089  if (myGlobalCache[key].find(f) != myGlobalCache[key].end())
1090  return true;
1091  return false;
1092  }
1093 
1098  void setInCache(OPERATOR key, const Face f,
1099  const DenseMatrix &ope) const
1100  {
1102  myGlobalCache[key][f] = ope;
1103  }
1104 
1109  static Vector project(const Vector & u, const Vector & n)
1110  {
1111  return u - (u.dot(n) / n.squaredNorm()) * n;
1112  }
1113 
1118  static Vector toVector(const Eigen::Vector3d & x)
1119  {
1120  Vector X(3);
1121  for (int i = 0; i < 3; i++)
1122  X(i) = x(i);
1123  return X;
1124  }
1125 
1129  static Eigen::Vector3d toVec3(const Real3dPoint & x)
1130  {
1131  return Eigen::Vector3d(x(0),x(1),x(2));
1132  }
1133 
1138  static Real3dVector toReal3dVector(const Eigen::Vector3d & x)
1139  {
1140  return { x(0), x(1), x(2)};
1141  }
1142 
1143 
1150  {
1151  Vector n(3);
1152  n(0) = 0.;
1153  n(1) = 0.;
1154  n(2) = 0.;
1155  /* for (auto f : mySurfaceMesh->incidentFaces(v))
1156  n += vectorArea(f);
1157  return n.normalized();
1158  */
1159  auto faces = mySurfaceMesh->incidentFaces(v);
1160  for (auto f : faces)
1161  n += vectorArea(f);
1162 
1163  if (fabs(n.norm() - 0.0) < 0.00001)
1164  {
1165  //On non-manifold edges touching the boundary, n may be null.
1166  trace.warning()<<"[PolygonalCalculus] Trying to compute the normal vector at a boundary vertex incident to pnon-manifold edge, we return a random vector."<<std::endl;
1167  n << Vector::Random(3);
1168  }
1169  n = n.normalized();
1170  return n;
1171  }
1172 
1175  Eigen::Vector3d n_v(const Vertex & v) const
1176  {
1177  return toVec3(myVertexNormalEmbedder(v));
1178  }
1179 
1180  //Covariant operators routines
1183  {
1184  auto nf = degree(f);
1185  DenseMatrix RU_fO = DenseMatrix::Zero(nf * 2,nf * 2);
1186  size_t cpt = 0;
1187  for (auto v : getSurfaceMeshPtr()->incidentVertices(f))
1188  {
1189  auto Rv = Rvf(v,f);
1190  RU_fO.block<2,2>(2 * cpt,2 * cpt) = Rv;
1191  ++cpt;
1192  }
1193  return RU_fO;
1194  }
1195 
1198  {
1199  size_t h = M.rows();
1200  size_t w = M.cols();
1201  DenseMatrix MK = DenseMatrix::Zero(h * 2,w * 2);
1202  for (size_t j = 0; j < h; j++)
1203  for (size_t i = 0; i < w; i++)
1204  {
1205  MK(2 * j, 2 * i) = M(j, i);
1206  MK(2 * j + 1, 2 * i + 1) = M(j, i);
1207  }
1208  return MK;
1209  }
1210 
1211 
1212 
1214 
1215  // ------------------------- Internals ------------------------------------
1216  //MARK: Internals
1217 private:
1218 
1221 
1223  std::function<Real3dPoint(Face, Vertex)> myEmbedder;
1224 
1227 
1229  std::vector<size_t> myFaceDegree;
1230 
1233  mutable std::array<std::unordered_map<Face,DenseMatrix>, 15> myGlobalCache;
1234 
1235 }; // end of class PolygonalCalculus
1236 
1243 template <typename TP, typename TV>
1244 std::ostream&
1245 operator<< ( std::ostream & out, const PolygonalCalculus<TP,TV> & object )
1246 {
1247  object.selfDisplay( out );
1248  return out;
1249 }
1250 
1251 } // namespace DGtal
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:187
Implements differential operators on polygonal surfaces from .
Eigen::Vector3d n_v(const Vertex &v) const
DenseMatrix Rvf(const Vertex &v, const Face &f) const
PolygonalCalculus(const ConstAlias< MySurfaceMesh > surf, const std::function< Real3dPoint(Face, Vertex)> &pos_embedder, const std::function< Vector(Vertex)> &normal_embedder, bool globalInternalCacheEnabled=false)
EigenLinearAlgebraBackend LinAlg
Linear Algebra Backend from Eigen.
DenseMatrix transportAndFormatVectorField(const Face f, const Vector &uf)
SurfaceMesh< TRealPoint, TRealVector > MySurfaceMesh
Type of SurfaceMesh.
std::function< Real3dPoint(Face, Vertex)> myEmbedder
Embedding function (face,vertex)->R^3 for the vertex position wrt. the face.
DenseMatrix D(const Face f) const
DenseMatrix laplaceBeltrami(const Face f, const double lambda=1.0) const
static Eigen::Vector3d toVec3(const Real3dPoint &x)
toVec3 convert Real3dPoint to Eigen::Vector3d
DenseMatrix Tv(const Vertex &v) const
LinAlg::SparseMatrix SparseMatrix
Type of sparse matrix.
const MySurfaceMesh * getSurfaceMeshPtr() const
OPERATOR
Enum for operators in the internal cache strategy.
std::vector< size_t > myFaceDegree
Cache containing the face degree.
DenseMatrix X(const Face f) const
void selfDisplay(std::ostream &out) const
DenseMatrix Tf(const Face &f) const
PolygonalCalculus(PolygonalCalculus &&other)=delete
Vector faceNormal(const Face f) const
Vector centroid(const Face f) const
const MySurfaceMesh * mySurfaceMesh
Underlying SurfaceMesh.
MySurfaceMesh::RealVector Real3dVector
Real vector type.
DenseMatrix curl(const Face f) const
static const Dimension dimension
Concept checking.
Real3dVector faceNormalAsDGtalVector(const Face f) const
PolygonalCalculus(const ConstAlias< MySurfaceMesh > surf, const std::function< Real3dPoint(Face, Vertex)> &embedder, bool globalInternalCacheEnabled=false)
Real3dPoint centroidAsDGtalPoint(const Face f) const
DenseMatrix covariantProjection(const Face f, const Vector &uf)
Vector vectorArea(const Face f) const
DenseMatrix E(const Face f) const
DenseMatrix blockConnection(const Face &f) const
MySurfaceMesh::Vertex Vertex
Vertex type.
SparseMatrix globalInverseLumpedMassMatrix() const
Vector computeVertexNormal(const Vertex &v) const
std::array< std::unordered_map< Face, DenseMatrix >, 15 > myGlobalCache
size_t faceDegree(Face f) const
Vector toExtrinsicVector(const Vertex v, const Vector &I) const
toExtrinsicVector
std::vector< Vector > toExtrinsicVectors(const std::vector< Vector > &I) const
static Real3dVector toReal3dVector(const Eigen::Vector3d &x)
toReal3dVector converts Eigen::Vector3d to Real3dVector.
std::vector< DenseMatrix > getOperatorCacheMatrix(const std::function< DenseMatrix(Face)> &perFaceOperator) const
SparseMatrix doubledGlobalLumpedMassMatrix() const
bool myGlobalCacheEnabled
Global cache.
DenseMatrix bracket(const Vector &n) const
PolygonalCalculus(const PolygonalCalculus &other)=delete
DenseMatrix kroneckerWithI2(const DenseMatrix &M) const
DenseMatrix P(const Face f) const
SparseMatrix globalLaplaceBeltrami(const double lambda=1.0) const
PolygonalCalculus(const ConstAlias< MySurfaceMesh > surf, const std::function< Real3dVector(Vertex)> &embedder, bool globalInternalCacheEnabled=false)
DenseMatrix Qvf(const Vertex &v, const Face &f) const
void setEmbedder(const std::function< Real3dPoint(Face, Vertex)> &externalFunctor)
LinAlg::SolverSimplicialLDLT Solver
Type of a sparse matrix solver.
DenseMatrix sharp(const Face f) const
bool checkCache(OPERATOR key, const Face f) const
double faceArea(const Face f) const
DenseMatrix covariantGradient_f(const Face &f) const
DenseMatrix coGradient(const Face f) const
DenseMatrix divergence(const Face f) const
DenseMatrix M(const Face f, const double lambda=1.0) const
DenseMatrix shapeOperator(const Face f) const
DenseMatrix connectionLaplacian(const Face &f, double lambda=1.0) const
size_t degree(const Face f) const
void updateFaceDegree()
Update the face degree cache.
SparseMatrix globalLumpedMassMatrix() const
DenseMatrix gradient(const Face f) const
MySurfaceMesh::Face Face
Face type.
PolygonalCalculus< TRealPoint, TRealVector > Self
Self type.
LinAlg::DenseMatrix DenseMatrix
Type of dense matrix.
MySurfaceMesh::RealPoint Real3dPoint
Position type.
static Vector toVector(const Eigen::Vector3d &x)
toVector convert Real3dPoint to Eigen::VectorXd
void setInCache(OPERATOR key, const Face f, const DenseMatrix &ope) const
std::vector< Vector > getOperatorCacheVector(const std::function< Vector(Face)> &perFaceVectorOperator) const
LinAlg::Triplet Triplet
Type of sparse matrix triplet.
std::function< Real3dVector(Vertex)> myVertexNormalEmbedder
Embedding function (vertex)->R^3 for the vertex normal.
PolygonalCalculus(const ConstAlias< MySurfaceMesh > surf, bool globalInternalCacheEnabled=false)
DenseMatrix B(const Face f) const
Vector Form
Global 0-form, 1-form, 2-form are Vector.
PolygonalCalculus & operator=(const PolygonalCalculus &other)=delete
DenseMatrix covariantProjection_f(const Face &f) const
LinAlg::DenseVector Vector
Type of Vector.
SparseMatrix globalConnectionLaplace(const double lambda=1.0) const
static Vector project(const Vector &u, const Vector &n)
DenseMatrix A(const Face f) const
DenseMatrix covariantGradient(const Face f, const Vector &uf)
BOOST_STATIC_ASSERT((dimension==3))
DenseMatrix flat(const Face f) const
SparseMatrix identity0() const
std::ostream & warning()
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & operator<<(std::ostream &out, const ATu0v1< TKSpace, TLinearAlgebra > &object)
DGtal::uint32_t Dimension
Definition: Common.h:136
Trace trace
Definition: Common.h:153
Aim: Provide linear algebra backend using Eigen dense and sparse matrix as well as dense vector....
Definition: EigenSupport.h:96
Eigen::SimplicialLDLT< SparseMatrix > SolverSimplicialLDLT
Definition: EigenSupport.h:106
Eigen::Triplet< double, SparseMatrix::StorageIndex > Triplet
Definition: EigenSupport.h:102
Eigen::SparseMatrix< DenseVector::Scalar, Eigen::ColMajor, DenseVector::Index > SparseMatrix
Definition: EigenSupport.h:101
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
Definition: SurfaceMesh.h:92
RealPoint & position(Vertex v)
Definition: SurfaceMesh.h:647
TRealPoint RealPoint
Definition: SurfaceMesh.h:93
std::size_t Index
The type used for numbering vertices and faces.
Definition: SurfaceMesh.h:105
const Vertices & incidentVertices(Face f) const
Definition: SurfaceMesh.h:315
Size nbFaces() const
Definition: SurfaceMesh.h:296
const Faces & incidentFaces(Vertex v) const
Definition: SurfaceMesh.h:321
Size nbVertices() const
Definition: SurfaceMesh.h:288
const Vertices & neighborVertices(Vertex v) const
Definition: SurfaceMesh.h:331
TRealVector RealVector
Definition: SurfaceMesh.h:94