Browse Source

missing cpp files

Former-commit-id: e526856629c940e0f485a3ae4ce6605d47b43be0
Alec Jacobson (jalec 12 years ago
parent
commit
96f38d6247

+ 6 - 2
file-formats/bf.html

@@ -2,9 +2,11 @@
 <html>
   <head>
     <link rel='stylesheet' type='text/css' href='../style.css' >
-    <title>IGL_LIB file formats | .bf</title>
+    <title>libigl file formats | .bf</title>
   </head>
-  <body>
+  <body class=article_body>
+  <div class=article>
+    <a href=..><img src=../libigl-logo.jpg alt="igl logo" class=center></a>
     <h1>.bf - bone forests</h1>
     <hr>
     <p>
@@ -20,6 +22,8 @@ Each line contains data about a vertex (joint) of a bone tree:
 Indices begin with 0.  The weight index is -1 if the bone does not have an
 associated weight. The parent index is -1 for root nodes.
     </p>
+    <p>See also: <a href=.>file formats</a></p>
+  </div>
   </body>
 </html>
 

+ 6 - 2
file-formats/dmat.html

@@ -2,9 +2,11 @@
 <html>
   <head>
     <link rel='stylesheet' type='text/css' href='../style.css' >
-    <title>IGL_LIB file formats | .dmat</title>
+    <title>libigl file formats | .dmat</title>
   </head>
-  <body>
+  <body class=article_body>
+  <div  class=article>
+    <a href=..><img src=../libigl-logo.jpg alt="igl logo" class=center></a>
     <h1>.dmat - dense matrices</h1>
     <hr>
     <p>
@@ -34,6 +36,8 @@ Then there should be another header containing the size of the binary part:
 Then coefficents are written in column-major order in Little-endian 4-byte
 double precision IEEE floating point format.
     </p>
+    <p>See also: <a href=.>file formats</a></p>
+  </div>
   </body>
 </html>
 

+ 6 - 3
file-formats/index.html

@@ -2,10 +2,12 @@
 <html>
   <head>
     <link rel='stylesheet' type='text/css' href='../style.css' >
-    <title>IGL_LIB file formats</title>
+    <title>libigl file formats</title>
   </head>
-  <body>
-  <h1>IGL_LIB file formats</h1>
+  <body class=article_body>
+  <div  class=article>
+    <a href=..><img src=../libigl-logo.jpg alt="igl logo" class=center></a>
+  <h1>libigl file formats</h1>
   <ul>
     <li><a href="./dmat.html">.dmat</a> uncompressed ASCII/binary files for dense matrices</li>
     <li><a href="./bf.html">.bf</a> ASCII files for representing skeletal bone "forests"</li>
@@ -35,5 +37,6 @@
   supports png image files via the <a href=https://github.com/yig/yimg>yimg</a>
   library. Alpha channels and compression are suppported.</li>
   </ul>
+  </div>
   </body>
 </html>

+ 6 - 2
file-formats/tgf.html

@@ -2,9 +2,11 @@
 <html>
   <head>
     <link rel='stylesheet' type='text/css' href='../style.css' >
-    <title>IGL_LIB file formats | .tgf</title>
+    <title>libigl file formats | .tgf</title>
   </head>
-  <body>
+  <body class=article_body>
+  <div  class=article>
+    <a href=..><img src=../libigl-logo.jpg alt="igl logo" class=center></a>
     <h1>.tgf - control handle graphs</h1>
     <hr>
     <p>
@@ -27,6 +29,8 @@ The next section concerns the edges of the graph. Each line corresponds to an ed
     <p>
 Bone edges trump pseudo and cage edges. 
     </p>
+    <p>See also: <a href=.>file formats</a></p>
+  </div>
   </body>
 </html>
 

+ 189 - 0
include/igl/mvc.cpp

@@ -0,0 +1,189 @@
+#include "mvc.h"
+#include <vector>
+#include <cassert>
+#include <iostream>
+
+// Broken Implementation
+IGL_INLINE void igl::mvc(const Eigen::MatrixXd &V, const Eigen::MatrixXd &C, Eigen::MatrixXd &W)
+{
+  
+  // at least three control points
+  assert(C.rows()>2);
+  
+  // dimension of points
+  assert(C.cols() == 3 || C.cols() == 2);
+  assert(V.cols() == 3 || V.cols() == 2);
+  
+  // number of polygon points
+  int num = C.rows();
+  
+  Eigen::MatrixXd V1,C1;
+  int i_prev, i_next;
+  
+  // check if either are 3D but really all z's are 0
+  bool V_flat = (V.cols() == 3) && (std::sqrt( (V.col(3)).dot(V.col(3)) ) < 1e-10);
+  bool C_flat = (C.cols() == 3) && (std::sqrt( (C.col(3)).dot(C.col(3)) ) < 1e-10);
+
+  // if both are essentially 2D then ignore z-coords
+  if((C.cols() == 2 || C_flat) && (V.cols() == 2 || V_flat))
+  {
+    // ignore z coordinate
+    V1 = V.block(0,0,V.rows(),2);
+    C1 = C.block(0,0,C.rows(),2);
+  }
+  else
+  {
+    // give dummy z coordinate to either mesh or poly
+    if(V.rows() == 2)
+    {
+      V1 = Eigen::MatrixXd(V.rows(),3);
+      V1.block(0,0,V.rows(),2) = V;
+    }
+    else
+      V1 = V;
+
+    if(C.rows() == 2)
+    {
+      C1 = Eigen::MatrixXd(C.rows(),3);
+      C1.block(0,0,C.rows(),2) = C;
+    }
+    else
+      C1 = C;
+
+    // check that C is planar
+    // average normal around poly corners
+
+    Eigen::Vector3d n = Eigen::Vector3d::Zero();
+    // take centroid as point on plane
+    Eigen::Vector3d p = Eigen::Vector3d::Zero();
+    for (int i = 0; i<num; ++i)
+    {
+      i_prev = (i>0)?(i-1):(num-1);
+      i_next = (i<num-1)?(i+1):0;
+      Eigen::Vector3d vnext = (C1.row(i_next) - C1.row(i)).transpose();
+      Eigen::Vector3d vprev = (C1.row(i_prev) - C1.row(i)).transpose();
+      n += vnext.cross(vprev);
+      p += C1.row(i);
+    }
+    p/=num;
+    n/=num;
+    // normalize n
+    n /= std::sqrt(n.dot(n));
+    
+    // check that poly is really coplanar
+#ifndef NDEBUG
+    for (int i = 0; i<num; ++i)
+    {
+      double dist_to_plane_C = std::abs((C1.row(i)-p.transpose()).dot(n));
+      assert(dist_to_plane_C<1e-10);
+    }
+#endif
+    
+    // check that poly is really coplanar
+    for (int i = 0; i<V1.rows(); ++i)
+    {
+      double dist_to_plane_V = std::abs((V1.row(i)-p.transpose()).dot(n));
+      if(dist_to_plane_V>1e-10)
+        std::cerr<<"Distance from V to plane of C is large..."<<std::endl;
+    }
+    
+    // change of basis
+    Eigen::Vector3d b1 = C1.row(1)-C1.row(0);
+    Eigen::Vector3d b2 = n.cross(b1);
+    // normalize basis rows
+    b1 /= std::sqrt(b1.dot(b1));
+    b2 /= std::sqrt(b2.dot(b2));
+    n /= std::sqrt(n.dot(n));
+    
+    //transpose of the basis matrix in the m-file
+    Eigen::Matrix3d basis = Eigen::Matrix3d::Zero();
+    basis.col(0) = b1;
+    basis.col(1) = b2;
+    basis.col(2) = n;
+    
+    // change basis of rows vectors by right multiplying with inverse of matrix
+    // with basis vectors as rows
+    Eigen::ColPivHouseholderQR<Eigen::Matrix3d> solver = basis.colPivHouseholderQr();
+    // Throw away coordinates in normal direction
+    V1 = solver.solve(V1.transpose()).transpose().block(0,0,V1.rows(),2);
+    C1 = solver.solve(C1.transpose()).transpose().block(0,0,C1.rows(),2);
+    
+  }
+  
+  // vectors from V to every C, where CmV(i,j,:) is the vector from domain
+  // vertex j to handle i
+  double EPSILON = 1e-10;
+  Eigen::MatrixXd WW = Eigen::MatrixXd(C1.rows(), V1.rows());
+  Eigen::MatrixXd dist_C_V (C1.rows(), V1.rows());
+  std::vector< std::pair<int,int> > on_corner(0);
+  std::vector< std::pair<int,int> > on_segment(0);
+  for (int i = 0; i<C1.rows(); ++i)
+  {
+    i_prev = (i>0)?(i-1):(num-1);
+    i_next = (i<num-1)?(i+1):0;
+    // distance from each corner in C to the next corner so that edge_length(i) 
+    // is the distance from C(i,:) to C(i+1,:) defined cyclically
+    double edge_length = std::sqrt((C1.row(i) - C1.row(i_next)).dot(C1.row(i) - C1.row(i_next)));
+    for (int j = 0; j<V1.rows(); ++j)
+    {
+      Eigen::VectorXd v = C1.row(i) - V1.row(j);
+      Eigen::VectorXd vnext = C1.row(i_next) - V1.row(j);
+      Eigen::VectorXd vprev = C1.row(i_prev) - V1.row(j);
+      // distance from V to every C, where dist_C_V(i,j) is the distance from domain
+      // vertex j to handle i
+      dist_C_V(i,j) = std::sqrt(v.dot(v));
+      double dist_C_V_next = std::sqrt(vnext.dot(vnext));
+      double a_prev = std::atan2(vprev[1],vprev[0]) - std::atan2(v[1],v[0]);
+      double a_next = std::atan2(v[1],v[0]) - std::atan2(vnext[1],vnext[0]);
+      // mean value coordinates
+      WW(i,j) = (std::tan(a_prev/2.0) + std::tan(a_next/2.0)) / dist_C_V(i,j);
+      
+      if (dist_C_V(i,j) < EPSILON)
+        on_corner.push_back(std::make_pair(j,i));
+      else
+        // only in case of no-corner (no need for checking for multiple segments afterwards --
+        // should only be on one segment (otherwise must be on a corner and we already
+        // handled that)
+        // domain vertex j is on the segment from i to i+1 if the distances from vj to
+        // pi and pi+1 are about 
+        if(abs((dist_C_V(i,j) + dist_C_V_next) / edge_length - 1) < EPSILON)
+          on_segment.push_back(std::make_pair(j,i));
+      
+    }
+  }
+  
+  // handle degenerate cases
+  // snap vertices close to corners
+  for (unsigned i = 0; i<on_corner.size(); ++i)
+  {
+    int vi = on_corner[i].first;
+    int ci = on_corner[i].second;
+    for (int ii = 0; ii<C.rows(); ++ii)
+      WW(ii,vi) = (ii==ci)?1:0;
+  }
+  
+  // snap vertices close to segments
+  for (unsigned i = 0; i<on_segment.size(); ++i)
+  {
+    int vi = on_segment[i].first;
+    int ci = on_segment[i].second;
+    int ci_next = (ci<num-1)?(ci+1):0;
+    for (int ii = 0; ii<C.rows(); ++ii)
+      if (ii == ci)
+        WW(ii,vi) = dist_C_V(ci_next,vi);
+      else
+      {
+        if ( ii == ci_next)
+          WW(ii,vi)  = dist_C_V(ci,vi);
+        else
+          WW(ii,vi) = 0;
+      }
+  }
+  
+  // normalize W
+  for (int i = 0; i<V.rows(); ++i)
+    WW.col(i) /= WW.col(i).sum();
+  
+  // we've made W transpose
+  W = WW.transpose();
+}

+ 25 - 0
include/igl/orth.cpp

@@ -0,0 +1,25 @@
+#include "orth.h"
+
+// Broken Implementation
+IGL_INLINE void igl::orth(const Eigen::MatrixXd &A, Eigen::MatrixXd &Q)
+{
+
+  //perform svd on A = U*S*V' (V is not computed and only the thin U is computed)
+  Eigen::JacobiSVD<Eigen::MatrixXd> svd(A, Eigen::ComputeThinU );
+  Eigen::MatrixXd U = svd.matrixU();
+  const Eigen::VectorXd S = svd.singularValues();
+  
+  //get rank of A
+  int m = A.rows();
+  int n = A.cols();
+  double tol = std::max(m,n) * S.maxCoeff() *  2.2204e-16;
+  int r = 0;
+  for (int i = 0; i < S.rows(); ++r,++i)
+  {
+    if (S[i] < tol)
+      break;
+  }
+  
+  //keep r first columns of U
+  Q = U.block(0,0,U.rows(),r);
+}

BIN
libigl-logo.jpg


+ 1 - 1
readme.txt

@@ -51,7 +51,7 @@ int main(int argc, char * argv[])
 
 using gcc (replacing appropriate paths):
 
-g++ -DIGL_HEADER_ONLY -I/usr/local/igl/igl_lib/include \
+g++ -DIGL_HEADER_ONLY -I/usr/local/igl/libigl/include \
   -I/opt/local/include/eigen3 example.cpp -o example
 
 Then run this example with:

+ 1 - 1
scripts/autoexplicit.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 # Usage:
-#   cd $IGL_LIB/include/igl
+#   cd $LIBIGL/include/igl
 #   make -C [your_project] 2>&1 | ../../scripts/autoexplicit.sh
 
 

+ 1 - 1
scripts/autoexplicit_linux.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 # Usage:
-#   cd $IGL_LIB/include/igl
+#   cd $LIBIGL/include/igl
 #   make -C [your_project] 2>&1 | ../../scripts/autoexplicit_linux.sh
 
 

+ 1 - 1
scripts/doc.sh

@@ -42,7 +42,7 @@ do
 done
 
 echo "    </table>"
-echo "    <p>See also: <a href=tutorial.html>tutorial</a>, <a href=style_guidelines.html>style guidelines</a></p>"
+echo "    <p>See also: <a href=tutorial.html>tutorial</a>, <a href=style_guidelines.html>style guidelines</a>, <a href=file-formats/index.html>file formats</a></p>"
 echo "    <p>Automatically generated on `date` by scripts/doc.sh.</p>"
 echo "  </div>"
 echo "  </body>"

+ 3 - 1
style_guidelines.html

@@ -185,7 +185,9 @@ and outputs.
       </tr>
     </table>
 
-    <p>See also: <a href=tutorial.html>tutorial</a>, <a href=doc.html>auto-documentation</a></p>
+    <p>See also: <a href=tutorial.html>tutorial</a>, <a
+    href=doc.html>auto-documentation</a>, <a href=file-formats/index.html>file
+    formats</a></p>
   </div>
   </body>
 </html>

+ 27 - 23
tutorial.html

@@ -24,12 +24,12 @@
 
       <h2 id=header_library>Headers (.h) only library</h2>
       <p>
-        All classes and functions in the IGL library are written in a way in
+        All classes and functions in the libigl library are written in a way in
         which the entire library may be compiled <i>just-in-time</i>,
         effectively behaiving as if it were a "headers only" library (like e.g.
         Eigen). This is achieved by careful organization of each pair of .h and
         .cpp files. To take advantage of this one must only include the path to
-        <code>igl_lib</code> directory in one's project's include path and
+        <code>libigl</code> directory in one's project's include path and
         define the preprocessor macro <code>IGL_HEADER_ONLY</code>.
       </p>
 
@@ -63,14 +63,16 @@
 #include &lt;igl/yet_another_igl_function.h&gt;
 ...
       </code></pre>
-      <span class=todo>example <code>examples/XXX</code> also highlights this feature</span>
+      <span class=todo>example <code>examples/XXX</code> also highlights this
+      feature</span>
 
-      <div class=note>This practice is not recommended outside of debugging purposes.</div>
+      <div class=note>This practice is not recommended outside of debugging
+      purposes.</div>
       
 
       <h3>Benefits of headers-only library</h3>
       <ul>
-        <li><strong>Easy templates:</strong> When using the IGL library as a
+        <li><strong>Easy templates:</strong> When using the libigl library as a
         headers-only library no special care need be taken when using templated
         functions.</li>
       </ul>
@@ -91,9 +93,9 @@
         specialization of templated functions</h3>
         <p>
           Special care must be taken by the developers of each function and
-          class in the IGL library that uses C++ templates. If this function is
-          intended to be compiled into the statically linked igl library then
-          function is only compiled for each <i>explicitly</i> specialized
+          class in the libigl library that uses C++ templates. If this function
+          is intended to be compiled into the statically linked libigl library
+          then function is only compiled for each <i>explicitly</i> specialized
           declaration. These should be added at the bottom of the corresponding
           .cpp file surrounded by a <code>#ifndef IGL_HEADER_ONLY</code>.
         </p>
@@ -114,10 +116,10 @@
         <p>
           Supposed for example we have compiled the igl static lib, including the
           cat.h and cat.cpp functions, without any explicit instanciation. Say
-          using the makefile in the <code>igl_lib</code> directory:
+          using the makefile in the <code>libigl</code> directory:
         </p>
         <pre><code>
-cd $IGL_LIB
+cd $LIBIGL
 make
         </code></pre>
         <p>
@@ -151,7 +153,7 @@ Undefined symbols for architecture x86_64:
           Then you must recompile the IGL static library.
         </p>
         <pre><code>
-cd $IGL_LIB
+cd $LIBIGL
 make
         </code></pre>
         <p>
@@ -174,14 +176,14 @@ make 2&gt;&1 | grep "referenced from" | sed -e "s/, referenced from.*//"
 
         <p>
           Alternatively you can use the <code>autoexplicit.sh</code> function
-          which (for well organized .cpp files in the igl_lib) automatically
+          which (for well organized .h/.cpp pairs in libigl) automatically
           create explicit instanciations from your compiler's error messages.
           Repeat this process until convergence:
         </p>
         <pre><code>
 cd /to/your/project
-make 2&gt;$IGL_LIB/make.err
-cd $IGL_LIB
+make 2&gt;$LIBIGL/make.err
+cd $LIBIGL
 cat make.err | ./autoexplicit.sh
 make clean 
 make
@@ -189,10 +191,10 @@ make
 
         <h3>Benefits of static library</h3>
         <ul>
-          <li><strong>Faster compile time:</strong> Because the igl library is
-          already compiled, only the new code in ones project must be compiled
-          and then linked to IGL. This means compile times are generally
-          faster.</li>
+          <li><strong>Faster compile time:</strong> Because the libigl library
+          is already compiled, only the new code in ones project must be
+          compiled and then linked to IGL. This means compile times are
+          generally faster.</li>
           <li><strong>Debug <i>or</i> optimized:</strong> The IGL static
           library may be compiled in debug mode or optimized release mode
           regardless of whether one's project is being optimized or
@@ -208,7 +210,7 @@ make
 
       <h2 id="dependencies">Dependencies</h2>
       <p>
-        By design the IGL library has very few external dependencies.
+        By design the libigl library has very few external dependencies.
       </p>
         <h3>Mandatory dependencies</h3>
         <p>
@@ -223,9 +225,9 @@ make
         </ul>
         <h3>Optional dependencies</h3>
         <p>
-          Certain functions and classes included the IGL library have external
-          dependencies by construction (e.g. the matlab_interface routines are
-          only useful when matlab is present anyway). These are
+          Certain functions and classes included the libigl library have
+          external dependencies by construction (e.g. the matlab_interface
+          routines are only useful when matlab is present anyway). These are
           <strong>never</strong> compiled by default into the static igl
           library <span class=todo>and are only exposed through compiler
           options</span>. These are:
@@ -244,7 +246,9 @@ make
         href="matlab-to-eigen.html">Our own translation table</a> shows a list
         of common matlab functions and their igl-eigen equivalents.  
       </p>
-      <p>See also: <a href=style_guidelines.html>style guidlines</a>, <a href=doc.html>auto-documentation</a></p>
+      <p>See also: <a href=style_guidelines.html>style guidlines</a>, <a
+      href=doc.html>auto-documentation</a>, <a
+      href=file-formats/index.html>file formats</a></p>
   </div>
   </body>
 </html>