Преглед на файлове

Merge branch 'master' of https://github.com/libigl/libigl

Former-commit-id: 2609521aba04ef368f928ed53477ef3f49692ba5
Daniele Panozzo преди 11 години
родител
ревизия
5cc9d77ab5
променени са 100 файла, в които са добавени 2072 реда и са изтрити 925 реда
  1. 4 0
      README.md
  2. 1 0
      RELEASE_HISTORY.txt
  3. 1 1
      VERSION.txt
  4. 9 2
      examples/arap/Makefile
  5. 21 20
      examples/arap/example.cpp
  6. 2 2
      include/igl/C_STR.h
  7. 2 2
      include/igl/MCTables.hh
  8. 2 2
      include/igl/MouseController.h
  9. 2 2
      include/igl/OpenGL_convenience.h
  10. 2 2
      include/igl/STR.h
  11. 46 43
      include/igl/SortableRow.h
  12. 171 174
      include/igl/Timer.h
  13. 340 0
      include/igl/WindingNumberAABB.h
  14. 13 0
      include/igl/WindingNumberMethod.h
  15. 454 0
      include/igl/WindingNumberTree.h
  16. 28 28
      include/igl/add_barycenter.cpp
  17. 1 1
      include/igl/angular_distance.cpp
  18. 1 1
      include/igl/angular_distance.h
  19. 1 1
      include/igl/arap_rhs.h
  20. 18 17
      include/igl/barycentric2global.h
  21. 1 1
      include/igl/boost/bfs_orient.cpp
  22. 1 1
      include/igl/boost/bfs_orient.h
  23. 7 0
      include/igl/cgal/CGAL_includes.hpp
  24. 16 3
      include/igl/cgal/SelfIntersectMesh.h
  25. 7 0
      include/igl/cgal/intersect_other.cpp
  26. 7 0
      include/igl/cgal/intersect_other.h
  27. 7 0
      include/igl/cgal/mesh_to_cgal_triangle_list.cpp
  28. 7 0
      include/igl/cgal/mesh_to_cgal_triangle_list.h
  29. 11 3
      include/igl/cgal/selfintersect.cpp
  30. 10 1
      include/igl/cgal/selfintersect.h
  31. 9 2
      include/igl/dated_copy.cpp
  32. 2 2
      include/igl/dated_copy.h
  33. 7 0
      include/igl/dqs.cpp
  34. 7 0
      include/igl/dqs.h
  35. 1 1
      include/igl/draw_rectangular_marquee.cpp
  36. 2 1
      include/igl/draw_rectangular_marquee.h
  37. 2 2
      include/igl/embree/ambient_occlusion.cpp
  38. 2 2
      include/igl/embree/ambient_occlusion.h
  39. 3 3
      include/igl/embree/project_mesh.h
  40. 0 1
      include/igl/embree/reorient_facets_raycast.cpp
  41. 2 2
      include/igl/embree/reorient_facets_raycast.h
  42. 2 2
      include/igl/embree/unproject_in_mesh.cpp
  43. 2 2
      include/igl/embree/unproject_in_mesh.h
  44. 104 0
      include/igl/exterior_edges.cpp
  45. 26 0
      include/igl/exterior_edges.h
  46. 7 0
      include/igl/face_areas.cpp
  47. 0 143
      include/igl/file_dialog.cpp
  48. 0 44
      include/igl/file_dialog.h
  49. 86 0
      include/igl/file_dialog_open.cpp
  50. 30 0
      include/igl/file_dialog_open.h
  51. 87 0
      include/igl/file_dialog_save.cpp
  52. 31 0
      include/igl/file_dialog_save.h
  53. 24 23
      include/igl/fit_plane.cpp
  54. 1 1
      include/igl/flare_textures.h.REMOVED.git-id
  55. 7 0
      include/igl/harmonic.cpp
  56. 7 0
      include/igl/histc.cpp
  57. 2 2
      include/igl/hsv_to_rgb.cpp
  58. 2 2
      include/igl/hsv_to_rgb.h
  59. 7 0
      include/igl/is_planar.cpp
  60. 2 2
      include/igl/jet.cpp
  61. 2 2
      include/igl/jet.h
  62. 7 0
      include/igl/lbs_matrix.cpp
  63. 19 18
      include/igl/lens_flare.cpp
  64. 4 3
      include/igl/lens_flare.h
  65. 0 109
      include/igl/linsolve_with_fixed.h
  66. 29 28
      include/igl/local_basis.cpp
  67. 7 0
      include/igl/local_basis.h
  68. 7 0
      include/igl/marching_cubes.h
  69. 6 0
      include/igl/matlab/mexErrMsgTxt.h
  70. 7 0
      include/igl/partition.cpp
  71. 7 0
      include/igl/partition.h
  72. 8 1
      include/igl/path_to_executable.cpp
  73. 1 1
      include/igl/path_to_executable.h
  74. 7 0
      include/igl/png/texture_from_file.cpp
  75. 7 0
      include/igl/png/texture_from_file.h
  76. 7 0
      include/igl/png/texture_from_png.cpp
  77. 7 0
      include/igl/png/texture_from_png.h
  78. 2 2
      include/igl/pos.h
  79. 2 2
      include/igl/random_dir.cpp
  80. 2 2
      include/igl/random_dir.h
  81. 8 0
      include/igl/random_points_on_mesh.cpp
  82. 7 0
      include/igl/ray_sphere_intersect.cpp
  83. 7 0
      include/igl/readSTL.cpp
  84. 7 0
      include/igl/render_to_tga.cpp
  85. 7 0
      include/igl/render_to_tga.h
  86. 2 2
      include/igl/reorder.cpp
  87. 1 1
      include/igl/rgb_to_hsv.cpp
  88. 1 1
      include/igl/rgb_to_hsv.h
  89. 1 1
      include/igl/sample_edges.h
  90. 1 1
      include/igl/shine_textures.h.REMOVED.git-id
  91. 2 2
      include/igl/sort.cpp
  92. 2 2
      include/igl/svd3x3/arap_dof.h
  93. 8 4
      include/igl/svd3x3/polar_svd3x3.h
  94. 31 31
      include/igl/svd3x3/svd3x3.cpp
  95. 65 61
      include/igl/svd3x3/svd3x3_avx.cpp
  96. 68 62
      include/igl/svd3x3/svd3x3_sse.cpp
  97. 2 2
      include/igl/tetgen/mesh_with_skeleton.cpp
  98. 43 43
      include/igl/tetgen/mesh_with_skeleton.h
  99. 7 0
      include/igl/texture_from_tga.cpp
  100. 7 0
      include/igl/texture_from_tga.h

+ 4 - 0
README.md

@@ -25,6 +25,7 @@ listed below.
 - Mosek  libiglmosek extra only
 - Matlab  libiglmatlab extra only
 - boost  libiglboost, libiglcgal extra only
+- SSE/AVX  libiglsvd3x3 extra only
 - CGAL  libiglcgal extra only
     * boost 
     * gmp
@@ -154,6 +155,9 @@ To build the a static YImg library on Mac OS X issue:
     cd external/yimg
     make
 
+You may need to install libpng. Systems with X11 might find this already
+installed at `/usr/X11/lib`.
+
 
 ### Windows (Experimental) ###
 To build a static library (.lib) on windows, open Visual Studio 2010.

+ 1 - 0
RELEASE_HISTORY.txt

@@ -1,3 +1,4 @@
+0.4.6  Generalized Winding Numbers
 0.4.5  CGAL extra: mesh selfintersection
 0.4.4  STL file format support
 0.4.3  ARAP implementation

+ 1 - 1
VERSION.txt

@@ -3,4 +3,4 @@
 # Anyone may increment Minor to indicate a small change.
 # Major indicates a large change or large number of changes (upload to website)
 # World indicates a substantial change or release
-0.4.5
+0.4.6

+ 9 - 2
examples/arap/Makefile

@@ -23,11 +23,18 @@ EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 # YIMAGE Library
 YIMG=$(LIBIGL)/external/yimg/
-YIMG_LIB=-L$(YIMG) -lyimg -lz -L/usr/X11/lib -lpng -bind_at_load
+YIMG_LIB=-L$(YIMG) -lyimg -lz -L/opt/local/lib -lpng
 YIMG_INC=-I/usr/X11/include -I$(YIMG)
 
 ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
+ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar
+UNAME := $(shell uname)
+# Apple needs to load the AppKit framework for anttweakbar and maybe bind at
+# load for png
+ifeq ($(UNAME), Darwin)
+	YIMG_LIB+=-bind_at_load
+	ANTTWEAKBAR_LIB+=-framework AppKit
+endif
 
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(YIMG_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(YIMG_LIB)

+ 21 - 20
examples/arap/example.cpp

@@ -141,8 +141,6 @@ double bbd;
 int tot_num_samples = 0;
 #define REBAR_NAME "temp.rbr"
 igl::ReTwBar rebar; // Pointer to the tweak bar
-bool flip_y = false;
-bool rotate_xy = false;
 
 int num_in_selection(const Eigen::VectorXi & S)
 {
@@ -176,12 +174,17 @@ bool init_arap()
         b(bi) = v;
         bc(bi,S(v)) = 1;
         bi++;
-        if(S(v) == 0)
-        {
-          C.row(v) = RowVector3d(0.039,0.31,1);
-        }else
+        switch(S(v))
         {
-          C.row(v) = RowVector3d(1,0.41,0.70);
+          case 0:
+            C.row(v) = RowVector3d(0.039,0.31,1);
+            break;
+          case 1:
+            C.row(v) = RowVector3d(1,0.41,0.70);
+            break;
+          default:
+            C.row(v) = RowVector3d(0.4,0.8,0.3);
+            break;
         }
       }else
       {
@@ -223,25 +226,25 @@ bool update_arap()
         {
           case 0:
           {
-            //const double r = mid(0)*0.25;
-            //bc(bi,0) += r*cos(0.5*get_seconds()*2.*PI);
-            //bc(bi,1) -= r+r*sin(0.5*get_seconds()*2.*PI);
+            const double r = mid(0)*0.25;
+            bc(bi,0) += r*cos(0.5*get_seconds()*2.*PI);
+            bc(bi,1) -= r+r*sin(0.5*get_seconds()*2.*PI);
             break;
           }
           case 1:
           {
-            //const double r = mid(1)*0.15;
-            //bc(bi,1) += r+r*cos(0.15*get_seconds()*2.*PI);
-            //bc(bi,2) -= r*sin(0.15*get_seconds()*2.*PI);
+            const double r = mid(1)*0.15;
+            bc(bi,1) += r+r*cos(0.15*get_seconds()*2.*PI);
+            bc(bi,2) -= r*sin(0.15*get_seconds()*2.*PI);
 
             //// Pull-up
             //bc(bi,0) += 0.42;//mid(0)*0.5;
             //bc(bi,1) += 0.55;//mid(0)*0.5;
-            // Bend
-            Vector3d t(-1,0,0);
-            Quaterniond q(AngleAxisd(PI/1.5,Vector3d(0,1.0,0.1).normalized()));
-            const Vector3d a = bc.row(bi);
-            bc.row(bi) = (q*(a-t) + t) + Vector3d(1.5,0.1,0.9);
+            //// Bend
+            //Vector3d t(-1,0,0);
+            //Quaterniond q(AngleAxisd(PI/1.5,Vector3d(0,1.0,0.1).normalized()));
+            //const Vector3d a = bc.row(bi);
+            //bc.row(bi) = (q*(a-t) + t) + Vector3d(1.5,0.1,0.9);
                 
 
             break;
@@ -660,8 +663,6 @@ int main(int argc, char * argv[])
     "igl_trackball,two-a...-fixed-up");
   rebar.TwAddVarCB( "rotation_type", RotationTypeTW,
     set_rotation_type,get_rotation_type,NULL,"keyIncr=] keyDecr=[");
-  rebar.TwAddVarRW("flip_y", TW_TYPE_BOOLCPP, &flip_y,"key=f");
-  rebar.TwAddVarRW("rotate_xy", TW_TYPE_BOOLCPP, &rotate_xy,"key=r");
   rebar.load(REBAR_NAME);
 
   glutInitDisplayString( "rgba depth double samples>=8 ");

+ 2 - 2
include/igl/C_STR.h

@@ -5,8 +5,8 @@
 // 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 C_STR_H
-#define C_STR_H
+#ifndef IGL_C_STR_H
+#define IGL_C_STR_H
 // http://stackoverflow.com/a/2433143/148668
 // Suppose you have a function:
 //   void func(const char * c);

+ 2 - 2
include/igl/MCTables.hh

@@ -24,8 +24,8 @@
  \*===========================================================================*/
 
 //=============================================================================
-#ifndef ISOEX_MC_TABLES_HH
-#define ISOEX_MC_TABLES_HH
+#ifndef IGL_ISOEX_MC_TABLES_HH
+#define IGL_ISOEX_MC_TABLES_HH
 //=============================================================================
 
 

+ 2 - 2
include/igl/MouseController.h

@@ -5,8 +5,8 @@
 // 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 MOUSECONTROLLER_H
-#define MOUSECONTROLLER_H
+#ifndef IGL_MOUSECONTROLLER_H
+#define IGL_MOUSECONTROLLER_H
 // Needs to be included before others
 #include <Eigen/StdVector>
 #include <igl/RotateWidget.h>

+ 2 - 2
include/igl/OpenGL_convenience.h

@@ -5,8 +5,8 @@
 // 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 OPENGL_CONVENIENCE_H
-#define OPENGL_CONVENIENCE_H
+#ifndef IGL_OPENGL_CONVENIENCE_H
+#define IGL_OPENGL_CONVENIENCE_H
 #ifndef IGL_NO_OPENGL
 
 // Always use this:

+ 2 - 2
include/igl/STR.h

@@ -5,8 +5,8 @@
 // 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 STR_H
-#define STR_H
+#ifndef IGL_STR_H
+#define IGL_STR_H
 // http://stackoverflow.com/a/2433143/148668
 #include <string>
 #include <sstream>

+ 46 - 43
include/igl/SortableRow.h

@@ -12,56 +12,59 @@
 // reordering
 #include <Eigen/Core>
 
-// Templates:
-//   T  should be a matrix that implments .size(), and operator(int i)
-template <typename T>
-class SortableRow
+namespace igl
 {
-  public:
-    T data;
-  public:
-    SortableRow():data(){};
-    SortableRow(const T & data):data(data){};
-    bool operator<(const SortableRow & that) const
-    {
-      // Get reference so that I can use parenthesis
-      const SortableRow<T> & THIS = *this;
-      // Lexicographical
-      int minc = (THIS.data.size() < that.data.size()? 
-          THIS.data.size() : that.data.size());
-      // loop over columns
-      for(int i = 0;i<minc;i++)
+  // Templates:
+  //   T  should be a matrix that implments .size(), and operator(int i)
+  template <typename T>
+  class SortableRow
+  {
+    public:
+      T data;
+    public:
+      SortableRow():data(){};
+      SortableRow(const T & data):data(data){};
+      bool operator<(const SortableRow & that) const
       {
-        if(THIS.data(i) == that.data(i))
+        // Get reference so that I can use parenthesis
+        const SortableRow<T> & THIS = *this;
+        // Lexicographical
+        int minc = (THIS.data.size() < that.data.size()? 
+            THIS.data.size() : that.data.size());
+        // loop over columns
+        for(int i = 0;i<minc;i++)
         {
-          continue;
+          if(THIS.data(i) == that.data(i))
+          {
+            continue;
+          }
+          return THIS.data(i) < that.data(i);
         }
-        return THIS.data(i) < that.data(i);
-      }
-      // All characters the same, comes done to length
-      return THIS.data.size()<that.data.size();
-    };
-    bool operator==(const SortableRow & that) const
-    {
-      // Get reference so that I can use parenthesis
-      const SortableRow<T> & THIS = *this;
-      if(THIS.data.size() != that.data.size())
+        // All characters the same, comes done to length
+        return THIS.data.size()<that.data.size();
+      };
+      bool operator==(const SortableRow & that) const
       {
-        return false;
-      }
-      for(int i = 0;i<THIS.data.size();i++)
-      {
-        if(THIS.data(i) != that.data(i))
+        // Get reference so that I can use parenthesis
+        const SortableRow<T> & THIS = *this;
+        if(THIS.data.size() != that.data.size())
         {
           return false;
         }
-      }
-      return true;
-    };
-    bool operator!=(const SortableRow & that) const
-    {
-      return !(*this == that);
-    };
-};
+        for(int i = 0;i<THIS.data.size();i++)
+        {
+          if(THIS.data(i) != that.data(i))
+          {
+            return false;
+          }
+        }
+        return true;
+      };
+      bool operator!=(const SortableRow & that) const
+      {
+        return !(*this == that);
+      };
+  };
+}
 
 #endif

+ 171 - 174
include/igl/Timer.h

@@ -5,177 +5,174 @@
 // 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/.
-// High Resolution Timer.
-//
-// Resolution on Mac (clock tick)
-// Resolution on Linux (1 us not tested)
-// Resolution on Windows (clock tick not tested)
-
-#ifndef IGL_TIMER_H
-#define IGL_TIMER_H
-
-#ifdef WIN32   // Windows system specific
-#include <windows.h>
-#elif __APPLE__ // Unix based system specific
-#include <mach/mach_time.h> // for mach_absolute_time
-#else
-#include <sys/time.h>
-#endif
-
-namespace igl
-{
-  class Timer
-  {
-  public:
-    // default constructor
-    Timer():
-      stopped(0),
-#ifdef WIN32
-      frequency(),
-      startCount(),
-      endCount()
-#elif __APPLE__
-      startCount(0),
-      endCount(0)
-#else
-      startCount(),
-      endCount()
-#endif
-    {
-#ifdef WIN32
-      QueryPerformanceFrequency(&frequency);
-      startCount.QuadPart = 0;
-      endCount.QuadPart = 0;
-#elif __APPLE__
-      startCount = 0;
-      endCount = 0;
-#else
-      startCount.tv_sec = startCount.tv_usec = 0;
-      endCount.tv_sec = endCount.tv_usec = 0;
-#endif
-      
-      stopped = 0;
-    }
-    // default destructor
-    ~Timer()                     
-    {
-      
-    }
-    
-#ifdef __APPLE__
-    //Raw mach_absolute_times going in, difference in seconds out
-    double subtractTimes( uint64_t endTime, uint64_t startTime )
-    {
-      uint64_t difference = endTime - startTime;
-      static double conversion = 0.0;
-      
-      if( conversion == 0.0 )
-      {
-        mach_timebase_info_data_t info;
-        kern_return_t err = mach_timebase_info( &info );
-        
-        //Convert the timebase into seconds
-        if( err == 0  )
-          conversion = 1e-9 * (double) info.numer / (double) info.denom;
-      }
-      
-      return conversion * (double) difference;
-    }
-#endif
-    
-    // start timer
-    void   start()               
-    {
-      stopped = 0; // reset stop flag
-#ifdef WIN32
-      QueryPerformanceCounter(&startCount);
-#elif __APPLE__
-      startCount = mach_absolute_time();
-#else
-      gettimeofday(&startCount, NULL);
-#endif
-      
-    }
-    
-    // stop the timer
-    void   stop()                
-    {
-      stopped = 1; // set timer stopped flag
-      
-#ifdef WIN32
-      QueryPerformanceCounter(&endCount);
-#elif __APPLE__
-      endCount = mach_absolute_time();
-#else
-      gettimeofday(&endCount, NULL);
-#endif
-      
-    }
-    // get elapsed time in second
-    double getElapsedTime()      
-    {
-      return this->getElapsedTimeInSec();
-    }
-    // get elapsed time in second (same as getElapsedTime)
-    double getElapsedTimeInSec() 
-    {
-      return this->getElapsedTimeInMicroSec() * 0.000001;
-    }
-    
-    // get elapsed time in milli-second
-    double getElapsedTimeInMilliSec()
-    {
-      return this->getElapsedTimeInMicroSec() * 0.001;
-    }
-    // get elapsed time in micro-second
-    double getElapsedTimeInMicroSec()          
-    {
-      double startTimeInMicroSec = 0;
-      double endTimeInMicroSec = 0;
-
-#ifdef WIN32
-      if(!stopped)
-        QueryPerformanceCounter(&endCount);
-      
-      startTimeInMicroSec = 
-        startCount.QuadPart * (1000000.0 / frequency.QuadPart);
-      endTimeInMicroSec = endCount.QuadPart * (1000000.0 / frequency.QuadPart);
-#elif __APPLE__
-      if (!stopped)
-        endCount = mach_absolute_time();
-      
-      return subtractTimes(endCount,startCount)/1e-6;
-#else
-      if(!stopped)
-        gettimeofday(&endCount, NULL);
-      
-      startTimeInMicroSec = 
-        (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
-      endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
-#endif
-      
-      return endTimeInMicroSec - startTimeInMicroSec;
-    }
-    
-    
-  protected:
-    
-    
-  private:
-    // stop flag 
-    int    stopped;               
-#ifdef WIN32
-    // ticks per second
-    LARGE_INTEGER frequency;      
-    LARGE_INTEGER startCount;     
-    LARGE_INTEGER endCount;       
-#elif __APPLE__
-    uint64_t startCount;           
-    uint64_t endCount;             
-#else
-    timeval startCount;           
-    timeval endCount;             
-#endif
-  };
-}
-#endif // TIMER_H_DEF
+// High Resolution Timer.
+//
+// Resolution on Mac (clock tick)
+// Resolution on Linux (1 us not tested)
+// Resolution on Windows (clock tick not tested)
+
+#ifndef IGL_TIMER_H
+#define IGL_TIMER_H
+
+#ifdef WIN32   // Windows system specific
+#include <windows.h>
+#elif __APPLE__ // Unix based system specific
+#include <mach/mach_time.h> // for mach_absolute_time
+#else
+#include <sys/time.h>
+#endif
+
+namespace igl
+{
+  class Timer
+  {
+  public:
+    // default constructor
+    Timer():
+      stopped(0),
+#ifdef WIN32
+      frequency(),
+      startCount(),
+      endCount()
+#elif __APPLE__
+      startCount(0),
+      endCount(0)
+#else
+      startCount(),
+      endCount()
+#endif
+    {
+#ifdef WIN32
+      QueryPerformanceFrequency(&frequency);
+      startCount.QuadPart = 0;
+      endCount.QuadPart = 0;
+#elif __APPLE__
+      startCount = 0;
+      endCount = 0;
+#else
+      startCount.tv_sec = startCount.tv_usec = 0;
+      endCount.tv_sec = endCount.tv_usec = 0;
+#endif
+
+      stopped = 0;
+    }
+    // default destructor
+    ~Timer()                     
+    {
+
+    }
+
+#ifdef __APPLE__
+    //Raw mach_absolute_times going in, difference in seconds out
+    double subtractTimes( uint64_t endTime, uint64_t startTime )
+    {
+      uint64_t difference = endTime - startTime;
+      static double conversion = 0.0;
+
+      if( conversion == 0.0 )
+      {
+        mach_timebase_info_data_t info;
+        kern_return_t err = mach_timebase_info( &info );
+
+        //Convert the timebase into seconds
+        if( err == 0  )
+          conversion = 1e-9 * (double) info.numer / (double) info.denom;
+      }
+
+      return conversion * (double) difference;
+    }
+#endif
+
+    // start timer
+    void   start()               
+    {
+      stopped = 0; // reset stop flag
+#ifdef WIN32
+      QueryPerformanceCounter(&startCount);
+#elif __APPLE__
+      startCount = mach_absolute_time();
+#else
+      gettimeofday(&startCount, NULL);
+#endif
+
+    }
+
+    // stop the timer
+    void   stop()                
+    {
+      stopped = 1; // set timer stopped flag
+
+#ifdef WIN32
+      QueryPerformanceCounter(&endCount);
+#elif __APPLE__
+      endCount = mach_absolute_time();
+#else
+      gettimeofday(&endCount, NULL);
+#endif
+
+    }
+    // get elapsed time in second
+    double getElapsedTime()      
+    {
+      return this->getElapsedTimeInSec();
+    }
+    // get elapsed time in second (same as getElapsedTime)
+    double getElapsedTimeInSec() 
+    {
+      return this->getElapsedTimeInMicroSec() * 0.000001;
+    }
+
+    // get elapsed time in milli-second
+    double getElapsedTimeInMilliSec()
+    {
+      return this->getElapsedTimeInMicroSec() * 0.001;
+    }
+    // get elapsed time in micro-second
+    double getElapsedTimeInMicroSec()          
+    {
+      double startTimeInMicroSec = 0;
+      double endTimeInMicroSec = 0;
+
+#ifdef WIN32
+      if(!stopped)
+        QueryPerformanceCounter(&endCount);
+
+      startTimeInMicroSec = 
+        startCount.QuadPart * (1000000.0 / frequency.QuadPart);
+      endTimeInMicroSec = endCount.QuadPart * (1000000.0 / frequency.QuadPart);
+#elif __APPLE__
+      if (!stopped)
+        endCount = mach_absolute_time();
+
+      return subtractTimes(endCount,startCount)/1e-6;
+#else
+      if(!stopped)
+        gettimeofday(&endCount, NULL);
+
+      startTimeInMicroSec = 
+        (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
+      endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
+#endif
+
+      return endTimeInMicroSec - startTimeInMicroSec;
+    }
+
+  private:
+    // stop flag 
+    int    stopped;               
+#ifdef WIN32
+    // ticks per second
+    LARGE_INTEGER frequency;      
+    LARGE_INTEGER startCount;     
+    LARGE_INTEGER endCount;       
+#elif __APPLE__
+    uint64_t startCount;           
+    uint64_t endCount;             
+#else
+    timeval startCount;           
+    timeval endCount;             
+#endif
+  };
+}
+#endif // TIMER_H_DEF
+

+ 340 - 0
include/igl/WindingNumberAABB.h

@@ -0,0 +1,340 @@
+#ifndef IGL_WINDINGNUMBERAABB_H
+#define IGL_WINDINGNUMBERAABB_H
+#include "WindingNumberTree.h"
+
+namespace igl
+{
+  template <typename Point>
+  class WindingNumberAABB : public WindingNumberTree<Point>
+  {
+    protected:
+      Point min_corner;
+      Point max_corner;
+      double total_positive_area;
+    public: 
+      enum SplitMethod
+      {
+        CENTER_ON_LONGEST_AXIS = 0,
+        MEDIAN_ON_LONGEST_AXIS = 1,
+        NUM_SPLIT_METHODS = 3
+      } split_method;
+    public:
+      inline WindingNumberAABB(
+        const Eigen::MatrixXd & V,
+        const Eigen::MatrixXi & F);
+      inline WindingNumberAABB(
+        const WindingNumberTree<Point> & parent,
+        const Eigen::MatrixXi & F);
+      // Initialize some things
+      inline void init();
+      inline bool inside(const Point & p) const;
+      inline virtual void grow();
+      // Compute min and max corners
+      inline void compute_min_max_corners();
+      inline double max_abs_winding_number(const Point & p) const;
+      inline double max_simple_abs_winding_number(const Point & p) const;
+  };
+}
+
+// Implementation
+
+#include "winding_number.h"
+
+#include "barycenter.h"
+#include "median.h"
+#include "doublearea.h"
+#include "per_face_normals.h"
+
+#include <limits>
+#include <vector>
+#include <iostream>
+
+// Minimum number of faces in a hierarchy element (this is probably dependent
+// on speed of machine and compiler optimization)
+#ifndef WindingNumberAABB_MIN_F
+#  define WindingNumberAABB_MIN_F 100
+#endif
+
+template <typename Point>
+inline void igl::WindingNumberAABB<Point>::init()
+{
+  using namespace igl;
+  using namespace Eigen;
+  assert(max_corner.size() == 3);
+  assert(min_corner.size() == 3);
+  compute_min_max_corners();
+  VectorXd dblA;
+  doublearea(this->getV(),this->getF(),dblA);
+  total_positive_area = dblA.sum()/2.0;
+}
+
+template <typename Point>
+inline igl::WindingNumberAABB<Point>::WindingNumberAABB(
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & F):
+  WindingNumberTree<Point>(V,F),
+  min_corner(),
+  max_corner(),
+  total_positive_area(std::numeric_limits<double>::infinity()),
+  split_method(MEDIAN_ON_LONGEST_AXIS)
+{
+  init();
+}
+
+template <typename Point>
+inline igl::WindingNumberAABB<Point>::WindingNumberAABB(
+  const WindingNumberTree<Point> & parent,
+  const Eigen::MatrixXi & F):
+  WindingNumberTree<Point>(parent,F),
+  min_corner(),
+  max_corner(),
+  total_positive_area(std::numeric_limits<double>::infinity()),
+  split_method(MEDIAN_ON_LONGEST_AXIS)
+{
+  init();
+}
+
+template <typename Point>
+inline void igl::WindingNumberAABB<Point>::grow()
+{
+  using namespace std;
+  using namespace Eigen;
+  using namespace igl;
+  //cout<<"cap.rows(): "<<this->getcap().rows()<<endl;
+  //cout<<"F.rows(): "<<this->getF().rows()<<endl;
+
+  // Base cases
+  if(
+    this->getF().rows() <= (WindingNumberAABB_MIN_F>0?WindingNumberAABB_MIN_F:0) ||
+    (this->getcap().rows() - 2) >= this->getF().rows())
+  {
+    // Don't grow
+    return;
+  }
+
+  // Compute longest direction
+  int max_d = -1;
+  double max_len = -numeric_limits<double>::infinity();
+  for(int d = 0;d<min_corner.size();d++)
+  {
+    if( (max_corner[d] - min_corner[d]) > max_len )
+    {
+      max_len = (max_corner[d] - min_corner[d]);
+      max_d = d;
+    }
+  }
+  // Compute facet barycenters
+  MatrixXd BC;
+  barycenter(this->getV(),this->getF(),BC);
+
+
+  // Blerg, why is selecting rows so difficult
+
+  vector<int> id( this->getF().rows());
+  double split_value;
+  // Split in longest direction
+  switch(split_method)
+  {
+    case MEDIAN_ON_LONGEST_AXIS:
+      // Determine median
+      median(BC.col(max_d),split_value);
+      break;
+    default:
+      assert(false);
+    case CENTER_ON_LONGEST_AXIS:
+      split_value = 0.5*(max_corner[max_d] + min_corner[max_d]);
+      break;
+  }
+  //cout<<"c: "<<0.5*(max_corner[max_d] + min_corner[max_d])<<" "<<
+  //  "m: "<<split_value<<endl;;
+
+  for(int i = 0;i<this->getF().rows();i++)
+  {
+    if(BC(i,max_d) <= split_value)
+    {
+      id[i] = 0; //left
+    }else
+    {
+      id[i] = 1; //right
+    }
+  }
+
+  const int lefts = (int) count(id.begin(),id.end(),0);
+  const int rights = (int) count(id.begin(),id.end(),1);
+  if(lefts == 0 || rights == 0)
+  {
+    // badly balanced base case (could try to recut)
+    return;
+  }
+  assert(lefts+rights == this->getF().rows());
+  MatrixXi leftF(lefts,  this->getF().cols());
+  MatrixXi rightF(rights,this->getF().cols());
+  int left_i = 0;
+  int right_i = 0;
+  for(int i = 0;i<this->getF().rows();i++)
+  {
+    if(id[i] == 0)
+    {
+      leftF.row(left_i++) = this->getF().row(i);
+    }else if(id[i] == 1)
+    {
+      rightF.row(right_i++) = this->getF().row(i);
+    }else
+    {
+      assert(false);
+    }
+  }
+  assert(right_i == rightF.rows());
+  assert(left_i == leftF.rows());
+  // Finally actually grow children and Recursively grow
+  WindingNumberAABB<Point> * leftWindingNumberAABB = new WindingNumberAABB<Point>(*this,leftF);
+  leftWindingNumberAABB->grow();
+  this->children.push_back(leftWindingNumberAABB);
+  WindingNumberAABB<Point> * rightWindingNumberAABB = new WindingNumberAABB<Point>(*this,rightF);
+  rightWindingNumberAABB->grow();
+  this->children.push_back(rightWindingNumberAABB);
+}
+
+template <typename Point>
+inline bool igl::WindingNumberAABB<Point>::inside(const Point & p) const
+{
+  assert(p.size() == max_corner.size());
+  assert(p.size() == min_corner.size());
+  for(int i = 0;i<p.size();i++)
+  {
+    if( p(i) < min_corner(i) || p(i) >= max_corner(i))
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+template <typename Point>
+inline void igl::WindingNumberAABB<Point>::compute_min_max_corners()
+{
+  using namespace std;
+  // initialize corners
+  for(int d = 0;d<min_corner.size();d++)
+  {
+    min_corner[d] =  numeric_limits<double>::infinity();
+    max_corner[d] = -numeric_limits<double>::infinity();
+  }
+
+  this->center = Point(0,0,0);
+  // Loop over facets
+  for(int i = 0;i<this->getF().rows();i++)
+  {
+    for(int j = 0;j<this->getF().cols();j++)
+    {
+      for(int d = 0;d<min_corner.size();d++)
+      {
+        min_corner[d] = 
+          this->getV()(this->getF()(i,j),d) < min_corner[d] ?  
+            this->getV()(this->getF()(i,j),d) : min_corner[d];
+        max_corner[d] = 
+          this->getV()(this->getF()(i,j),d) > max_corner[d] ?  
+            this->getV()(this->getF()(i,j),d) : max_corner[d];
+      }
+      // This is biased toward vertices incident on more than one face, but
+      // perhaps that's good
+      this->center += this->getV().row(this->getF()(i,j));
+    }
+  }
+  // Average
+  this->center.array() /= this->getF().size();
+
+  //cout<<"min_corner: "<<this->min_corner.transpose()<<endl;
+  //cout<<"Center: "<<this->center.transpose()<<endl;
+  //cout<<"max_corner: "<<this->max_corner.transpose()<<endl;
+  //cout<<"Diag center: "<<((this->max_corner + this->min_corner)*0.5).transpose()<<endl;
+  //cout<<endl;
+
+  this->radius = (max_corner-min_corner).norm()/2.0;
+}
+
+template <typename Point>
+inline double igl::WindingNumberAABB<Point>::max_abs_winding_number(const Point & p) const
+{
+  using namespace std;
+  // Only valid if not inside
+  if(inside(p))
+  {
+    return numeric_limits<double>::infinity();
+  }
+  // Q: we know the total positive area so what's the most this could project
+  // to? Remember it could be layered in the same direction.
+  return numeric_limits<double>::infinity();
+}
+
+template <typename Point>
+inline double igl::WindingNumberAABB<Point>::max_simple_abs_winding_number(const Point & p) const
+{
+  using namespace std;
+  using namespace Eigen;
+  using namespace igl;
+  // Only valid if not inside
+  if(inside(p))
+  {
+    return numeric_limits<double>::infinity();
+  }
+  // Max simple is the same as sum of positive winding number contributions of
+  // bounding box
+
+  // begin precomputation
+  //MatrixXd BV((int)pow(2,3),3);
+  MatrixXd BV((int)(1<<3),3);
+  BV <<
+    min_corner[0],min_corner[1],min_corner[2],
+    min_corner[0],min_corner[1],max_corner[2],
+    min_corner[0],max_corner[1],min_corner[2],
+    min_corner[0],max_corner[1],max_corner[2],
+    max_corner[0],min_corner[1],min_corner[2],
+    max_corner[0],min_corner[1],max_corner[2],
+    max_corner[0],max_corner[1],min_corner[2],
+    max_corner[0],max_corner[1],max_corner[2];
+  MatrixXi BF(2*2*3,3);
+  BF <<
+    0,6,4,
+    0,2,6,
+    0,3,2,
+    0,1,3,
+    2,7,6,
+    2,3,7,
+    4,6,7,
+    4,7,5,
+    0,4,5,
+    0,5,1,
+    1,5,7,
+    1,7,3;
+  MatrixXd BFN;
+  per_face_normals(BV,BF,BFN);
+  // end of precomputation
+
+  // Only keep those with positive dot products
+  MatrixXi PBF(BF.rows(),BF.cols());
+  int pbfi = 0;
+  Point p2c = 0.5*(min_corner+max_corner)-p;
+  for(int i = 0;i<BFN.rows();i++)
+  {
+    if(p2c.dot(BFN.row(i)) > 0)
+    {
+      PBF.row(pbfi++) = BF.row(i);
+    }
+  }
+  PBF.conservativeResize(pbfi,PBF.cols());
+  double w = numeric_limits<double>::infinity();
+  igl::winding_number_3(
+    BV.data(),
+    BV.rows(),
+    PBF.data(),
+    PBF.rows(),
+    p.data(),
+    1,
+    &w);
+  return w;
+}
+
+//// Explicit instanciation
+//template class igl::WindingNumberAABB<Eigen::Vector3d >;
+#endif

+ 13 - 0
include/igl/WindingNumberMethod.h

@@ -0,0 +1,13 @@
+#ifndef IGL_WINDINGNUMBERMETHOD_H
+#define IGL_WINDINGNUMBERMETHOD_H
+namespace igl
+{
+  enum WindingNumberMethod
+  {
+    EXACT_WINDING_NUMBER_METHOD = 0, // Exact hierarchical evaluation
+    APPROX_SIMPLE_WINDING_NUMBER_METHOD = 1,
+    APPROX_CACHE_WINDING_NUMBER_METHOD = 2, // Approximate hierarchical evaluation
+    NUM_WINDING_NUMBER_METHODS = 3
+  };
+}
+#endif

+ 454 - 0
include/igl/WindingNumberTree.h

@@ -0,0 +1,454 @@
+#ifndef IGL_BOUNDINGTREE_H
+#define IGL_BOUNDINGTREE_H
+#include <list>
+#include <map>
+#include <Eigen/Dense>
+#include "WindingNumberMethod.h"
+
+namespace igl
+{
+  // Templates:
+  //   Point  type for points in space, e.g. Eigen::Vector3d
+  template <typename Point>
+  class WindingNumberTree
+  {
+    public:
+      // Method to use (see enum above)
+      //static double min_max_w;
+      static std::map< 
+        std::pair<const WindingNumberTree*,const WindingNumberTree*>, double>
+          cached;
+    protected:
+      WindingNumberMethod method;
+      const WindingNumberTree * parent;
+      std::list<WindingNumberTree * > children;
+      //// List of boundary edges (recall edges are vertices in 2d)
+      //const Eigen::MatrixXi boundary;
+      // Base mesh vertices
+      Eigen::MatrixXd & V;
+      // Base mesh vertices with duplicates removed
+      Eigen::MatrixXd SV;
+      // Facets in this bounding volume
+      Eigen::MatrixXi F;
+      // Tesselated boundary curve
+      Eigen::MatrixXi cap;
+      // Upper Bound on radius of enclosing ball
+      double radius;
+      // (Approximate) center (of mass)
+      Point center;
+    public:
+      // For root
+      inline WindingNumberTree(
+        const Eigen::MatrixXd & V,
+        const Eigen::MatrixXi & F);
+      // For chilluns 
+      inline WindingNumberTree(
+        const WindingNumberTree<Point> & parent,
+        const Eigen::MatrixXi & F);
+      inline virtual ~WindingNumberTree();
+      // Set method
+      inline void set_method( const WindingNumberMethod & m);
+    public:
+      inline const Eigen::MatrixXd & getV() const;
+      inline const Eigen::MatrixXi & getF() const;
+      inline const Eigen::MatrixXi & getcap() const;
+      // Grow the Tree recursively
+      inline virtual void grow();
+      // Determine whether a given point is inside the bounding 
+      //
+      // Inputs:
+      //   p  query point 
+      // Returns true if the point p is inside this bounding volume
+      inline virtual bool inside(const Point & p) const;
+      // Compute the (partial) winding number of a given point p
+      // According to method
+      //  
+      // Inputs:
+      //   p  query point 
+      // Returns winding number 
+      inline double winding_number(const Point & p) const;
+      // Same as above, but always computes winding number using exact method
+      // (sum over every facet)
+      inline double winding_number_all(const Point & p) const;
+      // Same as above, but always computes using sum over tesslated boundary
+      inline double winding_number_boundary(const Point & p) const;
+      //// Same as winding_number above, but if max_simple_abs_winding_number is
+      //// less than some threshold min_max_w just return 0 (colloquially the "fast
+      //// multipole method)
+      ////
+      ////
+      //// Inputs:
+      ////   p  query point 
+      ////   min_max_w  minimum max simple w to be processed
+      //// Returns approximate winding number
+      //double winding_number_approx_simple(
+      //  const Point & p, 
+      //  const double min_max_w);
+      // Print contents of Tree
+      //
+      // Optional input:
+      //   tab  tab to show depth
+      inline void print(const char * tab="");
+      // Determine max absolute winding number
+      //
+      // Inputs:
+      //   p  query point 
+      // Returns max winding number of 
+      inline virtual double max_abs_winding_number(const Point & p) const; 
+      // Same as above, but stronger assumptions on (V,F). Assumes (V,F) is a
+      // simple polyhedron
+      inline virtual double max_simple_abs_winding_number(const Point & p) const;
+      // Compute or read cached winding number for point p with respect to mesh
+      // in bounding box, recursing according to approximation criteria
+      //
+      // Inputs:
+      //   p  query point 
+      //   that  WindingNumberTree containing mesh w.r.t. which we're computing w.n.
+      // Returns cached winding number
+      inline virtual double cached_winding_number(const WindingNumberTree & that, const Point & p) const;
+  };
+}
+
+// Implementation
+
+#include "WindingNumberTree.h"
+#include "winding_number.h"
+#include "triangle_fan.h"
+#include "exterior_edges.h"
+
+#include <igl/PI.h>
+#include <igl/remove_duplicate_vertices.h>
+
+#include <iostream>
+#include <limits>
+
+//template <typename Point>
+//WindingNumberMethod WindingNumberTree<Point>::method = EXACT_WINDING_NUMBER_METHOD;
+//template <typename Point>
+//double WindingNumberTree<Point>::min_max_w = 0;
+template <typename Point>
+std::map< std::pair<const igl::WindingNumberTree<Point>*,const igl::WindingNumberTree<Point>*>, double>
+  igl::WindingNumberTree<Point>::cached;
+
+static Eigen::MatrixXd dummyV;
+template <typename Point>
+inline igl::WindingNumberTree<Point>::WindingNumberTree(
+  const Eigen::MatrixXd & _V,
+  const Eigen::MatrixXi & _F):
+  method(EXACT_WINDING_NUMBER_METHOD),
+  parent(NULL),
+  V(dummyV),
+  SV(),
+  F(),
+  //boundary(igl::boundary_faces<Eigen::MatrixXi,Eigen::MatrixXi>(F))
+  cap(),
+  radius(std::numeric_limits<double>::infinity()),
+  center(0,0,0)
+{
+  // Remove any exactly duplicate vertices
+  // Q: Can this ever increase the complexity of the boundary?
+  // Q: Would we gain even more by remove almost exactly duplicate vertices?
+  Eigen::MatrixXi SF,SVI,SVJ;
+  igl::remove_duplicate_vertices(_V,_F,0.0,SV,SVI,SVJ,F);
+  triangle_fan(exterior_edges(F),cap);
+  V = SV;
+}
+
+template <typename Point>
+inline igl::WindingNumberTree<Point>::WindingNumberTree(
+  const igl::WindingNumberTree<Point> & parent,
+  const Eigen::MatrixXi & _F):
+  method(parent.method),
+  parent(&parent),
+  V(parent.V),
+  SV(),
+  F(_F),
+  cap(triangle_fan(exterior_edges(_F)))
+{
+}
+
+template <typename Point>
+inline igl::WindingNumberTree<Point>::~WindingNumberTree()
+{
+  using namespace std;
+  // Delete children
+  typename list<WindingNumberTree<Point>* >::iterator cit = children.begin();
+  while(cit != children.end())
+  {
+    // clear the memory of this item
+    delete (* cit);
+    // erase from list, returns next element in iterator
+    cit = children.erase(cit);
+  }
+}
+      
+template <typename Point>
+inline void igl::WindingNumberTree<Point>::set_method(const WindingNumberMethod & m)
+{
+  this->method = m;
+  for(auto child : children)
+  {
+    child->set_method(m);
+  }
+}
+
+template <typename Point>
+inline const Eigen::MatrixXd & igl::WindingNumberTree<Point>::getV() const
+{
+  return V;
+}
+
+template <typename Point>
+inline const Eigen::MatrixXi & igl::WindingNumberTree<Point>::getF() const
+{
+  return F;
+}
+
+template <typename Point>
+inline const Eigen::MatrixXi & igl::WindingNumberTree<Point>::getcap() const
+{
+  return cap;
+}
+
+template <typename Point>
+inline void igl::WindingNumberTree<Point>::grow()
+{
+  // Don't grow
+  return;
+}
+
+template <typename Point>
+inline bool igl::WindingNumberTree<Point>::inside(const Point & /*p*/) const
+{
+  return true;
+}
+
+template <typename Point>
+inline double igl::WindingNumberTree<Point>::winding_number(const Point & p) const
+{
+  using namespace std;
+  //cout<<"+"<<boundary.rows();
+  // If inside then we need to be careful
+  if(inside(p))
+  {
+    // If not a leaf then recurse
+    if(children.size()>0)
+    {
+      // Recurse on each child and accumulate
+      double sum = 0;
+      for(
+        typename list<WindingNumberTree<Point>* >::const_iterator cit = children.begin();
+        cit != children.end();
+        cit++)
+      {
+        switch(method)
+        {
+          case EXACT_WINDING_NUMBER_METHOD:
+            sum += (*cit)->winding_number(p);
+            break;
+          case APPROX_SIMPLE_WINDING_NUMBER_METHOD:
+          case APPROX_CACHE_WINDING_NUMBER_METHOD:
+            //if((*cit)->max_simple_abs_winding_number(p) > min_max_w)
+            //{
+              sum += (*cit)->winding_number(p);
+            //}
+            break;
+          default:
+            assert(false);
+            break;
+        }
+      }
+      return sum;
+    }else
+    {
+      return winding_number_all(p);
+    }
+  }else{
+    // Otherwise we can just consider boundary
+    // Q: If we using the "multipole" method should we also subdivide the
+    // boundary case?
+    if((cap.rows() - 2) < F.rows())
+    {
+      switch(method)
+      {
+        case EXACT_WINDING_NUMBER_METHOD:
+          return winding_number_boundary(p);
+        case APPROX_SIMPLE_WINDING_NUMBER_METHOD:
+        {
+          double dist = (p-center).norm();
+          // Radius is already an overestimate of inside
+          if(dist>1.0*radius)
+          {
+            return 0;
+          }else
+          {
+            return winding_number_boundary(p);
+          }
+        }
+        case APPROX_CACHE_WINDING_NUMBER_METHOD:
+        {
+          return parent->cached_winding_number(*this,p);
+        }
+        default: assert(false);break;
+      }
+    }else
+    {
+      // doesn't pay off to use boundary
+      return winding_number_all(p);
+    }
+  }
+  return 0;
+}
+
+template <typename Point>
+inline double igl::WindingNumberTree<Point>::winding_number_all(const Point & p) const
+{
+  double w = 0;
+  igl::winding_number_3(
+    V.data(),
+    V.rows(),
+    F.data(),
+    F.rows(),
+    p.data(),
+    1,
+    &w);
+  return w;
+}
+
+template <typename Point>
+inline double igl::WindingNumberTree<Point>::winding_number_boundary(const Point & p) const
+{
+  using namespace Eigen;
+  using namespace std;
+
+  double w = 0;
+  igl::winding_number_3(
+    V.data(),
+    V.rows(),
+    cap.data(),
+    cap.rows(),
+    &p[0],
+    1,
+    &w);
+  return w;
+}
+
+//template <typename Point>
+//inline double igl::WindingNumberTree<Point>::winding_number_approx_simple(
+//  const Point & p, 
+//  const double min_max_w)
+//{
+//  using namespace std;
+//  if(max_simple_abs_winding_number(p) > min_max_w)
+//  {
+//    return winding_number(p);
+//  }else
+//  {
+//    cout<<"Skipped! "<<max_simple_abs_winding_number(p)<<"<"<<min_max_w<<endl;
+//    return 0;
+//  }
+//}
+
+template <typename Point>
+inline void igl::WindingNumberTree<Point>::print(const char * tab)
+{
+  using namespace std;
+  // Print all facets
+  cout<<tab<<"["<<endl<<F<<endl<<"]";
+  // Print children
+  for(
+      typename list<WindingNumberTree<Point>* >::iterator cit = children.begin();
+      cit != children.end();
+      cit++)
+  {
+    cout<<","<<endl;
+    (*cit)->print((string(tab)+"").c_str());
+  }
+}
+
+template <typename Point>
+inline double igl::WindingNumberTree<Point>::max_abs_winding_number(const Point & p) const
+{
+  return std::numeric_limits<double>::infinity();
+}
+
+template <typename Point>
+inline double igl::WindingNumberTree<Point>::max_simple_abs_winding_number(const Point & p) const
+{
+  using namespace std;
+  return numeric_limits<double>::infinity();
+}
+
+template <typename Point>
+inline double igl::WindingNumberTree<Point>::cached_winding_number(
+  const igl::WindingNumberTree<Point> & that,
+  const Point & p) const
+{
+  using namespace std;
+  using namespace igl;
+  // Simple metric for "far".
+  //   this             that
+  //                   --------
+  //   -----          /   |    \ .
+  //  /  r  \        /    R     \ .
+  // | p !   |      |     !      |
+  //  \_____/        \          /
+  //                  \________/
+  //
+  // 
+  // a = angle formed by trapazoid formed by raising sides with lengths r and R
+  // at respective centers.
+  //
+  // a = atan2(R-r,d), where d is the distance between centers
+
+  // That should be bigger (what about parent? what about sister?)
+  bool far = this->radius<that.radius;
+  if(far)
+  {
+    double a = atan2(
+      that.radius - this->radius,
+      (that.center - this->center).norm());
+    assert(a>0);
+    far = (a<PI/8.0);
+  }
+
+  if(far)
+  {
+    // Not implemented yet
+    pair<const WindingNumberTree*,const WindingNumberTree*> this_that(this,&that);
+    // Need to compute it for first time?
+    if(cached.count(this_that)==0)
+    {
+      cached[this_that] = 
+        that.winding_number_boundary(this->center);
+    }
+    return cached[this_that];
+  }else if(children.size() == 0)
+  {
+    // not far and hierarchy ended too soon: can't use cache
+    return that.winding_number_boundary(p);
+  }else
+  {
+    for(
+      typename list<WindingNumberTree<Point>* >::const_iterator cit = children.begin();
+      cit != children.end();
+      cit++)
+    {
+      if((*cit)->inside(p))
+      {
+        return (*cit)->cached_winding_number(that,p);
+      }
+    }
+    // Not inside any children? This can totally happen because bounding boxes
+    // are set to bound contained facets. So sibilings may overlap and their
+    // union may not contain their parent (though, their union is certainly a
+    // subset of their parent).
+    assert(false);
+  }
+  return 0;
+}
+
+// Explicit instanciation
+//template class igl::WindingNumberTree<Eigen::Vector3d >;
+
+#endif

+ 28 - 28
include/igl/add_barycenter.cpp

@@ -19,34 +19,34 @@ IGL_INLINE void igl::add_barycenter(
     Eigen::PlainObjectBase<Index> & FD)
 {
   using namespace Eigen;
-	// Compute face barycenter
-	Eigen::MatrixXd BC;
-	igl::barycenter(V,F,BC);
-
-	// Add the barycenters to the vertices
-	VD.resize(V.rows()+F.rows(),3);
-	VD.block(0,0,V.rows(),3) = V;
-	VD.block(V.rows(),0,F.rows(),3) = BC;
-
-	// Each face is split four ways
-	FD.resize(F.rows()*3,3);
-
-	for (unsigned i=0; i<F.rows(); ++i)
-	{
-		int i0 = F(i,0);
-		int i1 = F(i,1);
-		int i2 = F(i,2);
-		int i3 = V.rows() + i;
-
-		Vector3i F0,F1,F2;
-		F0 << i0,i1,i3;
-		F1 << i1,i2,i3;
-		F2 << i2,i0,i3;
-
-		FD.row(i*3 + 0) = F0;
-		FD.row(i*3 + 1) = F1;
-		FD.row(i*3 + 2) = F2;
-	}
+  // Compute face barycenter
+  Eigen::MatrixXd BC;
+  igl::barycenter(V,F,BC);
+
+  // Add the barycenters to the vertices
+  VD.resize(V.rows()+F.rows(),3);
+  VD.block(0,0,V.rows(),3) = V;
+  VD.block(V.rows(),0,F.rows(),3) = BC;
+
+  // Each face is split four ways
+  FD.resize(F.rows()*3,3);
+
+  for (unsigned i=0; i<F.rows(); ++i)
+  {
+    int i0 = F(i,0);
+    int i1 = F(i,1);
+    int i2 = F(i,2);
+    int i3 = V.rows() + i;
+
+    Vector3i F0,F1,F2;
+    F0 << i0,i1,i3;
+    F1 << i1,i2,i3;
+    F2 << i2,i0,i3;
+
+    FD.row(i*3 + 0) = F0;
+    FD.row(i*3 + 1) = F1;
+    FD.row(i*3 + 2) = F2;
+  }
 
 
 }

+ 1 - 1
include/igl/angular_distance.cpp

@@ -8,7 +8,7 @@
 #include "angular_distance.h"
 #include <igl/EPS.h>
 #include <igl/PI.h>
-double igl::angular_distance(
+IGL_INLINE double igl::angular_distance(
   const Eigen::Quaterniond & A,
   const Eigen::Quaterniond & B)
 {

+ 1 - 1
include/igl/angular_distance.h

@@ -18,7 +18,7 @@ namespace igl
   //   A  unit quaternion
   //   B  unit quaternion
   // Returns angular distance
-  double angular_distance(
+  IGL_INLINE double angular_distance(
     const Eigen::Quaterniond & A,
     const Eigen::Quaterniond & B);
 }

+ 1 - 1
include/igl/arap_rhs.h

@@ -27,7 +27,7 @@ namespace igl
   //     b = K * reshape(permute(R,[3 1 2]),size(V|F,1)*size(V,2)*size(V,2),1);
   //   
   // See also: arap_linear_block
-  void arap_rhs(
+  IGL_INLINE void arap_rhs(
     const Eigen::MatrixXd & V, 
     const Eigen::MatrixXi & F,
     const igl::ARAPEnergyType energy,

+ 18 - 17
include/igl/barycentric2global.h

@@ -14,24 +14,25 @@
 
 namespace igl 
 {
-	// Converts barycentric coordinates in the embree form to 3D coordinates
-	// Embree stores barycentric coordinates as triples: fid, bc1, bc2
-	// fid is the id of a face, bc1 is the displacement of the point wrt the 
-	// first vertex v0 and the edge v1-v0. Similarly, bc2 is the displacement
-	// wrt v2-v0.
-  	// 
-  	// Input:
-  	// V:  #Vx3 Vertices of the mesh
-  	// F:  #Fxe Faces of the mesh
-  	// bc: #Xx3 Barycentric coordinates, one row per point
-  	//
-  	// Output:
-  	// #X: #Xx3 3D coordinates of all points in bc
+  // Converts barycentric coordinates in the embree form to 3D coordinates
+  // Embree stores barycentric coordinates as triples: fid, bc1, bc2
+  // fid is the id of a face, bc1 is the displacement of the point wrt the 
+  // first vertex v0 and the edge v1-v0. Similarly, bc2 is the displacement
+  // wrt v2-v0.
+  // 
+  // Input:
+  // V:  #Vx3 Vertices of the mesh
+  // F:  #Fxe Faces of the mesh
+  // bc: #Xx3 Barycentric coordinates, one row per point
+  //
+  // Output:
+  // #X: #Xx3 3D coordinates of all points in bc
   template <typename Scalar, typename Index>
-  IGL_INLINE Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> barycentric2global(
-    const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> & V, 
-	  const Eigen::Matrix<Index,Eigen::Dynamic,Eigen::Dynamic>   & F, 
-    const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>  & bc);
+  IGL_INLINE Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> 
+    barycentric2global(
+      const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> & V, 
+      const Eigen::Matrix<Index,Eigen::Dynamic,Eigen::Dynamic>   & F, 
+      const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>  & bc);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 1 - 1
include/igl/boost/bfs_orient.cpp

@@ -11,7 +11,7 @@
 #include <queue>
 
 template <typename DerivedF, typename DerivedFF, typename DerivedC>
-void igl::bfs_orient(
+IGL_INLINE void igl::bfs_orient(
   const Eigen::PlainObjectBase<DerivedF> & F,
   Eigen::PlainObjectBase<DerivedFF> & FF,
   Eigen::PlainObjectBase<DerivedC> & C)

+ 1 - 1
include/igl/boost/bfs_orient.h

@@ -24,7 +24,7 @@ namespace igl
   //
   //
   template <typename DerivedF, typename DerivedFF, typename DerivedC>
-  void bfs_orient(
+  IGL_INLINE void bfs_orient(
     const Eigen::PlainObjectBase<DerivedF> & F,
     Eigen::PlainObjectBase<DerivedFF> & FF,
     Eigen::PlainObjectBase<DerivedC> & C);

+ 7 - 0
include/igl/cgal/CGAL_includes.hpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_CGAL_INCLUDES_H
 #define IGL_CGAL_INCLUDES_H
 

+ 16 - 3
include/igl/cgal/SelfIntersectMesh.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_SELFINTERSECTMESH_H
 #define IGL_SELFINTERSECTMESH_H
 
@@ -84,7 +91,8 @@ namespace igl
         const SelfintersectParam & params,
         Eigen::MatrixXd & VV,
         Eigen::MatrixXi & FF,
-        Eigen::MatrixXi & IF);
+        Eigen::MatrixXi & IF,
+        Eigen::VectorXi & J);
     private:
       // Helper function to mark a face as offensive
       //
@@ -243,7 +251,8 @@ inline igl::SelfIntersectMesh<Kernel>::SelfIntersectMesh(
   const SelfintersectParam & params,
   Eigen::MatrixXd & VV,
   Eigen::MatrixXi & FF,
-  Eigen::MatrixXi & IF):
+  Eigen::MatrixXi & IF,
+  Eigen::VectorXi & J):
   V(V),
   F(F),
   count(0),
@@ -442,6 +451,7 @@ inline igl::SelfIntersectMesh<Kernel>::SelfIntersectMesh(
 #endif
   // Append faces
   FF.resize(F.rows()-offending.size()+NF_count,3);
+  J.resize(FF.rows());
   // First append non-offending original faces
   // There's an Eigen way to do this in one line but I forget
   int off = 0;
@@ -449,7 +459,9 @@ inline igl::SelfIntersectMesh<Kernel>::SelfIntersectMesh(
   {
     if(!offensive[f])
     {
-      FF.row(off++) = F.row(f);
+      FF.row(off) = F.row(f);
+      J(off) = f;
+      off++;
     }
   }
   assert(off == (int)(F.rows()-offending.size()));
@@ -457,6 +469,7 @@ inline igl::SelfIntersectMesh<Kernel>::SelfIntersectMesh(
   for(int o = 0;o<(int)offending.size();o++)
   {
     FF.block(off,0,NF[o].rows(),3) = NF[o];
+    J.block(off,0,NF[o].rows(),1).setConstant(offending[o]);
     off += NF[o].rows();
   }
   // Append vertices

+ 7 - 0
include/igl/cgal/intersect_other.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "intersect_other.h"
 #include "CGAL_includes.hpp"
 #include "mesh_to_cgal_triangle_list.h"

+ 7 - 0
include/igl/cgal/intersect_other.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_INTERSECT_OTHER_H
 #define IGL_INTERSECT_OTHER_H
 #include <igl/igl_inline.h>

+ 7 - 0
include/igl/cgal/mesh_to_cgal_triangle_list.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "mesh_to_cgal_triangle_list.h"
 
 #include <cassert>

+ 7 - 0
include/igl/cgal/mesh_to_cgal_triangle_list.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_MESH_TO_CGAL_TRIANGLE_LIST_H
 #define IGL_MESH_TO_CGAL_TRIANGLE_LIST_H
 #include <igl/igl_inline.h>

+ 11 - 3
include/igl/cgal/selfintersect.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "selfintersect.h"
 #include "SelfIntersectMesh.h"
 #include <igl/C_STR.h>
@@ -9,7 +16,8 @@ IGL_INLINE void igl::selfintersect(
   const SelfintersectParam & params,
   Eigen::MatrixXd & VV,
   Eigen::MatrixXi & FF,
-  Eigen::MatrixXi & IF)
+  Eigen::MatrixXi & IF,
+  Eigen::VectorXi & J)
 {
   using namespace std;
   if(params.detect_only)
@@ -27,7 +35,7 @@ IGL_INLINE void igl::selfintersect(
 //#endif
 
     typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
-    SelfIntersectMesh<Kernel> SIM = SelfIntersectMesh<Kernel>(V,F,params,VV,FF,IF);
+    SelfIntersectMesh<Kernel> SIM = SelfIntersectMesh<Kernel>(V,F,params,VV,FF,IF,J);
 
 //#ifdef __APPLE__
 //    signal(SIGFPE,SIG_DFL);
@@ -36,6 +44,6 @@ IGL_INLINE void igl::selfintersect(
   }else
   {
     typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
-    SelfIntersectMesh<Kernel> SIM = SelfIntersectMesh<Kernel>(V,F,params,VV,FF,IF);
+    SelfIntersectMesh<Kernel> SIM = SelfIntersectMesh<Kernel>(V,F,params,VV,FF,IF,J);
   }
 }

+ 10 - 1
include/igl/cgal/selfintersect.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_SELFINTERSECT_H
 #define IGL_SELFINTERSECT_H
 #include <igl/igl_inline.h>
@@ -39,13 +46,15 @@ namespace igl
   //   FF  #FF by 3 list of triangle indices into V
   //   IF  #intersecting face pairs by 2  list of intersecting face pairs,
   //     indexing F
+  //   J  #FF list of indices into F denoting birth triangle
   IGL_INLINE void selfintersect(
     const Eigen::MatrixXd & V,
     const Eigen::MatrixXi & F,
     const SelfintersectParam & params,
     Eigen::MatrixXd & VV,
     Eigen::MatrixXi & FF,
-    Eigen::MatrixXi & IF);
+    Eigen::MatrixXi & IF,
+    Eigen::VectorXi & J);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 9 - 2
include/igl/dated_copy.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "dated_copy.h"
 #include "dirname.h"
 #include "basename.h"
@@ -9,7 +16,7 @@
 #include <unistd.h>
 #include <iostream>
 
-bool igl::dated_copy(const std::string & src_path, const std::string & dir)
+IGL_INLINE bool igl::dated_copy(const std::string & src_path, const std::string & dir)
 {
   using namespace std;
   using namespace igl;
@@ -75,7 +82,7 @@ bool igl::dated_copy(const std::string & src_path, const std::string & dir)
   return true;
 }
 
-bool igl::dated_copy(const std::string & src_path)
+IGL_INLINE bool igl::dated_copy(const std::string & src_path)
 {
   return dated_copy(src_path,dirname(src_path));
 }

+ 2 - 2
include/igl/dated_copy.h

@@ -20,9 +20,9 @@ namespace igl
   // Example:
   //   dated_copy("/path/to/foo","/bar/");
   //   // copies /path/to/foo to /bar/foo-2013-12-12T18-10-56
-  bool dated_copy(const std::string & src_path, const std::string & dir);
+  IGL_INLINE bool dated_copy(const std::string & src_path, const std::string & dir);
   // Wrapper using directory of source file
-  bool dated_copy(const std::string & src_path);
+  IGL_INLINE bool dated_copy(const std::string & src_path);
 }
 #ifdef IGL_HEADER_ONLY
 #  include "dated_copy.cpp"

+ 7 - 0
include/igl/dqs.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "dqs.h"
 #include <Eigen/Geometry>
 template <

+ 7 - 0
include/igl/dqs.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_DQS_H
 #define IGL_DQS_H
 #include "igl_inline.h"

+ 1 - 1
include/igl/draw_rectangular_marquee.cpp

@@ -9,7 +9,7 @@
 #include "OpenGL_convenience.h"
 #include "material_colors.h"
 
-void igl::draw_rectangular_marquee(
+IGL_INLINE void igl::draw_rectangular_marquee(
   const int from_x,
   const int from_y,
   const int to_x,

+ 2 - 1
include/igl/draw_rectangular_marquee.h

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_DRAW_RECTANGULAR_MARQUEE_H
 #define IGL_DRAW_RECTANGULAR_MARQUEE_H
+#include "igl_inline.h"
 namespace igl
 {
   // Draw a rectangular marquee (selection box) in screen space. This sets up
@@ -17,7 +18,7 @@ namespace igl
   //   from_y  y coordinate of from point
   //   to_x  x coordinate of to point
   //   to_y  y coordinate of to point
-  void draw_rectangular_marquee(
+  IGL_INLINE void draw_rectangular_marquee(
     const int from_x,
     const int from_y,
     const int to_x,

+ 2 - 2
include/igl/embree/ambient_occlusion.cpp

@@ -14,7 +14,7 @@ template <
   typename DerivedP,
   typename DerivedN,
   typename DerivedS >
-void igl::ambient_occlusion(
+IGL_INLINE void igl::ambient_occlusion(
   const igl::EmbreeIntersector & ei,
   const Eigen::PlainObjectBase<DerivedP> & P,
   const Eigen::PlainObjectBase<DerivedN> & N,
@@ -61,7 +61,7 @@ template <
   typename DerivedP,
   typename DerivedN,
   typename DerivedS >
-void igl::ambient_occlusion(
+IGL_INLINE void igl::ambient_occlusion(
   const Eigen::PlainObjectBase<DerivedV> & V,
   const Eigen::PlainObjectBase<DerivedF> & F,
   const Eigen::PlainObjectBase<DerivedP> & P,

+ 2 - 2
include/igl/embree/ambient_occlusion.h

@@ -27,7 +27,7 @@ namespace igl
     typename DerivedP,
     typename DerivedN,
     typename DerivedS >
-  void ambient_occlusion(
+  IGL_INLINE void ambient_occlusion(
     const igl::EmbreeIntersector & ei,
     const Eigen::PlainObjectBase<DerivedP> & P,
     const Eigen::PlainObjectBase<DerivedN> & N,
@@ -41,7 +41,7 @@ namespace igl
     typename DerivedP,
     typename DerivedN,
     typename DerivedS >
-  void ambient_occlusion(
+  IGL_INLINE void ambient_occlusion(
     const Eigen::PlainObjectBase<DerivedV> & V,
     const Eigen::PlainObjectBase<DerivedF> & F,
     const Eigen::PlainObjectBase<DerivedP> & P,

+ 3 - 3
include/igl/embree/project_mesh.h

@@ -35,11 +35,11 @@ namespace igl
   template <typename ScalarMatrix, typename IndexMatrix>
   IGL_INLINE ScalarMatrix project_mesh
   (
-		const ScalarMatrix & V_source,
-  	const IndexMatrix  & F_source,
+    const ScalarMatrix & V_source,
+    const IndexMatrix  & F_source,
     const ScalarMatrix & V_target,
     const IndexMatrix  & F_target
-	);
+  );
 
   // Project the point cloud V_source onto the triangle mesh
   // V_target,F_target. 

+ 0 - 1
include/igl/embree/reorient_facets_raycast.cpp

@@ -10,7 +10,6 @@
 #include "../doublearea.h"
 #include "../random_dir.h"
 #include "../boost/bfs_orient.h"
-#include "orient_outward_ao.h"
 #include "EmbreeIntersector.h"
 #include <iostream>
 #include <random>

+ 2 - 2
include/igl/embree/reorient_facets_raycast.h

@@ -5,8 +5,8 @@
 // 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_ORIENT_OUTWARD_AO_H
-#define IGL_ORIENT_OUTWARD_AO_H
+#ifndef IGL_REORIENT_FACETS_RAYCAST_H
+#define IGL_REORIENT_FACETS_RAYCAST_H
 #include "../igl_inline.h"
 #include <Eigen/Core>
 namespace igl

+ 2 - 2
include/igl/embree/unproject_in_mesh.cpp

@@ -12,7 +12,7 @@
 
 template <
   typename Derivedobj>
-int igl::unproject_in_mesh(
+IGL_INLINE int igl::unproject_in_mesh(
   const int x,
   const int y,
   const igl::EmbreeIntersector & ei,
@@ -24,7 +24,7 @@ int igl::unproject_in_mesh(
 
 template <
   typename Derivedobj>
-int igl::unproject_in_mesh(
+IGL_INLINE int igl::unproject_in_mesh(
   const int x,
   const int y,
   const igl::EmbreeIntersector & ei,

+ 2 - 2
include/igl/embree/unproject_in_mesh.h

@@ -30,7 +30,7 @@ namespace igl
   //
   template <
     typename Derivedobj>
-  int unproject_in_mesh(
+  IGL_INLINE int unproject_in_mesh(
     const int x,
     const int y,
     const igl::EmbreeIntersector & ei,
@@ -38,7 +38,7 @@ namespace igl
 
   template <
     typename Derivedobj>
-  int unproject_in_mesh(
+  IGL_INLINE int unproject_in_mesh(
     const int x,
     const int y,
     const igl::EmbreeIntersector & ei,

+ 104 - 0
include/igl/exterior_edges.cpp

@@ -0,0 +1,104 @@
+#include "exterior_edges.h"
+#include "all_edges.h"
+
+#include <cassert>
+#include <map>
+#include <utility>
+
+//template <typename T> inline int sgn(T val) {
+//      return (T(0) < val) - (val < T(0));
+//}
+
+//static void mod2(std::pair<const std::pair<const int, const int>, int>& p)
+//{
+//  using namespace std;
+//  // Be sure that sign of mod matches sign of argument
+//  p.second = p.second%2 ? sgn(p.second) : 0;
+//}
+
+//// http://stackoverflow.com/a/5517869/148668
+//struct Compare
+//{
+//   int i;
+//   Compare(const int& i) : i(i) {}
+//};
+//bool operator==(const std::pair<std::pair<const int, const int>,int>&p, const Compare& c)
+//{
+//  return c.i == p.second;
+//}
+//bool operator==(const Compare& c, const std::pair<std::pair<const int, const int>, int> &p)
+//{
+//  return c.i == p.second;
+//}
+
+IGL_INLINE void igl::exterior_edges(
+  const Eigen::MatrixXi & F,
+  Eigen::MatrixXi & E)
+{
+  using namespace Eigen;
+  using namespace std;
+  assert(F.cols() == 3);
+  MatrixXi all_E;
+  all_edges(F,all_E);
+  // Count occurances looking only at pairs (i,j) where i<j, so we count and
+  // edge i-->j as +1 and j-->i as -1
+  map<pair<const int,const int>,int> C;
+  // Loop over edges
+  for(int e = 0;e<all_E.rows();e++)
+  {
+    int i = all_E(e,0);
+    int j = all_E(e,1);
+    if(i<j)
+    {
+      // Forward direction --> +1
+      C[pair<const int,const int>(i,j)]++;
+    }else
+    {
+      // Backward direction --> -1
+      C[pair<const int,const int>(j,i)]--;
+    }
+  }
+  // Q: Why mod off factors of 2? +1/-1 already takes care of interior edges?
+  //// Mod off any factors of 2
+  //for_each(C.begin(),C.end(),mod2);
+  //int zeros = (int) count(C.begin(),C.end(),Compare(0));
+  //E.resize(C.size() - zeros,2);
+  E.resize(all_E.rows(),all_E.cols());
+  int e = 0;
+  // Find all edges with -1 or 1 occurances, flipping direction for -1
+  for(
+    map<pair<const int, const int>,int>::const_iterator cit=C.begin();
+    cit!=C.end();
+    cit++)
+  {
+    int i,j;
+    if(cit->second > 0)
+    {
+      i = cit->first.first;
+      j = cit->first.second;
+    } else if(cit->second < 0)
+    {
+      i = cit->first.second;
+      j = cit->first.first;
+    } else if(cit->second == 0)
+    {
+      continue;
+    }
+    for(int k = 0;k<abs(cit->second);k++)
+    {
+      E(e,0) = i;
+      E(e,1) = j;
+      e++;
+    }
+  }
+  E.conservativeResize(e,2);
+  assert(e == E.rows());
+}
+
+IGL_INLINE Eigen::MatrixXi igl::exterior_edges( const Eigen::MatrixXi & F)
+{
+  using namespace Eigen;
+  MatrixXi E;
+  exterior_edges(F,E);
+  return E;
+}

+ 26 - 0
include/igl/exterior_edges.h

@@ -0,0 +1,26 @@
+#ifndef IGL_EXTERIOR_EDGES_H
+#define IGL_EXTERIOR_EDGES_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // EXTERIOR_EDGES Determines boundary "edges" and also edges with an
+  // odd number of occurances where seeing edge (i,j) counts as +1 and seeing
+  // the opposite edge (j,i) counts as -1
+  //
+  // Inputs:
+  //   F  #F by simplex_size list of "faces"
+  // Outputs:
+  //   E  #E by simplex_size-1  list of exterior edges
+  //
+  IGL_INLINE void exterior_edges(
+    const Eigen::MatrixXi & F,
+    Eigen::MatrixXi & E);
+  // Inline version
+  Eigen::MatrixXi exterior_edges( const Eigen::MatrixXi & F);
+}
+#ifdef IGL_HEADER_ONLY
+#  include "exterior_edges.h"
+#endif
+
+#endif

+ 7 - 0
include/igl/face_areas.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "face_areas.h"
 #include "edge_lengths.h"
 #include "doublearea.h"

+ 0 - 143
include/igl/file_dialog.cpp

@@ -1,143 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 
-// obtain one at http://mozilla.org/MPL/2.0/.
-
-#define FILE_DIALOG_MAX_BUFFER 1024
-
-std::string IGL_INLINE igl::file_dialog_open()
-{
-  char buffer[FILE_DIALOG_MAX_BUFFER];
-  
-#ifdef __APPLE__
-  // For apple use applescript hack
-  FILE * output = popen(
-                        "osascript -e \""
-                        "   tell application \\\"System Events\\\"\n"
-                        "           activate\n"
-                        "           set existing_file to choose file\n"
-                        "   end tell\n"
-                        "   set existing_file_path to (POSIX path of (existing_file))\n"
-                        "\" 2>/dev/null | tr -d '\n' ","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
-  }
-#elif _WIN32
-  
-  // Use native windows file dialog box
-  // (code contributed by Tino Weinkauf)
-
-  OPENFILENAME ofn;       // common dialog box structure
-  char szFile[260];       // buffer for file name
-  HWND hwnd;              // owner window
-  HANDLE hf;              // file handle
-
-  // Initialize OPENFILENAME
-  ZeroMemory(&ofn, sizeof(ofn));
-  ofn.lStructSize = sizeof(ofn);
-  ofn.hwndOwner = NULL;//hwnd;
-  ofn.lpstrFile = new wchar_t[100];
-  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
-  // use the contents of szFile to initialize itself.
-  ofn.lpstrFile[0] = '\0';
-  ofn.nMaxFile = sizeof(szFile);
-  ofn.lpstrFilter = L"*.*\0";//off\0*.off\0obj\0*.obj\0mp\0*.mp\0";
-  ofn.nFilterIndex = 1;
-  ofn.lpstrFileTitle = NULL;
-  ofn.nMaxFileTitle = 0;
-  ofn.lpstrInitialDir = NULL;
-  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
-  // Display the Open dialog box. 
-  int pos = 0;
-  if (GetOpenFileName(&ofn)==TRUE)
-  {
-    while(ofn.lpstrFile[pos] != '\0')
-    {
-      buffer[pos] = (char)ofn.lpstrFile[pos];
-      pos++;
-    }
-    buffer[pos] = 0;
-  } 
-  
-#else
-  
-  // For linux use zenity
-  FILE * output = popen("/usr/bin/zenity --file-selection","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
-  }
-  
-  if (strlen(buffer) > 0)
-    buffer[strlen(buffer)-1] = 0;
-#endif
-  return std::string(buffer);
-}
-
-std::string IGL_INLINE igl::file_dialog_save()
-{
-  char buffer[FILE_DIALOG_MAX_BUFFER];
-#ifdef __APPLE__
-  // For apple use applescript hack
-  // There is currently a bug in Applescript that strips extensions off
-  // of chosen existing files in the "choose file name" dialog
-  // I'm assuming that will be fixed soon
-  FILE * output = popen(
-                        "osascript -e \""
-                        "   tell application \\\"System Events\\\"\n"
-                        "           activate\n"
-                        "           set existing_file to choose file name\n"
-                        "   end tell\n"
-                        "   set existing_file_path to (POSIX path of (existing_file))\n"
-                        "\" 2>/dev/null | tr -d '\n' ","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
-  }
-#elif _WIN32
-
-  // Use native windows file dialog box
-  // (code contributed by Tino Weinkauf)
-
-  OPENFILENAME ofn;       // common dialog box structure
-  char szFile[260];       // buffer for file name
-  HWND hwnd;              // owner window
-  HANDLE hf;              // file handle
-
-  // Initialize OPENFILENAME
-  ZeroMemory(&ofn, sizeof(ofn));
-  ofn.lStructSize = sizeof(ofn);
-  ofn.hwndOwner = NULL;//hwnd;
-  ofn.lpstrFile = new wchar_t[100];
-  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
-  // use the contents of szFile to initialize itself.
-  ofn.lpstrFile[0] = '\0';
-  ofn.nMaxFile = sizeof(szFile);
-  ofn.lpstrFilter = L"";
-  ofn.nFilterIndex = 1;
-  ofn.lpstrFileTitle = NULL;
-  ofn.nMaxFileTitle = 0;
-  ofn.lpstrInitialDir = NULL;
-  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
-  // Display the Open dialog box. 
-  int pos = 0;
-  if (GetSaveFileName(&ofn)==TRUE)
-  {
-    while(ofn.lpstrFile[pos] != '\0')
-    {
-      buffer[pos] = (char)ofn.lpstrFile[pos];
-      pos++;
-    }
-    buffer[pos] = 0;
-  }
-
-#else
-  // For every other machine type use zenity
-  FILE * output = popen("/usr/bin/zenity --file-selection --save","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
-  }
-  
-  if (strlen(buffer) > 0)
-    buffer[strlen(buffer)-1] = 0;
-#endif
-}

+ 0 - 44
include/igl/file_dialog.h

@@ -1,44 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_FILE_DIALOG_H
-#define IGL_FILE_DIALOG_H
-
-#include <stdio.h>
-#include <string>
-
-#ifdef _WIN32
- #include <Commdlg.h>
-#endif
-
-namespace igl
-{
-
-// Returns a string with a path to an existing file
-// The string is returned empty if no file is selected
-// (on Linux machines, it assumes that Zenity is installed)
-//
-// Usage:
-//   std::string str = get_open_file_path();
-std::string IGL_INLINE file_dialog_open();
-
-// Returns a string with a path to a new/existing file
-// The string is returned empty if no file is selected
-// (on Linux machines, it assumes that Zenity is installed)
-//
-// Usage:
-//   char buffer[FILE_DIALOG_MAX_BUFFER];
-//   get_save_file_path(buffer);
-std::string IGL_INLINE file_dialog_save();
-
-}
-
-#ifdef IGL_HEADER_ONLY
-#  include "file_dialog.cpp"
-#endif
-
-#endif

+ 86 - 0
include/igl/file_dialog_open.cpp

@@ -0,0 +1,86 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "file_dialog_open.h"
+#include <cstdio>
+
+
+#ifdef _WIN32
+ #include <Commdlg.h>
+#endif
+
+IGL_INLINE std::string igl::file_dialog_open()
+{
+  const int FILE_DIALOG_MAX_BUFFER = 1024;
+  char buffer[FILE_DIALOG_MAX_BUFFER];
+  
+#ifdef __APPLE__
+  // For apple use applescript hack
+  FILE * output = popen(
+    "osascript -e \""
+    "   tell application \\\"System Events\\\"\n"
+    "           activate\n"
+    "           set existing_file to choose file\n"
+    "   end tell\n"
+    "   set existing_file_path to (POSIX path of (existing_file))\n"
+    "\" 2>/dev/null | tr -d '\n' ","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  {
+  }
+#elif _WIN32
+  
+  // Use native windows file dialog box
+  // (code contributed by Tino Weinkauf)
+
+  OPENFILENAME ofn;       // common dialog box structure
+  char szFile[260];       // buffer for file name
+  HWND hwnd;              // owner window
+  HANDLE hf;              // file handle
+
+  // Initialize OPENFILENAME
+  ZeroMemory(&ofn, sizeof(ofn));
+  ofn.lStructSize = sizeof(ofn);
+  ofn.hwndOwner = NULL;//hwnd;
+  ofn.lpstrFile = new wchar_t[100];
+  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
+  // use the contents of szFile to initialize itself.
+  ofn.lpstrFile[0] = '\0';
+  ofn.nMaxFile = sizeof(szFile);
+  ofn.lpstrFilter = L"*.*\0";//off\0*.off\0obj\0*.obj\0mp\0*.mp\0";
+  ofn.nFilterIndex = 1;
+  ofn.lpstrFileTitle = NULL;
+  ofn.nMaxFileTitle = 0;
+  ofn.lpstrInitialDir = NULL;
+  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+  // Display the Open dialog box. 
+  int pos = 0;
+  if (GetOpenFileName(&ofn)==TRUE)
+  {
+    while(ofn.lpstrFile[pos] != '\0')
+    {
+      buffer[pos] = (char)ofn.lpstrFile[pos];
+      pos++;
+    }
+    buffer[pos] = 0;
+  } 
+  
+#else
+  
+  // For linux use zenity
+  FILE * output = popen("/usr/bin/zenity --file-selection","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  {
+  }
+  
+  if (strlen(buffer) > 0)
+  {
+    buffer[strlen(buffer)-1] = 0;
+  }
+#endif
+  return std::string(buffer);
+}

+ 30 - 0
include/igl/file_dialog_open.h

@@ -0,0 +1,30 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_FILE_DIALOG_OPEN_H
+#define IGL_FILE_DIALOG_OPEN_H
+#include "igl_inline.h"
+
+#include <string>
+
+namespace igl
+{
+  // Returns a string with a path to an existing file
+  // The string is returned empty if no file is selected
+  // (on Linux machines, it assumes that Zenity is installed)
+  //
+  // Usage:
+  //   std::string str = get_open_file_path();
+  IGL_INLINE std::string file_dialog_open();
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "file_dialog_open.cpp"
+#endif
+
+#endif
+

+ 87 - 0
include/igl/file_dialog_save.cpp

@@ -0,0 +1,87 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "file_dialog_save.h"
+#include <cstdio>
+
+
+#ifdef _WIN32
+ #include <Commdlg.h>
+#endif
+
+IGL_INLINE std::string igl::file_dialog_save()
+{
+  const int FILE_DIALOG_MAX_BUFFER = 1024;
+  char buffer[FILE_DIALOG_MAX_BUFFER];
+#ifdef __APPLE__
+  // For apple use applescript hack
+  // There is currently a bug in Applescript that strips extensions off
+  // of chosen existing files in the "choose file name" dialog
+  // I'm assuming that will be fixed soon
+  FILE * output = popen(
+    "osascript -e \""
+    "   tell application \\\"System Events\\\"\n"
+    "           activate\n"
+    "           set existing_file to choose file name\n"
+    "   end tell\n"
+    "   set existing_file_path to (POSIX path of (existing_file))\n"
+    "\" 2>/dev/null | tr -d '\n' ","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  {
+  }
+#elif _WIN32
+
+  // Use native windows file dialog box
+  // (code contributed by Tino Weinkauf)
+
+  OPENFILENAME ofn;       // common dialog box structure
+  char szFile[260];       // buffer for file name
+  HWND hwnd;              // owner window
+  HANDLE hf;              // file handle
+
+  // Initialize OPENFILENAME
+  ZeroMemory(&ofn, sizeof(ofn));
+  ofn.lStructSize = sizeof(ofn);
+  ofn.hwndOwner = NULL;//hwnd;
+  ofn.lpstrFile = new wchar_t[100];
+  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
+  // use the contents of szFile to initialize itself.
+  ofn.lpstrFile[0] = '\0';
+  ofn.nMaxFile = sizeof(szFile);
+  ofn.lpstrFilter = L"";
+  ofn.nFilterIndex = 1;
+  ofn.lpstrFileTitle = NULL;
+  ofn.nMaxFileTitle = 0;
+  ofn.lpstrInitialDir = NULL;
+  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+  // Display the Open dialog box. 
+  int pos = 0;
+  if (GetSaveFileName(&ofn)==TRUE)
+  {
+    while(ofn.lpstrFile[pos] != '\0')
+    {
+      buffer[pos] = (char)ofn.lpstrFile[pos];
+      pos++;
+    }
+    buffer[pos] = 0;
+  }
+
+#else
+  // For every other machine type use zenity
+  FILE * output = popen("/usr/bin/zenity --file-selection --save","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  {
+  }
+  
+  if (strlen(buffer) > 0)
+  {
+    buffer[strlen(buffer)-1] = 0;
+  }
+#endif
+  return std::string(buffer);
+}

+ 31 - 0
include/igl/file_dialog_save.h

@@ -0,0 +1,31 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_FILE_DIALOG_SAVE_H
+#define IGL_FILE_DIALOG_SAVE_H
+#include "igl_inline.h"
+
+#include <string>
+
+namespace igl
+{
+  // Returns a string with a path to a new/existing file
+  // The string is returned empty if no file is selected
+  // (on Linux machines, it assumes that Zenity is installed)
+  //
+  // Usage:
+  //   char buffer[FILE_DIALOG_MAX_BUFFER];
+  //   get_save_file_path(buffer);
+  IGL_INLINE std::string file_dialog_save();
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "file_dialog_save.cpp"
+#endif
+
+#endif
+

+ 24 - 23
include/igl/fit_plane.cpp

@@ -14,36 +14,37 @@ void igl::fit_plane(
     Eigen::RowVector3d & N,
     Eigen::RowVector3d & C)
 {
-    assert(V.rows()>0);
+  assert(V.rows()>0);
 
-    Eigen::Vector3d sum = V.colwise().sum();
+  Eigen::Vector3d sum = V.colwise().sum();
 
-    Eigen::Vector3d center = sum.array()/(double(V.rows()));
+  Eigen::Vector3d center = sum.array()/(double(V.rows()));
 
-    C = center;
+  C = center;
 
-    double sumXX=0.0f,sumXY=0.0f,sumXZ=0.0f;
-    double sumYY=0.0f,sumYZ=0.0f;
-    double sumZZ=0.0f;
+  double sumXX=0.0f,sumXY=0.0f,sumXZ=0.0f;
+  double sumYY=0.0f,sumYZ=0.0f;
+  double sumZZ=0.0f;
 
-    for(int i=0;i<V.rows();i++){
-        double diffX=V(i,0)-center(0);
-        double diffY=V(i,1)-center(1);
-        double diffZ=V(i,2)-center(2);
-        sumXX+=diffX*diffX;
-        sumXY+=diffX*diffY;
-        sumXZ+=diffX*diffZ;
-        sumYY+=diffY*diffY;
-        sumYZ+=diffY*diffZ;
-        sumZZ+=diffZ*diffZ;
-    }
+  for(int i=0;i<V.rows();i++)
+  {
+    double diffX=V(i,0)-center(0);
+    double diffY=V(i,1)-center(1);
+    double diffZ=V(i,2)-center(2);
+    sumXX+=diffX*diffX;
+    sumXY+=diffX*diffY;
+    sumXZ+=diffX*diffZ;
+    sumYY+=diffY*diffY;
+    sumYZ+=diffY*diffZ;
+    sumZZ+=diffZ*diffZ;
+  }
 
-    Eigen::MatrixXd m(3,3);
-    m << sumXX,sumXY,sumXZ,
-        sumXY,sumYY,sumYZ,
-        sumXZ,sumYZ,sumZZ;
+  Eigen::MatrixXd m(3,3);
+  m << sumXX,sumXY,sumXZ,
+    sumXY,sumYY,sumYZ,
+    sumXZ,sumYZ,sumZZ;
 
-	Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(m);
+  Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(m);
   
   N = es.eigenvectors().col(0);
 }

+ 1 - 1
include/igl/flare_textures.h.REMOVED.git-id

@@ -1 +1 @@
-da428b7e4052aa0f654f311c46b07a27bc50d653
+d7410116de836a2f96c3de72373ca1d089065867

+ 7 - 0
include/igl/harmonic.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "harmonic.h"
 #include "cotmatrix.h"
 #include "massmatrix.h"

+ 7 - 0
include/igl/histc.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "histc.h"
 #include "matlab_format.h"
 #include <cassert>

+ 2 - 2
include/igl/hsv_to_rgb.cpp

@@ -10,7 +10,7 @@
 
 
 template <typename T>
-void igl::hsv_to_rgb(const T * hsv, T * rgb)
+IGL_INLINE void igl::hsv_to_rgb(const T * hsv, T * rgb)
 {
   igl::hsv_to_rgb( 
       hsv[0],hsv[1],hsv[2],
@@ -18,7 +18,7 @@ void igl::hsv_to_rgb(const T * hsv, T * rgb)
 }
 
 template <typename T>
-void igl::hsv_to_rgb( 
+IGL_INLINE void igl::hsv_to_rgb( 
   const T & h, const T & s, const T & v, 
   T & r, T & g, T & b)
 {

+ 2 - 2
include/igl/hsv_to_rgb.h

@@ -21,9 +21,9 @@ namespace igl
   //   g  green value ([0,1])
   //   b  blue value ([0,1])
   template <typename T>
-  void hsv_to_rgb(const T * hsv, T * rgb);
+  IGL_INLINE void hsv_to_rgb(const T * hsv, T * rgb);
   template <typename T>
-  void hsv_to_rgb( 
+  IGL_INLINE void hsv_to_rgb( 
     const T & h, const T & s, const T & v, 
     T & r, T & g, T & b);
 };

+ 7 - 0
include/igl/is_planar.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "is_planar.h"
 IGL_INLINE bool igl::is_planar(const Eigen::MatrixXd & V)
 {

+ 2 - 2
include/igl/jet.cpp

@@ -54,13 +54,13 @@
 
 
 template <typename T>
-void igl::jet(const T x, T * rgb)
+IGL_INLINE void igl::jet(const T x, T * rgb)
 {
   igl::jet(x,rgb[0],rgb[1],rgb[2]);
 }
 
 template <typename T>
-void igl::jet(const T x, T & r, T & g, T & b)
+IGL_INLINE void igl::jet(const T x, T & r, T & g, T & b)
 {
   // Only important if the number of colors is small. In which case the rest is
   // still wrong anyway

+ 2 - 2
include/igl/jet.h

@@ -33,9 +33,9 @@ namespace igl
   //   g  green value
   //   b  blue value
   template <typename T>
-  void jet(const T f, T * rgb);
+  IGL_INLINE void jet(const T f, T * rgb);
   template <typename T>
-  void jet(const T f, T & r, T & g, T & b);
+  IGL_INLINE void jet(const T f, T & r, T & g, T & b);
 };
 
 #ifdef IGL_HEADER_ONLY

+ 7 - 0
include/igl/lbs_matrix.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "lbs_matrix.h"
 
 IGL_INLINE void igl::lbs_matrix(

+ 19 - 18
include/igl/lens_flare.cpp

@@ -18,25 +18,26 @@
 
 // http://www.opengl.org/archives/resources/features/KilgardTechniques/LensFlare/glflare.c
 
-static void setup_texture(
-  const uint8_t * texture, 
-  const int width,
-  const int height,
-  GLuint texobj,
-  GLenum minFilter, GLenum maxFilter)
-{
-  glBindTexture(GL_TEXTURE_2D, texobj);
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
-  glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0,
-    GL_LUMINANCE, GL_UNSIGNED_BYTE, texture);
-}
-
-void igl::lens_flare_load_textures(
+IGL_INLINE void igl::lens_flare_load_textures(
   std::vector<GLuint> & shine_id,
   std::vector<GLuint> & flare_id)
 {
+
+  const auto setup_texture =[](
+    const uint8_t * texture, 
+    const int width,
+    const int height,
+    GLuint texobj,
+    GLenum minFilter, GLenum maxFilter)
+  {
+    glBindTexture(GL_TEXTURE_2D, texobj);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
+    glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0,
+      GL_LUMINANCE, GL_UNSIGNED_BYTE, texture);
+  };
+
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   shine_id.resize(10);
   glGenTextures(10,&shine_id[0]);
@@ -58,7 +59,7 @@ void igl::lens_flare_load_textures(
   }
 }
 
-void igl::lens_flare_create(
+IGL_INLINE void igl::lens_flare_create(
   const float * A,
   const float * B,
   const float * C,
@@ -84,7 +85,7 @@ void igl::lens_flare_create(
   flares[11] = Flare(5, -1.0f, 0.03f, A, 0.2);
 }
 
-void igl::lens_flare_draw(
+IGL_INLINE void igl::lens_flare_draw(
   const std::vector<igl::Flare> & flares,
   const std::vector<GLuint> & shine_ids,
   const std::vector<GLuint> & flare_ids,

+ 4 - 3
include/igl/lens_flare.h

@@ -11,6 +11,7 @@
 #ifndef IGL_NO_OPENGL
 #include <igl/OpenGL_convenience.h>
 #include <Eigen/Core>
+#include "igl_inline.h"
 
 #include <vector>
 
@@ -45,7 +46,7 @@ namespace igl
   // Outputs:
   //   shine  list of texture ids for shines
   //   flare  list of texture ids for flares
-  void lens_flare_load_textures(
+  IGL_INLINE void lens_flare_load_textures(
     std::vector<GLuint> & shine_ids,
     std::vector<GLuint> & flare_ids);
   
@@ -57,7 +58,7 @@ namespace igl
   //   C  secondary color
   // Outputs:
   //   flares  list of flare objects
-  void lens_flare_create(
+  IGL_INLINE void lens_flare_create(
     const float * A,
     const float * B,
     const float * C,
@@ -74,7 +75,7 @@ namespace igl
   //   shine_tic  current "tic" in shine textures
   // Outputs:
   //   shine_tic  current "tic" in shine textures
-  void lens_flare_draw(
+  IGL_INLINE void lens_flare_draw(
     const std::vector<Flare> & flares,
     const std::vector<GLuint> & shine_ids,
     const std::vector<GLuint> & flare_ids,

+ 0 - 109
include/igl/linsolve_with_fixed.h

@@ -1,109 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 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 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_LINSOLVE_WITH_FIXED_H
-#define IGL_LINSOLVE_WITH_FIXED_H
-#include "igl_inline.h"
-
-#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
-#include <Eigen/Core>
-#include <Eigen/Dense>
-#include <Eigen/Sparse>
-#include <Eigen/SparseExtra>
-// Bug in unsupported/Eigen/SparseExtra needs iostream first
-#include <iostream>
-#include <unsupported/Eigen/SparseExtra>
-
-namespace igl
-{
-  // LINSOLVE_WITH_FIXED Solves a sparse linear system Ax=b with
-  // fixed known values in x
-
-  // Templates:
-  //   T  should be a eigen matrix primitive type like float or double
-  // Inputs:
-  //   A  m by n sparse matrix
-  //   b  n by k dense matrix, k is bigger than 1 for multiple right handsides
-  //   known list of indices to known rows in x (must be sorted in ascending order)
-  //   Y  list of fixed values corresponding to known rows in Z
-  // Outputs:
-  //   x  n by k dense matrix containing the solution
-
-  template<typename T, typename Derived>
-  inline void SolveLinearSystemWithBoundaryConditions(const SparseMatrix<T>& A, const MatrixBase<Derived>& b, const vector<int>& known, MatrixBase<Derived>& x)
-  {
-  const int rows = x.rows();
-  const int cols = x.cols();
-  SparseMatrix<T> AP(rows,rows);
-
-  const int knownCount = known.size();
-  const int unknownCount = rows - knownCount;
-  int knownIndex = 0;
-  int unknownIndex = 0;
-
-  if(knownCount >= rows)
-  {
-  std::cerr << "No unknowns to solve for!\n";
-  return;
-  }
-
-  // Permutate to sort by known boundary conditions -> [A1,A2] * [x1;x2]
-  VectorXi transpositions;
-  transpositions.resize(rows);
-  for(int n=0;n<rows;n++)
-  {
-    if(knownIndex < known.size() && n == known[knownIndex])
-    {
-      transpositions[unknownCount + knownIndex] = n;
-      knownIndex++;
-    }
-    else
-    {
-      transpositions[unknownIndex] = n;
-      unknownIndex++;
-    }
-  }
-  PermutationMatrix<Dynamic,Dynamic,int> P(transpositions);
-  PermutationMatrix<Dynamic,Dynamic,int> PInv = P.inverse();
-  A.twistedBy(PInv).evalTo(AP);
-
-  // Split in kown and unknown parts A1,A2,x2,b1
-  SparseMatrix<T> A1, A2;
-  internal::plain_matrix_type<Derived>::type x1, x2, b1;
-  x2 = (PInv*x).block(unknownCount,0,knownCount,cols);
-  b1 = (PInv*b).block(0,0,unknownCount,cols);
-
-  SparseMatrix<T> A1Temp(rows,unknownCount);
-  SparseMatrix<T> A2Temp(rows,knownCount);
-  A1Temp = AP.innerVectors(0,unknownCount).transpose();
-  A2Temp = AP.innerVectors(unknownCount,knownCount).transpose();
-  A1 = A1Temp.innerVectors(0,unknownCount).transpose();
-  A2 = A2Temp.innerVectors(0,unknownCount).transpose();
-
-  // Solve A1*x1 = b - A2*x2
-  SparseLU<SparseMatrix<T>> solver;
-  solver.compute(A1);
-  if (solver.info() != Eigen::Success)
-  {
-  std::cerr << "Matrix can not be decomposed.\n";
-  return;
-  }
-
-  internal::plain_matrix_type<Derived>::type t = b1-A2*x2;
-  x1 = solver.solve(t);
-  if (solver.info() != Eigen::Success)
-  {
-  std::cerr << "Solving failed.\n";
-  return;
-  }
-
-  // Compose resulting x
-  x.block(0,0,unknownCount,cols) = x1;
-  x.block(unknownCount,0,knownCount,cols) = x2;
-  x = P * x;
-  };
-}

+ 29 - 28
include/igl/local_basis.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "local_basis.h"
 
 #include <sstream>
@@ -7,39 +14,33 @@
 #include <vector>
 #include <Eigen/Geometry>
 
-using namespace Eigen;
-using namespace std;
 
-namespace igl
+template <typename DerivedV, typename DerivedF>
+IGL_INLINE void igl::local_basis(
+  const Eigen::PlainObjectBase<DerivedV>& V,
+  const Eigen::PlainObjectBase<DerivedF>& F,
+  Eigen::PlainObjectBase<DerivedV>& B1,
+  Eigen::PlainObjectBase<DerivedV>& B2,
+  Eigen::PlainObjectBase<DerivedV>& B3
+  )
 {
+  using namespace Eigen;
+  using namespace std;
+  B1.resize(F.rows(),3);
+  B2.resize(F.rows(),3);
+  B3.resize(F.rows(),3);
 
-  template <typename DerivedV, typename DerivedF>
-  IGL_INLINE void local_basis(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    Eigen::PlainObjectBase<DerivedV>& B1,
-    Eigen::PlainObjectBase<DerivedV>& B2,
-    Eigen::PlainObjectBase<DerivedV>& B3
-    )
+  for (unsigned i=0;i<F.rows();++i)
   {
-    B1.resize(F.rows(),3);
-    B2.resize(F.rows(),3);
-    B3.resize(F.rows(),3);
-
-    for (unsigned i=0;i<F.rows();++i)
-    {
-      RowVector3d v1 = (V.row(F(i,1)) - V.row(F(i,0))).normalized();
-      RowVector3d t = V.row(F(i,2)) - V.row(F(i,0));
-      RowVector3d v3 = v1.cross(t).normalized();
-      RowVector3d v2 = v1.cross(v3).normalized();
-
-      B1.row(i) = v1;
-      B2.row(i) = v2;
-      B3.row(i) = v3;
-    }
-
+    RowVector3d v1 = (V.row(F(i,1)) - V.row(F(i,0))).normalized();
+    RowVector3d t = V.row(F(i,2)) - V.row(F(i,0));
+    RowVector3d v3 = v1.cross(t).normalized();
+    RowVector3d v2 = v1.cross(v3).normalized();
+
+    B1.row(i) = v1;
+    B2.row(i) = v2;
+    B3.row(i) = v3;
   }
-
 }
 
 #ifndef IGL_HEADER_ONLY

+ 7 - 0
include/igl/local_basis.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_LOCALBASIS_H
 #define IGL_LOCALBASIS_H
 

+ 7 - 0
include/igl/marching_cubes.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_MARCHINGCUBES_H
 #define IGL_MARCHINGCUBES_H
 #include "igl_inline.h"

+ 6 - 0
include/igl/matlab/mexErrMsgTxt.h

@@ -5,9 +5,15 @@
 // 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_MEXERRMSGTXT_H
+#define IGL_MEXERRMSGTXT_H
 #include "../igl_inline.h"
 namespace igl
 {
   // Wrapper for mexErrMsgTxt that only calls error if test fails
   IGL_INLINE void mexErrMsgTxt(bool test, const char * message);
 }
+#ifdef IGL_HEADER_ONLY
+#  include "mexErrMsgTxt.cpp"
+#endif
+#endif

+ 7 - 0
include/igl/partition.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "partition.h"
 #include "mat_min.h"
 

+ 7 - 0
include/igl/partition.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_PARTITION_H
 #define IGL_PARTITION_H
 #include "igl_inline.h"

+ 8 - 1
include/igl/path_to_executable.cpp

@@ -1,8 +1,15 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "path_to_executable.h"
 #ifdef __APPLE__
 #  include <mach-o/dyld.h>
 #endif
-std::string igl::path_to_executable()
+IGL_INLINE std::string igl::path_to_executable()
 {
   // http://pastebin.com/ffzzxPzi
   using namespace std;

+ 1 - 1
include/igl/path_to_executable.h

@@ -13,7 +13,7 @@ namespace igl
 {
   // Return the path of the current executable.
   // Note: Tested for Mac OS X
-  std::string path_to_executable();
+  IGL_INLINE std::string path_to_executable();
 }
 #ifdef IGL_HEADER_ONLY
 #  include "path_to_executable.cpp"

+ 7 - 0
include/igl/png/texture_from_file.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "texture_from_file.h"
 #ifndef IGL_NO_OPENGL
 

+ 7 - 0
include/igl/png/texture_from_file.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_TEXTURE_FROM_FILE_H
 #define IGL_TEXTURE_FROM_FILE_H
 #ifndef IGL_NO_OPENGL

+ 7 - 0
include/igl/png/texture_from_png.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "texture_from_png.h"
 #ifndef IGL_NO_OPENGL
 

+ 7 - 0
include/igl/png/texture_from_png.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_TEXTURE_FROM_PNG_H
 #define IGL_TEXTURE_FROM_PNG_H
 #ifndef IGL_NO_OPENGL

+ 2 - 2
include/igl/pos.h

@@ -85,8 +85,8 @@ template <typename S>
       {
         do
         {
-					flipF();
-					flipE();
+          flipF();
+          flipE();
         } while (!isBorder());
         flipE();
         return false;

+ 2 - 2
include/igl/random_dir.cpp

@@ -9,7 +9,7 @@
 #include <igl/PI.h>
 #include <cmath>
 
-Eigen::Vector3d igl::random_dir()
+IGL_INLINE Eigen::Vector3d igl::random_dir()
 {
   using namespace Eigen;
   using namespace igl;
@@ -22,7 +22,7 @@ Eigen::Vector3d igl::random_dir()
   return Vector3d(x,y,z); 
 }
 
-Eigen::MatrixXd igl::random_dir_stratified(const int n)
+IGL_INLINE Eigen::MatrixXd igl::random_dir_stratified(const int n)
 {
   using namespace Eigen;
   using namespace igl;

+ 2 - 2
include/igl/random_dir.h

@@ -14,14 +14,14 @@
 namespace igl
 {
   // Generate a uniformly random unit direction in 3D, return as vector
-  Eigen::Vector3d random_dir();
+  IGL_INLINE Eigen::Vector3d random_dir();
   // Generate n stratified uniformly random unit directions in 3d, return as rows
   // of an n by 3 matrix
   //
   // Inputs:
   //   n  number of directions
   // Return n by 3 matrix of random directions
-  Eigen::MatrixXd random_dir_stratified(const int n);
+  IGL_INLINE Eigen::MatrixXd random_dir_stratified(const int n);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 8 - 0
include/igl/random_points_on_mesh.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "random_points_on_mesh.h"
 #include "doublearea.h"
 #include "cumsum.h"
@@ -27,6 +34,7 @@ IGL_INLINE void igl::random_points_on_mesh(
   VectorXs A0(A.size()+1);
   A0(0) = 0;
   A0.bottomRightCorner(A.size(),1) = A;
+  // Even faster would be to use the "Alias Table Method"
   cumsum(A0,1,C);
   const VectorXs R = (VectorXs::Random(n,1).array() + 1.)/2.;
   assert(R.minCoeff() >= 0);

+ 7 - 0
include/igl/ray_sphere_intersect.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "ray_sphere_intersect.h"
 
 template <

+ 7 - 0
include/igl/readSTL.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "readSTL.h"
 #include "list_to_matrix.h"
 

+ 7 - 0
include/igl/render_to_tga.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "render_to_tga.h"
 #ifndef IGL_NO_OPENGL
 #include "tga.h"

+ 7 - 0
include/igl/render_to_tga.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_RENDER_TO_TGA_H
 #define IGL_RENDER_TO_TGA_H
 #include "igl_inline.h"

+ 2 - 2
include/igl/reorder.cpp

@@ -34,7 +34,7 @@ IGL_INLINE void igl::reorder(
 template void igl::reorder<double>(std::vector<double, std::allocator<double> > const&, std::vector<size_t, std::allocator<size_t> > const&, std::vector<double, std::allocator<double> >&);
 template void igl::reorder<int>(std::vector<int, std::allocator<int> > const&, std::vector<size_t, std::allocator<size_t> > const&, std::vector<int, std::allocator<int> >&);
 #  ifndef IGL_NO_EIGEN
-  template void igl::reorder<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&);
-  template void igl::reorder<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&);
+  template void igl::reorder<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&);
+  template void igl::reorder<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&);
 #  endif
 #endif

+ 1 - 1
include/igl/rgb_to_hsv.cpp

@@ -8,7 +8,7 @@
 #include "rgb_to_hsv.h"
 
 template <typename R,typename H>
-void igl::rgb_to_hsv(const R * rgb, H * hsv)
+IGL_INLINE void igl::rgb_to_hsv(const R * rgb, H * hsv)
 {
   // http://en.literateprograms.org/RGB_to_HSV_color_space_conversion_%28C%29
   R rgb_max = 0.0;

+ 1 - 1
include/igl/rgb_to_hsv.h

@@ -21,7 +21,7 @@ namespace igl
   //   s  saturation value ([0,1])
   //   v  value value ([0,1])
   template <typename R,typename H>
-  void rgb_to_hsv(const R * rgb, H * hsv);
+  IGL_INLINE void rgb_to_hsv(const R * rgb, H * hsv);
 };
 
 #ifdef IGL_HEADER_ONLY

+ 1 - 1
include/igl/sample_edges.h

@@ -24,7 +24,7 @@ namespace igl
   // Output:
   //   S  sampled vertices, size less than # edges * (2+k) by dim always begins
   //        with V so that E is also defined over S
-  void sample_edges(
+  IGL_INLINE void sample_edges(
     const Eigen::MatrixXd & V,
     const Eigen::MatrixXi & E,
     const int k,

+ 1 - 1
include/igl/shine_textures.h.REMOVED.git-id

@@ -1 +1 @@
-11b49f50d620e2129b86410e169b00478cf71802
+0d5fca3720af7a84eac998513a77ff1ef619d5f0

+ 2 - 2
include/igl/sort.cpp

@@ -221,9 +221,9 @@ template void igl::sort<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<in
 // generated by autoexplicit.sh
 template void igl::sort<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::sort<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::sort<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
+template void igl::sort<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
 template void igl::sort<int>(std::vector<int, std::allocator<int> > const&, bool, std::vector<int, std::allocator<int> >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
-template void igl::sort<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
+template void igl::sort<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
 template void igl::sort2<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::sort2<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::sort_new<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

+ 2 - 2
include/igl/svd3x3/arap_dof.h

@@ -98,8 +98,8 @@ namespace igl
   // Inputs:
   //   fixed_dim  list of transformation element indices for fixed (or partailly
   //   fixed) handles: not necessarily the complement of 'free'
-  //	  NOTE: the constraints for fixed transformations still need to be
-  //	  present in A_eq
+  //    NOTE: the constraints for fixed transformations still need to be
+  //    present in A_eq
   //   A_eq  dim*#constraint_points by m*dim*(dim+1)  matrix of linear equality
   //     constraint coefficients. Each row corresponds to a linear constraint,
   //     so that A_eq * L = Beq says that the linear transformation entries in

+ 8 - 4
include/igl/svd3x3/polar_svd3x3.h

@@ -11,14 +11,18 @@
 #include <igl/igl_inline.h>
 namespace igl
 {
-  // Computes the closest rotation to input matrix A using specialized 3x3 SVD singular value decomposition (WunderSVD3x3)
+  // Computes the closest rotation to input matrix A using specialized 3x3 SVD
+  // singular value decomposition (WunderSVD3x3)
+  //
   // Inputs:
   //   A  3 by 3 matrix to be decomposed
   // Outputs:
-  //   R  3 by 3 closest element in SO(3) (closeness in terms of Frobenius metric)
+  //   R  3 by 3 closest element in SO(3) (closeness in terms of Frobenius
+  //   metric)
   //
-  //	This means that det(R) = 1. Technically it's not polar decomposition which guarantees positive semidefinite
-  //   stretch factor (at the cost of having det(R) = -1).
+  //  This means that det(R) = 1. Technically it's not polar decomposition
+  //  which guarantees positive semidefinite stretch factor (at the cost of
+  //  having det(R) = -1).
   //
   template<typename Mat>
   IGL_INLINE void polar_svd3x3(const Mat& A, Mat& R);

+ 31 - 31
include/igl/svd3x3/svd3x3.cpp

@@ -21,45 +21,45 @@
 template<typename T>
 IGL_INLINE void igl::svd3x3(const Eigen::Matrix<T, 3, 3>& A, Eigen::Matrix<T, 3, 3> &U, Eigen::Matrix<T, 3, 1> &S, Eigen::Matrix<T, 3, 3>&V)
 {
-	// this code only supports the scalar version (otherwise we'd need to pass arrays of matrices)	
+  // this code only supports the scalar version (otherwise we'd need to pass arrays of matrices)  
 
 #include "Singular_Value_Decomposition_Kernel_Declarations.hpp"
 
-	ENABLE_SCALAR_IMPLEMENTATION(Sa11.f=A(0,0);)                                      ENABLE_SSE_IMPLEMENTATION(Va11=_mm_loadu_ps(a11);)                                  ENABLE_AVX_IMPLEMENTATION(Va11=_mm256_loadu_ps(a11);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa21.f=A(1,0);)                                      ENABLE_SSE_IMPLEMENTATION(Va21=_mm_loadu_ps(a21);)                                  ENABLE_AVX_IMPLEMENTATION(Va21=_mm256_loadu_ps(a21);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa31.f=A(2,0);)                                      ENABLE_SSE_IMPLEMENTATION(Va31=_mm_loadu_ps(a31);)                                  ENABLE_AVX_IMPLEMENTATION(Va31=_mm256_loadu_ps(a31);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa12.f=A(0,1);)                                      ENABLE_SSE_IMPLEMENTATION(Va12=_mm_loadu_ps(a12);)                                  ENABLE_AVX_IMPLEMENTATION(Va12=_mm256_loadu_ps(a12);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa22.f=A(1,1);)                                      ENABLE_SSE_IMPLEMENTATION(Va22=_mm_loadu_ps(a22);)                                  ENABLE_AVX_IMPLEMENTATION(Va22=_mm256_loadu_ps(a22);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa32.f=A(2,1);)                                      ENABLE_SSE_IMPLEMENTATION(Va32=_mm_loadu_ps(a32);)                                  ENABLE_AVX_IMPLEMENTATION(Va32=_mm256_loadu_ps(a32);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa13.f=A(0,2);)                                      ENABLE_SSE_IMPLEMENTATION(Va13=_mm_loadu_ps(a13);)                                  ENABLE_AVX_IMPLEMENTATION(Va13=_mm256_loadu_ps(a13);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa23.f=A(1,2);)                                      ENABLE_SSE_IMPLEMENTATION(Va23=_mm_loadu_ps(a23);)                                  ENABLE_AVX_IMPLEMENTATION(Va23=_mm256_loadu_ps(a23);)
-		ENABLE_SCALAR_IMPLEMENTATION(Sa33.f=A(2,2);)                                      ENABLE_SSE_IMPLEMENTATION(Va33=_mm_loadu_ps(a33);)                                  ENABLE_AVX_IMPLEMENTATION(Va33=_mm256_loadu_ps(a33);)
+  ENABLE_SCALAR_IMPLEMENTATION(Sa11.f=A(0,0);)                                      ENABLE_SSE_IMPLEMENTATION(Va11=_mm_loadu_ps(a11);)                                  ENABLE_AVX_IMPLEMENTATION(Va11=_mm256_loadu_ps(a11);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa21.f=A(1,0);)                                      ENABLE_SSE_IMPLEMENTATION(Va21=_mm_loadu_ps(a21);)                                  ENABLE_AVX_IMPLEMENTATION(Va21=_mm256_loadu_ps(a21);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa31.f=A(2,0);)                                      ENABLE_SSE_IMPLEMENTATION(Va31=_mm_loadu_ps(a31);)                                  ENABLE_AVX_IMPLEMENTATION(Va31=_mm256_loadu_ps(a31);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa12.f=A(0,1);)                                      ENABLE_SSE_IMPLEMENTATION(Va12=_mm_loadu_ps(a12);)                                  ENABLE_AVX_IMPLEMENTATION(Va12=_mm256_loadu_ps(a12);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa22.f=A(1,1);)                                      ENABLE_SSE_IMPLEMENTATION(Va22=_mm_loadu_ps(a22);)                                  ENABLE_AVX_IMPLEMENTATION(Va22=_mm256_loadu_ps(a22);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa32.f=A(2,1);)                                      ENABLE_SSE_IMPLEMENTATION(Va32=_mm_loadu_ps(a32);)                                  ENABLE_AVX_IMPLEMENTATION(Va32=_mm256_loadu_ps(a32);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa13.f=A(0,2);)                                      ENABLE_SSE_IMPLEMENTATION(Va13=_mm_loadu_ps(a13);)                                  ENABLE_AVX_IMPLEMENTATION(Va13=_mm256_loadu_ps(a13);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa23.f=A(1,2);)                                      ENABLE_SSE_IMPLEMENTATION(Va23=_mm_loadu_ps(a23);)                                  ENABLE_AVX_IMPLEMENTATION(Va23=_mm256_loadu_ps(a23);)
+    ENABLE_SCALAR_IMPLEMENTATION(Sa33.f=A(2,2);)                                      ENABLE_SSE_IMPLEMENTATION(Va33=_mm_loadu_ps(a33);)                                  ENABLE_AVX_IMPLEMENTATION(Va33=_mm256_loadu_ps(a33);)
 
 #include "Singular_Value_Decomposition_Main_Kernel_Body.hpp"
 
-		ENABLE_SCALAR_IMPLEMENTATION(U(0,0)=Su11.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u11,Vu11);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u11,Vu11);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(1,0)=Su21.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u21,Vu21);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u21,Vu21);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(2,0)=Su31.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u31,Vu31);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u31,Vu31);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(0,1)=Su12.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u12,Vu12);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u12,Vu12);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(1,1)=Su22.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u22,Vu22);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u22,Vu22);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(2,1)=Su32.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u32,Vu32);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u32,Vu32);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(0,2)=Su13.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u13,Vu13);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u13,Vu13);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(1,2)=Su23.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u23,Vu23);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u23,Vu23);)
-		ENABLE_SCALAR_IMPLEMENTATION(U(2,2)=Su33.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u33,Vu33);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u33,Vu33);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(0,0)=Su11.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u11,Vu11);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u11,Vu11);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(1,0)=Su21.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u21,Vu21);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u21,Vu21);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(2,0)=Su31.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u31,Vu31);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u31,Vu31);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(0,1)=Su12.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u12,Vu12);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u12,Vu12);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(1,1)=Su22.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u22,Vu22);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u22,Vu22);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(2,1)=Su32.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u32,Vu32);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u32,Vu32);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(0,2)=Su13.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u13,Vu13);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u13,Vu13);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(1,2)=Su23.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u23,Vu23);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u23,Vu23);)
+    ENABLE_SCALAR_IMPLEMENTATION(U(2,2)=Su33.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(u33,Vu33);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(u33,Vu33);)
 
-		ENABLE_SCALAR_IMPLEMENTATION(V(0,0)=Sv11.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v11,Vv11);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v11,Vv11);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(1,0)=Sv21.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v21,Vv21);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v21,Vv21);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(2,0)=Sv31.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v31,Vv31);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v31,Vv31);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(0,1)=Sv12.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v12,Vv12);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v12,Vv12);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(1,1)=Sv22.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v22,Vv22);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v22,Vv22);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(2,1)=Sv32.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v32,Vv32);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v32,Vv32);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(0,2)=Sv13.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v13,Vv13);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v13,Vv13);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(1,2)=Sv23.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v23,Vv23);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v23,Vv23);)
-		ENABLE_SCALAR_IMPLEMENTATION(V(2,2)=Sv33.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v33,Vv33);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v33,Vv33);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(0,0)=Sv11.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v11,Vv11);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v11,Vv11);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(1,0)=Sv21.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v21,Vv21);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v21,Vv21);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(2,0)=Sv31.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v31,Vv31);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v31,Vv31);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(0,1)=Sv12.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v12,Vv12);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v12,Vv12);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(1,1)=Sv22.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v22,Vv22);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v22,Vv22);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(2,1)=Sv32.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v32,Vv32);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v32,Vv32);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(0,2)=Sv13.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v13,Vv13);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v13,Vv13);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(1,2)=Sv23.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v23,Vv23);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v23,Vv23);)
+    ENABLE_SCALAR_IMPLEMENTATION(V(2,2)=Sv33.f;)                                      ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(v33,Vv33);)                                 ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(v33,Vv33);)
 
-		ENABLE_SCALAR_IMPLEMENTATION(S(0,0)=Sa11.f;)                                   ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(sigma1,Va11);)                              ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(sigma1,Va11);)
-		ENABLE_SCALAR_IMPLEMENTATION(S(1,0)=Sa22.f;)                                   ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(sigma2,Va22);)                              ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(sigma2,Va22);)
-		ENABLE_SCALAR_IMPLEMENTATION(S(2,0)=Sa33.f;)                                   ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(sigma3,Va33);)                              ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(sigma3,Va33);)
+    ENABLE_SCALAR_IMPLEMENTATION(S(0,0)=Sa11.f;)                                   ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(sigma1,Va11);)                              ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(sigma1,Va11);)
+    ENABLE_SCALAR_IMPLEMENTATION(S(1,0)=Sa22.f;)                                   ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(sigma2,Va22);)                              ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(sigma2,Va22);)
+    ENABLE_SCALAR_IMPLEMENTATION(S(2,0)=Sa33.f;)                                   ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(sigma3,Va33);)                              ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(sigma3,Va33);)
 }
 #pragma runtime_checks( "u", restore ) 
 

+ 65 - 61
include/igl/svd3x3/svd3x3_avx.cpp

@@ -20,78 +20,82 @@
 
 #pragma runtime_checks( "u", off )  // disable runtime asserts on xor eax,eax type of stuff (doesn't always work, disable explicitly in compiler settings)
 template<typename T>
-IGL_INLINE void igl::svd3x3_avx(const Eigen::Matrix<T, 3*8, 3>& A, Eigen::Matrix<T, 3*8, 3> &U, Eigen::Matrix<T, 3*8, 1> &S, Eigen::Matrix<T, 3*8, 3>&V)
+IGL_INLINE void igl::svd3x3_avx(
+  const Eigen::Matrix<T, 3*8, 3>& A, 
+  Eigen::Matrix<T, 3*8, 3> &U, 
+  Eigen::Matrix<T, 3*8, 1> &S, 
+  Eigen::Matrix<T, 3*8, 3>&V)
 {
-	// this code assumes USE_AVX_IMPLEMENTATION is defined 
-	float Ashuffle[9][8], Ushuffle[9][8], Vshuffle[9][8], Sshuffle[3][8];
-	for (int i=0; i<3; i++)
-	{
-		for (int j=0; j<3; j++)
-		{
-			for (int k=0; k<8; k++)
-			{
-				Ashuffle[i + j*3][k] = A(i + 3*k, j);
-			}
-		}
-	}
+  // this code assumes USE_AVX_IMPLEMENTATION is defined 
+  float Ashuffle[9][8], Ushuffle[9][8], Vshuffle[9][8], Sshuffle[3][8];
+  for (int i=0; i<3; i++)
+  {
+    for (int j=0; j<3; j++)
+    {
+      for (int k=0; k<8; k++)
+      {
+        Ashuffle[i + j*3][k] = A(i + 3*k, j);
+      }
+    }
+  }
 
 #include "Singular_Value_Decomposition_Kernel_Declarations.hpp"
 
-		ENABLE_AVX_IMPLEMENTATION(Va11=_mm256_loadu_ps(Ashuffle[0]);)
-		ENABLE_AVX_IMPLEMENTATION(Va21=_mm256_loadu_ps(Ashuffle[1]);)
-		ENABLE_AVX_IMPLEMENTATION(Va31=_mm256_loadu_ps(Ashuffle[2]);)
-		ENABLE_AVX_IMPLEMENTATION(Va12=_mm256_loadu_ps(Ashuffle[3]);)
-		ENABLE_AVX_IMPLEMENTATION(Va22=_mm256_loadu_ps(Ashuffle[4]);)
-		ENABLE_AVX_IMPLEMENTATION(Va32=_mm256_loadu_ps(Ashuffle[5]);)
-		ENABLE_AVX_IMPLEMENTATION(Va13=_mm256_loadu_ps(Ashuffle[6]);)
-		ENABLE_AVX_IMPLEMENTATION(Va23=_mm256_loadu_ps(Ashuffle[7]);)
-		ENABLE_AVX_IMPLEMENTATION(Va33=_mm256_loadu_ps(Ashuffle[8]);)
+  ENABLE_AVX_IMPLEMENTATION(Va11=_mm256_loadu_ps(Ashuffle[0]);)
+  ENABLE_AVX_IMPLEMENTATION(Va21=_mm256_loadu_ps(Ashuffle[1]);)
+  ENABLE_AVX_IMPLEMENTATION(Va31=_mm256_loadu_ps(Ashuffle[2]);)
+  ENABLE_AVX_IMPLEMENTATION(Va12=_mm256_loadu_ps(Ashuffle[3]);)
+  ENABLE_AVX_IMPLEMENTATION(Va22=_mm256_loadu_ps(Ashuffle[4]);)
+  ENABLE_AVX_IMPLEMENTATION(Va32=_mm256_loadu_ps(Ashuffle[5]);)
+  ENABLE_AVX_IMPLEMENTATION(Va13=_mm256_loadu_ps(Ashuffle[6]);)
+  ENABLE_AVX_IMPLEMENTATION(Va23=_mm256_loadu_ps(Ashuffle[7]);)
+  ENABLE_AVX_IMPLEMENTATION(Va33=_mm256_loadu_ps(Ashuffle[8]);)
 
 #include "Singular_Value_Decomposition_Main_Kernel_Body.hpp"
 
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[0],Vu11);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[1],Vu21);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[2],Vu31);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[3],Vu12);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[4],Vu22);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[5],Vu32);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[6],Vu13);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[7],Vu23);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[8],Vu33);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[0],Vu11);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[1],Vu21);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[2],Vu31);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[3],Vu12);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[4],Vu22);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[5],Vu32);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[6],Vu13);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[7],Vu23);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Ushuffle[8],Vu33);)
 
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[0],Vv11);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[1],Vv21);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[2],Vv31);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[3],Vv12);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[4],Vv22);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[5],Vv32);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[6],Vv13);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[7],Vv23);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[8],Vv33);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[0],Vv11);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[1],Vv21);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[2],Vv31);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[3],Vv12);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[4],Vv22);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[5],Vv32);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[6],Vv13);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[7],Vv23);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Vshuffle[8],Vv33);)
 
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Sshuffle[0],Va11);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Sshuffle[1],Va22);)
-		ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Sshuffle[2],Va33);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Sshuffle[0],Va11);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Sshuffle[1],Va22);)
+  ENABLE_AVX_IMPLEMENTATION(_mm256_storeu_ps(Sshuffle[2],Va33);)
 
-		for (int i=0; i<3; i++)
-		{
-			for (int j=0; j<3; j++)
-			{
-				for (int k=0; k<8; k++)
-				{
-					U(i + 3*k, j) = Ushuffle[i + j*3][k];
-					V(i + 3*k, j) = Vshuffle[i + j*3][k];
-				}
-			}
-		}
+  for (int i=0; i<3; i++)
+  {
+    for (int j=0; j<3; j++)
+    {
+      for (int k=0; k<8; k++)
+      {
+        U(i + 3*k, j) = Ushuffle[i + j*3][k];
+        V(i + 3*k, j) = Vshuffle[i + j*3][k];
+      }
+    }
+  }
 
-		for (int i=0; i<3; i++)
-		{
-			for (int k=0; k<8; k++)
-			{
-				S(i + 3*k, 0) = Sshuffle[i][k];
-			}
-		}
+  for (int i=0; i<3; i++)
+  {
+    for (int k=0; k<8; k++)
+    {
+      S(i + 3*k, 0) = Sshuffle[i][k];
+    }
+  }
 }
 #pragma runtime_checks( "u", restore )
 

+ 68 - 62
include/igl/svd3x3/svd3x3_sse.cpp

@@ -18,80 +18,86 @@
 #define COMPUTE_V_AS_MATRIX
 #include "Singular_Value_Decomposition_Preamble.hpp"
 
-#pragma runtime_checks( "u", off )  // disable runtime asserts on xor eax,eax type of stuff (doesn't always work, disable explicitly in compiler settings)
+// disable runtime asserts on xor eax,eax type of stuff (doesn't always work,
+// disable explicitly in compiler settings)
+#pragma runtime_checks( "u", off )  
 template<typename T>
-IGL_INLINE void igl::svd3x3_sse(const Eigen::Matrix<T, 3*4, 3>& A, Eigen::Matrix<T, 3*4, 3> &U, Eigen::Matrix<T, 3*4, 1> &S, Eigen::Matrix<T, 3*4, 3>&V)
+IGL_INLINE void igl::svd3x3_sse(
+  const Eigen::Matrix<T, 3*4, 3>& A, 
+  Eigen::Matrix<T, 3*4, 3> &U, 
+  Eigen::Matrix<T, 3*4, 1> &S, 
+  Eigen::Matrix<T, 3*4, 3>&V)
 {
-	// this code assumes USE_SSE_IMPLEMENTATION is defined 
-	float Ashuffle[9][4], Ushuffle[9][4], Vshuffle[9][4], Sshuffle[3][4];
-	for (int i=0; i<3; i++)
-	{
-		for (int j=0; j<3; j++)
-		{
-			for (int k=0; k<4; k++)
-			{
-				Ashuffle[i + j*3][k] = A(i + 3*k, j);
-			}
-		}
-	}
+  // this code assumes USE_SSE_IMPLEMENTATION is defined 
+  float Ashuffle[9][4], Ushuffle[9][4], Vshuffle[9][4], Sshuffle[3][4];
+  for (int i=0; i<3; i++)
+  {
+    for (int j=0; j<3; j++)
+    {
+      for (int k=0; k<4; k++)
+      {
+        Ashuffle[i + j*3][k] = A(i + 3*k, j);
+      }
+    }
+  }
 
 #include "Singular_Value_Decomposition_Kernel_Declarations.hpp"
 
-		ENABLE_SSE_IMPLEMENTATION(Va11=_mm_loadu_ps(Ashuffle[0]);)
-		ENABLE_SSE_IMPLEMENTATION(Va21=_mm_loadu_ps(Ashuffle[1]);)
-		ENABLE_SSE_IMPLEMENTATION(Va31=_mm_loadu_ps(Ashuffle[2]);)
-		ENABLE_SSE_IMPLEMENTATION(Va12=_mm_loadu_ps(Ashuffle[3]);)
-		ENABLE_SSE_IMPLEMENTATION(Va22=_mm_loadu_ps(Ashuffle[4]);)
-		ENABLE_SSE_IMPLEMENTATION(Va32=_mm_loadu_ps(Ashuffle[5]);)
-		ENABLE_SSE_IMPLEMENTATION(Va13=_mm_loadu_ps(Ashuffle[6]);)
-		ENABLE_SSE_IMPLEMENTATION(Va23=_mm_loadu_ps(Ashuffle[7]);)
-		ENABLE_SSE_IMPLEMENTATION(Va33=_mm_loadu_ps(Ashuffle[8]);)
+  ENABLE_SSE_IMPLEMENTATION(Va11=_mm_loadu_ps(Ashuffle[0]);)
+  ENABLE_SSE_IMPLEMENTATION(Va21=_mm_loadu_ps(Ashuffle[1]);)
+  ENABLE_SSE_IMPLEMENTATION(Va31=_mm_loadu_ps(Ashuffle[2]);)
+  ENABLE_SSE_IMPLEMENTATION(Va12=_mm_loadu_ps(Ashuffle[3]);)
+  ENABLE_SSE_IMPLEMENTATION(Va22=_mm_loadu_ps(Ashuffle[4]);)
+  ENABLE_SSE_IMPLEMENTATION(Va32=_mm_loadu_ps(Ashuffle[5]);)
+  ENABLE_SSE_IMPLEMENTATION(Va13=_mm_loadu_ps(Ashuffle[6]);)
+  ENABLE_SSE_IMPLEMENTATION(Va23=_mm_loadu_ps(Ashuffle[7]);)
+  ENABLE_SSE_IMPLEMENTATION(Va33=_mm_loadu_ps(Ashuffle[8]);)
 
 #include "Singular_Value_Decomposition_Main_Kernel_Body.hpp"
 
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[0],Vu11);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[1],Vu21);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[2],Vu31);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[3],Vu12);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[4],Vu22);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[5],Vu32);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[6],Vu13);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[7],Vu23);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[8],Vu33);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[0],Vu11);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[1],Vu21);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[2],Vu31);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[3],Vu12);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[4],Vu22);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[5],Vu32);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[6],Vu13);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[7],Vu23);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Ushuffle[8],Vu33);)
 
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[0],Vv11);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[1],Vv21);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[2],Vv31);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[3],Vv12);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[4],Vv22);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[5],Vv32);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[6],Vv13);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[7],Vv23);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[8],Vv33);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[0],Vv11);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[1],Vv21);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[2],Vv31);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[3],Vv12);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[4],Vv22);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[5],Vv32);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[6],Vv13);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[7],Vv23);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Vshuffle[8],Vv33);)
 
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Sshuffle[0],Va11);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Sshuffle[1],Va22);)
-		ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Sshuffle[2],Va33);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Sshuffle[0],Va11);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Sshuffle[1],Va22);)
+  ENABLE_SSE_IMPLEMENTATION(_mm_storeu_ps(Sshuffle[2],Va33);)
 
-		for (int i=0; i<3; i++)
-		{
-			for (int j=0; j<3; j++)
-			{
-				for (int k=0; k<4; k++)
-				{
-					U(i + 3*k, j) = Ushuffle[i + j*3][k];
-					V(i + 3*k, j) = Vshuffle[i + j*3][k];
-				}
-			}
-		}
+  for (int i=0; i<3; i++)
+  {
+    for (int j=0; j<3; j++)
+    {
+      for (int k=0; k<4; k++)
+      {
+        U(i + 3*k, j) = Ushuffle[i + j*3][k];
+        V(i + 3*k, j) = Vshuffle[i + j*3][k];
+      }
+    }
+  }
 
-		for (int i=0; i<3; i++)
-		{
-			for (int k=0; k<4; k++)
-			{
-				S(i + 3*k, 0) = Sshuffle[i][k];
-			}
-		}
+  for (int i=0; i<3; i++)
+  {
+    for (int k=0; k<4; k++)
+    {
+      S(i + 3*k, 0) = Sshuffle[i][k];
+    }
+  }
 }
 #pragma runtime_checks( "u", restore )
 

+ 2 - 2
include/igl/tetgen/mesh_with_skeleton.cpp

@@ -17,7 +17,7 @@
 // to produce a graded tet mesh
 const static std::string DEFAULT_TETGEN_FLAGS = "pq2Y";
 
-bool igl::mesh_with_skeleton(
+IGL_INLINE bool igl::mesh_with_skeleton(
   const Eigen::MatrixXd & V,
   const Eigen::MatrixXi & F,
   const Eigen::MatrixXd & C,
@@ -86,7 +86,7 @@ bool igl::mesh_with_skeleton(
   return true;
 }
 
-bool igl::mesh_with_skeleton(
+IGL_INLINE bool igl::mesh_with_skeleton(
   const Eigen::MatrixXd & V,
   const Eigen::MatrixXi & F,
   const Eigen::MatrixXd & C,

+ 43 - 43
include/igl/tetgen/mesh_with_skeleton.h

@@ -13,49 +13,49 @@
 
 namespace igl
 {
-// Mesh the interior of a given surface with tetrahedra which are graded (tend
-// to be small near the surface and large inside) and conform to the given
-// handles and samplings thereof.
-//
-// Inputs:
-//  V  #V by 3 list of mesh vertex positions
-//  F  #F by 3 list of triangle indices
-//  C  #C by 3 list of vertex positions
-//  P  #P list of point handle indices
-//  BE #BE by 2 list of bone-edge indices
-//  CE #CE by 2 list of cage-edge indices
-//  samples_per_bone  #samples to add per bone
-//  tetgen_flags  flags to pass to tetgen {""-->"pq2Y"} otherwise you're on
-//    your own and it's your funeral if you pass nonsense flags
-// Outputs:
-//  VV  #VV by 3 list of tet-mesh vertex positions
-//  TT  #TT by 4 list of tetrahedra indices
-//  FF  #FF by 3 list of surface triangle indices
-// Returns true only on success
-bool mesh_with_skeleton(
-  const Eigen::MatrixXd & V,
-  const Eigen::MatrixXi & F,
-  const Eigen::MatrixXd & C,
-  const Eigen::VectorXi & /*P*/,
-  const Eigen::MatrixXi & BE,
-  const Eigen::MatrixXi & CE,
-  const int samples_per_bone,
-  const std::string & tetgen_flags,
-  Eigen::MatrixXd & VV,
-  Eigen::MatrixXi & TT,
-  Eigen::MatrixXi & FF);
-// Wrapper using default tetgen_flags
-bool mesh_with_skeleton(
-  const Eigen::MatrixXd & V,
-  const Eigen::MatrixXi & F,
-  const Eigen::MatrixXd & C,
-  const Eigen::VectorXi & /*P*/,
-  const Eigen::MatrixXi & BE,
-  const Eigen::MatrixXi & CE,
-  const int samples_per_bone,
-  Eigen::MatrixXd & VV,
-  Eigen::MatrixXi & TT,
-  Eigen::MatrixXi & FF);
+  // Mesh the interior of a given surface with tetrahedra which are graded (tend
+  // to be small near the surface and large inside) and conform to the given
+  // handles and samplings thereof.
+  //
+  // Inputs:
+  //  V  #V by 3 list of mesh vertex positions
+  //  F  #F by 3 list of triangle indices
+  //  C  #C by 3 list of vertex positions
+  //  P  #P list of point handle indices
+  //  BE #BE by 2 list of bone-edge indices
+  //  CE #CE by 2 list of cage-edge indices
+  //  samples_per_bone  #samples to add per bone
+  //  tetgen_flags  flags to pass to tetgen {""-->"pq2Y"} otherwise you're on
+  //    your own and it's your funeral if you pass nonsense flags
+  // Outputs:
+  //  VV  #VV by 3 list of tet-mesh vertex positions
+  //  TT  #TT by 4 list of tetrahedra indices
+  //  FF  #FF by 3 list of surface triangle indices
+  // Returns true only on success
+  IGL_INLINE bool mesh_with_skeleton(
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXd & C,
+    const Eigen::VectorXi & /*P*/,
+    const Eigen::MatrixXi & BE,
+    const Eigen::MatrixXi & CE,
+    const int samples_per_bone,
+    const std::string & tetgen_flags,
+    Eigen::MatrixXd & VV,
+    Eigen::MatrixXi & TT,
+    Eigen::MatrixXi & FF);
+  // Wrapper using default tetgen_flags
+  IGL_INLINE bool mesh_with_skeleton(
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXd & C,
+    const Eigen::VectorXi & /*P*/,
+    const Eigen::MatrixXi & BE,
+    const Eigen::MatrixXi & CE,
+    const int samples_per_bone,
+    Eigen::MatrixXd & VV,
+    Eigen::MatrixXi & TT,
+    Eigen::MatrixXi & FF);
 }
 
 

+ 7 - 0
include/igl/texture_from_tga.cpp

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #include "texture_from_tga.h"
 #ifndef IGL_NO_OPENGL
 

+ 7 - 0
include/igl/texture_from_tga.h

@@ -1,3 +1,10 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 
+// obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_TEXTURE_FROM_TGA_H
 #define IGL_TEXTURE_FROM_TGA_H
 #ifndef IGL_NO_OPENGL

Някои файлове не бяха показани, защото твърде много файлове са промени