Browse Source

merge, orient_outward_ao compiles on mac os x

Former-commit-id: bd6dee7a8f76421b46f758942e5cc2108174eabb
Alec Jacobson (jalec 11 years ago
parent
commit
532720dc68

+ 3 - 0
Makefile

@@ -29,6 +29,9 @@ endif
 ifeq ($(IGL_WITH_MATLAB),1)
 	EXTRA_DIRS+=include/igl/matlab
 endif
+ifeq ($(IGL_WITH_BBW),1)
+	EXTRA_DIRS+=include/igl/BBW
+endif
 ifeq ($(IGL_WITH_MOSEK),1)
 	EXTRA_DIRS+=include/igl/mosek
 endif

+ 2 - 0
Makefile.conf

@@ -22,10 +22,12 @@ endif
 
 ifeq ($(IGL_USERNAME),ajx)
 	MOSEKPLATFORM=osx64x86
+	MOSEKVERSION=7
 	IGL_WITH_TETGEN=1
 	IGL_WITH_EMBREE=1
 	IGL_WITH_MATLAB=1
 	IGL_WITH_MOSEK=1
+	IGL_WITH_BBW=1
 	IGL_WITH_PNG=1
 	IGL_WITH_XML=1
 	IGL_WITH_BOOST=1

+ 3 - 0
RELEASE_HISTORY.txt

@@ -1,3 +1,6 @@
+0.3.6  boost extra, patches, mosek 7 support, libiglbbw (mosek optional)
+0.3.5  More examples, naive primitive sorting
+0.3.3  Many more examples, ambient occlusion with Embree.
 0.3.1  Linearly dependent constraints in min_quad_with_fixed, SparseQR buggy
 0.3.0  Better active set method support
 0.2.3  More explicits, active set method, opengl/anttweakbar guards

+ 1 - 1
VERSION.txt

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

+ 14 - 3
examples/bbw/Makefile

@@ -4,15 +4,26 @@ CXX=g++
 
 LIBIGL=../../
 LIBIGL_INC=-I${LIBIGL}/include
-LIBIGL_LIB=-L${LIBIGL}/lib -ligl
+LIBIGL_LIB=-L${LIBIGL}/lib -ligl -liglmosek -liglbbw
 
+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=../mosek/
+IGLMOSEK_INC=-I$(IGLMOSEK)/
+INC+=${IGLMOSEK_INC}
 MOSEK=/usr/local/mosek
-MOSEK_INC=-I$(MOSEK)/6/tools/platform/$(MOSEKPLATFORM)/h
-MOSEK_LIB=-L$(MOSEK)/6/tools/platform/$(MOSEKPLATFORM)/bin -lmosek64 -liglmosek
+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
 

+ 13 - 5
examples/bbw/main.cpp

@@ -8,7 +8,7 @@
 #include <igl/readTGF.h>
 #include <igl/launch_medit.h>
 #include <igl/boundary_conditions.h>
-#include <igl/mosek/bbw.h>
+#include <igl/bbw/bbw.h>
 #include <igl/writeDMAT.h>
 #include <igl/writeMESH.h>
 #include <igl/normalize_row_sums.h>
@@ -188,10 +188,16 @@ int main(int argc, char * argv[])
   using namespace std;
   using namespace Eigen;
   using namespace igl;
+  string mesh_filename = "examples/brick.obj";
+  string skeleton_filename = "examples/brick.tgf";
   if(argc<3)
   {
     cerr<<USAGE<<endl;
-    return 1;
+    cout<<endl<<"Using defaults..."<<endl;
+  }else
+  {
+    mesh_filename = argv[1];
+    skeleton_filename = argv[2];
   }
 
   // #V by 3 list of mesh vertex positions
@@ -199,7 +205,7 @@ int main(int argc, char * argv[])
   // #F by 3 list of triangle indices
   MatrixXi F;
   // load mesh from .obj, .off or .mesh
-  if(!load_mesh_from_file(argv[1],V,F))
+  if(!load_mesh_from_file(mesh_filename,V,F))
   {
     return 1;
   }
@@ -213,7 +219,7 @@ int main(int argc, char * argv[])
   // List of cage edges indexing *P*
   MatrixXi CE;
   // load skeleton (.tgf or .bf)
-  if(!load_skeleton_from_file(argv[2],C,P,BE,CE))
+  if(!load_skeleton_from_file(skeleton_filename,C,P,BE,CE))
   {
     return 1;
   }
@@ -250,6 +256,8 @@ int main(int argc, char * argv[])
   // compute BBW 
   // Default bbw data and flags
   BBWData bbw_data;
+  bbw_data.qp_solver = QP_SOLVER_IGL_ACTIVE_SET;
+  //bbw_data.qp_solver = QP_SOLVER_MOSEK;
   // Weights matrix
   MatrixXd W;
   if(!bbw(VV,TT,b,bc,bbw_data,W))
@@ -259,6 +267,6 @@ int main(int argc, char * argv[])
   // Normalize weights to sum to one
   normalize_row_sums(W,W);
   // Save output
-  save_output(argv[1],argv[2],V,F,VV,TT,FF,W);
+  save_output(mesh_filename,skeleton_filename,V,F,VV,TT,FF,W);
   return 0;
 }

+ 59 - 0
include/igl/bbw/Makefile

@@ -0,0 +1,59 @@
+include ../../../Makefile.conf
+
+.PHONY: all
+all: libiglbbw
+debug: libiglbbw
+
+include ../../../Makefile.conf
+all: OPTFLAGS += -O3 -DNDEBUG $(OPENMP)
+debug: OPTFLAGS += -g -Wall
+CFLAGS += $(OPTFLAGS)
+
+.PHONY: libiglbbw
+libiglbbw: obj ../../../lib/libiglbbw.a
+
+CPP_FILES=$(wildcard *.cpp)
+OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o)))
+
+# include igl headers
+INC+=-I../../../include/
+
+# EXPECTS THAT CFLAGS IS ALREADY SET APPROPRIATELY 
+
+# Eigen dependency
+EIGEN3_INC=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
+INC+=$(EIGEN3_INC)
+
+ifdef IGL_NO_MOSEK
+CFLAGS+=-DIGL_NO_MOSEK
+else
+# mosek dependency
+# TODO: linux, 32 bit etc
+ifndef MOSEKPLATFORM
+  MOSEKPLATFORM=osx64x86
+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
+
+obj: 
+	mkdir -p obj
+
+../../../lib/libiglbbw.a: $(OBJ_FILES)
+	rm -f $@
+	ar cqs $@ $(OBJ_FILES)
+
+obj/%.o: %.cpp %.h
+	g++ $(AFLAGS) $(CFLAGS) -c -o $@ $< $(INC)
+
+clean:
+	rm -f obj/*.o
+	rm -f ../../../lib/libiglbbw.a

+ 8 - 0
include/igl/bbw/README.txt

@@ -0,0 +1,8 @@
+This library extra implements "Bounded Biharmonic Weights". By default it
+depends on libiglmosek and therefor also mosek. To compile issue:
+
+    make
+
+To compile without the mosek dependency issue:
+
+    make IGL_NO_MOSEK=1

+ 34 - 12
include/igl/mosek/bbw.cpp → include/igl/bbw/bbw.cpp

@@ -1,4 +1,3 @@
-#define VERBOSE
 #include "bbw.h"
 
 #include <igl/cotmatrix.h>
@@ -7,7 +6,6 @@
 #include <igl/speye.h>
 #include <igl/slice_into.h>
 #include <igl/normalize_row_sums.h>
-#include <igl/verbose.h>
 #include <igl/min_quad_with_fixed.h>
 
 #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
@@ -19,8 +17,17 @@
 
 igl::BBWData::BBWData():
   partition_unity(false),
-  qp_solver(QP_SOLVER_IGL_ACTIVE_SET)
-{}
+  W0(),
+#ifndef IGL_NO_MOSEK
+  mosek_data(),
+#endif
+  active_set_params(),
+  qp_solver(QP_SOLVER_IGL_ACTIVE_SET),
+  verbosity(0)
+{
+  // We know that the Bilaplacian is positive semi-definite
+  active_set_params.Auu_pd = true;
+}
 
 void igl::BBWData::print()
 {
@@ -91,8 +98,11 @@ IGL_INLINE bool igl::bbw(
     {
       case QP_SOLVER_IGL_ACTIVE_SET:
       {
-        verbose("\n^%s: Computing initial weights for %d handle%s.\n\n",
-          __FUNCTION__,m,(m!=1?"s":""));
+        if(data.verbosity >= 1)
+        {
+          cout<<"BBW: Computing initial weights for "<<m<<" handle"<<
+            (m!=1?"s":"")<<"."<<endl;
+        }
         min_quad_with_fixed_data<typename DerivedW::Scalar > mqwf;
         min_quad_with_fixed_precompute(Q,b,Aeq,true,mqwf);
         min_quad_with_fixed_solve(mqwf,c,bc,Beq,W);
@@ -108,8 +118,11 @@ IGL_INLINE bool igl::bbw(
           {
             continue;
           }
-          verbose("\n^%s: Computing weight for handle %d out of %d.\n\n",
-              __FUNCTION__,i+1,m);
+          if(data.verbosity >= 1)
+          {
+            cout<<"BBW: Computing weight for handle "<<i+1<<" out of "<<m<<
+              "."<<endl;
+          }
           VectorXd bci = bc.col(i);
           VectorXd Wi;
           // use initial guess
@@ -121,11 +134,11 @@ IGL_INLINE bool igl::bbw(
             case SOLVER_STATUS_CONVERGED:
               break;
             case SOLVER_STATUS_MAX_ITER:
-              cout<<"active_set: max iter without convergence."<<endl;
+              cerr<<"active_set: max iter without convergence."<<endl;
               break;
             case SOLVER_STATUS_ERROR:
             default:
-              cout<<"active_set error."<<endl;
+              cerr<<"active_set error."<<endl;
               error = true;
           }
           W.col(i) = Wi;
@@ -138,11 +151,19 @@ IGL_INLINE bool igl::bbw(
       }
       case QP_SOLVER_MOSEK:
       {
+#ifdef IGL_NO_MOSEK
+        assert(false && "Use another QPSolver. Recompile without IGL_NO_MOSEK defined.");
+        cerr<<"Use another QPSolver. Recompile without IGL_NO_MOSEK defined."<<endl;
+        return false;
+#else
         // Loop over handles
         for(int i = 0;i<m;i++)
         {
-          verbose("\n^%s: Computing weight for handle %d out of %d.\n\n",
-              __FUNCTION__,i+1,m);
+          if(data.verbosity >= 1)
+          {
+            cout<<"BBW: Computing weight for handle "<<i+1<<" out of "<<m<<
+              "."<<endl;
+          }
           VectorXd bci = bc.col(i);
           VectorXd Wi;
           // impose boundary conditions via bounds
@@ -155,6 +176,7 @@ IGL_INLINE bool igl::bbw(
           }
           W.col(i) = Wi;
         }
+#endif
         break;
       }
       default:

+ 10 - 4
include/igl/mosek/bbw.h → include/igl/bbw/bbw.h

@@ -3,7 +3,9 @@
 #include "../igl_inline.h"
 
 #include <Eigen/Dense>
-#include "mosek_quadprog.h"
+#ifndef IGL_NO_MOSEK
+#  include <igl/mosek/mosek_quadprog.h>
+#endif
 #include <igl/active_set.h>
 
 namespace igl
@@ -26,15 +28,19 @@ namespace igl
       // Enforce partition of unity during optimization (optimize all weight
       // simultaneously)
       bool partition_unity;
-      // TODO: Is it safe if this is a reference?
       // Initial guess
       Eigen::MatrixXd W0;
-      // TODO: Mosek options
+#ifndef IGL_NO_MOSEK
       igl::MosekData mosek_data;
-      // TODO: Active set options
+#endif
       igl::active_set_params active_set_params;
       // Which solver
       QPSolver qp_solver;
+      // Verbosity level
+      // 0: quiet
+      // 1: loud
+      // 2: louder
+      int verbosity;
     public:
       BBWData();
       // Print current state of object

+ 2 - 2
include/igl/embree/Makefile

@@ -5,8 +5,8 @@ all: libiglembree
 debug: libiglembree
 
 include ../../../Makefile.conf
-all: CFLAGS += -O3 -DNDEBUG
-debug: CFLAGS += -g -Wall 
+all: CFLAGS += -O3 -DNDEBUG -std=c++11
+debug: CFLAGS += -g -Wall -std=c++11
 
 .PHONY: libiglembree
 libiglembree: obj ../../../lib/libiglembree.a

+ 7 - 1
include/igl/embree/orient_outward_ao.cpp

@@ -4,6 +4,7 @@
 #include "../doublearea.h"
 #include "../matlab_format.h"
 #include "ambient_occlusion.h"
+#include "EmbreeIntersector.h"
 #include <iostream>
 #include <random>
 
@@ -47,7 +48,7 @@ IGL_INLINE void igl::orient_outward_ao(
   double minarea = A.minCoeff();
   mt19937 engine;
   engine.seed(time(0));
-  Matrix<int, Dynamic, 1> A_int = (A * 100.0 / minarea).cast<int>();
+  Matrix<int, Dynamic, 1> A_int = (A * 100.0 / minarea).template cast<int>();
   auto ddist_func = [&] (double i) { return A_int(static_cast<int>(i)); };
   discrete_distribution<int> ddist(m, 0, m, ddist_func);      // simple ctor of (Iter, Iter) not provided by the stupid VC11 impl...
   uniform_real_distribution<double> rdist;
@@ -116,3 +117,8 @@ IGL_INLINE void igl::orient_outward_ao(
     Matrix<typename DerivedV::Scalar,3,1> > ei(V,F);
   return orient_outward_ao(V, F, C, ei, num_samples, FF, I);
 }
+
+#ifndef IGL_HEADER_ONLY
+// Explicit template specialization
+template void igl::orient_outward_ao<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+#endif

+ 3 - 3
include/igl/min_quad_with_fixed.cpp

@@ -105,13 +105,13 @@ IGL_INLINE bool igl::min_quad_with_fixed_precompute(
     data.Auu_sym = is_symmetric(Auu,EPS<double>());
   }
 
-#ifdef MIN_QUAD_WITH_FIXED_CPP_DEBUG
-  cout<<"    qr"<<endl;
-#endif
   // Determine number of linearly independent constraints
   int nc = 0;
   if(neq>0)
   {
+#ifdef MIN_QUAD_WITH_FIXED_CPP_DEBUG
+    cout<<"    qr"<<endl;
+#endif
     // QR decomposition to determine row rank in Aequ
     slice(Aeq,data.unknown,2,data.Aequ);
     assert(data.Aequ.rows() == neq);

+ 5 - 2
include/igl/mosek/Makefile

@@ -29,9 +29,12 @@ INC+=$(EIGEN3_INC)
 ifndef MOSEKPLATFORM
   MOSEKPLATFORM=osx64x86
 endif
+ifndef MOSEKVERSION
+  MOSEKVERSION=6
+endif
 MOSEK=/usr/local/mosek
-MOSEK_INC=-I$(MOSEK)/6/tools/platform/$(MOSEKPLATFORM)/h
-MOSEK_LIB=-L$(MOSEK)/6/tools/platform/$(MOSEKPLATFORM)/bin -lmosek64
+MOSEK_INC=-I$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/h
+MOSEK_LIB=-L$(MOSEK)/$(MOSEKVERSION)/tools/platform/$(MOSEKPLATFORM)/bin -lmosek64
 INC+=$(MOSEK_INC)
 
 obj: 

+ 35 - 2
include/igl/mosek/mosek_quadprog.cpp

@@ -28,7 +28,15 @@ igl::MosekData::MosekData()
   douparam[MSK_DPAR_INTPNT_TOL_REL_GAP]=1e-8;
   // Force using multiple threads, not sure if MOSEK is properly destorying
   //extra threads...
+#if MSK_VERSION_MAJOR >= 7
+  intparam[MSK_IPAR_NUM_THREADS] = 6;
+#elif MSK_VERSION_MAJOR == 6
   intparam[MSK_IPAR_INTPNT_NUM_THREADS] = 6;
+#endif
+#if MSK_VERSION_MAJOR == 6
+  // Force turn off data check
+  intparam[MSK_IPAR_DATA_CHECK]=MSK_OFF;
+#endif
   // Turn off presolving
   // intparam[MSK_IPAR_PRESOLVE_USE] = MSK_PRESOLVE_MODE_OFF;
   // Force particular matrix reordering method
@@ -46,8 +54,6 @@ igl::MosekData::MosekData()
   douparam[MSK_DPAR_INTPNT_TOL_PSAFE]= 1e2;
   // Turn off convexity check
   intparam[MSK_IPAR_CHECK_CONVEXITY] = MSK_CHECK_CONVEXITY_NONE;
-  // Force turn off data check
-  intparam[MSK_IPAR_DATA_CHECK]=MSK_OFF;
 }
 
 template <typename Index, typename Scalar>
@@ -90,7 +96,11 @@ IGL_INLINE bool igl::mosek_quadprog(
   MSKtask_t task;
 
   // Create the MOSEK environment
+#if MSK_VERSION_MAJOR >= 7
+  mosek_guarded(MSK_makeenv(&env,NULL));
+#elif MSK_VERSION_MAJOR == 6
   mosek_guarded(MSK_makeenv(&env,NULL,NULL,NULL,NULL));
+#endif
   ///* Directs the log stream to the 'printstr' function. */
   //mosek_guarded(MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,printstr));
   // initialize mosek environment
@@ -115,10 +125,18 @@ IGL_INLINE bool igl::mosek_quadprog(
   {
     // Append 'm' empty constraints, the constrainst will initially have no
     // bounds
+#if MSK_VERSION_MAJOR >= 7
+    mosek_guarded(MSK_appendcons(task,m));
+#elif MSK_VERSION_MAJOR == 6
     mosek_guarded(MSK_append(task,MSK_ACC_CON,m));
+#endif
   }
   // Append 'n' variables
+#if MSK_VERSION_MAJOR >= 7
+  mosek_guarded(MSK_appendvars(task,n));
+#elif MSK_VERSION_MAJOR == 6
   mosek_guarded(MSK_append(task,MSK_ACC_VAR,n));
+#endif
   // add a contant term to the objective
   mosek_guarded(MSK_putcfix(task,cf));
 
@@ -143,6 +161,16 @@ IGL_INLINE bool igl::mosek_quadprog(
     if(m>0)
     {
       // Input column j of A
+#if MSK_VERSION_MAJOR >= 7
+      mosek_guarded(
+        MSK_putacol(
+          task,
+          j,
+          Acp[j+1]-Acp[j],
+          &Ari[Acp[j]],
+          &Av[Acp[j]])
+        );
+#elif MSK_VERSION_MAJOR == 6
       mosek_guarded(
         MSK_putavec(
           task,
@@ -152,6 +180,7 @@ IGL_INLINE bool igl::mosek_quadprog(
           &Ari[Acp[j]],
           &Av[Acp[j]])
         );
+#endif
     }
   }
 
@@ -192,7 +221,11 @@ IGL_INLINE bool igl::mosek_quadprog(
 
   // Get status of solution
   MSKsolstae solsta;
+#if MSK_VERSION_MAJOR >= 7
+  MSK_getsolsta (task,MSK_SOL_ITR,&solsta);
+#elif MSK_VERSION_MAJOR == 6
   MSK_getsolutionstatus(task,MSK_SOL_ITR,NULL,&solsta);
+#endif
 
   bool success = false;
   switch(solsta)

+ 1 - 0
libigl-dependency-diagram.ai.REMOVED.git-id

@@ -0,0 +1 @@
+c4e91e4134b98edcc05afc387730c8cfa98edb1e

+ 1 - 0
readme.txt

@@ -22,6 +22,7 @@ Eigen3  Last tested with Eigen Version 3.2
   libpng  libiglpng extra only
   Mosek  libiglmosek extra only
   Matlab  libiglmatlab extra only
+  boost  libboost extra only
 
   = Optional (included in external/ =
   TetGen  libigltetgen extra only