Browse Source

dqs example finished

Former-commit-id: e64d90a2af061d934320409d935fdb92e2d13520
Alec Jacobson 11 years ago
parent
commit
708f42e018

+ 22 - 0
include/igl/directed_edge_orientations.cpp

@@ -0,0 +1,22 @@
+#include "directed_edge_orientations.h"
+
+template <typename DerivedC, typename DerivedE>
+IGL_INLINE void igl::directed_edge_orientations(
+  const Eigen::PlainObjectBase<DerivedC> & C,
+  const Eigen::PlainObjectBase<DerivedE> & E,
+  std::vector<
+      Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & Q)
+{
+  using namespace Eigen;
+  Q.resize(E.rows());
+  for(int e = 0;e<E.rows();e++)
+  {
+    const auto & b = C.row(E(e,1)) - C.row(E(e,0));
+    Q[e].setFromTwoVectors( RowVector3d(1,0,0),b);
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instanciation
+template void igl::directed_edge_orientations<Eigen::Matrix<double, -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&, std::vector<Eigen::Quaternion<double, 0>, Eigen::aligned_allocator<Eigen::Quaternion<double, 0> > >&);
+#endif

+ 38 - 0
include/igl/directed_edge_orientations.h

@@ -0,0 +1,38 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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_DIRECTED_EDGE_ORIENTATIONS_H
+#define IGL_DIRECTED_EDGE_ORIENTATIONS_H
+#include "igl_inline.h"
+
+#include <Eigen/Core>
+#include <Eigen/Geometry>
+#include <Eigen/StdVector>
+
+namespace igl
+{
+  // Determine rotations that take each edge from the x-axis to its given rest
+  // orientation.
+  //
+  // Inputs:
+  //   C  #C by 3 list of edge vertex positions
+  //   E  #E by 2 list of directed edges
+  // Outputs:
+  //   Q  #E list of quaternions 
+  //
+  template <typename DerivedC, typename DerivedE>
+  IGL_INLINE void directed_edge_orientations(
+    const Eigen::PlainObjectBase<DerivedC> & C,
+    const Eigen::PlainObjectBase<DerivedE> & E,
+    std::vector<
+      Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & Q);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "directed_edge_orientations.cpp"
+#endif
+#endif

+ 48 - 29
tutorial/404_DualQuaternionSkinning/main.cpp

@@ -1,22 +1,18 @@
-// Don't use static library for this example because of Mosek complications
-//#define IGL_NO_MOSEK
-#ifdef IGL_NO_MOSEK
-#undef IGL_STATIC_LIBRARY
-#endif
-#include <igl/boundary_conditions.h>
 #include <igl/colon.h>
 #include <igl/column_to_quats.h>
+#include <igl/directed_edge_orientations.h>
 #include <igl/directed_edge_parents.h>
 #include <igl/forward_kinematics.h>
+#include <igl/PI.h>
 #include <igl/jet.h>
 #include <igl/lbs_matrix.h>
 #include <igl/deform_skeleton.h>
+#include <igl/dqs.h>
 #include <igl/normalize_row_sums.h>
 #include <igl/readDMAT.h>
-#include <igl/readMESH.h>
+#include <igl/readOBJ.h>
 #include <igl/readTGF.h>
 #include <igl/viewer/Viewer.h>
-#include <igl/bbw/bbw.h>
 
 #include <Eigen/Geometry>
 #include <Eigen/StdVector>
@@ -29,24 +25,31 @@ typedef
   RotationList;
 
 const Eigen::RowVector3d sea_green(70./255.,252./255.,167./255.);
-Eigen::MatrixXd V,W;
+Eigen::MatrixXd V,W,C,U,M;
 Eigen::MatrixXi F,BE;
 Eigen::VectorXi P;
-RotationList pose;
-double anim_t = 1.0;
-double anim_t_dir = -0.03;
+std::vector<RotationList > poses;
+double anim_t = 0.0;
+double anim_t_dir = 0.015;
+bool use_dqs = false;
 
 bool pre_draw(igl::Viewer & viewer)
 {
   using namespace Eigen;
   using namespace std;
-  if(viewer.options.is_animating)
+  if(viewer.core.is_animating)
   {
+    // Find pose interval
+    const int begin = (int)floor(anim_t)%poses.size();
+    const int end = (int)(floor(anim_t)+1)%poses.size();
+    const double t = anim_t - floor(anim_t);
+    //cout<<anim_t<<": "<<begin<<" "<<end<<endl;
+
     // Interpolate pose and identity
-    RotationList anim_pose(pose.size());
-    for(int e = 0;e<pose.size();e++)
+    RotationList anim_pose(poses[begin].size());
+    for(int e = 0;e<poses[begin].size();e++)
     {
-      anim_pose[e] = pose[e].slerp(anim_t,Quaterniond::Identity());
+      anim_pose[e] = poses[begin][e].slerp(t,poses[end][e]);
     }
     // Propogate relative rotations via FK to retrieve absolute transformations
     RotationList vQ;
@@ -63,7 +66,13 @@ bool pre_draw(igl::Viewer & viewer)
         a.matrix().transpose().block(0,0,dim+1,dim);
     }
     // Compute deformation via LBS as matrix multiplication
-    U = M*T;
+    if(use_dqs)
+    {
+      igl::dqs(V,W,vQ,vT,U);
+    }else
+    {
+      U = M*T;
+    }
 
     // Also deform skeleton edges
     MatrixXd CT;
@@ -74,7 +83,6 @@ bool pre_draw(igl::Viewer & viewer)
     viewer.set_edges(CT,BET,sea_green);
     viewer.compute_normals();
     anim_t += anim_t_dir;
-    anim_t_dir *= (anim_t>=1.0 || anim_t<=0.0?-1.0:1.0);
   }
   return false;
 }
@@ -83,8 +91,12 @@ bool key_down(igl::Viewer &viewer, unsigned char key, int mods)
 {
   switch(key)
   {
+    case 'D':
+    case 'd':
+      use_dqs = !use_dqs;
+      break;
     case ' ':
-      viewer.options.is_animating = !viewer.options.is_animating;
+      viewer.core.is_animating = !viewer.core.is_animating;
       break;
   }
 }
@@ -97,23 +109,30 @@ int main(int argc, char *argv[])
   U=V;
   igl::readTGF("../shared/arm.tgf",C,BE);
   // retrieve parents for forward kinematics
-  directed_edge_parents(BE,P);
+  igl::directed_edge_parents(BE,P);
+  RotationList rest_pose;
+  igl::directed_edge_orientations(C,BE,rest_pose);
+  poses.resize(4,RotationList(4,Quaterniond::Identity()));
+  // poses[1] // twist
+  const Quaterniond twist(AngleAxisd(igl::PI,Vector3d(1,0,0)));
+  poses[1][2] = rest_pose[2]*twist*rest_pose[2].conjugate();
+  const Quaterniond bend(AngleAxisd(-igl::PI*0.7,Vector3d(0,0,1)));
+  poses[3][2] = rest_pose[2]*bend*rest_pose[2].conjugate();
+
   igl::readDMAT("../shared/arm-weights.dmat",W);
-  pose_0 identity
-  pose_1 twist
-  pose_2 bend
+  igl::lbs_matrix(V,W,M);
 
   // Plot the mesh with pseudocolors
   igl::Viewer viewer;
   viewer.set_mesh(U, F);
   viewer.set_edges(C,BE,sea_green);
-  viewer.options.show_lines = false;
-  viewer.options.show_overlay_depth = false;
-  viewer.options.line_width = 1;
-  viewer.options.trackball_angle.normalize();
+  viewer.core.show_lines = false;
+  viewer.core.show_overlay_depth = false;
+  viewer.core.line_width = 1;
+  viewer.core.trackball_angle.normalize();
   viewer.callback_pre_draw = &pre_draw;
   viewer.callback_key_down = &key_down;
-  viewer.options.is_animating = false;
-  viewer.options.animation_max_fps = 30.;
+  viewer.core.is_animating = false;
+  viewer.core.animation_max_fps = 30.;
   viewer.launch();
 }

+ 1 - 1
tutorial/shared/arm-weights.dmat.REMOVED.git-id

@@ -1 +1 @@
-2c590c9778cd6d08706d0f04522456ac5c3227e3
+b7cdb3c6082f4ae3559513b338adab08a5e00550

+ 4 - 4
tutorial/shared/arm.tgf

@@ -4,8 +4,8 @@
    4  0.5987815 -0.077609889 0.065252126 4.441723e+291 4.441723e+291 4.441723e+291          1          1          1          0          0          0          1  1.5751366 0.73446566  1.0652521          0    6 
    5 0.73572894 -0.17523362 0.090210152 2.7982368e+199 3.7150555e-27 6.0174446e+175          1          1          1          0          0          0          1  1.1543039 0.88360183  1.0902102          0    8 
 #
-   3    4 1 0 1 0 7
-   1    2 1 0 1 0 3
-   4    5 1 0 1 0 9
-   2    3 1 0 1 0 5
+   1    2
+   2    3
+   3    4
+   4    5
 #