Ver Fonte

fixed some bugs in arap

Former-commit-id: f309e975f00fffbcd51e1c9b5710fe89d3adf59a
Alec Jacobson há 11 anos atrás
pai
commit
39dd224f64
4 ficheiros alterados com 58 adições e 15 exclusões
  1. 3 2
      examples/arap/Makefile
  2. 30 5
      examples/arap/example.cpp
  3. 10 1
      include/igl/harmonic.cpp
  4. 15 7
      include/igl/svd3x3/arap.cpp

+ 3 - 2
examples/arap/Makefile

@@ -14,6 +14,7 @@ LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglpng -liglsvd3x3
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 
+
 #EMBREE=$(LIBIGL)/external/embree
 #EMBREE_INC=-I$(EMBREE)/rtcore -I$(EMBREE)/common
 #EMBREE_LIB=-L$(EMBREE)/build -lrtcore -lsys
@@ -36,8 +37,8 @@ ifeq ($(UNAME), Darwin)
 	ANTTWEAKBAR_LIB+=-framework AppKit
 endif
 
-INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(YIMG_INC)
-LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(YIMG_LIB)
+INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(YIMG_INC) 
+LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(YIMG_LIB) 
 
 example: example.o
 	g++ $(OPENMP) $(AFLAGS) $(CFLAGS) $(LIB) -o example $^

+ 30 - 5
examples/arap/example.cpp

@@ -28,7 +28,6 @@
 #include <igl/material_colors.h>
 #include <igl/barycenter.h>
 #include <igl/matlab_format.h>
-#include <igl/material_colors.h>
 #include <igl/ReAntTweakBar.h>
 #include <igl/pathinfo.h>
 #include <igl/Camera.h>
@@ -133,7 +132,7 @@ float light_pos[4] = {0.1,0.1,-0.9,0};
 Eigen::MatrixXd V,U,N,C,mid;
 Eigen::VectorXi S;
 igl::ARAPData arap_data;
-Eigen::MatrixXi F;
+Eigen::MatrixXi F,T;
 int selected_col = 0;
 // Faces
 // Bounding box diagonal length
@@ -164,6 +163,14 @@ bool init_arap()
   assert(S.rows() == V.rows());
   C.resize(S.rows(),3);
   MatrixXd bc = MatrixXd::Zero(b.size(),S.maxCoeff()+1);
+  MatrixXi * Ele;
+  if(T.rows()>0)
+  {
+    Ele = &T;
+  }else
+  {
+    Ele = &F;
+  }
   // get b from S
   {
     int bi = 0;
@@ -200,12 +207,12 @@ bool init_arap()
   VectorXi _S;
   VectorXd _D;
   MatrixXd W;
-  if(!harmonic(V,F,b,bc,1,W))
+  if(!harmonic(V,*Ele,b,bc,1,W))
   {
     return false;
   }
   partition(W,100,arap_data.G,_S,_D);
-  return arap_precomputation(V,F,b,arap_data);
+  return arap_precomputation(V,*Ele,b,arap_data);
 }
 
 bool update_arap()
@@ -606,6 +613,8 @@ int main(int argc, char * argv[])
   // init mesh
   string filename = "../shared/decimated-knight.obj";
   string sfilename = "../shared/decimated-knight-selection.dmat";
+  //string filename = "../shared/decimated-knight.mesh";
+  //string sfilename = "../shared/decimated-knight-1-selection.dmat";
   if(argc < 3)
   {
     cerr<<"Usage:"<<endl<<"    ./example input.obj selection.dmat"<<endl;
@@ -616,11 +625,27 @@ int main(int argc, char * argv[])
     filename = argv[1];
     sfilename = argv[2];
   }
+  string d,b,ext,f;
+  pathinfo(filename,d,b,ext,f);
+  // Convert extension to lower case
+  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
 
   vector<vector<double > > vV,vN,vTC;
   vector<vector<int > > vF,vTF,vFN;
   // Convert extension to lower case
-  if(!igl::readOBJ(filename,vV,vTC,vN,vF,vTF,vFN))
+  if(ext == "obj")
+  {
+    if(!igl::readOBJ(filename,vV,vTC,vN,vF,vTF,vFN))
+    {
+      return 1;
+    }
+  }else if(ext == "mesh")
+  {
+    if(!igl::readMESH(filename,V,T,F))
+    {
+      return 1;
+    }
+  }else
   {
     return 1;
   }

+ 10 - 1
include/igl/harmonic.cpp

@@ -24,7 +24,16 @@ IGL_INLINE bool igl::harmonic(
   using namespace Eigen;
   SparseMatrix<double> L,M,Mi;
   cotmatrix(V,F,L);
-  massmatrix(V,F,MASSMATRIX_VORONOI,M);
+  switch(F.cols())
+  {
+    case 3:
+      massmatrix(V,F,MASSMATRIX_VORONOI,M);
+      break;
+    case 4:
+    default:
+      massmatrix(V,F,MASSMATRIX_BARYCENTRIC,M);
+      break;
+  }
   invert_diag(M,Mi);
   SparseMatrix<double> Q = -L;
   for(int p = 1;p<k;p++)

+ 15 - 7
include/igl/svd3x3/arap.cpp

@@ -40,7 +40,7 @@ IGL_INLINE bool igl::arap_precomputation(
   assert((b.size() == 0 || b.minCoeff() >=0) && "b out of bounds");
   // remember b
   data.b = b;
-  assert(F.cols() == 3 && "For now only triangles");
+  //assert(F.cols() == 3 && "For now only triangles");
   // dimension
   const int dim = V.cols();
   assert(dim == 3 && "Only 3d supported");
@@ -66,14 +66,15 @@ IGL_INLINE bool igl::arap_precomputation(
         break;
       case 4:
         eff_energy = ARAP_ENERGY_TYPE_ELEMENTS;
+        break;
       default:
         assert(false);
     }
   }
 
 
-  // Get covariance scatter matrix, when applied collects the covariance matrices
-  // used to fit rotations to during optimization
+  // Get covariance scatter matrix, when applied collects the covariance
+  // matrices used to fit rotations to during optimization
   covariance_scatter_matrix(V,F,eff_energy,data.CSM);
 
   // Get group sum scatter matrix, when applied sums all entries of the same
@@ -81,7 +82,13 @@ IGL_INLINE bool igl::arap_precomputation(
   SparseMatrix<double> G_sum;
   if(data.G.size() == 0)
   {
-    speye(n,G_sum);
+    if(eff_energy == ARAP_ENERGY_TYPE_ELEMENTS)
+    {
+      speye(F.rows(),G_sum);
+    }else
+    {
+      speye(n,G_sum);
+    }
   }else
   {
     // groups are defined per vertex, convert to per face using mode
@@ -105,6 +112,7 @@ IGL_INLINE bool igl::arap_precomputation(
   }
   SparseMatrix<double> G_sum_dim;
   repdiag(G_sum,dim,G_sum_dim);
+  assert(G_sum_dim.cols() == data.CSM.rows());
   data.CSM = (G_sum_dim * data.CSM).eval();
 
   arap_rhs(V,F,eff_energy,data.K);
@@ -165,8 +173,8 @@ IGL_INLINE bool igl::arap_solve(
       eff_R = R;
     }else
     {
-      eff_R.resize(dim,dim*n);
-      for(int v = 0;v<n;v++)
+      eff_R.resize(dim,data.CSM.rows());
+      for(int v = 0;v<data.CSM.rows()/dim;v++)
       {
         eff_R.block(0,dim*v,dim,dim) = 
           R.block(0,dim*data.G(v),dim,dim);
@@ -174,7 +182,7 @@ IGL_INLINE bool igl::arap_solve(
     }
 
     VectorXd Rcol;
-    columnize(eff_R,n,2,Rcol);
+    columnize(eff_R,data.CSM.rows()/dim,2,Rcol);
     VectorXd Bcol = -data.K * Rcol;
     for(int c = 0;c<dim;c++)
     {