Browse Source

fix bug in reantweakbar, better draw mesh and generalized adjacnecy matrix

Former-commit-id: 9f59e5d36787a33b934f7f3f14c074ab273012c3
Alec Jacobson (jalec 12 năm trước cách đây
mục cha
commit
0b404948e7

+ 22 - 1
include/igl/ReAntTweakBar.cpp

@@ -7,7 +7,7 @@
 #include <iomanip>
 #include <map>
 
-#define MAX_CB_VAR_SIZE 10
+#define MAX_CB_VAR_SIZE 1000
 // Max line size for reading files
 #define MAX_LINE 1000
 #define MAX_WORD 100
@@ -372,6 +372,13 @@ std::string igl::ReTwBar::get_value_as_string(
         sstr << std::setprecision(15) << *(static_cast<double*>(var));
         break;
       }
+    case TW_TYPE_STDSTRING:
+      {
+        sstr << "TW_TYPE_STDSTRING" << " ";
+        std::string *destPtr = static_cast<std::string *>(var);
+        sstr << destPtr->c_str();
+        break;
+      }
     default:
       {
         std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter = 
@@ -508,6 +515,7 @@ bool igl::ReTwBar::set_value_from_string(
   double d[4];
   bool b;
   unsigned char uc;
+  std::string s;
 
   // First try to get value from default types
   switch(type)
@@ -629,6 +637,12 @@ bool igl::ReTwBar::set_value_from_string(
         }
         break;
       }
+    case TW_TYPE_STDSTRING:
+      {
+        s  = value_str;
+        value = &s;
+        break;
+      }
     default:
       // Try to find type in custom enum types
       std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter = 
@@ -751,6 +765,13 @@ bool igl::ReTwBar::set_value_from_string(
             *dvar = *fvalue;
             break;
           }
+        case TW_TYPE_STDSTRING:
+          {
+            std::string * svar =   static_cast<std::string*>(var);
+            std::string * svalue = static_cast<std::string*>(value);
+            *svar = *svalue;
+            break;
+          }
         default:
           // Try to find type in custom enum types
           std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter = 

+ 9 - 1
include/igl/adjacency_matrix.cpp

@@ -13,7 +13,15 @@ IGL_INLINE void igl::adjacency_matrix(
 {
   Eigen::DynamicSparseMatrix<T, Eigen::RowMajor> 
     dyn_A(F.maxCoeff()+1, F.maxCoeff()+1);
-  dyn_A.reserve(6*(F.maxCoeff()+1));
+  switch(F.cols())
+  {
+    case 3:
+      dyn_A.reserve(6*(F.maxCoeff()+1));
+      break;
+    case 4:
+      dyn_A.reserve(26*(F.maxCoeff()+1));
+      break;
+  }
 
   // Loop over faces
   for(int i = 0;i<F.rows();i++)

+ 1 - 1
include/igl/adjacency_matrix.h

@@ -12,7 +12,7 @@ namespace igl
   // Templates:
   //   T  should be a eigen sparse matrix primitive type like int or double
   // Inputs:
-  //   F  #F by dim list of mesh faces (must be triangles)
+  //   F  #F by dim list of mesh simplices
   // Outputs: 
   //   A  max(F) by max(F) cotangent matrix, each row i corresponding to V(i,:)
   //

+ 142 - 0
include/igl/draw_mesh.cpp

@@ -195,3 +195,145 @@ IGL_INLINE void igl::draw_mesh(
   glEnd();
 }
 
+IGL_INLINE void igl::draw_mesh(
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & F,
+  const Eigen::MatrixXd & N,
+  const Eigen::MatrixXi & NF,
+  const Eigen::MatrixXd & C,
+  const Eigen::MatrixXd & TC,
+  const Eigen::MatrixXi & TF,
+  const Eigen::MatrixXd & W,
+  const GLuint W_index,
+  const Eigen::MatrixXi & WI,
+  const GLuint WI_index)
+{
+  using namespace std;
+  if(F.size() > 0)
+  {
+    assert(F.maxCoeff() < V.rows());
+    assert(V.cols() == 3);
+    assert(C.rows() == V.rows() || C.rows() == F.rows()*3 || C.size() == 0);
+    assert(C.cols() == 3 || C.size() == 0);
+    assert(N.cols() == 3);
+    assert(TC.cols() == 2 || TC.size() == 0);
+  }
+  if(W.size()>0)
+  {
+    assert(W.rows() == V.rows());
+    assert(WI.rows() == V.rows());
+    assert(W.cols() == WI.cols());
+  }
+
+  glBegin(GL_TRIANGLES);
+  // loop over faces
+  for(int i = 0; i<F.rows();i++)
+  {
+    // loop over corners of triangle
+    for(int j = 0;j<3;j++)
+    {
+      if(W.size()>0 && W_index !=0 && WI_index != 0)
+      {
+        int weights_left = W.cols();
+        while(weights_left != 0)
+        {
+          int pass_size = std::min(4,weights_left);
+          int weights_already_passed = W.cols()-weights_left;
+          // Get attribute location of next 4 weights
+          int pass_W_index = W_index + weights_already_passed/4;
+          int pass_WI_index = WI_index + weights_already_passed/4;
+          switch(pass_size)
+          {
+            case 1:
+              glVertexAttrib1d(
+                pass_W_index,
+                W(F(i,j),0+weights_already_passed));
+              glVertexAttrib1d(
+                pass_WI_index,
+                WI(F(i,j),0+weights_already_passed));
+              break;
+            case 2:
+              glVertexAttrib2d(
+                pass_W_index,
+                W(F(i,j),0+weights_already_passed),
+                W(F(i,j),1+weights_already_passed));
+              glVertexAttrib2d(
+                pass_WI_index,
+                WI(F(i,j),0+weights_already_passed),
+                WI(F(i,j),1+weights_already_passed));
+              break;
+            case 3:
+              glVertexAttrib3d(
+                pass_W_index,
+                W(F(i,j),0+weights_already_passed),
+                W(F(i,j),1+weights_already_passed),
+                W(F(i,j),2+weights_already_passed));
+              glVertexAttrib3d(
+                pass_WI_index,
+                WI(F(i,j),0+weights_already_passed),
+                WI(F(i,j),1+weights_already_passed),
+                WI(F(i,j),2+weights_already_passed));
+              break;
+            default:
+              glVertexAttrib4d(
+                pass_W_index,
+                W(F(i,j),0+weights_already_passed),
+                W(F(i,j),1+weights_already_passed),
+                W(F(i,j),2+weights_already_passed),
+                W(F(i,j),3+weights_already_passed));
+              glVertexAttrib4d(
+                pass_WI_index,
+                WI(F(i,j),0+weights_already_passed),
+                WI(F(i,j),1+weights_already_passed),
+                WI(F(i,j),2+weights_already_passed),
+                WI(F(i,j),3+weights_already_passed));
+              break;
+          }
+          weights_left -= pass_size;
+        }
+      }
+      if(TC.rows() > 0 && TF.rows() > 0)
+      {
+        if(TF(i,j) >=  0 && TF(i,j)<TC.rows())
+        {
+          glTexCoord2d(TC(TF(i,j),0),TC(TF(i,j),1));
+          //printf("TexCoord: %d %g %g\n",TF(i,j), TC(TF(i,j),0),TC(TF(i,j),1));
+        }// else what?
+      }
+      if(C.rows() == V.rows())
+      {
+        glColor3d(C(F(i,j),0),C(F(i,j),1),C(F(i,j),2));
+      }else if(C.rows() == F.rows()*3)
+      {
+        glColor3d(C(i*3+j,0), C(i*3+j,1), C(i*3+j,2));
+      }
+      if(NF.rows() > 0)
+      {
+        const int nfij = NF(i,j);
+        if(nfij >=  0 && nfij<N.rows())
+        {
+          glNormal3d(N(nfij,0),N(nfij,1),N(nfij,2));
+          //printf("Normal: %d %g %g %g\n",nfij, N(nfij,0),N(nfij,1),N(nfij,2));
+        }// else what?
+
+      } else
+      {
+        if(N.rows() == V.rows())
+        {
+          glNormal3d(N(F(i,j),0),N(F(i,j),1),N(F(i,j),2));
+        }else if(N.rows() == F.rows()*3)
+        {
+          glNormal3d(N(i*3+j,0),N(i*3+j,1),N(i*3+j,2));
+        }else if(N.rows() == F.rows())
+        {
+          glNormal3d(N(i,0),N(i,1),N(i,2));
+        }
+      }
+      glVertex3d(V(F(i,j),0),V(F(i,j),1),V(F(i,j),2));
+          //printf("Vertex: %d %g %g %g\n",F(i,j), V(F(i,j),0),V(F(i,j),1),V(F(i,j),2));
+    }
+    //printf("\n");
+  }
+  glEnd();
+}
+

+ 33 - 0
include/igl/draw_mesh.h

@@ -51,8 +51,38 @@ namespace igl
   //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
   //   F  #F by 3 eigne Matrix of face (triangle) indices
   //   N  #V by 3 eigen Matrix of mesh vertex 3D normals
+  //   C  #V by 3 eigen Matrix of mesh vertex RGB colors
   //   TC  #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
+  //   W  #V by #H eigen Matrix of per mesh vertex, per handle weights
+  //   W_index  Specifies the index of the "weight" vertex attribute: see
+  //     glBindAttribLocation, if W_index is 0 then weights are ignored
+  //   WI  #V by #H eigen Matrix of per mesh vertex, per handle weight ids
+  //   WI_index  Specifies the index of the "weight" vertex attribute: see
+  //     glBindAttribLocation, if WI_index is 0 then weight indices are ignored
+  IGL_INLINE void draw_mesh(
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXd & N,
+    const Eigen::MatrixXd & C,
+    const Eigen::MatrixXd & TC,
+    const Eigen::MatrixXd & W,
+    const GLuint W_index,
+    const Eigen::MatrixXi & WI,
+    const GLuint WI_index);
+  
+  // Draw OpenGL commands needed to display a mesh with normals, per-vertex
+  // colors and LBS weights
+  //
+  // Inputs:
+  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F  #F by 3 eigne Matrix of face (triangle) indices
+  //   N  #V by 3 eigen Matrix of mesh vertex 3D normals
+  //   NF  #F by 3 eigen Matrix of face (triangle) normal indices, <0 means no
+  //     normal
   //   C  #V by 3 eigen Matrix of mesh vertex RGB colors
+  //   TC  #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
+  //   TF  #F by 3 eigen Matrix of face (triangle) texture indices, <0 means no
+  //     texture
   //   W  #V by #H eigen Matrix of per mesh vertex, per handle weights
   //   W_index  Specifies the index of the "weight" vertex attribute: see
   //     glBindAttribLocation, if W_index is 0 then weights are ignored
@@ -63,12 +93,15 @@ namespace igl
     const Eigen::MatrixXd & V,
     const Eigen::MatrixXi & F,
     const Eigen::MatrixXd & N,
+    const Eigen::MatrixXi & NF,
     const Eigen::MatrixXd & C,
     const Eigen::MatrixXd & TC,
+    const Eigen::MatrixXi & TF,
     const Eigen::MatrixXd & W,
     const GLuint W_index,
     const Eigen::MatrixXi & WI,
     const GLuint WI_index);
+
 }
 
 #ifdef IGL_HEADER_ONLY

+ 3 - 2
include/igl/readOBJ.cpp

@@ -99,8 +99,8 @@ IGL_INLINE bool igl::readOBJ(
         if(count != 2 && count != 3)
         {
           fprintf(stderr, 
-                  "Error: readOBJ() vertex on line %d should have 2 or 3 coordinates", 
-                  line_no);
+                  "Error: readOBJ() vertex on line %d should have 2 or 3 coordinates (%d)", 
+                  line_no,count);
           fclose(obj_file);
           return false;
         }
@@ -375,4 +375,5 @@ IGL_INLINE bool igl::readOBJ(
 // generated by autoexplicit.sh
 template bool igl::readOBJ<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template bool igl::readOBJ<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 2, 1, -1, 2> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 1, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> >&);
+template bool igl::readOBJ<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif