فهرست منبع

mv from volume project

Former-commit-id: f54c9b0648726a9b5251dc1b2073e29e024031c6
Alec Jacobson (jalec 12 سال پیش
والد
کامیت
90c610c06b

+ 36 - 0
include/igl/all_edges.cpp

@@ -0,0 +1,36 @@
+#include "all_edges.h"
+
+IGL_INLINE void igl::all_edges(
+  const Eigen::MatrixXi & F,
+  Eigen::MatrixXi & E)
+{
+  E.resize(F.rows()*F.cols(),F.cols()-1);
+  switch(F.cols())
+  {
+    case 4:
+      E.block(0*F.rows(),0,F.rows(),1) = F.col(1);
+      E.block(0*F.rows(),1,F.rows(),1) = F.col(3);
+      E.block(0*F.rows(),2,F.rows(),1) = F.col(2);
+
+      E.block(1*F.rows(),0,F.rows(),1) = F.col(0);
+      E.block(1*F.rows(),1,F.rows(),1) = F.col(2);
+      E.block(1*F.rows(),2,F.rows(),1) = F.col(3);
+
+      E.block(2*F.rows(),0,F.rows(),1) = F.col(0);
+      E.block(2*F.rows(),1,F.rows(),1) = F.col(3);
+      E.block(2*F.rows(),2,F.rows(),1) = F.col(1);
+
+      E.block(3*F.rows(),0,F.rows(),1) = F.col(0);
+      E.block(3*F.rows(),1,F.rows(),1) = F.col(1);
+      E.block(3*F.rows(),2,F.rows(),1) = F.col(2);
+      return;
+    case 3:
+      E.block(0*F.rows(),0,F.rows(),1) = F.col(1);
+      E.block(0*F.rows(),1,F.rows(),1) = F.col(2);
+      E.block(1*F.rows(),0,F.rows(),1) = F.col(2);
+      E.block(1*F.rows(),1,F.rows(),1) = F.col(0);
+      E.block(2*F.rows(),0,F.rows(),1) = F.col(0);
+      E.block(2*F.rows(),1,F.rows(),1) = F.col(1);
+      return;
+  }
+}

+ 27 - 0
include/igl/all_edges.h

@@ -0,0 +1,27 @@
+#ifndef IGL_ALL_EDGES_H
+#define IGL_ALL_EDGES_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // ALL_EDGES Determines all "directed edges" of a given set of simplices
+  //
+  // Inputs:
+  //   F  #F by simplex_size list of "faces"
+  // Outputs:
+  //   E  #E by simplex_size-1  list of edges
+  //
+  // Note: this is not the same as igl::edges because this includes every
+  // directed edge including repeats (meaning interior edges on a surface will
+  // show up once for each direction and non-manifold edges may appear more than
+  // once for each direction).
+  IGL_INLINE void all_edges(
+    const Eigen::MatrixXi & F,
+    Eigen::MatrixXi & E);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "all_edges.cpp"
+#endif
+
+#endif

+ 21 - 0
include/igl/barycenter.cpp

@@ -0,0 +1,21 @@
+#include "barycenter.h"
+
+IGL_INLINE void igl::barycenter(
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & F,
+  Eigen::MatrixXd & BC)
+{
+  BC.resize(F.rows(),V.cols());
+  // Loop over faces
+  for(int i = 0;i<F.rows();i++)
+  {
+    // loop around face
+    for(int j = 0;j<F.cols();j++)
+    {
+      // Accumulate
+      BC.row(i) += V.row(F(i,j));
+    }
+    // average
+    BC.row(i) /= double(F.cols());
+  }
+}

+ 28 - 0
include/igl/barycenter.h

@@ -0,0 +1,28 @@
+#ifndef IGL_BARYCENTER_H
+#define IGL_BARYCENTER_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // BARYCENTER
+  //
+  // B = barycenter(V,F)
+  //
+  // Compute the barycenter of every triangle
+  //
+  // Inputs:
+  //   V #V x dim matrix of vertex coordinates
+  //   F #F x simplex_size  matrix of indices of triangle corners
+  // Output:
+  //   BC a #F x dim matrix of 3d vertices
+  IGL_INLINE void barycenter(
+      const Eigen::MatrixXd & V,
+      const Eigen::MatrixXi & F,
+      Eigen::MatrixXd & BC);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "barycenter.cpp"
+#endif
+
+#endif

+ 21 - 0
include/igl/bounding_box_diagonal.cpp

@@ -0,0 +1,21 @@
+#include "bounding_box_diagonal.h"
+#include "mat_max.h"
+#include "mat_min.h"
+#include <cmath>
+
+IGL_INLINE double igl::bounding_box_diagonal(
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & F)
+{
+  using namespace igl;
+  using namespace Eigen;
+  VectorXd maxV,minV;
+  VectorXi maxVI,minVI;
+  mat_max(V,1,maxV,maxVI);
+  mat_min(V,1,minV,minVI);
+  return sqrt((maxV-minV).array().square().sum());
+}
+
+#ifndef IGL_HEADER_ONLY
+// Explicit template instanciation
+#endif

+ 23 - 0
include/igl/bounding_box_diagonal.h

@@ -0,0 +1,23 @@
+#ifndef IGL_BOUNDING_BOX_DIAGONAL_H
+#define IGL_BOUNDING_BOX_DIAGONAL_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // Compute the length of the diagonal of a given meshes axis-aligned bounding
+  // box
+  //
+  // Inputs:
+  //   V  #V by 3 list of vertex positions
+  //   F  #F by 3 list of triangle indices into V
+  // Returns length of bounding box diagonal
+  IGL_INLINE double bounding_box_diagonal(
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "bounding_box_diagonal.cpp"
+#endif
+
+#endif

+ 22 - 0
include/igl/median.cpp

@@ -0,0 +1,22 @@
+#include "median.h"
+#include "matrix_to_list.h"
+
+#include <vector>
+#include <algorithm>
+
+IGL_INLINE bool igl::median(const Eigen::VectorXd & V, double & m)
+{
+  using namespace std;
+  using namespace igl;
+  if(V.size() == 0)
+  {
+    return false;
+  }
+  vector<double> vV;
+  matrix_to_list(V,vV);
+  // http://stackoverflow.com/a/1719155/148668
+  size_t n = vV.size()/2;
+  nth_element(vV.begin(),vV.begin()+n,vV.end());
+  m = vV[n];
+  return true;
+}

+ 21 - 0
include/igl/median.h

@@ -0,0 +1,21 @@
+#ifndef IGL_MEDIAN_H
+#define IGL_MEDIAN_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // Compute the median of an eigen vector
+  //
+  // Inputs:
+  //   V  #V list of unsorted values
+  // Outputs:
+  //   m  median of those values
+  // Returns true on success, false on failure
+  IGL_INLINE bool median(const Eigen::VectorXd & V, double & m);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "median.cpp"
+#endif
+
+#endif

+ 61 - 0
include/igl/remove_duplicate_vertices.cpp

@@ -0,0 +1,61 @@
+#include "remove_duplicate_vertices.h"
+#include "round.h"
+#include "unique.h"
+#include "colon.h"
+#include "slice.h"
+#include <functional>
+
+template <
+  typename DerivedV, 
+  typename DerivedSV, 
+  typename DerivedSVI, 
+  typename DerivedSVJ>
+IGL_INLINE void igl::remove_duplicate_vertices(
+  const Eigen::PlainObjectBase<DerivedV>& V,
+  const double epsilon,
+  Eigen::PlainObjectBase<DerivedSV>& SV,
+  Eigen::PlainObjectBase<DerivedSVI>& SVI,
+  Eigen::PlainObjectBase<DerivedSVJ>& SVJ)
+{
+  using namespace igl;
+  if(epsilon > 0)
+  {
+    Eigen::PlainObjectBase<DerivedV> rV,rSV;
+    round((V/(10.0*epsilon)).eval(),rV);
+    unique_rows(rV,rSV,SVI,SVJ);
+    slice(V,SVI,colon<int>(0,V.cols()-1),SV);
+  }else
+  {
+    unique_rows(V,SV,SVI,SVJ);
+  }
+}
+
+template <
+  typename DerivedV, 
+  typename DerivedF,
+  typename DerivedSV, 
+  typename DerivedSVI, 
+  typename DerivedSVJ,
+  typename DerivedSF>
+IGL_INLINE void igl::remove_duplicate_vertices(
+  const Eigen::PlainObjectBase<DerivedV>& V,
+  const Eigen::PlainObjectBase<DerivedF>& F,
+  const double epsilon,
+  Eigen::PlainObjectBase<DerivedSV>& SV,
+  Eigen::PlainObjectBase<DerivedSVI>& SVI,
+  Eigen::PlainObjectBase<DerivedSVJ>& SVJ,
+  Eigen::PlainObjectBase<DerivedSF>& SF)
+{
+  using namespace Eigen;
+  using namespace std;
+  remove_duplicate_vertices(V,epsilon,SV,SVI,SVJ);
+  // remap faces
+  SF = F.unaryExpr(bind1st(mem_fun( 
+    static_cast<VectorXi::Scalar&(VectorXi::*)(VectorXi::Index)>
+      (&VectorXi::operator())), &SVJ)).eval();
+}
+
+#ifndef IGL_HEADER_ONLY
+// Explicit instanciation
+template void igl::remove_duplicate_vertices<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -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&, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+#endif

+ 58 - 0
include/igl/remove_duplicate_vertices.h

@@ -0,0 +1,58 @@
+#ifndef IGL_REMOVE_DUPLICATE_VERTICES_H
+#define IGL_REMOVE_DUPLICATE_VERTICES_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // REMOVE_DUPLICATE_VERTICES Remove duplicate vertices upto a uniqueness
+  // tolerance (epsilon)
+  //
+  // Inputs:
+  //   V  #V by dim list of vertex positions
+  //   epsilon  uniqueness tolerance (significant digit), can probably think of
+  //     this as a tolerance on L1 distance
+  // Outputs:
+  //   SV  #SV by dim new list of vertex positions
+  //   SVI #V by 1 list of indices so SV = V(SVI,:) 
+  //   SVJ #SV by 1 list of indices so V = SV(SVJ,:)
+  //
+  // Example:
+  //   % Mesh in (V,F)
+  //   [SV,SVI,SVJ] = remove_duplicate_vertices(V,1e-7);
+  //   % remap faces
+  //   SF = SVJ(F);
+  //
+  template <
+    typename DerivedV, 
+    typename DerivedSV, 
+    typename DerivedSVI, 
+    typename DerivedSVJ>
+  IGL_INLINE void remove_duplicate_vertices(
+    const Eigen::PlainObjectBase<DerivedV>& V,
+    const double epsilon,
+    Eigen::PlainObjectBase<DerivedSV>& SV,
+    Eigen::PlainObjectBase<DerivedSVI>& SVI,
+    Eigen::PlainObjectBase<DerivedSVJ>& SVJ);
+  // Wrapper that also remaps given faces (F) --> (SF) so that SF index SV
+  template <
+    typename DerivedV, 
+    typename DerivedF,
+    typename DerivedSV, 
+    typename DerivedSVI, 
+    typename DerivedSVJ,
+    typename DerivedSF>
+  IGL_INLINE void remove_duplicate_vertices(
+    const Eigen::PlainObjectBase<DerivedV>& V,
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    const double epsilon,
+    Eigen::PlainObjectBase<DerivedSV>& SV,
+    Eigen::PlainObjectBase<DerivedSVI>& SVI,
+    Eigen::PlainObjectBase<DerivedSVJ>& SVJ,
+    Eigen::PlainObjectBase<DerivedSF>& SF);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "remove_duplicate_vertices.cpp"
+#endif
+
+#endif

+ 32 - 0
include/igl/round.cpp

@@ -0,0 +1,32 @@
+#include "round.h"
+#include <cmath>
+
+
+// http://stackoverflow.com/a/485549
+template <typename DerivedX >
+IGL_INLINE DerivedX igl::round(const DerivedX r)
+{
+  return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
+}
+
+template < typename DerivedX, typename DerivedY>
+IGL_INLINE void igl::round(
+  const Eigen::PlainObjectBase<DerivedX>& X,
+  Eigen::PlainObjectBase<DerivedY>& Y)
+{
+  Y.resize(X.rows(),X.cols());
+  // loop over rows
+  for(int i = 0;i<X.rows();i++)
+  {
+    // loop over cols
+    for(int j = 0;j<X.cols();j++)
+    {
+      Y(i,j) = igl::round(X(i,j));
+    }
+  }
+}
+
+#ifndef IGL_HEADER_ONLY
+// Explicit instanciation
+template void igl::round<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+#endif

+ 30 - 0
include/igl/round.h

@@ -0,0 +1,30 @@
+#ifndef IGL_ROUND_H
+#define IGL_ROUND_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // Round a scalar value
+  //
+  // Inputs:
+  //   x  number
+  // Returns x rounded to integer
+  template <typename DerivedX>
+  DerivedX round(const DerivedX r);
+  // Round a given matrix to nearest integers
+  //
+  // Inputs:
+  //   X  m by n matrix of scalars
+  // Outputs:
+  //   Y  m by n matrix of rounded integers
+  template < typename DerivedX, typename DerivedY>
+  IGL_INLINE void round(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    Eigen::PlainObjectBase<DerivedY>& Y);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "round.cpp"
+#endif
+
+#endif

+ 24 - 0
include/igl/unique_simplices.cpp

@@ -0,0 +1,24 @@
+#include "unique_simplices.h"
+#include "sort.h"
+#include "unique.h"
+
+IGL_INLINE void igl::unique_simplices(
+  const Eigen::MatrixXi & F,
+  Eigen::MatrixXi & FF)
+{
+  using namespace Eigen;
+  using namespace igl;
+  // Sort each face
+  MatrixXi sortF, unusedI;
+  igl::sort(F,2,1,sortF,unusedI);
+  // Find unique faces
+  VectorXi IA,IC;
+  MatrixXi C;
+  igl::unique_rows(sortF,C,IA,IC);
+  FF.resize(IA.size(),F.cols());
+  // Copy into output
+  for(int i = 0;i<IA.rows();i++)
+  {
+    FF.row(i) = F.row(IA(i));
+  }
+}

+ 22 - 0
include/igl/unique_simplices.h

@@ -0,0 +1,22 @@
+#ifndef IGL_UNIQUE_SIMPLICES_H
+#define IGL_UNIQUE_SIMPLICES_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // Find *combinatorially* unique simplices in F
+  //
+  // Inputs:
+  //   F  #F by simplex-size list of simplices
+  // Outputs:
+  //   FF  #FF by simplex-size list of unique simplices in F
+  IGL_INLINE void unique_simplices(
+    const Eigen::MatrixXi & F,
+    Eigen::MatrixXi & FF);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "unique_simplices.cpp"
+#endif
+
+#endif