Эх сурвалжийг харах

Merge branch 'master' of github.com:libigl/libigl into alecjacobson

Former-commit-id: a67b16341337ce7b8df83d66afa2e1fa714ff112
Alec Jacobson 7 жил өмнө
parent
commit
b5e6c1cf42

+ 2 - 0
.gitignore

@@ -98,3 +98,5 @@ python/builddebug
 tutorial/.idea
 python/buildstatic
 tutorial/cmake-build-debug
+.vscode/
+.idea/

+ 17 - 0
CONTRIBUTING.md

@@ -0,0 +1,17 @@
+Before opening an issue on creating a pull request, please check the following:
+
+## Compilation Issues
+
+- If you are on Windows, did you select the **x64** version of the Visual Studio compiler?
+
+- If you have a **CMake issue**, make sure you follow the same approach as the  [libigl-example-project](https://github.com/libigl/libigl-example-project) to build libigl with your project, and make sure that you can compile the example project.
+
+- If you have an issue with a **submodule**, check if your submodules are up to date. If you have a doubt about a submodule, delete its folder and run `git submodule update --init --recursive` in the libigl directory.
+
+- If you have an issue with a missing **template issue**, check if your code compile with the *header-only* option of libigl activated. Turn **`OFF`** the CMake option `LIBIGL_USE_STATIC_LIBRARY`: either modify your `CMakeCache.txt` via CMake GUI or ccmake, or delete your `CMakeCache.txt` and re-run `cmake -DLIBIGL_USE_STATIC_LIBRARY=OFF ..` in your build folder.
+
+- Make sure your read the [**FAQ**](https://github.com/libigl/libigl/wiki/FAQ) before asking a new question, and search [**existing issues**](https://github.com/libigl/libigl/issues?q=is%3Aissue+is%3Aclosed) for a problem similar to yours.
+
+- Make sure you read the informations contained in the libigl [homepage](https://github.com/libigl/libigl) as well as the [tutorials](http://libigl.github.io/libigl/tutorial/tutorial.html).
+
+- If none of these solve your problem, then please report your issue in the bug tracker!

+ 3 - 5
coding-guidelines.html

@@ -1,14 +1,11 @@
 <!DOCTYPE html>
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
 <head>
 	<meta charset="utf-8"/>
 	<title>libigl</title>
 	<meta name="author" content="Alec Jacobson and Daniele Panozzo and others"/>
 	<link type="text/css" rel="stylesheet" href="../tutorial/style.css"/>
-<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
-<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
-<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
-<script>hljs.initHighlightingOnLoad();</script>
+<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script> <link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'> <script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script> <script>hljs.initHighlightingOnLoad();</script>
 </head>
 <body>
 
@@ -60,3 +57,4 @@
 
 </body>
 </html>
+

+ 6 - 4
include/igl/copyleft/cgal/assign_scalar.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "assign_scalar.h"
 
@@ -98,6 +98,7 @@ IGL_INLINE void igl::copyleft::cgal::assign_scalar(
   } while (d < float(interval.second));
 }
 
+#ifndef WIN32
 
 IGL_INLINE void igl::copyleft::cgal::assign_scalar(
   const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
@@ -132,3 +133,4 @@ IGL_INLINE void igl::copyleft::cgal::assign_scalar(
   } while (d < float(interval.second));
 }
 
+#endif // WIN32

+ 8 - 4
include/igl/copyleft/cgal/assign_scalar.h

@@ -1,16 +1,18 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_COPYLEFT_CGAL_ASSIGN_SCALAR_H
 #define IGL_COPYLEFT_CGAL_ASSIGN_SCALAR_H
 #include "../../igl_inline.h"
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 #include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h>
+#ifndef WIN32
 #include <CGAL/gmpxx.h>
+#endif
 
 namespace igl
 {
@@ -51,6 +53,7 @@ namespace igl
         const CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & cgal,
         float& d);
 
+#ifndef WIN32
       IGL_INLINE void assign_scalar(
         const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
         CGAL::Simple_cartesian<mpq_class>::FT & d);
@@ -60,6 +63,7 @@ namespace igl
       IGL_INLINE void assign_scalar(
         const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
         float& d);
+#endif // WIN32
 
     }
   }

+ 1 - 0
include/igl/exact_geodesic.cpp.REMOVED.git-id

@@ -0,0 +1 @@
+0ffa8b0392da9471a2fd26ec71effd909d4a75f3

+ 55 - 0
include/igl/exact_geodesic.h

@@ -0,0 +1,55 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Zhongshi Jiang <jiangzs@nyu.edu>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef IGL_EXACT_GEODESIC_H
+#define IGL_EXACT_GEODESIC_H
+
+#include "igl_inline.h"
+#include <Eigen/Core>
+
+namespace igl 
+{
+  // Exact geodesic algorithm for triangular mesh with the implementation from https://code.google.com/archive/p/geodesic/, 
+  // and the algorithm first described by Mitchell, Mount and Papadimitriou in 1987
+  //
+  // Inputs:
+  //   V  #V by 3 list of 3D vertex positions
+  //   F  #F by 3 list of mesh faces
+  //   VS #VS by 1 vector specifying indices of source vertices
+  //   FS #FS by 1 vector specifying indices of source faces
+  //   VT #VT by 1 vector specifying indices of target vertices
+  //   FT #FT by 1 vector specifying indices of target faces
+  // Output:
+  //   D  #VT+#FT by 1 vector of geodesic distances of each target w.r.t. the nearest one in the source set
+  //
+  // Note: 
+  //      Specifying a face as target/source means its center. 
+  //
+    template <
+    typename DerivedV,
+    typename DerivedF,
+    typename DerivedVS,
+    typename DerivedFS,
+    typename DerivedVT,
+    typename DerivedFT,
+    typename DerivedD>
+    IGL_INLINE void exact_geodesic(
+      const Eigen::MatrixBase<DerivedV> &V,
+      const Eigen::MatrixBase<DerivedF> &F,
+      const Eigen::MatrixBase<DerivedVS> &VS,
+      const Eigen::MatrixBase<DerivedFS> &FS,
+      const Eigen::MatrixBase<DerivedVT> &VT,
+      const Eigen::MatrixBase<DerivedFT> &FT,
+      Eigen::PlainObjectBase<DerivedD> &D);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "exact_geodesic.cpp"
+#endif
+
+#endif

+ 5 - 4
include/igl/grad.cpp

@@ -36,10 +36,11 @@ IGL_INLINE void grad_tet(const Eigen::PlainObjectBase<DerivedV>&V,
     F.row(3*m + i) << T(i,1), T(i,3), T(i,2);
   }
   // compute volume of each tet
-  VectorXd vol; igl::volume(V,T,vol);
+  Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> vol; 
+  igl::volume(V,T,vol);
 
-  VectorXd A(F.rows());
-  MatrixXd N(F.rows(),3);
+  Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 1> A(F.rows());
+  Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> N(F.rows(),3);
   if (!uniform) {
     // compute tetrahedron face normals
     igl::per_face_normals(V,F,N); int norm_rows = N.rows();
@@ -149,7 +150,7 @@ IGL_INLINE void grad_tri(const Eigen::PlainObjectBase<DerivedV>&V,
       // get h (by the area of the triangle)
       double h = sqrt( (dblA)/sin(M_PI / 3.0)); // (h^2*sin(60))/2. = Area => h = sqrt(2*Area/sin_60)
 
-      Eigen::Vector3d v1,v2,v3;
+      Eigen::Matrix<typename DerivedV::Scalar, 3, 1> v1,v2,v3;
       v1 << 0,0,0;
       v2 << h,0,0;
       v3 << h/2.,(sqrt(3)/2.)*h,0;

+ 70 - 76
include/igl/principal_curvature.cpp

@@ -105,13 +105,12 @@ public:
     }
 
 
-    IGL_INLINE static Quadric fit(std::vector<Eigen::Vector3d> &VV, bool zeroDetCheck, bool svd)
+    IGL_INLINE static Quadric fit(const std::vector<Eigen::Vector3d> &VV)
     {
-      using namespace std;
       assert(VV.size() >= 5);
       if (VV.size() < 5)
       {
-        cerr << "ASSERT FAILED!" << endl;
+        std::cerr << "ASSERT FAILED! fit function requires at least 5 points: Only " << VV.size() << " were given." << std::endl;
         exit(0);
       }
 
@@ -160,8 +159,6 @@ public:
   bool localMode; /* Use local mode */
   bool projectionPlaneCheck; /* Check collected vertices on tangent plane */
   bool montecarlo;
-  bool svd; /* Use svd calculation instead of pseudoinverse */
-  bool zeroDetCheck; /* Check if the determinant is close to zero */
   unsigned int montecarloN;
 
   searchType st; /* Use either a sphere search or a k-ring search */
@@ -179,23 +176,23 @@ public:
   IGL_INLINE CurvatureCalculator();
   IGL_INLINE void init(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F);
 
-  IGL_INLINE void finalEigenStuff (int, std::vector<Eigen::Vector3d>, Quadric );
-  IGL_INLINE void fitQuadric (Eigen::Vector3d, std::vector<Eigen::Vector3d> ref, const  std::vector<int>& , Quadric *);
-  IGL_INLINE void applyProjOnPlane(Eigen::Vector3d, std::vector<int>, std::vector<int>&);
+  IGL_INLINE void finalEigenStuff(int, const std::vector<Eigen::Vector3d>&, Quadric&);
+  IGL_INLINE void fitQuadric(const Eigen::Vector3d&, const std::vector<Eigen::Vector3d>& ref, const std::vector<int>& , Quadric *);
+  IGL_INLINE void applyProjOnPlane(const Eigen::Vector3d&, const std::vector<int>&, std::vector<int>&);
   IGL_INLINE void getSphere(const int, const double, std::vector<int>&, int min);
   IGL_INLINE void getKRing(const int, const double,std::vector<int>&);
-  IGL_INLINE Eigen::Vector3d project(Eigen::Vector3d, Eigen::Vector3d, Eigen::Vector3d);
-  IGL_INLINE void computeReferenceFrame(int, Eigen::Vector3d, std::vector<Eigen::Vector3d>&);
-  IGL_INLINE void getAverageNormal(int, std::vector<int>, Eigen::Vector3d&);
-  IGL_INLINE void getProjPlane(int, std::vector<int>, Eigen::Vector3d&);
-  IGL_INLINE void applyMontecarlo(std::vector<int>&,std::vector<int>*);
+  IGL_INLINE Eigen::Vector3d project(const Eigen::Vector3d&, const Eigen::Vector3d&, const Eigen::Vector3d&);
+  IGL_INLINE void computeReferenceFrame(int, const Eigen::Vector3d&, std::vector<Eigen::Vector3d>&);
+  IGL_INLINE void getAverageNormal(int, const std::vector<int>&, Eigen::Vector3d&);
+  IGL_INLINE void getProjPlane(int, const std::vector<int>&, Eigen::Vector3d&);
+  IGL_INLINE void applyMontecarlo(const std::vector<int>&,std::vector<int>*);
   IGL_INLINE void computeCurvature();
-  IGL_INLINE void printCurvature(std::string outpath);
+  IGL_INLINE void printCurvature(const std::string& outpath);
   IGL_INLINE double getAverageEdge();
 
-  IGL_INLINE static int rotateForward (float *v0, float *v1, float *v2)
+  IGL_INLINE static int rotateForward (double *v0, double *v1, double *v2)
   {
-    float t;
+    double t;
 
     if (std::abs(*v2) >= std::abs(*v1) && std::abs(*v2) >= std::abs(*v0))
       return 0;
@@ -208,9 +205,9 @@ public:
     return 1 + rotateForward (v0, v1, v2);
   }
 
-  IGL_INLINE static void rotateBackward (int nr, float *v0, float *v1, float *v2)
+  IGL_INLINE static void rotateBackward (int nr, double *v0, double *v1, double *v2)
   {
-    float t;
+    double t;
 
     if (nr == 0)
       return;
@@ -223,18 +220,18 @@ public:
     rotateBackward (nr - 1, v0, v1, v2);
   }
 
-  IGL_INLINE static Eigen::Vector3d chooseMax (Eigen::Vector3d n, Eigen::Vector3d abc, float ab)
+  IGL_INLINE static Eigen::Vector3d chooseMax (Eigen::Vector3d n, Eigen::Vector3d abc, double ab)
   {
-    int i, max_i;
-    float max_sp;
+    int max_i;
+    double max_sp;
     Eigen::Vector3d nt[8];
 
     n.normalize ();
     abc.normalize ();
 
-    max_sp = - std::numeric_limits<float>::max();
+    max_sp = - std::numeric_limits<double>::max();
 
-    for (i = 0; i < 4; i++)
+    for (int i = 0; i < 4; ++i)
     {
       nt[i] = n;
       if (ab > 0)
@@ -290,7 +287,6 @@ public:
         max_i = i;
       }
     }
-
     return nt[max_i];
   }
 
@@ -315,8 +311,6 @@ IGL_INLINE CurvatureCalculator::CurvatureCalculator()
   this->montecarlo=false;
   this->montecarloN=0;
   this->kRing=3;
-  this->svd=true;
-  this->zeroDetCheck=true;
   this->curvatureComputed=false;
   this->expStep=true;
 }
@@ -337,7 +331,7 @@ IGL_INLINE void CurvatureCalculator::init(const Eigen::MatrixXd& V, const Eigen:
   igl::per_vertex_normals(V, F, face_normals, vertex_normals);
 }
 
-IGL_INLINE void CurvatureCalculator::fitQuadric (Eigen::Vector3d v, std::vector<Eigen::Vector3d> ref, const std::vector<int>& vv, Quadric *q)
+IGL_INLINE void CurvatureCalculator::fitQuadric(const Eigen::Vector3d& v, const std::vector<Eigen::Vector3d>& ref, const std::vector<int>& vv, Quadric *q)
 {
   std::vector<Eigen::Vector3d> points;
   points.reserve (vv.size());
@@ -354,17 +348,25 @@ IGL_INLINE void CurvatureCalculator::fitQuadric (Eigen::Vector3d v, std::vector<
     double z = vTang.dot(ref[2]);
     points.push_back(Eigen::Vector3d (x,y,z));
   }
-  *q = Quadric::fit (points, zeroDetCheck, svd);
+  if (points.size() < 5)
+  {
+    std::cerr << "ASSERT FAILED! fit function requires at least 5 points: Only " << points.size() << " were given." << std::endl;
+    *q = Quadric(0,0,0,0,0);
+  }
+  else
+  {
+    *q = Quadric::fit (points);
+  }
 }
 
-IGL_INLINE void CurvatureCalculator::finalEigenStuff (int i, std::vector<Eigen::Vector3d> ref, Quadric q)
+IGL_INLINE void CurvatureCalculator::finalEigenStuff(int i, const std::vector<Eigen::Vector3d>& ref, Quadric& q)
 {
 
-  double a = q.a();
-  double b = q.b();
-  double c = q.c();
-  double d = q.d();
-  double e = q.e();
+  const double a = q.a();
+  const double b = q.b();
+  const double c = q.c();
+  const double d = q.d();
+  const double e = q.e();
 
 //  if (fabs(a) < 10e-8 || fabs(b) < 10e-8)
 //  {
@@ -457,7 +459,7 @@ IGL_INLINE void CurvatureCalculator::getKRing(const int start, const double r, s
     vv.push_back(toVisit);
     if (distance<(int)r)
     {
-      for (unsigned int i=0; i<vertex_to_vertices[toVisit].size(); i++)
+      for (unsigned int i=0; i<vertex_to_vertices[toVisit].size(); ++i)
       {
         int neighbor=vertex_to_vertices[toVisit][i];
         if (!visited[neighbor])
@@ -488,13 +490,13 @@ IGL_INLINE void CurvatureCalculator::getSphere(const int start, const double r,
     int toVisit=queue->front();
     queue->pop_front();
     vv.push_back(toVisit);
-    for (unsigned int i=0; i<vertex_to_vertices[toVisit].size(); i++)
+    for (unsigned int i=0; i<vertex_to_vertices[toVisit].size(); ++i)
     {
       int neighbor=vertex_to_vertices[toVisit][i];
       if (!visited[neighbor])
       {
         Eigen::Vector3d neigh=vertices.row(neighbor);
-        float distance=(me-neigh).norm();
+        double distance=(me-neigh).norm();
         if (distance<r)
           queue->push_back(neighbor);
         else if ((int)vv.size()<min)
@@ -508,13 +510,13 @@ IGL_INLINE void CurvatureCalculator::getSphere(const int start, const double r,
     std::pair<int, double> cand=extra_candidates->top();
     extra_candidates->pop();
     vv.push_back(cand.first);
-    for (unsigned int i=0; i<vertex_to_vertices[cand.first].size(); i++)
+    for (unsigned int i=0; i<vertex_to_vertices[cand.first].size(); ++i)
     {
       int neighbor=vertex_to_vertices[cand.first][i];
       if (!visited[neighbor])
       {
         Eigen::Vector3d neigh=vertices.row(neighbor);
-        float distance=(me-neigh).norm();
+        double distance=(me-neigh).norm();
         extra_candidates->push(std::pair<int,double>(neighbor,distance));
         visited[neighbor]=true;
       }
@@ -525,16 +527,15 @@ IGL_INLINE void CurvatureCalculator::getSphere(const int start, const double r,
   free(visited);
 }
 
-IGL_INLINE Eigen::Vector3d CurvatureCalculator::project(Eigen::Vector3d v, Eigen::Vector3d  vp, Eigen::Vector3d ppn)
+IGL_INLINE Eigen::Vector3d CurvatureCalculator::project(const Eigen::Vector3d& v, const Eigen::Vector3d& vp, const Eigen::Vector3d& ppn)
 {
   return (vp - (ppn * ((vp - v).dot(ppn))));
 }
 
-IGL_INLINE void CurvatureCalculator::computeReferenceFrame(int i, Eigen::Vector3d normal, std::vector<Eigen::Vector3d>& ref )
+IGL_INLINE void CurvatureCalculator::computeReferenceFrame(int i, const Eigen::Vector3d& normal, std::vector<Eigen::Vector3d>& ref )
 {
 
-  Eigen::Vector3d longest_v=Eigen::Vector3d::Zero();
-  longest_v=Eigen::Vector3d(vertices.row(vertex_to_vertices[i][0]));
+  Eigen::Vector3d longest_v=Eigen::Vector3d(vertices.row(vertex_to_vertices[i][0]));
 
   longest_v=(project(vertices.row(i),longest_v,normal)-Eigen::Vector3d(vertices.row(i))).normalized();
 
@@ -546,25 +547,25 @@ IGL_INLINE void CurvatureCalculator::computeReferenceFrame(int i, Eigen::Vector3
   ref[2]=normal;
 }
 
-IGL_INLINE void CurvatureCalculator::getAverageNormal(int j, std::vector<int> vv, Eigen::Vector3d& normal)
+IGL_INLINE void CurvatureCalculator::getAverageNormal(int j, const std::vector<int>& vv, Eigen::Vector3d& normal)
 {
   normal=(vertex_normals.row(j)).normalized();
   if (localMode)
     return;
 
-  for (unsigned int i=0; i<vv.size(); i++)
+  for (unsigned int i=0; i<vv.size(); ++i)
   {
     normal+=vertex_normals.row(vv[i]).normalized();
   }
   normal.normalize();
 }
 
-IGL_INLINE void CurvatureCalculator::getProjPlane(int j, std::vector<int> vv, Eigen::Vector3d& ppn)
+IGL_INLINE void CurvatureCalculator::getProjPlane(int j, const std::vector<int>& vv, Eigen::Vector3d& ppn)
 {
   int nr;
-  float a, b, c;
-  float nx, ny, nz;
-  float abcq;
+  double a, b, c;
+  double nx, ny, nz;
+  double abcq;
 
   a = b = c = 0;
 
@@ -605,9 +606,9 @@ IGL_INLINE double CurvatureCalculator::getAverageEdge()
   double sum = 0;
   int count = 0;
 
-  for (int i = 0; i<faces.rows(); i++)
+  for (int i = 0; i<faces.rows(); ++i)
   {
-    for (short unsigned j=0; j<3; j++)
+    for (short unsigned j=0; j<3; ++j)
     {
       Eigen::Vector3d p1=vertices.row(faces.row(i)[j]);
       Eigen::Vector3d p2=vertices.row(faces.row(i)[(j+1)%3]);
@@ -623,14 +624,14 @@ IGL_INLINE double CurvatureCalculator::getAverageEdge()
 }
 
 
-IGL_INLINE void CurvatureCalculator::applyProjOnPlane(Eigen::Vector3d ppn, std::vector<int> vin, std::vector<int> &vout)
+IGL_INLINE void CurvatureCalculator::applyProjOnPlane(const Eigen::Vector3d& ppn, const std::vector<int>& vin, std::vector<int> &vout)
 {
-  for (std::vector<int>::iterator vpi = vin.begin(); vpi != vin.end(); ++vpi)
-    if (vertex_normals.row(*vpi) * ppn > 0.0f)
-      vout.push_back (*vpi);
+  for (std::vector<int>::const_iterator vpi = vin.begin(); vpi != vin.end(); ++vpi)
+    if (vertex_normals.row(*vpi) * ppn > 0.0)
+      vout.push_back(*vpi);
 }
 
-IGL_INLINE void CurvatureCalculator::applyMontecarlo(std::vector<int>& vin, std::vector<int> *vout)
+IGL_INLINE void CurvatureCalculator::applyMontecarlo(const std::vector<int>& vin, std::vector<int> *vout)
 {
   if (montecarloN >= vin.size ())
   {
@@ -639,24 +640,22 @@ IGL_INLINE void CurvatureCalculator::applyMontecarlo(std::vector<int>& vin, std:
   }
 
   float p = ((float) montecarloN) / (float) vin.size();
-  for (std::vector<int>::iterator vpi = vin.begin(); vpi != vin.end(); ++vpi)
+  for (std::vector<int>::const_iterator vpi = vin.begin(); vpi != vin.end(); ++vpi)
   {
     float r;
     if ((r = ((float)rand () / RAND_MAX)) < p)
     {
-      vout->push_back (*vpi);
+      vout->push_back(*vpi);
     }
   }
 }
 
 IGL_INLINE void CurvatureCalculator::computeCurvature()
 {
-  using namespace std;
-
   //CHECK che esista la mesh
-  size_t vertices_count=vertices.rows() ;
+  const size_t vertices_count=vertices.rows();
 
-  if (vertices_count <=0)
+  if (vertices_count ==0)
     return;
 
   curvDir=std::vector< std::vector<Eigen::Vector3d> >(vertices_count);
@@ -691,10 +690,9 @@ IGL_INLINE void CurvatureCalculator::computeCurvature()
         return;
     }
 
-    std::vector<Eigen::Vector3d> ref(3);
     if (vv.size()<6)
     {
-      std::cerr << "Could not compute curvature of radius " << scaledRadius << endl;
+      std::cerr << "Could not compute curvature of radius " << scaledRadius << std::endl;
       return;
     }
 
@@ -704,8 +702,7 @@ IGL_INLINE void CurvatureCalculator::computeCurvature()
       vvtmp.reserve (vv.size ());
       applyProjOnPlane (vertex_normals.row(i), vv, vvtmp);
       if (vvtmp.size() >= 6 && vvtmp.size()<vv.size())
-	  vv = vvtmp;
-
+        vv = vvtmp;
     }
 
 
@@ -723,7 +720,7 @@ IGL_INLINE void CurvatureCalculator::computeCurvature()
     }
     if (vv.size()<6)
     {
-      std::cerr << "Could not compute curvature of radius " << scaledRadius << endl;
+      std::cerr << "Could not compute curvature of radius " << scaledRadius << std::endl;
       return;
     }
     if (montecarlo)
@@ -737,6 +734,7 @@ IGL_INLINE void CurvatureCalculator::computeCurvature()
 
     if (vv.size()<6)
       return;
+    std::vector<Eigen::Vector3d> ref(3);
     computeReferenceFrame(i,normal,ref);
 
     Quadric q;
@@ -748,7 +746,7 @@ IGL_INLINE void CurvatureCalculator::computeCurvature()
   curvatureComputed=true;
 }
 
-IGL_INLINE void CurvatureCalculator::printCurvature(std::string outpath)
+IGL_INLINE void CurvatureCalculator::printCurvature(const std::string& outpath)
 {
   using namespace std;
   if (!curvatureComputed)
@@ -765,7 +763,7 @@ IGL_INLINE void CurvatureCalculator::printCurvature(std::string outpath)
 
   int vertices_count=vertices.rows();
   of << vertices_count << endl;
-  for (int i=0; i<vertices_count; i++)
+  for (int i=0; i<vertices_count; ++i)
   {
     of << curv[i][0] << " " << curv[i][1] << " " << curvDir[i][0][0] << " " << curvDir[i][0][1] << " " << curvDir[i][0][2] << " " <<
     curvDir[i][1][0] << " " << curvDir[i][1][1] << " " << curvDir[i][1][2] << endl;
@@ -792,12 +790,10 @@ IGL_INLINE void igl::principal_curvature(
   unsigned radius,
   bool useKring)
 {
-  using namespace std;
-
   if (radius < 2)
   {
     radius = 2;
-    cout << "WARNING: igl::principal_curvature needs a radius >= 2, fixing it to 2." << endl;
+    std::cout << "WARNING: igl::principal_curvature needs a radius >= 2, fixing it to 2." << std::endl;
   }
 
   // Preallocate memory
@@ -823,10 +819,8 @@ IGL_INLINE void igl::principal_curvature(
   cc.computeCurvature();
 
   // Copy it back
-  for (unsigned i=0; i<V.rows(); i++)
+  for (unsigned i=0; i<V.rows(); ++i)
   {
-    Eigen::Vector3d d1;
-    Eigen::Vector3d d2;
     PD1.row(i) << cc.curvDir[i][0][0], cc.curvDir[i][0][1], cc.curvDir[i][0][2];
     PD2.row(i) << cc.curvDir[i][1][0], cc.curvDir[i][1][1], cc.curvDir[i][1][2];
     PD1.row(i).normalize();
@@ -843,7 +837,7 @@ IGL_INLINE void igl::principal_curvature(
 
     if (PD1.row(i) * PD2.row(i).transpose() > 10e-6)
     {
-      cerr << "PRINCIPAL_CURVATURE: Something is wrong with vertex: i" << endl;
+      std::cerr << "PRINCIPAL_CURVATURE: Something is wrong with vertex: " << i << std::endl;
       PD1.row(i) *= 0;
       PD2.row(i) *= 0;
     }

+ 56 - 57
index.html

@@ -1,14 +1,11 @@
 <!DOCTYPE html>
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
 <head>
 	<meta charset="utf-8"/>
 	<title>libigl</title>
 	<meta name="author" content="Alec Jacobson and Daniele Panozzo and others"/>
 	<link type="text/css" rel="stylesheet" href="tutorial/style.css"/>
-<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
-<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
-<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
-<script>hljs.initHighlightingOnLoad();</script>
+<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script> <link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'> <script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script> <script>hljs.initHighlightingOnLoad();</script>
 </head>
 <body>
 
@@ -22,10 +19,10 @@
 
 <blockquote>
 <p>Get started with:</p>
+</blockquote>
 
 <pre><code class="bash">git clone --recursive https://github.com/libigl/libigl.git
 </code></pre>
-</blockquote>
 
 <p>libigl is a simple C++ geometry processing library. We have a wide
 functionality including construction of sparse discrete differential geometry
@@ -39,7 +36,7 @@ like MATLAB.</p>
 just include igl headers (e.g. <code>#include &lt;igl/cotmatrix.h&gt;</code>) and run. Each
 header file contains a single function (e.g. <code>igl/cotmatrix.h</code> contains
 <code>igl::cotmatrix()</code>). Most are tailored to operate on a generic triangle mesh
-stored in an n-by&#8211;3 matrix of vertex positions <code>V</code> and an m-by&#8211;3 matrix of
+stored in an n-by-3 matrix of vertex positions <code>V</code> and an m-by-3 matrix of
 triangle indices <code>F</code>.</p>
 
 <p><em>Optionally</em> the library may also be <a href="optional/">pre-compiled</a> into a statically
@@ -121,14 +118,14 @@ libigl depends only on the <a href="http://eigen.tuxfamily.org">Eigen</a> librar
 <p>Libigl compartmentalizes its <strong>optional</strong> dependences via its directory
 organization in the <code>include/</code> folder. All header files located <em>directly</em> in
 the <code>include/igl/</code> folder have only stl and Eigen as dependencies. For example,
-all of the headers that depend on CGAL are located in <code>include/igl/cgal</code>. For a
-full list of <em>optional</em> dependencies check <code>optional/CMakeLists.txt</code>.</p>
+all of the headers that depend on CGAL are located in <code>include/igl/copyleft/cgal</code>.
+For a full list of <em>optional</em> dependencies check <code>optional/CMakeLists.txt</code>.</p>
 
 <h3 id="gccandtheoptionalcgaldependency">GCC and the Optional CGAL Dependency</h3>
 
-<p>The <code>include/igl/cgal/*.h</code> headers depend on CGAL. It has come to our attention
-that CGAL does not work properly with GCC 4.8. To the best of our knowledge,
-GCC 4.7 and clang will work correctly.</p>
+<p>The <code>include/igl/copyleft/cgal/*.h</code> headers depend on CGAL. It has come to
+our attention that CGAL does not work properly with GCC 4.8. To the best of
+our knowledge, GCC 4.7 and clang will work correctly.</p>
 
 <h3 id="openmpandwindows">OpenMP and Windows</h3>
 
@@ -210,7 +207,7 @@ BibTeX entry:</p>
   title = {{libigl}: A simple {C++} geometry processing library},
   author = {Alec Jacobson and Daniele Panozzo and others},
   note = {http://libigl.github.io/libigl/},
-  year = {2016},
+  year = {2017},
 }
 </code></pre>
 
@@ -221,56 +218,59 @@ Eurographics/ACM Symposium on Geometry Processing software award. Here are a
 few labs/companies/institutions using libigl:</p>
 
 <ul>
-<li><a href="http://www.activision.com">Activision</a></li>
-<li><a href="http://www.adobe.com/technology/">Adobe Research</a></li>
-<li><a href="http://www.ea.com">Electronic Arts, Inc</a></li>
-<li><a href="https://epicgames.com">Epic Games</a></li>
-<li><a href="https://research.google.com">Google Research</a></li>
-<li><a href="http://meshconsultants.ca/">Mesh</a>, consultants, Canada</li>
-<li><a href="http://graphics.pixar.com/research/">Pixar Research</a></li>
-<li><a href="http://esotericsoftware.com/">Spine by Esoteric Software</a> is an animation tool dedicated to 2D characters.</li>
-<li>Columbia University, <a href="http://www.cs.columbia.edu/cg/">Columbia Computer Graphics Group</a>, USA</li>
-<li><a href="http://www.graphics.cornell.edu/">Cornell University</a>, USA</li>
-<li><a href="http://dcgi.felk.cvut.cz/">Czech Technical University in Prague</a>, Czech</li>
-<li>EPF Lausanne, <a href="http://lgg.epfl.ch/people.php">Computer Graphics and Geometry Laboratory</a>, Switzerland</li>
-<li>ETH Zurich, <a href="http://igl.ethz.ch/">Interactive Geometry Lab</a> and <a href="http://ait.inf.ethz.ch/">Advanced Technologies Lab</a>, Swizterland</li>
-<li>George Mason University, <a href="http://cs.gmu.edu/~ygingold/">CraGL</a>, USA</li>
-<li><a href="http://www.ust.hk/">Hong Kong University of Science and Technology</a>, Hong Kong</li>
-<li><a href="https://www.inria.fr/centre/grenoble/">Inria, Université Grenoble Alpes</a>, France</li>
-<li><a href="http://english.jiangnan.edu.cn">Jiangnan university</a>, China</li>
-<li><a href="http://www.nii.ac.jp/en/">National Institute of Informatics</a>, Japan</li>
-<li>New York University, <a href="http://mrl.nyu.edu/">Media Research Lab</a>, USA</li>
-<li>NYUPoly, <a href="http://game.engineering.nyu.edu/">Game Innovation Lab</a>, USA</li>
-<li><a href="https://www.cg.tu-berlin.de">TU Berlin</a>, Germany</li>
-<li><a href="http://www.tudelft.nl/en/">TU Delft</a>, Netherlands</li>
-<li><a href="https://www.tuwien.ac.at/en/tuwien_home/">TU Wien</a>, Austria</li>
-<li><a href="http://www.telecom-paristech.fr/en/formation-et-innovation-dans-le-numerique.html">Telecom ParisTech</a>, Paris, France</li>
-<li><a href="http://www.staff.science.uu.nl/~vaxma001/">Utrecht University</a>, The Netherlands</li>
-<li><a href="http://mtm.ufsc.br/~leo/">Universidade Federal de Santa Catarina</a>, Brazil</li>
-<li><a href="http://vecg.cs.ucl.ac.uk/">University College London</a>, England</li>
-<li><a href="http://vis.berkeley.edu/">University of California Berkeley</a>, USA</li>
-<li><a href="http://www.cam.ac.uk/">University of Cambridge</a>, England</li>
-<li><a href="http://cg.cis.upenn.edu/">University of Pennsylvania</a>, USA</li>
-<li><a href="http://www.cs.utexas.edu/users/evouga/">University of Texas at Austin</a>, USA</li>
-<li><a href="http://dgp.toronto.edu">University of Toronto</a>, Canada</li>
-<li><a href="https://www.csc.uvic.ca/Research/graphics/">University of Victoria</a>, Canada</li>
-<li><a href="http://www.uwec.edu/computer-science/">University of Wisconsin-Eau Claire</a>, USA</li>
-<li><a href="http://www.usi.ch/en">Università della Svizzera Italiana</a>, Switzerland</li>
-<li><a href="http://www.univ-tlse3.fr/">Université Toulouse III Paul Sabatier</a>, France</li>
-<li><a href="http://www.math.zju.edu.cn/cagd/">Zhejiang University</a>, China</li>
+<li> <a href="http://www.activision.com">Activision</a></li>
+<li> <a href="http://www.adobe.com/technology/">Adobe Research</a></li>
+<li> <a href="http://www.ea.com">Electronic Arts, Inc</a></li>
+<li> <a href="https://epicgames.com">Epic Games</a></li>
+<li> <a href="https://research.google.com">Google Research</a></li>
+<li> <a href="http://ilm.com">Industrial Light and Magic</a></li>
+<li> <a href="http://meshconsultants.ca/">Mesh consultants</a>, Canada</li>
+<li> <a href="https://www.microsoft.com/en-us/research/">Microsoft Research</a></li>
+<li> <a href="http://graphics.pixar.com/research/">Pixar</a></li>
+<li> <a href="http://esotericsoftware.com/">Spine by Esoteric Software</a> is an animation tool dedicated to 2D characters.</li>
+<li> <a href="http://vvvv.org">vvvv toolkit</a> a multipurpose tookit</li>
+<li> Columbia University, <a href="http://www.cs.columbia.edu/cg/">Columbia Computer Graphics Group</a>, USA</li>
+<li> <a href="http://www.graphics.cornell.edu/">Cornell University</a>, USA</li>
+<li> <a href="http://dcgi.felk.cvut.cz/">Czech Technical University in Prague</a>, Czech</li>
+<li> EPF Lausanne, <a href="http://lgg.epfl.ch/people.php">Computer Graphics and Geometry Laboratory</a>, Switzerland</li>
+<li> ETH Zurich, <a href="http://igl.ethz.ch/">Interactive Geometry Lab</a> and <a href="http://ait.inf.ethz.ch/">Advanced Technologies Lab</a>, Swizterland</li>
+<li> George Mason University, <a href="http://cs.gmu.edu/~ygingold/">CraGL</a>, USA</li>
+<li> <a href="http://www.ust.hk/">Hong Kong University of Science and Technology</a>, Hong Kong</li>
+<li> <a href="https://www.inria.fr/centre/grenoble/">Inria, Université Grenoble Alpes</a>, France</li>
+<li> <a href="http://english.jiangnan.edu.cn">Jiangnan university</a>, China</li>
+<li> <a href="http://www.nii.ac.jp/en/">National Institute of Informatics</a>, Japan</li>
+<li> New York University, <a href="http://mrl.nyu.edu/">Media Research Lab</a>, USA</li>
+<li> NYUPoly, <a href="http://game.engineering.nyu.edu/">Game Innovation Lab</a>, USA</li>
+<li> <a href="https://www.cg.tu-berlin.de">TU Berlin</a>, Germany</li>
+<li> <a href="http://www.tudelft.nl/en/">TU Delft</a>, Netherlands</li>
+<li> <a href="https://www.tuwien.ac.at/en/tuwien_home/">TU Wien</a>, Austria</li>
+<li> <a href="http://www.telecom-paristech.fr/en/formation-et-innovation-dans-le-numerique.html">Telecom ParisTech</a>, Paris, France</li>
+<li> <a href="http://www.staff.science.uu.nl/~vaxma001/">Utrecht University</a>, The Netherlands</li>
+<li> <a href="http://mtm.ufsc.br/~leo/">Universidade Federal de Santa Catarina</a>, Brazil</li>
+<li> <a href="http://vecg.cs.ucl.ac.uk/">University College London</a>, England</li>
+<li> <a href="http://vis.berkeley.edu/">University of California Berkeley</a>, USA</li>
+<li> <a href="http://www.cam.ac.uk/">University of Cambridge</a>, England</li>
+<li> <a href="http://cg.cis.upenn.edu/">University of Pennsylvania</a>, USA</li>
+<li> <a href="http://www.cs.utexas.edu/users/evouga/">University of Texas at Austin</a>, USA</li>
+<li> <a href="http://dgp.toronto.edu">University of Toronto</a>, Canada</li>
+<li> <a href="https://www.csc.uvic.ca/Research/graphics/">University of Victoria</a>, Canada</li>
+<li> <a href="http://www.uwec.edu/computer-science/">University of Wisconsin-Eau Claire</a>, USA</li>
+<li> <a href="http://www.usi.ch/en">Università della Svizzera Italiana</a>, Switzerland</li>
+<li> <a href="http://www.univ-tlse3.fr/">Université Toulouse III Paul Sabatier</a>, France</li>
+<li> <a href="http://www.math.zju.edu.cn/cagd/">Zhejiang University</a>, China</li>
 </ul>
 
 <h2 id="contact">Contact</h2>
 
 <p>Libigl is a group endeavor led by <a href="http://www.cs.toronto.edu/~jacobson/">Alec
 Jacobson</a> and <a href="http://cs.nyu.edu/~panozzo/">Daniele
-Panozzo</a>. Please <a href="&#109;&#97;&#105;&#108;&#x74;&#111;&#x3a;&#x61;&#x6c;&#101;&#x63;&#x6a;&#x61;&#x63;&#111;&#98;&#115;&#111;&#110;&#64;&#103;&#109;&#x61;&#105;&#108;&#x2e;&#x63;&#x6f;&#x6d;&#44;&#x64;&#x61;&#110;&#105;&#101;&#x6c;&#101;&#x2e;&#x70;&#x61;&#110;&#x6f;&#122;&#x7a;&#x6f;&#64;&#x67;&#x6d;&#x61;&#x69;&#x6c;&#x2e;&#99;&#x6f;&#x6d;">&#99;&#x6f;&#x6e;&#116;&#x61;&#99;&#x74;
-&#117;&#115;</a> if you have
+Panozzo</a>. Please <a href="mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com">contact
+us</a> if you have
 questions or comments. For troubleshooting, please post an
 <a href="https://github.com/libigl/libigl/issues">issue</a> on github.</p>
 
-<p>If you&#8217;re using libigl in your projects, quickly <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#x6f;&#58;&#97;&#x6c;&#101;&#99;&#106;&#x61;&#x63;&#111;&#x62;&#x73;&#x6f;&#110;&#64;&#103;&#x6d;&#x61;&#x69;&#x6c;&#46;&#99;&#x6f;&#x6d;&#x2c;&#100;&#x61;&#110;&#105;&#x65;&#108;&#x65;&#x2e;&#112;&#97;&#x6e;&#111;&#x7a;&#x7a;&#x6f;&#x40;&#103;&#109;&#x61;&#105;&#x6c;&#x2e;&#x63;&#111;&#109;">&#x64;&#x72;&#111;&#112; &#x75;&#x73; &#97;
-&#110;&#111;&#116;&#101;</a>. Tell us who you
+<p>If you&#8217;re using libigl in your projects, quickly <a href="mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com">drop us a
+note</a>. Tell us who you
 are and what you&#8217;re using it for. This helps us apply for funding and justify
 spending time maintaining this.</p>
 
@@ -279,11 +279,10 @@ page</a>.</p>
 
 <h2 id="copyright">Copyright</h2>
 
-<p>2017 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
-Zhou, Sebastian Koch, Amir Vaxman, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De
-Giorgis, Luigi Rocca, Leonardo Sacht, Kevin Walliman, Olga Sorkine-Hornung, and others.</p>
+<p>2017 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan Zhou, Sebastian Koch, Jeremie Dumas, Amir Vaxman, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De Giorgis, Luigi Rocca, Leonardo Sacht, Kevin Walliman, Olga Sorkine-Hornung, and others.</p>
 
 <p>Please see individual files for appropriate copyright notices.</p>
 
 </body>
 </html>
+

+ 39 - 41
optional/index.html

@@ -1,14 +1,11 @@
 <!DOCTYPE html>
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
 <head>
 	<meta charset="utf-8"/>
 	<title>libigl</title>
 	<meta name="author" content="Alec Jacobson and Daniele Panozzo and others"/>
 	<link type="text/css" rel="stylesheet" href="../tutorial/style.css"/>
-<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
-<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
-<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
-<script>hljs.initHighlightingOnLoad();</script>
+<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script> <link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'> <script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script> <script>hljs.initHighlightingOnLoad();</script>
 </head>
 <body>
 
@@ -24,7 +21,7 @@ improve your compilation times.</p>
 <p>Libigl is developed most often on Mac OS X, though has current users in Linux
 and Windows.</p>
 
-<h3 id="linuxmacosxcygwin">Linux/Mac OS X/Cygwin</h3>
+<h3 id="linuxmacosxcygwin">Linux/Mac OS X/Cygwin </h3>
 
 <p>Libigl may also be compiled to a static library. This is advantageous when
 building a project with libigl, since when used as an header-only library can
@@ -40,7 +37,7 @@ cmake -DCMAKE_BUILD_TYPE=Release ../optional
 make
 </code></pre>
 
-<h4 id="warnings">Warnings</h4>
+<h4 id="warnings">Warnings </h4>
 
 <p>You should expect to see a few linker warnings of the form:</p>
 
@@ -50,7 +47,7 @@ make
 <p>These are (admittedly unpopular) functions that have never been used by us
 statically so we haven&#8217;t explicit instantiations (yet).</p>
 
-<h4 id="external">External</h4>
+<h4 id="external">External </h4>
 
 <p>Finally there are a number of external libraries that we include in
 <code>./external/</code> because they are either difficult to obtain or they have been
@@ -58,7 +55,7 @@ patched for easier use with libigl. Please see the respective readmes in those
 directories or build the tutorial using cmake, which will recursively build all
 dependencies.</p>
 
-<h5 id="installingembree2.0">Installing Embree 2.0</h5>
+<h5 id="installingembree2.0">Installing Embree 2.0 </h5>
 
 <p>To build the embree library and executables on Mac OS X issue:</p>
 
@@ -74,72 +71,72 @@ make
 #sudo make install
 </code></pre>
 
-<h2 id="extras">Extras</h2>
+<h2 id="extras">Extras </h2>
 
-<h3 id="bbw">bbw</h3>
+<h3 id="bbw">bbw </h3>
 
 <p>This library extra contains functions for computing Bounded Biharmonic Weights, can
 be used with and without the <a href="#mosek">mosek</a> extra via the <code>IGL_NO_MOSEK</code>
 macro.</p>
 
-<h3 id="boolean">boolean</h3>
+<h3 id="boolean">boolean </h3>
 
 <p>This library extra contains functions for computing mesh-mesh booleans,
 depending on CGAL and optionally Cork.</p>
 
-<h3 id="cgal">cgal</h3>
+<h3 id="cgal">cgal </h3>
 
 <p>This library extra utilizes CGAL&#8217;s efficient and exact intersection and
 proximity queries.</p>
 
-<h3 id="embree">embree</h3>
+<h3 id="embree">embree </h3>
 
 <p>This library extra utilizes embree&#8217;s efficient ray tracing queries.</p>
 
-<h3 id="matlab">matlab</h3>
+<h3 id="matlab">matlab </h3>
 
 <p>This library extra provides support for reading and writing <code>.mat</code> workspace
 files, interfacing with Matlab at run time and compiling mex functions.</p>
 
-<h3 id="mosek">mosek</h3>
+<h3 id="mosek">mosek </h3>
 
 <p>This library extra utilizes mosek&#8217;s efficient interior-point solver for
 quadratic programs.</p>
 
-<h3 id="png">png</h3>
+<h3 id="png">png </h3>
 
 <p>This library extra uses <code>libpng</code> and <code>YImage</code> to read and write <code>.png</code> files.</p>
 
-<h3 id="tetgen">tetgen</h3>
+<h3 id="tetgen">tetgen </h3>
 
 <p>This library extra provides a simplified wrapper to the tetgen 3d tetrahedral
 meshing library.</p>
 
-<h3 id="triangle">Triangle</h3>
+<h3 id="triangle">Triangle </h3>
 
 <p>This library extra provides a simplified wrapper to the triangle 2d triangle
 meshing library.</p>
 
-<h3 id="viewer">viewer</h3>
+<h3 id="viewer">viewer </h3>
 
 <p>This library extra utilizes glfw and glew to open an opengl context and launch
 a simple mesh viewer.</p>
 
-<h3 id="xml">xml</h3>
+<h3 id="xml">xml </h3>
 
 <p>This library extra utilizes tinyxml2 to read and write serialized classes
 containing Eigen matrices and other standard simple data-structures.</p>
 
-<h2 id="development">Development</h2>
+<h2 id="development">Development </h2>
 
 <p>Further documentation for developers is listed in
 <a href="../style_guidelines.html">style_guidelines.html</a>.</p>
 
-<h2 id="license">License</h2>
+<h2 id="license">License </h2>
 
 <p>See <code>LICENSE.txt</code></p>
 
-<h2 id="zipping">Zipping</h2>
+<h2 id="zipping">Zipping </h2>
 
 <p>Zip this directory without .git litter and binaries using:</p>
 
@@ -275,28 +272,28 @@ exposing templated functions.</li>
 
 <ul>
 <li><strong>Easy incorporation</strong>: This can be easily incorporated
- into external projects.</li>
+into external projects.</li>
 </ul>
 
 <h3 id="drawbacksofcompressed.h.cpppair">Drawbacks of compressed .h/.cpp pair</h3>
 
 <ul>
 <li><p><strong>Hard to debug/edit</strong>: The compressed files are
- automatically generated. They&#8217;re huge and should not be edited. Thus
- debugging and editing are near impossible.</p></li>
+automatically generated. They&#8217;re huge and should not be edited. Thus
+debugging and editing are near impossible.</p></li>
 <li><p><strong>Compounded dependencies</strong>:
- An immediate disadvantage of this
- seems to be that even to use a single function (e.g.
- <code>cotmatrix</code>), compiling and linking against
- <code>igl.cpp</code> will require linking to all of <code>libigl</code>&#8217;s
- dependencies (<code>OpenGL</code>, <code>GLUT</code>,
- <code>AntTweakBar</code>, <code>BLAS</code>). However, because all
- dependencies other than Eigen should be encapsulated between
- <code>#ifndef</code> guards (e.g. <code>#ifndef IGL_NO_OPENGL</code>, it
- is possible to ignore certain functions that have such dependencies.</p></li>
+An immediate disadvantage of this
+seems to be that even to use a single function (e.g.
+<code>cotmatrix</code>), compiling and linking against
+<code>igl.cpp</code> will require linking to all of <code>libigl</code>&#8217;s
+dependencies (<code>OpenGL</code>, <code>GLUT</code>,
+<code>AntTweakBar</code>, <code>BLAS</code>). However, because all
+dependencies other than Eigen should be encapsulated between
+<code>#ifndef</code> guards (e.g. <code>#ifndef IGL_NO_OPENGL</code>, it
+is possible to ignore certain functions that have such dependencies.</p></li>
 <li><p><strong>Long compile</strong>:
- Compiling <code>igl.cpp</code> takes a long time and isn&#8217;t easily parallelized (no <code>make
-  -j12</code> equivalent).</p></li>
+Compiling <code>igl.cpp</code> takes a long time and isn&#8217;t easily parallelized (no <code>make
+-j12</code> equivalent).</p></li>
 </ul>
 
 <p>Here&#8217;s a tiny test example using <code>igl.h</code> and <code>igl.cpp</code>. Save the following in <code>test.cpp</code>:</p>
@@ -334,7 +331,7 @@ return (argc&gt;=2 &amp;&amp; igl::read_triangle_mesh(argv[1],V,F)?0:1);
 <pre><code>grep OpenGL `grep -L IGL_NO_OPENGL include/igl/*`
 </code></pre>
 
-<h3 id="optional">Optional</h3>
+<h3 id="optional">Optional </h3>
 
 <ul>
 <li>OpenGL (disable with <code>IGL_NO_OPENGL</code>)
@@ -343,7 +340,7 @@ return (argc&gt;=2 &amp;&amp; igl::read_triangle_mesh(argv[1],V,F)?0:1);
 <li>OpenGL &gt;= 4 (enable with <code>IGL_OPENGL_4</code>)</li>
 </ul></li>
 <li>AntTweakBar (disable with <code>IGL_NO_ANTTWEAKBAR</code>) Last tested 1.16 (see
- <code>libigl/external/AntTweakBar</code>)</li>
+<code>libigl/external/AntTweakBar</code>)</li>
 <li>GLEW Windows and Linux</li>
 <li>OpenMP</li>
 <li>libpng libiglpng extra only</li>
@@ -361,7 +358,7 @@ return (argc&gt;=2 &amp;&amp; igl::read_triangle_mesh(argv[1],V,F)?0:1);
 <li>CoMiSo libcomiso extra only</li>
 </ul>
 
-<h3 id="optionalincludedinexternal">Optional (included in external/)</h3>
+<h3 id="optionalincludedinexternal">Optional (included in external/) </h3>
 
 <ul>
 <li>TetGen libigltetgen extra only</li>
@@ -373,3 +370,4 @@ return (argc&gt;=2 &amp;&amp; igl::read_triangle_mesh(argv[1],V,F)?0:1);
 
 </body>
 </html>
+

+ 7 - 7
python/iglhelpers.py

@@ -11,15 +11,15 @@ import pyigl as igl
 
 def p2e(m):
     if isinstance(m, np.ndarray):
-        if not m.flags['C_CONTIGUOUS']:
-            raise TypeError("p2e only support C-contiguous order")
-        if m.dtype.type == np.int32:
-            return igl.eigen.MatrixXi(m)
-        elif m.dtype.type == np.float64:
-            return igl.eigen.MatrixXd(m)
+        if not (m.flags['C_CONTIGUOUS'] or m.flags['F_CONTIGUOUS']):
+            raise TypeError('p2e support either c-order or f-order')
+        if m.dtype.type in [np.int32, np.int64]:
+            return igl.eigen.MatrixXi(m.astype(np.int32))
+        elif m.dtype.type in [np.float64, np.float32]:
+            return igl.eigen.MatrixXd(m.astype(np.float64))
         elif m.dtype.type == np.bool:
             return igl.eigen.MatrixXb(m)
-        raise TypeError("p2e only support dtype float64, int32 and bool")
+        raise TypeError("p2e only support dtype float64/32, int64/32 and bool")
     if sparse.issparse(m):
         # convert in a dense matrix with triples
         coo = m.tocoo()

+ 47 - 0
python/py_doc.cpp

@@ -598,6 +598,23 @@ const char *__doc_igl_embree_reorient_facets_raycast = R"igl_Qu8mg5v7(// Orient
     // Outputs:
     //   I  #F list of whether face has been flipped
     //   C  #F list of patch ID (output of bfs_orient > manifold patches))igl_Qu8mg5v7";
+const char *__doc_igl_exact_geodesic = R"igl_Qu8mg5v7( 
+    // Exact geodesic algorithm for triangular mesh with the implementation from https://code.google.com/archive/p/geodesic/,  
+    // and the algorithm first described by Mitchell, Mount and Papadimitriou in 1987 
+    //  
+    // Inputs: 
+    //   V  #V by 3 list of 3D vertex positions 
+    //   F  #F by 3 list of mesh faces 
+    //   VS #VS by 1 vector specifying indices of source vertices 
+    //   FS #FS by 1 vector specifying indices of source faces 
+    //   VT #VT by 1 vector specifying indices of target vertices 
+    //   FT #FT by 1 vector specifying indices of target faces 
+    // Output: 
+    //   D  #VT+#FT by 1 vector of geodesic distances of each target w.r.t. the nearest one in the source set 
+    // 
+    // Note:  
+    //      Specifying a face as target/source means its center.  
+    //)igl_Qu8mg5v7";
 const char *__doc_igl_find_cross_field_singularities = R"igl_Qu8mg5v7(// Inputs:
   //   V                #V by 3 eigen Matrix of mesh vertex 3D positions
   //   F                #F by 3 eigen Matrix of face (quad) indices
@@ -1453,3 +1470,33 @@ const char *__doc_igl_readPLY= R"igl_Qu8mg5v7(// Read a mesh from an ascii ply f
   //   N  double matrix of corner normals #N by 3
   //   UV #V by 2 texture coordinates
   // Returns true on success, false on errors)igl_Qu8mg5v7";
+const char *__doc_igl_seam_edges=R"igl_Qu8mg5v7(// Finds all UV-space boundaries of a mesh.
+  //
+  // Inputs:
+  //   V  #V by dim list of positions of the input mesh.
+  //   TC  #TC by 2 list of 2D texture coordinates of the input mesh
+  //   F  #F by 3 list of triange indices into V representing a
+  //     manifold-with-boundary triangle mesh
+  //   FTC  #F by 3 list of indices into TC for each corner
+  // Outputs:
+  //   seams  Edges where the forwards and backwards directions have different
+  //     texture coordinates, as a #seams-by-4 matrix of indices. Each row is
+  //     organized as [ forward_face_index, forward_face_vertex_index,
+  //     backwards_face_index, backwards_face_vertex_index ] such that one side
+  //     of the seam is the edge:
+  //         F[ seams( i, 0 ), seams( i, 1 ) ], F[ seams( i, 0 ), (seams( i, 1 ) + 1) % 3 ]
+  //     and the other side is the edge:
+  //         F[ seams( i, 2 ), seams( i, 3 ) ], F[ seams( i, 2 ), (seams( i, 3 ) + 1) % 3 ]
+  //   boundaries  Edges with only one incident triangle, as a #boundaries-by-2
+  //     matrix of indices. Each row is organized as 
+  //         [ face_index, face_vertex_index ]
+  //     such that the edge is:
+  //         F[ boundaries( i, 0 ), boundaries( i, 1 ) ], F[ boundaries( i, 0 ), (boundaries( i, 1 ) + 1) % 3 ]
+  //   foldovers  Edges where the two incident triangles fold over each other
+  //     in UV-space, as a #foldovers-by-4 matrix of indices.
+  //     Each row is organized as [ forward_face_index, forward_face_vertex_index,
+  //     backwards_face_index, backwards_face_vertex_index ]
+  //     such that one side of the foldover is the edge:
+  //       F[ foldovers( i, 0 ), foldovers( i, 1 ) ], F[ foldovers( i, 0 ), (foldovers( i, 1 ) + 1) % 3 ]
+  //     and the other side is the edge:
+  //       F[ foldovers( i, 2 ), foldovers( i, 3 ) ], F[ foldovers( i, 2 ), (foldovers( i, 3 ) + 1) % 3 ])igl_Qu8mg5v7";

+ 3 - 1
python/py_doc.h

@@ -48,6 +48,7 @@ extern const char *__doc_igl_eigs;
 extern const char *__doc_igl_embree_ambient_occlusion;
 extern const char *__doc_igl_embree_line_mesh_intersection;
 extern const char *__doc_igl_embree_reorient_facets_raycast;
+extern const char *__doc_igl_exact_geodesic;
 extern const char *__doc_igl_find_cross_field_singularities;
 extern const char *__doc_igl_fit_rotations;
 extern const char *__doc_igl_fit_rotations_planar;
@@ -99,6 +100,7 @@ extern const char *__doc_igl_readTGF;
 extern const char *__doc_igl_read_triangle_mesh;
 extern const char *__doc_igl_remove_duplicate_vertices;
 extern const char *__doc_igl_rotate_vectors;
+extern const char *__doc_igl_seam_edges;
 extern const char *__doc_igl_setdiff;
 extern const char *__doc_igl_signed_distance;
 extern const char *__doc_igl_signed_distance_pseudonormal;
@@ -125,4 +127,4 @@ extern const char *__doc_igl_winding_number_2;
 extern const char *__doc_igl_writeMESH;
 extern const char *__doc_igl_writeOBJ;
 extern const char *__doc_igl_writePLY;
-extern const char *__doc_igl_readPLY;
+extern const char *__doc_igl_readPLY;

+ 4 - 0
python/py_igl.cpp

@@ -44,6 +44,7 @@
 #include <igl/edge_lengths.h>
 #include <igl/edge_topology.h>
 #include <igl/eigs.h>
+#include <igl/exact_geodesic.h>
 #include <igl/find_cross_field_singularities.h>
 #include <igl/fit_rotations.h>
 #include <igl/floor.h>
@@ -102,6 +103,7 @@
 #include <igl/writeOBJ.h>
 #include <igl/writePLY.h>
 #include <igl/readPLY.h>
+#include <igl/seam_edges.h>
 
 void python_export_igl(py::module &m)
 {
@@ -141,6 +143,7 @@ void python_export_igl(py::module &m)
 #include "py_igl/py_edge_lengths.cpp"
 #include "py_igl/py_edge_topology.cpp"
 #include "py_igl/py_eigs.cpp"
+#include "py_igl/py_exact_geodesic.cpp"
 #include "py_igl/py_find_cross_field_singularities.cpp"
 #include "py_igl/py_fit_rotations.cpp"
 #include "py_igl/py_floor.cpp"
@@ -199,4 +202,5 @@ void python_export_igl(py::module &m)
 #include "py_igl/py_writeOBJ.cpp"
 #include "py_igl/py_writePLY.cpp"
 #include "py_igl/py_readPLY.cpp"
+#include "py_igl/py_seam_edges.cpp"
 }

+ 24 - 0
python/py_igl/py_exact_geodesic.cpp

@@ -0,0 +1,24 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2018 Zhongshi Jiang <jiangzs@nyu.edu>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+
+
+m.def("exact_geodesic", []
+(
+    const Eigen::MatrixXd &V,
+    const Eigen::MatrixXi &F,
+    const Eigen::MatrixXi &VS,
+    const Eigen::MatrixXi &FS,
+    const Eigen::MatrixXi &VT,
+    const Eigen::MatrixXi &FT,
+    Eigen::MatrixXd &D
+)
+{
+  return igl::exact_geodesic(V, F, VS,FS,VT,FT, D);
+}, __doc_igl_exact_geodesic,
+py::arg("V"), py::arg("F"), py::arg("VS"), py::arg("FS"), py::arg("VT"), py::arg("FT"), py::arg("D"));
+

+ 21 - 0
python/py_igl/py_seam_edges.cpp

@@ -0,0 +1,21 @@
+m.def("seam_edges", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXd& TC,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXi& FTC,
+  Eigen::MatrixXi& seams,
+  Eigen::MatrixXi& boundaries,
+  Eigen::MatrixXi& foldovers
+)
+{
+return igl::seam_edges( V, TC, F, FTC, seams, boundaries, foldovers);
+}, __doc_igl_seam_edges,
+py::arg("V"),
+py::arg("TC"),
+py::arg("F"),
+py::arg("FTC"),
+py::arg("seams"),
+py::arg("boundaries"),
+py::arg("foldovers"));
+

+ 14 - 16
style-guidelines.html

@@ -1,14 +1,11 @@
 <!DOCTYPE html>
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
 <head>
 	<meta charset="utf-8"/>
 	<title>libigl</title>
 	<meta name="author" content="Alec Jacobson and Daniele Panozzo and others"/>
 	<link type="text/css" rel="stylesheet" href="tutorial/style.css"/>
-<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
-<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
-<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
-<script>hljs.initHighlightingOnLoad();</script>
+<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script> <link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'> <script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script> <script>hljs.initHighlightingOnLoad();</script>
 </head>
 <body>
 
@@ -18,7 +15,7 @@
 style guidelines for <em>developers</em> of the library, but also acts as
 best-practices for users.</p>
 
-<h2 id="filefunction">One function, one .h/.cpp pair</h2>
+<h2 id="filefunction">One function, one .h/.cpp pair </h2>
 
 <p>The structure of libigl is very flat and function-based. For every
 function/sub-routine, create a single .h and .cpp file. For example, if you have
@@ -61,7 +58,7 @@ namespace igl
 }
 
 #ifndef IGL_STATIC_LIBRARY
-#  include &quot;example_fun.cpp&quot;
+#include &quot;example_fun.cpp&quot;
 #endif
 
 #endif
@@ -185,21 +182,21 @@ Eigen::SparseMatrix&lt;Atype&gt; adjacency_matrix(const ... &amp; F);
 <h2 id="templatingwitheigen">Templating with Eigen</h2>
 
 <p>Functions taking Eigen dense matrices/arrays as inputs and outputs (but <strong>not</strong>
-return arguments), should template on top of <code>Eigen::PlainObjectBase</code>. <strong>Each
+return arguments), should template on top of <code>Eigen::MatrixBase</code>. <strong>Each
 parameter</strong> should be derived using its own template.</p>
 
 <p>For example,</p>
 
 <pre><code class="cpp">template &lt;typename DerivedV, typename DerivedF, typename DerivedBC&gt;
 void barycenter(
-  const Eigen::PlainObjectBase&lt;DerivedV&gt; &amp; V,
-  const Eigen::PlainObjectBase&lt;DerivedF&gt; &amp; F,
-  const Eigen::PlainObjectBase&lt;DerivedBC&gt; &amp; BC);
+  const Eigen::MatrixBase&lt;DerivedV&gt; &amp; V,
+  const Eigen::MatrixBase&lt;DerivedF&gt; &amp; F,
+  const Eigen::MatrixBase&lt;DerivedBC&gt; &amp; BC);
 </code></pre>
 
 <p>The <code>Derived*</code> template encodes the scalar type (e.g. <code>double</code>, <code>int</code>), the
 number of rows and cols at compile time, and the data storage (Row-major vs.
-column-major). </p>
+column-major).</p>
 
 <p>Returning Eigen types is discouraged. In cases where the size and scalar type
 are a fixed <strong>and matching</strong> function of an input <code>Derived*</code> template, then
@@ -219,7 +216,7 @@ output-argument version and call that. So a full implementation looks like:</p>
 
 <pre><code class="cpp">template &lt;typename DerivedV, typename DerivedW&gt;
 void fit_to_unit_cube(
-  const Eigen::PlainObjectBase&lt;DerivedV&gt; &amp; V,
+  const Eigen::MatrixBase&lt;DerivedV&gt; &amp; V,
   Eigen::PlainObjectBase&lt;DerivedW&gt; &amp; W);
 template &lt;typename DerivedV&gt;
 void DerivedV fit_to_unit_cube(const Eigen::PlainObjectBase&lt;DerivedV&gt; &amp; V);
@@ -229,7 +226,7 @@ void DerivedV fit_to_unit_cube(const Eigen::PlainObjectBase&lt;DerivedV&gt; &amp
 
 <pre><code>template &lt;typename DerivedV, typename DerivedW&gt;
 void fit_to_unit_cube(
-  const Eigen::PlainObjectBase&lt;DerivedV&gt; &amp; V,
+  const Eigen::MatrixBase&lt;DerivedV&gt; &amp; V,
   Eigen::PlainObjectBase&lt;DerivedW&gt; &amp; W)
 {
   W = (V.rowwise()-V.colwise().minCoeff()).array() /
@@ -237,7 +234,7 @@ void fit_to_unit_cube(
 }
 
 template &lt;typename DerivedV&gt;
-void DerivedV fit_to_unit_cube(const Eigen::PlainObjectBase&lt;DerivedV&gt; &amp; V)
+void DerivedV fit_to_unit_cube(const Eigen::MatrixBase&lt;DerivedV&gt; &amp; V)
 {
   DerivedV W;
   fit_to_unit_cube(V,W);
@@ -274,7 +271,7 @@ to mean a list of faces/triangles.</p>
 <p>Classes should be avoided. When naming a class use CamelCase (e.g.
 SortableRow.h).</p>
 
-<h2 id="enumnamingconvertion">Enum naming conversion</h2>
+<h2 id="enumnamingconversion">Enum naming conversion</h2>
 
 <p>Enums types should be placed in the appropriate <code>igl::</code> namespace and should be
 named in CamelCase (e.g. <code>igl::SolverStatus</code>) and instances should be named in
@@ -392,3 +389,4 @@ implementation so we&#8217;re keeping it as long as possible and profitable.</p>
 
 </body>
 </html>
+

+ 5 - 0
tutorial/206_GeodesicDistance/CMakeLists.txt

@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(206_GeodesicDistance)
+
+add_executable(${PROJECT_NAME}_bin main.cpp)
+target_link_libraries(${PROJECT_NAME}_bin igl::core igl::opengl igl::opengl_glfw tutorials)

+ 73 - 0
tutorial/206_GeodesicDistance/main.cpp

@@ -0,0 +1,73 @@
+#include <igl/readOBJ.h>
+#include <igl/opengl/glfw/Viewer.h>
+#include <igl/exact_geodesic.h>
+#include <igl/colormap.h>
+#include <igl/unproject_onto_mesh.h>
+
+#include <iostream>
+#include "tutorial_shared_path.h"
+
+Eigen::MatrixXd V;
+Eigen::MatrixXi F;
+
+void plotMeshDistance(igl::opengl::glfw::Viewer& viewer, const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const Eigen::VectorXd& d, const double strip_size )
+{
+    // Rescale the function depending on the strip size
+    Eigen::VectorXd f = (d/strip_size);
+
+    // The function should be 1 on each integer coordinate
+    f = (f*M_PI).array().sin().abs();
+
+    // Compute per-vertex colors
+    Eigen::MatrixXd C;
+    igl::colormap(igl::COLOR_MAP_TYPE_INFERNO,f,false,C);
+
+    // Plot the mesh
+    viewer.data().set_mesh(V, F);
+    viewer.data().set_colors(C);
+}
+
+int main(int argc, char *argv[])
+{
+  using namespace Eigen;
+  using namespace std;
+
+  // Load a mesh in OFF format
+  igl::readOBJ(TUTORIAL_SHARED_PATH "/armadillo.obj", V, F);
+
+
+  igl::opengl::glfw::Viewer viewer;
+  // Plot a distance when a vertex is picked
+  viewer.callback_mouse_down =
+  [&](igl::opengl::glfw::Viewer& viewer, int, int)->bool
+  {
+      int fid;
+      Eigen::Vector3f bc;
+      // Cast a ray in the view direction starting from the mouse position
+      double x = viewer.current_mouse_x;
+      double y = viewer.core.viewport(3) - viewer.current_mouse_y;
+      if(igl::unproject_onto_mesh(Eigen::Vector2f(x,y), viewer.core.view * viewer.core.model,
+                                  viewer.core.proj, viewer.core.viewport, V, F, fid, bc))
+      {
+          int max;
+          bc.maxCoeff(&max);
+          int vid = F(fid,max);
+          Eigen::VectorXi VS,FS,VT,FT;
+          // The selected vertex is the source
+          VS.resize(1);
+          VS << vid;
+          // All vertices are the targets
+          VT.setLinSpaced(V.rows(),0,V.rows()-1);
+          Eigen::VectorXd d;
+          igl::exact_geodesic(V,F,VS,FS,VT,FT,d);
+
+          plotMeshDistance(viewer,V,F,d,0.05);
+      }
+      return false;
+  };
+  viewer.data().set_mesh(V,F);
+
+  cout << "Press [space] to smooth." << endl;;
+  cout << "Press [r] to reset." << endl;;
+  return viewer.launch();
+}

+ 1 - 0
tutorial/CMakeLists.txt

@@ -66,6 +66,7 @@ if(TUTORIALS_CHAPTER2)
   add_subdirectory("203_CurvatureDirections")
   add_subdirectory("204_Gradient")
   add_subdirectory("205_Laplacian")
+  add_subdirectory("206_GeodesicDistance")
 endif()
 
 # Chapter 3

BIN
tutorial/images/geodesicdistance.jpg


+ 1 - 1
tutorial/tutorial.html.REMOVED.git-id

@@ -1 +1 @@
-1dcb725e3bc41af89154fbadfd4b1d57e254c3a2
+8f9d830ca895398a806d67d62fd7f4598bb9f21a

+ 1 - 1
tutorial/tutorial.md.REMOVED.git-id

@@ -1 +1 @@
-96b0c1c12294ce44a5b90bad2868b33da79766a2
+41fe9810ef010cff31200f3c415b9c005560c67f