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

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

Former-commit-id: e81595ab550a6fd11efdf767bf5b45feccb7a74a
Olga Diamanti 10 жил өмнө
parent
commit
3ecda0096e
100 өөрчлөгдсөн 1557 нэмэгдсэн , 853 устгасан
  1. 2 0
      RELEASE_HISTORY.txt
  2. 1 1
      VERSION.txt
  3. 1 14
      build/Makefile
  4. 41 2
      build/Makefile.conf
  5. 1 0
      build/Makefile_bbw
  6. 1 0
      build/Makefile_boolean
  7. 1 0
      build/Makefile_boost
  8. 1 0
      build/Makefile_cgal
  9. 1 0
      build/Makefile_comiso
  10. 1 0
      build/Makefile_embree
  11. 1 0
      build/Makefile_lim
  12. 1 0
      build/Makefile_matlab
  13. 1 0
      build/Makefile_mosek
  14. 1 0
      build/Makefile_png
  15. 1 0
      build/Makefile_svd3x3
  16. 1 0
      build/Makefile_tetgen
  17. 1 0
      build/Makefile_triangle
  18. 1 0
      build/Makefile_viewer
  19. 1 0
      build/Makefile_xml
  20. 3 8
      examples/MatlabWorkspace/Makefile
  21. 2 7
      examples/ReAntTweakBar/Makefile
  22. 2 6
      examples/affine/Makefile
  23. 1 9
      examples/ambient-occlusion/Makefile
  24. 1 31
      examples/arap/Makefile
  25. 0 1
      examples/arap/example.cpp
  26. 0 24
      examples/basic_topology/Makefile
  27. 0 7
      examples/basic_topology/README
  28. 0 53
      examples/basic_topology/example1.cpp
  29. 1 13
      examples/bbw/Makefile
  30. 0 17
      examples/beach-balls/Makefile
  31. 2 26
      examples/camera/Makefile
  32. 0 25
      examples/cat/Makefile
  33. 0 9
      examples/cat/README
  34. 0 36
      examples/cat/example.cpp
  35. 0 13
      examples/colored-mesh/Makefile
  36. 2 6
      examples/dmat/Makefile
  37. 4 8
      examples/eigen-gotchas/Makefile
  38. 0 1
      examples/eigen-gotchas/example.cpp
  39. 0 15
      examples/embree/Makefile
  40. 4 7
      examples/example_fun/Makefile
  41. 2 5
      examples/file_contents_as_string/Makefile
  42. 0 21
      examples/flare-eyes/Makefile
  43. 2 5
      examples/get_seconds/Makefile
  44. 2 3
      examples/glslversion/Makefile
  45. 5 5
      examples/glut_speed_test/Makefile
  46. 4 8
      examples/harwell_boeing/Makefile
  47. 1 13
      examples/intersections/Makefile
  48. 2 5
      examples/is_dir/Makefile
  49. 2 6
      examples/marching_cubes/Makefile
  50. 2 6
      examples/meshio/Makefile
  51. 2 6
      examples/mode/Makefile
  52. 1 8
      examples/multi-viewport/Makefile
  53. 3 23
      examples/patches/Makefile
  54. 2 5
      examples/path_tests/Makefile
  55. 2 5
      examples/pathinfo/Makefile
  56. 2 6
      examples/quicklook-mesh/Makefile
  57. 2 24
      examples/randomly-sample-mesh/Makefile
  58. 3 10
      examples/render_to_png/Makefile
  59. 2 23
      examples/rotate-widget/Makefile
  60. 2 23
      examples/scene-rotation/Makefile
  61. 2 26
      examples/shadow-mapping/Makefile
  62. 3 46
      examples/skeleton-builder/Makefile
  63. 4 31
      examples/skeleton-posing/Makefile
  64. 3 25
      examples/skeleton/Makefile
  65. 2 6
      examples/slice/Makefile
  66. 2 5
      examples/sort/Makefile
  67. 2 6
      examples/sortrows/Makefile
  68. 2 3
      examples/stdin_to_temp/Makefile
  69. 2 3
      examples/svd/Makefile
  70. 1 14
      examples/textured-mesh/Makefile
  71. 2 4
      examples/trackball/Makefile
  72. 2 14
      examples/transparency/Makefile
  73. 2 6
      examples/transpose_blocks/Makefile
  74. 2 12
      examples/upright/Makefile
  75. 45 47
      include/igl/RotateWidget.h
  76. 47 8
      include/igl/boolean/mesh_boolean.cpp
  77. 2 2
      include/igl/boundary_facets.cpp
  78. 4 4
      include/igl/cgal/SelfIntersectMesh.h
  79. 71 0
      include/igl/circulation.cpp
  80. 56 0
      include/igl/circulation.h
  81. 156 0
      include/igl/collapse_edge.cpp
  82. 70 0
      include/igl/collapse_edge.h
  83. 1 1
      include/igl/doublearea.cpp
  84. 87 0
      include/igl/edge_collapse_is_valid.cpp
  85. 44 0
      include/igl/edge_collapse_is_valid.h
  86. 59 0
      include/igl/edge_flaps.cpp
  87. 45 0
      include/igl/edge_flaps.h
  88. 3 3
      include/igl/face_occurrences.cpp
  89. 4 4
      include/igl/face_occurrences.h
  90. 26 1
      include/igl/find.cpp
  91. 6 0
      include/igl/find.h
  92. 0 1
      include/igl/harwell_boeing.h
  93. 305 0
      include/igl/linprog.cpp
  94. 65 0
      include/igl/linprog.h
  95. 162 0
      include/igl/mosek/mosek_linprog.cpp
  96. 56 0
      include/igl/mosek/mosek_linprog.h
  97. 2 2
      include/igl/on_boundary.cpp
  98. 78 29
      include/igl/outer_hull.cpp
  99. 6 0
      include/igl/peel_outer_hull_layers.cpp
  100. 1 1
      include/igl/ply.h.REMOVED.git-id

+ 2 - 0
RELEASE_HISTORY.txt

@@ -1,3 +1,5 @@
+1.1.5  Bug fix in booleans
+1.1.4  Edge collapsing and linear program solving
 1.1.3  Bug fixes in active set and boundary_conditions
 1.1.1  PLY file format support
 1.1.0  Mesh boolean operations using CGAL and cork, implementing [Attene 14]

+ 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
-1.1.3
+1.1.5

+ 1 - 14
build/Makefile

@@ -3,6 +3,7 @@ all: lib extras examples
 framework: lib extras lib/igl.framework/
 
 # Shared flags etc.
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 $(info Hello, $(IGL_USERNAME)!)
 
@@ -85,23 +86,9 @@ INC+=-I../include/
 # DEPENDENCIES
 #############################################################################
 INC+=$(OPENGL_INC)
-
-# Eigen dependency
-ifndef EIGEN3_INC
-	EIGEN3_INC=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
-endif
 INC+=$(EIGEN3_INC)
-
-# AntTweakBar dependency
-#ANTTWEAKBAR_INC=-I$(DEFAULT_PREFIX)/include
-ANTTWEAKBAR_INC=-I../external/AntTweakBar/include
 INC+=$(ANTTWEAKBAR_INC)
 
-## OpenGL dependency
-#LIB+=-framework OpenGL
-#LIB+=-framework GLUT
-#LIB+=-framework AppKit
-
 .PHONY: obj
 obj:
 	mkdir -p obj

+ 41 - 2
build/Makefile.conf

@@ -3,6 +3,8 @@
 #############################################################################
 UNAME := $(shell uname)
 
+THIS_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+
 GG=g++
 #GG=clang++
 #GG=/usr/bin/g++     17s
@@ -10,7 +12,6 @@ GG=g++
 #GG=g++-mp-4.3       15.5s
 #GG=g++-mp-4.7       19.9s
 
-CFLAGS += -DIGL_STATIC_LIBRARY
 CFLAGS += -Wall
 CFLAGS += -std=c++11
 
@@ -46,6 +47,7 @@ ifeq ($(IGL_USERNAME),whitinge)
 endif
 
 ifeq ($(IGL_USERNAME),ajx)
+	CFLAGS += -DIGL_STATIC_LIBRARY
 	MOSEKPLATFORM=osx64x86
 	MOSEKVERSION=7
 	IGL_WITH_VIEWER=1
@@ -201,7 +203,44 @@ endif
 ifndef GLUT_LIB
 	GLUT_LIB=-framework GLUT
 endif
+# Eigen dependency
+ifndef EIGEN3_INC
+	EIGEN3_INC=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
+endif
+
+ifndef LIBIGL
+	LIBIGL=$(THIS_DIR)/../
+endif
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
+LIBIGL_INC=-I$(LIBIGL)/include
+
+ifndef ANTTWEAKBAR_INC
+	ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
+endif
 ifndef ANTTWEAKBAR_LIB
 	# AntTweakBar needs AppKit on mac os x
-	ANTTWEAKBAR_LIB=-lAntTweakBar -framework AppKit
+	ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
+endif
+
+ifndef SINGULAR_VALUE_DECOMPOSITION_INC
+				SINGULAR_VALUE_DECOMPOSITION_INC=\
+				-I$(LIBIGL)/external/Singular_Value_Decomposition/
+endif
+
+ifndef TETGEN
+# By default I'm using the libigl version. Adjust accordingly
+				TETGEN=$(LIBIGL)/external/tetgen
+				TETGEN_LIB=-L$(TETGEN) -ligltetgen -ltet 
+				TETGEN_INC=-I$(TETGEN)
+endif
+
+ifndef EMBREE
+				EMBREE=$(LIBIGL)/external/embree
+				EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
+				EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
+endif
+ifndef YIMG
+				YIMG=$(LIBIGL)/external/yimg
+				YIMG_LIB=-L$(YIMG) -lyimg -lz -L/usr/X11/lib -L$(DEFAULT_PREFIX)/lib -lpng -bind_at_load
+				YIMG_INC=-I/usr/X11/include -I$(YIMG) 
 endif

+ 1 - 0
build/Makefile_bbw

@@ -2,6 +2,7 @@
 all: libiglbbw
 debug: libiglbbw
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: OPTFLAGS += -O3 -DNDEBUG $(OPENMP)
 debug: OPTFLAGS += -g -Wall

+ 1 - 0
build/Makefile_boolean

@@ -4,6 +4,7 @@ include Makefile.conf
 all: libiglboolean
 debug: libiglboolean
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG -std=c++11
 debug: CFLAGS += -g -Wall -std=c++11

+ 1 - 0
build/Makefile_boost

@@ -4,6 +4,7 @@ include Makefile.conf
 all: libiglboost
 debug: libiglboost
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG
 debug: CFLAGS += -g -Wall 

+ 1 - 0
build/Makefile_cgal

@@ -3,6 +3,7 @@
 all: libiglcgal
 debug: libiglcgal
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG 
 debug: CFLAGS += -g -Wall -Werror

+ 1 - 0
build/Makefile_comiso

@@ -4,6 +4,7 @@ include Makefile.conf
 all: libiglcomiso
 debug: libiglcomiso
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG -std=c++11
 debug: CFLAGS += -g -Wall -std=c++11

+ 1 - 0
build/Makefile_embree

@@ -4,6 +4,7 @@ include Makefile.conf
 all: libiglembree
 debug: libiglembree
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG -std=c++11
 debug: CFLAGS += -g -Wall -std=c++11

+ 1 - 0
build/Makefile_lim

@@ -4,6 +4,7 @@ include Makefile.conf
 all: libigllim
 debug: libigllim
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG
 debug: CFLAGS += -g -Wall 

+ 1 - 0
build/Makefile_matlab

@@ -1,3 +1,4 @@
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG
 debug: CFLAGS += -g -Wall -Werror

+ 1 - 0
build/Makefile_mosek

@@ -1,3 +1,4 @@
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 
 .PHONY: all

+ 1 - 0
build/Makefile_png

@@ -1,3 +1,4 @@
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG
 debug: CFLAGS += -g -Wall -Werror

+ 1 - 0
build/Makefile_svd3x3

@@ -1,3 +1,4 @@
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 
 .PHONY: all

+ 1 - 0
build/Makefile_tetgen

@@ -3,6 +3,7 @@
 all: libigltetgen
 debug: libigltetgen
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG 
 debug: CFLAGS += -g -Wall -Werror

+ 1 - 0
build/Makefile_triangle

@@ -3,6 +3,7 @@
 all: libigltriangle
 debug: libigltriangle
 
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG 
 debug: CFLAGS += -g -Wall -Werror

+ 1 - 0
build/Makefile_viewer

@@ -1,3 +1,4 @@
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 all: CFLAGS += -O3 -DNDEBUG -fopenmp
 debug: CFLAGS += -g -Wall -Werror -fopenmp

+ 1 - 0
build/Makefile_xml

@@ -1,3 +1,4 @@
+CFLAGS += -DIGL_STATIC_LIBRARY
 include Makefile.conf
 
 .PHONY: all

+ 3 - 8
examples/MatlabWorkspace/Makefile

@@ -2,18 +2,13 @@
 
 # Shared flags etc.
 include ../../build/Makefile.conf
-
-IGL=../../
-IGL_LIB=-L$(IGL)/lib -ligl
-IGL_INC=-I$(IGL)/include
-
-EIGEN3_INC=-I/usr/local/include/eigen3 -I/usr/local/include/eigen3/unsupported -I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
+LIBIGL_LIB+=-liglmatlab
 
 MATLAB_INC=-I$(MATLAB)/extern/include/
 MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat
 
-LIB+=$(IGL_LIB) $(MATLAB_LIB)
-INC+=$(IGL_INC) $(EIGEN3_INC) $(MATLAB_INC)
+LIB+=$(LIBIGL_LIB) $(MATLAB_LIB)
+INC+=$(LIBIGL_INC) $(EIGEN3_INC) $(MATLAB_INC)
 
 CFLAGS += -g
 

+ 2 - 7
examples/ReAntTweakBar/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,12 +7,8 @@ all: example
 
 .PHONY: example
 
-IGL=../../
-
-ANTTWEAKBAR_INC=-I$(IGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(IGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-inc=-DIGL_HEADER_ONLY -I$(IGL)/include -I$(DEFAULT_PREFIX)/include $(ANTTWEAKBAR_INC)
-lib=-L$(IGL)/lib -ligl -L$(DEFAULT_PREFIX)/lib $(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB)
+inc=$(LIBIGL_INC) $(ANTTWEAKBAR_INC)
+lib=$(LIBIGL_LIB) $(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB)
 CFLAGS+=-g
 
 example: example.o

+ 2 - 6
examples/affine/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 all: example
@@ -8,12 +7,9 @@ include ../../build/Makefile.conf
 
 .PHONY: example
 
-igl_lib=../../
-eigen=$(DEFAULT_PREFIX)/include/eigen3
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include -I$(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 1 - 9
examples/ambient-occlusion/Makefile

@@ -1,25 +1,17 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglembree
 
 all: example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
 EMBREE=$(LIBIGL)/external/embree
 EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(EMBREE_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(EMBREE_LIB)
 

+ 1 - 31
examples/arap/Makefile

@@ -1,43 +1,13 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglsvd3x3
 
 all: example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglpng -liglsvd3x3
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-#CFLAGS+=-DIGL_HEADER_ONLY
-
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
-# YIMAGE Library
-YIMG=$(LIBIGL)/external/yimg/
-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
-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
-
-# SVD 
-SINGULAR_VALUE_DECOMPOSITION_INC=\
-	-I$(LIBIGL)/external/Singular_Value_Decomposition/
-
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(YIMG_INC) $(SINGULAR_VALUE_DECOMPOSITION_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(YIMG_LIB) 
 

+ 0 - 1
examples/arap/example.cpp

@@ -34,7 +34,6 @@
 #include <igl/get_seconds.h>
 #include <igl/PI.h>
 #include <igl/STR.h>
-#include <YImage.hpp>
 
 #ifdef __APPLE__
 #  include <GLUT/glut.h>

+ 0 - 24
examples/basic_topology/Makefile

@@ -1,24 +0,0 @@
-
-all: example1
-
-# Shared flags etc.
-include ../../build/Makefile.conf
-
-igl_lib=../../
-eigen_lib=$(DEFAULT_PREFIX)/include/eigen3/
-
-CFLAGS+=-g -fopenmp
-inc=-I$(igl_lib)/include -I$(eigen_lib)
-lib=-L$(igl_lib)/lib -ligl
-
-example1: example1.o
-	g++ $(CFLAGS) -o example1 example1.o $(lib)
-
-example1.o: example1.cpp
-	g++ $(CFLAGS) -c example1.cpp -o example1.o $(inc)
-
-
-clean:
-	rm -f example1.o
-	rm -f example1
-	rm -f bunny_out.off

+ 0 - 7
examples/basic_topology/README

@@ -1,7 +0,0 @@
-igl_lib is a lightweight C++ for mesh processing
-
-Example1.cpp: 
-- Load/save a mesh
-- Compute face and edge topology
-- Compute the cotan matrix of the loaded mesh
-

+ 0 - 53
examples/basic_topology/example1.cpp

@@ -1,53 +0,0 @@
-//
-//  IGL Lib - Simple C++ mesh library
-//
-//  Copyright 2011, Daniele Panozzo. All rights reserved.
-
-// IMPORTANT DO NOT REMOVE OR MOVE
-#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
-
-#include <iostream>
-#include <string>
-#include <igl/read_triangle_mesh.h>
-#include <igl/write_triangle_mesh.h>
-#include <igl/triangle_triangle_adjacency.h>
-#include <igl/edge_topology.h>
-
-using namespace std;
-
-int main (int argc, const char * argv[])
-{
-    Eigen::MatrixXd V;
-    Eigen::MatrixXi F;
-    igl::read_triangle_mesh("../shared/TinyTorus.obj",V,F);
-
-    std::cout << "Mesh loaded!\n";
-    cout << "Vertex Array:" << endl;
-    cout << V << endl;
-    cout << "-------------" << endl;
-    cout << "Face Array:" << endl;
-    cout << F << endl;
-    cout << "-------------" << endl;
-
-    igl::write_triangle_mesh("bunny_out.off",V,F);
-
-    // Face Topology
-    cout << "TT Topology:" << endl;
-    Eigen::MatrixXi TT;
-    igl::triangle_triangle_adjacency(V,F,TT);
-    cout << TT << endl;
-    cout << "-------------" << endl;
-
-    // Edge Topology
-    cout << "Edge Topology:" << endl;
-    Eigen::MatrixXi EV;
-    Eigen::MatrixXi FE;
-    Eigen::MatrixXi EF;
-
-    igl::edge_topology(V,F,EV,FE, EF);
-    cout << EV << endl << FE << endl << EF << endl;
-    cout << "-------------" << endl;
-
-
-    return 0;
-}

+ 1 - 13
examples/bbw/Makefile

@@ -2,9 +2,7 @@ include ../../build/Makefile.conf
 
 CXX=g++
 
-LIBIGL=../../
-LIBIGL_INC=-I${LIBIGL}/include
-LIBIGL_LIB=-L${LIBIGL}/lib -ligl -liglmosek -liglbbw
+LIBIGL_LIB+=-liglmosek -liglbbw -ligltetgen
 
 ifdef IGL_NO_MOSEK
 CFLAGS+=-DIGL_NO_MOSEK
@@ -16,22 +14,12 @@ endif
 ifndef MOSEKVERSION
   MOSEKVERSION=6
 endif
-IGLMOSEK=../mosek/
-IGLMOSEK_INC=-I$(IGLMOSEK)/
-INC+=${IGLMOSEK_INC}
 MOSEK=/usr/local/mosek
 MOSEK_INC=-I$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/h
 MOSEK_LIB=-L$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/bin -lmosek64
 INC+=$(MOSEK_INC)
 endif
 
-EIGEN3_INC=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
-
-# By default I'm using the libigl version. Adjust accordingly
-TETGEN=$(LIBIGL)/external/tetgen
-TETGEN_LIB=-L$(TETGEN) -ligltetgen -ltet 
-TETGEN_INC=-I$(TETGEN)
-
 INC=-I. ${EIGEN3_INC} ${LIBIGL_INC} ${TETGEN_INC} ${MOSEK_INC} 
 LIB=${TETGEN_LIB} ${MOSEK_LIB} ${OPENGL_LIB} ${GLUT_LIB} ${LIBIGL_LIB} 
 

+ 0 - 17
examples/beach-balls/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -10,22 +9,6 @@ all: obj example
 
 CFLAGS+=-g -std=c++11
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-# Use free glut for mouse scrolling
-GLUT_LIB=-framework GLUT
-GLUT_INC=-framework GLUT
-
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 

+ 2 - 26
examples/camera/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,31 +7,8 @@ all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-CARBON_LIB=-framework Carbon
-
-## Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-#GLUT_LIB=$(FREE_GLUT_LIB)
-#GLUT_INC=$(FREE_GLUT_INC)
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 0 - 25
examples/cat/Makefile

@@ -1,25 +0,0 @@
-
-.PHONY: all
-
-# Shared flags etc.
-include ../../build/Makefile.conf
-
-all: example
-
-.PHONY: example
-
-igl_lib=../../
-eigen=$(DEFAULT_PREFIX)/include/eigen3/
-
-CFLAGS+=-g
-inc=-I$(igl_lib)/include -I$(eigen)
-lib=-L$(igl_lib)/lib -ligl
-
-example: example.o
-	g++ $(CFLAGS) -o example example.o $(lib)
-
-example.o: example.cpp
-	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
-clean:
-	rm -f example.o
-	rm -f example

+ 0 - 9
examples/cat/README

@@ -1,9 +0,0 @@
-This is a simple example program that shows how to use the cat function on
-eigen matrices like matlab's C = cat(dim,A,B) function
-
-
-To Build:
-  make
-
-To Run:
-  ./example

+ 0 - 36
examples/cat/example.cpp

@@ -1,36 +0,0 @@
-// g++ -o main main.cpp -I. -I/usr/local/include/eigen3
-#include <Eigen/Core>
-#include <iostream>
-#include <igl/cat.h>
-
-using namespace std;
-using namespace igl;
-using namespace Eigen;
-
-
-template <class T>
-void matlab_print(const string name, const T & X)
-{
-  cout<<name<<"=["<<endl<<X<<endl<<"];"<<endl;
-}
-
-int main(int argc, char * argv[])
-{
-  Eigen::MatrixXd A(3,4);
-  A << 
-    3,5,4,5,
-    1,2,4,2,
-    1,1,2,5;
-  matlab_print("A",A);
-  Eigen::MatrixXd B(3,4);
-  B << 
-    13,15,14,15,
-    11,12,14,12,
-    11,11,12,15;
-  matlab_print("B",B);
-  Eigen::MatrixXd C;
-  C = cat(1,A,B);
-  matlab_print("cat(1,A,B)",C);
-  C = cat(2,A,B);
-  matlab_print("cat(2,A,B)",C);
-}

+ 0 - 13
examples/colored-mesh/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,18 +7,6 @@ all: example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(EMBREE_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(EMBREE_LIB)
 

+ 2 - 6
examples/dmat/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,12 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=$(DEFAULT_PREFIX)/include/eigen3
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include -I$(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 4 - 8
examples/eigen-gotchas/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,18 +7,15 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include $(eigen)
-lib=-L$(igl_lib)/lib -ligl
+INC=$(LIBIGL_INC) $(EIGEN3_INC)
+LIB=$(LIBIGL_LIB)
 
 example: example.o
-	g++ $(CFLAGS) -o example example.o $(lib)
+	g++ $(CFLAGS) -o example example.o $(LIB)
 
 example.o: example.cpp
-	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
+	g++ $(CFLAGS) -c example.cpp -o example.o $(INC)
 clean:
 	rm -f example.o
 	rm -f example

+ 0 - 1
examples/eigen-gotchas/example.cpp

@@ -4,7 +4,6 @@
 #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
 #define EIGEN_IM_MAD_AS_HELL_AND_IM_NOT_GOING_TO_TAKE_IT_ANYMORE
 #include <Eigen/Sparse>
-#include <Eigen/SparseExtra>
 using namespace Eigen;
 
 #include <cstdio>

+ 0 - 15
examples/embree/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,20 +7,6 @@ all: example
 
 .PHONY: example
 
-LIBIGL=../../
-#LIBIGL_INC=-I$(LIBIGL)/include -DIGL_HEADER_ONLY
-#LIBIGL_LIB=
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(EMBREE_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(EMBREE_LIB)
 

+ 4 - 7
examples/example_fun/Makefile

@@ -5,26 +5,23 @@ all: example_static example_header_only
 # Shared flags etc.
 include ../../build/Makefile.conf
 
-igl_lib=../../
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include
+INC=$(LIBIGL_INC)
 
-STATIC_LIB=-ligl -L../../lib
-HEADER_ONLY_DEF=-DIGL_HEADER_ONLY
+STATIC_LIB=-ligl -L../../lib -DIGL_STATIC_LIBRARY
 
 example_static: example_static.o
 	#g++ $(CFLAGS) -o example_static example_static.o $(lib) $(STATIC_LIB) ../../obj/example_fun.o
 	g++ $(CFLAGS) -o example_static example_static.o ../../obj/example_fun.o
 
 example_static.o: example.cpp
-	g++ $(CFLAGS) -c example.cpp -o example_static.o $(inc)
+	g++ $(CFLAGS) -c example.cpp -o example_static.o $(INC)
 
 example_header_only: example_header_only.o
 	g++ $(CFLAGS) -o example_header_only example_header_only.o $(lib)
 
 example_header_only.o: example.cpp
-	g++ $(CFLAGS) -c example.cpp -o example_header_only.o $(inc) $(HEADER_ONLY_DEF)
+	g++ $(CFLAGS) -c example.cpp -o example_header_only.o $(INC)
 
 clean:
 	rm -f example_static.o

+ 2 - 5
examples/file_contents_as_string/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,11 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 0 - 21
examples/flare-eyes/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,26 +7,6 @@ all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-CARBON_LIB=-framework Carbon
-
-## Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-#GLUT_LIB=$(FREE_GLUT_LIB)
-#GLUT_INC=$(FREE_GLUT_INC)
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB)
 

+ 2 - 5
examples/get_seconds/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,11 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-
 CFLAGS+=-g -Wall
-inc=-I$(igl_lib)/include
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 3
examples/glslversion/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -11,8 +10,8 @@ all: example
 igl_lib=../../
 
 CFLAGS+=-g
-inc=-I$(igl_lib)/include
-lib=$(OPENGL_LIB) $(GLUT_LIB) -L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC)
+lib=$(OPENGL_LIB) $(GLUT_LIB) $(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 5 - 5
examples/glut_speed_test/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 all: example
@@ -11,14 +10,15 @@ include ../../build/Makefile.conf
 igl_lib=../../
 
 CFLAGS+=-g -Wall 
-inc=-I$(igl_lib)/include
-lib=$(OPENGL_LIB) $(GLUT_LIB) -L$(igl_lib)/lib -ligl
+INC=$(LIBIGL_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(LIBIGL_LIB)
 
 example: example.o
-	g++ $(CFLAGS) -o example example.o $(lib)
+	g++ $(CFLAGS) -o example example.o $(LIB)
 
 example.o: example.cpp
-	g++ $(CFLAGS) $(deps) -c example.cpp -o example.o $(inc)
+	g++ $(CFLAGS) $(deps) -c example.cpp -o example.o $(INC)
+
 clean:
 	rm -f example.o
 	rm -f example

+ 4 - 8
examples/harwell_boeing/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,18 +7,15 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include $(eigen)
-lib=-L$(igl_lib)/lib -ligl
+INC=$(LIBIGL_INC) $(EIGEN3_INC)
+LIB=$(LIBIGL_LIB)
 
 example: example.o
-	g++ $(CFLAGS) -o example example.o $(lib)
+	g++ $(CFLAGS) -o example example.o $(LIB)
 
 example.o: example.cpp
-	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
+	g++ $(CFLAGS) -c example.cpp -o example.o $(INC)
 clean:
 	rm -f example.o
 	rm -f example

+ 1 - 13
examples/intersections/Makefile

@@ -1,31 +1,19 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB=+liglcgal
 
 all: example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree -liglcgal
-
 CGAL=/opt/local/
 CGAL_LIB=-L$(CGAL)/lib -lCGAL -lCGAL_Core -lgmp -lmpfr -lboost_thread-mt -lboost_system-mt
 CGAL_INC=-I$(CGAL)/include -I/usr/include/
 # This is absolutely necessary for Exact Construction
 CGAL_FLAGS=-frounding-math -fsignaling-nans 
 
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(EMBREE_INC) $(CGAL_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(EMBREE_LIB) $(CGAL_LIB)
 CFLAGS+=$(CGAL_FLAGS)

+ 2 - 5
examples/is_dir/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,11 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 6
examples/marching_cubes/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 all: example
@@ -8,12 +7,9 @@ all: example
 # Shared flags etc.
 include ../../build/Makefile.conf
 
-igl_lib=../../
-eigen=-I$(DEFAULT_PREFIX)/include/eigen3
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include $(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 6
examples/meshio/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,12 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=-I$(DEFAULT_PREFIX)/include/eigen3
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include $(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 6
examples/mode/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,12 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=$(DEFAULT_PREFIX)/include/eigen3/
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include -I$(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 1 - 8
examples/multi-viewport/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -7,16 +6,10 @@ all: example
 
 .PHONY:  example
 
-LIBIGL=/usr/local/igl/libigl/
-include $(LIBIGL)/build/Makefile.conf
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
+include ../..//build/Makefile.conf
 
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 CFLAGS+=-std=c++11 -g -Wno-deprecated-declarations
 
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 

+ 3 - 23
examples/patches/Makefile

@@ -1,8 +1,8 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglembree -liglboost
 
 all: obj example
 
@@ -10,28 +10,8 @@ all: obj example
 
 CFLAGS+=-g -std=c++11
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab -liglembree -liglboost
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-# Use free glut for mouse scrolling
-GLUT_LIB=-framework GLUT
-GLUT_INC=-framework GLUT
-
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC) $(EMBREE_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(EMBREE_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC) $(EMBREE_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(EMBREE_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 2 - 5
examples/path_tests/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,11 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-
 CFLAGS+=-g -Wall
-inc=-I$(igl_lib)/include
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 5
examples/pathinfo/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 all: example
@@ -8,11 +7,9 @@ include ../../build/Makefile.conf
 
 .PHONY: example
 
-igl_lib=../../
-
 CFLAGS+=-g -Wall 
-inc=-I$(igl_lib)/include
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib) 

+ 2 - 6
examples/quicklook-mesh/Makefile

@@ -10,13 +10,9 @@ C=clang
 #C=clang-mp-3.4
 CXXFLAGS += -stdlib=libc++ -std=c++11
 
-EIGEN=/opt/local/include/eigen3/
-EIGEN3_INC=-I$(EIGEN) -I$(EIGEN)/unsupported
-
+#Be sure that libs aren't used
 LIBIGL=../../
-#LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
-LIBIGL_LIB=
-LIBIGL_INC=-DIGL_HEADER_ONLY -I $(LIBIGL)/include
+LIBIGL_INC=-I$(LIBIGL)/include
 
 # Do not use the GLU that comes with the macports Mesa:
 # http://www.alecjacobson.com/weblog/?p=2827

+ 2 - 24
examples/randomly-sample-mesh/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,29 +7,8 @@ all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-CARBON_LIB=-framework Carbon
-
-# Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 3 - 10
examples/render_to_png/Makefile

@@ -1,17 +1,10 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglpng
 
 # YIMG dependency
-YIMG=../../external/yimg
-YIMG_LIB=-L$(YIMG) -lyimg -lz -L/usr/X11/lib -lpng -bind_at_load
-YIMG_INC=-I/usr/X11/include -I$(YIMG) 
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-# LIBPNG dependency
 
 all: example
 
@@ -19,8 +12,8 @@ all: example
 
 IGL=../../
 
-inc=-DIGL_HEADER_ONLY -I$(IGL)/include -I$(DEFAULT_PREFIX)/include $(YIMG_INC) $(EIGEN3_INC)
-lib=-L$(IGL)/lib -ligl -liglpng -L$(DEFAULT_PREFIX)/lib $(OPENGL_LIB) $(GLUT_LIB) $(YIMG_LIB) $(LIBPNG_LIB)
+inc=$(LIBIGL_INC) $(YIMG_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB) $(OPENGL_LIB) $(GLUT_LIB) $(YIMG_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 23
examples/rotate-widget/Makefile

@@ -8,29 +8,8 @@ all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-CARBON_LIB=-framework Carbon
-
-# Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 2 - 23
examples/scene-rotation/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,29 +7,9 @@ all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include -DIGL_HEADER_ONLY
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab 
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-CARBON_LIB=-framework Carbon
-
-# Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-GLUT_LIB=-framework GLUT
-GLUT_INC=
 
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)  $(GLUT_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 2 - 26
examples/shadow-mapping/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,31 +7,8 @@ all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-CARBON_LIB=-framework Carbon
-
-## Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-#GLUT_LIB=$(FREE_GLUT_LIB)
-#GLUT_INC=$(FREE_GLUT_INC)
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 3 - 46
examples/skeleton-builder/Makefile

@@ -1,58 +1,15 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglembree
 
 all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-TETGEN=$(LIBIGL)/external/tetgen
-TETGEN_LIB=-L$(TETGEN) -ltet 
-TETGEN_INC=-I$(TETGEN)
-
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
-CARBON_LIB=-framework Carbon
-
-# Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
-ifdef IGL_NO_MOSEK
-CFLAGS+=-DIGL_NO_MOSEK
-else
-# Adjust your mosek paths etc. accordingly
-ifndef MOSEKPLATFORM
-  MOSEKPLATFORM=osx64x86
-endif
-ifndef MOSEKVERSION
-  MOSEKVERSION=6
-endif
-IGLMOSEK=
-IGLMOSEK_INC=
-MOSEK=/usr/local/mosek
-MOSEK_INC=
-MOSEK_LIB=
-endif
-
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC) ${TETGEN_INC} $(MOSEK_INC) $(EMBREE_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB) $(TETGEN_LIB) $(MOSEK_LIB) $(EMBREE_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC) ${TETGEN_INC} $(MOSEK_INC) $(EMBREE_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(TETGEN_LIB) $(MOSEK_LIB) $(EMBREE_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 4 - 31
examples/skeleton-posing/Makefile

@@ -1,39 +1,13 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglbbw -liglcgal
 
 all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglcgal -ligltetgen -liglbbw -liglmosek
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-TETGEN=$(LIBIGL)/external/tetgen
-TETGEN_LIB=-L$(TETGEN) -ltet 
-TETGEN_INC=-I$(TETGEN)
-
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
-CARBON_LIB=-framework Carbon
-
-# Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
 ifdef IGL_NO_MOSEK
 CFLAGS+=-DIGL_NO_MOSEK
 else
@@ -44,11 +18,10 @@ endif
 ifndef MOSEKVERSION
   MOSEKVERSION=7
 endif
-IGLMOSEK=../mosek/
-IGLMOSEK_INC=-I$(IGLMOSEK)/
 MOSEK=/usr/local/mosek
 MOSEK_INC=-I$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/h
 MOSEK_LIB=-L$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/bin -lmosek64
+LIBIGL_LIB+=-liglmosek 
 endif
 
 CGAL=/opt/local/
@@ -58,8 +31,8 @@ CGAL_INC=-I$(CGAL)/include -I/usr/include/
 CGAL_FLAGS=-frounding-math -fsignaling-nans 
 CFLAGS+=$(CGAL_FLAGS)
 
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC) ${CGAL_INC} ${TETGEN_INC} $(MOSEK_INC) $(EMBREE_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) ${CGAL_LIB} $(CARBON_LIB) $(TETGEN_LIB) $(MOSEK_LIB) $(EMBREE_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC) ${CGAL_INC} ${TETGEN_INC} $(MOSEK_INC) $(EMBREE_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) ${CGAL_LIB} $(TETGEN_LIB) $(MOSEK_LIB) $(EMBREE_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 3 - 25
examples/skeleton/Makefile

@@ -1,35 +1,13 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglbbw -liglmosek
 
 all: obj example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -ligltetgen -liglbbw -liglmosek
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-TETGEN=$(LIBIGL)/external/tetgen
-TETGEN_LIB=-L$(TETGEN) -ltet 
-TETGEN_INC=-I$(TETGEN)
-
-CARBON_LIB=-framework Carbon
-
-# Use free glut for mouse scrolling
-#FREE_GLUT=/opt/local/
-#FREE_GLUT_INC=-I$(FREE_GLUT)/include
-#FREE_GLUT_LIB=-L$(FREE_GLUT)/lib -lglut
-GLUT_LIB=-framework GLUT
-GLUT_INC=
-
 ifdef IGL_NO_MOSEK
 CFLAGS+=-DIGL_NO_MOSEK
 else
@@ -47,8 +25,8 @@ MOSEK_INC=-I$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/h
 MOSEK_LIB=-L$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/bin -lmosek64
 endif
 
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC) $(GLUT_INC) ${TETGEN_INC} $(MOSEK_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB) $(CARBON_LIB) $(TETGEN_LIB) $(MOSEK_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(GLUT_INC) ${TETGEN_INC} $(MOSEK_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(TETGEN_LIB) $(MOSEK_LIB)
 
 CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 

+ 2 - 6
examples/slice/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,13 +7,10 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
-
 #CFLAGS+=-g
 CFLAGS+=-Os -DNDEBUG
-inc=-I$(igl_lib)/include $(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 5
examples/sort/Makefile

@@ -8,12 +8,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=$(DEFAULT_PREFIX)/include/eigen3/
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include -I$(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 6
examples/sortrows/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,12 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=$(DEFAULT_PREFIX)/include/eigen3/
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include -I$(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 3
examples/stdin_to_temp/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -11,8 +10,8 @@ all: example
 igl_lib=../../
 
 CFLAGS+=-g
-inc=-I$(igl_lib)/include
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 3
examples/svd/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -11,8 +10,8 @@ all: example
 igl_lib=../../
 
 CFLAGS+=-g
-inc=-I$(igl_lib)/include
-lib=-L$(igl_lib)/lib -ligl -framework Accelerate
+inc=$(LIBIGL_INC) 
+lib=$(LIBIGL_LIB) -framework Accelerate
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 1 - 14
examples/textured-mesh/Makefile

@@ -1,26 +1,13 @@
-
 .PHONY: all
 
 # Shared flags etc.
 include ../../build/Makefile.conf
+LIBIGL_LIB+=-liglpng
 
 all: example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglpng
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-# YIMAGE Library
-YIMG=$(LIBIGL)/external/yimg/
-YIMG_LIB=-L$(YIMG) -lyimg -lz -L/opt/local/lib -lpng -bind_at_load
-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
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(YIMG_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(YIMG_LIB)
 

+ 2 - 4
examples/trackball/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 all: example
@@ -12,9 +11,8 @@ igl_lib=../../
 
 CFLAGS+=-g -Wall 
 #deps=-MMD -MF depends.txt
-EIGEN3_INC=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
-inc=-I$(igl_lib)/include $(EIGEN3_INC)
-lib=$(OPENGL_LIB) $(GLUT_LIB) -L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB) $(OPENGL_LIB) $(GLUT_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 14
examples/transparency/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,21 +7,10 @@ all: example
 
 .PHONY: example
 
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 CFLAGS+=-O3 -fopenmp
 
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
-
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(MATLAB_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(MATLAB_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
 example: example.o
 	g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -o example example.o $(LIB)

+ 2 - 6
examples/transpose_blocks/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -8,12 +7,9 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
-eigen=$(DEFAULT_PREFIX)/include/eigen3
-
 CFLAGS+=-g
-inc=-I$(igl_lib)/include -I$(eigen)
-lib=-L$(igl_lib)/lib -ligl
+inc=$(LIBIGL_INC) $(EIGEN3_INC)
+lib=$(LIBIGL_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 2 - 12
examples/upright/Makefile

@@ -1,4 +1,3 @@
-
 .PHONY: all
 
 # Shared flags etc.
@@ -7,19 +6,10 @@ all: upright
 
 .PHONY: upright
 
-LIBIGL=/usr/local/igl/libigl/
-include $(LIBIGL)/build/Makefile.conf
-LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
-
-EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
-
-CARBON_LIB=-framework Carbon
+include ../..//build/Makefile.conf
 
-ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
-ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(CARBON_LIB)
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
 CFLAGS+=-g
 

+ 45 - 47
include/igl/RotateWidget.h

@@ -379,11 +379,8 @@ inline void igl::RotateWidget::draw() const
   using namespace Eigen;
   using namespace std;
   using namespace igl;
-  int l,dt;
-  glGetIntegerv(GL_LIGHTING,&l);
-  glGetIntegerv(GL_DEPTH_TEST,&dt);
-  double lw;
-  glGetDoublev(GL_LINE_WIDTH,&lw);
+  glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_LINE_BIT);
+  glDisable(GL_CLIP_PLANE0);
 
   glDisable(GL_LIGHTING);
   glDisable(GL_DEPTH_TEST);
@@ -470,9 +467,7 @@ inline void igl::RotateWidget::draw() const
   draw_guide();
   glPopMatrix();
 
-  glLineWidth(lw);
-  (l ? glEnable(GL_LIGHTING):glDisable(GL_LIGHTING));
-  (dt ? glEnable(GL_DEPTH_TEST):glDisable(GL_DEPTH_TEST));
+  glPopAttrib();
 };
 
 inline void igl::RotateWidget::draw_guide() const
@@ -480,12 +475,15 @@ inline void igl::RotateWidget::draw_guide() const
   using namespace Eigen;
   using namespace std;
   using namespace igl;
-  int posm,post,cf;
-  glGetIntegerv(GL_CULL_FACE,&cf);
-  glGetIntegerv(GL_POINT_SMOOTH,&posm);
-  glGetIntegerv(GL_POLYGON_STIPPLE,&post);
-  double posi;
-  glGetDoublev(GL_POINT_SIZE,&posi);
+  glPushAttrib(
+    GL_DEPTH_BUFFER_BIT | 
+    GL_ENABLE_BIT | 
+    GL_POLYGON_BIT | 
+    GL_POINT_BIT | 
+    GL_TRANSFORM_BIT |
+    GL_STENCIL_BUFFER_BIT |
+    GL_LIGHTING_BIT);
+
   // http://www.codeproject.com/Articles/23444/A-Simple-OpenGL-Stipple-Polygon-Example-EP_OpenGL_
   const GLubyte halftone[] = {
     0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
@@ -510,47 +508,47 @@ inline void igl::RotateWidget::draw_guide() const
   {
     case DOWN_TYPE_NONE:
     case DOWN_TYPE_TRACKBALL:
-      return;
+      goto finish;
     case DOWN_TYPE_OUTLINE:
       glScaled(outer_over_inner,outer_over_inner,outer_over_inner);
       break;
     default:
       break;
   }
-  const Vector3d nudown(udown.normalized()), 
-    nudrag(udrag.normalized());
-  glPushMatrix();
-  glDisable(GL_CULL_FACE);
-  glDisable(GL_POINT_SMOOTH);
-  glPointSize(5.);
-  glBegin(GL_POINTS);
-  glVertex3dv(nudown.data());
-  glVertex3d(0,0,0);
-  glVertex3dv(nudrag.data());
-  glEnd();
-  glBegin(GL_LINE_STRIP);
-  glVertex3dv(nudown.data());
-  glVertex3d(0,0,0);
-  glVertex3dv(nudrag.data());
-  glEnd();
-  glEnable(GL_POLYGON_STIPPLE);
-  glPolygonStipple(halftone);
-  glBegin(GL_TRIANGLE_FAN);
-  glVertex3d(0,0,0);
-  Quaterniond dq = rot * down_rot.conjugate();
-  //dq.setFromTwoVectors(nudown,nudrag);
-  for(double t = 0;t<1;t+=0.1)
   {
-    const Vector3d p = Quaterniond::Identity().slerp(t,dq) * nudown;
-    glVertex3dv(p.data());
+    const Vector3d nudown(udown.normalized()), 
+      nudrag(udrag.normalized());
+    glPushMatrix();
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_POINT_SMOOTH);
+    glPointSize(5.);
+    glBegin(GL_POINTS);
+    glVertex3dv(nudown.data());
+    glVertex3d(0,0,0);
+    glVertex3dv(nudrag.data());
+    glEnd();
+    glBegin(GL_LINE_STRIP);
+    glVertex3dv(nudown.data());
+    glVertex3d(0,0,0);
+    glVertex3dv(nudrag.data());
+    glEnd();
+    glEnable(GL_POLYGON_STIPPLE);
+    glPolygonStipple(halftone);
+    glBegin(GL_TRIANGLE_FAN);
+    glVertex3d(0,0,0);
+    Quaterniond dq = rot * down_rot.conjugate();
+    //dq.setFromTwoVectors(nudown,nudrag);
+    for(double t = 0;t<1;t+=0.1)
+    {
+      const Vector3d p = Quaterniond::Identity().slerp(t,dq) * nudown;
+      glVertex3dv(p.data());
+    }
+    glVertex3dv(nudrag.data());
+    glEnd();
+    glPopMatrix();
   }
-  glVertex3dv(nudrag.data());
-  glEnd();
-  glPopMatrix();
-  glPointSize(posi);
-  (cf?glEnable(GL_CULL_FACE):glDisable(GL_CULL_FACE));
-  (posm?glEnable(GL_POINT_SMOOTH):glDisable(GL_POINT_SMOOTH));
-  (post?glEnable(GL_POLYGON_STIPPLE):glDisable(GL_POLYGON_STIPPLE));
+finish:
+  glPopAttrib();
 }
 
 #endif

+ 47 - 8
include/igl/boolean/mesh_boolean.cpp

@@ -233,16 +233,55 @@ IGL_INLINE void igl::mesh_boolean(
 #ifdef IGL_MESH_BOOLEAN_DEBUG
   cout<<"clean..."<<endl;
 #endif
-  // remove duplicates: cancel out in all cases? assertion in others?
+  // Deal with duplicate faces
   {
-    MatrixXi oldG = G;
-    VectorXi IA,_1;
-    unique_simplices(oldG,G,IA,_1);
-    assert(IA.rows() == G.rows());
-    J.resize(IA.rows(),1);
-    for(size_t j = 0;j<(size_t)J.size();j++)
+    VectorXi IA,IC;
+    MatrixX3I uG;
+    unique_simplices(G,uG,IA,IC);
+    assert(IA.rows() == uG.rows());
+    // faces ontop of each unique face
+    vector<vector<Index> > uG2G(uG.rows());
+    // signed counts
+    VectorXi counts = VectorXi::Zero(uG.rows());
+    // loop over all faces
+    for(Index g = 0;g<gm;g++)
     {
-      J(j) = GJ(IA(j));
+      const int ug = IC(g);
+      assert(ug < uG2G.size());
+      uG2G[ug].push_back(g);
+      // is uG(g,:) just a rotated version of G(g,:) ?
+      const bool consistent = 
+        (G(g,0) == uG(ug,0) && G(g,1) == uG(ug,1) && G(g,2) == uG(ug,2)) ||
+        (G(g,0) == uG(ug,1) && G(g,1) == uG(ug,2) && G(g,2) == uG(ug,0)) ||
+        (G(g,0) == uG(ug,2) && G(g,1) == uG(ug,0) && G(g,2) == uG(ug,1));
+      counts(ug) += consistent ? 1 : -1;
+    }
+    MatrixX3I oldG = G;
+    // Faces of output vG[i] = j means ith face of output should be jth face in
+    // oldG
+    vG.clear();
+    for(size_t ug = 0;ug < uG2G.size();ug++)
+    {
+      // if signed occurrences is zero or ±two then keep none
+      // else if signed occurrences is ±one then keep just one facet
+      if(abs(counts(ug)) == 1)
+      {
+        assert(uG2G.size() > 0);
+        vG.push_back(uG2G[ug][0]);
+      }
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+      else
+      {
+        cout<<"Skipping "<<uG2G.size()<<" facets..."<<endl;
+      }
+#endif
+    }
+    G.resize(vG.size(),3);
+    J.resize(vG.size());
+    for(size_t g = 0;g<vG.size();g++)
+    {
+      G.row(g) = oldG.row(vG[g]);
+      J(g) = GJ(vG[g]);
     }
   }
   // remove unreferenced vertices

+ 2 - 2
include/igl/boundary_facets.cpp

@@ -6,7 +6,7 @@
 // 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 "boundary_facets.h"
-#include "face_occurences.h"
+#include "face_occurrences.h"
 
 // IGL includes
 #include "sort.h"
@@ -72,7 +72,7 @@ IGL_INLINE void igl::boundary_facets(
 
   // Counts
   vector<int> C;
-  face_occurences(allF,C);
+  face_occurrences(allF,C);
 
   // Q: Why not just count the number of ones?
   // A: because we are including non-manifold edges as boundary edges

+ 4 - 4
include/igl/cgal/SelfIntersectMesh.h

@@ -1026,14 +1026,14 @@ inline void igl::SelfIntersectMesh<
   const Index total_shared_vertices = comb_shared_vertices + geo_shared_vertices;
   if(comb_shared_vertices== 3)
   {
-    // Combinatorially duplicate face, these should be removed by preprocessing
-    cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are combinatorial duplicates")<<endl;
+    //// Combinatorially duplicate face, these should be removed by preprocessing
+    //cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are combinatorial duplicates")<<endl;
     goto done;
   }
   if(total_shared_vertices== 3)
   {
-    // Geometrically duplicate face, these should be removed by preprocessing
-    cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are geometrical duplicates")<<endl;
+    //// Geometrically duplicate face, these should be removed by preprocessing
+    //cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are geometrical duplicates")<<endl;
     goto done;
   }
   //// SPECIAL CASES ARE BROKEN FOR COPLANAR TRIANGLES

+ 71 - 0
include/igl/circulation.cpp

@@ -0,0 +1,71 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "circulation.h"
+#include "list_to_matrix.h"
+
+IGL_INLINE std::vector<int> igl::circulation(
+  const int e,
+  const bool ccw,
+  const Eigen::MatrixXi & F,
+  const Eigen::MatrixXi & E,
+  const Eigen::VectorXi & EMAP,
+  const Eigen::MatrixXi & EF,
+  const Eigen::MatrixXi & EI)
+{
+  // prepare output
+  std::vector<int> N;
+  N.reserve(6);
+  const int m = F.rows();
+  const auto & step = [&](
+    const int e, 
+    const int ff,
+    int & ne, 
+    int & nf)
+  {
+    assert((EF(e,1) == ff || EF(e,0) == ff) && "e should touch ff");
+    //const int fside = EF(e,1)==ff?1:0;
+    const int nside = EF(e,0)==ff?1:0;
+    const int nv = EI(e,nside);
+    // get next face
+    nf = EF(e,nside);
+    // get next edge 
+    const int dir = ccw?-1:1;
+    ne = EMAP(nf+m*((nv+dir+3)%3));
+  };
+  // Always start with first face (ccw in step will be sure to turn right
+  // direction)
+  const int f0 = EF(e,0);
+  int fi = f0;
+  int ei = e;
+  while(true)
+  {
+    N.push_back(fi);
+    step(ei,fi,ei,fi);
+    // back to start?
+    if(fi == f0)
+    {
+      assert(ei == e);
+      break;
+    }
+  }
+  return N;
+}
+
+IGL_INLINE void igl::circulation(
+  const int e,
+  const bool ccw,
+  const Eigen::MatrixXi & F,
+  const Eigen::MatrixXi & E,
+  const Eigen::VectorXi & EMAP,
+  const Eigen::MatrixXi & EF,
+  const Eigen::MatrixXi & EI,
+  Eigen::VectorXi & vN)
+{
+  std::vector<int> N = circulation(e,ccw,F,E,EMAP,EF,EI);
+  igl::list_to_matrix(N,vN);
+}

+ 56 - 0
include/igl/circulation.h

@@ -0,0 +1,56 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_CIRCULATION_H
+#define IGL_CIRCULATION_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+
+namespace igl
+{
+  // Return list of faces around the end point of an edge. Assumes
+  // data-structures are built from an edge-manifold **closed** mesh.
+  //
+  // Inputs:
+  //   e  index into E of edge to circulate
+  //   ccw  whether to _continue_ in ccw direction of edge (circulate around
+  //     E(e,1))
+  //   F  #F by 3 list of face indices
+  //   E  #E by 2 list of edge indices
+  //   EMAP #F*3 list of indices into E, mapping each directed edge to unique
+  //     unique edge in E
+  //   EF  #E by 2 list of edge flaps, EF(e,0)=f means e=(i-->j) is the edge of
+  //     F(f,:) opposite the vth corner, where EI(e,0)=v. Similarly EF(e,1) "
+  //     e=(j->i)
+  //   EI  #E by 2 list of edge flap corners (see above).
+  // Returns list of faces touched by circulation.
+  //   
+  IGL_INLINE std::vector<int> circulation(
+    const int e,
+    const bool ccw,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & EMAP,
+    const Eigen::MatrixXi & EF,
+    const Eigen::MatrixXi & EI);
+  // Wrapper with VectorXi output.
+  IGL_INLINE void circulation(
+    const int e,
+    const bool ccw,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & EMAP,
+    const Eigen::MatrixXi & EF,
+    const Eigen::MatrixXi & EI,
+    Eigen::VectorXi & vN);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "circulation.cpp"
+#endif
+#endif

+ 156 - 0
include/igl/collapse_edge.cpp

@@ -0,0 +1,156 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "collapse_edge.h"
+#include "circulation.h"
+#include "edge_collapse_is_valid.h"
+#include <vector>
+
+IGL_INLINE bool igl::collapse_edge(
+  const int e,
+  const Eigen::RowVectorXd & p,
+  Eigen::MatrixXd & V,
+  Eigen::MatrixXi & F,
+  Eigen::MatrixXi & E,
+  Eigen::VectorXi & EMAP,
+  Eigen::MatrixXi & EF,
+  Eigen::MatrixXi & EI,
+  int & a_e1,
+  int & a_e2,
+  int & a_f1,
+  int & a_f2)
+{
+  // Assign this to 0 rather than, say, -1 so that deleted elements will get
+  // draw as degenerate elements at vertex 0 (which should always exist and
+  // never get collapsed to anything else since it is the smallest index)
+  using namespace Eigen;
+  using namespace std;
+  using namespace igl;
+  const int eflip = E(e,0)>E(e,1);
+  // source and destination
+  const int s = eflip?E(e,1):E(e,0);
+  const int d = eflip?E(e,0):E(e,1);
+
+  if(!edge_collapse_is_valid(e,F,E,EMAP,EF,EI))
+  {
+    return false;
+  }
+
+  // Important to grab neighbors of d before monkeying with edges
+  const std::vector<int> nV2Fd = circulation(e,!eflip,F,E,EMAP,EF,EI);
+
+  // The following implementation strongly relies on s<d
+  assert(s<d && "s should be less than d");
+  // move source and destination to midpoint
+  V.row(s) = p;
+  V.row(d) = p;
+
+  // Helper function to replace edge and associate information with NULL
+  const auto & kill_edge = [&E,&EI,&EF](const int e)
+  {
+    E(e,0) = IGL_COLLAPSE_EDGE_NULL;
+    E(e,1) = IGL_COLLAPSE_EDGE_NULL;
+    EF(e,0) = IGL_COLLAPSE_EDGE_NULL;
+    EF(e,1) = IGL_COLLAPSE_EDGE_NULL;
+    EI(e,0) = IGL_COLLAPSE_EDGE_NULL;
+    EI(e,1) = IGL_COLLAPSE_EDGE_NULL;
+  };
+
+  // update edge info
+  // for each flap
+  const int m = F.rows();
+  for(int side = 0;side<2;side++)
+  {
+    const int f = EF(e,side);
+    const int v = EI(e,side);
+    const int sign = (eflip==0?1:-1)*(1-2*side);
+    // next edge emanating from d
+    const int e1 = EMAP(f+m*((v+sign*1+3)%3));
+    // prev edge pointing to s
+    const int e2 = EMAP(f+m*((v+sign*2+3)%3));
+    assert(E(e1,0) == d || E(e1,1) == d);
+    assert(E(e2,0) == s || E(e2,1) == s);
+    // face adjacent to f on e1, also incident on d
+    const bool flip1 = EF(e1,1)==f;
+    const int f1 = flip1 ? EF(e1,0) : EF(e1,1);
+    assert(f1!=f);
+    assert(F(f1,0)==d || F(f1,1)==d || F(f1,2) == d);
+    // across from which vertex of f1 does e1 appear?
+    const int v1 = flip1 ? EI(e1,0) : EI(e1,1);
+    // Kill e1
+    kill_edge(e1);
+    // Kill f
+    F(f,0) = IGL_COLLAPSE_EDGE_NULL;
+    F(f,1) = IGL_COLLAPSE_EDGE_NULL;
+    F(f,2) = IGL_COLLAPSE_EDGE_NULL;
+    // map f1's edge on e1 to e2
+    assert(EMAP(f1+m*v1) == e1);
+    EMAP(f1+m*v1) = e2;
+    // side opposite f2, the face adjacent to f on e2, also incident on s
+    const int opp2 = (EF(e2,0)==f?0:1);
+    assert(EF(e2,opp2) == f);
+    EF(e2,opp2) = f1;
+    EI(e2,opp2) = v1;
+    // remap e2 from d to s
+    E(e2,0) = E(e2,0)==d ? s : E(e2,0);
+    E(e2,1) = E(e2,1)==d ? s : E(e2,1);
+    if(side==0)
+    {
+      a_e1 = e1;
+      a_f1 = f;
+    }else
+    {
+      a_e2 = e1;
+      a_f2 = f;
+    }
+  }
+
+  // finally, reindex faces and edges incident on d. Do this last so asserts
+  // make sense.
+  //
+  // Could actually skip first two, since those are always the two collpased
+  // faces.
+  for(auto f : nV2Fd)
+  {
+    for(int v = 0;v<3;v++)
+    {
+      if(F(f,v) == d)
+      {
+        const int flip1 = (EF(EMAP(f+m*((v+1)%3)),0)==f)?1:0;
+        const int flip2 = (EF(EMAP(f+m*((v+2)%3)),0)==f)?0:1;
+        assert(
+          E(EMAP(f+m*((v+1)%3)),flip1) == d ||
+          E(EMAP(f+m*((v+1)%3)),flip1) == s);
+        E(EMAP(f+m*((v+1)%3)),flip1) = s;
+        assert(
+          E(EMAP(f+m*((v+2)%3)),flip2) == d ||
+          E(EMAP(f+m*((v+2)%3)),flip2) == s);
+        E(EMAP(f+m*((v+2)%3)),flip2) = s;
+        F(f,v) = s;
+        break;
+      }
+    }
+  }
+  // Finally, "remove" this edge and its information
+  kill_edge(e);
+
+  return true;
+}
+
+IGL_INLINE bool igl::collapse_edge(
+  const int e,
+  const Eigen::RowVectorXd & p,
+  Eigen::MatrixXd & V,
+  Eigen::MatrixXi & F,
+  Eigen::MatrixXi & E,
+  Eigen::VectorXi & EMAP,
+  Eigen::MatrixXi & EF,
+  Eigen::MatrixXi & EI)
+{
+  int e1,e2,f1,f2;
+  return collapse_edge(e,p,V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
+}

+ 70 - 0
include/igl/collapse_edge.h

@@ -0,0 +1,70 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_COLLAPSE_EDGE_H
+#define IGL_COLLAPSE_EDGE_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // Assumes (V,F) is a closed manifold mesh (except for previouslly collapsed
+  // faces which should be set to: 
+  // [IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL].
+  // Collapses exactly two faces and exactly 3 edges from E (e and one side of
+  // each face gets collapsed to the other). This is implemented in a way that
+  // it can be repeatedly called until satisfaction and then the garbage in F
+  // can be collected by removing NULL faces.
+  //
+  // Inputs:
+  //   e  index into E of edge to try to collapse. E(e,:) = [s d] or [d s] so
+  //     that s<d, then d is collapsed to s.
+  ///  p  dim list of vertex position where to place merged vertex
+  // Inputs/Outputs:
+  //   V  #V by dim list of vertex positions, lesser index of E(e,:) will be set
+  //     to midpoint of edge.
+  //   F  #F by 3 list of face indices into V.
+  //   E  #E by 2 list of edge indices into V.
+  //   EMAP #F*3 list of indices into E, mapping each directed edge to unique
+  //     unique edge in E
+  //   EF  #E by 2 list of edge flaps, EF(e,0)=f means e=(i-->j) is the edge of
+  //     F(f,:) opposite the vth corner, where EI(e,0)=v. Similarly EF(e,1) "
+  //     e=(j->i)
+  //   EI  #E by 2 list of edge flap corners (see above).
+  //   e1  index into E of edge collpased on left
+  //   e2  index into E of edge collpased on left
+  //   f1  index into E of edge collpased on left
+  //   f2  index into E of edge collpased on left
+  // Returns true if edge was collapsed
+  #define IGL_COLLAPSE_EDGE_NULL 0
+  IGL_INLINE bool collapse_edge(
+    const int e,
+    const Eigen::RowVectorXd & p,
+    Eigen::MatrixXd & V,
+    Eigen::MatrixXi & F,
+    Eigen::MatrixXi & E,
+    Eigen::VectorXi & EMAP,
+    Eigen::MatrixXi & EF,
+    Eigen::MatrixXi & EI,
+    int & e1,
+    int & e2,
+    int & f1,
+    int & f2);
+  IGL_INLINE bool collapse_edge(
+    const int e,
+    const Eigen::RowVectorXd & p,
+    Eigen::MatrixXd & V,
+    Eigen::MatrixXi & F,
+    Eigen::MatrixXi & E,
+    Eigen::VectorXi & EMAP,
+    Eigen::MatrixXi & EF,
+    Eigen::MatrixXi & EI);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "collapse_edge.cpp"
+#endif
+#endif

+ 1 - 1
include/igl/doublearea.cpp

@@ -133,7 +133,7 @@ IGL_INLINE void igl::doublearea(
   #  define IGL_OMP_MIN_VALUE 1000
   #endif
   #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
-  for(long int i = 0;i<m;i++)
+  for(size_t i = 0;i<m;i++)
   {
     //// Heron's formula for area
     //const typename Derivedl::Scalar arg =

+ 87 - 0
include/igl/edge_collapse_is_valid.cpp

@@ -0,0 +1,87 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "edge_collapse_is_valid.h"
+#include "collapse_edge.h"
+#include "circulation.h"
+#include "intersect.h"
+#include "unique.h"
+#include "list_to_matrix.h"
+#include <vector>
+
+IGL_INLINE bool igl::edge_collapse_is_valid(
+  const int e,
+  const Eigen::MatrixXi & F,
+  const Eigen::MatrixXi & E,
+  const Eigen::VectorXi & EMAP,
+  const Eigen::MatrixXi & EF,
+  const Eigen::MatrixXi & EI)
+{
+  using namespace Eigen;
+  using namespace std;
+  using namespace igl;
+  // For consistency with collapse_edge.cpp, let's determine edge flipness
+  // (though not needed to check validity)
+  const int eflip = E(e,0)>E(e,1);
+  // source and destination
+  const int s = eflip?E(e,1):E(e,0);
+  const int d = eflip?E(e,0):E(e,1);
+
+  if(s == IGL_COLLAPSE_EDGE_NULL && d==IGL_COLLAPSE_EDGE_NULL)
+  {
+    return false;
+  }
+  // check if edge collapse is valid: intersection of vertex neighbors of s and
+  // d should be exactly 2+(s,d) = 4
+  // http://stackoverflow.com/a/27049418/148668
+  {
+    // all vertex neighbors around edge, including the two vertices of the edge
+    const auto neighbors = [](
+      const int e,
+      const bool ccw,
+      const Eigen::MatrixXi & F,
+      const Eigen::MatrixXi & E,
+      const Eigen::VectorXi & EMAP,
+      const Eigen::MatrixXi & EF,
+      const Eigen::MatrixXi & EI) 
+    {
+      vector<int> N,uN;
+      vector<int> V2Fe = circulation(e, ccw,F,E,EMAP,EF,EI);
+      for(auto f : V2Fe)
+      {
+        N.push_back(F(f,0));
+        N.push_back(F(f,1));
+        N.push_back(F(f,2));
+      }
+      vector<size_t> _1,_2;
+      igl::unique(N,uN,_1,_2);
+      VectorXi uNm;
+      list_to_matrix(uN,uNm);
+      return uNm;
+    };
+    VectorXi Ns = neighbors(e, eflip,F,E,EMAP,EF,EI);
+    VectorXi Nd = neighbors(e,!eflip,F,E,EMAP,EF,EI);
+    VectorXi Nint = igl::intersect(Ns,Nd);
+    if(Nint.size() != 4)
+    {
+      return false;
+    }
+    if(Ns.size() == 4 && Nd.size() == 4)
+    {
+      VectorXi NsNd(8);
+      NsNd<<Ns,Nd;
+      VectorXi Nun,_1,_2;
+      igl::unique(NsNd,Nun,_1,_2);
+      // single tet, don't collapse
+      if(Nun.size() == 4)
+      {
+        return false;
+      }
+    }
+  }
+  return true;
+}

+ 44 - 0
include/igl/edge_collapse_is_valid.h

@@ -0,0 +1,44 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_EDGE_COLLAPSE_IS_VALID_H
+#define IGL_EDGE_COLLAPSE_IS_VALID_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // Assumes (V,F) is a closed manifold mesh (except for previouslly collapsed
+  // faces which should be set to: 
+  // [IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL].
+  // Tests whether collapsing exactly two faces and exactly 3 edges from E (e
+  // and one side of each face gets collapsed to the other) will result in a
+  // mesh with the same topology.
+  //
+  // Inputs:
+  //   e  index into E of edge to try to collapse. E(e,:) = [s d] or [d s] so
+  //     that s<d, then d is collapsed to s.
+  //   F  #F by 3 list of face indices into V.
+  //   E  #E by 2 list of edge indices into V.
+  //   EMAP #F*3 list of indices into E, mapping each directed edge to unique
+  //     unique edge in E
+  //   EF  #E by 2 list of edge flaps, EF(e,0)=f means e=(i-->j) is the edge of
+  //     F(f,:) opposite the vth corner, where EI(e,0)=v. Similarly EF(e,1) "
+  //     e=(j->i)
+  //   EI  #E by 2 list of edge flap corners (see above).
+  // Returns true if edge collapse is valid
+  IGL_INLINE bool edge_collapse_is_valid(
+    const int e,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & EMAP,
+    const Eigen::MatrixXi & EF,
+    const Eigen::MatrixXi & EI);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "edge_collapse_is_valid.cpp"
+#endif
+#endif

+ 59 - 0
include/igl/edge_flaps.cpp

@@ -0,0 +1,59 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "edge_flaps.h"
+#include "unique_edge_map.h"
+#include <vector>
+#include <cassert>
+
+IGL_INLINE void igl::edge_flaps(
+  const Eigen::MatrixXi & F,
+  const Eigen::MatrixXi & E,
+  const Eigen::VectorXi & EMAP,
+  Eigen::MatrixXi & EF,
+  Eigen::MatrixXi & EI)
+{
+  EF.resize(E.rows(),2);
+  EI.resize(E.rows(),2);
+  // loop over all faces
+  for(int f = 0;f<F.rows();f++)
+  {
+    // loop over edges across from corners
+    for(int v = 0;v<3;v++)
+    {
+      // get edge id
+      const int e = EMAP(v*F.rows()+f);
+      // See if this is left or right flap w.r.t. edge orientation
+      if( F(f,(v+1)%3) == E(e,0) && F(f,(v+2)%3) == E(e,1))
+      {
+        EF(e,0) = f;
+        EI(e,0) = v;
+      }else
+      {
+        assert(F(f,(v+1)%3) == E(e,1) && F(f,(v+2)%3) == E(e,0));
+        EF(e,1) = f;
+        EI(e,1) = v;
+      }
+    }
+  }
+}
+
+IGL_INLINE void igl::edge_flaps(
+  const Eigen::MatrixXi & F,
+  Eigen::MatrixXi & E,
+  Eigen::VectorXi & EMAP,
+  Eigen::MatrixXi & EF,
+  Eigen::MatrixXi & EI)
+{
+  Eigen::MatrixXi allE;
+  std::vector<std::vector<int> > uE2E;
+  igl::unique_edge_map(F,allE,E,EMAP,uE2E);
+  // Const-ify to call overload
+  const auto & cE = E;
+  const auto & cEMAP = EMAP;
+  return edge_flaps(F,cE,cEMAP,EF,EI);
+}

+ 45 - 0
include/igl/edge_flaps.h

@@ -0,0 +1,45 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_EDGE_FLAPS_H
+#define IGL_EDGE_FLAPS_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // Determine "edge flaps": two faces on either side of a unique edge (assumes
+  // edge-manifold mesh)
+  //
+  // Inputs:
+  //   F  #F by 3 list of face indices
+  //   E  #E by 2 list of edge indices into V.
+  //   EMAP #F*3 list of indices into E, mapping each directed edge to unique
+  //     unique edge in E
+  // Outputs:
+  //   EF  #E by 2 list of edge flaps, EF(e,0)=f means e=(i-->j) is the edge of
+  //     F(f,:) opposite the vth corner, where EI(e,0)=v. Similarly EF(e,1) "
+  //     e=(j->i)
+  //   EI  #E by 2 list of edge flap corners (see above).
+  IGL_INLINE void edge_flaps(
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & EMAP,
+    Eigen::MatrixXi & EF,
+    Eigen::MatrixXi & EI);
+  // Only faces as input
+  IGL_INLINE void edge_flaps(
+    const Eigen::MatrixXi & F,
+    Eigen::MatrixXi & E,
+    Eigen::VectorXi & EMAP,
+    Eigen::MatrixXi & EF,
+    Eigen::MatrixXi & EI);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "edge_flaps.cpp"
+#endif
+
+#endif

+ 3 - 3
include/igl/face_occurences.cpp → include/igl/face_occurrences.cpp

@@ -5,14 +5,14 @@
 // 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_occurences.h"
+#include "face_occurrences.h"
 
 #include <map>
 #include "sort.h"
 #include <cassert>
 
 template <typename IntegerF, typename IntegerC>
-IGL_INLINE void igl::face_occurences(
+IGL_INLINE void igl::face_occurrences(
   const std::vector<std::vector<IntegerF> > & F,
   std::vector<IntegerC> & C)
 {
@@ -52,5 +52,5 @@ IGL_INLINE void igl::face_occurences(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
-template void igl::face_occurences<int, int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<int, std::allocator<int> >&);
+template void igl::face_occurrences<int, int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<int, std::allocator<int> >&);
 #endif

+ 4 - 4
include/igl/face_occurences.h → include/igl/face_occurrences.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_FACE_OCCURENCES
-#define IGL_FACE_OCCURENCES
+#ifndef IGL_FACE_OCCURRENCES
+#define IGL_FACE_OCCURRENCES
 #include "igl_inline.h"
 
 #include <vector>
@@ -20,13 +20,13 @@ namespace igl
   //   C  #F list of counts
   // Known bug: triangles/tets only (where ignoring order still gives simplex)
   template <typename IntegerF, typename IntegerC>
-  IGL_INLINE void face_occurences(
+  IGL_INLINE void face_occurrences(
     const std::vector<std::vector<IntegerF> > & F,
     std::vector<IntegerC> & C);
 }
 
 #ifndef IGL_STATIC_LIBRARY
-#  include "face_occurences.cpp"
+#  include "face_occurrences.cpp"
 #endif
 
 #endif

+ 26 - 1
include/igl/find.cpp

@@ -52,7 +52,7 @@ IGL_INLINE void igl::find(
   Eigen::PlainObjectBase<DerivedJ> & J,
   Eigen::PlainObjectBase<DerivedV> & V)
 {
-  const int nnz = X.template cast<bool>().template cast<int>().sum();
+  const int nnz = X.count();
   I.resize(nnz,1);
   J.resize(nnz,1);
   V.resize(nnz,1);
@@ -73,6 +73,31 @@ IGL_INLINE void igl::find(
     }
   }
 }
+
+template <
+  typename DerivedX,
+  typename DerivedI>
+IGL_INLINE void igl::find(
+  const Eigen::PlainObjectBase<DerivedX>& X,
+  Eigen::PlainObjectBase<DerivedI> & I)
+{
+  const int nnz = X.count();
+  I.resize(nnz,1);
+  {
+    int k = 0;
+    for(int j = 0;j<X.cols();j++)
+    {
+      for(int i = 0;i<X.rows();i++)
+      {
+        if(X(i,j))
+        {
+          I(k) = i+X.rows()*j;
+          k++;
+        }
+      }
+    }
+  }
+}
   
 template <typename T>
 IGL_INLINE void igl::find(

+ 6 - 0
include/igl/find.h

@@ -45,6 +45,12 @@ namespace igl
     Eigen::PlainObjectBase<DerivedI> & I,
     Eigen::PlainObjectBase<DerivedJ> & J,
     Eigen::PlainObjectBase<DerivedV> & V);
+  template <
+    typename DerivedX,
+    typename DerivedI>
+  IGL_INLINE void find(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    Eigen::PlainObjectBase<DerivedI> & I);
   // Find the non-zero entries and there respective indices in a sparse vector.
   // Similar to matlab's [I,J,V] = find(X), but instead of [I,J] being
   // subscripts into X, since X is a vector we just return I, a list of indices

+ 0 - 1
include/igl/harwell_boeing.h

@@ -9,7 +9,6 @@
 #define IGL_HARWELL_BOEING_H
 #include "igl_inline.h"
 
-#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
 #include <Eigen/Sparse>
 #include <vector>
 

+ 305 - 0
include/igl/linprog.cpp

@@ -0,0 +1,305 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "linprog.h"
+#include "slice.h"
+#include "slice_into.h"
+#include "find.h"
+#include "matlab_format.h"
+#include "colon.h"
+#include <iostream>
+
+//#define IGL_LINPROG_VERBOSE
+IGL_INLINE bool igl::linprog(
+  const Eigen::VectorXd & c,
+  const Eigen::MatrixXd & _A,
+  const Eigen::VectorXd & b,
+  const int k,
+  Eigen::VectorXd & x)
+{
+  // This is a very literal translation of
+  // http://www.mathworks.com/matlabcentral/fileexchange/2166-introduction-to-linear-algebra/content/strang/linprog.m
+  using namespace Eigen;
+  using namespace std;
+  using namespace igl;
+  bool success = true;
+  // number of constraints
+  const int m = _A.rows();
+  // number of original variables
+  const int n = _A.cols();
+  // number of iterations
+  int it = 0;
+  // maximum number of iterations
+  //const int MAXIT = 10*m;
+  const int MAXIT = 100*m;
+  // residual tolerance
+  const double tol = 1e-10;
+  const auto & sign = [](const Eigen::VectorXd & B) -> Eigen::VectorXd
+  {
+    Eigen::VectorXd Bsign(B.size());
+    for(int i = 0;i<B.size();i++)
+    {
+      Bsign(i) = B(i)>0?1:(B(i)<0?-1:0);
+    }
+    return Bsign;
+  };
+  // initial (inverse) basis matrix
+  VectorXd Dv = sign(sign(b).array()+0.5);
+  Dv.head(k).setConstant(1.);
+  MatrixXd D = Dv.asDiagonal();
+  // Incorporate slack variables
+  MatrixXd A(_A.rows(),_A.cols()+D.cols());
+  A<<_A,D;
+  // Initial basis
+  VectorXi B = igl::colon<int>(n,n+m-1);
+  // non-basis, may turn out that vector<> would be better here
+  VectorXi N = igl::colon<int>(0,n-1);
+  int j;
+  double bmin = b.minCoeff(&j);
+  int phase;
+  VectorXd xb;
+  VectorXd s;
+  VectorXi J;
+  if(k>0 && bmin<0)
+  {
+    phase = 1;
+    xb = VectorXd::Ones(m);
+    // super cost
+    s.resize(n+m+1);
+    s<<VectorXd::Zero(n+k),VectorXd::Ones(m-k+1);
+    N.resize(n+1);
+    N<<igl::colon<int>(0,n-1),B(j);
+    J.resize(B.size()-1);
+    // [0 1 2 3 4]
+    //      ^
+    // [0 1]
+    //      [3 4]
+    J.head(j) = B.head(j);
+    J.tail(B.size()-j-1) = B.tail(B.size()-j-1);
+    B(j) = n+m;
+    MatrixXd AJ;
+    igl::slice(A,J,2,AJ);
+    const VectorXd a = b - AJ.rowwise().sum();
+    {
+      MatrixXd old_A = A;
+      A.resize(A.rows(),A.cols()+a.cols());
+      A<<old_A,a;
+    }
+    D.col(j) = -a/a(j);
+    D(j,j) = 1./a(j);
+  }else if(k==m)
+  {
+    phase = 2;
+    xb = b;
+    s.resize(c.size()+m);
+    // cost function
+    s<<c,VectorXd::Zero(m);
+  }else //k = 0 or bmin >=0
+  {
+    phase = 1;
+    xb = b.array().abs();
+    s.resize(n+m);
+    // super cost
+    s<<VectorXd::Zero(n+k),VectorXd::Ones(m-k);
+  }
+  while(phase<3)
+  {
+    double df = -1;
+    int t = std::numeric_limits<int>::max();
+    // Lagrange mutipliers fro Ax=b
+    VectorXd yb = D.transpose() * igl::slice(s,B);
+    while(true)
+    {
+      if(MAXIT>0 && it>=MAXIT)
+      {
+#ifdef IGL_LINPROG_VERBOSE
+        cerr<<"linprog: warning! maximum iterations without convergence."<<endl;
+#endif
+        success = false;
+        break;
+      }
+      // no freedom for minimization
+      if(N.size() == 0)
+      {
+        break;
+      }
+      // reduced costs
+      VectorXd sN = igl::slice(s,N);
+      MatrixXd AN = igl::slice(A,N,2);
+      VectorXd r = sN - AN.transpose() * yb;
+      int q;
+      // determine new basic variable
+      double rmin = r.minCoeff(&q);
+      // optimal! infinity norm
+      if(rmin>=-tol*(sN.array().abs().maxCoeff()+1))
+      {
+        break;
+      }
+      // increment iteration count
+      it++;
+      // apply Bland's rule to avoid cycling
+      if(df>=0)
+      {
+        if(MAXIT == -1)
+        {
+#ifdef IGL_LINPROG_VERBOSE
+          cerr<<"linprog: warning! degenerate vertex"<<endl;
+#endif
+          success = false;
+        }
+        igl::find((r.array()<0).eval(),J);
+        double Nq = igl::slice(N,J).minCoeff();
+        // again seems like q is assumed to be a scalar though matlab code
+        // could produce a vector for multiple matches
+        (N.array()==Nq).cast<int>().maxCoeff(&q);
+      }
+      VectorXd d = D*A.col(N(q));
+      VectorXi I;
+      igl::find((d.array()>tol).eval(),I);
+      if(I.size() == 0)
+      {
+#ifdef IGL_LINPROG_VERBOSE
+        cerr<<"linprog: warning! solution is unbounded"<<endl;
+#endif
+        // This seems dubious:
+        it=-it;
+        success = false;
+        break;
+      }
+      VectorXd xbd = igl::slice(xb,I).array()/igl::slice(d,I).array();
+      // new use of r
+      int p;
+      {
+        double r;
+        r = xbd.minCoeff(&p);
+        p = I(p);
+        // apply Bland's rule to avoid cycling
+        if(df>=0)
+        {
+          igl::find((xbd.array()==r).eval(),J);
+          double Bp = igl::slice(B,igl::slice(I,J)).minCoeff();
+          // idiotic way of finding index in B of Bp
+          // code down the line seems to assume p is a scalar though the matlab
+          // code could find a vector of matches)
+          (B.array()==Bp).cast<int>().maxCoeff(&p);
+        }
+        // update x
+        xb -= r*d;
+        xb(p) = r;
+        // change in f
+        df = r*rmin;
+      }
+      // row vector
+      RowVectorXd v = D.row(p)/d(p);
+      yb += v.transpose() * (s(N(q)) - d.transpose()*igl::slice(s,B));
+      d(p)-=1;
+      // update inverse basis matrix
+      D = D - d*v;
+      t = B(p);
+      B(p) = N(q);
+      if(t>(n+k-1))
+      {
+        // remove qth entry from N
+        VectorXi old_N = N;
+        N.resize(N.size()-1);
+        N.head(q) = old_N.head(q);
+        N.head(q) = old_N.head(q);
+        N.tail(old_N.size()-q-1) = old_N.tail(old_N.size()-q-1);
+      }else
+      {
+        N(q) = t;
+      }
+    }
+    // iterative refinement
+    xb = (xb+D*(b-igl::slice(A,B,2)*xb)).eval();
+    // must be due to rounding
+    VectorXi I;
+    igl::find((xb.array()<0).eval(),I);
+    if(I.size()>0)
+    {
+      // so correct
+      VectorXd Z = VectorXd::Zero(I.size(),1);
+      igl::slice_into(Z,I,xb);
+    }
+    // B, xb,n,m,res=A(:,B)*xb-b
+    if(phase == 2 || it<0)
+    {
+      break;
+    }
+    if(xb.transpose()*igl::slice(s,B) > tol)
+    {
+      it = -it;
+#ifdef IGL_LINPROG_VERBOSE
+      cerr<<"linprog: warning, no feasible solution"<<endl;
+#endif
+      success = false;
+      break;
+    }
+    // re-initialize for Phase 2
+    phase = phase+1;
+    s*=1e6*c.array().abs().maxCoeff();
+    s.head(n) = c;
+  }
+  x.resize(std::max(B.maxCoeff()+1,n));
+  igl::slice_into(xb,B,x);
+  x = x.head(n).eval();
+  return success;
+}
+
+IGL_INLINE bool igl::linprog(
+  const Eigen::VectorXd & f,
+  const Eigen::MatrixXd & A,
+  const Eigen::VectorXd & b,
+  const Eigen::MatrixXd & B,
+  const Eigen::VectorXd & c,
+  Eigen::VectorXd & x)
+{
+  using namespace Eigen;
+  using namespace igl;
+  using namespace std;
+  const int m = A.rows();
+  const int n = A.cols();
+  const int p = B.rows();
+  MatrixXd Im = MatrixXd::Identity(m,m);
+  MatrixXd AS(m,n+m);
+  AS<<A,Im;
+  MatrixXd bS = b.array().abs();
+  for(int i = 0;i<m;i++)
+  {
+    const auto & sign = [](double x)->double
+    {
+      return (x<0?-1:(x>0?1:0));
+    };
+    AS.row(i) *= sign(b(i));
+  }
+  MatrixXd In = MatrixXd::Identity(n,n);
+  MatrixXd P(n+m,2*n+m);
+  P<<              In, -In, MatrixXd::Zero(n,m),
+     MatrixXd::Zero(m,2*n), Im;
+  MatrixXd ASP = AS*P;
+  MatrixXd BSP(0,2*n+m);
+  if(p>0)
+  {
+    MatrixXd BS(p,2*n);
+    BS<<B,MatrixXd::Zero(p,n);
+    BSP = BS*P;
+  }
+
+  VectorXd fSP = VectorXd::Ones(2*n+m);
+  fSP.head(2*n) = P.block(0,0,n,2*n).transpose()*f;
+  const VectorXd & cc = fSP;
+
+  MatrixXd AA(m+p,2*n+m);
+  AA<<ASP,BSP;
+  VectorXd bb(m+p);
+  bb<<bS,c;
+
+  VectorXd xxs;
+  bool ret = linprog(cc,AA,bb,0,xxs);
+  x = P.block(0,0,n,2*n+m)*xxs;
+  return ret;
+}

+ 65 - 0
include/igl/linprog.h

@@ -0,0 +1,65 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_LINPROG_H
+#define IGL_LINPROG_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // Solve a linear program given in "standard form"
+  //
+  // min  f'x
+  // s.t. A(    1:k,:) x <= b(1:k)
+  //      A(k+1:end,:) x = b(k+1:end)
+  //   ** x >= 0 **
+  //
+  // In contrast to other APIs the entries in b may be negative.
+  //
+  // Inputs:
+  //   c  #x list of linear coefficients
+  //   A  #A by #x matrix of linear constraint coefficients
+  //   b  #A list of linear constraint right-hand sides
+  //   k  number of inequality constraints as first rows of A,b
+  // Outputs:
+  //   x  #x solution vector
+  //
+  IGL_INLINE bool linprog(
+    const Eigen::VectorXd & c,
+    const Eigen::MatrixXd & A,
+    const Eigen::VectorXd & b,
+    const int k,
+    Eigen::VectorXd & f);
+  
+  // Wrapper in friendlier general form (no implicit bounds on x)
+  //
+  // min  f'x
+  // s.t. A x <= b
+  //      B x = c
+  //
+  // Inputs:
+  //   f  #x list of linear coefficients
+  //   A  #A by #x matrix of linear inequality constraint coefficients
+  //   b  #A list of linear constraint right-hand sides
+  //   B  #B by #x matrix of linear equality constraint coefficients
+  //   c  #B list of linear constraint right-hand sides
+  // Outputs:
+  //   x  #x solution vector
+  //
+  IGL_INLINE bool linprog(
+    const Eigen::VectorXd & f,
+    const Eigen::MatrixXd & A,
+    const Eigen::VectorXd & b,
+    const Eigen::MatrixXd & B,
+    const Eigen::VectorXd & c,
+    Eigen::VectorXd & x);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "linprog.cpp"
+#endif
+#endif

+ 162 - 0
include/igl/mosek/mosek_linprog.cpp

@@ -0,0 +1,162 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "mosek_linprog.h"
+#include "../mosek/mosek_guarded.h"
+#include "../harwell_boeing.h"
+#include <limits>
+#include <cmath>
+#include <vector>
+
+IGL_INLINE bool igl::mosek_linprog(
+  const Eigen::VectorXd & c,
+  const Eigen::SparseMatrix<double> & A,
+  const Eigen::VectorXd & lc,
+  const Eigen::VectorXd & uc,
+  const Eigen::VectorXd & lx,
+  const Eigen::VectorXd & ux,
+  Eigen::VectorXd & x)
+{
+  // variables for mosek task, env and result code
+  MSKenv_t env;
+  // Create the MOSEK environment
+  mosek_guarded(MSK_makeenv(&env,NULL));
+  // initialize mosek environment
+  mosek_guarded(MSK_initenv(env));
+  const bool ret = mosek_linprog(c,A,lc,uc,lx,ux,env,x);
+  MSK_deleteenv(&env);
+  return ret;
+}
+
+IGL_INLINE bool igl::mosek_linprog(
+  const Eigen::VectorXd & c,
+  const Eigen::SparseMatrix<double> & A,
+  const Eigen::VectorXd & lc,
+  const Eigen::VectorXd & uc,
+  const Eigen::VectorXd & lx,
+  const Eigen::VectorXd & ux,
+  const MSKenv_t & env,
+  Eigen::VectorXd & x)
+{
+  // following http://docs.mosek.com/7.1/capi/Linear_optimization.html
+  using namespace std;
+  // number of constraints
+  const int m = A.rows();
+  // number of variables
+  const int n = A.cols();
+
+
+  vector<double> vAv;
+  vector<int> vAri,vAcp;
+  int nr;
+  harwell_boeing(A,nr,vAv,vAri,vAcp);
+
+  MSKtask_t task;
+  // Create the optimization task
+  mosek_guarded(MSK_maketask(env,m,n,&task));
+  // no threads
+  mosek_guarded(MSK_putintparam(task,MSK_IPAR_NUM_THREADS,1));
+  if(m>0)
+  {
+    // Append 'm' empty constraints, the constrainst will initially have no
+    // bounds
+    mosek_guarded(MSK_appendcons(task,m));
+  }
+  mosek_guarded(MSK_appendvars(task,n));
+
+  
+  const auto & key = [](const double lxj, const double uxj) ->
+    MSKboundkeye
+  {
+    MSKboundkeye k = MSK_BK_FR;
+    if(isfinite(lxj) && isfinite(uxj))
+    {
+      if(lxj == uxj)
+      {
+        k = MSK_BK_RA;
+      }else{
+        k = MSK_BK_FX;
+      }
+    }else if(isfinite(lxj))
+    {
+      k = MSK_BK_LO;
+    }else if(isfinite(uxj))
+    {
+      k = MSK_BK_UP;
+    }
+    return k;
+  };
+
+  // loop over variables
+  for(int j = 0;j<n;j++)
+  {
+    if(c.size() > 0)
+    {
+      // Set linear term c_j in the objective
+      mosek_guarded(MSK_putcj(task,j,c(j)));
+    }
+
+    // Set constant bounds on variable j
+    const double lxj = lx.size()>0?lx[j]:-numeric_limits<double>::infinity();
+    const double uxj = ux.size()>0?ux[j]: numeric_limits<double>::infinity();
+    mosek_guarded(MSK_putvarbound(task,j,key(lxj,uxj),lxj,uxj));
+
+    if(m>0)
+    {
+      // Input column j of A
+      mosek_guarded(
+        MSK_putacol(
+          task,
+          j,
+          vAcp[j+1]-vAcp[j],
+          &vAri[vAcp[j]],
+          &vAv[vAcp[j]])
+        );
+    }
+  }
+  // loop over constraints
+  for(int i = 0;i<m;i++)
+  {
+    // Set constraint bounds for row i
+    const double lci = lc.size()>0?lc[i]:-numeric_limits<double>::infinity();
+    const double uci = uc.size()>0?uc[i]: numeric_limits<double>::infinity();
+    mosek_guarded(MSK_putconbound(task,i,key(lci,uci),lci,uci));
+  }
+
+  // Now the optimizer has been prepared
+  MSKrescodee trmcode;
+  // run the optimizer
+  mosek_guarded(MSK_optimizetrm(task,&trmcode));
+  // Get status
+  MSKsolstae solsta;
+  MSK_getsolsta (task,MSK_SOL_ITR,&solsta);
+  bool success = false;
+  switch(solsta)
+  {
+    case MSK_SOL_STA_OPTIMAL:   
+    case MSK_SOL_STA_NEAR_OPTIMAL:
+      x.resize(n);
+      /* Request the basic solution. */ 
+      MSK_getxx(task,MSK_SOL_BAS,x.data()); 
+      success = true;
+      break;
+    case MSK_SOL_STA_DUAL_INFEAS_CER:
+    case MSK_SOL_STA_PRIM_INFEAS_CER:
+    case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
+    case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:  
+      //printf("Primal or dual infeasibility certificate found.\n");
+      break;
+    case MSK_SOL_STA_UNKNOWN:
+      //printf("The status of the solution could not be determined.\n");
+      break;
+    default:
+      //printf("Other solution status.");
+      break;
+  }
+  MSK_deletetask(&task);
+  return success;
+}

+ 56 - 0
include/igl/mosek/mosek_linprog.h

@@ -0,0 +1,56 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_MOSEK_LINPROG_H
+#define IGL_MOSEK_LINPROG_H
+#include "../igl_inline.h"
+#include <Eigen/Core>
+#include <Eigen/Sparse>
+#include <mosek.h>
+namespace igl
+{
+  // Solve a linear program using mosek:
+  // 
+  // min c'x
+  // s.t. lc <= A x <= uc
+  //      lx <= x <= ux
+  //
+  // Inputs:
+  //   c  #x list of linear objective coefficients
+  //   A  #A by #x matrix of linear inequality constraint coefficients
+  //   lc  #A list of lower constraint bounds
+  //   uc  #A list of upper constraint bounds
+  //   lx  #x list of lower variable bounds
+  //   ux  #x list of upper variable bounds
+  // Outputs:
+  //   x  #x list of solution values
+  // Returns true iff success.
+  IGL_INLINE bool mosek_linprog(
+    const Eigen::VectorXd & c,
+    const Eigen::SparseMatrix<double> & A,
+    const Eigen::VectorXd & lc,
+    const Eigen::VectorXd & uc,
+    const Eigen::VectorXd & lx,
+    const Eigen::VectorXd & ux,
+    Eigen::VectorXd & x);
+  // Wrapper that keeps mosek environment alive (if licence checking is
+  // becoming a bottleneck)
+  IGL_INLINE bool mosek_linprog(
+    const Eigen::VectorXd & c,
+    const Eigen::SparseMatrix<double> & A,
+    const Eigen::VectorXd & lc,
+    const Eigen::VectorXd & uc,
+    const Eigen::VectorXd & lx,
+    const Eigen::VectorXd & ux,
+    const MSKenv_t & env,
+    Eigen::VectorXd & x);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "mosek_linprog.cpp"
+#endif
+#endif

+ 2 - 2
include/igl/on_boundary.cpp

@@ -9,7 +9,7 @@
 
 // IGL includes
 #include "sort.h"
-#include "face_occurences.h"
+#include "face_occurrences.h"
 
 // STL includes
 
@@ -47,7 +47,7 @@ IGL_INLINE void igl::on_boundary(
   }
   // Counts
   vector<int> FC;
-  face_occurences(F,FC);
+  face_occurrences(F,FC);
   C.resize(T.size(),vector<bool>(4));
   I.resize(T.size(),false);
   for(int i = 0; i< (int)T.size();i++)

+ 78 - 29
include/igl/outer_hull.cpp

@@ -1,15 +1,12 @@
 #include "outer_hull.h"
 #include "outer_facet.h"
-#include "sort.h"
+#include "sortrows.h"
 #include "facet_components.h"
 #include "winding_number.h"
 #include "triangle_triangle_adjacency.h"
 #include "unique_edge_map.h"
 #include "barycenter.h"
 #include "per_face_normals.h"
-#include "all_edges.h"
-#include "colon.h"
-#include "get_seconds.h"
 
 #include <Eigen/Geometry>
 #include <vector>
@@ -64,8 +61,11 @@ IGL_INLINE void igl::outer_hull(
   // uE --> sorted order index 
   // uE --> bool, whether needed to flip face to make "consistent" with unique
   //   edge
+  // Place order of each half-edge in its corresponding sorted list around edge
   VectorXI diIM(3*m);
+  // Whether face's edge used for sorting is consistent with unique edge
   VectorXI dicons(3*m);
+  // dihedral angles of faces around edge with face of edge in dicons
   vector<vector<typename DerivedV::Scalar> > di(uE2E.size());
   // For each list of face-edges incide on a unique edge
   for(size_t ui = 0;ui<(size_t)uE.rows();ui++)
@@ -73,7 +73,7 @@ IGL_INLINE void igl::outer_hull(
     // Base normal vector to orient against
     const auto fe0 = uE2E[ui][0];
     const RowVector3N & eVp = N.row(fe0%m);
-    di[ui].resize(uE2E[ui].size());
+    MatrixXd di_I(uE2E[ui].size(),2);
 
     const typename DerivedF::Scalar d = F(fe0%m,((fe0/m)+2)%3);
     const typename DerivedF::Scalar s = F(fe0%m,((fe0/m)+1)%3);
@@ -94,26 +94,40 @@ IGL_INLINE void igl::outer_hull(
       assert(!cons[fei] || (d == F(f,(c+1)%3)));
       // Angle between n and f
       const RowVector3N & n = N.row(f);
-      di[ui][fei] = M_PI - atan2( eVp.cross(n).dot(eV), eVp.dot(n));
+      di_I(fei,0) = M_PI - atan2( eVp.cross(n).dot(eV), eVp.dot(n));
       if(!cons[fei])
       {
-        di[ui][fei] = di[ui][fei] + M_PI;
-        if(di[ui][fei]>2.*M_PI)
+        di_I(fei,0) = di_I(fei,0) + M_PI;
+        if(di_I(fei,0)>=2.*M_PI)
         {
-          di[ui][fei] = di[ui][fei] - 2.*M_PI;
+          di_I(fei,0) = di_I(fei,0) - 2.*M_PI;
         }
       }
+      // This signing is very important to make sure different edges sort
+      // duplicate faces the same way, regardless of their orientations
+      di_I(fei,1) = (cons[fei]?1.:-1.)*f;
+    }
+    VectorXi IM;
+
+    //igl::sort(di[ui],true,di[ui],IM);
+    // Sort, but break ties using index to ensure that duplicates always show
+    // up in same order.
+    MatrixXd s_di_I;
+    igl::sortrows(di_I,true,s_di_I,IM);
+    di[ui].resize(uE2E[ui].size());
+    for(size_t i = 0;i<di[ui].size();i++)
+    {
+      di[ui][i] = s_di_I(i,0);
     }
-    vector<size_t> IM;
-    igl::sort(di[ui],true,di[ui],IM);
+
     // copy old list
     vector<typename DerivedF::Index> temp = uE2E[ui];
     for(size_t fei = 0;fei<uE2E[ui].size();fei++)
     {
-      uE2E[ui][fei] = temp[IM[fei]];
+      uE2E[ui][fei] = temp[IM(fei)];
       const auto & fe = uE2E[ui][fei];
       diIM(fe) = fei;
-      dicons(fe) = cons[IM[fei]];
+      dicons(fe) = cons[IM(fei)];
     }
 
   }
@@ -177,7 +191,8 @@ IGL_INLINE void igl::outer_hull(
 #ifdef IGL_OUTER_HULL_DEBUG
   cout<<"outer facet: "<<f<<endl;
 #endif
-    int FHcount = 0;
+    int FHcount = 1;
+    FH[f] = true;
     // Q contains list of face edges to continue traversing upong
     queue<int> Q;
     Q.push(f+0*m);
@@ -203,24 +218,18 @@ IGL_INLINE void igl::outer_hull(
         continue;
       }
       EH[e] = true;
-      // first time seeing face
-      if(!FH[f])
-      {
-        FH[f] = true;
-        FHcount++;
-      }
-      // find overlapping face-edges
-      const auto & neighbors = uE2E[EMAP(e)];
-      // normal after possible flipping 
-      const auto & fN = (flip(f)?-1.:1.)*N.row(f);
       // source of edge according to f
       const int fs = flip(f)?F(f,(c+2)%3):F(f,(c+1)%3);
       // destination of edge according to f
       const int fd = flip(f)?F(f,(c+1)%3):F(f,(c+2)%3);
-      // Edge vector according to f's (flipped) orientation.
-      const auto & eV = (V.row(fd)-V.row(fs)).normalized();
       // edge valence
       const size_t val = uE2E[EMAP(e)].size();
+      //// find overlapping face-edges
+      //const auto & neighbors = uE2E[EMAP(e)];
+      //// normal after possible flipping 
+      //const auto & fN = (flip(f)?-1.:1.)*N.row(f);
+      //// Edge vector according to f's (flipped) orientation.
+      ////const auto & eV = (V.row(fd)-V.row(fs)).normalized();
 
 //#warning "EXPERIMENTAL, DO NOT USE"
       //// THIS IS WRONG! The first face is---after sorting---no longer the face
@@ -228,9 +237,37 @@ IGL_INLINE void igl::outer_hull(
       //const auto ui = EMAP(e);
       //const auto fe0 = uE2E[ui][0];
       //const auto es = F(fe0%m,((fe0/m)+1)%3);
+
+      // is edge consistent with edge of face used for sorting
       const int e_cons = (dicons(e) ? 1: -1);
-      const int nfei = (diIM(e) + val + e_cons*(flip(f)?-1:1))%val;
-      const int max_ne_2 = uE2E[EMAP(e)][nfei];
+      int nfei = -1;
+      // Loop once around trying to find suitable next face
+      for(size_t step = 1; step<val+2;step++)
+      {
+        const int nfei_new = (diIM(e) + 2*val + e_cons*step*(flip(f)?-1:1))%val;
+        const int nf = uE2E[EMAP(e)][nfei_new] % m;
+        // Don't consider faces with identical dihedral angles
+        if(di[EMAP(e)][diIM(e)] != di[EMAP(e)][nfei_new])
+//#warning "THIS IS HACK, FIX ME"
+//        if( abs(di[EMAP(e)][diIM(e)] - di[EMAP(e)][nfei_new]) < 1e-16 )
+        {
+//#ifdef IGL_OUTER_HULL_DEBUG
+//        cout<<"Next facet: "<<(f+1)<<" --> "<<(nf+1)<<", |"<<
+//          di[EMAP(e)][diIM(e)]<<" - "<<di[EMAP(e)][nfei_new]<<"| = "<<
+//            abs(di[EMAP(e)][diIM(e)] - di[EMAP(e)][nfei_new])
+//            <<endl;
+//#endif
+          // Only use this face if not already seen
+          if(!FH[nf])
+          {
+            nfei = nfei_new;
+          }
+          break;
+        }
+//#ifdef IGL_OUTER_HULL_DEBUG
+//        cout<<"Skipping co-planar facet: "<<(f+1)<<" --> "<<(nf+1)<<endl;
+//#endif
+      }
 
       int max_ne = -1;
       //// Loop over and find max dihedral angle
@@ -291,12 +328,24 @@ IGL_INLINE void igl::outer_hull(
       //    }
       //  }
       //}
-      max_ne = max_ne_2;
+      if(nfei >= 0)
+      {
+        max_ne = uE2E[EMAP(e)][nfei];
+      }
 
       if(max_ne>=0)
       {
         // face of neighbor
         const int nf = max_ne%m;
+#ifdef IGL_OUTER_HULL_DEBUG
+        if(!FH[nf])
+        {
+          // first time seeing face
+          cout<<(f+1)<<" --> "<<(nf+1)<<endl;
+        }
+#endif
+        FH[nf] = true;
+        FHcount++;
         // corner of neighbor
         const int nc = max_ne/m;
         const int nd = F(nf,(nc+2)%3);

+ 6 - 0
include/igl/peel_outer_hull_layers.cpp

@@ -6,6 +6,7 @@
 //#define IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
 #include "writePLY.h"
+#include "writeDMAT.h"
 #include "STR.h"
 #endif
 
@@ -34,6 +35,10 @@ IGL_INLINE size_t igl::peel_outer_hull_layers(
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
   cout<<"peel outer hull layers..."<<endl;
 #endif
+#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
+  cout<<"calling outer hull..."<<endl;
+  writePLY(STR("peel-outer-hull-input.ply"),V,F);
+#endif
 
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
   cout<<"resize output ..."<<endl;
@@ -59,6 +64,7 @@ IGL_INLINE size_t igl::peel_outer_hull_layers(
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
   cout<<"calling outer hull..."<<endl;
   writePLY(STR("outer-hull-input-"<<iter<<".ply"),V,Fr);
+  writeDMAT(STR("outer-hull-input-"<<iter<<".dmat"),Nr);
 #endif
     outer_hull(V,Fr,Nr,Fo,Jo,flipr);
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG

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

@@ -1 +1 @@
-6693ed81cd72749c90548f5078b27623d108a17f
+31ac787262543763805c0a1c35a57998ebb1628c

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно