Explorar el Código

fixed reanttweakbar example and eadded bbw examples from FAST

Former-commit-id: 6b625d5115935f5631da05d6c0d81b8d84a42aaa
Alec Jacobson (jalec hace 12 años
padre
commit
51bc4c46fe

+ 5 - 4
examples/ReAntTweakBar/Makefile

@@ -8,11 +8,12 @@ all: example
 
 .PHONY: example
 
-igl_lib=../../
+IGL=../../
 
-APPKIT_LIB =
-lib= $(ANTTWEAKBAR_LIB) -L$(igl_lib)/lib -ligl -L$(DEFAULT_PREFIX)/lib $(OPENGL_LIB) $(GLUT_LIB)
-inc=-I$(igl_lib)/include -I$(DEFAULT_PREFIX)/include
+ANTTWEAKBAR_INC=-I$(IGL)/external/AntTweakBar/include
+ANTTWEAKBAR_LIB=-L$(IGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
+inc=-I$(IGL)/include -I$(DEFAULT_PREFIX)/include $(ANTTWEAKBAR_INC)
+lib=-L$(IGL)/lib -ligl -L$(DEFAULT_PREFIX)/lib $(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB)
 
 example: example.o
 	g++ $(CFLAGS) -o example example.o $(lib)

+ 47 - 0
examples/bbw/Makefile

@@ -0,0 +1,47 @@
+include ../../Makefile.conf
+
+IGL=../../
+IGL_INC=-I${IGL}/include
+IGL_LIB=-L${IGL}/lib -ligl
+
+MOSEKPLATFORM=osx64x86
+MOSEK=/usr/local/mosek
+MOSEK_INC=-I$(MOSEK)/6/tools/platform/$(MOSEKPLATFORM)/h
+MOSEK_LIB=-L$(MOSEK)/6/tools/platform/$(MOSEKPLATFORM)/bin -lmosek64 -liglmosek
+
+EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
+
+TETGEN=$(IGL)/external/tetgen
+TETGEN_LIB=-L$(TETGEN) -ligltetgen -ltet 
+TETGEN_INC=-I$(TETGEN)
+
+INC=-I. ${EIGEN3_INC} ${IGL_INC} ${TETGEN_INC} ${MOSEK_INC} 
+LIB=${TETGEN_LIB} ${MOSEK_LIB} ${OPENGL_LIB} ${GLUT_LIB} ${IGL_LIB} 
+
+# Make file for bbw_demo
+.PHONY: all
+all: bbw_demo
+
+CPP_FILES=$(wildcard ./*.cpp)
+#C_FILES=$(wildcard ./*.c)
+OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 
+#$(addprefix obj/,$(notdir $(C_FILES:.c=.o)))
+CFLAGS+=-DSHADER_DIR="\"./GLSL\""
+
+bbw_demo: obj $(OBJ_FILES)
+	g++ -o bbw_demo $(CFLAGS) $(OBJ_FILES) $(LIB)
+
+obj:
+	mkdir -p obj
+
+#obj/%.o: %.c %.h
+#	gcc $(CFLAGS) -o $@ -c $< $(INC)
+obj/%.o: %.cpp %.h
+	g++ $(CFLAGS) -o $@ -c $< $(INC)
+obj/%.o: %.cpp
+	g++ $(CFLAGS) -o $@ -c $< $(INC)
+
+.PHONY: clean
+clean:
+	rm -f $(OBJ_FILES)
+	rm -f bbw_demo

+ 19 - 0
examples/bbw/examples/armadillo.bf

@@ -0,0 +1,19 @@
+0 -1 0.129257 0.422406 0.196763 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+1 -1 -0.152254 0.423852 0.169958 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+-1 -1 -0.0109722 0.173294 -0.0092734 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+-1 -1 -0.00468155 -0.13266 -0.125831 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+2 2 -0.0026014 0.097823 0.152078 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+3 2 -0.153069 -0.030196 0.021722 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+4 2 0.180203 -0.027431 0.0197277 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+5 3 -0.0956565 -0.008814 -0.004997 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+6 3 0.102697 0.001587 0.002381 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+13 5 -0.145449 0.018419 0.0492195 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+15 6 0.132523 0.037847 0.109096 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+7 7 -0.092032 -0.170904 0.0771798 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+10 8 0.119696 -0.165775 0.0816835 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+14 9 -0.071846 0.102468 0.0987159 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+16 10 0.055387 0.053723 0.10658 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+8 11 0.050883 -0.223767 -0.103315 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+11 12 -0.025665 -0.231096 -0.0767775 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+9 15 -0.070583 0.002246 0.0876127 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 
+12 16 0.079788 -0.001878 0.0786744 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 

+ 1 - 0
examples/bbw/examples/armadillo.obj.REMOVED.git-id

@@ -0,0 +1 @@
+fbec5d216516015b925b9fd2cb46a8ca91b45995

+ 36 - 0
examples/bbw/examples/armadillo.tgf

@@ -0,0 +1,36 @@
+   1 -0.0109722   0.173294 -0.0092734          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    1 
+   2 -0.00468155   -0.13266  -0.125831          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    3 
+   3 -0.0135736   0.271117   0.142805          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    4 
+   4  -0.100338  -0.141474  -0.130828          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    5 
+   5   -0.19237  -0.312378 -0.0536482          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    6 
+   6  -0.141487  -0.536145  -0.156963          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    7 
+   7   -0.21207  -0.533899 -0.0693503          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    8 
+   8  0.0980157  -0.131073   -0.12345          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0    9 
+   9   0.217712  -0.296848 -0.0417665          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   10 
+  10   0.192047  -0.527944  -0.118544          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   11 
+  11   0.271835  -0.529822 -0.0398696          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   12 
+  12  -0.164041   0.143098  0.0124486          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   13 
+  13   -0.30949   0.161517  0.0616681          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   14 
+  14  -0.381336   0.263985   0.160384          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   15 
+  15   0.169231   0.145863  0.0104543          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   16 
+  16   0.301754    0.18371    0.11955          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   17 
+  17   0.357141   0.237433    0.22613          0          0          0 6.9532605e-310 2.3525269e-314 3.1373169e-321 2.1368449e-314 2.1219958e-314 6.953223e-310          1 2.1368449e-314 7.9050503e-323 2.1447907e-314          0   18 
+  18   0.129257   0.422406   0.196763          0 1.7604077e-310          0          1          1          1          0          0          0          1   1.078406    1.05751     1.1997          0   36 
+  19  -0.152254   0.423852   0.169958 2.1219958e-314 5.7559406e-09 3.9642947e-07          1          1          1          0          0          0          1   0.881232   1.047886   1.174727          0   37 
+#
+  15   16 1 0 0 0 34
+   8    9 1 0 0 0 29
+   2    8 1 0 0 0 25
+   2    4 1 0 0 0 24
+  13   14 1 0 0 0 33
+   6    7 1 0 0 0 28
+  16   17 1 0 0 0 35
+   4    5 1 0 0 0 26
+   9   10 1 0 0 0 30
+   5    6 1 0 0 0 27
+   1    3 1 0 0 0 19
+   1   15 1 0 0 0 20
+   1   12 1 0 0 0 22
+  10   11 1 0 0 0 31
+  12   13 1 0 0 0 32
+#

+ 1 - 0
examples/bbw/examples/brick.obj.REMOVED.git-id

@@ -0,0 +1 @@
+34a3aac9ef5d09124a85c97d0f135e3c24f32e85

+ 4 - 0
examples/bbw/examples/brick.tgf

@@ -0,0 +1,4 @@
+   1          4        0.5        0.5 6.9532423e-310 6.9532423e-310 6.9532423e-310          1          1          1          0          0          0          1      4.125     1.1875        1.5          0    1 
+   2          0        0.5        0.5 9.8813129e-324          0 2.1219958e-314          1          1          1          0          0          0          1 0.040798319 0.48263485  3.1593933          0    3 
+#
+#

+ 13 - 0
examples/bbw/examples/gargoyle-skeleton-4-points.tgf

@@ -0,0 +1,13 @@
+1 0.281152 0.703812 0.17955 0.281152 0.703812 0.17955 1 1 1 0 0 0 1 0 0 0 
+2 0.279014 0.78407 0.281131 0.279014 0.78407 0.281131 1 1 1 0 0 0 1 0 0 0 
+3 0.283274 0.798735 0.427544 0.283274 0.798735 0.427544 1 1 1 0 0 0 1 0 0 0 
+4 0.289027 0.352549 0.175056 0.289027 0.352549 0.175056 1 1 1 0 0 0 1 0 0 0 
+5 0.533399 0.97653 0.053801 0.533399 0.97653 0.053801 1 1 1 0 0 0 1 0 0 0 
+6 0.0164236 0.986867 0.0583015 0.0164236 0.986867 0.0583015 1 1 1 0 0 0 1 0 0 0 
+7 0.371475 0.764257 0.180104 1.02184e-193 1.2683e-314 -9.18791e-189 1 1 1 0 0 0 1 0.998461 0.98759 1.1801 
+8 0.205292 0.774223 0.177497 2.5518e-300 1.2683e-314 -9.18791e-189 1 1 1 0 0 0 1 1.02601 0.988331 1.1775 
+#
+1 4 1 1 0
+1 2 1 1 0
+2 3 1 1 0
+#

+ 1 - 0
examples/bbw/examples/gargoyle.obj.REMOVED.git-id

@@ -0,0 +1 @@
+67232d7546e073aef29d1008e4d71bac5d3801d0

+ 8 - 0
examples/bbw/examples/toy.tgf

@@ -0,0 +1,8 @@
+   1 0.022050698  0.2184666 0.048204916          0          1          0          1          1          1          0          0          0          1          1          1          1          0    1 
+   2 -0.00082061799 0.078092507 0.016942195          0       1440        874          1          1          1          0          0          0          1 0.99682216 0.89773834 0.97767308          0    2 
+   3 0.0026832858 -0.027061348 -0.0057913033          0          1          0          1          1          1          0          0          0          1   1.002247 0.89798112 0.97790599          0    4 
+   4 0.19749935 -0.54836793 -0.11514182          0 1.7604077e-310          0          1          1          1          0          0          0          1  1.1906136 0.18666707  1.0466804          0    6 
+#
+   1    2 1 1 0 0 3
+   2    3 1 1 0 0 5
+#

+ 347 - 0
examples/bbw/main.cpp

@@ -0,0 +1,347 @@
+
+#include <igl/pathinfo.h>
+#include <igl/readOBJ.h>
+#include <igl/readOFF.h>
+#include <igl/readMESH.h>
+#include <igl/sample_edges.h>
+#include <igl/cat.h>
+#include <igl/faces_first.h>
+#include <igl/readTGF.h>
+#include <igl/tetgen/tetrahedralize.h>
+#include <igl/launch_medit.h>
+#include <igl/boundary_conditions.h>
+#include <igl/mosek/bbw.h>
+#include <igl/writeDMAT.h>
+#include <igl/writeMESH.h>
+
+#include <Eigen/Dense>
+
+#include <Eigen/Dense>
+
+#include <iostream>
+#include <string>
+
+// Whether medit program is install
+const bool WITH_MEDIT = true;
+
+const char * USAGE=
+"Usage:\n"
+"  ./bbw_demo shape{.obj|.off|.mesh} skeleton{.tgf|.bf}\n"
+;
+
+// Read a surface mesh from a {.obj|.off|.mesh} files
+// Inputs:
+//   mesh_filename  path to {.obj|.off|.mesh} file
+// Outputs:
+//   V  #V by 3 list of mesh vertex positions
+//   F  #F by 3 list of triangle indices
+// Returns true only if successfuly able to read file
+bool load_mesh_from_file(
+  const std::string mesh_filename,
+  Eigen::MatrixXd & V,
+  Eigen::MatrixXi & F)
+{
+  using namespace std;
+  using namespace igl;
+  using namespace Eigen;
+  string dirname, basename, extension, filename;
+  pathinfo(mesh_filename,dirname,basename,extension,filename);
+  transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+  bool success = false;
+  if(extension == "obj")
+  {
+    success = readOBJ(mesh_filename,V,F);
+  }else if(extension == "off")
+  {
+    success = readOFF(mesh_filename,V,F);
+  }else if(extension == "mesh")
+  {
+    // Unused Tets read from .mesh file
+    MatrixXi Tets;
+    success = readMESH(mesh_filename,V,Tets,F);
+    // We're not going to use any input tets. Only the surface
+    if(Tets.size() > 0 && F.size() == 0)
+    {
+      // If Tets read, but no faces then use surface of tet volume
+    }else
+    {
+      // Rearrange vertices so that faces come first
+      VectorXi IM;
+      faces_first(V,F,IM);
+      // Dont' bother reordering Tets, but this is how one would:
+      //Tets = 
+      //  Tets.unaryExpr(bind1st(mem_fun( static_cast<VectorXi::Scalar&
+      //  (VectorXi::*)(VectorXi::Index)>(&VectorXi::operator())),
+      //  &IM)).eval();
+      // Don't throw away any interior vertices, since user may want weights
+      // there
+    }
+  }else
+  {
+    cerr<<"Error: Unknown shape file format extension: ."<<extension<<endl;
+    return false;
+  }
+  return success;
+}
+
+// Load a skeleton (bones, points and cage edges) from a {.bf|.tgf} file
+//
+// Inputs:
+//   skel_filename  path to skeleton {.bf|.tgf} file
+// Outputs:
+//  C  # vertices by 3 list of vertex positions
+//  P  # point-handles list of point handle indices
+//  BE # bone-edges by 2 list of bone-edge indices
+//  CE # cage-edges by 2 list of cage-edge indices
+bool load_skeleton_from_file(
+  const std::string skel_filename,
+  Eigen::MatrixXd & C,
+  Eigen::VectorXi & P,
+  Eigen::MatrixXi & BE,
+  Eigen::MatrixXi & CE)
+{
+  using namespace std;
+  using namespace igl;
+  using namespace Eigen;
+  string dirname, basename, extension, filename;
+  pathinfo(skel_filename,dirname,basename,extension,filename);
+  transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+  bool success = false;
+  if(extension == "tgf")
+  {
+    // Phony space for unused all edges and pseudo edges
+    MatrixXi E;
+    MatrixXi PE;
+    success = readTGF(skel_filename,C,E,P,BE,CE,PE);
+  }else
+  {
+    cerr<<"Error: Unknown skeleton file format extension: ."<<extension<<endl;
+    return false;
+  }
+  return success;
+}
+
+// Mesh the interior of a given surface with tetrahedra which are graded (tend
+// to be small near the surface and large inside) and conform to the given
+// handles and samplings thereof.
+//
+// Inputs:
+//  V  #V by 3 list of mesh vertex positions
+//  F  #F by 3 list of triangle indices
+//  C  #C by 3 list of vertex positions
+//  P  #P list of point handle indices
+//  BE #BE by 2 list of bone-edge indices
+//  CE #CE by 2 list of cage-edge indices
+// Outputs:
+//  VV  #VV by 3 list of tet-mesh vertex positions
+//  TT  #TT by 4 list of tetrahedra indices
+//  FF  #FF by 3 list of surface triangle indices
+// Returns true only on success
+bool mesh_with_skeleton(
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & F,
+  const Eigen::MatrixXd & C,
+  const Eigen::VectorXi & /*P*/,
+  const Eigen::MatrixXi & BE,
+  const Eigen::MatrixXi & CE,
+  Eigen::MatrixXd & VV,
+  Eigen::MatrixXi & TT,
+  Eigen::MatrixXi & FF)
+{
+  using namespace Eigen;
+  using namespace igl;
+  using namespace std;
+  // Collect all edges that need samples:
+  MatrixXi BECE = cat(1,BE,CE);
+  MatrixXd S;
+  // Sample each edge with 10 samples. (Choice of 10 doesn't seem to matter so
+  // much, but could under some circumstances)
+  sample_edges(C,BECE,10,S);
+  // Vertices we'll constrain tet mesh to meet
+  MatrixXd VS = cat(1,V,S);
+  // Boundary faces
+  MatrixXi BF;
+  // Use tetgen to mesh the interior of surface, this assumes surface:
+  //   * has no holes
+  //   * has no non-manifold edges or vertices
+  //   * has consistent orientation
+  //   * has no self-intersections
+  //   * has no 0-volume pieces
+  // Default settings pq100 tell tetgen to mesh interior of triangle mesh and
+  // to produce a graded tet mesh
+  cerr<<"tetgen begin()"<<endl;
+  int status = tetrahedralize( VS,F,"pq100",VV,TT,FF);
+  cerr<<"tetgen end()"<<endl;
+  if(FF.rows() != F.rows())
+  {
+    // Issue a warning if the surface has changed
+    cerr<<"mesh_with_skeleton: Warning: boundary faces != input faces"<<endl;
+  }
+  if(status != 0)
+  {
+    cerr<<
+      "***************************************************************"<<endl<<
+      "***************************************************************"<<endl<<
+      "***************************************************************"<<endl<<
+      "***************************************************************"<<endl<<
+      "* mesh_with_skeleton: tetgen failed. Just meshing convex hull *"<<endl<<
+      "***************************************************************"<<endl<<
+      "***************************************************************"<<endl<<
+      "***************************************************************"<<endl<<
+      "***************************************************************"<<endl;
+    // If meshing convex hull then use more regular mesh
+    status = tetrahedralize(VS,F,"q1.414",VV,TT,FF);
+    // I suppose this will fail if the skeleton is outside the mesh
+    assert(FF.maxCoeff() < VV.rows());
+    if(status != 0)
+    {
+      cerr<<"mesh_with_skeleton: tetgen failed again."<<endl;
+      return false;
+    }
+  }
+  // If you have medit installed then it's convenient to visualize the tet mesh
+  // at this point
+  if(WITH_MEDIT)
+  {
+    launch_medit(VV,TT,FF,false);
+  }
+  return true;
+}
+
+// Writes output files to /path/to/input/mesh-skeleton.dmat,
+// mesh-volume.dmat, mesh-volume.mesh if input mesh was
+// located at /path/to/input/mesh.obj and input skeleton was at
+// /other/path/to/input/skel.tgf
+// 
+// Writes:
+////   mesh.dmat  dense weights matrix corresponding to original input
+////     vertices V
+//   mesh-volume.dmat  dense weights matrix corresponding to all
+//     vertices in tet mesh used for computation VV
+//   mesh-volume.mesh  Tet mesh used for computation
+//
+// Inputs:
+//   mesh_filename  path to {.obj|.off|.mesh} file
+//   skel_filename  path to skeleton {.bf|.tgf} file
+//   V  #V by 3 list of original mesh vertex positions
+//   F  #F by 3 list of original triangle indices
+//   VV  #VV by 3 list of tet-mesh vertex positions
+//   TT  #TT by 4 list of tetrahedra indices
+//   FF  #FF by 3 list of surface triangle indices
+//   W   #VV by #W weights matrix
+// Returns true on success
+bool save_output(
+  const std::string mesh_filename,
+  const std::string /*skel_filename*/,
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & /*F*/,
+  const Eigen::MatrixXd & VV,
+  const Eigen::MatrixXi & TT,
+  const Eigen::MatrixXi & FF,
+  const Eigen::MatrixXd & W)
+{
+  using namespace std;
+  using namespace igl;
+  using namespace Eigen;
+  // build filename prefix out of input base names
+  string prefix = "";
+  {
+    string dirname, basename, extension, filename;
+    pathinfo(mesh_filename,dirname,basename,extension,filename);
+    transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+    prefix += dirname + "/" + filename;
+  }
+
+  //{
+  //  string dirname, basename, extension, filename;
+  //  pathinfo(skel_filename,dirname,basename,extension,filename);
+  //  transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+  //  prefix += "-" + filename;
+  //}
+
+  // Keep track if any fail
+  bool success = true;
+  //// Weights matrix for just V. Assumes V prefaces VV
+  //MatrixXd WV = W.block(0,0,V.rows(),W.cols());
+  //// write dmat
+  //success &= writeDMAT(prefix + ".dmat",WV);
+  // write volume weights dmat
+  success &= writeDMAT(prefix + "-volume.dmat",W);
+  // write volume mesh
+  success &= writeMESH(prefix + "-volume.mesh",VV,TT,FF);
+  //// write surface OBJ with pseudocolor
+  return success;
+}
+
+int main(int argc, char * argv[])
+{
+  using namespace std;
+  using namespace Eigen;
+  using namespace igl;
+  if(argc<3)
+  {
+    cerr<<USAGE<<endl;
+    return 1;
+  }
+
+  // #V by 3 list of mesh vertex positions
+  MatrixXd V;
+  // #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))
+  {
+    return 1;
+  }
+  // "Skeleton" (handles) descriptors:
+  // List of control and joint (bone endpoint) positions
+  MatrixXd C;
+  // List of point handles indexing C
+  VectorXi P;
+  // List of bone edges indexing C
+  MatrixXi BE;
+  // List of cage edges indexing *P*
+  MatrixXi CE;
+  // load skeleton (.tgf or .bf)
+  if(!load_skeleton_from_file(argv[2],C,P,BE,CE))
+  {
+    return 1;
+  }
+
+  // Mesh with samples on skeleton
+  // New vertices of tet mesh, V prefaces VV
+  MatrixXd VV;
+  // Tetrahedra
+  MatrixXi TT;
+  // New surface faces FF
+  MatrixXi FF;
+  if(!mesh_with_skeleton(V,F,C,P,BE,CE,VV,TT,FF))
+  {
+    return 1;
+  }
+  // Compute boundary conditions (aka fixed value constraints)
+  // List of boundary indices (aka fixed value indices into VV)
+  VectorXi b;
+  // List of boundary conditions of each weight function
+  MatrixXd bc;
+  if(!boundary_conditions(VV,TT,C,P,BE,CE,b,bc))
+  {
+    return 1;
+  }
+
+  cout<<"b=["<<b<<"];"<<endl;
+  cout<<"bc=["<<bc<<"];"<<endl;
+
+  // compute BBW 
+  // Default bbw data and flags
+  BBWData bbw_data;
+  // Weights matrix
+  MatrixXd W;
+  if(!bbw(VV,TT,b,bc,bbw_data,W))
+  {
+    return 1;
+  }
+  // Save output
+  save_output(argv[1],argv[2],V,F,VV,TT,FF,W);
+  return 0;
+}