Alec Jacobson 2 years ago
parent
commit
261fec1d05
100 changed files with 0 additions and 16639 deletions
  1. 0 1074
      include/igl/AABB.cpp
  2. 0 130
      include/igl/AtA_cached.cpp
  3. 0 30
      include/igl/EPS.cpp
  4. 0 162
      include/igl/HalfEdgeIterator.cpp
  5. 0 497
      include/igl/MshLoader.cpp
  6. 0 347
      include/igl/MshSaver.cpp
  7. 0 52
      include/igl/accumarray.cpp
  8. 0 370
      include/igl/active_set.cpp
  9. 0 180
      include/igl/adjacency_list.cpp
  10. 0 125
      include/igl/adjacency_matrix.cpp
  11. 0 26
      include/igl/all.cpp
  12. 0 39
      include/igl/all_pairs_distances.cpp
  13. 0 139
      include/igl/ambient_occlusion.cpp
  14. 0 20
      include/igl/angular_distance.cpp
  15. 0 26
      include/igl/any.cpp
  16. 0 306
      include/igl/arap.cpp
  17. 0 883
      include/igl/arap_dof.cpp
  18. 0 259
      include/igl/arap_linear_block.cpp
  19. 0 95
      include/igl/arap_rhs.cpp
  20. 0 69
      include/igl/average_from_edges_onto_vertices.cpp
  21. 0 27
      include/igl/average_onto_faces.cpp
  22. 0 33
      include/igl/average_onto_vertices.cpp
  23. 0 39
      include/igl/avg_edge_length.cpp
  24. 0 42
      include/igl/axis_angle_to_quat.cpp
  25. 0 58
      include/igl/barycenter.cpp
  26. 0 113
      include/igl/barycentric_coordinates.cpp
  27. 0 42
      include/igl/barycentric_interpolation.cpp
  28. 0 38
      include/igl/basename.cpp
  29. 0 144
      include/igl/bbw.cpp
  30. 0 74
      include/igl/bezier.cpp
  31. 0 93
      include/igl/bfs.cpp
  32. 0 100
      include/igl/bfs_orient.cpp
  33. 0 207
      include/igl/biharmonic_coordinates.cpp
  34. 0 115
      include/igl/bijective_composite_harmonic_mapping.cpp
  35. 0 71
      include/igl/blkdiag.cpp
  36. 0 379
      include/igl/blue_noise.cpp
  37. 0 32
      include/igl/bone_parents.cpp
  38. 0 245
      include/igl/boundary_conditions.cpp
  39. 0 225
      include/igl/boundary_facets.cpp
  40. 0 154
      include/igl/boundary_loop.cpp
  41. 0 105
      include/igl/bounding_box.cpp
  42. 0 26
      include/igl/bounding_box_diagonal.cpp
  43. 0 21
      include/igl/canonical_quaternions.cpp
  44. 0 263
      include/igl/cat.cpp
  45. 0 24
      include/igl/ceil.cpp
  46. 0 73
      include/igl/centroid.cpp
  47. 0 143
      include/igl/circulation.cpp
  48. 0 30
      include/igl/circumradius.cpp
  49. 0 373
      include/igl/collapse_edge.cpp
  50. 0 139
      include/igl/collapse_small_triangles.cpp
  51. 0 69
      include/igl/colon.cpp
  52. 0 1697
      include/igl/colormap.cpp
  53. 0 27
      include/igl/column_to_quats.cpp
  54. 0 63
      include/igl/columnize.cpp
  55. 0 155
      include/igl/comb_cross_field.cpp
  56. 0 78
      include/igl/comb_frame_field.cpp
  57. 0 132
      include/igl/comb_line_field.cpp
  58. 0 99
      include/igl/combine.cpp
  59. 0 86
      include/igl/compute_frame_field_bisectors.cpp
  60. 0 55
      include/igl/connect_boundary_to_infinity.cpp
  61. 0 63
      include/igl/connected_components.cpp
  62. 0 88
      include/igl/copyleft/cgal/assign.cpp
  63. 0 199
      include/igl/copyleft/cgal/assign_scalar.cpp
  64. 0 16
      include/igl/copyleft/cgal/barycenter.cpp
  65. 0 36
      include/igl/copyleft/cgal/cell_adjacency.cpp
  66. 0 509
      include/igl/copyleft/cgal/closest_facet.cpp
  67. 0 153
      include/igl/copyleft/cgal/complex_to_mesh.cpp
  68. 0 67
      include/igl/copyleft/cgal/component_inside_component.cpp
  69. 0 103
      include/igl/copyleft/cgal/convex_hull.cpp
  70. 0 48
      include/igl/copyleft/cgal/coplanar.cpp
  71. 0 67
      include/igl/copyleft/cgal/delaunay_triangulation.cpp
  72. 0 397
      include/igl/copyleft/cgal/extract_cells.cpp
  73. 0 233
      include/igl/copyleft/cgal/extract_cells_single_component.cpp
  74. 0 124
      include/igl/copyleft/cgal/extract_feature.cpp
  75. 0 65
      include/igl/copyleft/cgal/fast_winding_number.cpp
  76. 0 122
      include/igl/copyleft/cgal/half_space_box.cpp
  77. 0 45
      include/igl/copyleft/cgal/hausdorff.cpp
  78. 0 48
      include/igl/copyleft/cgal/incircle.cpp
  79. 0 68
      include/igl/copyleft/cgal/insert_into_cdt.cpp
  80. 0 41
      include/igl/copyleft/cgal/insphere.cpp
  81. 0 295
      include/igl/copyleft/cgal/intersect_other.cpp
  82. 0 84
      include/igl/copyleft/cgal/intersect_with_half_space.cpp
  83. 0 24
      include/igl/copyleft/cgal/lexicographic_triangulation.cpp
  84. 0 15
      include/igl/copyleft/cgal/list_to_matrix.cpp
  85. 0 459
      include/igl/copyleft/cgal/mesh_boolean.cpp
  86. 0 39
      include/igl/copyleft/cgal/mesh_boolean_type_to_funcs.cpp
  87. 0 81
      include/igl/copyleft/cgal/mesh_to_cgal_triangle_list.cpp
  88. 0 58
      include/igl/copyleft/cgal/mesh_to_polyhedron.cpp
  89. 0 387
      include/igl/copyleft/cgal/minkowski_sum.cpp
  90. 0 418
      include/igl/copyleft/cgal/order_facets_around_edge.cpp
  91. 0 333
      include/igl/copyleft/cgal/order_facets_around_edges.cpp
  92. 0 46
      include/igl/copyleft/cgal/orient2D.cpp
  93. 0 39
      include/igl/copyleft/cgal/orient3D.cpp
  94. 0 159
      include/igl/copyleft/cgal/outer_edge.cpp
  95. 0 168
      include/igl/copyleft/cgal/outer_facet.cpp
  96. 0 109
      include/igl/copyleft/cgal/outer_hull.cpp
  97. 0 452
      include/igl/copyleft/cgal/outer_hull_legacy.cpp
  98. 0 103
      include/igl/copyleft/cgal/outer_vertex.cpp
  99. 0 127
      include/igl/copyleft/cgal/peel_outer_hull_layers.cpp
  100. 0 33
      include/igl/copyleft/cgal/peel_winding_number_layers.cpp

+ 0 - 1074
include/igl/AABB.cpp

@@ -1,1074 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "AABB.h"
-#include "EPS.h"
-#include "barycenter.h"
-#include "colon.h"
-#include "doublearea.h"
-#include "point_simplex_squared_distance.h"
-#include "project_to_line_segment.h"
-#include "sort.h"
-#include "volume.h"
-#include "ray_box_intersect.h"
-#include "parallel_for.h"
-#include "ray_mesh_intersect.h"
-#include <iostream>
-#include <iomanip>
-#include <limits>
-#include <list>
-#include <queue>
-#include <stack>
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle, typename Derivedbb_mins, typename Derivedbb_maxs, typename Derivedelements>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::init(
-    const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixBase<DerivedEle> & Ele,
-    const Eigen::MatrixBase<Derivedbb_mins> & bb_mins,
-    const Eigen::MatrixBase<Derivedbb_maxs> & bb_maxs,
-    const Eigen::MatrixBase<Derivedelements> & elements,
-    const int i)
-{
-  using namespace std;
-  using namespace Eigen;
-  deinit();
-  if(bb_mins.size() > 0)
-  {
-    assert(bb_mins.rows() == bb_maxs.rows() && "Serial tree arrays must match");
-    assert(bb_mins.cols() == V.cols() && "Serial tree array dim must match V");
-    assert(bb_mins.cols() == bb_maxs.cols() && "Serial tree arrays must match");
-    assert(bb_mins.rows() == elements.rows() &&
-        "Serial tree arrays must match");
-    // construct from serialization
-    m_box.extend(bb_mins.row(i).transpose());
-    m_box.extend(bb_maxs.row(i).transpose());
-    m_primitive = elements(i);
-    // Not leaf then recurse
-    if(m_primitive == -1)
-    {
-      m_left = new AABB();
-      m_left->init( V,Ele,bb_mins,bb_maxs,elements,2*i+1);
-      m_right = new AABB();
-      m_right->init( V,Ele,bb_mins,bb_maxs,elements,2*i+2);
-      //m_depth = std::max( m_left->m_depth, m_right->m_depth)+1;
-    }
-  }else
-  {
-    VectorXi allI = colon<int>(0,Ele.rows()-1);
-    MatrixXDIMS BC;
-    if(Ele.cols() == 1)
-    {
-      // points
-      BC = V;
-    }else
-    {
-      // Simplices
-      barycenter(V,Ele,BC);
-    }
-    MatrixXi SI(BC.rows(),BC.cols());
-    {
-      MatrixXDIMS _;
-      MatrixXi IS;
-      igl::sort(BC,1,true,_,IS);
-      // Need SI(i) to tell which place i would be sorted into
-      const int dim = IS.cols();
-      for(int i = 0;i<IS.rows();i++)
-      {
-        for(int d = 0;d<dim;d++)
-        {
-          SI(IS(i,d),d) = i;
-        }
-      }
-    }
-    init(V,Ele,SI,allI);
-  }
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-void igl::AABB<DerivedV,DIM>::init(
-    const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixBase<DerivedEle> & Ele)
-{
-  using namespace Eigen;
-  // deinit will be immediately called...
-  return init(V,Ele,MatrixXDIMS(),MatrixXDIMS(),VectorXi(),0);
-}
-
-  template <typename DerivedV, int DIM>
-template <
-  typename DerivedEle,
-  typename DerivedSI,
-  typename DerivedI>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::init(
-    const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixBase<DerivedEle> & Ele,
-    const Eigen::MatrixBase<DerivedSI> & SI,
-    const Eigen::MatrixBase<DerivedI> & I)
-{
-  using namespace Eigen;
-  using namespace std;
-  deinit();
-  if(V.size() == 0 || Ele.size() == 0 || I.size() == 0)
-  {
-    return;
-  }
-  assert(DIM == V.cols() && "V.cols() should matched declared dimension");
-  //const Scalar inf = numeric_limits<Scalar>::infinity();
-  m_box = AlignedBox<Scalar,DIM>();
-  // Compute bounding box
-  for(int i = 0;i<I.rows();i++)
-  {
-    for(int c = 0;c<Ele.cols();c++)
-    {
-      m_box.extend(V.row(Ele(I(i),c)).transpose());
-      m_box.extend(V.row(Ele(I(i),c)).transpose());
-    }
-  }
-  switch(I.size())
-  {
-    case 0:
-      {
-        assert(false);
-      }
-    case 1:
-      {
-        m_primitive = I(0);
-        break;
-      }
-    default:
-      {
-        // Compute longest direction
-        int max_d = -1;
-        m_box.diagonal().maxCoeff(&max_d);
-        // Can't use median on BC directly because many may have same value,
-        // but can use median on sorted BC indices
-        VectorXi SIdI(I.rows());
-        for(int i = 0;i<I.rows();i++)
-        {
-          SIdI(i) = SI(I(i),max_d);
-        }
-        // Pass by copy to avoid changing input
-        const auto median = [](VectorXi A)->int
-        {
-          size_t n = (A.size()-1)/2;
-          nth_element(A.data(),A.data()+n,A.data()+A.size());
-          return A(n);
-        };
-        const int med = median(SIdI);
-        VectorXi LI((I.rows()+1)/2),RI(I.rows()/2);
-        assert(LI.rows()+RI.rows() == I.rows());
-        // Distribute left and right
-        {
-          int li = 0;
-          int ri = 0;
-          for(int i = 0;i<I.rows();i++)
-          {
-            if(SIdI(i)<=med)
-            {
-              LI(li++) = I(i);
-            }else
-            {
-              RI(ri++) = I(i);
-            }
-          }
-        }
-        //m_depth = 0;
-        if(LI.rows()>0)
-        {
-          m_left = new AABB();
-          m_left->init(V,Ele,SI,LI);
-          //m_depth = std::max(m_depth, m_left->m_depth+1);
-        }
-        if(RI.rows()>0)
-        {
-          m_right = new AABB();
-          m_right->init(V,Ele,SI,RI);
-          //m_depth = std::max(m_depth, m_right->m_depth+1);
-        }
-      }
-  }
-}
-
-template <typename DerivedV, int DIM>
-IGL_INLINE bool igl::AABB<DerivedV,DIM>::is_leaf() const
-{
-  return m_primitive != -1;
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle, typename Derivedq>
-IGL_INLINE std::vector<int> igl::AABB<DerivedV,DIM>::find(
-    const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixBase<DerivedEle> & Ele,
-    const Eigen::MatrixBase<Derivedq> & q,
-    const bool first) const
-{
-  using namespace std;
-  using namespace Eigen;
-  assert(q.size() == DIM &&
-      "Query dimension should match aabb dimension");
-  assert(Ele.cols() == V.cols()+1 &&
-      "AABB::find only makes sense for (d+1)-simplices");
-  const Scalar epsilon = igl::EPS<Scalar>();
-  // Check if outside bounding box
-  bool inside = m_box.contains(q.transpose());
-  if(!inside)
-  {
-    return std::vector<int>();
-  }
-  assert(m_primitive==-1 || (m_left == NULL && m_right == NULL));
-  if(is_leaf())
-  {
-    // Initialize to some value > -epsilon
-    Scalar a1=0,a2=0,a3=0,a4=0;
-    switch(DIM)
-    {
-      case 3:
-        {
-          // Barycentric coordinates
-          typedef Eigen::Matrix<Scalar,1,3> RowVector3S;
-          const RowVector3S V1 = V.row(Ele(m_primitive,0));
-          const RowVector3S V2 = V.row(Ele(m_primitive,1));
-          const RowVector3S V3 = V.row(Ele(m_primitive,2));
-          const RowVector3S V4 = V.row(Ele(m_primitive,3));
-          a1 = volume_single(V2,V4,V3,(RowVector3S)q);
-          a2 = volume_single(V1,V3,V4,(RowVector3S)q);
-          a3 = volume_single(V1,V4,V2,(RowVector3S)q);
-          a4 = volume_single(V1,V2,V3,(RowVector3S)q);
-          break;
-        }
-      case 2:
-        {
-          // Barycentric coordinates
-          typedef Eigen::Matrix<Scalar,2,1> Vector2S;
-          const Vector2S V1 = V.row(Ele(m_primitive,0));
-          const Vector2S V2 = V.row(Ele(m_primitive,1));
-          const Vector2S V3 = V.row(Ele(m_primitive,2));
-          // Hack for now to keep templates simple. If becomes bottleneck
-          // consider using std::enable_if_t
-          const Vector2S q2 = q.head(2);
-          a1 = doublearea_single(V1,V2,q2);
-          a2 = doublearea_single(V2,V3,q2);
-          a3 = doublearea_single(V3,V1,q2);
-          break;
-        }
-      default:assert(false);
-    }
-    // Normalization is important for correcting sign
-    Scalar sum = a1+a2+a3+a4;
-    a1 /= sum;
-    a2 /= sum;
-    a3 /= sum;
-    a4 /= sum;
-    if(
-        a1>=-epsilon &&
-        a2>=-epsilon &&
-        a3>=-epsilon &&
-        a4>=-epsilon)
-    {
-      return std::vector<int>(1,m_primitive);
-    }else
-    {
-      return std::vector<int>();
-    }
-  }
-  std::vector<int> left = m_left->find(V,Ele,q,first);
-  if(first && !left.empty())
-  {
-    return left;
-  }
-  std::vector<int> right = m_right->find(V,Ele,q,first);
-  if(first)
-  {
-    return right;
-  }
-  left.insert(left.end(),right.begin(),right.end());
-  return left;
-}
-
-template <typename DerivedV, int DIM>
-IGL_INLINE int igl::AABB<DerivedV,DIM>::subtree_size() const
-{
-  // 1 for self
-  int n = 1;
-  int n_left = 0,n_right = 0;
-  if(m_left != NULL)
-  {
-    n_left = m_left->subtree_size();
-  }
-  if(m_right != NULL)
-  {
-    n_right = m_right->subtree_size();
-  }
-  n += 2*std::max(n_left,n_right);
-  return n;
-}
-
-
-template <typename DerivedV, int DIM>
-template <typename Derivedbb_mins, typename Derivedbb_maxs, typename Derivedelements>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::serialize(
-    Eigen::PlainObjectBase<Derivedbb_mins> & bb_mins,
-    Eigen::PlainObjectBase<Derivedbb_maxs> & bb_maxs,
-    Eigen::PlainObjectBase<Derivedelements> & elements,
-    const int i) const
-{
-  using namespace std;
-  using namespace Eigen;
-  // Calling for root then resize output
-  if(i==0)
-  {
-    const int m = subtree_size();
-    //cout<<"m: "<<m<<endl;
-    bb_mins.resize(m,DIM);
-    bb_maxs.resize(m,DIM);
-    elements.resize(m,1);
-  }
-  //cout<<i<<" ";
-  bb_mins.row(i) = m_box.min();
-  bb_maxs.row(i) = m_box.max();
-  elements(i) = m_primitive;
-  if(m_left != NULL)
-  {
-    m_left->serialize(bb_mins,bb_maxs,elements,2*i+1);
-  }
-  if(m_right != NULL)
-  {
-    m_right->serialize(bb_mins,bb_maxs,elements,2*i+2);
-  }
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
-igl::AABB<DerivedV,DIM>::squared_distance(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & p,
-  int & i,
-  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
-{
-  return squared_distance(V,Ele,p,std::numeric_limits<Scalar>::infinity(),i,c);
-}
-
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
-igl::AABB<DerivedV,DIM>::squared_distance(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & p,
-  Scalar low_sqr_d,
-  Scalar up_sqr_d,
-  int & i,
-  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
-{
-  using namespace Eigen;
-  using namespace std;
-  //assert(low_sqr_d <= up_sqr_d);
-  if(low_sqr_d > up_sqr_d)
-  {
-    return low_sqr_d;
-  }
-  Scalar sqr_d = up_sqr_d;
-  //assert(DIM == 3 && "Code has only been tested for DIM == 3");
-  assert((Ele.cols() == 3 || Ele.cols() == 2 || Ele.cols() == 1)
-    && "Code has only been tested for simplex sizes 3,2,1");
-
-  assert(m_primitive==-1 || (m_left == NULL && m_right == NULL));
-  if(is_leaf())
-  {
-    leaf_squared_distance(V,Ele,p,low_sqr_d,sqr_d,i,c);
-  }else
-  {
-    bool looked_left = false;
-    bool looked_right = false;
-    const auto & look_left = [&]()
-    {
-      int i_left;
-      RowVectorDIMS c_left = c;
-      Scalar sqr_d_left =
-        m_left->squared_distance(V,Ele,p,low_sqr_d,sqr_d,i_left,c_left);
-      this->set_min(p,sqr_d_left,i_left,c_left,sqr_d,i,c);
-      looked_left = true;
-    };
-    const auto & look_right = [&]()
-    {
-      int i_right;
-      RowVectorDIMS c_right = c;
-      Scalar sqr_d_right =
-        m_right->squared_distance(V,Ele,p,low_sqr_d,sqr_d,i_right,c_right);
-      this->set_min(p,sqr_d_right,i_right,c_right,sqr_d,i,c);
-      looked_right = true;
-    };
-
-    // must look left or right if in box
-    if(m_left->m_box.contains(p.transpose()))
-    {
-      look_left();
-    }
-    if(m_right->m_box.contains(p.transpose()))
-    {
-      look_right();
-    }
-    // if haven't looked left and could be less than current min, then look
-    Scalar left_up_sqr_d =
-      m_left->m_box.squaredExteriorDistance(p.transpose());
-    Scalar right_up_sqr_d =
-      m_right->m_box.squaredExteriorDistance(p.transpose());
-    if(left_up_sqr_d < right_up_sqr_d)
-    {
-      if(!looked_left && left_up_sqr_d<sqr_d)
-      {
-        look_left();
-      }
-      if( !looked_right && right_up_sqr_d<sqr_d)
-      {
-        look_right();
-      }
-    }else
-    {
-      if( !looked_right && right_up_sqr_d<sqr_d)
-      {
-        look_right();
-      }
-      if(!looked_left && left_up_sqr_d<sqr_d)
-      {
-        look_left();
-      }
-    }
-  }
-  return sqr_d;
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
-igl::AABB<DerivedV,DIM>::squared_distance(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & p,
-  Scalar up_sqr_d,
-  int & i,
-  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
-{
-  return squared_distance(V,Ele,p,0.0,up_sqr_d,i,c);
-}
-
-template <typename DerivedV, int DIM>
-template <
-  typename DerivedEle,
-  typename DerivedP,
-  typename DerivedsqrD,
-  typename DerivedI,
-  typename DerivedC>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const Eigen::MatrixBase<DerivedP> & P,
-  Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
-  Eigen::PlainObjectBase<DerivedI> & I,
-  Eigen::PlainObjectBase<DerivedC> & C) const
-{
-  assert(P.cols() == V.cols() && "cols in P should match dim of cols in V");
-  sqrD.resize(P.rows(),1);
-  I.resize(P.rows(),1);
-  C.resizeLike(P);
-  // O( #P * log #Ele ), where log #Ele is really the depth of this AABB
-  // hierarchy
-  //for(int p = 0;p<P.rows();p++)
-  igl::parallel_for(P.rows(),[&](int p)
-    {
-      RowVectorDIMS Pp = P.row(p), c;
-      int Ip;
-      sqrD(p) = squared_distance(V,Ele,Pp,Ip,c);
-      I(p) = Ip;
-      C.row(p).head(DIM) = c;
-    },
-    10000);
-}
-
-template <typename DerivedV, int DIM>
-template <
-  typename DerivedEle,
-  typename Derivedother_V,
-  typename Derivedother_Ele,
-  typename DerivedsqrD,
-  typename DerivedI,
-  typename DerivedC>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const AABB<Derivedother_V,DIM> & other,
-  const Eigen::MatrixBase<Derivedother_V> & other_V,
-  const Eigen::MatrixBase<Derivedother_Ele> & other_Ele,
-  Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
-  Eigen::PlainObjectBase<DerivedI> & I,
-  Eigen::PlainObjectBase<DerivedC> & C) const
-{
-  assert(other_Ele.cols() == 1 &&
-    "Only implemented for other as list of points");
-  assert(other_V.cols() == V.cols() && "other must match this dimension");
-  sqrD.setConstant(other_Ele.rows(),1,std::numeric_limits<double>::infinity());
-  I.resize(other_Ele.rows(),1);
-  C.resize(other_Ele.rows(),other_V.cols());
-  // All points in other_V currently think they need to check against root of
-  // this. The point of using another AABB is to quickly prune chunks of
-  // other_V so that most points just check some subtree of this.
-
-  // This holds a conservative estimate of max(sqr_D) where sqr_D is the
-  // current best minimum squared distance for all points in this subtree
-  double up_sqr_d = std::numeric_limits<double>::infinity();
-  squared_distance_helper(
-    V,Ele,&other,other_V,other_Ele,0,up_sqr_d,sqrD,I,C);
-}
-
-template <typename DerivedV, int DIM>
-template <
-  typename DerivedEle,
-  typename Derivedother_V,
-  typename Derivedother_Ele,
-  typename DerivedsqrD,
-  typename DerivedI,
-  typename DerivedC>
-IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
-  igl::AABB<DerivedV,DIM>::squared_distance_helper(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const AABB<Derivedother_V,DIM> * other,
-  const Eigen::MatrixBase<Derivedother_V> & other_V,
-  const Eigen::MatrixBase<Derivedother_Ele> & other_Ele,
-  const Scalar /*up_sqr_d*/,
-  Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
-  Eigen::PlainObjectBase<DerivedI> & I,
-  Eigen::PlainObjectBase<DerivedC> & C) const
-{
-  using namespace std;
-  using namespace Eigen;
-
-  // This implementation is a bit disappointing. There's no major speed up. Any
-  // performance gains seem to come from accidental cache coherency and
-  // diminish for larger "other" (the opposite of what was intended).
-
-  // Base case
-  if(other->is_leaf() && this->is_leaf())
-  {
-    Scalar sqr_d = sqrD(other->m_primitive);
-    int i = I(other->m_primitive);
-    RowVectorDIMS c = C.row(      other->m_primitive);
-    RowVectorDIMS p = other_V.row(other->m_primitive);
-    leaf_squared_distance(V,Ele,p,sqr_d,i,c);
-    sqrD( other->m_primitive) = sqr_d;
-    I(    other->m_primitive) = i;
-    C.row(other->m_primitive) = c;
-    //cout<<"leaf: "<<sqr_d<<endl;
-    //other->m_low_sqr_d = sqr_d;
-    return sqr_d;
-  }
-
-  if(other->is_leaf())
-  {
-    Scalar sqr_d = sqrD(other->m_primitive);
-    int i = I(other->m_primitive);
-    RowVectorDIMS c = C.row(      other->m_primitive);
-    RowVectorDIMS p = other_V.row(other->m_primitive);
-    sqr_d = squared_distance(V,Ele,p,sqr_d,i,c);
-    sqrD( other->m_primitive) = sqr_d;
-    I(    other->m_primitive) = i;
-    C.row(other->m_primitive) = c;
-    //other->m_low_sqr_d = sqr_d;
-    return sqr_d;
-  }
-
-  //// Exact minimum squared distance between arbitrary primitives inside this and
-  //// othre's bounding boxes
-  //const auto & min_squared_distance = [&](
-  //  const AABB<DerivedV,DIM> * A,
-  //  const AABB<Derivedother_V,DIM> * B)->Scalar
-  //{
-  //  return A->m_box.squaredExteriorDistance(B->m_box);
-  //};
-
-  if(this->is_leaf())
-  {
-    //if(min_squared_distance(this,other) < other->m_low_sqr_d)
-    if(true)
-    {
-      this->squared_distance_helper(
-        V,Ele,other->m_left,other_V,other_Ele,0,sqrD,I,C);
-      this->squared_distance_helper(
-        V,Ele,other->m_right,other_V,other_Ele,0,sqrD,I,C);
-    }else
-    {
-      // This is never reached...
-    }
-    //// we know other is not a leaf
-    //other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
-    return 0;
-  }
-
-  // FORCE DOWN TO OTHER LEAF EVAL
-  //if(min_squared_distance(this,other) < other->m_low_sqr_d)
-  if(true)
-  {
-    if(true)
-    {
-      this->squared_distance_helper(
-        V,Ele,other->m_left,other_V,other_Ele,0,sqrD,I,C);
-      this->squared_distance_helper(
-        V,Ele,other->m_right,other_V,other_Ele,0,sqrD,I,C);
-    }else // this direction never seems to be faster
-    {
-      this->m_left->squared_distance_helper(
-        V,Ele,other,other_V,other_Ele,0,sqrD,I,C);
-      this->m_right->squared_distance_helper(
-        V,Ele,other,other_V,other_Ele,0,sqrD,I,C);
-    }
-  }else
-  {
-    // this is never reached ... :-(
-  }
-  //// we know other is not a leaf
-  //other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
-
-  return 0;
-#if 0 // False
-
-  // _Very_ conservative approximation of maximum squared distance between
-  // primitives inside this and other's bounding boxes
-  const auto & max_squared_distance = [](
-    const AABB<DerivedV,DIM> * A,
-    const AABB<Derivedother_V,DIM> * B)->Scalar
-  {
-    AlignedBox<Scalar,DIM> combo = A->m_box;
-    combo.extend(B->m_box);
-    return combo.diagonal().squaredNorm();
-  };
-
-  //// other base-case
-  //if(other->is_leaf())
-  //{
-  //  double sqr_d = sqrD(other->m_primitive);
-  //  int i = I(other->m_primitive);
-  //  RowVectorDIMS c = C.row(m_primitive);
-  //  RowVectorDIMS p = other_V.row(m_primitive);
-  //  leaf_squared_distance(V,Ele,p,sqr_d,i,c);
-  //  sqrD(other->m_primitive) = sqr_d;
-  //  I(other->m_primitive) = i;
-  //  C.row(m_primitive) = c;
-  //  return;
-  //}
-  std::vector<const AABB<DerivedV,DIM> * > this_list;
-  if(this->is_leaf())
-  {
-    this_list.push_back(this);
-  }else
-  {
-    assert(this->m_left);
-    this_list.push_back(this->m_left);
-    assert(this->m_right);
-    this_list.push_back(this->m_right);
-  }
-  std::vector<AABB<Derivedother_V,DIM> *> other_list;
-  if(other->is_leaf())
-  {
-    other_list.push_back(other);
-  }else
-  {
-    assert(other->m_left);
-    other_list.push_back(other->m_left);
-    assert(other->m_right);
-    other_list.push_back(other->m_right);
-  }
-
-  //const std::function<Scalar(
-  //  const AABB<Derivedother_V,DIM> * other)
-  //    > low_sqr_d = [&sqrD,&low_sqr_d](const AABB<Derivedother_V,DIM> * other)->Scalar
-  //  {
-  //    if(other->is_leaf())
-  //    {
-  //      return sqrD(other->m_primitive);
-  //    }else
-  //    {
-  //      return std::max(low_sqr_d(other->m_left),low_sqr_d(other->m_right));
-  //    }
-  //  };
-
-  //// Potentially recurse on all pairs, if minimum distance is less than running
-  //// bound
-  //Eigen::Matrix<Scalar,Eigen::Dynamic,1> other_low_sqr_d =
-  //  Eigen::Matrix<Scalar,Eigen::Dynamic,1>::Constant(other_list.size(),1,up_sqr_d);
-  for(size_t child = 0;child<other_list.size();child++)
-  {
-    auto other_tree = other_list[child];
-
-    Eigen::Matrix<Scalar,Eigen::Dynamic,1> this_low_sqr_d(this_list.size(),1);
-    for(size_t t = 0;t<this_list.size();t++)
-    {
-      const auto this_tree = this_list[t];
-      this_low_sqr_d(t) = max_squared_distance(this_tree,other_tree);
-    }
-    if(this_list.size() ==2 &&
-      ( this_low_sqr_d(0) > this_low_sqr_d(1))
-      )
-    {
-      std::swap(this_list[0],this_list[1]);
-      //std::swap(this_low_sqr_d(0),this_low_sqr_d(1));
-    }
-    const Scalar sqr_d = this_low_sqr_d.minCoeff();
-
-
-    for(size_t t = 0;t<this_list.size();t++)
-    {
-      const auto this_tree = this_list[t];
-
-      //const auto mm = low_sqr_d(other_tree);
-      //const Scalar mc = other_low_sqr_d(child);
-      //assert(mc == mm);
-      // Only look left/right in this_list if can possible decrease somebody's
-      // distance in this_tree.
-      const Scalar min_this_other = min_squared_distance(this_tree,other_tree);
-      if(
-          min_this_other < sqr_d &&
-          min_this_other < other_tree->m_low_sqr_d)
-      {
-        //cout<<"before: "<<other_low_sqr_d(child)<<endl;
-        //other_low_sqr_d(child) = std::min(
-        //  other_low_sqr_d(child),
-        //  this_tree->squared_distance_helper(
-        //    V,Ele,other_tree,other_V,other_Ele,other_low_sqr_d(child),sqrD,I,C));
-        //cout<<"after: "<<other_low_sqr_d(child)<<endl;
-          this_tree->squared_distance_helper(
-            V,Ele,other_tree,other_V,other_Ele,0,sqrD,I,C);
-      }
-    }
-  }
-  //const Scalar ret = other_low_sqr_d.maxCoeff();
-  //const auto mm = low_sqr_d(other);
-  //assert(mm == ret);
-  //cout<<"non-leaf: "<<ret<<endl;
-  //return ret;
-  if(!other->is_leaf())
-  {
-    other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
-  }
-  return 0;
-#endif
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & p,
-  const Scalar low_sqr_d,
-  Scalar & sqr_d,
-  int & i,
-  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
-{
-  using namespace Eigen;
-  using namespace std;
-  if(low_sqr_d > sqr_d)
-  {
-    sqr_d = low_sqr_d;
-    return;
-  }
-  RowVectorDIMS c_candidate;
-  Scalar sqr_d_candidate;
-  igl::point_simplex_squared_distance<DIM>(
-    p,V,Ele,m_primitive,sqr_d_candidate,c_candidate);
-  set_min(p,sqr_d_candidate,m_primitive,c_candidate,sqr_d,i,c);
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & p,
-  Scalar & sqr_d,
-  int & i,
-  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
-{
-  return leaf_squared_distance(V,Ele,p,0,sqr_d,i,c);
-}
-
-
-template <typename DerivedV, int DIM>
-IGL_INLINE void igl::AABB<DerivedV,DIM>::set_min(
-  const RowVectorDIMS &
-#ifndef NDEBUG
-  p
-#endif
-  ,
-  const Scalar sqr_d_candidate,
-  const int i_candidate,
-  const RowVectorDIMS & c_candidate,
-  Scalar & sqr_d,
-  int & i,
-  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
-{
-#ifndef NDEBUG
-  //std::cout<<matlab_format(c_candidate,"c_candidate")<<std::endl;
-  //// This doesn't quite make sense to check with bounds
-  // const Scalar pc_norm = (p-c_candidate).squaredNorm();
-  // const Scalar diff = fabs(sqr_d_candidate - pc_norm);
-  // assert(diff<=1e-10 && "distance should match norm of difference");
-#endif
-  if(sqr_d_candidate < sqr_d)
-  {
-    i = i_candidate;
-    c = c_candidate;
-    sqr_d = sqr_d_candidate;
-  }
-}
-
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE bool
-igl::AABB<DerivedV,DIM>::intersect_ray(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & origin,
-  const RowVectorDIMS & dir,
-  std::vector<igl::Hit> & hits) const
-{
-  hits.clear();
-  const Scalar t0 = 0;
-  const Scalar t1 = std::numeric_limits<Scalar>::infinity();
-  {
-    Scalar _1,_2;
-    if(!ray_box_intersect(origin,dir,m_box,t0,t1,_1,_2))
-    {
-      return false;
-    }
-  }
-  if(this->is_leaf())
-  {
-    // Actually process elements
-    assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
-    // Cheesecake way of hitting element
-    bool ret = ray_mesh_intersect(origin,dir,V,Ele.row(m_primitive),hits);
-    // Since we only gave ray_mesh_intersect a single face, it will have set
-    // any hits to id=0. Set these to this primitive's id
-    for(auto & hit : hits)
-    {
-      hit.id = m_primitive;
-    }
-    return ret;
-  }
-  std::vector<igl::Hit> left_hits;
-  std::vector<igl::Hit> right_hits;
-  const bool left_ret = m_left->intersect_ray(V,Ele,origin,dir,left_hits);
-  const bool right_ret = m_right->intersect_ray(V,Ele,origin,dir,right_hits);
-  hits.insert(hits.end(),left_hits.begin(),left_hits.end());
-  hits.insert(hits.end(),right_hits.begin(),right_hits.end());
-  return left_ret || right_ret;
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE bool
-igl::AABB<DerivedV,DIM>::intersect_ray(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & origin,
-  const RowVectorDIMS & dir,
-  igl::Hit & hit) const
-{
-#if false
-  // BFS
-  std::queue<const AABB *> Q;
-  // Or DFS
-  //std::stack<const AABB *> Q;
-  Q.push(this);
-  bool any_hit = false;
-  hit.t = std::numeric_limits<Scalar>::infinity();
-  while(!Q.empty())
-  {
-    const AABB * tree = Q.front();
-    //const AABB * tree = Q.top();
-    Q.pop();
-    {
-      Scalar _1,_2;
-      if(!ray_box_intersect(
-        origin,dir,tree->m_box,Scalar(0),Scalar(hit.t),_1,_2))
-      {
-        continue;
-      }
-    }
-    if(tree->is_leaf())
-    {
-      // Actually process elements
-      assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
-      igl::Hit leaf_hit;
-      if(
-        ray_mesh_intersect(origin,dir,V,Ele.row(tree->m_primitive),leaf_hit)&&
-        leaf_hit.t < hit.t)
-      {
-        // correct the id
-        leaf_hit.id = tree->m_primitive;
-        hit = leaf_hit;
-      }
-      continue;
-    }
-    // Add children to queue
-    Q.push(tree->m_left);
-    Q.push(tree->m_right);
-  }
-  return any_hit;
-#else
-  // DFS
-  return intersect_ray(
-    V,Ele,origin,dir,std::numeric_limits<Scalar>::infinity(),hit);
-#endif
-}
-
-template <typename DerivedV, int DIM>
-template <typename DerivedEle>
-IGL_INLINE bool
-igl::AABB<DerivedV,DIM>::intersect_ray(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedEle> & Ele,
-  const RowVectorDIMS & origin,
-  const RowVectorDIMS & dir,
-  const Scalar _min_t,
-  igl::Hit & hit) const
-{
-  //// Naive, slow
-  //std::vector<igl::Hit> hits;
-  //intersect_ray(V,Ele,origin,dir,hits);
-  //if(hits.size() > 0)
-  //{
-  //  hit = hits.front();
-  //  return true;
-  //}else
-  //{
-  //  return false;
-  //}
-  Scalar min_t = _min_t;
-  const Scalar t0 = 0;
-  {
-    Scalar _1,_2;
-    if(!ray_box_intersect(origin,dir,m_box,t0,min_t,_1,_2))
-    {
-      return false;
-    }
-  }
-  if(this->is_leaf())
-  {
-    // Actually process elements
-    assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
-    // Cheesecake way of hitting element
-    bool ret = ray_mesh_intersect(origin,dir,V,Ele.row(m_primitive),hit);
-    hit.id = m_primitive;
-    return ret;
-  }
-
-  // Doesn't seem like smartly choosing left before/after right makes a
-  // differnce
-  igl::Hit left_hit;
-  igl::Hit right_hit;
-  bool left_ret = m_left->intersect_ray(V,Ele,origin,dir,min_t,left_hit);
-  if(left_ret && left_hit.t<min_t)
-  {
-    // It's scary that this line doesn't seem to matter....
-    min_t = left_hit.t;
-    hit = left_hit;
-    left_ret = true;
-  }else
-  {
-    left_ret = false;
-  }
-  bool right_ret = m_right->intersect_ray(V,Ele,origin,dir,min_t,right_hit);
-  if(right_ret && right_hit.t<min_t)
-  {
-    min_t = right_hit.t;
-    hit = right_hit;
-    right_ret = true;
-  }else
-  {
-    right_ret = false;
-  }
-  return left_ret || right_ret;
-}
-
-// This is a bullshit template because AABB annoyingly needs templates for bad
-// combinations of 3D V with DIM=2 AABB
-//
-// _Define_ as a no-op rather than monkeying around with the proper code above
-//
-// Meanwhile, GCC seems to have a bug. Let's see if GCC likes using explicit
-// namespace block instead. https://stackoverflow.com/a/25594681/148668
-namespace igl
-{
-  template<> template<> IGL_INLINE float AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
-  template<> template<> IGL_INLINE float igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 2, 1, 1, 2> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
-  template<> template<> IGL_INLINE void igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 2>::init (Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&) { assert(false);};
-  template<> template<> IGL_INLINE double AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
-  template<> template<> IGL_INLINE double igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, double, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
-  template<> template<> IGL_INLINE void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 2>::init (Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&) { assert(false);};
-  template<> template<> IGL_INLINE void igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 2>::init(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&) {assert(false);};
-  template<> template<> IGL_INLINE float igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 2>::squared_distance(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<float, 1, 2, 1, 1, 2> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template bool igl::AABB<Eigen::Matrix<float, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<float, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, 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, 3, 1, -1, 3> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template bool igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, igl::Hit&) const;
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
-template double igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
-template float igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
-template float igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
-template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
-template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, bool) const;
-template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<int, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, 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> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
-template void igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
-template void igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
-#ifdef WIN32
-template void igl::AABB<class Eigen::Matrix<double,-1,-1,0,-1,-1>,2>::squared_distance<class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,3,0,-1,3> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > &)const;
-template void igl::AABB<class Eigen::Matrix<double,-1,-1,0,-1,-1>,3>::squared_distance<class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,3,0,-1,3> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > &)const;
-#endif
-#endif

+ 0 - 130
include/igl/AtA_cached.cpp

@@ -1,130 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2017 Daniele Panozzo <[email protected]>
-//
-// 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/.
-#include "AtA_cached.h"
-
-#include <iostream>
-#include <vector>
-#include <utility>
-
-template <typename Scalar>
-IGL_INLINE void igl::AtA_cached_precompute(
-    const Eigen::SparseMatrix<Scalar>& A,
-    igl::AtA_cached_data& data,
-    Eigen::SparseMatrix<Scalar>& AtA)
-{
-  // 1 Compute At (this could be avoided, but performance-wise it will not make a difference)
-  std::vector<std::vector<int> > Col_RowPtr;
-  std::vector<std::vector<int> > Col_IndexPtr;
-
-  Col_RowPtr.resize(A.cols());
-  Col_IndexPtr.resize(A.cols());
-
-  for (unsigned k=0; k<A.outerSize(); ++k)
-  {
-    unsigned outer_index = *(A.outerIndexPtr()+k);
-    unsigned next_outer_index = (k+1 == A.outerSize()) ? A.nonZeros() : *(A.outerIndexPtr()+k+1); 
-    
-    for (unsigned l=outer_index; l<next_outer_index; ++l)
-    {
-      int col = k;
-      int row = *(A.innerIndexPtr()+l);
-      int value_index = l;
-      assert(col < A.cols());
-      assert(col >= 0);
-      assert(row < A.rows());
-      assert(row >= 0);
-      assert(value_index >= 0);
-      assert(value_index < A.nonZeros());
-
-      Col_RowPtr[col].push_back(row);
-      Col_IndexPtr[col].push_back(value_index);
-    }
-  }
-
-  Eigen::SparseMatrix<Scalar> At = A.transpose();
-  At.makeCompressed();
-  AtA = At * A;
-  AtA.makeCompressed();
-
-  assert(AtA.isCompressed());
-
-  // If weights are not provided, use 1
-  if (data.W.size() == 0)
-    data.W = Eigen::VectorXd::Ones(A.rows());
-  assert(data.W.size() == A.rows());
-
-  data.I_outer.reserve(AtA.outerSize());
-  data.I_row.reserve(2*AtA.nonZeros());
-  data.I_col.reserve(2*AtA.nonZeros());
-  data.I_w.reserve(2*AtA.nonZeros());
-
-  // 2 Construct the rules
-  for (unsigned k=0; k<AtA.outerSize(); ++k)
-  {
-    unsigned outer_index = *(AtA.outerIndexPtr()+k);
-    unsigned next_outer_index = (k+1 == AtA.outerSize()) ? AtA.nonZeros() : *(AtA.outerIndexPtr()+k+1); 
-    
-    for (unsigned l=outer_index; l<next_outer_index; ++l)
-    {
-      int col = k;
-      int row = *(AtA.innerIndexPtr()+l);
-      int value_index = l;
-      assert(col < AtA.cols());
-      assert(col >= 0);
-      assert(row < AtA.rows());
-      assert(row >= 0);
-      assert(value_index >= 0);
-      assert(value_index < AtA.nonZeros());
-
-      data.I_outer.push_back(data.I_row.size());
-
-      // Find correspondences
-      unsigned i=0;
-      unsigned j=0;
-      while (i<Col_RowPtr[row].size() && j<Col_RowPtr[col].size())
-      {
-          if (Col_RowPtr[row][i] == Col_RowPtr[col][j])
-          {
-            data.I_row.push_back(Col_IndexPtr[row][i]);
-            data.I_col.push_back(Col_IndexPtr[col][j]);
-            data.I_w.push_back(Col_RowPtr[col][j]);
-            ++i;
-            ++j;
-          } else 
-          if (Col_RowPtr[row][i] > Col_RowPtr[col][j])
-            ++j;
-          else
-            ++i;
-
-      }
-    }
-  }
-  data.I_outer.push_back(data.I_row.size()); // makes it more efficient to iterate later on
-
-  igl::AtA_cached(A,data,AtA);
-}
-
-template <typename Scalar>
-IGL_INLINE void igl::AtA_cached(
-    const Eigen::SparseMatrix<Scalar>& A,
-    const igl::AtA_cached_data& data,
-    Eigen::SparseMatrix<Scalar>& AtA)
-{
-  for (unsigned i=0; i<data.I_outer.size()-1; ++i)
-  {
-    *(AtA.valuePtr() + i) = 0;
-    for (unsigned j=data.I_outer[i]; j<data.I_outer[i+1]; ++j)
-      *(AtA.valuePtr() + i) += *(A.valuePtr() + data.I_row[j]) * data.W[data.I_w[j]] * *(A.valuePtr() + data.I_col[j]);
-  }
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-template void igl::AtA_cached<double>(Eigen::SparseMatrix<double, 0, int> const&, igl::AtA_cached_data const&, Eigen::SparseMatrix<double, 0, int>&);
-template void igl::AtA_cached_precompute<double>(Eigen::SparseMatrix<double, 0, int> const&, igl::AtA_cached_data&, Eigen::SparseMatrix<double, 0, int>&);
-#endif

+ 0 - 30
include/igl/EPS.cpp

@@ -1,30 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "EPS.h"
-
-template <> IGL_INLINE float igl::EPS()
-{
-  return igl::FLOAT_EPS;
-}
-template <> IGL_INLINE double igl::EPS()
-{
-  return igl::DOUBLE_EPS;
-}
-
-template <> IGL_INLINE float igl::EPS_SQ()
-{
-  return igl::FLOAT_EPS_SQ;
-}
-template <> IGL_INLINE double igl::EPS_SQ()
-{
-  return igl::DOUBLE_EPS_SQ;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#endif

+ 0 - 162
include/igl/HalfEdgeIterator.cpp

@@ -1,162 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2014 Daniele Panozzo <[email protected]>
-//
-// 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/.
-
-#include "HalfEdgeIterator.h"
-
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::HalfEdgeIterator(
-    const Eigen::MatrixBase<DerivedF>& _F,
-    const Eigen::MatrixBase<DerivedFF>& _FF,
-    const Eigen::MatrixBase<DerivedFFi>& _FFi,
-    int _fi,
-    int _ei,
-    bool _reverse
-)
-: fi(_fi), ei(_ei), reverse(_reverse), F(_F), FF(_FF), FFi(_FFi)
-{}
-
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE void igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::flipF()
-{
-  if (isBorder())
-    return;
-
-  int fin = (FF)(fi,ei);
-  int ein = (FFi)(fi,ei);
-
-  fi = fin;
-  ei = ein;
-  reverse = !reverse;
-}
-
-
-// Change Edge
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE void igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::flipE()
-{
-  if (!reverse)
-    ei = (ei+2)%3; // ei-1
-  else
-    ei = (ei+1)%3;
-
-  reverse = !reverse;
-}
-
-// Change Vertex
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE void igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::flipV()
-{
-  reverse = !reverse;
-}
-
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE bool igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::isBorder()
-{
-  return (FF)(fi,ei) == -1;
-}
-
-/*!
- * Returns the next edge skipping the border
- *      _________
- *     /\ c | b /\
- *    /  \  |  /  \
- *   / d  \ | / a  \
- *  /______\|/______\
- *          v
- * In this example, if a and d are of-border and the pos is iterating counterclockwise, this method iterate through the faces incident on vertex v,
- * producing the sequence a, b, c, d, a, b, c, ...
- */
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE bool igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::NextFE()
-{
-  if ( isBorder() ) // we are on a border
-  {
-    do
-    {
-      flipF();
-      flipE();
-    } while (!isBorder());
-    flipE();
-    return false;
-  }
-  else
-  {
-    flipF();
-    flipE();
-    return true;
-  }
-}
-
-// Get vertex index
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE int igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::Vi()
-{
-  assert(fi >= 0);
-  assert(fi < F.rows());
-  assert(ei >= 0);
-  assert(ei <= 2);
-
-  if (!reverse)
-    return (F)(fi,ei);
-  else
-    return (F)(fi,(ei+1)%3);
-}
-
-// Get face index
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE int igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::Fi()
-{
-  return fi;
-}
-
-// Get edge index
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE int igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::Ei()
-{
-  return ei;
-}
-
-
-template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
-IGL_INLINE bool igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::operator==(HalfEdgeIterator& p2)
-{
-  return
-      (
-          (fi == p2.fi) &&
-              (ei == p2.ei) &&
-              (reverse == p2.reverse) &&
-              (F   == p2.F) &&
-              (FF  == p2.FF) &&
-              (FFi == p2.FFi)
-      );
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template      igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::HalfEdgeIterator(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, int, int, bool);
-template igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::HalfEdgeIterator(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, bool);
-template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::NextFE();
-template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Ei();
-template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Ei();
-template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::Ei();
-template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::Fi();
-template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::NextFE();
-template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Vi();
-template      igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::HalfEdgeIterator(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, bool);
-template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Fi();
-template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::flipE();
-template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >::flipE();
-template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::flipF();
-template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >::flipF();
-template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::flipV();
-template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::operator==(igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template int igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Fi();
-template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::NextFE();
-template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >::isBorder();
-template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::isBorder();
-#endif

+ 0 - 497
include/igl/MshLoader.cpp

@@ -1,497 +0,0 @@
-// based on MSH reader from PyMesh 
-
-// Copyright (c) 2015 Qingnan Zhou <[email protected]>           
-// Copyright (C) 2020 Vladimir Fonov <[email protected]> 
-//
-// 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/. 
-
-#include "MshLoader.h"
-
-#include <cassert>
-#include <iostream>
-#include <sstream>
-#include <vector>
-
-#include <string.h>
-
-namespace igl {
-    // helper function
-    void inline _msh_eat_white_space(std::ifstream& fin) {
-        char next = fin.peek();
-        while (next == '\n' || next == ' ' || next == '\t' || next == '\r') {
-            fin.get();
-            next = fin.peek();
-        }
-    }
-}
-
-IGL_INLINE igl::MshLoader::MshLoader(const std::string &filename) {
-    std::ifstream fin(filename, std::ios::in | std::ios::binary);
-
-    if (!fin.is_open()) {
-        std::stringstream err_msg;
-        err_msg << "failed to open file \"" << filename << "\"";
-        throw std::ios_base::failure(err_msg.str());
-    }
-    // Parse header
-    std::string buf;
-    double version;
-    int type;
-    fin >> buf;
-    if (buf != "$MeshFormat") { throw std::runtime_error("Unexpected .msh format"); }
-
-    fin >> version >> type >> m_data_size;
-    m_binary = (type == 1);
-    if(version>2.2 || version<2.0)
-    {
-        // probably unsupported version
-        std::stringstream err_msg;
-        err_msg << "Error: Unsupported file version:" << version << std::endl;
-        throw std::runtime_error(err_msg.str());
-
-    }
-    // Some sanity check.
-    if (m_data_size != 8) {
-        std::stringstream err_msg;
-        err_msg << "Error: data size must be 8 bytes." << std::endl;
-        throw std::runtime_error(err_msg.str());
-    }
-    if (sizeof(int) != 4) {
-        std::stringstream err_msg;
-        err_msg << "Error: code must be compiled with int size 4 bytes." << std::endl;
-        throw std::runtime_error(err_msg.str());
-    }
-
-    // Read in extra info from binary header.
-    if (m_binary) {
-        int one;
-        igl::_msh_eat_white_space(fin);
-        fin.read(reinterpret_cast<char*>(&one), sizeof(int));
-        if (one != 1) {
-            std::stringstream err_msg;
-                err_msg << "Binary msh file " << filename
-                << " is saved with different endianness than this machine."
-                << std::endl;
-            throw std::runtime_error(err_msg.str());
-        }
-    }
-
-    fin >> buf;
-    if (buf != "$EndMeshFormat") 
-    { 
-        std::stringstream err_msg;
-        err_msg << "Unexpected contents in the file header." << std::endl;
-        throw std::runtime_error(err_msg.str());
-    }
-
-    while (!fin.eof()) {
-        buf.clear();
-        fin >> buf;
-        if (buf == "$Nodes") {
-            parse_nodes(fin);
-            fin >> buf;
-            if (buf != "$EndNodes") { throw std::runtime_error("Unexpected tag"); }
-        } else if (buf == "$Elements") {
-            parse_elements(fin);
-            fin >> buf;
-            if (buf != "$EndElements") { throw std::runtime_error("Unexpected tag"); }
-        } else if (buf == "$NodeData") {
-            parse_node_field(fin);
-            fin >> buf;
-            if (buf != "$EndNodeData") { throw std::runtime_error("Unexpected tag"); }
-        } else if (buf == "$ElementData") {
-            parse_element_field(fin);
-            fin >> buf;
-            if (buf != "$EndElementData") { throw std::runtime_error("Unexpected tag"); }
-        } else if (fin.eof()) {
-            break;
-        } else {
-            parse_unknown_field(fin, buf);
-        }
-    }
-    fin.close();
-}
-
-IGL_INLINE void igl::MshLoader::parse_nodes(std::ifstream& fin) {
-    size_t num_nodes;
-    fin >> num_nodes;
-    m_nodes.resize(num_nodes*3);
-
-    if (m_binary) {
-		size_t stride = (4+3*m_data_size);
-        size_t num_bytes = stride * num_nodes;
-        char* data = new char[num_bytes];
-        igl::_msh_eat_white_space(fin);
-        fin.read(data, num_bytes);
-
-        for (size_t i=0; i<num_nodes; i++) {
-            int node_idx;
-			memcpy(&node_idx, data+i*stride, sizeof(int));
-			node_idx-=1;
-			// directly move into vector storage
-			// this works only when m_data_size==sizeof(Float)==sizeof(double)
-			memcpy(&m_nodes[node_idx*3], data+i*stride + 4, m_data_size*3);
-        }
-        delete [] data;
-    } else {
-        int node_idx;
-        for (size_t i=0; i<num_nodes; i++) {
-            fin >> node_idx;
-            node_idx -= 1;
-            // here it's 3D node explicitly
-            fin >> m_nodes[node_idx*3]
-                >> m_nodes[node_idx*3+1]
-                >> m_nodes[node_idx*3+2];
-        }
-    }
-}
-
-IGL_INLINE void igl::MshLoader::parse_elements(std::ifstream& fin) {
-    m_elements_tags.resize(2); //hardcoded to have 2 tags
-    size_t num_elements;
-    fin >> num_elements;
-
-    size_t nodes_per_element;
-
-    if (m_binary) {
-        igl::_msh_eat_white_space(fin);
-        int elem_read = 0;
-        while (elem_read < num_elements) {
-            // Parse element header.
-            int elem_type, num_elems, num_tags;
-            fin.read((char*)&elem_type, sizeof(int));
-            fin.read((char*)&num_elems, sizeof(int));
-            fin.read((char*)&num_tags,  sizeof(int));
-            nodes_per_element = num_nodes_per_elem_type(elem_type);
-
-            // store node info
-            for (size_t i=0; i<num_elems; i++) {
-                int elem_idx;
-
-                // all elements in the segment share the same elem_type and number of nodes per element
-                m_elements_types.push_back(elem_type);
-                m_elements_lengths.push_back(nodes_per_element);
-
-                fin.read((char*)&elem_idx, sizeof(int));
-                elem_idx -= 1;
-                m_elements_ids.push_back(elem_idx);
-
-                // read first two tags
-                for (size_t j=0; j<num_tags; j++) {
-                    int tag;
-                    fin.read((char*)&tag, sizeof(int));
-                    if(j<2) m_elements_tags[j].push_back(tag);
-                }
-
-                for (size_t j=num_tags; j<2; j++) 
-                    m_elements_tags[j].push_back(-1); // fill up tags if less then 2
-
-                m_elements_nodes_idx.push_back(m_elements.size());
-                // Element values.
-                for (size_t j=0; j<nodes_per_element; j++) {
-                    int idx;
-                    fin.read((char*)&idx, sizeof(int));
-                    
-                    m_elements.push_back(idx-1);
-                }
-            }
-            elem_read += num_elems;
-        }
-    } else {
-        for (size_t i=0; i<num_elements; i++) {
-            // Parse per element header
-            int elem_num, elem_type, num_tags;
-            fin >> elem_num >> elem_type >> num_tags;
-
-            // read tags.
-            for (size_t j=0; j<num_tags; j++) {
-                int tag;
-                fin >> tag;
-                if(j<2) m_elements_tags[j].push_back(tag);
-            }
-            for (size_t j=num_tags; j<2; j++) 
-                m_elements_tags[j].push_back(-1); // fill up tags if less then 2
-            
-            nodes_per_element = num_nodes_per_elem_type(elem_type);
-            m_elements_types.push_back(elem_type);
-            m_elements_lengths.push_back(nodes_per_element);
-
-            elem_num -= 1;
-            m_elements_ids.push_back(elem_num);
-            m_elements_nodes_idx.push_back(m_elements.size());
-            // Parse node idx.
-            for (size_t j=0; j<nodes_per_element; j++) {
-                int idx;
-                fin >> idx;
-                m_elements.push_back(idx-1); // msh index starts from 1.
-            }
-        }
-    }
-    // debug
-    assert(m_elements_types.size()   == m_elements_ids.size());
-    assert(m_elements_tags[0].size() == m_elements_ids.size());
-    assert(m_elements_tags[1].size() == m_elements_ids.size());
-    assert(m_elements_lengths.size() == m_elements_ids.size());
-}
-
-IGL_INLINE void igl::MshLoader::parse_node_field( std::ifstream& fin ) {
-    size_t num_string_tags;
-    size_t num_real_tags;
-    size_t num_int_tags;
-
-    fin >> num_string_tags;
-    std::vector<std::string> str_tags(num_string_tags);
-
-    for (size_t i=0; i<num_string_tags; i++) {
-        igl::_msh_eat_white_space(fin);
-        if (fin.peek() == '\"') {
-            // Handle field name between quotes.
-            char buf[128];
-            fin.get(); // remove the quote at the beginning.
-            fin.getline(buf, 128, '\"');
-            str_tags[i] = std::string(buf);
-        } else {
-            fin >> str_tags[i];
-        }
-    }
-
-    fin >> num_real_tags;
-    std::vector<Float> real_tags(num_real_tags);
-    for (size_t i=0; i<num_real_tags; i++)
-        fin >> real_tags[i];
-
-    fin >> num_int_tags;
-    std::vector<int> int_tags(num_int_tags);
-    for (size_t i=0; i<num_int_tags; i++)
-        fin >> int_tags[i];
-
-    if (num_string_tags <= 0 || num_int_tags <= 2) {
-        throw std::runtime_error("Unexpected number of field tags");
-    }
-    std::string fieldname = str_tags[0];
-    int num_components    = int_tags[1];
-    int num_entries       = int_tags[2];
-
-    std::vector<Float> field( num_entries*num_components );
-
-    if (m_binary) {
-        size_t num_bytes = (num_components * m_data_size + 4) * num_entries;
-        char* data = new char[num_bytes];
-        igl::_msh_eat_white_space(fin);
-        fin.read(data, num_bytes);
-        for (size_t i=0; i<num_entries; i++) {
-			int node_idx;
-			memcpy(&node_idx,&data[i*(4+num_components*m_data_size)],4);
-			
-            if(node_idx<1) throw std::runtime_error("Negative or zero index");
-            node_idx -= 1;
-			
-            if(node_idx>=num_entries) throw std::runtime_error("Index too big");
-            size_t base_idx = i*(4+num_components*m_data_size) + 4;
-            // TODO: make this work when m_data_size != sizeof(double) ?
-			memcpy(&field[node_idx*num_components], &data[base_idx], num_components*m_data_size);
-        }
-        delete [] data;
-    } else {
-        int node_idx;
-        for (size_t i=0; i<num_entries; i++) {
-            fin >> node_idx;
-            node_idx -= 1;
-            for (size_t j=0; j<num_components; j++) {
-                fin >> field[node_idx*num_components+j];
-            }
-        }
-    }
-    
-    m_node_fields_names.push_back(fieldname);
-    m_node_fields.push_back(field);
-    m_node_fields_components.push_back(num_components);
-}
-
-IGL_INLINE void igl::MshLoader::parse_element_field(std::ifstream& fin) {
-    size_t num_string_tags;
-    size_t num_real_tags;
-    size_t num_int_tags;
-
-    fin >> num_string_tags;
-    std::vector<std::string> str_tags(num_string_tags);
-    for (size_t i=0; i<num_string_tags; i++) {
-        igl::_msh_eat_white_space(fin);
-        if (fin.peek() == '\"') {
-            // Handle field name between quoates.
-            char buf[128];
-            fin.get(); // remove the quote at the beginning.
-            fin.getline(buf, 128, '\"');
-            str_tags[i] = buf;
-        } else {
-            fin >> str_tags[i];
-        }
-    }
-
-    fin >> num_real_tags;
-    std::vector<Float> real_tags(num_real_tags);
-    for (size_t i=0; i<num_real_tags; i++)
-        fin >> real_tags[i];
-
-    fin >> num_int_tags;
-    std::vector<int> int_tags(num_int_tags);
-    for (size_t i=0; i<num_int_tags; i++)
-        fin >> int_tags[i];
-
-    if (num_string_tags <= 0 || num_int_tags <= 2) {
-        throw std::runtime_error("Invalid file format");
-    }
-    std::string fieldname = str_tags[0];
-    int num_components = int_tags[1];
-    int num_entries = int_tags[2];
-    std::vector<Float> field(num_entries*num_components);
-
-    if (m_binary) {
-        size_t num_bytes = (num_components * m_data_size + 4) * num_entries;
-        char* data = new char[num_bytes];
-        igl::_msh_eat_white_space(fin);
-        fin.read(data, num_bytes);
-        for (int i=0; i<num_entries; i++) {
-			int elem_idx;
-			// works with sizeof(int)==4
-			memcpy(&elem_idx, &data[i*(4+num_components*m_data_size)],4);
-            elem_idx -= 1;
-			
-			// directly copy data into vector storage space
-			memcpy(&field[elem_idx*num_components], &data[i*(4+num_components*m_data_size) + 4], m_data_size*num_components);
-        }
-        delete [] data;
-    } else {
-        int elem_idx;
-        for (size_t i=0; i<num_entries; i++) {
-            fin >> elem_idx;
-            elem_idx -= 1;
-            for (size_t j=0; j<num_components; j++) {
-                fin >> field[elem_idx*num_components+j];
-            }
-        }
-    }
-    m_element_fields_names.push_back(fieldname);
-    m_element_fields.push_back(field);
-    m_element_fields_components.push_back(num_components);
-}
-
-IGL_INLINE void igl::MshLoader::parse_unknown_field(std::ifstream& fin,
-        const std::string& fieldname) {
-    std::cerr << "Warning: \"" << fieldname << "\" not supported yet.  Ignored." << std::endl;
-    std::string endmark = fieldname.substr(0,1) + "End"
-        + fieldname.substr(1,fieldname.size()-1);
-
-    std::string buf("");
-    while (buf != endmark && !fin.eof()) {
-        fin >> buf;
-    }
-}
-
-IGL_INLINE int igl::MshLoader::num_nodes_per_elem_type(int elem_type) {
-    int nodes_per_element = 0;
-    switch (elem_type) {
-        case ELEMENT_LINE:         // 2-node line
-            nodes_per_element = 2; 
-            break;
-        case ELEMENT_TRI:
-            nodes_per_element = 3; // 3-node triangle
-            break;
-        case ELEMENT_QUAD:
-            nodes_per_element = 4; // 5-node quad
-            break;
-        case ELEMENT_TET:
-            nodes_per_element = 4; // 4-node tetrahedra
-            break;
-        case ELEMENT_HEX:          // 8-node hexahedron
-            nodes_per_element = 8; 
-            break;
-        case ELEMENT_PRISM:        // 6-node prism
-            nodes_per_element = 6; 
-            break;
-        case ELEMENT_LINE_2ND_ORDER: 
-            nodes_per_element = 3;
-            break;
-        case ELEMENT_TRI_2ND_ORDER: 
-            nodes_per_element = 6;
-            break;
-        case ELEMENT_QUAD_2ND_ORDER: 
-            nodes_per_element = 9;
-            break;
-        case ELEMENT_TET_2ND_ORDER: 
-            nodes_per_element = 10;
-            break;
-        case ELEMENT_HEX_2ND_ORDER: 
-            nodes_per_element = 27;
-            break;
-        case ELEMENT_PRISM_2ND_ORDER: 
-            nodes_per_element = 18;
-            break;
-        case ELEMENT_PYRAMID_2ND_ORDER: 
-            nodes_per_element = 14;
-            break;
-        case ELEMENT_POINT:        // 1-node point
-            nodes_per_element = 1; 
-            break;
-        default:
-            std::stringstream err_msg;
-                err_msg << "Element type (" << elem_type << ") is not supported yet."
-                << std::endl;
-            throw std::runtime_error(err_msg.str());
-    }
-    return nodes_per_element;
-}
-
-
-IGL_INLINE bool igl::MshLoader::is_element_map_identity() const
-{
-    for(int i=0;i<m_elements_ids.size();i++) {
-        int id=m_elements_ids[i];
-        if (id!=i) return false;
-    }
-    return true;
-}
-
-
-IGL_INLINE void igl::MshLoader::index_structures(int tag_column)
-{
-    //cleanup
-    m_structure_index.clear();
-    m_structures.clear();
-    m_structure_length.clear();
-
-    //index structure tags
-    for(auto i=0; i != m_elements_tags[tag_column].size(); ++i )
-    {
-        m_structure_index.insert(
-            std::pair<msh_struct,int>(
-                msh_struct( m_elements_tags[tag_column][i], 
-                            m_elements_types[i]), i)
-            );
-    }
-
-    // identify unique structures 
-    std::vector<StructIndex::value_type> _unique_structs;
-    std::unique_copy(std::begin(m_structure_index), 
-                     std::end(m_structure_index), 
-                     std::back_inserter(_unique_structs),
-                     [](const StructIndex::value_type &c1, const StructIndex::value_type &c2)
-                     { return c1.first == c2.first; });
-
-    std::for_each( _unique_structs.begin(), _unique_structs.end(), 
-        [this](const StructIndex::value_type &n){ this->m_structures.push_back(n.first); });
-
-    for(auto t = m_structures.begin(); t != m_structures.end(); ++t)
-    {
-        // identify all elements corresponding to this tag
-        auto structure_range = m_structure_index.equal_range( *t );
-        int cnt=0;
-
-        for(auto i=structure_range.first; i!=structure_range.second; i++)
-            cnt++;
-
-        m_structure_length.insert( std::pair<msh_struct,int>( *t, cnt));
-    }
-}

+ 0 - 347
include/igl/MshSaver.cpp

@@ -1,347 +0,0 @@
-// based on MSH writer from PyMesh 
-
-// Copyright (c) 2015 Qingnan Zhou <[email protected]>           
-// Copyright (C) 2020 Vladimir Fonov <[email protected]> 
-//
-// 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/. 
-
-#include "MshSaver.h"
-
-#include <cassert>
-#include <iostream>
-#include <sstream>
-#include <exception>
-
-
-IGL_INLINE igl::MshSaver::MshSaver(const std::string& filename, bool binary) :
-    m_binary(binary), m_num_nodes(0), m_num_elements(0) {
-        if (!m_binary) {
-            fout.open(filename.c_str(), std::fstream::out);
-        } else {
-            fout.open(filename.c_str(), std::fstream::binary);
-        }
-        if (!fout) {
-            std::stringstream err_msg;
-            err_msg << "Error opening " << filename << " to write msh file." << std::endl;
-            throw std::ios_base::failure(err_msg.str());
-        }
-}
-
-IGL_INLINE igl::MshSaver::~MshSaver() {
-    fout.close();
-}
-
-IGL_INLINE void igl::MshSaver::save_mesh(
-    const FloatVector& nodes, 
-    const IndexVector& elements, 
-    const IntVector& element_lengths,
-    const IntVector& element_types,
-    const IntVector& element_tags
-     ) {
-
-    save_header();
-
-    save_nodes(nodes);
-
-    save_elements(elements, element_lengths, element_types, element_tags );
-}
-
-IGL_INLINE void igl::MshSaver::save_header() {
-    if (!m_binary) {
-        fout << "$MeshFormat" << std::endl;
-        fout << "2.2 0 " << sizeof(double) << std::endl;
-        fout << "$EndMeshFormat" << std::endl;
-        fout.precision(17);
-    } else {
-        fout << "$MeshFormat" << std::endl;
-        fout << "2.2 1 " << sizeof(double) << std::endl;
-        int one = 1;
-        fout.write((char*)&one, sizeof(int));
-        fout << "\n$EndMeshFormat" << std::endl;
-    }
-    fout.flush();
-}
-
-IGL_INLINE void igl::MshSaver::save_nodes(const FloatVector& nodes) {
-    // Save nodes.
-    // 3D hadrcoded
-    m_num_nodes = nodes.size() / 3;
-    fout << "$Nodes" << std::endl;
-    fout << m_num_nodes << std::endl;
-    if (!m_binary) {
-        for (size_t i=0; i<nodes.size(); i+=3) {
-            //const VectorF& v = nodes.segment(i,m_dim);
-            int node_idx = i/3 + 1;
-            fout << node_idx << " " << nodes[i] << " " << nodes[i+1] << " " << nodes[i+2] << std::endl;
-        }
-    } else {
-        for (size_t i=0; i<nodes.size(); i+=3) {
-            //const VectorF& v = nodes.segment(i,m_dim);
-            int node_idx = i/3 + 1;
-            fout.write((const char*)&node_idx, sizeof(int));
-            fout.write((const char*)&nodes[i], sizeof(Float)*3);
-        }
-    }
-    fout << "$EndNodes" << std::endl;
-    fout.flush();
-}
-
-IGL_INLINE void igl::MshSaver::save_elements(const IndexVector& elements, 
-            const IntVector& element_lengths,
-            const IntVector& element_types,
-            const IntVector& element_tags) 
-    {
-
-    m_num_elements = element_tags.size();
-    assert(element_lengths.size() == element_types.size() );
-    assert(element_lengths.size() == element_tags.size() );
-    // TODO: sum up all lengths
-    // Save elements.
-    // node inxes are 1-based
-    fout << "$Elements" << std::endl;
-    fout << m_num_elements << std::endl;
-
-    if (m_num_elements > 0) {
-        //int elem_type = el_type;
-        int num_elems = m_num_elements;
-        //int tags = 0;
-        if (!m_binary) {
-            size_t el_ptr=0;
-            for (size_t i=0;i<m_num_elements;++i) {
-                
-                int elem_num = (int) i + 1;
-                ///VectorI elem = elements.segment(i, nodes_per_element) + VectorI::Ones(nodes_per_element);
-                // hardcoded: duplicate tags (I don't know why)
-                fout << elem_num << " " << element_types[i] << " " << 2 << " "<< element_tags[i] << " "<< element_tags[i] << " ";
-                for (size_t j=0; j<element_lengths[i]; j++) {
-                    fout << elements[el_ptr + j] + 1 << " ";
-                }
-                fout << std::endl;
-                el_ptr+=element_lengths[i];
-            }
-        } else {
-            size_t el_ptr=0,i=0;
-            while(i<m_num_elements) {
-
-                // write elements in consistent chunks
-                // TODO: refactor this code to be able to specify different elements
-                // more effeciently 
-
-                int elem_type=-1;
-                int elem_len=-1;
-                size_t j=i;
-                for(;j<m_num_elements;++j)
-                {
-                    if( elem_type==-1 ) 
-                    {
-                        elem_type=element_types[j];
-                        elem_len=element_lengths[j];
-                    } else if( elem_type!=element_types[j] || 
-                               elem_len!=element_lengths[j]) {
-                        break; // found the edge of the segment
-                    }
-                }
-
-                //hardcoded: 2 tags
-                int num_elems=j-i, num_tags=2;
-
-                fout.write((const char*)& elem_type, sizeof(int));
-                fout.write((const char*)& num_elems, sizeof(int));
-                fout.write((const char*)& num_tags,  sizeof(int));
-
-                for(int k=0;k<num_elems; ++k,++i){
-                    int elem_num = (int )i + 1;
-                    fout.write((const char*)&elem_num, sizeof(int));
-
-                    // HACK: hardcoded 2 tags
-                    fout.write((const char*)& element_tags[i], sizeof(int));
-                    fout.write((const char*)& element_tags[i], sizeof(int));
-
-                    for (size_t e=0; e<elem_len; e++) {
-                        int _elem = static_cast<int>( elements[el_ptr + e] )+1;
-                        fout.write((const char*)&_elem, sizeof(int));
-                    }
-                    el_ptr+=elem_len;
-                }
-            }
-        }
-    }
-    fout << "$EndElements" << std::endl;
-    fout.flush();
-}
-
-IGL_INLINE void igl::MshSaver::save_scalar_field(const std::string& fieldname, const FloatVector& field) {
-    assert(field.size() == m_num_nodes);
-    fout << "$NodeData" << std::endl;
-    fout << "1" << std::endl; // num string tags.
-    fout << "\"" << fieldname << "\"" << std::endl;
-    fout << "1" << std::endl; // num real tags.
-    fout << "0.0" << std::endl; // time value.
-    fout << "3" << std::endl; // num int tags.
-    fout << "0" << std::endl; // the time step
-    fout << "1" << std::endl; // 1-component scalar field.
-    fout << m_num_nodes << std::endl; // number of nodes
-
-    if (m_binary) {
-        for (size_t i=0; i<m_num_nodes; i++) {
-            int node_idx = i+1;
-            fout.write((char*)&node_idx, sizeof(int));
-            fout.write((char*)&field[i], sizeof(Float));
-        }
-    } else {
-        for (size_t i=0; i<m_num_nodes; i++) {
-            int node_idx = i+1;
-            fout << node_idx << " " << field[i] << std::endl;
-        }
-    }
-    fout << "$EndNodeData" << std::endl;
-    fout.flush();
-}
-
-IGL_INLINE void igl::MshSaver::save_vector_field(const std::string& fieldname, const FloatVector& field) {
-    assert(field.size() == 3 * m_num_nodes);
-
-    fout << "$NodeData" << std::endl;
-    fout << "1" << std::endl; // num string tags.
-    fout << "\"" << fieldname << "\"" << std::endl;
-    fout << "1" << std::endl; // num real tags.
-    fout << "0.0" << std::endl; // time value.
-    fout << "3" << std::endl; // num int tags.
-    fout << "0" << std::endl; // the time step
-    fout << "3" << std::endl; // 3-component vector field.
-    fout << m_num_nodes << std::endl; // number of nodes
-
-    const Float zero = 0.0;
-    if (m_binary) {
-        for (size_t i=0; i<m_num_nodes; i++) {
-            int node_idx = i+1;
-            fout.write((const char*)&node_idx, sizeof(int));
-            fout.write((const char*)&field[i*3], sizeof(Float)*3);
-        }
-    } else {
-        for (size_t i=0; i<m_num_nodes; i++) {
-            int node_idx = i+1;
-                fout << node_idx
-                    << " " << field[i*3]
-                    << " " << field[i*3+1]
-                    << " " << field[i*3+2]
-                    << std::endl;
-        }
-    }
-    fout << "$EndNodeData" << std::endl;
-    fout.flush();
-}
-
-IGL_INLINE void igl::MshSaver::save_elem_scalar_field(const std::string& fieldname, const FloatVector& field) {
-    assert(field.size() == m_num_elements);
-    fout << "$ElementData" << std::endl;
-    fout << 1 << std::endl; // num string tags.
-    fout << "\"" << fieldname << "\"" << std::endl;
-    fout << "1" << std::endl; // num real tags.
-    fout << "0.0" << std::endl; // time value.
-    fout << "3" << std::endl; // num int tags.
-    fout << "0" << std::endl; // the time step
-    fout << "1" << std::endl; // 1-component scalar field.
-    fout << m_num_elements << std::endl; // number of elements
-
-    if (m_binary) {
-        for (size_t i=0; i<m_num_elements; i++) {
-            int elem_idx = i+1;
-            fout.write((const char*)&elem_idx, sizeof(int));
-            fout.write((const char*)&field[i], sizeof(Float));
-        }
-    } else {
-        for (size_t i=0; i<m_num_elements; i++) {
-            int elem_idx = i+1;
-            fout << elem_idx << " " << field[i] << std::endl;
-        }
-    }
-
-    fout << "$EndElementData" << std::endl;
-    fout.flush();
-}
-
-IGL_INLINE void igl::MshSaver::save_elem_vector_field(const std::string& fieldname, const FloatVector& field) {
-    assert(field.size() == m_num_elements * 3);
-    fout << "$ElementData" << std::endl;
-    fout << 1 << std::endl; // num string tags.
-    fout << "\"" << fieldname << "\"" << std::endl;
-    fout << "1" << std::endl; // num real tags.
-    fout << "0.0" << std::endl; // time value.
-    fout << "3" << std::endl; // num int tags.
-    fout << "0" << std::endl; // the time step
-    fout << "3" << std::endl; // 3-component vector field.
-    fout << m_num_elements << std::endl; // number of elements
-
-    const Float zero = 0.0;
-    if (m_binary) {
-        for (size_t i=0; i<m_num_elements; ++i) {
-            int elem_idx = i+1;
-            fout.write((const char*)&elem_idx, sizeof(int));
-            fout.write((const char*)&field[i*3], sizeof(Float) * 3);
-        }
-    } else {
-        for (size_t i=0; i<m_num_elements; ++i) {
-            int elem_idx = i+1;
-            fout << elem_idx
-                << " " << field[i*3]
-                << " " << field[i*3+1]
-                << " " << field[i*3+2]
-                << std::endl;
-        }
-    }
-
-    fout << "$EndElementData" << std::endl;
-    fout.flush();
-}
-
-
-IGL_INLINE void igl::MshSaver::save_elem_tensor_field(const std::string& fieldname, const FloatVector& field) {
-    assert(field.size() == m_num_elements * 3 * (3 + 1) / 2);
-    fout << "$ElementData" << std::endl;
-    fout << 1 << std::endl; // num string tags.
-    fout << "\"" << fieldname << "\"" << std::endl;
-    fout << "1" << std::endl; // num real tags.
-    fout << "0.0" << std::endl; // time value.
-    fout << "3" << std::endl; // num int tags.
-    fout << "0" << std::endl; // the time step
-    fout << "9" << std::endl; // 9-component tensor field.
-    fout << m_num_elements << std::endl; // number of elements
-
-    const Float zero = 0.0;
-    
-    if (m_binary) {
-        for (size_t i=0; i<m_num_elements; i++) {
-            int elem_idx = i+1;
-            fout.write((char*)&elem_idx, sizeof(int));
-            //const VectorF& val = field.segment(i*6, 6);
-            const Float* val = &field[i*6];
-            Float tensor[9] = {
-                val[0], val[5], val[4],
-                val[5], val[1], val[3],
-                val[4], val[3], val[2] };
-            fout.write((char*)tensor, sizeof(Float) * 9);
-        }
-    } else {
-        for (size_t i=0; i<m_num_elements; i++) {
-            int elem_idx = i+1;
-            const Float* val = &field[i*6];
-            fout << elem_idx
-                << " " << val[0]
-                << " " << val[5]
-                << " " << val[4]
-                << " " << val[5]
-                << " " << val[1]
-                << " " << val[3]
-                << " " << val[4]
-                << " " << val[3]
-                << " " << val[2]
-                << std::endl;
-        }
-    }
-
-    fout << "$EndElementData" << std::endl;
-    fout.flush();
-}

+ 0 - 52
include/igl/accumarray.cpp

@@ -1,52 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2018 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "accumarray.h"
-#include <cassert>
-
-template <
-  typename DerivedS,
-  typename DerivedV,
-  typename DerivedA
-  >
-void igl::accumarray(
-  const Eigen::MatrixBase<DerivedS> & S,
-  const Eigen::MatrixBase<DerivedV> & V,
-  Eigen::PlainObjectBase<DerivedA> & A)
-{
-  assert(V.size() == S.size() && "S and V should be same size");
-  if(S.size() == 0) { A.resize(0,1); return; }
-  A.setZero(S.maxCoeff()+1,1);
-  for(int s = 0;s<S.size();s++)
-  {
-    A(S(s)) += V(s);
-  }
-}
-
-template <
-  typename DerivedS,
-  typename DerivedA
-  >
-void igl::accumarray(
-  const Eigen::MatrixBase<DerivedS> & S,
-  const typename DerivedA::Scalar V,
-  Eigen::PlainObjectBase<DerivedA> & A)
-{
-  if(S.size() == 0) { A.resize(0,1); return; }
-  A.setZero(S.maxCoeff()+1,1);
-  for(int s = 0;s<S.size();s++)
-  {
-    A(S(s)) += V;
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::accumarray<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::accumarray<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 370
include/igl/active_set.cpp

@@ -1,370 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "active_set.h"
-#include "min_quad_with_fixed.h"
-#include "slice.h"
-#include "slice_into.h"
-#include "cat.h"
-//#include "matlab_format.h"
-
-#include <iostream>
-#include <limits>
-#include <algorithm>
-
-template <
-  typename AT,
-  typename DerivedB,
-  typename Derivedknown,
-  typename DerivedY,
-  typename AeqT,
-  typename DerivedBeq,
-  typename AieqT,
-  typename DerivedBieq,
-  typename Derivedlx,
-  typename Derivedux,
-  typename DerivedZ
-  >
-IGL_INLINE igl::SolverStatus igl::active_set(
-  const Eigen::SparseMatrix<AT>& A,
-  const Eigen::PlainObjectBase<DerivedB> & B,
-  const Eigen::PlainObjectBase<Derivedknown> & known,
-  const Eigen::PlainObjectBase<DerivedY> & Y,
-  const Eigen::SparseMatrix<AeqT>& Aeq,
-  const Eigen::PlainObjectBase<DerivedBeq> & Beq,
-  const Eigen::SparseMatrix<AieqT>& Aieq,
-  const Eigen::PlainObjectBase<DerivedBieq> & Bieq,
-  const Eigen::PlainObjectBase<Derivedlx> & p_lx,
-  const Eigen::PlainObjectBase<Derivedux> & p_ux,
-  const igl::active_set_params & params,
-  Eigen::PlainObjectBase<DerivedZ> & Z
-  )
-{
-//#define ACTIVE_SET_CPP_DEBUG
-#if defined(ACTIVE_SET_CPP_DEBUG) && !defined(_MSC_VER)
-#  warning "ACTIVE_SET_CPP_DEBUG"
-#endif
-  using namespace Eigen;
-  using namespace std;
-  SolverStatus ret = SOLVER_STATUS_ERROR;
-  const int n = A.rows();
-  assert(n == A.cols() && "A must be square");
-  // Discard const qualifiers
-  //if(B.size() == 0)
-  //{
-  //  B = DerivedB::Zero(n,1);
-  //}
-  assert(n == B.rows() && "B.rows() must match A.rows()");
-  assert(B.cols() == 1 && "B must be a column vector");
-  assert(Y.cols() == 1 && "Y must be a column vector");
-  assert((Aeq.size() == 0 && Beq.size() == 0) || Aeq.cols() == n);
-  assert((Aeq.size() == 0 && Beq.size() == 0) || Aeq.rows() == Beq.rows());
-  assert((Aeq.size() == 0 && Beq.size() == 0) || Beq.cols() == 1);
-  assert((Aieq.size() == 0 && Bieq.size() == 0) || Aieq.cols() == n);
-  assert((Aieq.size() == 0 && Bieq.size() == 0) || Aieq.rows() == Bieq.rows());
-  assert((Aieq.size() == 0 && Bieq.size() == 0) || Bieq.cols() == 1);
-  Eigen::Matrix<typename Derivedlx::Scalar,Eigen::Dynamic,1> lx;
-  Eigen::Matrix<typename Derivedux::Scalar,Eigen::Dynamic,1> ux;
-  if(p_lx.size() == 0)
-  {
-    lx = Derivedlx::Constant(
-      n,1,-numeric_limits<typename Derivedlx::Scalar>::max());
-  }else
-  {
-    lx = p_lx;
-  }
-  if(p_ux.size() == 0)
-  {
-    ux = Derivedux::Constant(
-      n,1,numeric_limits<typename Derivedux::Scalar>::max());
-  }else
-  {
-    ux = p_ux;
-  }
-  assert(lx.rows() == n && "lx must have n rows");
-  assert(ux.rows() == n && "ux must have n rows");
-  assert(ux.cols() == 1 && "lx must be a column vector");
-  assert(lx.cols() == 1 && "ux must be a column vector");
-  assert((ux.array()-lx.array()).minCoeff() > 0 && "ux(i) must be > lx(i)");
-  if(Z.size() != 0)
-  {
-    // Initial guess should have correct size
-    assert(Z.rows() == n && "Z must have n rows");
-    assert(Z.cols() == 1 && "Z must be a column vector");
-  }
-  assert(known.cols() == 1 && "known must be a column vector");
-  // Number of knowns
-  const int nk = known.size();
-
-  // Initialize active sets
-  typedef int BOOL;
-#define TRUE 1
-#define FALSE 0
-  Matrix<BOOL,Dynamic,1> as_lx = Matrix<BOOL,Dynamic,1>::Constant(n,1,FALSE);
-  Matrix<BOOL,Dynamic,1> as_ux = Matrix<BOOL,Dynamic,1>::Constant(n,1,FALSE);
-  Matrix<BOOL,Dynamic,1> as_ieq = Matrix<BOOL,Dynamic,1>::Constant(Aieq.rows(),1,FALSE);
-
-  // Keep track of previous Z for comparison
-  DerivedZ old_Z;
-  old_Z = DerivedZ::Constant(
-      n,1,numeric_limits<typename DerivedZ::Scalar>::max());
-
-  int iter = 0;
-  while(true)
-  {
-#ifdef ACTIVE_SET_CPP_DEBUG
-    cout<<"Iteration: "<<iter<<":"<<endl;
-    cout<<"  pre"<<endl;
-#endif
-    // FIND BREACHES OF CONSTRAINTS
-    int new_as_lx = 0;
-    int new_as_ux = 0;
-    int new_as_ieq = 0;
-    if(Z.size() > 0)
-    {
-      for(int z = 0;z < n;z++)
-      {
-        if(Z(z) < lx(z))
-        {
-          new_as_lx += (as_lx(z)?0:1);
-          //new_as_lx++;
-          as_lx(z) = TRUE;
-        }
-        if(Z(z) > ux(z))
-        {
-          new_as_ux += (as_ux(z)?0:1);
-          //new_as_ux++;
-          as_ux(z) = TRUE;
-        }
-      }
-      if(Aieq.rows() > 0)
-      {
-        DerivedZ AieqZ;
-        AieqZ = Aieq*Z;
-        for(int a = 0;a<Aieq.rows();a++)
-        {
-          if(AieqZ(a) > Bieq(a))
-          {
-            new_as_ieq += (as_ieq(a)?0:1);
-            as_ieq(a) = TRUE;
-          }
-        }
-      }
-#ifdef ACTIVE_SET_CPP_DEBUG
-      cout<<"  new_as_lx: "<<new_as_lx<<endl;
-      cout<<"  new_as_ux: "<<new_as_ux<<endl;
-#endif
-      const double diff = (Z-old_Z).squaredNorm();
-#ifdef ACTIVE_SET_CPP_DEBUG
-      cout<<"diff: "<<diff<<endl;
-#endif
-      if(diff < params.solution_diff_threshold)
-      {
-        ret = SOLVER_STATUS_CONVERGED;
-        break;
-      }
-      old_Z = Z;
-    }
-
-    const int as_lx_count = std::count(as_lx.data(),as_lx.data()+n,TRUE);
-    const int as_ux_count = std::count(as_ux.data(),as_ux.data()+n,TRUE);
-    const int as_ieq_count =
-      std::count(as_ieq.data(),as_ieq.data()+as_ieq.size(),TRUE);
-#ifndef NDEBUG
-    {
-      int count = 0;
-      for(int a = 0;a<as_ieq.size();a++)
-      {
-        if(as_ieq(a))
-        {
-          assert(as_ieq(a) == TRUE);
-          count++;
-        }
-      }
-      assert(as_ieq_count == count);
-    }
-#endif
-
-    // PREPARE FIXED VALUES
-    Derivedknown known_i;
-    known_i.resize(nk + as_lx_count + as_ux_count,1);
-    DerivedY Y_i;
-    Y_i.resize(nk + as_lx_count + as_ux_count,1);
-    {
-      known_i.block(0,0,known.rows(),known.cols()) = known;
-      Y_i.block(0,0,Y.rows(),Y.cols()) = Y;
-      int k = nk;
-      // Then all lx
-      for(int z = 0;z < n;z++)
-      {
-        if(as_lx(z))
-        {
-          known_i(k) = z;
-          Y_i(k) = lx(z);
-          k++;
-        }
-      }
-      // Finally all ux
-      for(int z = 0;z < n;z++)
-      {
-        if(as_ux(z))
-        {
-          known_i(k) = z;
-          Y_i(k) = ux(z);
-          k++;
-        }
-      }
-      assert(k==Y_i.size());
-      assert(k==known_i.size());
-    }
-    //cout<<matlab_format((known_i.array()+1).eval(),"known_i")<<endl;
-    // PREPARE EQUALITY CONSTRAINTS
-    Eigen::Matrix<typename DerivedY::Scalar, Eigen::Dynamic, 1> as_ieq_list(as_ieq_count,1);
-    // Gather active constraints and resp. rhss
-    DerivedBeq Beq_i;
-    Beq_i.resize(Beq.rows()+as_ieq_count,1);
-    Beq_i.head(Beq.rows()) = Beq;
-    {
-      int k =0;
-      for(int a=0;a<as_ieq.size();a++)
-      {
-        if(as_ieq(a))
-        {
-          assert(k<as_ieq_list.size());
-          as_ieq_list(k)=a;
-          Beq_i(Beq.rows()+k,0) = Bieq(k,0);
-          k++;
-        }
-      }
-      assert(k == as_ieq_count);
-    }
-    // extract active constraint rows
-    SparseMatrix<AeqT> Aeq_i,Aieq_i;
-    slice(Aieq,as_ieq_list,1,Aieq_i);
-    // Append to equality constraints
-    cat(1,Aeq,Aieq_i,Aeq_i);
-
-
-    min_quad_with_fixed_data<AT> data;
-#ifndef NDEBUG
-    {
-      // NO DUPES!
-      Matrix<BOOL,Dynamic,1> fixed = Matrix<BOOL,Dynamic,1>::Constant(n,1,FALSE);
-      for(int k = 0;k<known_i.size();k++)
-      {
-        assert(!fixed[known_i(k)]);
-        fixed[known_i(k)] = TRUE;
-      }
-    }
-#endif
-
-    DerivedZ sol;
-    if(known_i.size() == A.rows())
-    {
-      // Everything's fixed?
-#ifdef ACTIVE_SET_CPP_DEBUG
-      cout<<"  everything's fixed."<<endl;
-#endif
-      Z.resize(A.rows(),Y_i.cols());
-      slice_into(Y_i,known_i,1,Z);
-      sol.resize(0,Y_i.cols());
-      assert(Aeq_i.rows() == 0 && "All fixed but linearly constrained");
-    }else
-    {
-#ifdef ACTIVE_SET_CPP_DEBUG
-      cout<<"  min_quad_with_fixed_precompute"<<endl;
-#endif
-      if(!min_quad_with_fixed_precompute(A,known_i,Aeq_i,params.Auu_pd,data))
-      {
-        cerr<<"Error: min_quad_with_fixed precomputation failed."<<endl;
-        if(iter > 0 && Aeq_i.rows() > Aeq.rows())
-        {
-          cerr<<"  *Are you sure rows of [Aeq;Aieq] are linearly independent?*"<<
-            endl;
-        }
-        ret = SOLVER_STATUS_ERROR;
-        break;
-      }
-#ifdef ACTIVE_SET_CPP_DEBUG
-      cout<<"  min_quad_with_fixed_solve"<<endl;
-#endif
-      if(!min_quad_with_fixed_solve(data,B,Y_i,Beq_i,Z,sol))
-      {
-        cerr<<"Error: min_quad_with_fixed solve failed."<<endl;
-        ret = SOLVER_STATUS_ERROR;
-        break;
-      }
-      //cout<<matlab_format((Aeq*Z-Beq).eval(),"cr")<<endl;
-      //cout<<matlab_format(Z,"Z")<<endl;
-#ifdef ACTIVE_SET_CPP_DEBUG
-      cout<<"  post"<<endl;
-#endif
-      // Computing Lagrange multipliers needs to be adjusted slightly if A is not symmetric
-      assert(data.Auu_sym);
-    }
-
-    // Compute Lagrange multiplier values for known_i
-    SparseMatrix<AT> Ak;
-    // Slow
-    slice(A,known_i,1,Ak);
-    DerivedB Bk;
-    slice(B,known_i,Bk);
-    MatrixXd Lambda_known_i = -(0.5*Ak*Z + 0.5*Bk);
-    // reverse the lambda values for lx
-    Lambda_known_i.block(nk,0,as_lx_count,1) =
-      (-1*Lambda_known_i.block(nk,0,as_lx_count,1)).eval();
-
-    // Extract Lagrange multipliers for Aieq_i (always at back of sol)
-    VectorXd Lambda_Aieq_i(Aieq_i.rows(),1);
-    for(int l = 0;l<Aieq_i.rows();l++)
-    {
-      Lambda_Aieq_i(Aieq_i.rows()-1-l) = sol(sol.rows()-1-l);
-    }
-
-    // Remove from active set
-    for(int l = 0;l<as_lx_count;l++)
-    {
-      if(Lambda_known_i(nk + l) < params.inactive_threshold)
-      {
-        as_lx(known_i(nk + l)) = FALSE;
-      }
-    }
-    for(int u = 0;u<as_ux_count;u++)
-    {
-      if(Lambda_known_i(nk + as_lx_count + u) <
-        params.inactive_threshold)
-      {
-        as_ux(known_i(nk + as_lx_count + u)) = FALSE;
-      }
-    }
-    for(int a = 0;a<as_ieq_count;a++)
-    {
-      if(Lambda_Aieq_i(a) < params.inactive_threshold)
-      {
-        as_ieq(int(as_ieq_list(a))) = FALSE;
-      }
-    }
-
-    iter++;
-    //cout<<iter<<endl;
-    if(params.max_iter>0 && iter>=params.max_iter)
-    {
-      ret = SOLVER_STATUS_MAX_ITER;
-      break;
-    }
-
-  }
-
-  return ret;
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template igl::SolverStatus igl::active_set<double, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, igl::active_set_params const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-template igl::SolverStatus igl::active_set<double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, igl::active_set_params const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 180
include/igl/adjacency_list.cpp

@@ -1,180 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "adjacency_list.h"
-
-#include "verbose.h"
-#include <algorithm>
-
-template <typename Index, typename IndexVector>
-IGL_INLINE void igl::adjacency_list(
-    const Eigen::MatrixBase<Index>  & F,
-    std::vector<std::vector<IndexVector> >& A,
-    bool sorted)
-{
-  A.clear(); 
-  A.resize(F.maxCoeff()+1);
-  
-  // Loop over faces
-  for(int i = 0;i<F.rows();i++)
-  {
-    // Loop over this face
-    for(int j = 0;j<F.cols();j++)
-    {
-      // Get indices of edge: s --> d
-      int s = F(i,j);
-      int d = F(i,(j+1)%F.cols());
-      A.at(s).push_back(d);
-      A.at(d).push_back(s);
-    }
-  }
-  
-  // Remove duplicates
-  for(int i=0; i<(int)A.size();++i)
-  {
-    std::sort(A[i].begin(), A[i].end());
-    A[i].erase(std::unique(A[i].begin(), A[i].end()), A[i].end());
-  }
-  
-  // If needed, sort every VV
-  if (sorted)
-  {
-    // Loop over faces
-    
-    // for every vertex v store a set of ordered edges not incident to v that belongs to triangle incident on v.
-    std::vector<std::vector<std::vector<int> > > SR; 
-    SR.resize(A.size());
-    
-    for(int i = 0;i<F.rows();i++)
-    {
-      // Loop over this face
-      for(int j = 0;j<F.cols();j++)
-      {
-        // Get indices of edge: s --> d
-        int s = F(i,j);
-        int d = F(i,(j+1)%F.cols());
-        // Get index of opposing vertex v
-        int v = F(i,(j+2)%F.cols());
-        
-        std::vector<int> e(2);
-        e[0] = d;
-        e[1] = v;
-        SR[s].push_back(e);
-      }
-    }
-    
-    for(int v=0; v<(int)SR.size();++v)
-    {
-      std::vector<IndexVector>& vv = A.at(v);
-      std::vector<std::vector<int> >& sr = SR[v];
-      
-      std::vector<std::vector<int> > pn = sr;
-      
-      // Compute previous/next for every element in sr
-      for(int i=0;i<(int)sr.size();++i)
-      {
-        int a = sr[i][0];
-        int b = sr[i][1];
-        
-        // search for previous
-        int p = -1;
-        for(int j=0;j<(int)sr.size();++j)
-          if(sr[j][1] == a)
-            p = j;
-        pn[i][0] = p;
-        
-        // search for next
-        int n = -1;
-        for(int j=0;j<(int)sr.size();++j)
-          if(sr[j][0] == b)
-            n = j;
-        pn[i][1] = n;
-        
-      }
-      
-      // assume manifoldness (look for beginning of a single chain)
-      int c = 0;
-      for(int j=0; j<=(int)sr.size();++j)
-        if (pn[c][0] != -1)
-          c = pn[c][0];
-      
-      if (pn[c][0] == -1) // border case
-      {
-        // finally produce the new vv relation
-        for(int j=0; j<(int)sr.size();++j)
-        {
-          vv[j] = sr[c][0];
-          if (pn[c][1] != -1)
-            c = pn[c][1];
-        }
-        vv.back() = sr[c][1];
-      }
-      else
-      {
-        // finally produce the new vv relation
-        for(int j=0; j<(int)sr.size();++j)
-        {
-          vv[j] = sr[c][0];
-          
-          c = pn[c][1];
-        }
-      }
-    }
-  }
-}
-
-template <typename Index>
-IGL_INLINE void igl::adjacency_list(
-  const std::vector<std::vector<Index> > & F,
-  std::vector<std::vector<Index> >& A)
-{
-  A.clear();
-  
-  // Find maxCoeff
-  Index maxCoeff = 0;
-  for(const auto &vec : F)
-  {
-    for(int coeff : vec)
-    {
-      maxCoeff = std::max(coeff, maxCoeff);
-    }
-  }
-  A.resize(maxCoeff + 1);
-  
-  // Loop over faces
-  for(int i = 0;i<F.size();i++)
-  {
-    // Loop over this face
-    for(int j = 0;j<F[i].size();j++)
-    {
-      // Get indices of edge: s --> d
-      int s = F[i][j];
-      int d = F[i][(j+1)%F[i].size()];
-      A.at(s).push_back(d);
-      A.at(d).push_back(s);
-    }
-  }
-  
-  // Remove duplicates
-  for(int i=0; i<(int)A.size();++i)
-  {
-    std::sort(A[i].begin(), A[i].end());
-    A[i].erase(std::unique(A[i].begin(), A[i].end()), A[i].end());
-  }
-  
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::adjacency_list<Eigen::Matrix<int, -1, 2, 0, -1, 2>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, bool);
-// generated by autoexplicit.sh
-template void igl::adjacency_list<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, bool);
-template void igl::adjacency_list<Eigen::Matrix<int, -1, 3, 0, -1, 3>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, bool);
-template void igl::adjacency_list<class Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned int>(class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const &, class std::vector<class std::vector<unsigned int, class std::allocator<unsigned int> >, class std::allocator<class std::vector<unsigned int, class std::allocator<unsigned int> > > > &, bool);
-template void igl::adjacency_list<int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
-#endif

+ 0 - 125
include/igl/adjacency_matrix.cpp

@@ -1,125 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "adjacency_matrix.h"
-
-#include "verbose.h"
-
-#include <vector>
-
-template <typename DerivedF, typename T>
-IGL_INLINE void igl::adjacency_matrix(
-  const Eigen::MatrixBase<DerivedF> & F,
-  Eigen::SparseMatrix<T>& A)
-{
-  using namespace std;
-  using namespace Eigen;
-  typedef typename DerivedF::Scalar Index;
-
-  typedef Triplet<T> IJV;
-  vector<IJV > ijv;
-  ijv.reserve(F.size()*2);
-  // Loop over **simplex** (i.e., **not quad**)
-  for(int i = 0;i<F.rows();i++)
-  {
-    // Loop over this **simplex**
-    for(int j = 0;j<F.cols();j++)
-    for(int k = j+1;k<F.cols();k++)
-    {
-      // Get indices of edge: s --> d
-      Index s = F(i,j);
-      Index d = F(i,k);
-      ijv.push_back(IJV(s,d,1));
-      ijv.push_back(IJV(d,s,1));
-    }
-  }
-
-  const Index n = F.maxCoeff()+1;
-  A.resize(n,n);
-  switch(F.cols())
-  {
-    case 3:
-      A.reserve(6*(F.maxCoeff()+1));
-      break;
-    case 4:
-      A.reserve(26*(F.maxCoeff()+1));
-      break;
-  }
-  A.setFromTriplets(ijv.begin(),ijv.end());
-
-  // Force all non-zeros to be one
-
-  // Iterate over outside
-  for(int k=0; k<A.outerSize(); ++k)
-  {
-    // Iterate over inside
-    for(typename Eigen::SparseMatrix<T>::InnerIterator it (A,k); it; ++it)
-    {
-      assert(it.value() != 0);
-      A.coeffRef(it.row(),it.col()) = 1;
-    }
-  }
-}
-
-template <typename DerivedI, typename DerivedC, typename T>
-IGL_INLINE void igl::adjacency_matrix(
-  const Eigen::MatrixBase<DerivedI> & I,
-  const Eigen::MatrixBase<DerivedC> & C,
-  Eigen::SparseMatrix<T>& A)
-{
-  using namespace std;
-  using namespace Eigen;
-
-  typedef Triplet<T> IJV;
-  vector<IJV > ijv;
-  ijv.reserve(C(C.size()-1)*2);
-  typedef typename DerivedI::Scalar Index;
-  const Index n = I.maxCoeff()+1;
-  {
-    // loop over polygons
-    for(Index p = 0;p<C.size()-1;p++)
-    {
-      // number of edges
-      const Index np = C(p+1)-C(p);
-      // loop over edges
-      for(Index c = 0;c<np;c++)
-      {
-        const Index i = I(C(p)+c);
-        const Index j = I(C(p)+((c+1)%np));
-        ijv.emplace_back(i,j,1);
-        ijv.emplace_back(j,i,1);
-      }
-    }
-  }
-
-  A.resize(n,n);
-  A.reserve(6*n);
-  A.setFromTriplets(ijv.begin(),ijv.end());
-
-  // Force all non-zeros to be one
-
-  // Iterate over outside
-  for(int k=0; k<A.outerSize(); ++k)
-  {
-    // Iterate over inside
-    for(typename Eigen::SparseMatrix<T>::InnerIterator it (A,k); it; ++it)
-    {
-      assert(it.value() != 0);
-      A.coeffRef(it.row(),it.col()) = 1;
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::adjacency_matrix<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<int, 0, int>& );
-// generated by autoexplicit.sh
-template void igl::adjacency_matrix<Eigen::Matrix<int, -1, -1, 0, -1, -1>, bool>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<bool, 0, int>&);
-template void igl::adjacency_matrix<Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
-template void igl::adjacency_matrix<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<int, 0, int>&);
-template void igl::adjacency_matrix<Eigen::Matrix<int, -1, 3, 0, -1, 3>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::SparseMatrix<int, 0, int>&);
-#endif

+ 0 - 26
include/igl/all.cpp

@@ -1,26 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "all.h"
-#include "redux.h"
-
-
-template <typename AType, typename DerivedB>
-IGL_INLINE void igl::all(
-  const Eigen::SparseMatrix<AType> & A, 
-  const int dim,
-  Eigen::PlainObjectBase<DerivedB>& B)
-{
-  typedef typename DerivedB::Scalar Scalar;
-  igl::redux(A,dim,[](Scalar a, Scalar b){ return a && b!=0;},B);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#endif
-
-

+ 0 - 39
include/igl/all_pairs_distances.cpp

@@ -1,39 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "all_pairs_distances.h"
-#include <Eigen/Dense>
-
-template <typename Mat>
-IGL_INLINE void igl::all_pairs_distances(
-  const Mat & V,
-  const Mat & U,
-  const bool squared,
-  Mat & D)
-{
-  // dimension should be the same
-  assert(V.cols() == U.cols());
-  // resize output
-  D.resize(V.rows(),U.rows());
-  for(int i = 0;i<V.rows();i++)
-  {
-    for(int j=0;j<U.rows();j++)
-    {
-      D(i,j) = (V.row(i)-U.row(j)).squaredNorm();
-      if(!squared)
-      {
-        D(i,j) = sqrt(D(i,j));
-      }
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::all_pairs_distances<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, bool, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
-#endif

+ 0 - 139
include/igl/ambient_occlusion.cpp

@@ -1,139 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "ambient_occlusion.h"
-#include "random_dir.h"
-#include "ray_mesh_intersect.h"
-#include "EPS.h"
-#include "Hit.h"
-#include "parallel_for.h"
-#include <functional>
-#include <vector>
-#include <algorithm>
-
-template <
-  typename DerivedP,
-  typename DerivedN,
-  typename DerivedS >
-IGL_INLINE void igl::ambient_occlusion(
-  const std::function<
-    bool(
-      const Eigen::Vector3f&,
-      const Eigen::Vector3f&)
-      > & shoot_ray,
-  const Eigen::MatrixBase<DerivedP> & P,
-  const Eigen::MatrixBase<DerivedN> & N,
-  const int num_samples,
-  Eigen::PlainObjectBase<DerivedS> & S)
-{
-  using namespace Eigen;
-  const int n = P.rows();
-  // Resize output
-  S.resize(n,1);
-  // Embree seems to be parallel when constructing but not when tracing rays
-  const MatrixXf D = random_dir_stratified(num_samples).cast<float>();
-
-  const auto & inner = [&P,&N,&num_samples,&D,&S,&shoot_ray](const int p)
-  {
-    const Vector3f origin = P.row(p).template cast<float>();
-    const Vector3f normal = N.row(p).template cast<float>();
-    int num_hits = 0;
-    for(int s = 0;s<num_samples;s++)
-    {
-      Vector3f d = D.row(s);
-      if(d.dot(normal) < 0)
-      {
-        // reverse ray
-        d *= -1;
-      }
-      if(shoot_ray(origin,d))
-      {
-        num_hits++;
-      }
-    }
-    S(p) = (double)num_hits/(double)num_samples;
-  };
-  parallel_for(n,inner,1000);
-}
-
-template <
-  typename DerivedV,
-  int DIM,
-  typename DerivedF,
-  typename DerivedP,
-  typename DerivedN,
-  typename DerivedS >
-IGL_INLINE void igl::ambient_occlusion(
-  const igl::AABB<DerivedV,DIM> & aabb,
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedF> & F,
-  const Eigen::MatrixBase<DerivedP> & P,
-  const Eigen::MatrixBase<DerivedN> & N,
-  const int num_samples,
-  Eigen::PlainObjectBase<DerivedS> & S)
-{
-  const auto & shoot_ray = [&aabb,&V,&F](
-    const Eigen::Vector3f& _s,
-    const Eigen::Vector3f& dir)->bool
-  {
-    Eigen::Vector3f s = _s+1e-4*dir;
-    igl::Hit hit;
-    return aabb.intersect_ray(
-      V,
-      F,
-      s  .cast<typename DerivedV::Scalar>().eval(),
-      dir.cast<typename DerivedV::Scalar>().eval(),
-      hit);
-  };
-  return ambient_occlusion(shoot_ray,P,N,num_samples,S);
-
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedP,
-  typename DerivedN,
-  typename DerivedS >
-IGL_INLINE void igl::ambient_occlusion(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedF> & F,
-  const Eigen::MatrixBase<DerivedP> & P,
-  const Eigen::MatrixBase<DerivedN> & N,
-  const int num_samples,
-  Eigen::PlainObjectBase<DerivedS> & S)
-{
-  if(F.rows() < 100)
-  {
-    // Super naive
-    const auto & shoot_ray = [&V,&F](
-      const Eigen::Vector3f& _s,
-      const Eigen::Vector3f& dir)->bool
-    {
-      Eigen::Vector3f s = _s+1e-4*dir;
-      igl::Hit hit;
-      return ray_mesh_intersect(s,dir,V,F,hit);
-    };
-    return ambient_occlusion(shoot_ray,P,N,num_samples,S);
-  }
-  AABB<DerivedV,3> aabb;
-  aabb.init(V,F);
-  return ambient_occlusion(aabb,V,F,P,N,num_samples,S);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::ambient_occlusion<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-// generated by autoexplicit.sh
-template void igl::ambient_occlusion<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-// generated by autoexplicit.sh
-template void igl::ambient_occlusion<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-// generated by autoexplicit.sh
-template void igl::ambient_occlusion<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-template void igl::ambient_occlusion<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 20
include/igl/angular_distance.cpp

@@ -1,20 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "angular_distance.h"
-#include "EPS.h"
-#include "PI.h"
-IGL_INLINE double igl::angular_distance(
-  const Eigen::Quaterniond & A,
-  const Eigen::Quaterniond & B)
-{
-  assert(fabs(A.norm()-1)<FLOAT_EPS && "A should be unit norm");
-  assert(fabs(B.norm()-1)<FLOAT_EPS && "B should be unit norm");
-  //// acos is always in [0,2*pi)
-  //return acos(fabs(A.dot(B)));
-  return fmod(2.*acos(A.dot(B)),2.*PI);
-}

+ 0 - 26
include/igl/any.cpp

@@ -1,26 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "any.h"
-#include "redux.h"
-
-
-template <typename AType, typename DerivedB>
-IGL_INLINE void igl::any(
-  const Eigen::SparseMatrix<AType> & A, 
-  const int dim,
-  Eigen::PlainObjectBase<DerivedB>& B)
-{
-  typedef typename DerivedB::Scalar Scalar;
-  igl::redux(A,dim,[](Scalar a, Scalar b){ return a || b!=0;},B);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::any<bool, Eigen::Array<bool, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<bool, 0, int> const&, int, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 306
include/igl/arap.cpp

@@ -1,306 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "arap.h"
-#include "colon.h"
-#include "cotmatrix.h"
-#include "massmatrix.h"
-#include "group_sum_matrix.h"
-#include "covariance_scatter_matrix.h"
-#include "speye.h"
-#include "mode.h"
-#include "project_isometrically_to_plane.h"
-#include "slice.h"
-#include "arap_rhs.h"
-#include "repdiag.h"
-#include "columnize.h"
-#include "fit_rotations.h"
-#include <cassert>
-#include <iostream>
-
-template <typename Scalar>
-using MatrixXX = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Derivedb>
-IGL_INLINE bool igl::arap_precomputation(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedF> & F,
-  const int dim,
-  const Eigen::MatrixBase<Derivedb> & b,
-  ARAPData & data)
-{
-  using namespace std;
-  using namespace Eigen;
-  typedef typename DerivedV::Scalar Scalar;
-  typedef typename DerivedF::Scalar Integer;
-  // number of vertices
-  const int n = V.rows();
-  data.n = n;
-  assert((b.size() == 0 || b.maxCoeff() < n) && "b out of bounds");
-  assert((b.size() == 0 || b.minCoeff() >=0) && "b out of bounds");
-  // remember b
-  data.b = b;
-  //assert(F.cols() == 3 && "For now only triangles");
-  // dimension
-  //const int dim = V.cols();
-  assert((dim == 3 || dim ==2) && "dim should be 2 or 3");
-  data.dim = dim;
-  //assert(dim == 3 && "Only 3d supported");
-  // Defaults
-  data.f_ext = MatrixXd::Zero(n,data.dim);
-
-  assert(data.dim <= V.cols() && "solve dim should be <= embedding");
-  bool flat = (V.cols() - data.dim)==1;
-
-  MatrixXX<Scalar> plane_V;
-  MatrixXX<Integer> plane_F;
-  typedef SparseMatrix<Scalar> SparseMatrixS;
-  SparseMatrixS ref_map,ref_map_dim;
-  if(flat)
-  {
-    project_isometrically_to_plane(V,F,plane_V,plane_F,ref_map);
-    repdiag(ref_map,dim,ref_map_dim);
-  }
-  const MatrixXX<Scalar>& ref_V = (flat?plane_V:V);
-  const MatrixXX<Integer>& ref_F = (flat?plane_F:F);
-  SparseMatrixS L;
-  cotmatrix(V,F,L);
-
-  ARAPEnergyType eff_energy = data.energy;
-  if(eff_energy == ARAP_ENERGY_TYPE_DEFAULT)
-  {
-    switch(F.cols())
-    {
-      case 3:
-        if(data.dim == 3)
-        {
-          eff_energy = ARAP_ENERGY_TYPE_SPOKES_AND_RIMS;
-        }else
-        {
-          eff_energy = ARAP_ENERGY_TYPE_ELEMENTS;
-        }
-        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
-  covariance_scatter_matrix(ref_V,ref_F,eff_energy,data.CSM);
-  if(flat)
-  {
-    data.CSM = (data.CSM * ref_map_dim.transpose()).eval();
-  }
-  assert(data.CSM.cols() == V.rows()*data.dim);
-
-  // Get group sum scatter matrix, when applied sums all entries of the same
-  // group according to G
-  SparseMatrix<double> G_sum;
-  if(data.G.size() == 0)
-  {
-    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
-    if(eff_energy == ARAP_ENERGY_TYPE_ELEMENTS)
-    {
-      Eigen::Matrix<int,Eigen::Dynamic,1> GG;
-      MatrixXi GF(F.rows(),F.cols());
-      for(int j = 0;j<F.cols();j++)
-      {
-        Matrix<int,Eigen::Dynamic,1> GFj;
-        slice(data.G,F.col(j),GFj);
-        GF.col(j) = GFj;
-      }
-      mode<int>(GF,2,GG);
-      data.G=GG;
-    }
-    //printf("group_sum_matrix()\n");
-    group_sum_matrix(data.G,G_sum);
-  }
-  SparseMatrix<double> G_sum_dim;
-  repdiag(G_sum,data.dim,G_sum_dim);
-  assert(G_sum_dim.cols() == data.CSM.rows());
-  data.CSM = (G_sum_dim * data.CSM).eval();
-
-
-  arap_rhs(ref_V,ref_F,data.dim,eff_energy,data.K);
-  if(flat)
-  {
-    data.K = (ref_map_dim * data.K).eval();
-  }
-  assert(data.K.rows() == data.n*data.dim);
-
-  SparseMatrix<double> Q = (-L).eval();
-
-  if(data.with_dynamics)
-  {
-    const double h = data.h;
-    assert(h != 0);
-    SparseMatrix<double> M;
-    massmatrix(V,F,MASSMATRIX_TYPE_DEFAULT,data.M);
-    const double dw = (1./data.ym)*(h*h);
-    SparseMatrix<double> DQ = dw * 1./(h*h)*data.M;
-    Q += DQ;
-    // Dummy external forces
-    data.f_ext = MatrixXd::Zero(n,data.dim);
-    data.vel = MatrixXd::Zero(n,data.dim);
-  }
-
-  return min_quad_with_fixed_precompute(
-    Q,b,SparseMatrix<double>(),true,data.solver_data);
-}
-
-template <
-  typename Derivedbc,
-  typename DerivedU>
-IGL_INLINE bool igl::arap_solve(
-  const Eigen::MatrixBase<Derivedbc> & bc,
-  ARAPData & data,
-  Eigen::MatrixBase<DerivedU> & U)
-{
-  using namespace Eigen;
-  using namespace std;
-  assert(data.b.size() == bc.rows());
-  assert(U.size() != 0 && "U cannot be empty");
-  assert(U.cols() == data.dim && "U.cols() match data.dim");
-  if (bc.size() > 0) {
-    assert(bc.cols() == data.dim && "bc.cols() match data.dim");
-  }
-  const int n = data.n;
-  int iter = 0;
-  // changes each arap iteration
-  MatrixXd U_prev = U;
-  // doesn't change for fixed with_dynamics timestep
-  MatrixXd U0;
-  if(data.with_dynamics)
-  {
-    U0 = U_prev;
-  }
-  while(iter < data.max_iter)
-  {
-    U_prev = U;
-    // enforce boundary conditions exactly
-    for(int bi = 0;bi<bc.rows();bi++)
-    {
-      U.row(data.b(bi)) = bc.row(bi);
-    }
-
-    const auto & Udim = U.replicate(data.dim,1);
-    assert(U.cols() == data.dim);
-    // As if U.col(2) was 0
-    MatrixXd S = data.CSM * Udim;
-    // THIS NORMALIZATION IS IMPORTANT TO GET SINGLE PRECISION SVD CODE TO WORK
-    // CORRECTLY.
-    S /= S.array().abs().maxCoeff();
-
-    const int Rdim = data.dim;
-    MatrixXd R(Rdim,data.CSM.rows());
-    if(R.rows() == 2)
-    {
-      fit_rotations_planar(S,R);
-    }else
-    {
-      fit_rotations(S,true,R);
-//#ifdef __SSE__ // fit_rotations_SSE will convert to float if necessary
-//      fit_rotations_SSE(S,R);
-//#else
-//      fit_rotations(S,true,R);
-//#endif
-    }
-    //for(int k = 0;k<(data.CSM.rows()/dim);k++)
-    //{
-    //  R.block(0,dim*k,dim,dim) = MatrixXd::Identity(dim,dim);
-    //}
-
-
-    // Number of rotations: #vertices or #elements
-    int num_rots = data.K.cols()/Rdim/Rdim;
-    // distribute group rotations to vertices in each group
-    MatrixXd eff_R;
-    if(data.G.size() == 0)
-    {
-      // copy...
-      eff_R = R;
-    }else
-    {
-      eff_R.resize(Rdim,num_rots*Rdim);
-      for(int r = 0;r<num_rots;r++)
-      {
-        eff_R.block(0,Rdim*r,Rdim,Rdim) =
-          R.block(0,Rdim*data.G(r),Rdim,Rdim);
-      }
-    }
-
-    MatrixXd Dl;
-    if(data.with_dynamics)
-    {
-      assert(data.M.rows() == n &&
-        "No mass matrix. Call arap_precomputation if changing with_dynamics");
-      const double h = data.h;
-      assert(h != 0);
-      //Dl = 1./(h*h*h)*M*(-2.*V0 + Vm1) - fext;
-      // data.vel = (V0-Vm1)/h
-      // h*data.vel = (V0-Vm1)
-      // -h*data.vel = -V0+Vm1)
-      // -V0-h*data.vel = -2V0+Vm1
-      const double dw = (1./data.ym)*(h*h);
-      Dl = dw * (1./(h*h)*data.M*(-U0 - h*data.vel) - data.f_ext);
-    }
-
-    VectorXd Rcol;
-    columnize(eff_R,num_rots,2,Rcol);
-    VectorXd Bcol = -data.K * Rcol;
-    assert(Bcol.size() == data.n*data.dim);
-    for(int c = 0;c<data.dim;c++)
-    {
-      VectorXd Uc,Bc,bcc,Beq;
-      Bc = Bcol.block(c*n,0,n,1);
-      if(data.with_dynamics)
-      {
-        Bc += Dl.col(c);
-      }
-      if(bc.size()>0)
-      {
-        bcc = bc.col(c);
-      }
-      min_quad_with_fixed_solve(
-        data.solver_data,
-        Bc,bcc,Beq,
-        Uc);
-      U.col(c) = Uc;
-    }
-
-    iter++;
-  }
-  if(data.with_dynamics)
-  {
-    // Keep track of velocity for next time
-    data.vel = (U-U0)/data.h;
-  }
-
-  return true;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-template bool igl::arap_solve<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, igl::ARAPData&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template bool igl::arap_precomputation<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, igl::ARAPData&);
-#endif

+ 0 - 883
include/igl/arap_dof.cpp

@@ -1,883 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "arap_dof.h"
-
-#include "cotmatrix.h"
-#include "massmatrix.h"
-#include "speye.h"
-#include "repdiag.h"
-#include "repmat.h"
-#include "slice.h"
-#include "colon.h"
-#include "is_sparse.h"
-#include "mode.h"
-#include "is_symmetric.h"
-#include "group_sum_matrix.h"
-#include "arap_rhs.h"
-#include "covariance_scatter_matrix.h"
-#include "fit_rotations.h"
-
-#include "verbose.h"
-#include "print_ijv.h"
-
-//#include "MKLEigenInterface.h"
-#include "kkt_inverse.h"
-#include "get_seconds.h"
-#include "columnize.h"
-
-// defined if no early exit is supported, i.e., always take a fixed number of iterations
-#define IGL_ARAP_DOF_FIXED_ITERATIONS_COUNT
-
-// A careful derivation of this implementation is given in the corresponding
-// matlab function arap_dof.m
-template <typename LbsMatrixType, typename SSCALAR>
-IGL_INLINE bool igl::arap_dof_precomputation(
-  const Eigen::MatrixXd & V, 
-  const Eigen::MatrixXi & F,
-  const LbsMatrixType & M,
-  const Eigen::Matrix<int,Eigen::Dynamic,1> & G,
-  ArapDOFData<LbsMatrixType, SSCALAR> & data)
-{
-  using namespace Eigen;
-  typedef Matrix<SSCALAR, Dynamic, Dynamic> MatrixXS;
-  // number of mesh (domain) vertices
-  int n = V.rows();
-  // cache problem size
-  data.n = n;
-  // dimension of mesh
-  data.dim = V.cols();
-  assert(data.dim == M.rows()/n);
-  assert(data.dim*n == M.rows());
-  if(data.dim == 3)
-  {
-    // Check if z-coordinate is all zeros
-    if(V.col(2).minCoeff() == 0 && V.col(2).maxCoeff() == 0)
-    {
-      data.effective_dim = 2;
-    }
-  }else
-  {
-    data.effective_dim = data.dim;
-  }
-  // Number of handles
-  data.m = M.cols()/data.dim/(data.dim+1);
-  assert(data.m*data.dim*(data.dim+1) == M.cols());
-  //assert(m == C.rows());
-
-  //printf("n=%d; dim=%d; m=%d;\n",n,data.dim,data.m);
-
-  // Build cotangent laplacian
-  SparseMatrix<double> Lcot;
-  //printf("cotmatrix()\n");
-  cotmatrix(V,F,Lcot);
-  // Discrete laplacian (should be minus matlab version)
-  SparseMatrix<double> Lapl = -2.0*Lcot;
-#ifdef EXTREME_VERBOSE
-  cout<<"LaplIJV=["<<endl;print_ijv(Lapl,1);cout<<endl<<"];"<<
-    endl<<"Lapl=sparse(LaplIJV(:,1),LaplIJV(:,2),LaplIJV(:,3),"<<
-    Lapl.rows()<<","<<Lapl.cols()<<");"<<endl;
-#endif
-
-  // Get group sum scatter matrix, when applied sums all entries of the same
-  // group according to G
-  SparseMatrix<double> G_sum;
-  if(G.size() == 0)
-  {
-    speye(n,G_sum);
-  }else
-  {
-    // groups are defined per vertex, convert to per face using mode
-    Eigen::Matrix<int,Eigen::Dynamic,1> GG;
-    if(data.energy == ARAP_ENERGY_TYPE_ELEMENTS)
-    {
-      MatrixXi GF(F.rows(),F.cols());
-      for(int j = 0;j<F.cols();j++)
-      {
-        Matrix<int,Eigen::Dynamic,1> GFj;
-        slice(G,F.col(j),GFj);
-        GF.col(j) = GFj;
-      }
-      mode<int>(GF,2,GG);
-    }else
-    {
-      GG=G;
-    }
-    //printf("group_sum_matrix()\n");
-    group_sum_matrix(GG,G_sum);
-  }
-
-#ifdef EXTREME_VERBOSE
-  cout<<"G_sumIJV=["<<endl;print_ijv(G_sum,1);cout<<endl<<"];"<<
-    endl<<"G_sum=sparse(G_sumIJV(:,1),G_sumIJV(:,2),G_sumIJV(:,3),"<<
-    G_sum.rows()<<","<<G_sum.cols()<<");"<<endl;
-#endif
-
-  // Get covariance scatter matrix, when applied collects the covariance matrices
-  // used to fit rotations to during optimization
-  SparseMatrix<double> CSM;
-  //printf("covariance_scatter_matrix()\n");
-  covariance_scatter_matrix(V,F,data.energy,CSM);
-#ifdef EXTREME_VERBOSE
-  cout<<"CSMIJV=["<<endl;print_ijv(CSM,1);cout<<endl<<"];"<<
-    endl<<"CSM=sparse(CSMIJV(:,1),CSMIJV(:,2),CSMIJV(:,3),"<<
-    CSM.rows()<<","<<CSM.cols()<<");"<<endl;
-#endif
-  
-
-  // Build the covariance matrix "constructor". This is a set of *scatter*
-  // matrices that when multiplied on the right by column of the transformation
-  // matrix entries (the degrees of freedom) L, we get a stack of dim by 1
-  // covariance matrix column, with a column in the stack for each rotation
-  // *group*. The output is a list of matrices because we construct each column
-  // in the stack of covariance matrices with an independent matrix-vector
-  // multiplication.
-  //
-  // We want to build S which is a stack of dim by dim covariance matrices.
-  // Thus S is dim*g by dim, where dim is the number of dimensions and g is the
-  // number of groups. We can precompute dim matrices CSM_M such that column i
-  // in S is computed as S(:,i) = CSM_M{i} * L, where L is a column of the
-  // skinning transformation matrix values. To be clear, the covariance matrix
-  // for group k is then given as the dim by dim matrix pulled from the stack:
-  // S((k-1)*dim + 1:dim,:)
-
-  // Apply group sum to each dimension's block of covariance scatter matrix
-  SparseMatrix<double> G_sum_dim;
-  repdiag(G_sum,data.dim,G_sum_dim);
-  CSM = (G_sum_dim * CSM).eval();
-#ifdef EXTREME_VERBOSE
-  cout<<"CSMIJV=["<<endl;print_ijv(CSM,1);cout<<endl<<"];"<<
-    endl<<"CSM=sparse(CSMIJV(:,1),CSMIJV(:,2),CSMIJV(:,3),"<<
-    CSM.rows()<<","<<CSM.cols()<<");"<<endl;
-#endif
-
-  //printf("CSM_M()\n");
-  // Precompute CSM times M for each dimension
-  data.CSM_M.resize(data.dim);
-#ifdef EXTREME_VERBOSE
-  cout<<"data.CSM_M = cell("<<data.dim<<",1);"<<endl;
-#endif
-  // span of integers from 0 to n-1
-  Eigen::Matrix<int,Eigen::Dynamic,1> span_n(n);
-  for(int i = 0;i<n;i++)
-  {
-    span_n(i) = i;
-  }
-
-  // span of integers from 0 to M.cols()-1
-  Eigen::Matrix<int,Eigen::Dynamic,1> span_mlbs_cols(M.cols());
-  for(int i = 0;i<M.cols();i++)
-  {
-    span_mlbs_cols(i) = i;
-  }
-
-  // number of groups
-  int k = CSM.rows()/data.dim;
-  for(int i = 0;i<data.dim;i++)
-  {
-    //printf("CSM_M(): Mi\n");
-    LbsMatrixType M_i;
-    //printf("CSM_M(): slice\n");
-    slice(M,(span_n.array()+i*n).matrix().eval(),span_mlbs_cols,M_i);
-    LbsMatrixType M_i_dim;
-    data.CSM_M[i].resize(k*data.dim,data.m*data.dim*(data.dim+1));
-    assert(data.CSM_M[i].cols() == M.cols());
-    for(int j = 0;j<data.dim;j++)
-    {
-      SparseMatrix<double> CSMj;
-      //printf("CSM_M(): slice\n");
-      slice(
-        CSM,
-        colon<int>(j*k,(j+1)*k-1),
-        colon<int>(j*n,(j+1)*n-1),
-        CSMj);
-      assert(CSMj.rows() == k);
-      assert(CSMj.cols() == n);
-      LbsMatrixType CSMjM_i = CSMj * M_i;
-      if(is_sparse(CSMjM_i))
-      {
-        // Convert to full
-        //printf("CSM_M(): full\n");
-        MatrixXd CSMjM_ifull(CSMjM_i);
-//        printf("CSM_M[%d]: %d %d\n",i,data.CSM_M[i].rows(),data.CSM_M[i].cols());
-//        printf("CSM_M[%d].block(%d*%d=%d,0,%d,%d): %d %d\n",i,j,k,CSMjM_i.rows(),CSMjM_i.cols(),
-//            data.CSM_M[i].block(j*k,0,CSMjM_i.rows(),CSMjM_i.cols()).rows(),
-//            data.CSM_M[i].block(j*k,0,CSMjM_i.rows(),CSMjM_i.cols()).cols());
-//        printf("CSM_MjMi: %d %d\n",i,CSMjM_i.rows(),CSMjM_i.cols());
-//        printf("CSM_MjM_ifull: %d %d\n",i,CSMjM_ifull.rows(),CSMjM_ifull.cols());
-        data.CSM_M[i].block(j*k,0,CSMjM_i.rows(),CSMjM_i.cols()) = CSMjM_ifull;
-      }else
-      {
-        data.CSM_M[i].block(j*k,0,CSMjM_i.rows(),CSMjM_i.cols()) = CSMjM_i;
-      }
-    }
-#ifdef EXTREME_VERBOSE
-    cout<<"CSM_Mi=["<<endl<<data.CSM_M[i]<<endl<<"];"<<endl;
-#endif
-  }
-
-  // precompute arap_rhs matrix
-  //printf("arap_rhs()\n");
-  SparseMatrix<double> K;
-  arap_rhs(V,F,V.cols(),data.energy,K);
-//#ifdef EXTREME_VERBOSE
-//  cout<<"KIJV=["<<endl;print_ijv(K,1);cout<<endl<<"];"<<
-//    endl<<"K=sparse(KIJV(:,1),KIJV(:,2),KIJV(:,3),"<<
-//    K.rows()<<","<<K.cols()<<");"<<endl;
-//#endif
-  // Precompute left muliplication by M and right multiplication by G_sum
-  SparseMatrix<double> G_sumT = G_sum.transpose();
-  SparseMatrix<double> G_sumT_dim_dim;
-  repdiag(G_sumT,data.dim*data.dim,G_sumT_dim_dim);
-  LbsMatrixType MT = M.transpose();
-  // If this is a bottle neck then consider reordering matrix multiplication
-  data.M_KG = -4.0 * (MT * (K * G_sumT_dim_dim));
-//#ifdef EXTREME_VERBOSE
-//  cout<<"data.M_KGIJV=["<<endl;print_ijv(data.M_KG,1);cout<<endl<<"];"<<
-//    endl<<"data.M_KG=sparse(data.M_KGIJV(:,1),data.M_KGIJV(:,2),data.M_KGIJV(:,3),"<<
-//    data.M_KG.rows()<<","<<data.M_KG.cols()<<");"<<endl;
-//#endif
-
-  // Precompute system matrix
-  //printf("A()\n");
-  SparseMatrix<double> A;
-  repdiag(Lapl,data.dim,A);
-  data.Q = MT * (A * M);
-//#ifdef EXTREME_VERBOSE
-//  cout<<"QIJV=["<<endl;print_ijv(data.Q,1);cout<<endl<<"];"<<
-//    endl<<"Q=sparse(QIJV(:,1),QIJV(:,2),QIJV(:,3),"<<
-//    data.Q.rows()<<","<<data.Q.cols()<<");"<<endl;
-//#endif
-
-  // Always do dynamics precomputation so we can hot-switch
-  //if(data.with_dynamics)
-  //{
-    // Build cotangent laplacian
-    SparseMatrix<double> Mass;
-    //printf("massmatrix()\n");
-    massmatrix(V,F,(F.cols()>3?MASSMATRIX_TYPE_BARYCENTRIC:MASSMATRIX_TYPE_VORONOI),Mass);
-    //cout<<"MIJV=["<<endl;print_ijv(Mass,1);cout<<endl<<"];"<<
-    //  endl<<"M=sparse(MIJV(:,1),MIJV(:,2),MIJV(:,3),"<<
-    //  Mass.rows()<<","<<Mass.cols()<<");"<<endl;
-    //speye(data.n,Mass);
-    SparseMatrix<double> Mass_rep;
-    repdiag(Mass,data.dim,Mass_rep);
-
-    // Multiply either side by weights matrix (should be dense)
-    data.Mass_tilde = MT * Mass_rep * M;
-    MatrixXd ones(data.dim*data.n,data.dim);
-    for(int i = 0;i<data.n;i++)
-    {
-      for(int d = 0;d<data.dim;d++)
-      {
-        ones(i+d*data.n,d) = 1;
-      }
-    }
-    data.fgrav = MT * (Mass_rep * ones);
-    data.fext = MatrixXS::Zero(MT.rows(),1);
-    //data.fgrav = MT * (ones);
-  //}
-
-
-  // This may/should be superfluous
-  //printf("is_symmetric()\n");
-  if(!is_symmetric(data.Q))
-  {
-    //printf("Fixing symmetry...\n");
-    // "Fix" symmetry
-    LbsMatrixType QT = data.Q.transpose();
-    LbsMatrixType Q_copy = data.Q;
-    data.Q = 0.5*(Q_copy+QT);
-    // Check that ^^^ this really worked. It doesn't always
-    //assert(is_symmetric(*Q));
-  }
-
-  //printf("arap_dof_precomputation() succeeded... so far...\n");
-  verbose("Number of handles: %i\n", data.m);
-  return true;
-}
-
-/////////////////////////////////////////////////////////////////////////
-//
-// STATIC FUNCTIONS (These should be removed or properly defined)
-//
-/////////////////////////////////////////////////////////////////////////
-namespace igl
-{
-  // returns maximal difference of 'blok' from scalar times 3x3 identity:
-  template <typename SSCALAR>
-  inline static SSCALAR maxBlokErr(const Eigen::Matrix3f &blok)
-  {
-    SSCALAR mD;
-    SSCALAR value = blok(0,0);
-    SSCALAR diff1 = fabs(blok(1,1) - value);
-    SSCALAR diff2 = fabs(blok(2,2) - value);
-    if (diff1 > diff2) mD = diff1;
-    else mD = diff2;
-    
-    for (int v=0; v<3; v++)
-    {
-      for (int w=0; w<3; w++)
-      {
-        if (v == w)
-        {
-          continue;
-        }
-        if (mD < fabs(blok(v, w)))
-        {
-          mD = fabs(blok(v, w));
-        }
-      }
-    }
-    
-    return mD;
-  }
-  
-  // converts CSM_M_SSCALAR[0], CSM_M_SSCALAR[1], CSM_M_SSCALAR[2] into one
-  // "condensed" matrix CSM while checking we're not losing any information by
-  // this process; specifically, returns maximal difference from scaled 3x3
-  // identity blocks, which should be pretty small number
-  template <typename MatrixXS>
-  static typename MatrixXS::Scalar condense_CSM(
-    const std::vector<MatrixXS> &CSM_M_SSCALAR, 
-    int numBones, 
-    int dim, 
-    MatrixXS &CSM)
-  {
-    const int numRows = CSM_M_SSCALAR[0].rows();
-    assert(CSM_M_SSCALAR[0].cols() == dim*(dim+1)*numBones);
-    assert(CSM_M_SSCALAR[1].cols() == dim*(dim+1)*numBones);
-    assert(CSM_M_SSCALAR[2].cols() == dim*(dim+1)*numBones);
-    assert(CSM_M_SSCALAR[1].rows() == numRows);
-    assert(CSM_M_SSCALAR[2].rows() == numRows);
-  
-    const int numCols = (dim + 1)*numBones;
-    CSM.resize(numRows, numCols);
-  
-    typedef typename MatrixXS::Scalar SSCALAR;
-    SSCALAR maxDiff = 0.0f;
-  
-    for (int r=0; r<numRows; r++)
-    {
-      for (int coord=0; coord<dim+1; coord++)
-      {
-        for (int b=0; b<numBones; b++)
-        {
-          // this is just a test if we really have a multiple of 3x3 identity
-          Eigen::Matrix3f blok;
-          for (int v=0; v<3; v++)
-          {
-            for (int w=0; w<3; w++)
-            {
-              blok(v,w) = CSM_M_SSCALAR[v](r, coord*(numBones*dim) + b + w*numBones);
-            }          
-          }
-  
-          //SSCALAR value[3];
-          //for (int v=0; v<3; v++)
-          //  CSM_M_SSCALAR[v](r, coord*(numBones*dim) + b + v*numBones);
-  
-          SSCALAR mD = maxBlokErr<SSCALAR>(blok);
-          if (mD > maxDiff) maxDiff = mD;
-  
-          // use the first value:
-          CSM(r, coord*numBones + b) = blok(0,0);
-        }
-      }
-    }
-  
-    return maxDiff;
-  }
-  
-  // splits x_0, ... , x_dim coordinates in column vector 'L' into a numBones*(dimp1) x dim matrix 'Lsep';
-  // assumes 'Lsep' has already been preallocated
-  //
-  // is this the same as uncolumnize? no.
-  template <typename MatL, typename MatLsep>
-  static void splitColumns(
-   const MatL &L, 
-   int numBones, 
-   int dim, 
-   int dimp1, 
-   MatLsep &Lsep)
-  {
-    assert(L.cols() == 1);
-    assert(L.rows() == dim*(dimp1)*numBones);
-  
-    assert(Lsep.rows() == (dimp1)*numBones && Lsep.cols() == dim);
-  
-    for (int b=0; b<numBones; b++)
-    {
-      for (int coord=0; coord<dimp1; coord++)
-      {
-        for (int c=0; c<dim; c++)
-        {
-          Lsep(coord*numBones + b, c) = L(coord*numBones*dim + c*numBones + b, 0);
-        }
-      }
-    }
-  }
-  
-  
-  // the inverse of splitColumns, i.e., takes numBones*(dimp1) x dim matrix 'Lsep' and merges the dimensions
-  // into columns vector 'L' (which is assumed to be already allocated):
-  //
-  // is this the same as columnize? no.
-  template <typename MatrixXS>
-  static void mergeColumns(const MatrixXS &Lsep, int numBones, int dim, int dimp1, MatrixXS &L)
-  {
-    assert(L.cols() == 1);
-    assert(L.rows() == dim*(dimp1)*numBones);
-  
-    assert(Lsep.rows() == (dimp1)*numBones && Lsep.cols() == dim);
-  
-    for (int b=0; b<numBones; b++)
-    {
-      for (int coord=0; coord<dimp1; coord++)
-      {
-        for (int c=0; c<dim; c++)
-        {
-          L(coord*numBones*dim + c*numBones + b, 0) = Lsep(coord*numBones + b, c);
-        }
-      }
-    }
-  }
-  
-  // converts "Solve1" the "rotations" part of FullSolve matrix (the first part)
-  // into one "condensed" matrix CSolve1 while checking we're not losing any
-  // information by this process; specifically, returns maximal difference from
-  // scaled 3x3 identity blocks, which should be pretty small number
-  template <typename MatrixXS>
-  static typename MatrixXS::Scalar condense_Solve1(MatrixXS &Solve1, int numBones, int numGroups, int dim, MatrixXS &CSolve1)
-  {
-    assert(Solve1.rows() == dim*(dim + 1)*numBones);
-    assert(Solve1.cols() == dim*dim*numGroups);
-  
-    typedef typename MatrixXS::Scalar SSCALAR;
-    SSCALAR maxDiff = 0.0f;
-  
-    CSolve1.resize((dim + 1)*numBones, dim*numGroups);  
-    for (int rowCoord=0; rowCoord<dim+1; rowCoord++)
-    {
-      for (int b=0; b<numBones; b++)
-      {
-        for (int colCoord=0; colCoord<dim; colCoord++)
-        {
-          for (int g=0; g<numGroups; g++)
-          {
-            Eigen::Matrix3f blok;
-            for (int r=0; r<3; r++)
-            {
-              for (int c=0; c<3; c++)
-              {
-                blok(r, c) = Solve1(rowCoord*numBones*dim + r*numBones + b, colCoord*numGroups*dim + c*numGroups + g);
-              }
-            }
-  
-            SSCALAR mD = maxBlokErr<SSCALAR>(blok);
-            if (mD > maxDiff) maxDiff = mD;
-  
-            CSolve1(rowCoord*numBones + b, colCoord*numGroups + g) = blok(0,0);
-          }
-        }
-      }
-    }  
-    
-    return maxDiff;
-  }
-}
-
-template <typename LbsMatrixType, typename SSCALAR>
-IGL_INLINE bool igl::arap_dof_recomputation(
-  const Eigen::Matrix<int,Eigen::Dynamic,1> & fixed_dim,
-  const Eigen::SparseMatrix<double> & A_eq,
-  ArapDOFData<LbsMatrixType, SSCALAR> & data)
-{
-  using namespace Eigen;
-  typedef Matrix<SSCALAR, Dynamic, Dynamic> MatrixXS;
-
-  LbsMatrixType * Q;
-  LbsMatrixType Qdyn;
-  if(data.with_dynamics)
-  {
-    // multiply by 1/timestep and to quadratic coefficients matrix
-    // Might be missing a 0.5 here
-    LbsMatrixType Q_copy = data.Q;
-    Qdyn = Q_copy + (1.0/(data.h*data.h))*data.Mass_tilde;
-    Q = &Qdyn;
-
-    // This may/should be superfluous
-    //printf("is_symmetric()\n");
-    if(!is_symmetric(*Q))
-    {
-      //printf("Fixing symmetry...\n");
-      // "Fix" symmetry
-      LbsMatrixType QT = (*Q).transpose();
-      LbsMatrixType Q_copy = *Q;
-      *Q = 0.5*(Q_copy+QT);
-      // Check that ^^^ this really worked. It doesn't always
-      //assert(is_symmetric(*Q));
-    }
-  }else
-  {
-    Q = &data.Q;
-  }
-
-  assert((int)data.CSM_M.size() == data.dim);
-  assert(A_eq.cols() == data.m*data.dim*(data.dim+1));
-  data.fixed_dim = fixed_dim;
-
-  if(fixed_dim.size() > 0)
-  {
-    assert(fixed_dim.maxCoeff() < data.m*data.dim*(data.dim+1));
-    assert(fixed_dim.minCoeff() >= 0);
-  }
-
-#ifdef EXTREME_VERBOSE
-  cout<<"data.fixed_dim=["<<endl<<data.fixed_dim<<endl<<"]+1;"<<endl;
-#endif
-
-  // Compute dense solve matrix (alternative of matrix factorization)
-  //printf("kkt_inverse()\n");
-  MatrixXd Qfull(*Q);
-  MatrixXd A_eqfull(A_eq);
-  MatrixXd M_Solve;
-
-  double timer0_start = get_seconds();
-  bool use_lu = data.effective_dim != 2;
-  //use_lu = false;
-  //printf("use_lu: %s\n",(use_lu?"TRUE":"FALSE"));
-  kkt_inverse(Qfull, A_eqfull, use_lu,M_Solve);
-  double timer0_end = get_seconds();
-  verbose("Bob timing: %.20f\n", (timer0_end - timer0_start)*1000.0);
-
-  // Precompute full solve matrix:
-  const int fsRows = data.m * data.dim * (data.dim + 1); // 12 * number_of_bones
-  const int fsCols1 = data.M_KG.cols(); // 9 * number_of_posConstraints
-  const int fsCols2 = A_eq.rows(); // number_of_posConstraints
-  data.M_FullSolve.resize(fsRows, fsCols1 + fsCols2);
-  // note the magical multiplicative constant "-0.5", I've no idea why it has
-  // to be there :)
-  data.M_FullSolve << 
-    (-0.5 * M_Solve.block(0, 0, fsRows, fsRows) * data.M_KG).template cast<SSCALAR>(), 
-    M_Solve.block(0, fsRows, fsRows, fsCols2).template cast<SSCALAR>();
-
-  if(data.with_dynamics)
-  {
-    printf(
-      "---------------------------------------------------------------------\n"
-      "\n\n\nWITH DYNAMICS recomputation\n\n\n"
-      "---------------------------------------------------------------------\n"
-      );
-    // Also need to save Π1 before it gets multiplied by Ktilde (aka M_KG)
-    data.Pi_1 = M_Solve.block(0, 0, fsRows, fsRows).template cast<SSCALAR>();
-  }
-
-  // Precompute condensed matrices,
-  // first CSM:
-  std::vector<MatrixXS> CSM_M_SSCALAR;
-  CSM_M_SSCALAR.resize(data.dim);
-  for (int i=0; i<data.dim; i++) CSM_M_SSCALAR[i] = data.CSM_M[i].template cast<SSCALAR>();
-  SSCALAR maxErr1 = condense_CSM(CSM_M_SSCALAR, data.m, data.dim, data.CSM);  
-  verbose("condense_CSM maxErr = %.15f (this should be close to zero)\n", maxErr1);
-  assert(fabs(maxErr1) < 1e-5);
-  
-  // and then solveBlock1:
-  // number of groups
-  const int k = data.CSM_M[0].rows()/data.dim;
-  MatrixXS SolveBlock1 = data.M_FullSolve.block(0, 0, data.M_FullSolve.rows(), data.dim * data.dim * k);
-  SSCALAR maxErr2 = condense_Solve1(SolveBlock1, data.m, k, data.dim, data.CSolveBlock1);  
-  verbose("condense_Solve1 maxErr = %.15f (this should be close to zero)\n", maxErr2);
-  assert(fabs(maxErr2) < 1e-5);
-
-  return true;
-}
-
-template <typename LbsMatrixType, typename SSCALAR>
-IGL_INLINE bool igl::arap_dof_update(
-  const ArapDOFData<LbsMatrixType, SSCALAR> & data,
-  const Eigen::Matrix<double,Eigen::Dynamic,1> & B_eq,
-  const Eigen::MatrixXd & L0,
-  const int max_iters,
-  const double 
-#ifdef IGL_ARAP_DOF_FIXED_ITERATIONS_COUNT
-  tol,
-#else
-  /*tol*/,
-#endif
-  Eigen::MatrixXd & L
-  )
-{
-  using namespace Eigen;
-  typedef Matrix<SSCALAR, Dynamic, Dynamic> MatrixXS;
-#ifdef ARAP_GLOBAL_TIMING
-  double timer_start = get_seconds();
-#endif
-
-  // number of dimensions
-  assert((int)data.CSM_M.size() == data.dim);
-  assert((int)L0.size() == (data.m)*data.dim*(data.dim+1));
-  assert(max_iters >= 0);
-  assert(tol >= 0);
-
-  // timing variables
-  double 
-    sec_start, 
-    sec_covGather, 
-    sec_fitRotations, 
-    //sec_rhs, 
-    sec_prepMult, 
-    sec_solve, sec_end;
-
-  assert(L0.cols() == 1);
-#ifdef EXTREME_VERBOSE
-  cout<<"dim="<<data.dim<<";"<<endl;
-  cout<<"m="<<data.m<<";"<<endl;
-#endif
-
-  // number of groups
-  const int k = data.CSM_M[0].rows()/data.dim;
-  for(int i = 0;i<data.dim;i++)
-  {
-    assert(data.CSM_M[i].rows()/data.dim == k);
-  }
-#ifdef EXTREME_VERBOSE
-  cout<<"k="<<k<<";"<<endl;
-#endif
-
-  // resize output and initialize with initial guess
-  L = L0;
-#ifndef IGL_ARAP_DOF_FIXED_ITERATIONS_COUNT
-  // Keep track of last solution
-  MatrixXS L_prev;
-#endif
-  // We will be iterating on L_SSCALAR, only at the end we convert back to double
-  MatrixXS L_SSCALAR = L.cast<SSCALAR>();
-
-  int iters = 0;
-#ifndef IGL_ARAP_DOF_FIXED_ITERATIONS_COUNT
-  double max_diff = tol+1;  
-#endif
-
-  MatrixXS S(k*data.dim,data.dim);
-  MatrixXS R(data.dim,data.dim*k);
-  Eigen::Matrix<SSCALAR,Eigen::Dynamic,1> Rcol(data.dim * data.dim * k);
-  Matrix<SSCALAR,Dynamic,1> B_eq_SSCALAR = B_eq.cast<SSCALAR>();
-  Matrix<SSCALAR,Dynamic,1> B_eq_fix_SSCALAR;
-  Matrix<SSCALAR,Dynamic,1> L0SSCALAR = L0.cast<SSCALAR>();
-  slice(L0SSCALAR, data.fixed_dim, B_eq_fix_SSCALAR);    
-  //MatrixXS rhsFull(Rcol.rows() + B_eq.rows() + B_eq_fix_SSCALAR.rows(), 1); 
-
-  MatrixXS Lsep(data.m*(data.dim + 1), 3);  
-  const MatrixXS L_part2 = 
-    data.M_FullSolve.block(0, Rcol.rows(), data.M_FullSolve.rows(), B_eq_SSCALAR.rows()) * B_eq_SSCALAR;
-  const MatrixXS L_part3 = 
-    data.M_FullSolve.block(0, Rcol.rows() + B_eq_SSCALAR.rows(), data.M_FullSolve.rows(), B_eq_fix_SSCALAR.rows()) * B_eq_fix_SSCALAR;
-  MatrixXS L_part2and3 = L_part2 + L_part3;
-
-  // preallocate workspace variables:
-  MatrixXS Rxyz(k*data.dim, data.dim);  
-  MatrixXS L_part1xyz((data.dim + 1) * data.m, data.dim);
-  MatrixXS L_part1(data.dim * (data.dim + 1) * data.m, 1);
-
-#ifdef ARAP_GLOBAL_TIMING
-    double timer_prepFinished = get_seconds();
-#endif
-
-#ifdef IGL_ARAP_DOF_FIXED_ITERATIONS_COUNT
-  while(iters < max_iters)
-#else
-  while(iters < max_iters && max_diff > tol)
-#endif
-  {  
-    if(data.print_timings)
-    {
-      sec_start = get_seconds();
-    }
-
-#ifndef IGL_ARAP_DOF_FIXED_ITERATIONS_COUNT
-    L_prev = L_SSCALAR;
-#endif
-    ///////////////////////////////////////////////////////////////////////////
-    // Local step: Fix positions, fit rotations
-    ///////////////////////////////////////////////////////////////////////////    
-  
-    // Gather covariance matrices    
-
-    splitColumns(L_SSCALAR, data.m, data.dim, data.dim + 1, Lsep);
-
-    S = data.CSM * Lsep; 
-    // interestingly, this doesn't seem to be so slow, but
-    //MKL is still 2x faster (probably due to AVX)
-    //#ifdef IGL_ARAP_DOF_DOUBLE_PRECISION_SOLVE
-    //    MKL_matMatMult_double(S, data.CSM, Lsep);
-    //#else
-    //    MKL_matMatMult_single(S, data.CSM, Lsep);
-    //#endif
-    
-    if(data.print_timings)
-    {
-      sec_covGather = get_seconds();
-    }
-
-#ifdef EXTREME_VERBOSE
-    cout<<"S=["<<endl<<S<<endl<<"];"<<endl;
-#endif
-    // Fit rotations to covariance matrices
-    if(data.effective_dim == 2)
-    {
-      fit_rotations_planar(S,R);
-    }else
-    {
-#ifdef __SSE__ // fit_rotations_SSE will convert to float if necessary
-      fit_rotations_SSE(S,R);
-#else
-      fit_rotations(S,false,R);
-#endif
-    }
-
-#ifdef EXTREME_VERBOSE
-    cout<<"R=["<<endl<<R<<endl<<"];"<<endl;
-#endif  
-
-    if(data.print_timings)
-    {
-      sec_fitRotations = get_seconds();
-    }
-  
-    ///////////////////////////////////////////////////////////////////////////
-    // "Global" step: fix rotations per mesh vertex, solve for
-    // linear transformations at handles
-    ///////////////////////////////////////////////////////////////////////////
-
-    // all this shuffling is retarded and not completely negligible time-wise;
-    // TODO: change fit_rotations_XXX so it returns R in the format ready for
-    // CSolveBlock1 multiplication
-    columnize(R, k, 2, Rcol);
-#ifdef EXTREME_VERBOSE
-    cout<<"Rcol=["<<endl<<Rcol<<endl<<"];"<<endl;
-#endif  
-    splitColumns(Rcol, k, data.dim, data.dim, Rxyz);
-    
-    if(data.print_timings)
-    {
-      sec_prepMult = get_seconds();
-    }  
-    
-    L_part1xyz = data.CSolveBlock1 * Rxyz;
-    //#ifdef IGL_ARAP_DOF_DOUBLE_PRECISION_SOLVE
-    //    MKL_matMatMult_double(L_part1xyz, data.CSolveBlock1, Rxyz);    
-    //#else
-    //    MKL_matMatMult_single(L_part1xyz, data.CSolveBlock1, Rxyz);    
-    //#endif
-    mergeColumns(L_part1xyz, data.m, data.dim, data.dim + 1, L_part1);
-
-    if(data.with_dynamics)
-    {
-      // Consider reordering or precomputing matrix multiplications
-      MatrixXS L_part1_dyn(data.dim * (data.dim + 1) * data.m, 1);
-      // Eigen can't parse this:
-      //L_part1_dyn = 
-      //  -(2.0/(data.h*data.h)) * data.Pi_1 * data.Mass_tilde * data.L0 +
-      //   (1.0/(data.h*data.h)) * data.Pi_1 * data.Mass_tilde * data.Lm1;
-      // -1.0 because we've moved these linear terms to the right hand side
-      //MatrixXS temp = -1.0 * 
-      //    ((-2.0/(data.h*data.h)) * data.L0.array() + 
-      //      (1.0/(data.h*data.h)) * data.Lm1.array()).matrix();
-      //MatrixXS temp = -1.0 * 
-      //    ( (-1.0/(data.h*data.h)) * data.L0.array() + 
-      //      (1.0/(data.h*data.h)) * data.Lm1.array()
-      //      (-1.0/(data.h*data.h)) * data.L0.array() + 
-      //      ).matrix();
-      //Lvel0 = (1.0/(data.h)) * data.Lm1.array() - data.L0.array();
-      MatrixXS temp = -1.0 * 
-          ( (-1.0/(data.h*data.h)) * data.L0.array() + 
-            (1.0/(data.h)) * data.Lvel0.array()
-            ).matrix();
-      MatrixXd temp_d = temp.template cast<double>();
-
-      MatrixXd temp_g = data.fgrav*(data.grav_mag*data.grav_dir);
-
-      assert(data.fext.rows() == temp_g.rows());
-      assert(data.fext.cols() == temp_g.cols());
-      MatrixXd temp2 = data.Mass_tilde * temp_d + temp_g + data.fext.template cast<double>();
-      MatrixXS temp2_f = temp2.template cast<SSCALAR>();
-      L_part1_dyn = data.Pi_1 * temp2_f;
-      L_part1.array() = L_part1.array() + L_part1_dyn.array();
-    }
-
-    //L_SSCALAR = L_part1 + L_part2and3;
-    assert(L_SSCALAR.rows() == L_part1.rows() && L_SSCALAR.rows() == L_part2and3.rows());
-    for (int i=0; i<L_SSCALAR.rows(); i++)
-    {
-      L_SSCALAR(i, 0) = L_part1(i, 0) + L_part2and3(i, 0);
-    }
-
-#ifdef EXTREME_VERBOSE
-    cout<<"L=["<<endl<<L<<endl<<"];"<<endl;
-#endif  
-
-    if(data.print_timings)
-    {
-      sec_solve = get_seconds();
-    }
-
-#ifndef IGL_ARAP_DOF_FIXED_ITERATIONS_COUNT
-    // Compute maximum absolute difference with last iteration's solution
-    max_diff = (L_SSCALAR-L_prev).eval().array().abs().matrix().maxCoeff();
-#endif
-    iters++;  
-
-    if(data.print_timings)
-    {
-      sec_end = get_seconds();
-#ifndef WIN32
-      // trick to get sec_* variables to compile without warning on mac
-      if(false)
-#endif
-      printf(
-        "\ntotal iteration time = %f "
-        "[local: covGather = %f, "
-        "fitRotations = %f, "
-        "global: prep = %f, "
-        "solve = %f, "
-        "error = %f [ms]]\n", 
-        (sec_end - sec_start)*1000.0, 
-        (sec_covGather - sec_start)*1000.0, 
-        (sec_fitRotations - sec_covGather)*1000.0, 
-        (sec_prepMult - sec_fitRotations)*1000.0, 
-        (sec_solve - sec_prepMult)*1000.0, 
-        (sec_end - sec_solve)*1000.0 );
-    }
-  }
-
-
-  L = L_SSCALAR.template cast<double>();
-  assert(L.cols() == 1);
-
-#ifdef ARAP_GLOBAL_TIMING
-  double timer_finito = get_seconds();
-  printf(
-    "ARAP preparation = %f, "
-    "all %i iterations = %f [ms]\n", 
-    (timer_prepFinished - timer_start)*1000.0, 
-    max_iters, 
-    (timer_finito - timer_prepFinished)*1000.0);  
-#endif
-
-  return true;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::arap_dof_update<Eigen::Matrix<double, -1, -1, 0, -1, -1>, double>(ArapDOFData<Eigen::Matrix<double, -1, -1, 0, -1, -1>, double> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, int, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
-template bool igl::arap_dof_recomputation<Eigen::Matrix<double, -1, -1, 0, -1, -1>, double>(Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::SparseMatrix<double, 0, int> const&, ArapDOFData<Eigen::Matrix<double, -1, -1, 0, -1, -1>, double>&);
-template bool igl::arap_dof_precomputation<Eigen::Matrix<double, -1, -1, 0, -1, -1>, double>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, ArapDOFData<Eigen::Matrix<double, -1, -1, 0, -1, -1>, double>&);
-template bool igl::arap_dof_update<Eigen::Matrix<double, -1, -1, 0, -1, -1>, float>(igl::ArapDOFData<Eigen::Matrix<double, -1, -1, 0, -1, -1>, float> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, int, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
-template bool igl::arap_dof_recomputation<Eigen::Matrix<double, -1, -1, 0, -1, -1>, float>(Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::SparseMatrix<double, 0, int> const&, igl::ArapDOFData<Eigen::Matrix<double, -1, -1, 0, -1, -1>, float>&);
-template bool igl::arap_dof_precomputation<Eigen::Matrix<double, -1, -1, 0, -1, -1>, float>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, igl::ArapDOFData<Eigen::Matrix<double, -1, -1, 0, -1, -1>, float>&);
-#endif

+ 0 - 259
include/igl/arap_linear_block.cpp

@@ -1,259 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "arap_linear_block.h"
-#include "verbose.h"
-#include "cotmatrix_entries.h"
-#include <Eigen/Dense>
-
-template <typename MatV, typename MatF, typename MatK>
-IGL_INLINE void igl::arap_linear_block(
-  const MatV & V,
-  const MatF & F,
-  const int d,
-  const igl::ARAPEnergyType energy,
-  MatK & Kd)
-{
-  switch(energy)
-  {
-    case ARAP_ENERGY_TYPE_SPOKES:
-      return igl::arap_linear_block_spokes(V,F,d,Kd);
-      break;
-    case ARAP_ENERGY_TYPE_SPOKES_AND_RIMS:
-      return igl::arap_linear_block_spokes_and_rims(V,F,d,Kd);
-      break;
-    case ARAP_ENERGY_TYPE_ELEMENTS:
-      return igl::arap_linear_block_elements(V,F,d,Kd);
-      break;
-    default:
-      verbose("Unsupported energy type: %d\n",energy);
-      assert(false);
-  }
-}
-
-
-template <typename MatV, typename MatF, typename MatK>
-IGL_INLINE void igl::arap_linear_block_spokes(
-  const MatV & V,
-  const MatF & F,
-  const int d,
-  MatK & Kd)
-{
-  typedef typename MatK::Scalar Scalar;
-
-  using namespace std;
-  using namespace Eigen;
-  // simplex size (3: triangles, 4: tetrahedra)
-  int simplex_size = F.cols();
-  // Number of elements
-  int m = F.rows();
-  // Temporary output
-  Matrix<int,Dynamic,2> edges;
-  Kd.resize(V.rows(), V.rows());
-  vector<Triplet<Scalar> > Kd_IJV;
-  if(simplex_size == 3)
-  {
-    // triangles
-    Kd.reserve(7*V.rows());
-    Kd_IJV.reserve(7*V.rows());
-    edges.resize(3,2);
-    edges << 
-      1,2,
-      2,0,
-      0,1;
-  }else if(simplex_size == 4)
-  {
-    // tets
-    Kd.reserve(17*V.rows());
-    Kd_IJV.reserve(17*V.rows());
-    edges.resize(6,2);
-    edges << 
-      1,2,
-      2,0,
-      0,1,
-      3,0,
-      3,1,
-      3,2;
-  }
-  // gather cotangent weights
-  Matrix<Scalar,Dynamic,Dynamic> C;
-  cotmatrix_entries(V,F,C);
-  // should have weights for each edge
-  assert(C.cols() == edges.rows());
-  // loop over elements
-  for(int i = 0;i<m;i++)
-  {
-    // loop over edges of element
-    for(int e = 0;e<edges.rows();e++)
-    {
-      int source = F(i,edges(e,0));
-      int dest = F(i,edges(e,1));
-      double v = 0.5*C(i,e)*(V(source,d)-V(dest,d));
-      Kd_IJV.push_back(Triplet<Scalar>(source,dest,v));
-      Kd_IJV.push_back(Triplet<Scalar>(dest,source,-v));
-      Kd_IJV.push_back(Triplet<Scalar>(source,source,v));
-      Kd_IJV.push_back(Triplet<Scalar>(dest,dest,-v));
-    }
-  }
-  Kd.setFromTriplets(Kd_IJV.begin(),Kd_IJV.end());
-  Kd.makeCompressed();
-}
-
-template <typename MatV, typename MatF, typename MatK>
-IGL_INLINE void igl::arap_linear_block_spokes_and_rims(
-  const MatV & V,
-  const MatF & F,
-  const int d,
-  MatK & Kd)
-{
-  typedef typename MatK::Scalar Scalar;
-
-  using namespace std;
-  using namespace Eigen;
-  // simplex size (3: triangles, 4: tetrahedra)
-  int simplex_size = F.cols();
-  // Number of elements
-  int m = F.rows();
-  // Temporary output
-  Kd.resize(V.rows(), V.rows());
-  vector<Triplet<Scalar> > Kd_IJV;
-  Matrix<int,Dynamic,2> edges;
-  if(simplex_size == 3)
-  {
-    // triangles
-    Kd.reserve(7*V.rows());
-    Kd_IJV.reserve(7*V.rows());
-    edges.resize(3,2);
-    edges << 
-      1,2,
-      2,0,
-      0,1;
-  }else if(simplex_size == 4)
-  {
-    // tets
-    Kd.reserve(17*V.rows());
-    Kd_IJV.reserve(17*V.rows());
-    edges.resize(6,2);
-    edges << 
-      1,2,
-      2,0,
-      0,1,
-      3,0,
-      3,1,
-      3,2;
-    // Not implemented yet for tets
-    assert(false);
-  }
-  // gather cotangent weights
-  Matrix<Scalar,Dynamic,Dynamic> C;
-  cotmatrix_entries(V,F,C);
-  // should have weights for each edge
-  assert(C.cols() == edges.rows());
-  // loop over elements
-  for(int i = 0;i<m;i++)
-  {
-    // loop over edges of element
-    for(int e = 0;e<edges.rows();e++)
-    {
-      int source = F(i,edges(e,0));
-      int dest = F(i,edges(e,1));
-      double v = C(i,e)*(V(source,d)-V(dest,d))/3.0;
-      // loop over edges again
-      for(int f = 0;f<edges.rows();f++)
-      {
-        int Rs = F(i,edges(f,0));
-        int Rd = F(i,edges(f,1));
-        if(Rs == source && Rd == dest)
-        {
-          Kd_IJV.push_back(Triplet<Scalar>(Rs,Rd,v));
-          Kd_IJV.push_back(Triplet<Scalar>(Rd,Rs,-v));
-        }else if(Rd == source)
-        {
-          Kd_IJV.push_back(Triplet<Scalar>(Rd,Rs,v));
-        }else if(Rs == dest)
-        {
-          Kd_IJV.push_back(Triplet<Scalar>(Rs,Rd,-v));
-        }
-      }
-      Kd_IJV.push_back(Triplet<Scalar>(source,source,v));
-      Kd_IJV.push_back(Triplet<Scalar>(dest,dest,-v));
-    }
-  }
-  Kd.setFromTriplets(Kd_IJV.begin(),Kd_IJV.end());
-  Kd.makeCompressed();
-}
-
-template <typename MatV, typename MatF, typename MatK>
-IGL_INLINE void igl::arap_linear_block_elements(
-  const MatV & V,
-  const MatF & F,
-  const int d,
-  MatK & Kd)
-{
-  typedef typename MatK::Scalar Scalar;
-  using namespace std;
-  using namespace Eigen;
-  // simplex size (3: triangles, 4: tetrahedra)
-  int simplex_size = F.cols();
-  // Number of elements
-  int m = F.rows();
-  // Temporary output
-  Kd.resize(V.rows(), F.rows());
-  vector<Triplet<Scalar> > Kd_IJV;
-  Matrix<int,Dynamic,2> edges;
-  if(simplex_size == 3)
-  {
-    // triangles
-    Kd.reserve(7*V.rows());
-    Kd_IJV.reserve(7*V.rows());
-    edges.resize(3,2);
-    edges << 
-      1,2,
-      2,0,
-      0,1;
-  }else if(simplex_size == 4)
-  {
-    // tets
-    Kd.reserve(17*V.rows());
-    Kd_IJV.reserve(17*V.rows());
-    edges.resize(6,2);
-    edges << 
-      1,2,
-      2,0,
-      0,1,
-      3,0,
-      3,1,
-      3,2;
-  }
-  // gather cotangent weights
-  Matrix<Scalar,Dynamic,Dynamic> C;
-  cotmatrix_entries(V,F,C);
-  // should have weights for each edge
-  assert(C.cols() == edges.rows());
-  // loop over elements
-  for(int i = 0;i<m;i++)
-  {
-    // loop over edges of element
-    for(int e = 0;e<edges.rows();e++)
-    {
-      int source = F(i,edges(e,0));
-      int dest = F(i,edges(e,1));
-      double v = C(i,e)*(V(source,d)-V(dest,d));
-      Kd_IJV.push_back(Triplet<Scalar>(source,i,v));
-      Kd_IJV.push_back(Triplet<Scalar>(dest,i,-v));
-    }
-  }
-  Kd.setFromTriplets(Kd_IJV.begin(),Kd_IJV.end());
-  Kd.makeCompressed();
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::arap_linear_block<Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::SparseMatrix<double, 0, int> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, igl::ARAPEnergyType, Eigen::SparseMatrix<double, 0, int>&);
-template void igl::arap_linear_block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::SparseMatrix<double, 0, int> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, int, igl::ARAPEnergyType, Eigen::SparseMatrix<double, 0, int>&);
-#endif

+ 0 - 95
include/igl/arap_rhs.cpp

@@ -1,95 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "arap_rhs.h"
-#include "arap_linear_block.h"
-#include "verbose.h"
-#include "repdiag.h"
-#include "cat.h"
-#include <iostream>
-
-template<typename DerivedV, typename DerivedF, typename DerivedK>
-IGL_INLINE void igl::arap_rhs(
-    const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixBase<DerivedF> & F,
-    const int dim,
-    const igl::ARAPEnergyType energy,
-    Eigen::SparseCompressedBase<DerivedK>& K)
-{
-  using namespace std;
-  using namespace Eigen;
-  // Number of dimensions
-  int Vdim = V.cols();
-  //// Number of mesh vertices
-  //int n = V.rows();
-  //// Number of mesh elements
-  //int m = F.rows();
-  //// number of rotations
-  //int nr;
-  switch(energy)
-  {
-    case ARAP_ENERGY_TYPE_SPOKES:
-      //nr = n;
-      break;
-    case ARAP_ENERGY_TYPE_SPOKES_AND_RIMS:
-      //nr = n;
-      break;
-    case ARAP_ENERGY_TYPE_ELEMENTS:
-      //nr = m;
-      break;
-    default:
-      fprintf(
-        stderr,
-        "arap_rhs.h: Error: Unsupported arap energy %d\n",
-        energy);
-      return;
-  }
-
-  DerivedK KX,KY,KZ;
-  arap_linear_block(V,F,0,energy,KX);
-  arap_linear_block(V,F,1,energy,KY);
-  if(Vdim == 2)
-  {
-    K = cat(2,repdiag(KX,dim),repdiag(KY,dim));
-  }else if(Vdim == 3)
-  {
-    arap_linear_block(V,F,2,energy,KZ);
-    if(dim == 3)
-    {
-      K = cat(2,cat(2,repdiag(KX,dim),repdiag(KY,dim)),repdiag(KZ,dim));
-    }else if(dim ==2)
-    {
-      DerivedK ZZ(KX.rows()*2,KX.cols());
-      K = cat(2,cat(2,
-            cat(2,repdiag(KX,dim),ZZ),
-            cat(2,repdiag(KY,dim),ZZ)),
-            cat(2,repdiag(KZ,dim),ZZ));
-    }else
-    {
-      assert(false);
-      fprintf(
-      stderr,
-      "arap_rhs.h: Error: Unsupported dimension %d\n",
-      dim);
-    }
-  }else
-  {
-    assert(false);
-    fprintf(
-     stderr,
-     "arap_rhs.h: Error: Unsupported dimension %d\n",
-     Vdim);
-    return;
-  }
-
-}
-
-
-
-#ifdef IGL_STATIC_LIBRARY
-template void igl::arap_rhs(const Eigen::MatrixBase<Eigen::MatrixXd> & V, const Eigen::MatrixBase<Eigen::MatrixXi> & F,const int dim, const igl::ARAPEnergyType energy,Eigen::SparseCompressedBase<Eigen::SparseMatrix<double>>& K);
-#endif

+ 0 - 69
include/igl/average_from_edges_onto_vertices.cpp

@@ -1,69 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2020 Oded Stein <[email protected]>
-//
-// 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/.
-#include "average_from_edges_onto_vertices.h"
-
-template<typename DerivedF,typename DerivedE,typename DerivedoE,
-typename DeriveduE,typename DeriveduV>
-IGL_INLINE void
-igl::average_from_edges_onto_vertices(
-  const Eigen::MatrixBase<DerivedF> &F,
-  const Eigen::MatrixBase<DerivedE> &E,
-  const Eigen::MatrixBase<DerivedoE> &oE,
-  const Eigen::MatrixBase<DeriveduE> &uE,
-  Eigen::PlainObjectBase<DeriveduV> &uV)
-{
-  using Scalar = typename DeriveduE::Scalar;
-  using VecX = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
-  using Int = typename DerivedF::Scalar;
-  
-  assert(E.rows()==F.rows() && "E does not match dimensions of F.");
-  assert(oE.rows()==F.rows() && "oE does not match dimensions of F.");
-  assert(E.cols()==3 && F.cols()==3 && oE.cols()==3 &&
-   "This method is for triangle meshes.");
-  
-  const Int n = F.maxCoeff()+1;
-  
-  VecX edgesPerVertex(n);
-  edgesPerVertex.setZero();
-  uV.resize(n,1);
-  uV.setZero();
-  
-  for(Eigen::Index i=0; i<F.rows(); ++i) {
-    for(int j=0; j<3; ++j) {
-      if(oE(i,j)<0) {
-        continue;
-      }
-      const Int e = E(i,j);
-      const Int vi=F(i,(j+1)%3), vj=F(i,(j+2)%3);
-      
-      //Count vertex valence
-      ++edgesPerVertex(vi);
-      ++edgesPerVertex(vj);
-      
-      //Average uE value onto vertices
-      uV(vi) += uE(e);
-      uV(vj) += uE(e);
-    }
-  }
-  
-  //Divide by valence
-  for(Int i=0; i<n; ++i) {
-    const Scalar valence = edgesPerVertex(i);
-    if(valence>0) {
-      uV(i) /= valence;
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::average_from_edges_onto_vertices<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::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::average_from_edges_onto_vertices<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::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::average_from_edges_onto_vertices<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::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 27
include/igl/average_onto_faces.cpp

@@ -1,27 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "average_onto_faces.h"
-
-template <typename DerivedF, typename DerivedS, typename DerivedSF>
-IGL_INLINE void igl::average_onto_faces(
-  const Eigen::MatrixBase<DerivedF> & F,
-  const Eigen::MatrixBase<DerivedS> & S,
-  Eigen::PlainObjectBase<DerivedSF> & SF)
-{
-  SF.setConstant(F.rows(),S.cols(),0);
-  for (int i = 0; i <F.rows(); ++i)
-    for (int j = 0; j<F.cols(); ++j)
-      SF.row(i) += S.row(F(i,j));
-  SF.array() /= F.cols();
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::average_onto_faces<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 33
include/igl/average_onto_vertices.cpp

@@ -1,33 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "average_onto_vertices.h"
-
-template<typename DerivedV,typename DerivedF,typename DerivedS,typename DerivedSV >
-IGL_INLINE void igl::average_onto_vertices(const Eigen::MatrixBase<DerivedV> &V,
-  const Eigen::MatrixBase<DerivedF> &F,
-  const Eigen::MatrixBase<DerivedS> &S,
-  Eigen::PlainObjectBase<DerivedSV> &SV)
-{
-  SV = DerivedS::Zero(V.rows(),S.cols());
-  Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> COUNT(V.rows());
-  COUNT.setZero();
-  for (int i = 0; i <F.rows(); ++i)
-  {
-    for (int j = 0; j<F.cols(); ++j)
-    {
-      SV.row(F(i,j)) += S.row(i);
-      COUNT[F(i,j)] ++;
-    }
-  }
-  for (int i = 0; i <V.rows(); ++i)
-    SV.row(i) /= COUNT[i];
-};
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#endif

+ 0 - 39
include/igl/avg_edge_length.cpp

@@ -1,39 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "avg_edge_length.h"
-#include "edges.h"
-
-#include <vector>
-
-template <typename DerivedV, typename DerivedF>
-IGL_INLINE double igl::avg_edge_length(
-  const Eigen::MatrixBase<DerivedV>& V,
-  const Eigen::MatrixBase<DerivedF>& F)
-{
-  typedef typename DerivedF::Scalar Index;
-  Eigen::Matrix<Index, Eigen::Dynamic, 2> E;
-
-  igl::edges(F, E);
-
-  double avg = 0;
-
-  for (unsigned i=0;i<E.rows();++i)
-  {
-    avg += (V.row(E(i,0)) - V.row(E(i,1))).norm();
-  }
-
-  return avg / (double) E.rows();
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template double igl::avg_edge_length<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template double igl::avg_edge_length<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
-// generated by autoexplicit.sh
-#endif

+ 0 - 42
include/igl/axis_angle_to_quat.cpp

@@ -1,42 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "axis_angle_to_quat.h"
-#include "EPS.h"
-#include <cmath>
-
-// http://www.antisphere.com/Wiki/tools:anttweakbar
-template <typename Q_type>
-IGL_INLINE void igl::axis_angle_to_quat(
-  const Q_type *axis, 
-  const Q_type angle,
-  Q_type *out)
-{
-    Q_type n = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2];
-    if( fabs(n)>igl::EPS<Q_type>())
-    {
-        Q_type f = 0.5*angle;
-        out[3] = cos(f);
-        f = sin(f)/sqrt(n);
-        out[0] = axis[0]*f;
-        out[1] = axis[1]*f;
-        out[2] = axis[2]*f;
-    }
-    else
-    {
-        out[3] = 1.0;
-        out[0] = out[1] = out[2] = 0.0;
-    }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::axis_angle_to_quat<double>(double const*, double, double*);
-// generated by autoexplicit.sh
-template void igl::axis_angle_to_quat<float>(float const*, float, float*);
-#endif

+ 0 - 58
include/igl/barycenter.cpp

@@ -1,58 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "barycenter.h"
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedBC>
-IGL_INLINE void igl::barycenter(
-    const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixBase<DerivedF> & F,
-    Eigen::PlainObjectBase<DerivedBC> & BC)
-{
-  BC.setZero(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());
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::barycenter<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-// generated by autoexplicit.sh
-template void igl::barycenter<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::barycenter<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-template void igl::barycenter<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
-template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::barycenter<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);
-template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-#endif

+ 0 - 113
include/igl/barycentric_coordinates.cpp

@@ -1,113 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2014 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "barycentric_coordinates.h"
-#include "volume.h"
-
-template <
-  typename DerivedP,
-  typename DerivedA,
-  typename DerivedB,
-  typename DerivedC,
-  typename DerivedD,
-  typename DerivedL>
-IGL_INLINE void igl::barycentric_coordinates(
-  const Eigen::MatrixBase<DerivedP> & P,
-  const Eigen::MatrixBase<DerivedA> & A,
-  const Eigen::MatrixBase<DerivedB> & B,
-  const Eigen::MatrixBase<DerivedC> & C,
-  const Eigen::MatrixBase<DerivedD> & D,
-  Eigen::PlainObjectBase<DerivedL> & L)
-{
-  using namespace Eigen;
-  assert(P.cols() == 3 && "query must be in 3d");
-  assert(A.cols() == 3 && "corners must be in 3d");
-  assert(B.cols() == 3 && "corners must be in 3d");
-  assert(C.cols() == 3 && "corners must be in 3d");
-  assert(D.cols() == 3 && "corners must be in 3d");
-  assert(P.rows() == A.rows() && "Must have same number of queries as corners");
-  assert(A.rows() == B.rows() && "Corners must be same size");
-  assert(A.rows() == C.rows() && "Corners must be same size");
-  assert(A.rows() == D.rows() && "Corners must be same size");
-  typedef Matrix<typename DerivedL::Scalar,DerivedL::RowsAtCompileTime,1> 
-    VectorXS;
-  // Total volume
-  VectorXS vol,LA,LB,LC,LD;
-  volume(B,D,C,P,LA);
-  volume(A,C,D,P,LB);
-  volume(A,D,B,P,LC);
-  volume(A,B,C,P,LD);
-  volume(A,B,C,D,vol);
-  L.resize(P.rows(),4);
-  L<<LA,LB,LC,LD;
-  L.array().colwise() /= vol.array();
-}
-
-template <
-  typename DerivedP,
-  typename DerivedA,
-  typename DerivedB,
-  typename DerivedC,
-  typename DerivedL>
-IGL_INLINE void igl::barycentric_coordinates(
-  const Eigen::MatrixBase<DerivedP> & P,
-  const Eigen::MatrixBase<DerivedA> & A,
-  const Eigen::MatrixBase<DerivedB> & B,
-  const Eigen::MatrixBase<DerivedC> & C,
-  Eigen::PlainObjectBase<DerivedL> & L)
-{
-  using namespace Eigen;
-#ifndef NDEBUG
-  const int DIM = P.cols();
-  assert(A.cols() == DIM && "corners must be in same dimension as query");
-  assert(B.cols() == DIM && "corners must be in same dimension as query");
-  assert(C.cols() == DIM && "corners must be in same dimension as query");
-  assert(P.rows() == A.rows() && "Must have same number of queries as corners");
-  assert(A.rows() == B.rows() && "Corners must be same size");
-  assert(A.rows() == C.rows() && "Corners must be same size");
-#endif
-
-  // http://gamedev.stackexchange.com/a/23745
-  typedef 
-    Eigen::Array<
-      typename DerivedP::Scalar,
-               DerivedP::RowsAtCompileTime,
-               DerivedP::ColsAtCompileTime>
-    ArrayS;
-  typedef 
-    Eigen::Array<
-      typename DerivedP::Scalar,
-               DerivedP::RowsAtCompileTime,
-               1>
-    VectorS;
-
-  const ArrayS v0 = B.array() - A.array();
-  const ArrayS v1 = C.array() - A.array();
-  const ArrayS v2 = P.array() - A.array();
-  VectorS d00 = (v0*v0).rowwise().sum();
-  VectorS d01 = (v0*v1).rowwise().sum();
-  VectorS d11 = (v1*v1).rowwise().sum();
-  VectorS d20 = (v2*v0).rowwise().sum();
-  VectorS d21 = (v2*v1).rowwise().sum();
-  VectorS denom = d00 * d11 - d01 * d01;
-  L.resize(P.rows(),3);
-  L.col(1) = (d11 * d20 - d01 * d21) / denom;
-  L.col(2) = (d00 * d21 - d01 * d20) / denom;
-  L.col(0) = 1.0f -(L.col(1) + L.col(2)).array();
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::barycentric_coordinates<Eigen::Matrix<float, 1, -1, 1, 1, -1>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
-template void igl::barycentric_coordinates<Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
-template void igl::barycentric_coordinates<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
-template void igl::barycentric_coordinates<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::barycentric_coordinates<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
-template void igl::barycentric_coordinates<Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
-template void igl::barycentric_coordinates<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
-template void igl::barycentric_coordinates<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 42
include/igl/barycentric_interpolation.cpp

@@ -1,42 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2020 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "barycentric_interpolation.h"
-#include "parallel_for.h"
-
-template <
-  typename DerivedD,
-  typename DerivedF,
-  typename DerivedB,
-  typename DerivedI,
-  typename DerivedX>
-IGL_INLINE void igl::barycentric_interpolation(
-  const Eigen::MatrixBase<DerivedD> & D,
-  const Eigen::MatrixBase<DerivedF> & F,
-  const Eigen::MatrixBase<DerivedB> & B,
-  const Eigen::MatrixBase<DerivedI> & I,
-  Eigen::PlainObjectBase<DerivedX> & X)
-{
-  assert(B.rows() == I.size());
-  assert(F.cols() == B.cols());
-  X.setZero(B.rows(),D.cols());
-  // should use parallel_for
-  //for(int i = 0;i<X.rows();i++)
-  parallel_for(X.rows(),[&X,&B,&D,&F,&I](const int i)
-  {
-    for(int j = 0;j<F.cols();j++)
-    {
-      X.row(i) += B(i,j) * D.row(F(I(i),j));
-    }
-  },1000);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::barycentric_interpolation<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<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 38
include/igl/basename.cpp

@@ -1,38 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "basename.h"
-
-#include <algorithm>
-
-IGL_INLINE std::string igl::basename(const std::string & path)
-{
-  if(path == "")
-  {
-    return std::string("");
-  }
-  // http://stackoverflow.com/questions/5077693/dirnamephp-similar-function-in-c
-  std::string::const_reverse_iterator last_slash =
-    std::find(
-      path.rbegin(), 
-      path.rend(), '/');
-  if( last_slash == path.rend() )
-  {
-    // No slashes found
-    return path;
-  }else if(1 == (last_slash.base() - path.begin()))
-  {
-    // Slash is first char
-    return std::string(path.begin()+1,path.end());
-  }else if(path.end() == last_slash.base() )
-  {
-    // Slash is last char
-    std::string redo = std::string(path.begin(),path.end()-1);
-    return igl::basename(redo);
-  }
-  return std::string(last_slash.base(),path.end());
-}

+ 0 - 144
include/igl/bbw.cpp

@@ -1,144 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "bbw.h"
-#include "min_quad_with_fixed.h"
-#include "harmonic.h"
-#include "parallel_for.h"
-#include <Eigen/Sparse>
-#include <iostream>
-#include <mutex>
-#include <cstdio>
-
-igl::BBWData::BBWData():
-  partition_unity(false),
-  W0(),
-  active_set_params(),
-  verbosity(0)
-{
-  // We know that the Bilaplacian is positive semi-definite
-  active_set_params.Auu_pd = true;
-}
-
-void igl::BBWData::print()
-{
-  using namespace std;
-  cout<<"partition_unity: "<<partition_unity<<endl;
-  cout<<"W0=["<<endl<<W0<<endl<<"];"<<endl;
-}
-
-
-template <
-  typename DerivedV,
-  typename DerivedEle,
-  typename Derivedb,
-  typename Derivedbc,
-  typename DerivedW>
-IGL_INLINE bool igl::bbw(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedEle> & Ele,
-  const Eigen::PlainObjectBase<Derivedb> & b,
-  const Eigen::PlainObjectBase<Derivedbc> & bc,
-  igl::BBWData & data,
-  Eigen::PlainObjectBase<DerivedW> & W
-  )
-{
-  using namespace std;
-  using namespace Eigen;
-  assert(!data.partition_unity && "partition_unity not implemented yet");
-  // number of domain vertices
-  int n = V.rows();
-  // number of handles
-  int m = bc.cols();
-  // Build biharmonic operator
-  Eigen::SparseMatrix<typename DerivedV::Scalar> Q;
-  harmonic(V,Ele,2,Q);
-  W.derived().resize(n,m);
-  // No linear terms
-  VectorXd c = VectorXd::Zero(n);
-  // No linear constraints
-  SparseMatrix<typename DerivedW::Scalar> A(0,n),Aeq(0,n),Aieq(0,n);
-  VectorXd Beq(0,1),Bieq(0,1);
-  // Upper and lower box constraints (Constant bounds)
-  VectorXd ux = VectorXd::Ones(n);
-  VectorXd lx = VectorXd::Zero(n);
-  active_set_params eff_params = data.active_set_params;
-  if(data.verbosity >= 1)
-  {
-    cout<<"BBW: max_iter: "<<data.active_set_params.max_iter<<endl;
-    cout<<"BBW: eff_max_iter: "<<eff_params.max_iter<<endl;
-  }
-  if(data.verbosity >= 1)
-  {
-    cout<<"BBW: Computing initial weights for "<<m<<" handle"<<
-      (m!=1?"s":"")<<"."<<endl;
-  }
-  min_quad_with_fixed_data<typename DerivedW::Scalar > mqwf;
-  min_quad_with_fixed_precompute(Q,b,Aeq,true,mqwf);
-  min_quad_with_fixed_solve(mqwf,c,bc,Beq,W);
-  // decrement
-  eff_params.max_iter--;
-  bool error = false;
-  // Loop over handles
-  std::mutex critical;
-  const auto & optimize_weight = [&](const int i)
-  {
-    // Quicker exit for paralle_for
-    if(error)
-    {
-      return;
-    }
-    if(data.verbosity >= 1)
-    {
-      std::lock_guard<std::mutex> lock(critical);
-      cout<<"BBW: Computing weight for handle "<<i+1<<" out of "<<m<<
-        "."<<endl;
-    }
-    VectorXd bci = bc.col(i);
-    VectorXd Wi;
-    // use initial guess
-    Wi = W.col(i);
-    SolverStatus ret = active_set(
-        Q,c,b,bci,Aeq,Beq,Aieq,Bieq,lx,ux,eff_params,Wi);
-    switch(ret)
-    {
-      case SOLVER_STATUS_CONVERGED:
-        break;
-      case SOLVER_STATUS_MAX_ITER:
-        cerr<<"active_set: max iter without convergence."<<endl;
-        break;
-      case SOLVER_STATUS_ERROR:
-      default:
-        cerr<<"active_set error."<<endl;
-        error = true;
-    }
-    W.col(i) = Wi;
-  };
-
-  parallel_for(m,optimize_weight,2);
-  if(error)
-  {
-    return false;
-  }
-
-#ifndef NDEBUG
-  const double min_rowsum = W.rowwise().sum().array().abs().minCoeff();
-  if(min_rowsum < 0.1)
-  {
-    cerr<<"bbw.cpp: Warning, minimum row sum is very low. Consider more "
-      "active set iterations or enforcing partition of unity."<<endl;
-  }
-#endif
-
-  return true;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::bbw<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<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<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, igl::BBWData&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif
-

+ 0 - 74
include/igl/bezier.cpp

@@ -1,74 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2020 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "bezier.h"
-#include <cassert>
-
-// Adapted from main.c accompanying
-// An Algorithm for Automatically Fitting Digitized Curves
-// by Philip J. Schneider
-// from "Graphics Gems", Academic Press, 1990
-template <typename DerivedV, typename DerivedP>
-IGL_INLINE void igl::bezier(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const typename DerivedV::Scalar t,
-  Eigen::PlainObjectBase<DerivedP> & P)
-{
-  // working local copy
-  DerivedV Vtemp = V;
-  int degree = Vtemp.rows()-1;
-  /* Triangle computation	*/
-  for (int i = 1; i <= degree; i++)
-  {	
-    for (int j = 0; j <= degree-i; j++) 
-    {
-      Vtemp.row(j) = ((1.0 - t) * Vtemp.row(j) + t * Vtemp.row(j+1)).eval();
-    }
-  }
-  P = Vtemp.row(0);
-}
-
-template <typename DerivedV, typename DerivedT, typename DerivedP>
-IGL_INLINE void igl::bezier(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedT> & T,
-  Eigen::PlainObjectBase<DerivedP> & P)
-{
-  P.resize(T.size(),V.cols());
-  for(int i = 0;i<T.size();i++)
-  {
-    Eigen::Matrix<typename DerivedV::Scalar,1,DerivedV::ColsAtCompileTime> Pi;
-    bezier(V,T(i),Pi);
-    P.row(i) = Pi;
-  }
-}
-
-template <typename VMat, typename DerivedT, typename DerivedP>
-IGL_INLINE void igl::bezier(
-  const std::vector<VMat> & spline,
-  const Eigen::MatrixBase<DerivedT> & T,
-  Eigen::PlainObjectBase<DerivedP> & P)
-{
-  if(spline.size() == 0) return;
-  const int m = T.rows();
-  const int dim = spline[0].cols();
-  P.resize(m*spline.size(),dim);
-  for(int c = 0;c<spline.size();c++)
-  {
-    assert(dim == spline[c].cols() && "All curves must have same dimension");
-    DerivedP Pc;
-    bezier(spline[c],T,Pc);
-    P.block(m*c,0,m,dim) = Pc;
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::bezier<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::bezier<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::bezier<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&);
-#endif

+ 0 - 93
include/igl/bfs.cpp

@@ -1,93 +0,0 @@
-#include "bfs.h"
-#include "list_to_matrix.h"
-#include <vector>
-#include <queue>
-
-template <
-  typename AType,
-  typename DerivedD,
-  typename DerivedP>
-IGL_INLINE void igl::bfs(
-  const AType & A,
-  const size_t s,
-  Eigen::PlainObjectBase<DerivedD> & D,
-  Eigen::PlainObjectBase<DerivedP> & P)
-{
-  std::vector<typename DerivedD::Scalar> vD;
-  std::vector<typename DerivedP::Scalar> vP;
-  bfs(A,s,vD,vP);
-  list_to_matrix(vD,D);
-  list_to_matrix(vP,P);
-}
-
-template <
-  typename AType,
-  typename DType,
-  typename PType>
-IGL_INLINE void igl::bfs(
-  const std::vector<std::vector<AType> > & A,
-  const size_t s,
-  std::vector<DType> & D,
-  std::vector<PType> & P)
-{
-  // number of nodes
-  int N = s+1;
-  for(const auto & Ai : A) for(const auto & a : Ai) N = std::max(N,a+1);
-  std::vector<bool> seen(N,false);
-  P.resize(N,-1);
-  std::queue<std::pair<int,int> > Q;
-  Q.push({s,-1});
-  while(!Q.empty())
-  {
-    const int f = Q.front().first;
-    const int p = Q.front().second;
-    Q.pop();
-    if(seen[f])
-    {
-      continue;
-    }
-    D.push_back(f);
-    P[f] = p;
-    seen[f] = true;
-    for(const auto & n : A[f]) Q.push({n,f});
-  }
-}
-
-
-template <
-  typename AType,
-  typename DType,
-  typename PType>
-IGL_INLINE void igl::bfs(
-  const Eigen::SparseCompressedBase<AType> & A,
-  const size_t s,
-  std::vector<DType> & D,
-  std::vector<PType> & P)
-{
-  // number of nodes
-  int N = A.rows();
-  assert(A.rows() == A.cols());
-  std::vector<bool> seen(N,false);
-  P.resize(N,-1);
-  std::queue<std::pair<int,int> > Q;
-  Q.push({s,-1});
-  while(!Q.empty())
-  {
-    const int f = Q.front().first;
-    const int p = Q.front().second;
-    Q.pop();
-    if(seen[f])
-    {
-      continue;
-    }
-    D.push_back(f);
-    P[f] = p;
-    seen[f] = true;
-    for(typename AType::InnerIterator it (A,f); it; ++it)
-    {
-      if(it.value()) Q.push({it.index(),f});
-    }
-  }
-
-}
-

+ 0 - 100
include/igl/bfs_orient.cpp

@@ -1,100 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "bfs_orient.h"
-#include "orientable_patches.h"
-#include "parallel_for.h"
-#include <Eigen/Sparse>
-#include <queue>
-
-template <typename DerivedF, typename DerivedFF, typename DerivedC>
-IGL_INLINE void igl::bfs_orient(
-  const Eigen::MatrixBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedFF> & FF,
-  Eigen::PlainObjectBase<DerivedC> & C)
-{
-  using namespace Eigen;
-  using namespace std;
-  SparseMatrix<typename DerivedF::Scalar> A;
-  orientable_patches(F,C,A);
-
-  // number of faces
-  const int m = F.rows();
-  // number of patches
-  const int num_cc = C.maxCoeff()+1;
-  VectorXi seen = VectorXi::Zero(m);
-
-  // Edge sets
-  const int ES[3][2] = {{1,2},{2,0},{0,1}};
-
-  if(((void*)&FF) != ((void*)&F))
-  {
-    FF = F;
-  }
-  // loop over patches
-  parallel_for(num_cc,[&](const int c)
-  {
-    queue<typename DerivedF::Scalar> Q;
-    // find first member of patch c
-    for(int f = 0;f<FF.rows();f++)
-    {
-      if(C(f) == c)
-      {
-        Q.push(f);
-        break;
-      }
-    }
-    assert(!Q.empty());
-    while(!Q.empty())
-    {
-      const typename DerivedF::Scalar f = Q.front();
-      Q.pop();
-      if(seen(f) > 0)
-      {
-        continue;
-      }
-      seen(f)++;
-      // loop over neighbors of f
-      for(typename SparseMatrix<typename DerivedF::Scalar>::InnerIterator it (A,f); it; ++it)
-      {
-        // might be some lingering zeros, and skip self-adjacency
-        if(it.value() != 0 && it.row() != f)
-        {
-          const int n = it.row();
-          assert(n != f);
-          // loop over edges of f
-          for(int efi = 0;efi<3;efi++)
-          {
-            // efi'th edge of face f
-            Vector2i ef(FF(f,ES[efi][0]),FF(f,ES[efi][1]));
-            // loop over edges of n
-            for(int eni = 0;eni<3;eni++)
-            {
-              // eni'th edge of face n
-              Vector2i en(FF(n,ES[eni][0]),FF(n,ES[eni][1]));
-              // Match (half-edges go same direction)
-              if(ef(0) == en(0) && ef(1) == en(1))
-              {
-                // flip face n
-                FF.row(n) = FF.row(n).reverse().eval();
-              }
-            }
-          }
-          // add neighbor to queue
-          Q.push(n);
-        }
-      }
-    }
-  },1000);
-
-  // make sure flip is OK if &FF = &F
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::bfs_orient<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::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 207
include/igl/biharmonic_coordinates.cpp

@@ -1,207 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "biharmonic_coordinates.h"
-#include "cotmatrix.h"
-#include "sum.h"
-#include "massmatrix.h"
-#include "min_quad_with_fixed.h"
-#include "crouzeix_raviart_massmatrix.h"
-#include "crouzeix_raviart_cotmatrix.h"
-#include "normal_derivative.h"
-#include "on_boundary.h"
-#include <Eigen/Sparse>
-
-template <
-  typename DerivedV,
-  typename DerivedT,
-  typename SType,
-  typename DerivedW>
-IGL_INLINE bool igl::biharmonic_coordinates(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedT> & T,
-  const std::vector<std::vector<SType> > & S,
-  Eigen::PlainObjectBase<DerivedW> & W)
-{
-  return biharmonic_coordinates(V,T,S,2,W);
-}
-
-template <
-  typename DerivedV,
-  typename DerivedT,
-  typename SType,
-  typename DerivedW>
-IGL_INLINE bool igl::biharmonic_coordinates(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedT> & T,
-  const std::vector<std::vector<SType> > & S,
-  const int k,
-  Eigen::PlainObjectBase<DerivedW> & W)
-{
-  using namespace Eigen;
-  using namespace std;
-
-  typedef typename DerivedV::Scalar Scalar;
-  typedef typename DerivedT::Scalar Integer;
-
-  // This is not the most efficient way to build A, but follows "Linear
-  // Subspace Design for Real-Time Shape Deformation" [Wang et al. 2015].
-  SparseMatrix<Scalar> A;
-  {
-    DiagonalMatrix<Scalar, Dynamic> Minv;
-    SparseMatrix<Scalar> L, K;
-    Array<bool,Dynamic,Dynamic> C;
-    {
-      Array<bool,Dynamic,1> I;
-      on_boundary(T,I,C);
-    }
-#ifdef false
-    // Version described in paper is "wrong"
-    // http://www.cs.toronto.edu/~jacobson/images/error-in-linear-subspace-design-for-real-time-shape-deformation-2017-wang-et-al.pdf
-    SparseMatrix<Scalar> N, Z, M;
-    normal_derivative(V,T,N);
-    {
-      std::vector<Triplet<Scalar>> ZIJV;
-      for(int t =0;t<T.rows();t++)
-      {
-        for(int f =0;f<T.cols();f++)
-        {
-          if(C(t,f))
-          {
-            const int i = t+f*T.rows();
-            for(int c = 1;c<T.cols();c++)
-            {
-              ZIJV.emplace_back(T(t,(f+c)%T.cols()),i,1);
-            }
-          }
-        }
-      }
-      Z.resize(V.rows(),N.rows());
-      Z.setFromTriplets(ZIJV.begin(),ZIJV.end());
-      N = (Z*N).eval();
-    }
-    cotmatrix(V,T,L);
-    K = N+L;
-    massmatrix(V,T,MASSMATRIX_TYPE_DEFAULT,M);
-    // normalize
-    M /= ((Matrix<Scalar, Dynamic, 1>)M.diagonal()).array().abs().maxCoeff();
-    Minv =
-      ((Matrix<Scalar, Dynamic, 1>)M.diagonal().array().inverse()).asDiagonal();
-#else
-    Eigen::SparseMatrix<Scalar> M;
-    Eigen::Matrix<Integer, Dynamic, Dynamic> E;
-    Eigen::Matrix<Integer, Dynamic, 1> EMAP;
-    crouzeix_raviart_massmatrix(V,T,M,E,EMAP);
-    crouzeix_raviart_cotmatrix(V,T,E,EMAP,L);
-    // Ad  #E by #V facet-vertex incidence matrix
-    Eigen::SparseMatrix<Scalar> Ad(E.rows(),V.rows());
-    {
-      std::vector<Eigen::Triplet<Scalar>> AIJV(E.size());
-      for(int e = 0;e<E.rows();e++)
-      {
-        for(int c = 0;c<E.cols();c++)
-        {
-          AIJV[e + c * E.rows()] = Eigen::Triplet<Scalar>(e, E(e, c), 1);
-        }
-      }
-      Ad.setFromTriplets(AIJV.begin(),AIJV.end());
-    }
-    // Degrees
-    Eigen::Matrix<Scalar, Dynamic, 1> De;
-    sum(Ad,2,De);
-    Eigen::DiagonalMatrix<Scalar,Eigen::Dynamic> De_diag =
-      De.array().inverse().matrix().asDiagonal();
-    K = L*(De_diag*Ad);
-    // normalize
-    M /= ((Matrix<Scalar, Dynamic, 1>)M.diagonal()).array().abs().maxCoeff();
-    Minv = ((Matrix<Scalar, Dynamic, 1>)M.diagonal().array().inverse()).asDiagonal();
-    // kill boundary edges
-    for(int f = 0;f<T.rows();f++)
-    {
-      for(int c = 0;c<T.cols();c++)
-      {
-        if(C(f,c))
-        {
-          const int e = EMAP(f+T.rows()*c);
-          Minv.diagonal()(e) = 0;
-        }
-      }
-    }
-
-#endif
-    switch(k)
-    {
-      default:
-        assert(false && "unsupported");
-      case 2:
-        // For C1 smoothness in 2D, one should use bi-harmonic
-        A = K.transpose() * (Minv * K);
-        break;
-      case 3:
-        // For C1 smoothness in 3D, one should use tri-harmonic
-        A = K.transpose() * (Minv * (-L * (Minv * K)));
-        break;
-    }
-  }
-  // Vertices in point handles
-  const size_t mp =
-    count_if(S.begin(),S.end(),[](const vector<int> & h){return h.size()==1;});
-  // number of region handles
-  const size_t r = S.size()-mp;
-  // Vertices in region handles
-  size_t mr = 0;
-  for(const auto & h : S)
-  {
-    if(h.size() > 1)
-    {
-      mr += h.size();
-    }
-  }
-  const size_t dim = T.cols()-1;
-  // Might as well be dense... I think...
-  Matrix<Scalar, Dynamic, Dynamic> J = Matrix<Scalar, Dynamic, Dynamic>::Zero(mp+mr,mp+r*(dim+1));
-  Matrix<Integer, Dynamic, 1> b(mp+mr);
-  Matrix<Scalar, Dynamic, Dynamic> H(mp+r*(dim+1),dim);
-  {
-    int v = 0;
-    int c = 0;
-    for(int h = 0;h<S.size();h++)
-    {
-      if(S[h].size()==1)
-      {
-        H.row(c) = V.block(S[h][0],0,1,dim);
-        J(v,c++) = 1;
-        b(v) = S[h][0];
-        v++;
-      }else
-      {
-        assert(S[h].size() >= dim+1);
-        for(int p = 0;p<S[h].size();p++)
-        {
-          for(int d = 0;d<dim;d++)
-          {
-            J(v,c+d) = V(S[h][p],d);
-          }
-          J(v,c+dim) = 1;
-          b(v) = S[h][p];
-          v++;
-        }
-        H.block(c,0,dim+1,dim).setIdentity();
-        c+=dim+1;
-      }
-    }
-  }
-  // minimize    ½ W' A W'
-  // subject to  W(b,:) = J
-  return min_quad_with_fixed(
-    A,Matrix<Scalar, Dynamic, 1>::Zero(A.rows()).eval(),b,J,SparseMatrix<Scalar>(),Matrix<Scalar, Dynamic, 1>(),true,W);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::biharmonic_coordinates<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 115
include/igl/bijective_composite_harmonic_mapping.cpp

@@ -1,115 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2017 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "bijective_composite_harmonic_mapping.h"
-
-#include "slice.h"
-#include "doublearea.h"
-#include "harmonic.h"
-//#include "matlab/MatlabWorkspace.h"
-#include <iostream>
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Derivedb,
-  typename Derivedbc,
-  typename DerivedU>
-IGL_INLINE bool igl::bijective_composite_harmonic_mapping(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedF> & F,
-  const Eigen::MatrixBase<Derivedb> & b,
-  const Eigen::MatrixBase<Derivedbc> & bc,
-  Eigen::PlainObjectBase<DerivedU> & U)
-{
-  return bijective_composite_harmonic_mapping(V,F,b,bc,1,200,20,true,U);
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Derivedb,
-  typename Derivedbc,
-  typename DerivedU>
-IGL_INLINE bool igl::bijective_composite_harmonic_mapping(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedF> & F,
-  const Eigen::MatrixBase<Derivedb> & b,
-  const Eigen::MatrixBase<Derivedbc> & bc,
-  const int min_steps,
-  const int max_steps,
-  const int num_inner_iters,
-  const bool test_for_flips,
-  Eigen::PlainObjectBase<DerivedU> & U)
-{
-  typedef typename Derivedbc::Scalar Scalar;
-  assert(V.cols() == 2 && bc.cols() == 2 && "Input should be 2D");
-  assert(F.cols() == 3 && "F should contain triangles");
-  int tries = 0;
-  int nsteps = min_steps;
-  Eigen::Matrix<typename Derivedbc::Scalar, Eigen::Dynamic, Eigen::Dynamic> bc0;
-  slice(V,b.col(0),1,bc0);
-
-  // It's difficult to check for flips "robustly" in the sense that the input
-  // mesh might not have positive/consistent sign to begin with.
-
-  while(nsteps<=max_steps)
-  {
-    U = V;
-    int flipped = 0;
-    int nans = 0;
-    int step = 0;
-    for(;step<=nsteps;step++)
-    {
-      const Scalar t = ((Scalar)step)/((Scalar)nsteps);
-      // linearly interpolate boundary conditions
-      // TODO: replace this with something that guarantees a homotopic "morph"
-      // of the boundary conditions. Something like "Homotopic Morphing of
-      // Planar Curves" [Dym et al. 2015] but also handling multiple connected
-      // components.
-      Eigen::Matrix<typename Derivedbc::Scalar, Eigen::Dynamic, Eigen::Dynamic> bct = bc0 + t * (bc - bc0);
-      // Compute dsicrete harmonic map using metric of previous step
-      for(int iter = 0;iter<num_inner_iters;iter++)
-      {
-        //std::cout<<nsteps<<" t: "<<t<<" iter: "<<iter;
-        //igl::matlab::MatlabWorkspace mw;
-        //mw.save(U,"U");
-        //mw.save_index(F,"F");
-        //mw.save_index(b,"b");
-        //mw.save(bct,"bct");
-        //mw.write("numerical.mat");
-        harmonic(Eigen::Matrix<typename DerivedU::Scalar, Eigen::Dynamic, Eigen::Dynamic>(U), F, b, bct, 1, U);
-        igl::slice(U,b.col(0),1,bct);
-        nans = (U.array() != U.array()).count();
-        if(test_for_flips)
-        {
-          Eigen::Matrix<Scalar,Eigen::Dynamic,1> A;
-          doublearea(U,F,A);
-          flipped = (A.array() < 0 ).count();
-          //std::cout<<"  "<<flipped<<"  nan? "<<(U.array() != U.array()).any()<<std::endl;
-          if(flipped == 0 && nans == 0) break;
-        }
-      }
-      if(flipped > 0 || nans>0) break;
-    }
-    if(flipped == 0 && nans == 0)
-    {
-      return step == nsteps+1;
-    }
-    nsteps *= 2;
-  }
-  //std::cout<<"failed to finish in "<<nsteps<<"..."<<std::endl;
-  return false;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template bool igl::bijective_composite_harmonic_mapping<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&);
-// generated by autoexplicit.sh
-template bool igl::bijective_composite_harmonic_mapping<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, int, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&);
-#endif

+ 0 - 71
include/igl/blkdiag.cpp

@@ -1,71 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2020 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "blkdiag.h"
-
-template <typename Scalar>
-IGL_INLINE void igl::blkdiag(
-  const std::vector<Eigen::SparseMatrix<Scalar>> & L, 
-  Eigen::SparseMatrix<Scalar> & Y)
-{
-  int nr = 0;
-  int nc = 0;
-  int nnz = 0;
-  for(const auto & A : L)
-  {
-    nr += A.rows();
-    nc += A.cols();
-  }
-  Y.resize(nr,nc);
-  {
-    int i = 0;
-    int j = 0;
-    for(const auto & A : L)
-    {
-      for(int k = 0;k<A.outerSize();++k)
-      {
-        for(typename Eigen::SparseMatrix<Scalar>::InnerIterator it(A,k);it;++it)
-        {
-           Y.insert(i+it.row(),j+k) = it.value();
-        }
-      }
-      i += A.rows();
-      j += A.cols();
-    }
-  }
-}
-
-template <typename DerivedY>
-IGL_INLINE void igl::blkdiag(
-  const std::vector<DerivedY> & L, 
-  Eigen::PlainObjectBase<DerivedY> & Y)
-{
-  int nr = 0;
-  int nc = 0;
-  for(const auto & A : L)
-  {
-    nr += A.rows();
-    nc += A.cols();
-  }
-  Y.setZero(nr,nc);
-  {
-    int i = 0;
-    int j = 0;
-    for(const auto & A : L)
-    {
-      Y.block(i,j,A.rows(),A.cols()) = A;
-      i += A.rows();
-      j += A.cols();
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// explicit template instantiations
-template void igl::blkdiag<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::blkdiag<double>(std::vector<Eigen::SparseMatrix<double, 0, int>, std::allocator<Eigen::SparseMatrix<double, 0, int> > > const&, Eigen::SparseMatrix<double, 0, int>&);
-#endif

+ 0 - 379
include/igl/blue_noise.cpp

@@ -1,379 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2020 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "blue_noise.h"
-#include "doublearea.h"
-#include "random_points_on_mesh.h"
-#include "slice.h"
-#include "sortrows.h"
-#include "PI.h"
-#include "get_seconds.h"
-#include <unordered_map>
-#include <algorithm>
-#include <vector>
-#include <random>
-
-namespace igl
-{
-  // It is very important that we use 64bit keys to avoid out of bounds (easy to
-  // get to happen with dense samplings (e.g., r = 0.0005*bbd)
-  typedef int64_t BlueNoiseKeyType;
-}
-
-// Helper functions
-namespace igl
-{
-  // Should probably find and replace with less generic name
-  //
-  // Map 3D subscripts (x,y,z) to unique index (return value)
-  //
-  // Inputs:
-  //   w  side length of w×w×w integer cube lattice
-  //   x  subscript along x direction
-  //   y  subscript along y direction
-  //   z  subscript along z direction
-  // Returns index value
-  //
-  inline BlueNoiseKeyType blue_noise_key(
-    const BlueNoiseKeyType w, // pass by copy --> int64_t so that multiplication is OK
-    const BlueNoiseKeyType x, // pass by copy --> int64_t so that multiplication is OK
-    const BlueNoiseKeyType y, // pass by copy --> int64_t so that multiplication is OK
-    const BlueNoiseKeyType z) // pass by copy --> int64_t so that multiplication is OK
-  {
-    return x+w*(y+w*z);
-  }
-  // Determine if a query candidate at position X.row(i) is too close to already
-  // selected sites (stored in S).
-  //
-  // Inputs:
-  //   X  #X by 3 list of raw candidate positions
-  //   Xs  #Xs by 3 list of corresponding integer cell subscripts
-  //   i  index of candidate in question
-  //   S   map from cell index to index into X of selected candidate (or -1 if
-  //     cell is currently empty)
-  //   rr  Poisson disk radius squared
-  //   w  side length of w×w×w integer cube lattice (into which Xs subscripts)
-  template <
-    typename DerivedX,
-    typename DerivedXs>
-  inline bool blue_noise_far_enough(
-    const Eigen::MatrixBase<DerivedX> & X,
-    const Eigen::MatrixBase<DerivedXs> & Xs,
-    const std::unordered_map<BlueNoiseKeyType,int> & S,
-    const double & rr,
-    const int & w,
-    const int i)
-  {
-    const int xi = Xs(i,0);
-    const int yi = Xs(i,1);
-    const int zi = Xs(i,2);
-    BlueNoiseKeyType k = blue_noise_key(w,xi,yi,zi);
-    int g = 2; // ceil(r/s)
-    for(int x = std::max(xi-g,0);x<=std::min(xi+g,w-1);x++)
-    for(int y = std::max(yi-g,0);y<=std::min(yi+g,w-1);y++)
-    for(int z = std::max(zi-g,0);z<=std::min(zi+g,w-1);z++)
-    {
-      if(x!=xi || y!=yi || z!=zi)
-      {
-        const BlueNoiseKeyType nk = blue_noise_key(w,x,y,z);
-        // have already selected from this cell
-        const auto Siter = S.find(nk);
-        if(Siter !=S.end() && Siter->second >= 0)
-        {
-          const int ni = Siter->second;
-          // too close
-          if( (X.row(i)-X.row(ni)).squaredNorm() < rr)
-          {
-            return false;
-          }
-        }
-      }
-    }
-    return true;
-  }
-  // Try to activate a candidate in a given cell
-  //
-  // Inputs:
-  //   X  #X by 3 list of raw candidate positions
-  //   Xs  #Xs by 3 list of corresponding integer cell subscripts
-  //   rr  Poisson disk radius squared
-  //   w  side length of w×w×w integer cube lattice (into which Xs subscripts)
-  //   nk  index of cell in which we'd like to activate a candidate
-  //   M   map from cell index to list of candidates
-  //   S   map from cell index to index into X of selected candidate (or -1 if
-  //     cell is currently empty)
-  //   active   list of indices into X of active candidates
-  // Outputs:
-  //   M  visited candidates deemed too close to already selected points are
-  //      removed
-  //   S  updated to reflect activated point (if successful)
-  //   active   updated to reflect activated point (if successful)
-  // Returns true iff activation was successful
-  template <
-    typename DerivedX,
-    typename DerivedXs>
-  inline bool activate(
-    const Eigen::MatrixBase<DerivedX> & X,
-    const Eigen::MatrixBase<DerivedXs> & Xs,
-    const double & rr,
-    const int & i,
-    const int & w,
-    const BlueNoiseKeyType & nk,
-    std::unordered_map<BlueNoiseKeyType,std::vector<int> > & M,
-    std::unordered_map<BlueNoiseKeyType,int> & S,
-    std::vector<int> & active)
-  {
-    assert(M.count(nk));
-    auto & Mvec = M.find(nk)->second;
-    auto miter = Mvec.begin();
-    while(miter != Mvec.end())
-    {
-      const int mi = *miter;
-      // mi is our candidate sample. Is it far enough from all existing
-      // samples?
-      if(i>=0 && (X.row(i)-X.row(mi)).squaredNorm() > 4.*rr)
-      {
-        // too far skip (reject)
-       miter++;
-      } else if(blue_noise_far_enough(X,Xs,S,rr,w,mi))
-      {
-        active.push_back(mi);
-        S.find(nk)->second = mi;
-        //printf("  found %d\n",mi);
-        return true;
-      }else
-      {
-        // remove forever (instead of incrementing we swap and eat from the
-        // back)
-        //std::swap(*miter,Mvec.back());
-        *miter = Mvec.back();
-        bool was_last = (std::next(miter) == Mvec.end());
-        Mvec.pop_back();
-        if (was_last) {
-          // popping from the vector can invalidate the iterator, if it was
-          // pointing to the last element that was popped. Alternatively,
-          // one could use indices directly...
-          miter = Mvec.end();
-        }
-      }
-    }
-    return false;
-  }
-
-  template <
-    typename DerivedX,
-    typename DerivedXs,
-    typename URBG>
-  inline bool step(
-    const Eigen::MatrixBase<DerivedX> & X,
-    const Eigen::MatrixBase<DerivedXs> & Xs,
-    const double & rr,
-    const int & w,
-    URBG && urbg,
-    std::unordered_map<BlueNoiseKeyType,std::vector<int> > & M,
-    std::unordered_map<BlueNoiseKeyType,int> & S,
-    std::vector<int> & active,
-    std::vector<int> & collected
-    )
-  {
-    //considered.clear();
-    if(active.size() == 0) return false;
-    // random entry
-    std::uniform_int_distribution<> dis(0, active.size()-1);
-    const int e = dis(urbg);
-    const int i = active[e];
-    //printf("%d\n",i);
-    const int xi = Xs(i,0);
-    const int yi = Xs(i,1);
-    const int zi = Xs(i,2);
-    //printf("%d %d %d - %g %g %g\n",xi,yi,zi,X(i,0),X(i,1),X(i,2));
-    // cell indices of neighbors
-    int g = 4;
-    std::vector<BlueNoiseKeyType> N;N.reserve((1+g*1)^3-1);
-    for(int x = std::max(xi-g,0);x<=std::min(xi+g,w-1);x++)
-    for(int y = std::max(yi-g,0);y<=std::min(yi+g,w-1);y++)
-    for(int z = std::max(zi-g,0);z<=std::min(zi+g,w-1);z++)
-    {
-      if(x!=xi || y!=yi || z!=zi)
-      {
-        //printf("  %d %d %d\n",x,y,z);
-        const BlueNoiseKeyType nk = blue_noise_key(w,x,y,z);
-        // haven't yet selected from this cell?
-        const auto Siter = S.find(nk);
-        if(Siter !=S.end() && Siter->second < 0)
-        {
-          assert(M.find(nk) != M.end());
-          N.emplace_back(nk);
-        }
-      }
-    }
-        //printf("  --------\n");
-    // randomize order: this might be a little paranoid...
-    std::shuffle(std::begin(N), std::end(N), urbg);
-    bool found = false;
-    for(const BlueNoiseKeyType & nk : N)
-    {
-      assert(M.find(nk) != M.end());
-      if(activate(X,Xs,rr,i,w,nk,M,S,active))
-      {
-        found = true;
-        break;
-      }
-    }
-    if(!found)
-    {
-      // remove i from active list
-      // https://stackoverflow.com/a/60765833/148668
-      collected.push_back(i);
-      //printf("  before: "); for(const int j : active) { printf("%d ",j); } printf("\n");
-      std::swap(active[e], active.back());
-      //printf("  after : "); for(const int j : active) { printf("%d ",j); } printf("\n");
-      active.pop_back();
-      //printf("  removed %d\n",i);
-    }
-    //printf("  active: "); for(const int j : active) { printf("%d ",j); } printf("\n");
-    return true;
-  }
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedB,
-  typename DerivedFI,
-  typename DerivedP,
-  typename URBG>
-IGL_INLINE void igl::blue_noise(
-    const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixBase<DerivedF> & F,
-    const typename DerivedV::Scalar r,
-    Eigen::PlainObjectBase<DerivedB> & B,
-    Eigen::PlainObjectBase<DerivedFI> & FI,
-    Eigen::PlainObjectBase<DerivedP> & P,
-    URBG && urbg)
-{
-  typedef typename DerivedV::Scalar Scalar;
-  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1> VectorXS;
-  // float+RowMajor is faster...
-  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3,Eigen::RowMajor> MatrixX3S;
-  assert(V.cols() == 3 && "Only 3D embeddings allowed");
-  // minimum radius
-  const Scalar min_r = r;
-  // cell size based on 3D distance
-  // It works reasonably well (but is probably biased to use s=2*r/√3 here and
-  // g=1 in the outer loop below.
-  //
-  // One thing to try would be to store a list in S (rather than a single point)
-  // or equivalently a mask over M and just use M as a generic spatial hash
-  // (with arbitrary size) and then tune its size (being careful to make g a
-  // function of r and s; and removing the `if S=-1 checks`)
-  const Scalar s = r/sqrt(3.0);
-
-  const double area =
-    [&](){Eigen::VectorXd A;igl::doublearea(V,F,A);return A.array().sum()/2;}();
-  // Circle packing in the plane has igl::PI*sqrt(3)/6 efficiency
-  const double expected_number_of_points =
-    area * (igl::PI * sqrt(3.0) / 6.0) / (igl::PI * min_r * min_r / 4.0);
-
-  // Make a uniform random sampling with 30*expected_number_of_points.
-  const int nx = 30.0*expected_number_of_points;
-  MatrixX3S X,XB;
-  Eigen::VectorXi XFI;
-  igl::random_points_on_mesh(nx,V,F,XB,XFI,X,urbg);
-
-  // Rescale so that s = 1
-  Eigen::Matrix<int,Eigen::Dynamic,3,Eigen::RowMajor> Xs =
-    ((X.rowwise()-X.colwise().minCoeff())/s).template cast<int>();
-  const int w = Xs.maxCoeff()+1;
-  {
-    Eigen::VectorXi I;
-    igl::sortrows(decltype(Xs)(Xs),true,Xs,I);
-    igl::slice(decltype(X)(X),I,1,X);
-    // These two could be spun off in their own thread.
-    igl::slice(decltype(XB)(XB),I,1,XB);
-    igl::slice(decltype(XFI)(XFI),I,1,XFI);
-  }
-  // Initialization
-  std::unordered_map<BlueNoiseKeyType,std::vector<int> > M;
-  std::unordered_map<BlueNoiseKeyType, int > S;
-  // attempted to seed
-  std::unordered_map<BlueNoiseKeyType, int > A;
-  // Q: Too many?
-  // A: Seems to help though.
-  M.reserve(Xs.rows());
-  S.reserve(Xs.rows());
-  for(int i = 0;i<Xs.rows();i++)
-  {
-    BlueNoiseKeyType k = blue_noise_key(w,Xs(i,0),Xs(i,1),Xs(i,2));
-    const auto Miter = M.find(k);
-    if(Miter  == M.end())
-    {
-      M.insert({k,{i}});
-    }else
-    {
-      Miter->second.push_back(i);
-    }
-    S.emplace(k,-1);
-    A.emplace(k,false);
-  }
-
-  std::vector<int> active;
-  // precompute r²
-  // Q: is this necessary?
-  const double rr = r*r;
-  std::vector<int> collected;
-  collected.reserve(2.0*expected_number_of_points);
-
-  auto Mouter = M.begin();
-  // Just take the first point as the initial seed
-  const auto initialize = [&]()->bool
-  {
-    while(true)
-    {
-      if(Mouter == M.end())
-      {
-        return false;
-      }
-      const BlueNoiseKeyType k = Mouter->first;
-      // Haven't placed in this cell yet
-      if(S[k]<0)
-      {
-        if(activate(X,Xs,rr,-1,w,k,M,S,active)) return true;
-      }
-      Mouter++;
-    }
-    assert(false && "should not be reachable.");
-  };
-
-  // important if mesh contains many connected components
-  while(initialize())
-  {
-    while(active.size()>0)
-    {
-      step(X,Xs,rr,w,urbg,M,S,active,collected);
-    }
-  }
-  {
-    const int n = collected.size();
-    P.resize(n,3);
-    B.resize(n,3);
-    FI.resize(n);
-    for(int i = 0;i<n;i++)
-    {
-      const int c = collected[i];
-      P.row(i) = X.row(c).template cast<typename DerivedP::Scalar>();
-      B.row(i) = XB.row(c).template cast<typename DerivedB::Scalar>();
-      FI(i) = XFI(c);
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::blue_noise<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<double, -1, -1, 0, -1, -1>, std::mt19937_64 >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, 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> >&, std::mt19937_64&&);
-template void igl::blue_noise<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<double, -1, -1, 0, -1, -1>, std::mt19937 >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, 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> >&, std::mt19937&&);
-#endif

+ 0 - 32
include/igl/bone_parents.cpp

@@ -1,32 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "bone_parents.h"
-
-template <typename DerivedBE, typename DerivedP>
-IGL_INLINE void igl::bone_parents(
-  const Eigen::MatrixBase<DerivedBE>& BE,
-  Eigen::PlainObjectBase<DerivedP>& P)
-{
-  P.resize(BE.rows(),1);
-  // Stupid O(n²) version
-  for(int e = 0;e<BE.rows();e++)
-  {
-    P(e) = -1;
-    for(int f = 0;f<BE.rows();f++)
-    {
-      if(BE(e,0) == BE(f,1))
-      {
-        P(e) = f;
-      }
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-template void igl::bone_parents<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 245
include/igl/boundary_conditions.cpp

@@ -1,245 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "boundary_conditions.h"
-
-#include "verbose.h"
-#include "EPS.h"
-#include "project_to_line.h"
-
-#include <vector>
-#include <map>
-#include <iostream>
-
-IGL_INLINE bool igl::boundary_conditions(
-  const Eigen::MatrixXd & V  ,
-  const Eigen::MatrixXi & /*Ele*/,
-  const Eigen::MatrixXd & C  ,
-  const Eigen::VectorXi & P  ,
-  const Eigen::MatrixXi & BE ,
-  const Eigen::MatrixXi & CE ,
-  const Eigen::MatrixXi & CF ,
-  Eigen::VectorXi &       b  ,
-  Eigen::MatrixXd &       bc )
-{
-  using namespace Eigen;
-  using namespace std;
-
-  if(P.size()+BE.rows() == 0)
-  {
-    verbose("^%s: Error: no handles found\n",__FUNCTION__);
-    return false;
-  }
-
-  vector<int> bci;
-  vector<int> bcj;
-  vector<double> bcv;
-
-  // loop over points
-  for(int p = 0;p<P.size();p++)
-  {
-    VectorXd pos = C.row(P(p));
-    // loop over domain vertices
-    for(int i = 0;i<V.rows();i++)
-    {
-      // Find samples just on pos
-      //Vec3 vi(V(i,0),V(i,1),V(i,2));
-      // EIGEN GOTCHA:
-      // double sqrd = (V.row(i)-pos).array().pow(2).sum();
-      // Must first store in temporary
-      VectorXd vi = V.row(i);
-      double sqrd = (vi-pos).squaredNorm();
-      if(sqrd <= FLOAT_EPS)
-      {
-        //cout<<"sum((["<<
-        //  V(i,0)<<" "<<
-        //  V(i,1)<<" "<<
-        //  V(i,2)<<"] - ["<<
-        //  pos(0)<<" "<<
-        //  pos(1)<<" "<<
-        //  pos(2)<<"]).^2) = "<<sqrd<<endl;
-        bci.push_back(i);
-        bcj.push_back(p);
-        bcv.push_back(1.0);
-      }
-    }
-  }
-
-  // loop over bone edges
-  for(int e = 0;e<BE.rows();e++)
-  {
-    // loop over domain vertices
-    for(int i = 0;i<V.rows();i++)
-    {
-      // Find samples from tip up to tail
-      VectorXd tip = C.row(BE(e,0));
-      VectorXd tail = C.row(BE(e,1));
-      // Compute parameter along bone and squared distance
-      double t,sqrd;
-      project_to_line(
-          V(i,0),V(i,1),V(i,2),
-          tip(0),tip(1),tip(2),
-          tail(0),tail(1),tail(2),
-          t,sqrd);
-      if(t>=-FLOAT_EPS && t<=(1.0f+FLOAT_EPS) && sqrd<=FLOAT_EPS)
-      {
-        bci.push_back(i);
-        bcj.push_back(P.size()+e);
-        bcv.push_back(1.0);
-      }
-    }
-  }
-
-  // loop over cage edges
-  for(int e = 0;e<CE.rows();e++)
-  {
-    // loop over domain vertices
-    for(int i = 0;i<V.rows();i++)
-    {
-      // Find samples from tip up to tail
-      VectorXd tip = C.row(P(CE(e,0)));
-      VectorXd tail = C.row(P(CE(e,1)));
-      // Compute parameter along bone and squared distance
-      double t,sqrd;
-      project_to_line(
-          V(i,0),V(i,1),V(i,2),
-          tip(0),tip(1),tip(2),
-          tail(0),tail(1),tail(2),
-          t,sqrd);
-      if(t>=-FLOAT_EPS && t<=(1.0f+FLOAT_EPS) && sqrd<=FLOAT_EPS)
-      {
-        bci.push_back(i);
-        bcj.push_back(CE(e,0));
-        bcv.push_back(1.0-t);
-        bci.push_back(i);
-        bcj.push_back(CE(e,1));
-        bcv.push_back(t);
-      }
-    }
-  }
-
-  std::vector<uint8_t> vertices_marked(V.rows(), 0);
-  // loop over cage faces
-  for(int f = 0;f<CF.rows();f++)
-  {
-    Vector3d v_0 = C.row(P(CF(f, 0)));
-    Vector3d v_1 = C.row(P(CF(f, 1)));
-    Vector3d v_2 = C.row(P(CF(f, 2)));
-    Vector3d n = (v_1 - v_0).cross(v_2 - v_1);
-    n.normalize();
-    // loop over domain vertices
-    for (int i = 0;i<V.rows();i++)
-    {
-      // ensure each vertex is associated with only one face
-      if (vertices_marked[i])
-      {
-          continue;
-      }
-      Vector3d point = V.row(i);
-      Vector3d v = point - v_0;
-      double dist = abs(v.dot(n));
-      Vector3d projected_point = point - dist * n;
-      if (dist <= 1.e-1f)
-      {
-        //barycentric coordinates
-        Vector3d vec_0 = v_1 - v_0, vec_1 = v_2 - v_0, vec_2 = point - v_0;
-        double d00 = vec_0.dot(vec_0);
-        double d01 = vec_0.dot(vec_1);
-        double d11 = vec_1.dot(vec_1);
-        double d20 = vec_2.dot(vec_0);
-        double d21 = vec_2.dot(vec_1);
-        double denom = d00 * d11 - d01 * d01;
-        double v = (d11 * d20 - d01 * d21) / denom;
-        double w = (d00 * d21 - d01 * d20) / denom;
-        double u = 1.0 - v - w;
-
-        if (u>=0. && u<=1.0 && v>=0. && v<=1.0 && w >=0. && w<=1.0)
-        {
-          vertices_marked[i] = 1;
-          bci.push_back(i);
-          bcj.push_back(CF(f, 0));
-          bcv.push_back(u);
-          bci.push_back(i);
-          bcj.push_back(CF(f, 1));
-          bcv.push_back(v);
-          bci.push_back(i);
-          bcj.push_back(CF(f, 2));
-          bcv.push_back(w);
-        }
-      }
-    }
-  }
-
-  // find unique boundary indices
-  vector<int> vb = bci;
-  sort(vb.begin(),vb.end());
-  vb.erase(unique(vb.begin(), vb.end()), vb.end());
-
-  b.resize(vb.size());
-  bc = MatrixXd::Zero(vb.size(),P.size()+BE.rows());
-  // Map from boundary index to index in boundary
-  map<int,int> bim;
-  int i = 0;
-  // Also fill in b
-  for(vector<int>::iterator bit = vb.begin();bit != vb.end();bit++)
-  {
-    b(i) = *bit;
-    bim[*bit] = i;
-    i++;
-  }
-
-  // Build BC
-  for(i = 0;i < (int)bci.size();i++)
-  {
-    assert(bim.find(bci[i]) != bim.end());
-    bc(bim[bci[i]],bcj[i]) = bcv[i];
-  }
-
-  // Normalize across rows so that conditions sum to one
-  for(i = 0;i<bc.rows();i++)
-  {
-    double sum = bc.row(i).sum();
-    assert(sum != 0 && "Some boundary vertex getting all zero BCs");
-    bc.row(i).array() /= sum;
-  }
-
-  if(bc.size() == 0)
-  {
-    verbose("^%s: Error: boundary conditions are empty.\n",__FUNCTION__);
-    return false;
-  }
-
-  // If there's only a single boundary condition, the following tests
-  // are overzealous.
-  if(bc.cols() == 1)
-  {
-    // If there is only one weight function,
-    // then we expect that there is only one handle.
-    assert(P.rows() + BE.rows() == 1);
-    return true;
-  }
-
-  // Check that every Weight function has at least one boundary value of 1 and
-  // one value of 0
-  for(i = 0;i<bc.cols();i++)
-  {
-    double min_abs_c = bc.col(i).array().abs().minCoeff();
-    double max_c = bc.col(i).maxCoeff();
-    if(min_abs_c > FLOAT_EPS)
-    {
-      verbose("^%s: Error: handle %d does not receive 0 weight\n",__FUNCTION__,i);
-      return false;
-    }
-    if(max_c< (1-FLOAT_EPS))
-    {
-      verbose("^%s: Error: handle %d does not receive 1 weight\n",__FUNCTION__,i);
-      return false;
-    }
-  }
-
-  return true;
-}

+ 0 - 225
include/igl/boundary_facets.cpp

@@ -1,225 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "boundary_facets.h"
-#include "face_occurrences.h"
-#include "list_to_matrix.h"
-#include "matrix_to_list.h"
-#include "sort.h"
-#include "unique_rows.h"
-#include "accumarray.h"
-#include "slice_mask.h"
-
-#include <Eigen/Core>
-
-#include <map>
-#include <iostream>
-
-template <
-  typename DerivedT, 
-  typename DerivedF,
-  typename DerivedJ,
-  typename DerivedK>
-IGL_INLINE void igl::boundary_facets(
-  const Eigen::MatrixBase<DerivedT>& T,
-  Eigen::PlainObjectBase<DerivedF>& F,
-  Eigen::PlainObjectBase<DerivedJ>& J,
-  Eigen::PlainObjectBase<DerivedK>& K)
-{
-  const int simplex_size = T.cols();
-  // Handle boring base case
-  if(T.rows() == 0)
-  {
-    F.resize(0,simplex_size-1);
-    J.resize(0,1);
-    K.resize(0,1);
-    return;
-  }
-  // Get a list of all facets/edges
-  DerivedF allF(T.rows()*simplex_size,simplex_size-1);
-  switch(simplex_size)
-  {
-    case 4:
-      // Gather faces (e.g., loop over tets)
-      for(int i = 0; i< (int)T.rows();i++)
-      {
-        // get face in correct order
-        allF(i*simplex_size+0,0) = T(i,1);
-        allF(i*simplex_size+0,1) = T(i,3);
-        allF(i*simplex_size+0,2) = T(i,2);
-        // get face in correct order
-        allF(i*simplex_size+1,0) = T(i,0);
-        allF(i*simplex_size+1,1) = T(i,2);
-        allF(i*simplex_size+1,2) = T(i,3);
-        // get face in correct order
-        allF(i*simplex_size+2,0) = T(i,0);
-        allF(i*simplex_size+2,1) = T(i,3);
-        allF(i*simplex_size+2,2) = T(i,1);
-        // get face in correct order
-        allF(i*simplex_size+3,0) = T(i,0);
-        allF(i*simplex_size+3,1) = T(i,1);
-        allF(i*simplex_size+3,2) = T(i,2);
-      }
-      break;
-    case 3:
-      // Gather edges (loop over triangles)
-      for(int i = 0; i< (int)T.rows();i++)
-      {
-        allF(i*simplex_size+0,0) = T(i,1);
-        allF(i*simplex_size+0,1) = T(i,2);
-        allF(i*simplex_size+1,0) = T(i,2);
-        allF(i*simplex_size+1,1) = T(i,0);
-        allF(i*simplex_size+2,0) = T(i,0);
-        allF(i*simplex_size+2,1) = T(i,1);
-      }
-  }
-  DerivedF sortedF;
-  igl::sort(allF,2,true,sortedF);
-  Eigen::VectorXi m,n;
-  {
-    DerivedF _1;
-    igl::unique_rows(sortedF,_1,m,n);
-  }
-  Eigen::VectorXi C;
-  igl::accumarray(n,1,C);
-  const int ones = (C.array()==1).count();
-  // Resize output to fit number of non-twos
-  F.resize(ones, allF.cols());
-  J.resize(F.rows(),1);
-  K.resize(F.rows(),1);
-  int k = 0;
-  for(int c = 0;c< (int)C.size();c++)
-  {
-    if(C(c) == 1)
-    {
-      const int i = m(c);
-      assert(k<(int)F.rows());
-      F.row(k) = allF.row(i);
-      J(k) = i/simplex_size;
-      K(k) = i%simplex_size;
-      k++;
-    }
-  }
-  assert(k==(int)F.rows());
-}
-
-template <typename DerivedT, typename DerivedF>
-IGL_INLINE void igl::boundary_facets(
-  const Eigen::MatrixBase<DerivedT>& T,
-  Eigen::PlainObjectBase<DerivedF>& F)
-{
-  Eigen::VectorXi J,K;
-  return boundary_facets(T,F,J,K);
-}
-
-template <typename DerivedT, typename Ret>
-Ret igl::boundary_facets(
-  const Eigen::MatrixBase<DerivedT>& T)
-{
-  Ret F;
-  igl::boundary_facets(T,F);
-  return F;
-}
-
-template <typename IntegerT, typename IntegerF>
-IGL_INLINE void igl::boundary_facets(
-  const std::vector<std::vector<IntegerT> > & T,
-  std::vector<std::vector<IntegerF> > & F)
-{
-  // Kept for legacy reasons. Could probably just delete.
-  using namespace std;
-
-  if(T.size() == 0)
-  {
-    F.clear();
-    return;
-  }
-
-  int simplex_size = T[0].size();
-  // Get a list of all faces
-  vector<vector<IntegerF> > allF(
-    T.size()*simplex_size,
-    vector<IntegerF>(simplex_size-1));
-
-  // Gather faces, loop over tets
-  for(int i = 0; i< (int)T.size();i++)
-  {
-    assert((int)T[i].size() == simplex_size);
-    switch(simplex_size)
-    {
-      case 4:
-        // get face in correct order
-        allF[i*simplex_size+0][0] = T[i][1];
-        allF[i*simplex_size+0][1] = T[i][3];
-        allF[i*simplex_size+0][2] = T[i][2];
-        // get face in correct order
-        allF[i*simplex_size+1][0] = T[i][0];
-        allF[i*simplex_size+1][1] = T[i][2];
-        allF[i*simplex_size+1][2] = T[i][3];
-        // get face in correct order
-        allF[i*simplex_size+2][0] = T[i][0];
-        allF[i*simplex_size+2][1] = T[i][3];
-        allF[i*simplex_size+2][2] = T[i][1];
-        // get face in correct order
-        allF[i*simplex_size+3][0] = T[i][0];
-        allF[i*simplex_size+3][1] = T[i][1];
-        allF[i*simplex_size+3][2] = T[i][2];
-        break;
-      case 3:
-        allF[i*simplex_size+0][0] = T[i][1];
-        allF[i*simplex_size+0][1] = T[i][2];
-        allF[i*simplex_size+1][0] = T[i][2];
-        allF[i*simplex_size+1][1] = T[i][0];
-        allF[i*simplex_size+2][0] = T[i][0];
-        allF[i*simplex_size+2][1] = T[i][1];
-        break;
-    }
-  }
-
-  // Counts
-  vector<int> C;
-  face_occurrences(allF,C);
-
-  // Q: Why not just count the number of ones?
-  // A: because we are including non-manifold edges as boundary edges
-  int twos = (int) count(C.begin(),C.end(),2);
-  //int ones = (int) count(C.begin(),C.end(),1);
-  // Resize output to fit number of ones
-  F.resize(allF.size() - twos);
-  //F.resize(ones);
-  int k = 0;
-  for(int i = 0;i< (int)allF.size();i++)
-  {
-    if(C[i] != 2)
-    {
-      assert(k<(int)F.size());
-      F[k] = allF[i];
-      k++;
-    }
-  }
-  assert(k==(int)F.size());
-  //if(k != F.size())
-  //{
-  //  printf("%d =? %d\n",k,F.size());
-  //}
-
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::boundary_facets<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::boundary_facets<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >&);
-// generated by autoexplicit.sh
-template void igl::boundary_facets<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
-template void igl::boundary_facets<int, int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
-//template Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > igl::boundary_facets(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template Eigen::Matrix<int, -1, -1, 0, -1, -1> igl::boundary_facets<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template void igl::boundary_facets<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
-#endif

+ 0 - 154
include/igl/boundary_loop.cpp

@@ -1,154 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2014 Stefan Brugger <[email protected]>
-//
-// 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/.
-#include "boundary_loop.h"
-#include "slice.h"
-#include "triangle_triangle_adjacency.h"
-#include "vertex_triangle_adjacency.h"
-#include "is_border_vertex.h"
-#include <set>
-
-template <typename DerivedF, typename Index>
-IGL_INLINE void igl::boundary_loop(
-    const Eigen::MatrixBase<DerivedF> & F,
-    std::vector<std::vector<Index> >& L)
-{
-  using namespace std;
-  using namespace Eigen;
-
-  if(F.rows() == 0)
-    return;
-
-  VectorXd Vdummy(F.maxCoeff()+1,1);
-  Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> TT,TTi;
-  vector<std::vector<int> > VF, VFi;
-  triangle_triangle_adjacency(F,TT,TTi);
-  vertex_triangle_adjacency(Vdummy,F,VF,VFi);
-
-  vector<bool> unvisited = is_border_vertex(F);
-  set<int> unseen;
-  for (size_t i = 0; i < unvisited.size(); ++i)
-  {
-    if (unvisited[i])
-      unseen.insert(unseen.end(),i);
-  }
-
-  while (!unseen.empty())
-  {
-    vector<Index> l;
-
-    // Get first vertex of loop
-    int start = *unseen.begin();
-    unseen.erase(unseen.begin());
-    unvisited[start] = false;
-    l.push_back(start);
-
-    bool done = false;
-    while (!done)
-    {
-      // Find next vertex
-      bool newBndEdge = false;
-      int v = l[l.size()-1];
-      int next;
-      for (int i = 0; i < (int)VF[v].size() && !newBndEdge; i++)
-      {
-        int fid = VF[v][i];
-
-        if (TT.row(fid).minCoeff() < 0.) // Face contains boundary edge
-        {
-          int vLoc = -1;
-          if (F(fid,0) == v) vLoc = 0;
-          if (F(fid,1) == v) vLoc = 1;
-          if (F(fid,2) == v) vLoc = 2;
-
-          int vNext = F(fid,(vLoc + 1) % F.cols());
-
-          newBndEdge = false;
-          if (unvisited[vNext] && TT(fid,vLoc) < 0)
-          {
-            next = vNext;
-            newBndEdge = true;
-          }
-        }
-      }
-
-      if (newBndEdge)
-      {
-        l.push_back(next);
-        unseen.erase(next);
-        unvisited[next] = false;
-      }
-      else
-        done = true;
-    }
-    L.push_back(l);
-  }
-}
-
-template <typename DerivedF, typename Index>
-IGL_INLINE void igl::boundary_loop(
-  const Eigen::MatrixBase<DerivedF>& F,
-  std::vector<Index>& L)
-{
-  using namespace Eigen;
-  using namespace std;
-
-  if(F.rows() == 0)
-    return;
-
-  vector<vector<int> > Lall;
-  boundary_loop(F,Lall);
-
-  int idxMax = -1;
-  size_t maxLen = 0;
-  for (size_t i = 0; i < Lall.size(); ++i)
-  {
-    if (Lall[i].size() > maxLen)
-    {
-      maxLen = Lall[i].size();
-      idxMax = i;
-    }
-  }
-
-  //Check for meshes without boundary
-  if (idxMax == -1)
-  {
-      L.clear();
-      return;
-  }
-
-  L.resize(Lall[idxMax].size());
-  for (size_t i = 0; i < Lall[idxMax].size(); ++i)
-  {
-    L[i] = Lall[idxMax][i];
-  }
-}
-
-template <typename DerivedF, typename DerivedL>
-IGL_INLINE void igl::boundary_loop(
-  const Eigen::MatrixBase<DerivedF>& F,
-  Eigen::PlainObjectBase<DerivedL>& L)
-{
-  using namespace Eigen;
-  using namespace std;
-
-  if(F.rows() == 0)
-    return;
-
-  vector<int> Lvec;
-  boundary_loop(F,Lvec);
-
-  L.resize(Lvec.size(), 1);
-  for (size_t i = 0; i < Lvec.size(); ++i)
-    L(i) = Lvec[i];
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::boundary_loop<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::boundary_loop<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
-#endif

+ 0 - 105
include/igl/bounding_box.cpp

@@ -1,105 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2014 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "bounding_box.h"
-#include <iostream>
-
-template <typename DerivedV, typename DerivedBV, typename DerivedBF>
-IGL_INLINE void igl::bounding_box(
-  const Eigen::MatrixBase<DerivedV>& V,
-  Eigen::PlainObjectBase<DerivedBV>& BV,
-  Eigen::PlainObjectBase<DerivedBF>& BF)
-{
-  return bounding_box(V,0.,BV,BF);
-}
-
-template <typename DerivedV, typename DerivedBV, typename DerivedBF>
-IGL_INLINE void igl::bounding_box(
-  const Eigen::MatrixBase<DerivedV>& V,
-  const typename DerivedV::Scalar pad,
-  Eigen::PlainObjectBase<DerivedBV>& BV,
-  Eigen::PlainObjectBase<DerivedBF>& BF)
-{
-  using namespace std;
-
-  const int dim = V.cols();
-  const auto & minV = V.colwise().minCoeff().array()-pad;
-  const auto & maxV = V.colwise().maxCoeff().array()+pad;
-  // 2^n vertices
-  BV.resize((1ull<<dim),dim);
-
-  // Recursive lambda to generate all 2^n combinations
-  const std::function<void(const int,const int,int*,int)> combos =
-  [&BV,&minV,&maxV,&combos](
-    const int dim,
-    const int i,
-    int * X,
-    const int pre_index)
-  {
-    for(X[i] = 0;X[i]<2;X[i]++)
-    {
-      int index = pre_index*2+X[i];
-      if((i+1)<dim)
-      {
-        combos(dim,i+1,X,index);
-      }else
-      {
-        for(int d = 0;d<dim;d++)
-        {
-          BV(index,d) = (X[d]?minV[d]:maxV[d]);
-        }
-      }
-    }
-  };
-
-  Eigen::VectorXi X(dim);
-  combos(dim,0,X.data(),0);
-  switch(dim)
-  {
-    case 2:
-      BF.resize(4,2);
-      BF<<
-        3,1,
-        1,0,
-        0,2,
-        2,3;
-      break;
-    case 3:
-      BF.resize(12,3);
-      BF<<
-        2,0,6,
-        0,4,6,
-        5,4,0,
-        5,0,1,
-        6,4,5,
-        5,7,6,
-        3,0,2,
-        1,0,3,
-        3,2,6,
-        6,7,3,
-        5,1,3,
-        3,7,5;
-      break;
-    default:
-      assert(false && "Unsupported dimension.");
-      break;
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::bounding_box<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::bounding_box<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::bounding_box<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 1, -1, -1>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::bounding_box<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::bounding_box<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
-template void igl::bounding_box<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 26
include/igl/bounding_box_diagonal.cpp

@@ -1,26 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "bounding_box_diagonal.h"
-#include "max.h"
-#include "min.h"
-#include <cmath>
-
-IGL_INLINE double igl::bounding_box_diagonal(
-  const Eigen::MatrixXd & V)
-{
-  using namespace Eigen;
-  VectorXd maxV,minV;
-  VectorXi maxVI,minVI;
-  igl::max(V,1,maxV,maxVI);
-  igl::min(V,1,minV,minVI);
-  return sqrt((maxV-minV).array().square().sum());
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#endif

+ 0 - 21
include/igl/canonical_quaternions.cpp

@@ -1,21 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "canonical_quaternions.h"
-
-template <> IGL_INLINE float igl::CANONICAL_VIEW_QUAT<float>(int i, int j)
-{
-  return (float)igl::CANONICAL_VIEW_QUAT_F[i][j];
-}
-template <> IGL_INLINE double igl::CANONICAL_VIEW_QUAT<double>(int i, int j)
-{
-  return (double)igl::CANONICAL_VIEW_QUAT_D[i][j];
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#endif

+ 0 - 263
include/igl/cat.cpp

@@ -1,263 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "cat.h"
-
-#include <cstdio>
-
-// Bug in unsupported/Eigen/SparseExtra needs iostream first
-#include <iostream>
-#include <unsupported/Eigen/SparseExtra>
-
-
-// Sparse matrices need to be handled carefully. Because C++ does not
-// Template:
-//   Scalar  sparse matrix scalar type, e.g. double
-template <typename Scalar>
-IGL_INLINE void igl::cat(
-    const int dim,
-    const Eigen::SparseMatrix<Scalar> & A,
-    const Eigen::SparseMatrix<Scalar> & B,
-    Eigen::SparseMatrix<Scalar> & C)
-{
-
-  assert(dim == 1 || dim == 2);
-  using namespace Eigen;
-  // Special case if B or A is empty
-  if(A.size() == 0)
-  {
-    C = B;
-    return;
-  }
-  if(B.size() == 0)
-  {
-    C = A;
-    return;
-  }
-
-  // This is faster than using DynamicSparseMatrix or setFromTriplets
-  C = SparseMatrix<Scalar>(
-      dim == 1 ? A.rows()+B.rows() : A.rows(),
-      dim == 1 ? A.cols()          : A.cols()+B.cols());
-  Eigen::VectorXi per_col = Eigen::VectorXi::Zero(C.cols());
-  if(dim == 1)
-  {
-    assert(A.outerSize() == B.outerSize());
-    for(int k = 0;k<A.outerSize();++k)
-    {
-      for(typename SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it)
-      {
-        per_col(k)++;
-      }
-      for(typename SparseMatrix<Scalar>::InnerIterator it (B,k); it; ++it)
-      {
-        per_col(k)++;
-      }
-    }
-  }else
-  {
-    for(int k = 0;k<A.outerSize();++k)
-    {
-      for(typename SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it)
-      {
-        per_col(k)++;
-      }
-    }
-    for(int k = 0;k<B.outerSize();++k)
-    {
-      for(typename SparseMatrix<Scalar>::InnerIterator it (B,k); it; ++it)
-      {
-        per_col(A.cols() + k)++;
-      }
-    }
-  }
-  C.reserve(per_col);
-  if(dim == 1)
-  {
-    for(int k = 0;k<A.outerSize();++k)
-    {
-      for(typename SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it)
-      {
-        C.insert(it.row(),k) = it.value();
-      }
-      for(typename SparseMatrix<Scalar>::InnerIterator it (B,k); it; ++it)
-      {
-        C.insert(A.rows()+it.row(),k) = it.value();
-      }
-    }
-  }else
-  {
-    for(int k = 0;k<A.outerSize();++k)
-    {
-      for(typename SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it)
-      {
-        C.insert(it.row(),k) = it.value();
-      }
-    }
-    for(int k = 0;k<B.outerSize();++k)
-    {
-      for(typename SparseMatrix<Scalar>::InnerIterator it (B,k); it; ++it)
-      {
-        C.insert(it.row(),A.cols()+k) = it.value();
-      }
-    }
-  }
-  C.makeCompressed();
-}
-
-template <typename Derived, class MatC>
-IGL_INLINE void igl::cat(
-  const int dim,
-  const Eigen::MatrixBase<Derived> & A,
-  const Eigen::MatrixBase<Derived> & B,
-  MatC & C)
-{
-  assert(dim == 1 || dim == 2);
-  // Special case if B or A is empty
-  if(A.size() == 0)
-  {
-    C = B;
-    return;
-  }
-  if(B.size() == 0)
-  {
-    C = A;
-    return;
-  }
-
-  if(dim == 1)
-  {
-    assert(A.cols() == B.cols());
-    C.resize(A.rows()+B.rows(),A.cols());
-    C << A,B;
-  }else if(dim == 2)
-  {
-    assert(A.rows() == B.rows());
-    C.resize(A.rows(),A.cols()+B.cols());
-    C << A,B;
-  }else
-  {
-    fprintf(stderr,"cat.h: Error: Unsupported dimension %d\n",dim);
-  }
-}
-
-template <class Mat>
-IGL_INLINE Mat igl::cat(const int dim, const Mat & A, const Mat & B)
-{
-  assert(dim == 1 || dim == 2);
-  Mat C;
-  igl::cat(dim,A,B,C);
-  return C;
-}
-
-template <class Mat>
-IGL_INLINE void igl::cat(const std::vector<std::vector< Mat > > & A, Mat & C)
-{
-  using namespace std;
-  // Start with empty matrix
-  C.resize(0,0);
-  for(const auto & row_vec : A)
-  {
-    // Concatenate each row horizontally
-    // Start with empty matrix
-    Mat row(0,0);
-    for(const auto & element : row_vec)
-    {
-      row = cat(2,row,element);
-    }
-    // Concatenate rows vertically
-    C = cat(1,C,row);
-  }
-}
-
-template <typename T, typename DerivedC>
-IGL_INLINE void igl::cat(const int dim, const std::vector<T> & A, Eigen::PlainObjectBase<DerivedC> & C)
-{
-  assert(dim == 1 || dim == 2);
-  using namespace Eigen;
-
-  const int num_mat = A.size();
-  if(num_mat == 0)
-  {
-    C.resize(0,0);
-    return;
-  }
-
-  if(dim == 1)
-  {
-    const int A_cols = A[0].cols();
-
-    int tot_rows = 0;
-    for(const auto & m : A)
-    {
-      tot_rows += m.rows();
-    }
-
-    C.resize(tot_rows, A_cols);
-
-    int cur_row = 0;
-    for(int i = 0; i < num_mat; i++)
-    {
-      assert(A_cols == A[i].cols());
-      C.block(cur_row,0,A[i].rows(),A_cols) = A[i];
-      cur_row += A[i].rows();
-    }
-  }
-  else if(dim == 2)
-  {
-    const int A_rows = A[0].rows();
-
-    int tot_cols = 0;
-    for(const auto & m : A)
-    {
-      tot_cols += m.cols();
-    }
-
-    C.resize(A_rows,tot_cols);
-
-    int cur_col = 0;
-    for(int i = 0; i < num_mat; i++)
-    {
-      assert(A_rows == A[i].rows());
-      C.block(0,cur_col,A_rows,A[i].cols()) = A[i];
-      cur_col += A[i].cols();
-    }
-  }
-  else
-  {
-    fprintf(stderr,"cat.h: Error: Unsupported dimension %d\n",dim);
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::cat<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<float, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<float, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template Eigen::Matrix<double, -1, -1, 0, -1, -1> igl::cat<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&);
-// generated by autoexplicit.sh
-template Eigen::SparseMatrix<double, 0, int> igl::cat<Eigen::SparseMatrix<double, 0, int> >(int, Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&);
-// generated by autoexplicit.sh
-template Eigen::Matrix<int, -1, -1, 0, -1, -1> igl::cat<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&);
-template void igl::cat<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(int, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
-template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::cat<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&);
-template Eigen::Matrix<double, -1, 1, 0, -1, 1> igl::cat<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(int, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&);
-template void igl::cat<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
-template void igl::cat<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&);
-template void igl::cat<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
-template void igl::cat<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<int, 1, 4, 1, 1, 4>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 1, 4, 1, 1, 4>, std::allocator<Eigen::Matrix<int, 1, 4, 1, 1, 4> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<int, 1, 15, 1, 1, 15>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 1, 15, 1, 1, 15>, std::allocator<Eigen::Matrix<int, 1, 15, 1, 1, 15> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<int, 1, 2, 1, 1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 1, 2, 1, 1, 2>, std::allocator<Eigen::Matrix<int, 1, 2, 1, 1, 2> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<int, 1, 27, 1, 1, 27>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 1, 27, 1, 1, 27>, std::allocator<Eigen::Matrix<int, 1, 27, 1, 1, 27> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 1, 3, 1, 1, 3>, std::allocator<Eigen::Matrix<int, 1, 3, 1, 1, 3> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 3, 1, 0, 3, 1>, std::allocator<Eigen::Matrix<int, 3, 1, 0, 3, 1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<double, 1, 3, 1, 1, 3>, std::allocator<Eigen::Matrix<double, 1, 3, 1, 1, 3> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<double, 3, 1, 0, 3, 1>, std::allocator<Eigen::Matrix<double, 3, 1, 0, 3, 1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<int, 1, -1, 1, 1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 1, -1, 1, 1, -1>, std::allocator<Eigen::Matrix<int, 1, -1, 1, 1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::cat<Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<double, 1, 2, 1, 1, 2>, std::allocator<Eigen::Matrix<double, 1, 2, 1, 1, 2> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 24
include/igl/ceil.cpp

@@ -1,24 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "ceil.h"
-#include <cmath>
-
-template < typename DerivedX, typename DerivedY>
-IGL_INLINE void igl::ceil(
-  const Eigen::PlainObjectBase<DerivedX>& X,
-  Eigen::PlainObjectBase<DerivedY>& Y)
-{
-  using namespace std;
-  typedef typename DerivedX::Scalar Scalar;
-  Y = X.unaryExpr([](const Scalar &x)->Scalar{return std::ceil(x);}).template cast<typename DerivedY::Scalar >();
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::ceil<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

+ 0 - 73
include/igl/centroid.cpp

@@ -1,73 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2014 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "centroid.h"
-#include <Eigen/Geometry>
-
-template <
-  typename DerivedV, 
-  typename DerivedF, 
-  typename Derivedc, 
-  typename Derivedvol>
-IGL_INLINE void igl::centroid(
-  const Eigen::MatrixBase<DerivedV>& V,
-  const Eigen::MatrixBase<DerivedF>& F,
-  Eigen::PlainObjectBase<Derivedc>& cen,
-  Derivedvol & vol)
-{
-  using namespace Eigen;
-  assert(F.cols() == 3 && "F should contain triangles.");
-  assert(V.cols() == 3 && "V should contain 3d points.");
-  const int m = F.rows();
-  cen.setZero();
-  vol = 0;
-  // loop over faces
-  for(int f = 0;f<m;f++)
-  {
-    // "Calculating the volume and centroid of a polyhedron in 3d" [Nuernberg 2013]
-    // http://www2.imperial.ac.uk/~rn/centroid.pdf
-    // rename corners
-    typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
-    const RowVector3S & a = V.row(F(f,0));
-    const RowVector3S & b = V.row(F(f,1));
-    const RowVector3S & c = V.row(F(f,2));
-    // un-normalized normal
-    const RowVector3S & n = (b-a).cross(c-a);
-    // total volume via divergence theorem: ∫ 1
-    vol += n.dot(a)/6.;
-    // centroid via divergence theorem and midpoint quadrature: ∫ x
-    cen.array() += (1./24.*n.array()*((a+b).array().square() + (b+c).array().square() + 
-        (c+a).array().square()).array());
-  }
-  cen *= 1./(2.*vol);
-}
-
-template <
-  typename DerivedV, 
-  typename DerivedF, 
-  typename Derivedc>
-IGL_INLINE void igl::centroid(
-  const Eigen::MatrixBase<DerivedV>& V,
-  const Eigen::MatrixBase<DerivedF>& F,
-  Eigen::PlainObjectBase<Derivedc>& c)
-{
-  typename Derivedc::Scalar vol;
-  return centroid(V,F,c,vol);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::centroid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, double&);
-// generated by autoexplicit.sh
-template void igl::centroid<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, float>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&, float&);
-// generated by autoexplicit.sh
-template void igl::centroid<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
-// generated by autoexplicit.sh
-template void igl::centroid<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
-template void igl::centroid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
-template void igl::centroid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
-#endif

+ 0 - 143
include/igl/circulation.cpp

@@ -1,143 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "circulation.h"
-#include "list_to_matrix.h"
-#include <cassert>
-
-IGL_INLINE std::vector<int> igl::circulation(
-  const int e,
-  const bool ccw,
-  const Eigen::VectorXi & EMAP,
-  const Eigen::MatrixXi & EF,
-  const Eigen::MatrixXi & EI)
-{
-  // prepare output
-  std::vector<int> N;
-  N.reserve(6);
-  const int m = EMAP.size()/3;
-  assert(m*3 == EMAP.size());
-  const auto & step = [&](
-    const int e, 
-    const int ff,
-    int & ne, 
-    int & nf)
-  {
-    assert((EF(e,1) == ff || EF(e,0) == ff) && "e should touch ff");
-    //const int fside = EF(e,1)==ff?1:0;
-    const int nside = EF(e,0)==ff?1:0;
-    const int nv = EI(e,nside);
-    // get next face
-    nf = EF(e,nside);
-    // get next edge 
-    const int dir = ccw?-1:1;
-    ne = EMAP(nf+m*((nv+dir+3)%3));
-  };
-  // Always start with first face (ccw in step will be sure to turn right
-  // direction)
-  const int f0 = EF(e,0);
-  int fi = f0;
-  int ei = e;
-  while(true)
-  {
-    step(ei,fi,ei,fi);
-    N.push_back(fi);
-    // back to start?
-    if(fi == f0)
-    {
-      assert(ei == e);
-      break;
-    }
-  }
-  return N;
-}
-
-IGL_INLINE void igl::circulation(
-  const int e,
-  const bool ccw,
-  const Eigen::VectorXi & EMAP,
-  const Eigen::MatrixXi & EF,
-  const Eigen::MatrixXi & EI,
-  Eigen::VectorXi & vN)
-{
-  std::vector<int> N = circulation(e,ccw,EMAP,EF,EI);
-  igl::list_to_matrix(N,vN);
-}
-
-IGL_INLINE void igl::circulation(
-  const int e,
-  const bool ccw,
-  const Eigen::MatrixXi & F,
-  const Eigen::VectorXi & EMAP,
-  const Eigen::MatrixXi & EF,
-  const Eigen::MatrixXi & EI,
-  /*std::vector<int> & Ne,*/
-  std::vector<int> & Nv,
-  std::vector<int> & Nf)
-{
-  //
-  // for e --> (bf) and ccw=true
-  //
-  //     c---d
-  //    / \ / \
-  //   a---b-e-f
-  //    \ / \ /
-  //     g---h
-  //
-  //  // (might start with {bhf} depending on edge)
-  //  Ne = […] -> [fd db dc cb ca ab ag gb gh hb hf fb]
-  //              {upto cylic order}
-  //  Nf = […] -> [{bfd}, {bdc}, {bca}, {bag}, {bgh}, {bhf}]
-  //  Nv = [d c a g h f]
-  //
-  // prepare output
-  //Ne.clear();Ne.reserve(2*10);
-  Nv.clear();Nv.reserve(10);
-  Nf.clear();Nf.reserve(10);
-  const int m = EMAP.size()/3;
-  assert(m*3 == EMAP.size());
-  const auto & step = [&](
-    const int e, 
-    const int ff,
-    int & ne, 
-    //int & re,
-    int & rv,
-    int & nf)
-  {
-    assert((EF(e,1) == ff || EF(e,0) == ff) && "e should touch ff");
-    //const int fside = EF(e,1)==ff?1:0;
-    const int nside = EF(e,0)==ff?1:0;
-    const int nv = EI(e,nside);
-    // get next face
-    nf = EF(e,nside);
-    // get next edge 
-    const int dir = ccw?-1:1;
-    rv = F(nf,nv);
-    ne = EMAP(nf+m*((nv+dir+3)%3));
-    //re = EMAP(nf+m*((nv+2*dir+3)%3));
-  };
-  // Always start with first face (ccw in step will be sure to turn right
-  // direction)
-  const int f0 = EF(e,0);
-  int fi = f0;
-  int ei = e;
-  while(true)
-  {
-    int re,rv;
-    step(ei,fi,ei/*,re*/,rv,fi);
-    Nf.push_back(fi);
-    //Ne.push_back(re);
-    //Ne.push_back(ei);
-    Nv.push_back(rv);
-    // back to start?
-    if(fi == f0)
-    {
-      assert(ei == e);
-      break;
-    }
-  }
-}

+ 0 - 30
include/igl/circumradius.cpp

@@ -1,30 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "circumradius.h"
-#include "edge_lengths.h"
-#include "doublearea.h"
-template <
-  typename DerivedV, 
-  typename DerivedF,
-  typename DerivedR>
-IGL_INLINE void igl::circumradius(
-  const Eigen::MatrixBase<DerivedV> & V, 
-  const Eigen::MatrixBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedR> & R)
-{
-  Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> l;
-  igl::edge_lengths(V,F,l);
-  DerivedR A;
-  igl::doublearea(l,0.,A);
-  // use formula: R=abc/(4*area) to compute the circum radius
-  R = l.col(0).array() * l.col(1).array() * l.col(2).array() / (2.0*A.array());
-}
-
-#ifdef IGL_STATIC_LIBRARY
-template void igl::circumradius<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 373
include/igl/collapse_edge.cpp

@@ -1,373 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "collapse_edge.h"
-#include "circulation.h"
-#include "edge_collapse_is_valid.h"
-#include "decimate_trivial_callbacks.h"
-#include <vector>
-
-IGL_INLINE bool igl::collapse_edge(
-  const int e,
-  const Eigen::RowVectorXd & p,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXi & E,
-  Eigen::VectorXi & EMAP,
-  Eigen::MatrixXi & EF,
-  Eigen::MatrixXi & EI,
-  int & e1,
-  int & e2,
-  int & f1,
-  int & f2)
-{
-  std::vector<int> /*Nse,*/Nsf,Nsv;
-  circulation(e, true,F,EMAP,EF,EI,/*Nse,*/Nsv,Nsf);
-  std::vector<int> /*Nde,*/Ndf,Ndv;
-  circulation(e, false,F,EMAP,EF,EI,/*Nde,*/Ndv,Ndf);
-  return collapse_edge(
-    e,p,Nsv,Nsf,Ndv,Ndf,V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
-}
-
-IGL_INLINE bool igl::collapse_edge(
-  const int e,
-  const Eigen::RowVectorXd & p,
-  /*const*/ std::vector<int> & Nsv,
-  const std::vector<int> & Nsf,
-  /*const*/ std::vector<int> & Ndv,
-  const std::vector<int> & Ndf,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXi & E,
-  Eigen::VectorXi & EMAP,
-  Eigen::MatrixXi & EF,
-  Eigen::MatrixXi & EI,
-  int & a_e1,
-  int & a_e2,
-  int & a_f1,
-  int & a_f2)
-{
-  // Assign this to 0 rather than, say, -1 so that deleted elements will get
-  // draw as degenerate elements at vertex 0 (which should always exist and
-  // never get collapsed to anything else since it is the smallest index)
-  using namespace Eigen;
-  using namespace std;
-  const int eflip = E(e,0)>E(e,1);
-  // source and destination
-  const int s = eflip?E(e,1):E(e,0);
-  const int d = eflip?E(e,0):E(e,1);
-
-  if(!edge_collapse_is_valid(Nsv,Ndv))
-  {
-    return false;
-  }
-
-  // OVERLOAD: caller may have just computed this
-  //
-  // Important to grab neighbors of d before monkeying with edges
-  const std::vector<int> & nV2Fd = (!eflip ? Nsf : Ndf);
-
-  // The following implementation strongly relies on s<d
-  assert(s<d && "s should be less than d");
-  // move source and destination to placement
-  V.row(s) = p;
-  V.row(d) = p;
-
-  // Helper function to replace edge and associate information with NULL
-  const auto & kill_edge = [&E,&EI,&EF](const int e)
-  {
-    E(e,0) = IGL_COLLAPSE_EDGE_NULL;
-    E(e,1) = IGL_COLLAPSE_EDGE_NULL;
-    EF(e,0) = IGL_COLLAPSE_EDGE_NULL;
-    EF(e,1) = IGL_COLLAPSE_EDGE_NULL;
-    EI(e,0) = IGL_COLLAPSE_EDGE_NULL;
-    EI(e,1) = IGL_COLLAPSE_EDGE_NULL;
-  };
-
-  // update edge info
-  // for each flap
-  const int m = F.rows();
-  for(int side = 0;side<2;side++)
-  {
-    const int f = EF(e,side);
-    const int v = EI(e,side);
-    const int sign = (eflip==0?1:-1)*(1-2*side);
-    // next edge emanating from d
-    const int e1 = EMAP(f+m*((v+sign*1+3)%3));
-    // prev edge pointing to s
-    const int e2 = EMAP(f+m*((v+sign*2+3)%3));
-    assert(E(e1,0) == d || E(e1,1) == d);
-    assert(E(e2,0) == s || E(e2,1) == s);
-    // face adjacent to f on e1, also incident on d
-    const bool flip1 = EF(e1,1)==f;
-    const int f1 = flip1 ? EF(e1,0) : EF(e1,1);
-    assert(f1!=f);
-    assert(F(f1,0)==d || F(f1,1)==d || F(f1,2) == d);
-    // across from which vertex of f1 does e1 appear?
-    const int v1 = flip1 ? EI(e1,0) : EI(e1,1);
-    // Kill e1
-    kill_edge(e1);
-    // Kill f
-    F(f,0) = IGL_COLLAPSE_EDGE_NULL;
-    F(f,1) = IGL_COLLAPSE_EDGE_NULL;
-    F(f,2) = IGL_COLLAPSE_EDGE_NULL;
-    // map f1's edge on e1 to e2
-    assert(EMAP(f1+m*v1) == e1);
-    EMAP(f1+m*v1) = e2;
-    // side opposite f2, the face adjacent to f on e2, also incident on s
-    const int opp2 = (EF(e2,0)==f?0:1);
-    assert(EF(e2,opp2) == f);
-    EF(e2,opp2) = f1;
-    EI(e2,opp2) = v1;
-    // remap e2 from d to s
-    E(e2,0) = E(e2,0)==d ? s : E(e2,0);
-    E(e2,1) = E(e2,1)==d ? s : E(e2,1);
-    if(side==0)
-    {
-      a_e1 = e1;
-      a_f1 = f;
-    }else
-    {
-      a_e2 = e1;
-      a_f2 = f;
-    }
-  }
-
-  // finally, reindex faces and edges incident on d. Do this last so asserts
-  // make sense.
-  //
-  // Could actually skip first and last, since those are always the two
-  // collpased faces. Nah, this is handled by (F(f,v) == d)
-  //
-  // Don't attempt to use Nde,Nse here because EMAP has changed
-  {
-    int p1 = -1;
-    for(auto f : nV2Fd)
-    {
-      for(int v = 0;v<3;v++)
-      {
-        if(F(f,v) == d)
-        {
-          const int e1 = EMAP(f+m*((v+1)%3));
-          const int flip1 = (EF(e1,0)==f)?1:0;
-          assert( E(e1,flip1) == d || E(e1,flip1) == s);
-          E(e1,flip1) = s;
-          const int e2 = EMAP(f+m*((v+2)%3));
-          // Skip if we just handled this edge (claim: this will be all except
-          // for the first non-trivial face)
-          if(e2 != p1)
-          {
-            const int flip2 = (EF(e2,0)==f)?0:1;
-            assert( E(e2,flip2) == d || E(e2,flip2) == s);
-            E(e2,flip2) = s;
-          }
-
-          F(f,v) = s;
-          p1 = e1;
-          break;
-        }
-      }
-    }
-  }
-  // Finally, "remove" this edge and its information
-  kill_edge(e);
-  return true;
-}
-
-IGL_INLINE bool igl::collapse_edge(
-  const int e,
-  const Eigen::RowVectorXd & p,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXi & E,
-  Eigen::VectorXi & EMAP,
-  Eigen::MatrixXi & EF,
-  Eigen::MatrixXi & EI)
-{
-  int e1,e2,f1,f2;
-  return collapse_edge(e,p,V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
-}
-
-IGL_INLINE bool igl::collapse_edge(
-  const decimate_cost_and_placement_callback & cost_and_placement,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXi & E,
-  Eigen::VectorXi & EMAP,
-  Eigen::MatrixXi & EF,
-  Eigen::MatrixXi & EI,
-  igl::min_heap< std::tuple<double,int,int> > & Q,
-  Eigen::VectorXi & EQ,
-  Eigen::MatrixXd & C)
-{
-  int e,e1,e2,f1,f2;
-  decimate_pre_collapse_callback always_try;
-  decimate_post_collapse_callback never_care;
-  decimate_trivial_callbacks(always_try,never_care);
-  return 
-    collapse_edge(
-      cost_and_placement,always_try,never_care,
-      V,F,E,EMAP,EF,EI,Q,EQ,C,e,e1,e2,f1,f2);
-}
-
-IGL_INLINE bool igl::collapse_edge(
-  const decimate_cost_and_placement_callback & cost_and_placement,
-  const decimate_pre_collapse_callback       & pre_collapse,
-  const decimate_post_collapse_callback      & post_collapse,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXi & E,
-  Eigen::VectorXi & EMAP,
-  Eigen::MatrixXi & EF,
-  Eigen::MatrixXi & EI,
-  igl::min_heap< std::tuple<double,int,int> > & Q,
-  Eigen::VectorXi & EQ,
-  Eigen::MatrixXd & C)
-{
-  int e,e1,e2,f1,f2;
-  return 
-    collapse_edge(
-      cost_and_placement,pre_collapse,post_collapse,
-      V,F,E,EMAP,EF,EI,Q,EQ,C,e,e1,e2,f1,f2);
-}
-
-
-IGL_INLINE bool igl::collapse_edge(
-  const decimate_cost_and_placement_callback & cost_and_placement,
-  const decimate_pre_collapse_callback       & pre_collapse,
-  const decimate_post_collapse_callback      & post_collapse,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXi & E,
-  Eigen::VectorXi & EMAP,
-  Eigen::MatrixXi & EF,
-  Eigen::MatrixXi & EI,
-  igl::min_heap< std::tuple<double,int,int> > & Q,
-  Eigen::VectorXi & EQ,
-  Eigen::MatrixXd & C,
-  int & e,
-  int & e1,
-  int & e2,
-  int & f1,
-  int & f2)
-{
-  using namespace Eigen;
-  using namespace igl;
-  std::tuple<double,int,int> p;
-  while(true)
-  {
-    // Check if Q is empty
-    if(Q.empty())
-    {
-      // no edges to collapse
-      e = -1;
-      return false;
-    }
-    // pop from Q
-    p = Q.top();
-    if(std::get<0>(p) == std::numeric_limits<double>::infinity())
-    {
-      e = -1;
-      // min cost edge is infinite cost
-      return false;
-    }
-    Q.pop();
-    e = std::get<1>(p);
-    // Check if matches timestamp
-    if(std::get<2>(p) == EQ(e))
-    {
-      break;
-    }
-    // must be stale or dead.
-    assert(std::get<2>(p)  < EQ(e) || EQ(e) == -1);
-    // try again.
-  }
-
-  // Why is this computed up here?
-  // If we just need original face neighbors of edge, could we gather that more
-  // directly than gathering face neighbors of each vertex?
-  std::vector<int> /*Nse,*/Nsf,Nsv;
-  circulation(e, true,F,EMAP,EF,EI,/*Nse,*/Nsv,Nsf);
-  std::vector<int> /*Nde,*/Ndf,Ndv;
-  circulation(e, false,F,EMAP,EF,EI,/*Nde,*/Ndv,Ndf);
-
-
-  bool collapsed = true;
-  if(pre_collapse(V,F,E,EMAP,EF,EI,Q,EQ,C,e))
-  {
-    collapsed = collapse_edge(
-      e,C.row(e),
-      Nsv,Nsf,Ndv,Ndf,
-      V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
-  }else
-  {
-    // Aborted by pre collapse callback
-    collapsed = false;
-  }
-  post_collapse(V,F,E,EMAP,EF,EI,Q,EQ,C,e,e1,e2,f1,f2,collapsed);
-  if(collapsed)
-  {
-    // Erase the two, other collapsed edges by marking their timestamps as -1
-    EQ(e1) = -1;
-    EQ(e2) = -1;
-    // TODO: visits edges multiple times, ~150% more updates than should
-    //
-    // update local neighbors
-    // loop over original face neighbors
-    //
-    // Can't use previous computed Nse and Nde because those refer to EMAP
-    // before it was changed...
-    std::vector<int> Nf;
-    Nf.reserve( Nsf.size() + Ndf.size() ); // preallocate memory
-    Nf.insert( Nf.end(), Nsf.begin(), Nsf.end() );
-    Nf.insert( Nf.end(), Ndf.begin(), Ndf.end() );
-    // https://stackoverflow.com/a/1041939/148668
-    std::sort( Nf.begin(), Nf.end() );
-    Nf.erase( std::unique( Nf.begin(), Nf.end() ), Nf.end() );
-    // Collect all edges that must be updated
-    std::vector<int> Ne;
-    Ne.reserve(3*Nf.size());
-    for(auto & n : Nf)
-    {
-      if(F(n,0) != IGL_COLLAPSE_EDGE_NULL ||
-          F(n,1) != IGL_COLLAPSE_EDGE_NULL ||
-          F(n,2) != IGL_COLLAPSE_EDGE_NULL)
-      {
-        for(int v = 0;v<3;v++)
-        {
-          // get edge id
-          const int ei = EMAP(v*F.rows()+n);
-          Ne.push_back(ei);
-        }
-      }
-    }
-    // Only process edge once
-    std::sort( Ne.begin(), Ne.end() );
-    Ne.erase( std::unique( Ne.begin(), Ne.end() ), Ne.end() );
-    for(auto & ei : Ne)
-    {
-       // compute cost and potential placement
-       double cost;
-       RowVectorXd place;
-       cost_and_placement(ei,V,F,E,EMAP,EF,EI,cost,place);
-       // Increment timestamp
-       EQ(ei)++;
-       // Replace in queue
-       Q.emplace(cost,ei,EQ(ei));
-       C.row(ei) = place;
-    }
-  }else
-  {
-    // reinsert with infinite weight (the provided cost function must **not**
-    // have given this un-collapsable edge inf cost already)
-    // Increment timestamp
-    EQ(e)++;
-    // Replace in queue
-    Q.emplace(std::numeric_limits<double>::infinity(),e,EQ(e));
-  }
-  return collapsed;
-}

+ 0 - 139
include/igl/collapse_small_triangles.cpp

@@ -1,139 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "collapse_small_triangles.h"
-
-#include "bounding_box_diagonal.h"
-#include "doublearea.h"
-#include "edge_lengths.h"
-#include "colon.h"
-#include "faces_first.h"
-
-#include <limits>
-
-#include <iostream>
-
-void igl::collapse_small_triangles(
-  const Eigen::MatrixXd & V,
-  const Eigen::MatrixXi & F,
-  const double eps,
-  Eigen::MatrixXi & FF)
-{
-  using namespace Eigen;
-  using namespace std;
-
-  // Compute bounding box diagonal length
-  double bbd = bounding_box_diagonal(V);
-  MatrixXd l;
-  edge_lengths(V,F,l);
-  VectorXd dblA;
-  doublearea(l,0.,dblA);
-
-  // Minimum area tolerance
-  const double min_dblarea = 2.0*eps*bbd*bbd;
-
-  Eigen::VectorXi FIM = colon<int>(0,V.rows()-1);
-  int num_edge_collapses = 0;
-  // Loop over triangles
-  for(int f = 0;f<F.rows();f++)
-  {
-    if(dblA(f) < min_dblarea)
-    {
-      double minl = 0;
-      int minli = -1;
-      // Find shortest edge
-      for(int e = 0;e<3;e++)
-      {
-        if(minli==-1 || l(f,e)<minl)
-        {
-          minli = e;
-          minl = l(f,e);
-        }
-      }
-      double maxl = 0;
-      int maxli = -1;
-      // Find longest edge
-      for(int e = 0;e<3;e++)
-      {
-        if(maxli==-1 || l(f,e)>maxl)
-        {
-          maxli = e;
-          maxl = l(f,e);
-        }
-      }
-      // Be sure that min and max aren't the same
-      maxli = (minli==maxli?(minli+1)%3:maxli);
-
-      // Collapse min edge maintaining max edge: i-->j
-      // Q: Why this direction?
-      int i = maxli;
-      int j = ((minli+1)%3 == maxli ? (minli+2)%3: (minli+1)%3);
-      assert(i != minli);
-      assert(j != minli);
-      assert(i != j);
-      FIM(F(f,i)) = FIM(F(f,j));
-      num_edge_collapses++;
-    }
-  }
-
-  // Reindex faces
-  MatrixXi rF = F;
-  // Loop over triangles
-  for(int f = 0;f<rF.rows();f++)
-  {
-    for(int i = 0;i<rF.cols();i++)
-    {
-      rF(f,i) = FIM(rF(f,i));
-    }
-  }
-
-  FF.resizeLike(rF);
-  int num_face_collapses=0;
-  // Only keep uncollapsed faces
-  {
-    int ff = 0;
-    // Loop over triangles
-    for(int f = 0;f<rF.rows();f++)
-    {
-      bool collapsed = false;
-      // Check if any indices are the same
-      for(int i = 0;i<rF.cols();i++)
-      {
-        for(int j = i+1;j<rF.cols();j++)
-        {
-          if(rF(f,i)==rF(f,j))
-          {
-            collapsed = true;
-            num_face_collapses++;
-            break;
-          }
-        }
-      }
-      if(!collapsed)
-      {
-        FF.row(ff++) = rF.row(f);
-      }
-    }
-    // Use conservative resize
-    FF.conservativeResize(ff,FF.cols());
-  }
-  //cout<<"num_edge_collapses: "<<num_edge_collapses<<endl;
-  //cout<<"num_face_collapses: "<<num_face_collapses<<endl;
-  if(num_edge_collapses == 0)
-  {
-    // There must have been a "collapsed edge" in the input
-    assert(num_face_collapses==0);
-    // Base case
-    return;
-  }
-
-  //// force base case
-  //return;
-
-  MatrixXi recFF = FF;
-  return collapse_small_triangles(V,recFF,eps,FF);
-}

+ 0 - 69
include/igl/colon.cpp

@@ -1,69 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "colon.h"
-#include "LinSpaced.h"
-
-#include <cstdio>
-
-template <typename L,typename S,typename H,typename T>
-IGL_INLINE void igl::colon(
-  const L low,
-  const S step,
-  const H hi,
-  Eigen::Matrix<T,Eigen::Dynamic,1> & I)
-{
-  const H size = ((hi-low)/step)+1;
-  I = igl::LinSpaced<Eigen::Matrix<T,Eigen::Dynamic,1> >(size,low,low+step*(size-1));
-}
-
-template <typename L,typename H,typename T>
-IGL_INLINE void igl::colon(
-  const L low,
-  const H hi,
-  Eigen::Matrix<T,Eigen::Dynamic,1> & I)
-{
-  return igl::colon(low,(T)1,hi,I);
-}
-
-template <typename T,typename L,typename H>
-IGL_INLINE Eigen::Matrix<T,Eigen::Dynamic,1> igl::colon(
-  const L low,
-  const H hi)
-{
-  Eigen::Matrix<T,Eigen::Dynamic,1> I;
-  igl::colon(low,hi,I);
-  return I;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, int>(int, int);
-template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, long>(int, long);
-template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, long long int>(int, long long int);
-template Eigen::Matrix<double, -1, 1, 0, -1, 1> igl::colon<double, double, double>(double, double);
-template void igl::colon<int, long, double>(int, long, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
-// generated by autoexplicit.sh
-template void igl::colon<int, long, int, int>(int, long, int, Eigen::Matrix<int, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, int, long, int>(int, int, long, Eigen::Matrix<int, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, long, int>(int, long, Eigen::Matrix<int, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, int, int>(int, int, Eigen::Matrix<int, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, long long int, int>(int, long long int, Eigen::Matrix<int, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, int, int, int>(int, int, int, Eigen::Matrix<int, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, long, long>(int, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, double, double, double>(int, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
-template void igl::colon<double, double, double>(double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
-template void igl::colon<double, double, double, double>(double, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, int, long>(int, int, Eigen::Matrix<long, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, int, double>(int, int, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
-#ifdef WIN32
-template void igl::colon<int, __int64, double>(int, __int64, class Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, long long, long>(int, long long, class Eigen::Matrix<long, -1, 1, 0, -1, 1> &);
-template void igl::colon<int, __int64, __int64>(int, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> &);
-#endif
-#endif

+ 0 - 1697
include/igl/colormap.cpp

@@ -1,1697 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2017 Joe Graus <[email protected]>, Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "colormap.h"
-#include <algorithm>
-
-// One of the new matplotlib colormaps by Nathaniel J.Smith, Stefan van der Walt, and (in the case of viridis) Eric Firing.
-// Released under the CC0 license / public domain dedication
-
-namespace igl
-{
-
-static double turbo_cm[256][3] = {
-  {0.18995,0.07176,0.23217},
-  {0.19483,0.08339,0.26149},
-  {0.19956,0.09498,0.29024},
-  {0.20415,0.10652,0.31844},
-  {0.20860,0.11802,0.34607},
-  {0.21291,0.12947,0.37314},
-  {0.21708,0.14087,0.39964},
-  {0.22111,0.15223,0.42558},
-  {0.22500,0.16354,0.45096},
-  {0.22875,0.17481,0.47578},
-  {0.23236,0.18603,0.50004},
-  {0.23582,0.19720,0.52373},
-  {0.23915,0.20833,0.54686},
-  {0.24234,0.21941,0.56942},
-  {0.24539,0.23044,0.59142},
-  {0.24830,0.24143,0.61286},
-  {0.25107,0.25237,0.63374},
-  {0.25369,0.26327,0.65406},
-  {0.25618,0.27412,0.67381},
-  {0.25853,0.28492,0.69300},
-  {0.26074,0.29568,0.71162},
-  {0.26280,0.30639,0.72968},
-  {0.26473,0.31706,0.74718},
-  {0.26652,0.32768,0.76412},
-  {0.26816,0.33825,0.78050},
-  {0.26967,0.34878,0.79631},
-  {0.27103,0.35926,0.81156},
-  {0.27226,0.36970,0.82624},
-  {0.27334,0.38008,0.84037},
-  {0.27429,0.39043,0.85393},
-  {0.27509,0.40072,0.86692},
-  {0.27576,0.41097,0.87936},
-  {0.27628,0.42118,0.89123},
-  {0.27667,0.43134,0.90254},
-  {0.27691,0.44145,0.91328},
-  {0.27701,0.45152,0.92347},
-  {0.27698,0.46153,0.93309},
-  {0.27680,0.47151,0.94214},
-  {0.27648,0.48144,0.95064},
-  {0.27603,0.49132,0.95857},
-  {0.27543,0.50115,0.96594},
-  {0.27469,0.51094,0.97275},
-  {0.27381,0.52069,0.97899},
-  {0.27273,0.53040,0.98461},
-  {0.27106,0.54015,0.98930},
-  {0.26878,0.54995,0.99303},
-  {0.26592,0.55979,0.99583},
-  {0.26252,0.56967,0.99773},
-  {0.25862,0.57958,0.99876},
-  {0.25425,0.58950,0.99896},
-  {0.24946,0.59943,0.99835},
-  {0.24427,0.60937,0.99697},
-  {0.23874,0.61931,0.99485},
-  {0.23288,0.62923,0.99202},
-  {0.22676,0.63913,0.98851},
-  {0.22039,0.64901,0.98436},
-  {0.21382,0.65886,0.97959},
-  {0.20708,0.66866,0.97423},
-  {0.20021,0.67842,0.96833},
-  {0.19326,0.68812,0.96190},
-  {0.18625,0.69775,0.95498},
-  {0.17923,0.70732,0.94761},
-  {0.17223,0.71680,0.93981},
-  {0.16529,0.72620,0.93161},
-  {0.15844,0.73551,0.92305},
-  {0.15173,0.74472,0.91416},
-  {0.14519,0.75381,0.90496},
-  {0.13886,0.76279,0.89550},
-  {0.13278,0.77165,0.88580},
-  {0.12698,0.78037,0.87590},
-  {0.12151,0.78896,0.86581},
-  {0.11639,0.79740,0.85559},
-  {0.11167,0.80569,0.84525},
-  {0.10738,0.81381,0.83484},
-  {0.10357,0.82177,0.82437},
-  {0.10026,0.82955,0.81389},
-  {0.09750,0.83714,0.80342},
-  {0.09532,0.84455,0.79299},
-  {0.09377,0.85175,0.78264},
-  {0.09287,0.85875,0.77240},
-  {0.09267,0.86554,0.76230},
-  {0.09320,0.87211,0.75237},
-  {0.09451,0.87844,0.74265},
-  {0.09662,0.88454,0.73316},
-  {0.09958,0.89040,0.72393},
-  {0.10342,0.89600,0.71500},
-  {0.10815,0.90142,0.70599},
-  {0.11374,0.90673,0.69651},
-  {0.12014,0.91193,0.68660},
-  {0.12733,0.91701,0.67627},
-  {0.13526,0.92197,0.66556},
-  {0.14391,0.92680,0.65448},
-  {0.15323,0.93151,0.64308},
-  {0.16319,0.93609,0.63137},
-  {0.17377,0.94053,0.61938},
-  {0.18491,0.94484,0.60713},
-  {0.19659,0.94901,0.59466},
-  {0.20877,0.95304,0.58199},
-  {0.22142,0.95692,0.56914},
-  {0.23449,0.96065,0.55614},
-  {0.24797,0.96423,0.54303},
-  {0.26180,0.96765,0.52981},
-  {0.27597,0.97092,0.51653},
-  {0.29042,0.97403,0.50321},
-  {0.30513,0.97697,0.48987},
-  {0.32006,0.97974,0.47654},
-  {0.33517,0.98234,0.46325},
-  {0.35043,0.98477,0.45002},
-  {0.36581,0.98702,0.43688},
-  {0.38127,0.98909,0.42386},
-  {0.39678,0.99098,0.41098},
-  {0.41229,0.99268,0.39826},
-  {0.42778,0.99419,0.38575},
-  {0.44321,0.99551,0.37345},
-  {0.45854,0.99663,0.36140},
-  {0.47375,0.99755,0.34963},
-  {0.48879,0.99828,0.33816},
-  {0.50362,0.99879,0.32701},
-  {0.51822,0.99910,0.31622},
-  {0.53255,0.99919,0.30581},
-  {0.54658,0.99907,0.29581},
-  {0.56026,0.99873,0.28623},
-  {0.57357,0.99817,0.27712},
-  {0.58646,0.99739,0.26849},
-  {0.59891,0.99638,0.26038},
-  {0.61088,0.99514,0.25280},
-  {0.62233,0.99366,0.24579},
-  {0.63323,0.99195,0.23937},
-  {0.64362,0.98999,0.23356},
-  {0.65394,0.98775,0.22835},
-  {0.66428,0.98524,0.22370},
-  {0.67462,0.98246,0.21960},
-  {0.68494,0.97941,0.21602},
-  {0.69525,0.97610,0.21294},
-  {0.70553,0.97255,0.21032},
-  {0.71577,0.96875,0.20815},
-  {0.72596,0.96470,0.20640},
-  {0.73610,0.96043,0.20504},
-  {0.74617,0.95593,0.20406},
-  {0.75617,0.95121,0.20343},
-  {0.76608,0.94627,0.20311},
-  {0.77591,0.94113,0.20310},
-  {0.78563,0.93579,0.20336},
-  {0.79524,0.93025,0.20386},
-  {0.80473,0.92452,0.20459},
-  {0.81410,0.91861,0.20552},
-  {0.82333,0.91253,0.20663},
-  {0.83241,0.90627,0.20788},
-  {0.84133,0.89986,0.20926},
-  {0.85010,0.89328,0.21074},
-  {0.85868,0.88655,0.21230},
-  {0.86709,0.87968,0.21391},
-  {0.87530,0.87267,0.21555},
-  {0.88331,0.86553,0.21719},
-  {0.89112,0.85826,0.21880},
-  {0.89870,0.85087,0.22038},
-  {0.90605,0.84337,0.22188},
-  {0.91317,0.83576,0.22328},
-  {0.92004,0.82806,0.22456},
-  {0.92666,0.82025,0.22570},
-  {0.93301,0.81236,0.22667},
-  {0.93909,0.80439,0.22744},
-  {0.94489,0.79634,0.22800},
-  {0.95039,0.78823,0.22831},
-  {0.95560,0.78005,0.22836},
-  {0.96049,0.77181,0.22811},
-  {0.96507,0.76352,0.22754},
-  {0.96931,0.75519,0.22663},
-  {0.97323,0.74682,0.22536},
-  {0.97679,0.73842,0.22369},
-  {0.98000,0.73000,0.22161},
-  {0.98289,0.72140,0.21918},
-  {0.98549,0.71250,0.21650},
-  {0.98781,0.70330,0.21358},
-  {0.98986,0.69382,0.21043},
-  {0.99163,0.68408,0.20706},
-  {0.99314,0.67408,0.20348},
-  {0.99438,0.66386,0.19971},
-  {0.99535,0.65341,0.19577},
-  {0.99607,0.64277,0.19165},
-  {0.99654,0.63193,0.18738},
-  {0.99675,0.62093,0.18297},
-  {0.99672,0.60977,0.17842},
-  {0.99644,0.59846,0.17376},
-  {0.99593,0.58703,0.16899},
-  {0.99517,0.57549,0.16412},
-  {0.99419,0.56386,0.15918},
-  {0.99297,0.55214,0.15417},
-  {0.99153,0.54036,0.14910},
-  {0.98987,0.52854,0.14398},
-  {0.98799,0.51667,0.13883},
-  {0.98590,0.50479,0.13367},
-  {0.98360,0.49291,0.12849},
-  {0.98108,0.48104,0.12332},
-  {0.97837,0.46920,0.11817},
-  {0.97545,0.45740,0.11305},
-  {0.97234,0.44565,0.10797},
-  {0.96904,0.43399,0.10294},
-  {0.96555,0.42241,0.09798},
-  {0.96187,0.41093,0.09310},
-  {0.95801,0.39958,0.08831},
-  {0.95398,0.38836,0.08362},
-  {0.94977,0.37729,0.07905},
-  {0.94538,0.36638,0.07461},
-  {0.94084,0.35566,0.07031},
-  {0.93612,0.34513,0.06616},
-  {0.93125,0.33482,0.06218},
-  {0.92623,0.32473,0.05837},
-  {0.92105,0.31489,0.05475},
-  {0.91572,0.30530,0.05134},
-  {0.91024,0.29599,0.04814},
-  {0.90463,0.28696,0.04516},
-  {0.89888,0.27824,0.04243},
-  {0.89298,0.26981,0.03993},
-  {0.88691,0.26152,0.03753},
-  {0.88066,0.25334,0.03521},
-  {0.87422,0.24526,0.03297},
-  {0.86760,0.23730,0.03082},
-  {0.86079,0.22945,0.02875},
-  {0.85380,0.22170,0.02677},
-  {0.84662,0.21407,0.02487},
-  {0.83926,0.20654,0.02305},
-  {0.83172,0.19912,0.02131},
-  {0.82399,0.19182,0.01966},
-  {0.81608,0.18462,0.01809},
-  {0.80799,0.17753,0.01660},
-  {0.79971,0.17055,0.01520},
-  {0.79125,0.16368,0.01387},
-  {0.78260,0.15693,0.01264},
-  {0.77377,0.15028,0.01148},
-  {0.76476,0.14374,0.01041},
-  {0.75556,0.13731,0.00942},
-  {0.74617,0.13098,0.00851},
-  {0.73661,0.12477,0.00769},
-  {0.72686,0.11867,0.00695},
-  {0.71692,0.11268,0.00629},
-  {0.70680,0.10680,0.00571},
-  {0.69650,0.10102,0.00522},
-  {0.68602,0.09536,0.00481},
-  {0.67535,0.08980,0.00449},
-  {0.66449,0.08436,0.00424},
-  {0.65345,0.07902,0.00408},
-  {0.64223,0.07380,0.00401},
-  {0.63082,0.06868,0.00401},
-  {0.61923,0.06367,0.00410},
-  {0.60746,0.05878,0.00427},
-  {0.59550,0.05399,0.00453},
-  {0.58336,0.04931,0.00486},
-  {0.57103,0.04474,0.00529},
-  {0.55852,0.04028,0.00579},
-  {0.54583,0.03593,0.00638},
-  {0.53295,0.03169,0.00705},
-  {0.51989,0.02756,0.00780},
-  {0.50664,0.02354,0.00863},
-  {0.49321,0.01963,0.00955},
-  {0.47960,0.01583,0.01055}
-};
-
-static double inferno_cm[256][3] = {
-  { 0.001462, 0.000466, 0.013866 },
-  { 0.002267, 0.001270, 0.018570 },
-  { 0.003299, 0.002249, 0.024239 },
-  { 0.004547, 0.003392, 0.030909 },
-  { 0.006006, 0.004692, 0.038558 },
-  { 0.007676, 0.006136, 0.046836 },
-  { 0.009561, 0.007713, 0.055143 },
-  { 0.011663, 0.009417, 0.063460 },
-  { 0.013995, 0.011225, 0.071862 },
-  { 0.016561, 0.013136, 0.080282 },
-  { 0.019373, 0.015133, 0.088767 },
-  { 0.022447, 0.017199, 0.097327 },
-  { 0.025793, 0.019331, 0.105930 },
-  { 0.029432, 0.021503, 0.114621 },
-  { 0.033385, 0.023702, 0.123397 },
-  { 0.037668, 0.025921, 0.132232 },
-  { 0.042253, 0.028139, 0.141141 },
-  { 0.046915, 0.030324, 0.150164 },
-  { 0.051644, 0.032474, 0.159254 },
-  { 0.056449, 0.034569, 0.168414 },
-  { 0.061340, 0.036590, 0.177642 },
-  { 0.066331, 0.038504, 0.186962 },
-  { 0.071429, 0.040294, 0.196354 },
-  { 0.076637, 0.041905, 0.205799 },
-  { 0.081962, 0.043328, 0.215289 },
-  { 0.087411, 0.044556, 0.224813 },
-  { 0.092990, 0.045583, 0.234358 },
-  { 0.098702, 0.046402, 0.243904 },
-  { 0.104551, 0.047008, 0.253430 },
-  { 0.110536, 0.047399, 0.262912 },
-  { 0.116656, 0.047574, 0.272321 },
-  { 0.122908, 0.047536, 0.281624 },
-  { 0.129285, 0.047293, 0.290788 },
-  { 0.135778, 0.046856, 0.299776 },
-  { 0.142378, 0.046242, 0.308553 },
-  { 0.149073, 0.045468, 0.317085 },
-  { 0.155850, 0.044559, 0.325338 },
-  { 0.162689, 0.043554, 0.333277 },
-  { 0.169575, 0.042489, 0.340874 },
-  { 0.176493, 0.041402, 0.348111 },
-  { 0.183429, 0.040329, 0.354971 },
-  { 0.190367, 0.039309, 0.361447 },
-  { 0.197297, 0.038400, 0.367535 },
-  { 0.204209, 0.037632, 0.373238 },
-  { 0.211095, 0.037030, 0.378563 },
-  { 0.217949, 0.036615, 0.383522 },
-  { 0.224763, 0.036405, 0.388129 },
-  { 0.231538, 0.036405, 0.392400 },
-  { 0.238273, 0.036621, 0.396353 },
-  { 0.244967, 0.037055, 0.400007 },
-  { 0.251620, 0.037705, 0.403378 },
-  { 0.258234, 0.038571, 0.406485 },
-  { 0.264810, 0.039647, 0.409345 },
-  { 0.271347, 0.040922, 0.411976 },
-  { 0.277850, 0.042353, 0.414392 },
-  { 0.284321, 0.043933, 0.416608 },
-  { 0.290763, 0.045644, 0.418637 },
-  { 0.297178, 0.047470, 0.420491 },
-  { 0.303568, 0.049396, 0.422182 },
-  { 0.309935, 0.051407, 0.423721 },
-  { 0.316282, 0.053490, 0.425116 },
-  { 0.322610, 0.055634, 0.426377 },
-  { 0.328921, 0.057827, 0.427511 },
-  { 0.335217, 0.060060, 0.428524 },
-  { 0.341500, 0.062325, 0.429425 },
-  { 0.347771, 0.064616, 0.430217 },
-  { 0.354032, 0.066925, 0.430906 },
-  { 0.360284, 0.069247, 0.431497 },
-  { 0.366529, 0.071579, 0.431994 },
-  { 0.372768, 0.073915, 0.432400 },
-  { 0.379001, 0.076253, 0.432719 },
-  { 0.385228, 0.078591, 0.432955 },
-  { 0.391453, 0.080927, 0.433109 },
-  { 0.397674, 0.083257, 0.433183 },
-  { 0.403894, 0.085580, 0.433179 },
-  { 0.410113, 0.087896, 0.433098 },
-  { 0.416331, 0.090203, 0.432943 },
-  { 0.422549, 0.092501, 0.432714 },
-  { 0.428768, 0.094790, 0.432412 },
-  { 0.434987, 0.097069, 0.432039 },
-  { 0.441207, 0.099338, 0.431594 },
-  { 0.447428, 0.101597, 0.431080 },
-  { 0.453651, 0.103848, 0.430498 },
-  { 0.459875, 0.106089, 0.429846 },
-  { 0.466100, 0.108322, 0.429125 },
-  { 0.472328, 0.110547, 0.428334 },
-  { 0.478558, 0.112764, 0.427475 },
-  { 0.484789, 0.114974, 0.426548 },
-  { 0.491022, 0.117179, 0.425552 },
-  { 0.497257, 0.119379, 0.424488 },
-  { 0.503493, 0.121575, 0.423356 },
-  { 0.509730, 0.123769, 0.422156 },
-  { 0.515967, 0.125960, 0.420887 },
-  { 0.522206, 0.128150, 0.419549 },
-  { 0.528444, 0.130341, 0.418142 },
-  { 0.534683, 0.132534, 0.416667 },
-  { 0.540920, 0.134729, 0.415123 },
-  { 0.547157, 0.136929, 0.413511 },
-  { 0.553392, 0.139134, 0.411829 },
-  { 0.559624, 0.141346, 0.410078 },
-  { 0.565854, 0.143567, 0.408258 },
-  { 0.572081, 0.145797, 0.406369 },
-  { 0.578304, 0.148039, 0.404411 },
-  { 0.584521, 0.150294, 0.402385 },
-  { 0.590734, 0.152563, 0.400290 },
-  { 0.596940, 0.154848, 0.398125 },
-  { 0.603139, 0.157151, 0.395891 },
-  { 0.609330, 0.159474, 0.393589 },
-  { 0.615513, 0.161817, 0.391219 },
-  { 0.621685, 0.164184, 0.388781 },
-  { 0.627847, 0.166575, 0.386276 },
-  { 0.633998, 0.168992, 0.383704 },
-  { 0.640135, 0.171438, 0.381065 },
-  { 0.646260, 0.173914, 0.378359 },
-  { 0.652369, 0.176421, 0.375586 },
-  { 0.658463, 0.178962, 0.372748 },
-  { 0.664540, 0.181539, 0.369846 },
-  { 0.670599, 0.184153, 0.366879 },
-  { 0.676638, 0.186807, 0.363849 },
-  { 0.682656, 0.189501, 0.360757 },
-  { 0.688653, 0.192239, 0.357603 },
-  { 0.694627, 0.195021, 0.354388 },
-  { 0.700576, 0.197851, 0.351113 },
-  { 0.706500, 0.200728, 0.347777 },
-  { 0.712396, 0.203656, 0.344383 },
-  { 0.718264, 0.206636, 0.340931 },
-  { 0.724103, 0.209670, 0.337424 },
-  { 0.729909, 0.212759, 0.333861 },
-  { 0.735683, 0.215906, 0.330245 },
-  { 0.741423, 0.219112, 0.326576 },
-  { 0.747127, 0.222378, 0.322856 },
-  { 0.752794, 0.225706, 0.319085 },
-  { 0.758422, 0.229097, 0.315266 },
-  { 0.764010, 0.232554, 0.311399 },
-  { 0.769556, 0.236077, 0.307485 },
-  { 0.775059, 0.239667, 0.303526 },
-  { 0.780517, 0.243327, 0.299523 },
-  { 0.785929, 0.247056, 0.295477 },
-  { 0.791293, 0.250856, 0.291390 },
-  { 0.796607, 0.254728, 0.287264 },
-  { 0.801871, 0.258674, 0.283099 },
-  { 0.807082, 0.262692, 0.278898 },
-  { 0.812239, 0.266786, 0.274661 },
-  { 0.817341, 0.270954, 0.270390 },
-  { 0.822386, 0.275197, 0.266085 },
-  { 0.827372, 0.279517, 0.261750 },
-  { 0.832299, 0.283913, 0.257383 },
-  { 0.837165, 0.288385, 0.252988 },
-  { 0.841969, 0.292933, 0.248564 },
-  { 0.846709, 0.297559, 0.244113 },
-  { 0.851384, 0.302260, 0.239636 },
-  { 0.855992, 0.307038, 0.235133 },
-  { 0.860533, 0.311892, 0.230606 },
-  { 0.865006, 0.316822, 0.226055 },
-  { 0.869409, 0.321827, 0.221482 },
-  { 0.873741, 0.326906, 0.216886 },
-  { 0.878001, 0.332060, 0.212268 },
-  { 0.882188, 0.337287, 0.207628 },
-  { 0.886302, 0.342586, 0.202968 },
-  { 0.890341, 0.347957, 0.198286 },
-  { 0.894305, 0.353399, 0.193584 },
-  { 0.898192, 0.358911, 0.188860 },
-  { 0.902003, 0.364492, 0.184116 },
-  { 0.905735, 0.370140, 0.179350 },
-  { 0.909390, 0.375856, 0.174563 },
-  { 0.912966, 0.381636, 0.169755 },
-  { 0.916462, 0.387481, 0.164924 },
-  { 0.919879, 0.393389, 0.160070 },
-  { 0.923215, 0.399359, 0.155193 },
-  { 0.926470, 0.405389, 0.150292 },
-  { 0.929644, 0.411479, 0.145367 },
-  { 0.932737, 0.417627, 0.140417 },
-  { 0.935747, 0.423831, 0.135440 },
-  { 0.938675, 0.430091, 0.130438 },
-  { 0.941521, 0.436405, 0.125409 },
-  { 0.944285, 0.442772, 0.120354 },
-  { 0.946965, 0.449191, 0.115272 },
-  { 0.949562, 0.455660, 0.110164 },
-  { 0.952075, 0.462178, 0.105031 },
-  { 0.954506, 0.468744, 0.099874 },
-  { 0.956852, 0.475356, 0.094695 },
-  { 0.959114, 0.482014, 0.089499 },
-  { 0.961293, 0.488716, 0.084289 },
-  { 0.963387, 0.495462, 0.079073 },
-  { 0.965397, 0.502249, 0.073859 },
-  { 0.967322, 0.509078, 0.068659 },
-  { 0.969163, 0.515946, 0.063488 },
-  { 0.970919, 0.522853, 0.058367 },
-  { 0.972590, 0.529798, 0.053324 },
-  { 0.974176, 0.536780, 0.048392 },
-  { 0.975677, 0.543798, 0.043618 },
-  { 0.977092, 0.550850, 0.039050 },
-  { 0.978422, 0.557937, 0.034931 },
-  { 0.979666, 0.565057, 0.031409 },
-  { 0.980824, 0.572209, 0.028508 },
-  { 0.981895, 0.579392, 0.026250 },
-  { 0.982881, 0.586606, 0.024661 },
-  { 0.983779, 0.593849, 0.023770 },
-  { 0.984591, 0.601122, 0.023606 },
-  { 0.985315, 0.608422, 0.024202 },
-  { 0.985952, 0.615750, 0.025592 },
-  { 0.986502, 0.623105, 0.027814 },
-  { 0.986964, 0.630485, 0.030908 },
-  { 0.987337, 0.637890, 0.034916 },
-  { 0.987622, 0.645320, 0.039886 },
-  { 0.987819, 0.652773, 0.045581 },
-  { 0.987926, 0.660250, 0.051750 },
-  { 0.987945, 0.667748, 0.058329 },
-  { 0.987874, 0.675267, 0.065257 },
-  { 0.987714, 0.682807, 0.072489 },
-  { 0.987464, 0.690366, 0.079990 },
-  { 0.987124, 0.697944, 0.087731 },
-  { 0.986694, 0.705540, 0.095694 },
-  { 0.986175, 0.713153, 0.103863 },
-  { 0.985566, 0.720782, 0.112229 },
-  { 0.984865, 0.728427, 0.120785 },
-  { 0.984075, 0.736087, 0.129527 },
-  { 0.983196, 0.743758, 0.138453 },
-  { 0.982228, 0.751442, 0.147565 },
-  { 0.981173, 0.759135, 0.156863 },
-  { 0.980032, 0.766837, 0.166353 },
-  { 0.978806, 0.774545, 0.176037 },
-  { 0.977497, 0.782258, 0.185923 },
-  { 0.976108, 0.789974, 0.196018 },
-  { 0.974638, 0.797692, 0.206332 },
-  { 0.973088, 0.805409, 0.216877 },
-  { 0.971468, 0.813122, 0.227658 },
-  { 0.969783, 0.820825, 0.238686 },
-  { 0.968041, 0.828515, 0.249972 },
-  { 0.966243, 0.836191, 0.261534 },
-  { 0.964394, 0.843848, 0.273391 },
-  { 0.962517, 0.851476, 0.285546 },
-  { 0.960626, 0.859069, 0.298010 },
-  { 0.958720, 0.866624, 0.310820 },
-  { 0.956834, 0.874129, 0.323974 },
-  { 0.954997, 0.881569, 0.337475 },
-  { 0.953215, 0.888942, 0.351369 },
-  { 0.951546, 0.896226, 0.365627 },
-  { 0.950018, 0.903409, 0.380271 },
-  { 0.948683, 0.910473, 0.395289 },
-  { 0.947594, 0.917399, 0.410665 },
-  { 0.946809, 0.924168, 0.426373 },
-  { 0.946392, 0.930761, 0.442367 },
-  { 0.946403, 0.937159, 0.458592 },
-  { 0.946903, 0.943348, 0.474970 },
-  { 0.947937, 0.949318, 0.491426 },
-  { 0.949545, 0.955063, 0.507860 },
-  { 0.951740, 0.960587, 0.524203 },
-  { 0.954529, 0.965896, 0.540361 },
-  { 0.957896, 0.971003, 0.556275 },
-  { 0.961812, 0.975924, 0.571925 },
-  { 0.966249, 0.980678, 0.587206 },
-  { 0.971162, 0.985282, 0.602154 },
-  { 0.976511, 0.989753, 0.616760 },
-  { 0.982257, 0.994109, 0.631017 },
-  { 0.988362, 0.998364, 0.644924 }
-};
-
-static double magma_cm[256][3] = {
-  { 0.001462, 0.000466, 0.013866 },
-  { 0.002258, 0.001295, 0.018331 },
-  { 0.003279, 0.002305, 0.023708 },
-  { 0.004512, 0.003490, 0.029965 },
-  { 0.005950, 0.004843, 0.037130 },
-  { 0.007588, 0.006356, 0.044973 },
-  { 0.009426, 0.008022, 0.052844 },
-  { 0.011465, 0.009828, 0.060750 },
-  { 0.013708, 0.011771, 0.068667 },
-  { 0.016156, 0.013840, 0.076603 },
-  { 0.018815, 0.016026, 0.084584 },
-  { 0.021692, 0.018320, 0.092610 },
-  { 0.024792, 0.020715, 0.100676 },
-  { 0.028123, 0.023201, 0.108787 },
-  { 0.031696, 0.025765, 0.116965 },
-  { 0.035520, 0.028397, 0.125209 },
-  { 0.039608, 0.031090, 0.133515 },
-  { 0.043830, 0.033830, 0.141886 },
-  { 0.048062, 0.036607, 0.150327 },
-  { 0.052320, 0.039407, 0.158841 },
-  { 0.056615, 0.042160, 0.167446 },
-  { 0.060949, 0.044794, 0.176129 },
-  { 0.065330, 0.047318, 0.184892 },
-  { 0.069764, 0.049726, 0.193735 },
-  { 0.074257, 0.052017, 0.202660 },
-  { 0.078815, 0.054184, 0.211667 },
-  { 0.083446, 0.056225, 0.220755 },
-  { 0.088155, 0.058133, 0.229922 },
-  { 0.092949, 0.059904, 0.239164 },
-  { 0.097833, 0.061531, 0.248477 },
-  { 0.102815, 0.063010, 0.257854 },
-  { 0.107899, 0.064335, 0.267289 },
-  { 0.113094, 0.065492, 0.276784 },
-  { 0.118405, 0.066479, 0.286321 },
-  { 0.123833, 0.067295, 0.295879 },
-  { 0.129380, 0.067935, 0.305443 },
-  { 0.135053, 0.068391, 0.315000 },
-  { 0.140858, 0.068654, 0.324538 },
-  { 0.146785, 0.068738, 0.334011 },
-  { 0.152839, 0.068637, 0.343404 },
-  { 0.159018, 0.068354, 0.352688 },
-  { 0.165308, 0.067911, 0.361816 },
-  { 0.171713, 0.067305, 0.370771 },
-  { 0.178212, 0.066576, 0.379497 },
-  { 0.184801, 0.065732, 0.387973 },
-  { 0.191460, 0.064818, 0.396152 },
-  { 0.198177, 0.063862, 0.404009 },
-  { 0.204935, 0.062907, 0.411514 },
-  { 0.211718, 0.061992, 0.418647 },
-  { 0.218512, 0.061158, 0.425392 },
-  { 0.225302, 0.060445, 0.431742 },
-  { 0.232077, 0.059889, 0.437695 },
-  { 0.238826, 0.059517, 0.443256 },
-  { 0.245543, 0.059352, 0.448436 },
-  { 0.252220, 0.059415, 0.453248 },
-  { 0.258857, 0.059706, 0.457710 },
-  { 0.265447, 0.060237, 0.461840 },
-  { 0.271994, 0.060994, 0.465660 },
-  { 0.278493, 0.061978, 0.469190 },
-  { 0.284951, 0.063168, 0.472451 },
-  { 0.291366, 0.064553, 0.475462 },
-  { 0.297740, 0.066117, 0.478243 },
-  { 0.304081, 0.067835, 0.480812 },
-  { 0.310382, 0.069702, 0.483186 },
-  { 0.316654, 0.071690, 0.485380 },
-  { 0.322899, 0.073782, 0.487408 },
-  { 0.329114, 0.075972, 0.489287 },
-  { 0.335308, 0.078236, 0.491024 },
-  { 0.341482, 0.080564, 0.492631 },
-  { 0.347636, 0.082946, 0.494121 },
-  { 0.353773, 0.085373, 0.495501 },
-  { 0.359898, 0.087831, 0.496778 },
-  { 0.366012, 0.090314, 0.497960 },
-  { 0.372116, 0.092816, 0.499053 },
-  { 0.378211, 0.095332, 0.500067 },
-  { 0.384299, 0.097855, 0.501002 },
-  { 0.390384, 0.100379, 0.501864 },
-  { 0.396467, 0.102902, 0.502658 },
-  { 0.402548, 0.105420, 0.503386 },
-  { 0.408629, 0.107930, 0.504052 },
-  { 0.414709, 0.110431, 0.504662 },
-  { 0.420791, 0.112920, 0.505215 },
-  { 0.426877, 0.115395, 0.505714 },
-  { 0.432967, 0.117855, 0.506160 },
-  { 0.439062, 0.120298, 0.506555 },
-  { 0.445163, 0.122724, 0.506901 },
-  { 0.451271, 0.125132, 0.507198 },
-  { 0.457386, 0.127522, 0.507448 },
-  { 0.463508, 0.129893, 0.507652 },
-  { 0.469640, 0.132245, 0.507809 },
-  { 0.475780, 0.134577, 0.507921 },
-  { 0.481929, 0.136891, 0.507989 },
-  { 0.488088, 0.139186, 0.508011 },
-  { 0.494258, 0.141462, 0.507988 },
-  { 0.500438, 0.143719, 0.507920 },
-  { 0.506629, 0.145958, 0.507806 },
-  { 0.512831, 0.148179, 0.507648 },
-  { 0.519045, 0.150383, 0.507443 },
-  { 0.525270, 0.152569, 0.507192 },
-  { 0.531507, 0.154739, 0.506895 },
-  { 0.537755, 0.156894, 0.506551 },
-  { 0.544015, 0.159033, 0.506159 },
-  { 0.550287, 0.161158, 0.505719 },
-  { 0.556571, 0.163269, 0.505230 },
-  { 0.562866, 0.165368, 0.504692 },
-  { 0.569172, 0.167454, 0.504105 },
-  { 0.575490, 0.169530, 0.503466 },
-  { 0.581819, 0.171596, 0.502777 },
-  { 0.588158, 0.173652, 0.502035 },
-  { 0.594508, 0.175701, 0.501241 },
-  { 0.600868, 0.177743, 0.500394 },
-  { 0.607238, 0.179779, 0.499492 },
-  { 0.613617, 0.181811, 0.498536 },
-  { 0.620005, 0.183840, 0.497524 },
-  { 0.626401, 0.185867, 0.496456 },
-  { 0.632805, 0.187893, 0.495332 },
-  { 0.639216, 0.189921, 0.494150 },
-  { 0.645633, 0.191952, 0.492910 },
-  { 0.652056, 0.193986, 0.491611 },
-  { 0.658483, 0.196027, 0.490253 },
-  { 0.664915, 0.198075, 0.488836 },
-  { 0.671349, 0.200133, 0.487358 },
-  { 0.677786, 0.202203, 0.485819 },
-  { 0.684224, 0.204286, 0.484219 },
-  { 0.690661, 0.206384, 0.482558 },
-  { 0.697098, 0.208501, 0.480835 },
-  { 0.703532, 0.210638, 0.479049 },
-  { 0.709962, 0.212797, 0.477201 },
-  { 0.716387, 0.214982, 0.475290 },
-  { 0.722805, 0.217194, 0.473316 },
-  { 0.729216, 0.219437, 0.471279 },
-  { 0.735616, 0.221713, 0.469180 },
-  { 0.742004, 0.224025, 0.467018 },
-  { 0.748378, 0.226377, 0.464794 },
-  { 0.754737, 0.228772, 0.462509 },
-  { 0.761077, 0.231214, 0.460162 },
-  { 0.767398, 0.233705, 0.457755 },
-  { 0.773695, 0.236249, 0.455289 },
-  { 0.779968, 0.238851, 0.452765 },
-  { 0.786212, 0.241514, 0.450184 },
-  { 0.792427, 0.244242, 0.447543 },
-  { 0.798608, 0.247040, 0.444848 },
-  { 0.804752, 0.249911, 0.442102 },
-  { 0.810855, 0.252861, 0.439305 },
-  { 0.816914, 0.255895, 0.436461 },
-  { 0.822926, 0.259016, 0.433573 },
-  { 0.828886, 0.262229, 0.430644 },
-  { 0.834791, 0.265540, 0.427671 },
-  { 0.840636, 0.268953, 0.424666 },
-  { 0.846416, 0.272473, 0.421631 },
-  { 0.852126, 0.276106, 0.418573 },
-  { 0.857763, 0.279857, 0.415496 },
-  { 0.863320, 0.283729, 0.412403 },
-  { 0.868793, 0.287728, 0.409303 },
-  { 0.874176, 0.291859, 0.406205 },
-  { 0.879464, 0.296125, 0.403118 },
-  { 0.884651, 0.300530, 0.400047 },
-  { 0.889731, 0.305079, 0.397002 },
-  { 0.894700, 0.309773, 0.393995 },
-  { 0.899552, 0.314616, 0.391037 },
-  { 0.904281, 0.319610, 0.388137 },
-  { 0.908884, 0.324755, 0.385308 },
-  { 0.913354, 0.330052, 0.382563 },
-  { 0.917689, 0.335500, 0.379915 },
-  { 0.921884, 0.341098, 0.377376 },
-  { 0.925937, 0.346844, 0.374959 },
-  { 0.929845, 0.352734, 0.372677 },
-  { 0.933606, 0.358764, 0.370541 },
-  { 0.937221, 0.364929, 0.368567 },
-  { 0.940687, 0.371224, 0.366762 },
-  { 0.944006, 0.377643, 0.365136 },
-  { 0.947180, 0.384178, 0.363701 },
-  { 0.950210, 0.390820, 0.362468 },
-  { 0.953099, 0.397563, 0.361438 },
-  { 0.955849, 0.404400, 0.360619 },
-  { 0.958464, 0.411324, 0.360014 },
-  { 0.960949, 0.418323, 0.359630 },
-  { 0.963310, 0.425390, 0.359469 },
-  { 0.965549, 0.432519, 0.359529 },
-  { 0.967671, 0.439703, 0.359810 },
-  { 0.969680, 0.446936, 0.360311 },
-  { 0.971582, 0.454210, 0.361030 },
-  { 0.973381, 0.461520, 0.361965 },
-  { 0.975082, 0.468861, 0.363111 },
-  { 0.976690, 0.476226, 0.364466 },
-  { 0.978210, 0.483612, 0.366025 },
-  { 0.979645, 0.491014, 0.367783 },
-  { 0.981000, 0.498428, 0.369734 },
-  { 0.982279, 0.505851, 0.371874 },
-  { 0.983485, 0.513280, 0.374198 },
-  { 0.984622, 0.520713, 0.376698 },
-  { 0.985693, 0.528148, 0.379371 },
-  { 0.986700, 0.535582, 0.382210 },
-  { 0.987646, 0.543015, 0.385210 },
-  { 0.988533, 0.550446, 0.388365 },
-  { 0.989363, 0.557873, 0.391671 },
-  { 0.990138, 0.565296, 0.395122 },
-  { 0.990871, 0.572706, 0.398714 },
-  { 0.991558, 0.580107, 0.402441 },
-  { 0.992196, 0.587502, 0.406299 },
-  { 0.992785, 0.594891, 0.410283 },
-  { 0.993326, 0.602275, 0.414390 },
-  { 0.993834, 0.609644, 0.418613 },
-  { 0.994309, 0.616999, 0.422950 },
-  { 0.994738, 0.624350, 0.427397 },
-  { 0.995122, 0.631696, 0.431951 },
-  { 0.995480, 0.639027, 0.436607 },
-  { 0.995810, 0.646344, 0.441361 },
-  { 0.996096, 0.653659, 0.446213 },
-  { 0.996341, 0.660969, 0.451160 },
-  { 0.996580, 0.668256, 0.456192 },
-  { 0.996775, 0.675541, 0.461314 },
-  { 0.996925, 0.682828, 0.466526 },
-  { 0.997077, 0.690088, 0.471811 },
-  { 0.997186, 0.697349, 0.477182 },
-  { 0.997254, 0.704611, 0.482635 },
-  { 0.997325, 0.711848, 0.488154 },
-  { 0.997351, 0.719089, 0.493755 },
-  { 0.997351, 0.726324, 0.499428 },
-  { 0.997341, 0.733545, 0.505167 },
-  { 0.997285, 0.740772, 0.510983 },
-  { 0.997228, 0.747981, 0.516859 },
-  { 0.997138, 0.755190, 0.522806 },
-  { 0.997019, 0.762398, 0.528821 },
-  { 0.996898, 0.769591, 0.534892 },
-  { 0.996727, 0.776795, 0.541039 },
-  { 0.996571, 0.783977, 0.547233 },
-  { 0.996369, 0.791167, 0.553499 },
-  { 0.996162, 0.798348, 0.559820 },
-  { 0.995932, 0.805527, 0.566202 },
-  { 0.995680, 0.812706, 0.572645 },
-  { 0.995424, 0.819875, 0.579140 },
-  { 0.995131, 0.827052, 0.585701 },
-  { 0.994851, 0.834213, 0.592307 },
-  { 0.994524, 0.841387, 0.598983 },
-  { 0.994222, 0.848540, 0.605696 },
-  { 0.993866, 0.855711, 0.612482 },
-  { 0.993545, 0.862859, 0.619299 },
-  { 0.993170, 0.870024, 0.626189 },
-  { 0.992831, 0.877168, 0.633109 },
-  { 0.992440, 0.884330, 0.640099 },
-  { 0.992089, 0.891470, 0.647116 },
-  { 0.991688, 0.898627, 0.654202 },
-  { 0.991332, 0.905763, 0.661309 },
-  { 0.990930, 0.912915, 0.668481 },
-  { 0.990570, 0.920049, 0.675675 },
-  { 0.990175, 0.927196, 0.682926 },
-  { 0.989815, 0.934329, 0.690198 },
-  { 0.989434, 0.941470, 0.697519 },
-  { 0.989077, 0.948604, 0.704863 },
-  { 0.988717, 0.955742, 0.712242 },
-  { 0.988367, 0.962878, 0.719649 },
-  { 0.988033, 0.970012, 0.727077 },
-  { 0.987691, 0.977154, 0.734536 },
-  { 0.987387, 0.984288, 0.742002 },
-  { 0.987053, 0.991438, 0.749504 }
-};
-
-static double plasma_cm[256][3] = {
-  { 0.050383, 0.029803, 0.527975 },
-  { 0.063536, 0.028426, 0.533124 },
-  { 0.075353, 0.027206, 0.538007 },
-  { 0.086222, 0.026125, 0.542658 },
-  { 0.096379, 0.025165, 0.547103 },
-  { 0.105980, 0.024309, 0.551368 },
-  { 0.115124, 0.023556, 0.555468 },
-  { 0.123903, 0.022878, 0.559423 },
-  { 0.132381, 0.022258, 0.563250 },
-  { 0.140603, 0.021687, 0.566959 },
-  { 0.148607, 0.021154, 0.570562 },
-  { 0.156421, 0.020651, 0.574065 },
-  { 0.164070, 0.020171, 0.577478 },
-  { 0.171574, 0.019706, 0.580806 },
-  { 0.178950, 0.019252, 0.584054 },
-  { 0.186213, 0.018803, 0.587228 },
-  { 0.193374, 0.018354, 0.590330 },
-  { 0.200445, 0.017902, 0.593364 },
-  { 0.207435, 0.017442, 0.596333 },
-  { 0.214350, 0.016973, 0.599239 },
-  { 0.221197, 0.016497, 0.602083 },
-  { 0.227983, 0.016007, 0.604867 },
-  { 0.234715, 0.015502, 0.607592 },
-  { 0.241396, 0.014979, 0.610259 },
-  { 0.248032, 0.014439, 0.612868 },
-  { 0.254627, 0.013882, 0.615419 },
-  { 0.261183, 0.013308, 0.617911 },
-  { 0.267703, 0.012716, 0.620346 },
-  { 0.274191, 0.012109, 0.622722 },
-  { 0.280648, 0.011488, 0.625038 },
-  { 0.287076, 0.010855, 0.627295 },
-  { 0.293478, 0.010213, 0.629490 },
-  { 0.299855, 0.009561, 0.631624 },
-  { 0.306210, 0.008902, 0.633694 },
-  { 0.312543, 0.008239, 0.635700 },
-  { 0.318856, 0.007576, 0.637640 },
-  { 0.325150, 0.006915, 0.639512 },
-  { 0.331426, 0.006261, 0.641316 },
-  { 0.337683, 0.005618, 0.643049 },
-  { 0.343925, 0.004991, 0.644710 },
-  { 0.350150, 0.004382, 0.646298 },
-  { 0.356359, 0.003798, 0.647810 },
-  { 0.362553, 0.003243, 0.649245 },
-  { 0.368733, 0.002724, 0.650601 },
-  { 0.374897, 0.002245, 0.651876 },
-  { 0.381047, 0.001814, 0.653068 },
-  { 0.387183, 0.001434, 0.654177 },
-  { 0.393304, 0.001114, 0.655199 },
-  { 0.399411, 0.000859, 0.656133 },
-  { 0.405503, 0.000678, 0.656977 },
-  { 0.411580, 0.000577, 0.657730 },
-  { 0.417642, 0.000564, 0.658390 },
-  { 0.423689, 0.000646, 0.658956 },
-  { 0.429719, 0.000831, 0.659425 },
-  { 0.435734, 0.001127, 0.659797 },
-  { 0.441732, 0.001540, 0.660069 },
-  { 0.447714, 0.002080, 0.660240 },
-  { 0.453677, 0.002755, 0.660310 },
-  { 0.459623, 0.003574, 0.660277 },
-  { 0.465550, 0.004545, 0.660139 },
-  { 0.471457, 0.005678, 0.659897 },
-  { 0.477344, 0.006980, 0.659549 },
-  { 0.483210, 0.008460, 0.659095 },
-  { 0.489055, 0.010127, 0.658534 },
-  { 0.494877, 0.011990, 0.657865 },
-  { 0.500678, 0.014055, 0.657088 },
-  { 0.506454, 0.016333, 0.656202 },
-  { 0.512206, 0.018833, 0.655209 },
-  { 0.517933, 0.021563, 0.654109 },
-  { 0.523633, 0.024532, 0.652901 },
-  { 0.529306, 0.027747, 0.651586 },
-  { 0.534952, 0.031217, 0.650165 },
-  { 0.540570, 0.034950, 0.648640 },
-  { 0.546157, 0.038954, 0.647010 },
-  { 0.551715, 0.043136, 0.645277 },
-  { 0.557243, 0.047331, 0.643443 },
-  { 0.562738, 0.051545, 0.641509 },
-  { 0.568201, 0.055778, 0.639477 },
-  { 0.573632, 0.060028, 0.637349 },
-  { 0.579029, 0.064296, 0.635126 },
-  { 0.584391, 0.068579, 0.632812 },
-  { 0.589719, 0.072878, 0.630408 },
-  { 0.595011, 0.077190, 0.627917 },
-  { 0.600266, 0.081516, 0.625342 },
-  { 0.605485, 0.085854, 0.622686 },
-  { 0.610667, 0.090204, 0.619951 },
-  { 0.615812, 0.094564, 0.617140 },
-  { 0.620919, 0.098934, 0.614257 },
-  { 0.625987, 0.103312, 0.611305 },
-  { 0.631017, 0.107699, 0.608287 },
-  { 0.636008, 0.112092, 0.605205 },
-  { 0.640959, 0.116492, 0.602065 },
-  { 0.645872, 0.120898, 0.598867 },
-  { 0.650746, 0.125309, 0.595617 },
-  { 0.655580, 0.129725, 0.592317 },
-  { 0.660374, 0.134144, 0.588971 },
-  { 0.665129, 0.138566, 0.585582 },
-  { 0.669845, 0.142992, 0.582154 },
-  { 0.674522, 0.147419, 0.578688 },
-  { 0.679160, 0.151848, 0.575189 },
-  { 0.683758, 0.156278, 0.571660 },
-  { 0.688318, 0.160709, 0.568103 },
-  { 0.692840, 0.165141, 0.564522 },
-  { 0.697324, 0.169573, 0.560919 },
-  { 0.701769, 0.174005, 0.557296 },
-  { 0.706178, 0.178437, 0.553657 },
-  { 0.710549, 0.182868, 0.550004 },
-  { 0.714883, 0.187299, 0.546338 },
-  { 0.719181, 0.191729, 0.542663 },
-  { 0.723444, 0.196158, 0.538981 },
-  { 0.727670, 0.200586, 0.535293 },
-  { 0.731862, 0.205013, 0.531601 },
-  { 0.736019, 0.209439, 0.527908 },
-  { 0.740143, 0.213864, 0.524216 },
-  { 0.744232, 0.218288, 0.520524 },
-  { 0.748289, 0.222711, 0.516834 },
-  { 0.752312, 0.227133, 0.513149 },
-  { 0.756304, 0.231555, 0.509468 },
-  { 0.760264, 0.235976, 0.505794 },
-  { 0.764193, 0.240396, 0.502126 },
-  { 0.768090, 0.244817, 0.498465 },
-  { 0.771958, 0.249237, 0.494813 },
-  { 0.775796, 0.253658, 0.491171 },
-  { 0.779604, 0.258078, 0.487539 },
-  { 0.783383, 0.262500, 0.483918 },
-  { 0.787133, 0.266922, 0.480307 },
-  { 0.790855, 0.271345, 0.476706 },
-  { 0.794549, 0.275770, 0.473117 },
-  { 0.798216, 0.280197, 0.469538 },
-  { 0.801855, 0.284626, 0.465971 },
-  { 0.805467, 0.289057, 0.462415 },
-  { 0.809052, 0.293491, 0.458870 },
-  { 0.812612, 0.297928, 0.455338 },
-  { 0.816144, 0.302368, 0.451816 },
-  { 0.819651, 0.306812, 0.448306 },
-  { 0.823132, 0.311261, 0.444806 },
-  { 0.826588, 0.315714, 0.441316 },
-  { 0.830018, 0.320172, 0.437836 },
-  { 0.833422, 0.324635, 0.434366 },
-  { 0.836801, 0.329105, 0.430905 },
-  { 0.840155, 0.333580, 0.427455 },
-  { 0.843484, 0.338062, 0.424013 },
-  { 0.846788, 0.342551, 0.420579 },
-  { 0.850066, 0.347048, 0.417153 },
-  { 0.853319, 0.351553, 0.413734 },
-  { 0.856547, 0.356066, 0.410322 },
-  { 0.859750, 0.360588, 0.406917 },
-  { 0.862927, 0.365119, 0.403519 },
-  { 0.866078, 0.369660, 0.400126 },
-  { 0.869203, 0.374212, 0.396738 },
-  { 0.872303, 0.378774, 0.393355 },
-  { 0.875376, 0.383347, 0.389976 },
-  { 0.878423, 0.387932, 0.386600 },
-  { 0.881443, 0.392529, 0.383229 },
-  { 0.884436, 0.397139, 0.379860 },
-  { 0.887402, 0.401762, 0.376494 },
-  { 0.890340, 0.406398, 0.373130 },
-  { 0.893250, 0.411048, 0.369768 },
-  { 0.896131, 0.415712, 0.366407 },
-  { 0.898984, 0.420392, 0.363047 },
-  { 0.901807, 0.425087, 0.359688 },
-  { 0.904601, 0.429797, 0.356329 },
-  { 0.907365, 0.434524, 0.352970 },
-  { 0.910098, 0.439268, 0.349610 },
-  { 0.912800, 0.444029, 0.346251 },
-  { 0.915471, 0.448807, 0.342890 },
-  { 0.918109, 0.453603, 0.339529 },
-  { 0.920714, 0.458417, 0.336166 },
-  { 0.923287, 0.463251, 0.332801 },
-  { 0.925825, 0.468103, 0.329435 },
-  { 0.928329, 0.472975, 0.326067 },
-  { 0.930798, 0.477867, 0.322697 },
-  { 0.933232, 0.482780, 0.319325 },
-  { 0.935630, 0.487712, 0.315952 },
-  { 0.937990, 0.492667, 0.312575 },
-  { 0.940313, 0.497642, 0.309197 },
-  { 0.942598, 0.502639, 0.305816 },
-  { 0.944844, 0.507658, 0.302433 },
-  { 0.947051, 0.512699, 0.299049 },
-  { 0.949217, 0.517763, 0.295662 },
-  { 0.951344, 0.522850, 0.292275 },
-  { 0.953428, 0.527960, 0.288883 },
-  { 0.955470, 0.533093, 0.285490 },
-  { 0.957469, 0.538250, 0.282096 },
-  { 0.959424, 0.543431, 0.278701 },
-  { 0.961336, 0.548636, 0.275305 },
-  { 0.963203, 0.553865, 0.271909 },
-  { 0.965024, 0.559118, 0.268513 },
-  { 0.966798, 0.564396, 0.265118 },
-  { 0.968526, 0.569700, 0.261721 },
-  { 0.970205, 0.575028, 0.258325 },
-  { 0.971835, 0.580382, 0.254931 },
-  { 0.973416, 0.585761, 0.251540 },
-  { 0.974947, 0.591165, 0.248151 },
-  { 0.976428, 0.596595, 0.244767 },
-  { 0.977856, 0.602051, 0.241387 },
-  { 0.979233, 0.607532, 0.238013 },
-  { 0.980556, 0.613039, 0.234646 },
-  { 0.981826, 0.618572, 0.231287 },
-  { 0.983041, 0.624131, 0.227937 },
-  { 0.984199, 0.629718, 0.224595 },
-  { 0.985301, 0.635330, 0.221265 },
-  { 0.986345, 0.640969, 0.217948 },
-  { 0.987332, 0.646633, 0.214648 },
-  { 0.988260, 0.652325, 0.211364 },
-  { 0.989128, 0.658043, 0.208100 },
-  { 0.989935, 0.663787, 0.204859 },
-  { 0.990681, 0.669558, 0.201642 },
-  { 0.991365, 0.675355, 0.198453 },
-  { 0.991985, 0.681179, 0.195295 },
-  { 0.992541, 0.687030, 0.192170 },
-  { 0.993032, 0.692907, 0.189084 },
-  { 0.993456, 0.698810, 0.186041 },
-  { 0.993814, 0.704741, 0.183043 },
-  { 0.994103, 0.710698, 0.180097 },
-  { 0.994324, 0.716681, 0.177208 },
-  { 0.994474, 0.722691, 0.174381 },
-  { 0.994553, 0.728728, 0.171622 },
-  { 0.994561, 0.734791, 0.168938 },
-  { 0.994495, 0.740880, 0.166335 },
-  { 0.994355, 0.746995, 0.163821 },
-  { 0.994141, 0.753137, 0.161404 },
-  { 0.993851, 0.759304, 0.159092 },
-  { 0.993482, 0.765499, 0.156891 },
-  { 0.993033, 0.771720, 0.154808 },
-  { 0.992505, 0.777967, 0.152855 },
-  { 0.991897, 0.784239, 0.151042 },
-  { 0.991209, 0.790537, 0.149377 },
-  { 0.990439, 0.796859, 0.147870 },
-  { 0.989587, 0.803205, 0.146529 },
-  { 0.988648, 0.809579, 0.145357 },
-  { 0.987621, 0.815978, 0.144363 },
-  { 0.986509, 0.822401, 0.143557 },
-  { 0.985314, 0.828846, 0.142945 },
-  { 0.984031, 0.835315, 0.142528 },
-  { 0.982653, 0.841812, 0.142303 },
-  { 0.981190, 0.848329, 0.142279 },
-  { 0.979644, 0.854866, 0.142453 },
-  { 0.977995, 0.861432, 0.142808 },
-  { 0.976265, 0.868016, 0.143351 },
-  { 0.974443, 0.874622, 0.144061 },
-  { 0.972530, 0.881250, 0.144923 },
-  { 0.970533, 0.887896, 0.145919 },
-  { 0.968443, 0.894564, 0.147014 },
-  { 0.966271, 0.901249, 0.148180 },
-  { 0.964021, 0.907950, 0.149370 },
-  { 0.961681, 0.914672, 0.150520 },
-  { 0.959276, 0.921407, 0.151566 },
-  { 0.956808, 0.928152, 0.152409 },
-  { 0.954287, 0.934908, 0.152921 },
-  { 0.951726, 0.941671, 0.152925 },
-  { 0.949151, 0.948435, 0.152178 },
-  { 0.946602, 0.955190, 0.150328 },
-  { 0.944152, 0.961916, 0.146861 },
-  { 0.941896, 0.968590, 0.140956 },
-  { 0.940015, 0.975158, 0.131326 }
-};
-
-static double viridis_cm[256][3] = {
-  { 0.267004, 0.004874, 0.329415 },
-  { 0.268510, 0.009605, 0.335427 },
-  { 0.269944, 0.014625, 0.341379 },
-  { 0.271305, 0.019942, 0.347269 },
-  { 0.272594, 0.025563, 0.353093 },
-  { 0.273809, 0.031497, 0.358853 },
-  { 0.274952, 0.037752, 0.364543 },
-  { 0.276022, 0.044167, 0.370164 },
-  { 0.277018, 0.050344, 0.375715 },
-  { 0.277941, 0.056324, 0.381191 },
-  { 0.278791, 0.062145, 0.386592 },
-  { 0.279566, 0.067836, 0.391917 },
-  { 0.280267, 0.073417, 0.397163 },
-  { 0.280894, 0.078907, 0.402329 },
-  { 0.281446, 0.084320, 0.407414 },
-  { 0.281924, 0.089666, 0.412415 },
-  { 0.282327, 0.094955, 0.417331 },
-  { 0.282656, 0.100196, 0.422160 },
-  { 0.282910, 0.105393, 0.426902 },
-  { 0.283091, 0.110553, 0.431554 },
-  { 0.283197, 0.115680, 0.436115 },
-  { 0.283229, 0.120777, 0.440584 },
-  { 0.283187, 0.125848, 0.444960 },
-  { 0.283072, 0.130895, 0.449241 },
-  { 0.282884, 0.135920, 0.453427 },
-  { 0.282623, 0.140926, 0.457517 },
-  { 0.282290, 0.145912, 0.461510 },
-  { 0.281887, 0.150881, 0.465405 },
-  { 0.281412, 0.155834, 0.469201 },
-  { 0.280868, 0.160771, 0.472899 },
-  { 0.280255, 0.165693, 0.476498 },
-  { 0.279574, 0.170599, 0.479997 },
-  { 0.278826, 0.175490, 0.483397 },
-  { 0.278012, 0.180367, 0.486697 },
-  { 0.277134, 0.185228, 0.489898 },
-  { 0.276194, 0.190074, 0.493001 },
-  { 0.275191, 0.194905, 0.496005 },
-  { 0.274128, 0.199721, 0.498911 },
-  { 0.273006, 0.204520, 0.501721 },
-  { 0.271828, 0.209303, 0.504434 },
-  { 0.270595, 0.214069, 0.507052 },
-  { 0.269308, 0.218818, 0.509577 },
-  { 0.267968, 0.223549, 0.512008 },
-  { 0.266580, 0.228262, 0.514349 },
-  { 0.265145, 0.232956, 0.516599 },
-  { 0.263663, 0.237631, 0.518762 },
-  { 0.262138, 0.242286, 0.520837 },
-  { 0.260571, 0.246922, 0.522828 },
-  { 0.258965, 0.251537, 0.524736 },
-  { 0.257322, 0.256130, 0.526563 },
-  { 0.255645, 0.260703, 0.528312 },
-  { 0.253935, 0.265254, 0.529983 },
-  { 0.252194, 0.269783, 0.531579 },
-  { 0.250425, 0.274290, 0.533103 },
-  { 0.248629, 0.278775, 0.534556 },
-  { 0.246811, 0.283237, 0.535941 },
-  { 0.244972, 0.287675, 0.537260 },
-  { 0.243113, 0.292092, 0.538516 },
-  { 0.241237, 0.296485, 0.539709 },
-  { 0.239346, 0.300855, 0.540844 },
-  { 0.237441, 0.305202, 0.541921 },
-  { 0.235526, 0.309527, 0.542944 },
-  { 0.233603, 0.313828, 0.543914 },
-  { 0.231674, 0.318106, 0.544834 },
-  { 0.229739, 0.322361, 0.545706 },
-  { 0.227802, 0.326594, 0.546532 },
-  { 0.225863, 0.330805, 0.547314 },
-  { 0.223925, 0.334994, 0.548053 },
-  { 0.221989, 0.339161, 0.548752 },
-  { 0.220057, 0.343307, 0.549413 },
-  { 0.218130, 0.347432, 0.550038 },
-  { 0.216210, 0.351535, 0.550627 },
-  { 0.214298, 0.355619, 0.551184 },
-  { 0.212395, 0.359683, 0.551710 },
-  { 0.210503, 0.363727, 0.552206 },
-  { 0.208623, 0.367752, 0.552675 },
-  { 0.206756, 0.371758, 0.553117 },
-  { 0.204903, 0.375746, 0.553533 },
-  { 0.203063, 0.379716, 0.553925 },
-  { 0.201239, 0.383670, 0.554294 },
-  { 0.199430, 0.387607, 0.554642 },
-  { 0.197636, 0.391528, 0.554969 },
-  { 0.195860, 0.395433, 0.555276 },
-  { 0.194100, 0.399323, 0.555565 },
-  { 0.192357, 0.403199, 0.555836 },
-  { 0.190631, 0.407061, 0.556089 },
-  { 0.188923, 0.410910, 0.556326 },
-  { 0.187231, 0.414746, 0.556547 },
-  { 0.185556, 0.418570, 0.556753 },
-  { 0.183898, 0.422383, 0.556944 },
-  { 0.182256, 0.426184, 0.557120 },
-  { 0.180629, 0.429975, 0.557282 },
-  { 0.179019, 0.433756, 0.557430 },
-  { 0.177423, 0.437527, 0.557565 },
-  { 0.175841, 0.441290, 0.557685 },
-  { 0.174274, 0.445044, 0.557792 },
-  { 0.172719, 0.448791, 0.557885 },
-  { 0.171176, 0.452530, 0.557965 },
-  { 0.169646, 0.456262, 0.558030 },
-  { 0.168126, 0.459988, 0.558082 },
-  { 0.166617, 0.463708, 0.558119 },
-  { 0.165117, 0.467423, 0.558141 },
-  { 0.163625, 0.471133, 0.558148 },
-  { 0.162142, 0.474838, 0.558140 },
-  { 0.160665, 0.478540, 0.558115 },
-  { 0.159194, 0.482237, 0.558073 },
-  { 0.157729, 0.485932, 0.558013 },
-  { 0.156270, 0.489624, 0.557936 },
-  { 0.154815, 0.493313, 0.557840 },
-  { 0.153364, 0.497000, 0.557724 },
-  { 0.151918, 0.500685, 0.557587 },
-  { 0.150476, 0.504369, 0.557430 },
-  { 0.149039, 0.508051, 0.557250 },
-  { 0.147607, 0.511733, 0.557049 },
-  { 0.146180, 0.515413, 0.556823 },
-  { 0.144759, 0.519093, 0.556572 },
-  { 0.143343, 0.522773, 0.556295 },
-  { 0.141935, 0.526453, 0.555991 },
-  { 0.140536, 0.530132, 0.555659 },
-  { 0.139147, 0.533812, 0.555298 },
-  { 0.137770, 0.537492, 0.554906 },
-  { 0.136408, 0.541173, 0.554483 },
-  { 0.135066, 0.544853, 0.554029 },
-  { 0.133743, 0.548535, 0.553541 },
-  { 0.132444, 0.552216, 0.553018 },
-  { 0.131172, 0.555899, 0.552459 },
-  { 0.129933, 0.559582, 0.551864 },
-  { 0.128729, 0.563265, 0.551229 },
-  { 0.127568, 0.566949, 0.550556 },
-  { 0.126453, 0.570633, 0.549841 },
-  { 0.125394, 0.574318, 0.549086 },
-  { 0.124395, 0.578002, 0.548287 },
-  { 0.123463, 0.581687, 0.547445 },
-  { 0.122606, 0.585371, 0.546557 },
-  { 0.121831, 0.589055, 0.545623 },
-  { 0.121148, 0.592739, 0.544641 },
-  { 0.120565, 0.596422, 0.543611 },
-  { 0.120092, 0.600104, 0.542530 },
-  { 0.119738, 0.603785, 0.541400 },
-  { 0.119512, 0.607464, 0.540218 },
-  { 0.119423, 0.611141, 0.538982 },
-  { 0.119483, 0.614817, 0.537692 },
-  { 0.119699, 0.618490, 0.536347 },
-  { 0.120081, 0.622161, 0.534946 },
-  { 0.120638, 0.625828, 0.533488 },
-  { 0.121380, 0.629492, 0.531973 },
-  { 0.122312, 0.633153, 0.530398 },
-  { 0.123444, 0.636809, 0.528763 },
-  { 0.124780, 0.640461, 0.527068 },
-  { 0.126326, 0.644107, 0.525311 },
-  { 0.128087, 0.647749, 0.523491 },
-  { 0.130067, 0.651384, 0.521608 },
-  { 0.132268, 0.655014, 0.519661 },
-  { 0.134692, 0.658636, 0.517649 },
-  { 0.137339, 0.662252, 0.515571 },
-  { 0.140210, 0.665859, 0.513427 },
-  { 0.143303, 0.669459, 0.511215 },
-  { 0.146616, 0.673050, 0.508936 },
-  { 0.150148, 0.676631, 0.506589 },
-  { 0.153894, 0.680203, 0.504172 },
-  { 0.157851, 0.683765, 0.501686 },
-  { 0.162016, 0.687316, 0.499129 },
-  { 0.166383, 0.690856, 0.496502 },
-  { 0.170948, 0.694384, 0.493803 },
-  { 0.175707, 0.697900, 0.491033 },
-  { 0.180653, 0.701402, 0.488189 },
-  { 0.185783, 0.704891, 0.485273 },
-  { 0.191090, 0.708366, 0.482284 },
-  { 0.196571, 0.711827, 0.479221 },
-  { 0.202219, 0.715272, 0.476084 },
-  { 0.208030, 0.718701, 0.472873 },
-  { 0.214000, 0.722114, 0.469588 },
-  { 0.220124, 0.725509, 0.466226 },
-  { 0.226397, 0.728888, 0.462789 },
-  { 0.232815, 0.732247, 0.459277 },
-  { 0.239374, 0.735588, 0.455688 },
-  { 0.246070, 0.738910, 0.452024 },
-  { 0.252899, 0.742211, 0.448284 },
-  { 0.259857, 0.745492, 0.444467 },
-  { 0.266941, 0.748751, 0.440573 },
-  { 0.274149, 0.751988, 0.436601 },
-  { 0.281477, 0.755203, 0.432552 },
-  { 0.288921, 0.758394, 0.428426 },
-  { 0.296479, 0.761561, 0.424223 },
-  { 0.304148, 0.764704, 0.419943 },
-  { 0.311925, 0.767822, 0.415586 },
-  { 0.319809, 0.770914, 0.411152 },
-  { 0.327796, 0.773980, 0.406640 },
-  { 0.335885, 0.777018, 0.402049 },
-  { 0.344074, 0.780029, 0.397381 },
-  { 0.352360, 0.783011, 0.392636 },
-  { 0.360741, 0.785964, 0.387814 },
-  { 0.369214, 0.788888, 0.382914 },
-  { 0.377779, 0.791781, 0.377939 },
-  { 0.386433, 0.794644, 0.372886 },
-  { 0.395174, 0.797475, 0.367757 },
-  { 0.404001, 0.800275, 0.362552 },
-  { 0.412913, 0.803041, 0.357269 },
-  { 0.421908, 0.805774, 0.351910 },
-  { 0.430983, 0.808473, 0.346476 },
-  { 0.440137, 0.811138, 0.340967 },
-  { 0.449368, 0.813768, 0.335384 },
-  { 0.458674, 0.816363, 0.329727 },
-  { 0.468053, 0.818921, 0.323998 },
-  { 0.477504, 0.821444, 0.318195 },
-  { 0.487026, 0.823929, 0.312321 },
-  { 0.496615, 0.826376, 0.306377 },
-  { 0.506271, 0.828786, 0.300362 },
-  { 0.515992, 0.831158, 0.294279 },
-  { 0.525776, 0.833491, 0.288127 },
-  { 0.535621, 0.835785, 0.281908 },
-  { 0.545524, 0.838039, 0.275626 },
-  { 0.555484, 0.840254, 0.269281 },
-  { 0.565498, 0.842430, 0.262877 },
-  { 0.575563, 0.844566, 0.256415 },
-  { 0.585678, 0.846661, 0.249897 },
-  { 0.595839, 0.848717, 0.243329 },
-  { 0.606045, 0.850733, 0.236712 },
-  { 0.616293, 0.852709, 0.230052 },
-  { 0.626579, 0.854645, 0.223353 },
-  { 0.636902, 0.856542, 0.216620 },
-  { 0.647257, 0.858400, 0.209861 },
-  { 0.657642, 0.860219, 0.203082 },
-  { 0.668054, 0.861999, 0.196293 },
-  { 0.678489, 0.863742, 0.189503 },
-  { 0.688944, 0.865448, 0.182725 },
-  { 0.699415, 0.867117, 0.175971 },
-  { 0.709898, 0.868751, 0.169257 },
-  { 0.720391, 0.870350, 0.162603 },
-  { 0.730889, 0.871916, 0.156029 },
-  { 0.741388, 0.873449, 0.149561 },
-  { 0.751884, 0.874951, 0.143228 },
-  { 0.762373, 0.876424, 0.137064 },
-  { 0.772852, 0.877868, 0.131109 },
-  { 0.783315, 0.879285, 0.125405 },
-  { 0.793760, 0.880678, 0.120005 },
-  { 0.804182, 0.882046, 0.114965 },
-  { 0.814576, 0.883393, 0.110347 },
-  { 0.824940, 0.884720, 0.106217 },
-  { 0.835270, 0.886029, 0.102646 },
-  { 0.845561, 0.887322, 0.099702 },
-  { 0.855810, 0.888601, 0.097452 },
-  { 0.866013, 0.889868, 0.095953 },
-  { 0.876168, 0.891125, 0.095250 },
-  { 0.886271, 0.892374, 0.095374 },
-  { 0.896320, 0.893616, 0.096335 },
-  { 0.906311, 0.894855, 0.098125 },
-  { 0.916242, 0.896091, 0.100717 },
-  { 0.926106, 0.897330, 0.104071 },
-  { 0.935904, 0.898570, 0.108131 },
-  { 0.945636, 0.899815, 0.112838 },
-  { 0.955300, 0.901065, 0.118128 },
-  { 0.964894, 0.902323, 0.123941 },
-  { 0.974417, 0.903590, 0.130215 },
-  { 0.983868, 0.904867, 0.136897 },
-  { 0.993248, 0.906157, 0.143936 }
-};
-
-static double parula_cm[256][3] = {
-  { 0.2081, 0.1663, 0.5292 },
-  { 0.2091, 0.1721, 0.5411 },
-  { 0.2101, 0.1779, 0.553   },
-  { 0.2109, 0.1837, 0.565   },
-  { 0.2116, 0.1895, 0.5771 },
-  { 0.2121, 0.1954, 0.5892 },
-  { 0.2124, 0.2013, 0.6013 },
-  { 0.2125, 0.2072, 0.6135 },
-  { 0.2123, 0.2132, 0.6258 },
-  { 0.2118, 0.2192, 0.6381 },
-  { 0.2111, 0.2253, 0.6505 },
-  { 0.2099, 0.2315, 0.6629 },
-  { 0.2084, 0.2377, 0.6753 },
-  { 0.2063, 0.244, 0.6878   },
-  { 0.2038, 0.2503, 0.7003 },
-  { 0.2006, 0.2568, 0.7129 },
-  { 0.1968, 0.2632, 0.7255 },
-  { 0.1921, 0.2698, 0.7381 },
-  { 0.1867, 0.2764, 0.7507 },
-  { 0.1802, 0.2832, 0.7634 },
-  { 0.1728, 0.2902, 0.7762 },
-  { 0.1641, 0.2975, 0.789   },
-  { 0.1541, 0.3052, 0.8017 },
-  { 0.1427, 0.3132, 0.8145 },
-  { 0.1295, 0.3217, 0.8269 },
-  { 0.1147, 0.3306, 0.8387 },
-  { 0.0986, 0.3397, 0.8495 },
-  { 0.0816, 0.3486, 0.8588 },
-  { 0.0646, 0.3572, 0.8664 },
-  { 0.0482, 0.3651, 0.8722 },
-  { 0.0329, 0.3724, 0.8765 },
-  { 0.0213, 0.3792, 0.8796 },
-  { 0.0136, 0.3853, 0.8815 },
-  { 0.0086, 0.3911, 0.8827 },
-  { 0.006,  0.3965, 0.8833 },
-  { 0.0051, 0.4017, 0.8834 },
-  { 0.0054, 0.4066, 0.8831 },
-  { 0.0067, 0.4113, 0.8825 },
-  { 0.0089, 0.4159, 0.8816 },
-  { 0.0116, 0.4203, 0.8805 },
-  { 0.0148, 0.4246, 0.8793 },
-  { 0.0184, 0.4288, 0.8779 },
-  { 0.0223, 0.4329, 0.8763 },
-  { 0.0264, 0.437, 0.8747   },
-  { 0.0306, 0.441, 0.8729   },
-  { 0.0349, 0.4449, 0.8711 },
-  { 0.0394, 0.4488, 0.8692 },
-  { 0.0437, 0.4526, 0.8672 },
-  { 0.0477, 0.4564, 0.8652 },
-  { 0.0514, 0.4602, 0.8632 },
-  { 0.0549, 0.464, 0.8611   },
-  { 0.0582, 0.4677, 0.8589 },
-  { 0.0612, 0.4714, 0.8568 },
-  { 0.064,  0.4751, 0.8546 },
-  { 0.0666, 0.4788, 0.8525 },
-  { 0.0689, 0.4825, 0.8503 },
-  { 0.071,  0.4862, 0.8481 },
-  { 0.0729, 0.4899, 0.846   },
-  { 0.0746, 0.4937, 0.8439 },
-  { 0.0761, 0.4974, 0.8418 },
-  { 0.0773, 0.5012, 0.8398 },
-  { 0.0782, 0.5051, 0.8378 },
-  { 0.0789, 0.5089, 0.8359 },
-  { 0.0794, 0.5129, 0.8341 },
-  { 0.0795, 0.5169, 0.8324 },
-  { 0.0793, 0.521, 0.8308   },
-  { 0.0788, 0.5251, 0.8293 },
-  { 0.0778, 0.5295, 0.828   },
-  { 0.0764, 0.5339, 0.827   },
-  { 0.0746, 0.5384, 0.8261 },
-  { 0.0724, 0.5431, 0.8253 },
-  { 0.0698, 0.5479, 0.8247 },
-  { 0.0668, 0.5527, 0.8243 },
-  { 0.0636, 0.5577, 0.8239 },
-  { 0.06,   0.5627, 0.8237 },
-  { 0.0562, 0.5677, 0.8234 },
-  { 0.0523, 0.5727, 0.8231 },
-  { 0.0484, 0.5777, 0.8228 },
-  { 0.0445, 0.5826, 0.8223 },
-  { 0.0408, 0.5874, 0.8217 },
-  { 0.0372, 0.5922, 0.8209 },
-  { 0.0342, 0.5968, 0.8198 },
-  { 0.0317, 0.6012, 0.8186 },
-  { 0.0296, 0.6055, 0.8171 },
-  { 0.0279, 0.6097, 0.8154 },
-  { 0.0265, 0.6137, 0.8135 },
-  { 0.0255, 0.6176, 0.8114 },
-  { 0.0248, 0.6214, 0.8091 },
-  { 0.0243, 0.625, 0.8066   },
-  { 0.0239, 0.6285, 0.8039 },
-  { 0.0237, 0.6319, 0.801   },
-  { 0.0235, 0.6352, 0.798   },
-  { 0.0233, 0.6384, 0.7948 },
-  { 0.0231, 0.6415, 0.7916 },
-  { 0.023,  0.6445, 0.7881 },
-  { 0.0229, 0.6474, 0.7846 },
-  { 0.0227, 0.6503, 0.781, },
-  { 0.0227, 0.6531, 0.7773 },
-  { 0.0232, 0.6558, 0.7735 },
-  { 0.0238, 0.6585, 0.7696 },
-  { 0.0246, 0.6611, 0.7656 },
-  { 0.0263, 0.6637, 0.7615 },
-  { 0.0282, 0.6663, 0.7574 },
-  { 0.0306, 0.6688, 0.7532 },
-  { 0.0338, 0.6712, 0.749   },
-  { 0.0373, 0.6737, 0.7446 },
-  { 0.0418, 0.6761, 0.7402 },
-  { 0.0467, 0.6784, 0.7358 },
-  { 0.0516, 0.6808, 0.7313 },
-  { 0.0574, 0.6831, 0.7267 },
-  { 0.0629, 0.6854, 0.7221 },
-  { 0.0692, 0.6877, 0.7173 },
-  { 0.0755, 0.6899, 0.7126 },
-  { 0.082,  0.6921, 0.7078 },
-  { 0.0889, 0.6943, 0.7029 },
-  { 0.0956, 0.6965, 0.6979 },
-  { 0.1031, 0.6986, 0.6929 },
-  { 0.1104, 0.7007, 0.6878 },
-  { 0.118,  0.7028, 0.6827 },
-  { 0.1258, 0.7049, 0.6775 },
-  { 0.1335, 0.7069, 0.6723 },
-  { 0.1418, 0.7089, 0.6669 },
-  { 0.1499, 0.7109, 0.6616 },
-  { 0.1585, 0.7129, 0.6561 },
-  { 0.1671, 0.7148, 0.6507 },
-  { 0.1758, 0.7168, 0.6451 },
-  { 0.1849, 0.7186, 0.6395 },
-  { 0.1938, 0.7205, 0.6338 },
-  { 0.2033, 0.7223, 0.6281 },
-  { 0.2128, 0.7241, 0.6223 },
-  { 0.2224, 0.7259, 0.6165 },
-  { 0.2324, 0.7275, 0.6107 },
-  { 0.2423, 0.7292, 0.6048 },
-  { 0.2527, 0.7308, 0.5988 },
-  { 0.2631, 0.7324, 0.5929 },
-  { 0.2735, 0.7339, 0.5869 },
-  { 0.2845, 0.7354, 0.5809 },
-  { 0.2953, 0.7368, 0.5749 },
-  { 0.3064, 0.7381, 0.5689 },
-  { 0.3177, 0.7394, 0.563   },
-  { 0.3289, 0.7406, 0.557   },
-  { 0.3405, 0.7417, 0.5512 },
-  { 0.352,  0.7428, 0.5453 },
-  { 0.3635, 0.7438, 0.5396 },
-  { 0.3753, 0.7446, 0.5339 },
-  { 0.3869, 0.7454, 0.5283 },
-  { 0.3986, 0.7461, 0.5229 },
-  { 0.4103, 0.7467, 0.5175 },
-  { 0.4218, 0.7473, 0.5123 },
-  { 0.4334, 0.7477, 0.5072 },
-  { 0.4447, 0.7482, 0.5021 },
-  { 0.4561, 0.7485, 0.4972 },
-  { 0.4672, 0.7487, 0.4924 },
-  { 0.4783, 0.7489, 0.4877 },
-  { 0.4892, 0.7491, 0.4831 },
-  { 0.5,    0.7491, 0.4786 },
-  { 0.5106, 0.7492, 0.4741 },
-  { 0.5212, 0.7492, 0.4698 },
-  { 0.5315, 0.7491, 0.4655 },
-  { 0.5418, 0.749, 0.4613   },
-  { 0.5519, 0.7489, 0.4571 },
-  { 0.5619, 0.7487, 0.4531 },
-  { 0.5718, 0.7485, 0.449   },
-  { 0.5816, 0.7482, 0.4451 },
-  { 0.5913, 0.7479, 0.4412 },
-  { 0.6009, 0.7476, 0.4374 },
-  { 0.6103, 0.7473, 0.4335 },
-  { 0.6197, 0.7469, 0.4298 },
-  { 0.629,  0.7465, 0.4261 },
-  { 0.6382, 0.746, 0.4224   },
-  { 0.6473, 0.7456, 0.4188 },
-  { 0.6564, 0.7451, 0.4152 },
-  { 0.6653, 0.7446, 0.4116 },
-  { 0.6742, 0.7441, 0.4081 },
-  { 0.683,  0.7435, 0.4046 },
-  { 0.6918, 0.743, 0.4011   },
-  { 0.7004, 0.7424, 0.3976 },
-  { 0.7091, 0.7418, 0.3942 },
-  { 0.7176, 0.7412, 0.3908 },
-  { 0.7261, 0.7405, 0.3874 },
-  { 0.7346, 0.7399, 0.384   },
-  { 0.743,  0.7392, 0.3806 },
-  { 0.7513, 0.7385, 0.3773 },
-  { 0.7596, 0.7378, 0.3739 },
-  { 0.7679, 0.7372, 0.3706 },
-  { 0.7761, 0.7364, 0.3673 },
-  { 0.7843, 0.7357, 0.3639 },
-  { 0.7924, 0.735, 0.3606   },
-  { 0.8005, 0.7343, 0.3573 },
-  { 0.8085, 0.7336, 0.3539 },
-  { 0.8166, 0.7329, 0.3506 },
-  { 0.8246, 0.7322, 0.3472 },
-  { 0.8325, 0.7315, 0.3438 },
-  { 0.8405, 0.7308, 0.3404 },
-  { 0.8484, 0.7301, 0.337   },
-  { 0.8563, 0.7294, 0.3336 },
-  { 0.8642, 0.7288, 0.33    },
-  { 0.872,  0.7282, 0.3265 },
-  { 0.8798, 0.7276, 0.3229 },
-  { 0.8877, 0.7271, 0.3193 },
-  { 0.8954, 0.7266, 0.3156 },
-  { 0.9032, 0.7262, 0.3117 },
-  { 0.911,  0.7259, 0.3078 },
-  { 0.9187, 0.7256, 0.3038 },
-  { 0.9264, 0.7256, 0.2996 },
-  { 0.9341, 0.7256, 0.2953 },
-  { 0.9417, 0.7259, 0.2907 },
-  { 0.9493, 0.7264, 0.2859 },
-  { 0.9567, 0.7273, 0.2808 },
-  { 0.9639, 0.7285, 0.2754 },
-  { 0.9708, 0.7303, 0.2696 },
-  { 0.9773, 0.7326, 0.2634 },
-  { 0.9831, 0.7355, 0.257   },
-  { 0.9882, 0.739, 0.2504   },
-  { 0.9922, 0.7431, 0.2437 },
-  { 0.9952, 0.7476, 0.2373 },
-  { 0.9973, 0.7524, 0.231   },
-  { 0.9986, 0.7573, 0.2251 },
-  { 0.9991, 0.7624, 0.2195 },
-  { 0.999,  0.7675, 0.2141 },
-  { 0.9985, 0.7726, 0.209   },
-  { 0.9976, 0.7778, 0.2042 },
-  { 0.9964, 0.7829, 0.1995 },
-  { 0.995,  0.788, 0.1949   },
-  { 0.9933, 0.7931, 0.1905 },
-  { 0.9914, 0.7981, 0.1863 },
-  { 0.9894, 0.8032, 0.1821 },
-  { 0.9873, 0.8083, 0.178   },
-  { 0.9851, 0.8133, 0.174   },
-  { 0.9828, 0.8184, 0.17    },
-  { 0.9805, 0.8235, 0.1661 },
-  { 0.9782, 0.8286, 0.1622 },
-  { 0.9759, 0.8337, 0.1583 },
-  { 0.9736, 0.8389, 0.1544 },
-  { 0.9713, 0.8441, 0.1505 },
-  { 0.9692, 0.8494, 0.1465 },
-  { 0.9672, 0.8548, 0.1425 },
-  { 0.9654, 0.8603, 0.1385 },
-  { 0.9638, 0.8659, 0.1343 },
-  { 0.9623, 0.8716, 0.1301 },
-  { 0.9611, 0.8774, 0.1258 },
-  { 0.96,   0.8834, 0.1215 },
-  { 0.9593, 0.8895, 0.1171 },
-  { 0.9588, 0.8958, 0.1126 },
-  { 0.9586, 0.9022, 0.1082 },
-  { 0.9587, 0.9088, 0.1036 },
-  { 0.9591, 0.9155, 0.099   },
-  { 0.9599, 0.9225, 0.0944 },
-  { 0.961,  0.9296, 0.0897 },
-  { 0.9624, 0.9368, 0.085   },
-  { 0.9641, 0.9443, 0.0802 },
-  { 0.9662, 0.9518, 0.0753 },
-  { 0.9685, 0.9595, 0.0703 },
-  { 0.971,  0.9673, 0.0651 },
-  { 0.9736, 0.9752, 0.0597 },
-  { 0.9763, 0.9831, 0.0538 }
-};
-}
-
-template <typename T>
-IGL_INLINE void igl::colormap(const ColorMapType cm, const T x, T * rgb)
-{
-  return colormap(cm,x,rgb[0],rgb[1],rgb[2]);
-}
-
-template <typename T>
-IGL_INLINE void igl::colormap(
-  const ColorMapType cm, const T x_in, T & r, T & g, T & b)
-{
-  switch (cm)
-  {
-    case COLOR_MAP_TYPE_INFERNO:
-      colormap(inferno_cm, x_in, r, g, b);
-      break;
-    case COLOR_MAP_TYPE_JET:
-      // jet is bad so we use turbo instead
-      // https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html
-    case COLOR_MAP_TYPE_TURBO:
-      colormap(turbo_cm, x_in, r, g, b);
-      break;
-    case COLOR_MAP_TYPE_MAGMA:
-      colormap(magma_cm, x_in, r, g, b);
-      break;
-    case COLOR_MAP_TYPE_PARULA:
-      colormap(parula_cm, x_in, r, g, b);
-      break;
-    case COLOR_MAP_TYPE_PLASMA:
-      colormap(plasma_cm, x_in, r, g, b);
-      break;
-    case COLOR_MAP_TYPE_VIRIDIS:
-      colormap(viridis_cm, x_in, r, g, b);
-      break;
-    default:
-      throw std::invalid_argument("igl::colormap(): Selected colormap is unsupported!");
-      break;
-  }
-}
-
-template <typename T>
-IGL_INLINE void igl::colormap(
-  const double palette[256][3], const T x_in, T & r, T & g, T & b)
-{
-  static const unsigned int pal = 256;
-  const T zero = 0.0;
-  const T one = 1.0;
-  T x_in_clamped = static_cast<T>(std::max(zero, std::min(one, x_in)));
-
-  // simple rgb lerp from palette
-  unsigned int least = std::floor(x_in_clamped * static_cast<T>(pal - 1));
-  unsigned int most = std::ceil(x_in_clamped * static_cast<T>(pal - 1));
-
-  T _r[2] = { static_cast<T>(palette[least][0]), static_cast<T>(palette[most][0]) };
-  T _g[2] = { static_cast<T>(palette[least][1]), static_cast<T>(palette[most][1]) };
-  T _b[2] = { static_cast<T>(palette[least][2]), static_cast<T>(palette[most][2]) };
-
-  T t = std::max(zero, std::min(one, static_cast<T>(fmod(x_in_clamped * static_cast<T>(pal), one))));
-
-  r = std::max(zero, std::min(one, (one - t) * _r[0] + t * _r[1]));
-  g = std::max(zero, std::min(one, (one - t) * _g[0] + t * _g[1]));
-  b = std::max(zero, std::min(one, (one - t) * _b[0] + t * _b[1]));
-}
-
-template <typename DerivedZ, typename DerivedC>
-IGL_INLINE void igl::colormap(
-  const ColorMapType cm,
-  const Eigen::MatrixBase<DerivedZ> & Z,
-  const bool normalize,
-  Eigen::PlainObjectBase<DerivedC> & C)
-{
-  const double min_z = normalize ? Z.minCoeff() : 0;
-  const double max_z = normalize ? Z.maxCoeff() : 1;
-  return colormap(cm, Z, min_z, max_z, C);
-}
-
-template <typename DerivedZ, typename DerivedC>
-IGL_INLINE void igl::colormap(
-  const ColorMapType cm,
-  const Eigen::MatrixBase<DerivedZ> & Z,
-  const double min_z,
-  const double max_z,
-  Eigen::PlainObjectBase<DerivedC> & C)
-{
-  C.resize(Z.rows(),3);
-  double denom = (max_z - min_z);
-  denom = (denom == 0) ? 1 : denom;
-  for(int r = 0; r < Z.rows(); ++r) {
-  colormap(
-      cm,
-      (typename DerivedC::Scalar)((-min_z + Z(r,0)) / denom),
-      C(r,0),
-      C(r,1),
-      C(r,2));
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::colormap<float>(igl::ColorMapType, float, float*);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Array<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Array<double, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<double>(igl::ColorMapType, double, double&, double&, double&);
-// generated by autoexplicit.sh
-template void igl::colormap<double>(igl::ColorMapType, double, double*);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::colormap<Eigen::Array<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Array<int, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-
-template void igl::colormap<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::colormap<float>(igl::ColorMapType, float, float&, float&, float&);
-#endif

+ 0 - 27
include/igl/column_to_quats.cpp

@@ -1,27 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "column_to_quats.h"
-IGL_INLINE bool igl::column_to_quats(
-  const Eigen::VectorXd & Q,
-  std::vector<
-    Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & vQ)
-{
-  using namespace Eigen;
-  if(Q.size() % 4 != 0)
-  {
-    return false;
-  }
-  const int nQ = Q.size()/4;
-  vQ.resize(nQ);
-  for(int q=0;q<nQ;q++)
-  {
-    // Constructor uses wxyz
-    vQ[q] = Quaterniond( Q(q*4+3), Q(q*4+0), Q(q*4+1), Q(q*4+2));
-  }
-  return true;
-}

+ 0 - 63
include/igl/columnize.cpp

@@ -1,63 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "columnize.h"
-#include <cassert>
-
-template <typename DerivedA, typename DerivedB>
-IGL_INLINE void igl::columnize(
-  const Eigen::PlainObjectBase<DerivedA> & A,
-  const int k,
-  const int dim,
-  Eigen::PlainObjectBase<DerivedB> & B)
-{
-  // Eigen matrices must be 2d so dim must be only 1 or 2
-  assert(dim == 1 || dim == 2);
-
-  // block height, width, and number of blocks
-  int m,n;
-  if(dim == 1)
-  {
-    m = A.rows()/k;
-    assert(m*(int)k == (int)A.rows());
-    n = A.cols();
-  }else// dim == 2
-  {
-    m = A.rows();
-    n = A.cols()/k;
-    assert(n*(int)k == (int)A.cols());
-  }
-
-  // resize output
-  B.resize(A.rows()*A.cols(),1);
-
-  for(int b = 0;b<(int)k;b++)
-  {
-    for(int i = 0;i<m;i++)
-    {
-      for(int j = 0;j<n;j++)
-      {
-        if(dim == 1)
-        {
-          B(j*m*k+i*k+b) = A(i+b*m,j);
-        }else
-        {
-          B(j*m*k+i*k+b) = A(i,b*n+j);
-        }
-      }
-    }
-  }
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::columnize<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&, int, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
-template void igl::columnize<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&, int, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::columnize<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, int, int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
-template void igl::columnize<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, int, int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 155
include/igl/comb_cross_field.cpp

@@ -1,155 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2014 Daniele Panozzo <[email protected]>, Olga Diamanti <[email protected]>
-//
-// 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/.
-
-#include "comb_cross_field.h"
-
-#include <vector>
-#include <deque>
-#include <Eigen/Geometry>
-#include "per_face_normals.h"
-#include "is_border_vertex.h"
-#include "rotation_matrix_from_directions.h"
-
-#include "triangle_triangle_adjacency.h"
-
-namespace igl {
-  template <typename DerivedV, typename DerivedF>
-  class Comb
-  {
-  public:
-
-    const Eigen::MatrixBase<DerivedV> &V;
-    const Eigen::MatrixBase<DerivedF> &F;
-    const Eigen::MatrixBase<DerivedV> &PD1;
-    const Eigen::MatrixBase<DerivedV> &PD2;
-    DerivedV N;
-
-  private:
-    // internal
-    DerivedF TT;
-    DerivedF TTi;
-
-
-  private:
-
-
-    static inline double Sign(double a){return (double)((a>0)?+1:-1);}
-
-
-  private:
-
-    // returns the 90 deg rotation of a (around n) most similar to target b
-    /// a and b should be in the same plane orthogonal to N
-    static inline Eigen::Matrix<typename DerivedV::Scalar, 3, 1> K_PI_new(const Eigen::Matrix<typename DerivedV::Scalar, 3, 1>& a,
-                                                                   const Eigen::Matrix<typename DerivedV::Scalar, 3, 1>& b,
-                                                                   const Eigen::Matrix<typename DerivedV::Scalar, 3, 1>& n)
-    {
-      Eigen::Matrix<typename DerivedV::Scalar, 3, 1> c = (a.cross(n)).normalized();
-      typename DerivedV::Scalar scorea = a.dot(b);
-      typename DerivedV::Scalar scorec = c.dot(b);
-      if (fabs(scorea)>=fabs(scorec))
-        return a*Sign(scorea);
-      else
-        return c*Sign(scorec);
-    }
-
-
-
-  public:
-    inline Comb(const Eigen::MatrixBase<DerivedV> &_V,
-         const Eigen::MatrixBase<DerivedF> &_F,
-         const Eigen::MatrixBase<DerivedV> &_PD1,
-         const Eigen::MatrixBase<DerivedV> &_PD2
-         ):
-    V(_V),
-    F(_F),
-    PD1(_PD1),
-    PD2(_PD2)
-    {
-      igl::per_face_normals(V,F,N);
-      igl::triangle_triangle_adjacency(F,TT,TTi);
-    }
-    inline void comb(Eigen::PlainObjectBase<DerivedV> &PD1out,
-              Eigen::PlainObjectBase<DerivedV> &PD2out)
-    {
-//      PD1out = PD1;
-//      PD2out = PD2;
-      PD1out.setZero(F.rows(),3);PD1out<<PD1;
-      PD2out.setZero(F.rows(),3);PD2out<<PD2;
-
-      Eigen::VectorXi mark = Eigen::VectorXi::Constant(F.rows(),false);
-
-      std::deque<int> d;
-
-      while (!mark.all()) // Stop until all vertices are marked
-      {
-        int unmarked = 0;
-        while (mark(unmarked))
-          unmarked++;
-        
-        d.push_back(unmarked);
-        mark(unmarked) = true;
-
-        while (!d.empty())
-        {
-          int f0 = d.at(0);
-          d.pop_front();
-          for (int k=0; k<3; k++)
-          {
-            int f1 = TT(f0,k);
-            if (f1==-1) continue;
-            if (mark(f1)) continue;
-
-            Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0    = PD1out.row(f0);
-            Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir1    = PD1out.row(f1);
-            Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n0    = N.row(f0);
-            Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n1    = N.row(f1);
-
-
-            Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0Rot = igl::rotation_matrix_from_directions(n0, n1)*dir0;
-            dir0Rot.normalize();
-            Eigen::Matrix<typename DerivedV::Scalar, 3, 1> targD   = K_PI_new(dir1,dir0Rot,n1);
-
-            PD1out.row(f1)  = targD;
-            PD2out.row(f1)  = n1.cross(targD).normalized();
-
-            mark(f1) = true;
-            d.push_back(f1);
-
-          }
-        }
-      }
-
-      // everything should be marked
-      for (int i=0; i<F.rows(); i++)
-      {
-        assert(mark(i));
-      }
-    }
-
-
-
-  };
-}
-template <typename DerivedV, typename DerivedF>
-IGL_INLINE void igl::comb_cross_field(const Eigen::MatrixBase<DerivedV> &V,
-                                      const Eigen::MatrixBase<DerivedF> &F,
-                                      const Eigen::MatrixBase<DerivedV> &PD1,
-                                      const Eigen::MatrixBase<DerivedV> &PD2,
-                                      Eigen::PlainObjectBase<DerivedV> &PD1out,
-                                      Eigen::PlainObjectBase<DerivedV> &PD2out)
-{
-  igl::Comb<DerivedV, DerivedF> cmb(V, F, PD1, PD2);
-  cmb.comb(PD1out, PD2out);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::comb_cross_field<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::comb_cross_field<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 78
include/igl/comb_frame_field.cpp

@@ -1,78 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2014 Daniele Panozzo <[email protected]>, Olga Diamanti <[email protected]>
-//
-// 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/.
-
-#ifdef WIN32
-  #define _USE_MATH_DEFINES
-#endif
-#include <cmath>
-
-#include "comb_frame_field.h"
-#include "local_basis.h"
-#include "PI.h"
-
-template <typename DerivedV, typename DerivedF, typename DerivedP>
-IGL_INLINE void igl::comb_frame_field(const Eigen::MatrixBase<DerivedV> &V,
-                                      const Eigen::MatrixBase<DerivedF> &F,
-                                      const Eigen::MatrixBase<DerivedP> &PD1,
-                                      const Eigen::MatrixBase<DerivedP> &PD2,
-                                      const Eigen::MatrixBase<DerivedP> &BIS1_combed,
-                                      const Eigen::MatrixBase<DerivedP> &BIS2_combed,
-                                      Eigen::PlainObjectBase<DerivedP> &PD1_combed,
-                                      Eigen::PlainObjectBase<DerivedP> &PD2_combed)
-{
-  DerivedV B1, B2, B3;
-  igl::local_basis(V,F,B1,B2,B3);
-
-  PD1_combed.resize(BIS1_combed.rows(),3);
-  PD2_combed.resize(BIS2_combed.rows(),3);
-
-  for (unsigned i=0; i<PD1.rows();++i)
-  {
-    Eigen::Matrix<typename DerivedP::Scalar,4,3> DIRs;
-    DIRs <<
-    PD1.row(i),
-    -PD1.row(i),
-    PD2.row(i),
-    -PD2.row(i);
-
-    std::vector<double> a(4);
-
-
-    double a_combed = atan2(B2.row(i).dot(BIS1_combed.row(i)),B1.row(i).dot(BIS1_combed.row(i)));
-
-    // center on the combed sector center
-    for (unsigned j=0;j<4;++j)
-    {
-      a[j] = atan2(B2.row(i).dot(DIRs.row(j)),B1.row(i).dot(DIRs.row(j))) - a_combed;
-      //make it positive by adding some multiple of 2pi
-      a[j] += std::ceil (std::max(0., -a[j]) / (igl::PI*2.)) * (igl::PI*2.);
-      //take modulo 2pi
-      a[j] = fmod(a[j], (igl::PI*2.));
-    }
-    // now the max is u and the min is v
-
-    int m = std::min_element(a.begin(),a.end())-a.begin();
-    int M = std::max_element(a.begin(),a.end())-a.begin();
-
-    assert(
-           ((m>=0 && m<=1) && (M>=2 && M<=3))
-           ||
-           ((m>=2 && m<=3) && (M>=0 && M<=1))
-           );
-
-    PD1_combed.row(i) = DIRs.row(m);
-    PD2_combed.row(i) = DIRs.row(M);
-
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::comb_frame_field<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::comb_frame_field<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 132
include/igl/comb_line_field.cpp

@@ -1,132 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2014 Nico Pietroni <[email protected]>
-//
-// 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/.
-
-#include "comb_line_field.h"
-
-#include <vector>
-#include <deque>
-#include "per_face_normals.h"
-#include "is_border_vertex.h"
-#include "rotation_matrix_from_directions.h"
-
-#include "triangle_triangle_adjacency.h"
-
-namespace igl {
-template <typename DerivedV, typename DerivedF>
-class CombLine
-{
-public:
-
-    const Eigen::MatrixBase<DerivedV> &V;
-    const Eigen::MatrixBase<DerivedF> &F;
-    const Eigen::MatrixBase<DerivedV> &PD1;
-    DerivedV N;
-
-private:
-    // internal
-    DerivedF TT;
-    DerivedF TTi;
-
-
-private:
-
-
-    static inline double Sign(double a){return (double)((a>0)?+1:-1);}
-
-
-private:
-
-    // returns the 180 deg rotation of a (around n) most similar to target b
-    // a and b should be in the same plane orthogonal to N
-    static inline Eigen::Matrix<typename DerivedV::Scalar, 3, 1> K_PI_line(const Eigen::Matrix<typename DerivedV::Scalar, 3, 1>& a,
-                                                                           const Eigen::Matrix<typename DerivedV::Scalar, 3, 1>& b)
-    {
-        typename DerivedV::Scalar scorea = a.dot(b);
-        if (scorea<0)
-            return -a;
-        else
-            return a;
-    }
-
-
-
-public:
-
-    inline CombLine(const Eigen::MatrixBase<DerivedV> &_V,
-                    const Eigen::MatrixBase<DerivedF> &_F,
-                    const Eigen::MatrixBase<DerivedV> &_PD1):
-        V(_V),
-        F(_F),
-        PD1(_PD1)
-    {
-        igl::per_face_normals(V,F,N);
-        igl::triangle_triangle_adjacency(F,TT,TTi);
-    }
-
-    inline void comb(Eigen::PlainObjectBase<DerivedV> &PD1out)
-    {
-        PD1out.setZero(F.rows(),3);PD1out<<PD1;
-
-        Eigen::VectorXi mark = Eigen::VectorXi::Constant(F.rows(),false);
-
-        std::deque<int> d;
-
-        d.push_back(0);
-        mark(0) = true;
-
-        while (!d.empty())
-        {
-            int f0 = d.at(0);
-            d.pop_front();
-            for (int k=0; k<3; k++)
-            {
-                int f1 = TT(f0,k);
-                if (f1==-1) continue;
-                if (mark(f1)) continue;
-
-                Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0  = PD1out.row(f0);
-                Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir1  = PD1out.row(f1);
-                Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n0    = N.row(f0);
-                Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n1    = N.row(f1);
-
-                Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0Rot = igl::rotation_matrix_from_directions(n0, n1)*dir0;
-                dir0Rot.normalize();
-                Eigen::Matrix<typename DerivedV::Scalar, 3, 1> targD   = K_PI_line(dir1,dir0Rot);
-
-                PD1out.row(f1)  = targD;
-                //PD2out.row(f1)  = n1.cross(targD).normalized();
-
-                mark(f1) = true;
-                d.push_back(f1);
-
-            }
-        }
-
-        // everything should be marked
-        for (int i=0; i<F.rows(); i++)
-        {
-            assert(mark(i));
-        }
-    }
-
-};
-}
-
-template <typename DerivedV, typename DerivedF>
-IGL_INLINE void igl::comb_line_field(const Eigen::MatrixBase<DerivedV> &V,
-                                     const Eigen::MatrixBase<DerivedF> &F,
-                                     const Eigen::MatrixBase<DerivedV> &PD1,
-                                     Eigen::PlainObjectBase<DerivedV> &PD1out)
-{
-    igl::CombLine<DerivedV, DerivedF> cmb(V, F, PD1);
-    cmb.comb(PD1out);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#endif

+ 0 - 99
include/igl/combine.cpp

@@ -1,99 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "combine.h"
-#include <cassert>
-
-template <
-  typename DerivedVV,
-  typename DerivedFF,
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedVsizes,
-  typename DerivedFsizes>
-IGL_INLINE void igl::combine(
-  const std::vector<DerivedVV> & VV,
-  const std::vector<DerivedFF> & FF,
-  Eigen::PlainObjectBase<DerivedV> & V,
-  Eigen::PlainObjectBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedVsizes> & Vsizes,
-  Eigen::PlainObjectBase<DerivedFsizes> & Fsizes)
-{
-  assert(VV.size() == FF.size() &&
-    "Lists of verex lists and face lists should be same size");
-  Vsizes.resize(VV.size());
-  Fsizes.resize(FF.size());
-  // Dimension of vertex positions
-  const int dim = VV.size() > 0 ? VV[0].cols() : 0;
-  // Simplex/element size
-  const int ss = FF.size() > 0 ? FF[0].cols() : 0;
-  int n = 0;
-  int m = 0;
-  for(int i = 0;i<VV.size();i++)
-  {
-    const auto & Vi = VV[i];
-    const auto & Fi = FF[i];
-    Vsizes(i) = Vi.rows();
-    n+=Vi.rows();
-    assert((Vi.size()==0 || dim == Vi.cols()) && "All vertex lists should have same #columns");
-    Fsizes(i) = Fi.rows();
-    m+=Fi.rows();
-    assert((Fi.size()==0 || ss == Fi.cols()) && "All face lists should have same #columns");
-  }
-  V.resize(n,dim);
-  F.resize(m,ss);
-  {
-    int kv = 0;
-    int kf = 0;
-    for(int i = 0;i<VV.size();i++)
-    {
-      const auto & Vi = VV[i];
-      const int ni = Vi.rows();
-      const auto & Fi = FF[i];
-      const int mi = Fi.rows();
-      if(Fi.size() >0)
-      {
-        F.block(kf,0,mi,ss) = Fi.array()+kv;
-      }
-      kf+=mi;
-      if(Vi.size() >0)
-      {
-        V.block(kv,0,ni,dim) = Vi;
-      }
-      kv+=ni;
-    }
-    assert(kv == V.rows());
-    assert(kf == F.rows());
-  }
-}
-
-template <
-  typename DerivedVV,
-  typename DerivedFF,
-  typename DerivedV,
-  typename DerivedF>
-IGL_INLINE void igl::combine(
-  const std::vector<DerivedVV> & VV,
-  const std::vector<DerivedFF> & FF,
-  Eigen::PlainObjectBase<DerivedV> & V,
-  Eigen::PlainObjectBase<DerivedF> & F)
-{
-  Eigen::VectorXi Vsizes,Fsizes;
-  return igl::combine(VV,FF,V,F,Vsizes,Fsizes);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::combine<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::vector<Eigen::Matrix<float, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<float, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::combine<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<unsigned long, -1, 1, 0, -1, 1>, Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >&);
-template void igl::combine<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::vector<Eigen::Matrix<double, -1, 3, 1, -1, 3>, std::allocator<Eigen::Matrix<double, -1, 3, 1, -1, 3> > > const&, std::vector<Eigen::Matrix<int, -1, 3, 1, -1, 3>, std::allocator<Eigen::Matrix<int, -1, 3, 1, -1, 3> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
-template void igl::combine<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> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#ifdef WIN32
-template void igl::combine<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<unsigned __int64,-1,1,0,-1,1>,Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> >(class std::vector<Eigen::Matrix<double,-1,-1,0,-1,-1>,class std::allocator<Eigen::Matrix<double,-1,-1,0,-1,-1> > > const &,class std::vector<Eigen::Matrix<int,-1,-1,0,-1,-1>,class std::allocator<Eigen::Matrix<int,-1,-1,0,-1,-1> > > const &,Eigen::PlainObjectBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > &,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > &,Eigen::PlainObjectBase<Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> > &,Eigen::PlainObjectBase<Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> > &);
-#endif
-#endif

+ 0 - 86
include/igl/compute_frame_field_bisectors.cpp

@@ -1,86 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2014 Daniele Panozzo <[email protected]>, Olga Diamanti <[email protected]>
-//
-// 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/.
-
-#ifdef WIN32
-  #define _USE_MATH_DEFINES
-#endif
-#include <cmath>
-
-#include "compute_frame_field_bisectors.h"
-#include "igl/local_basis.h"
-#include "PI.h"
-
-template <typename DerivedV, typename DerivedF>
-IGL_INLINE void igl::compute_frame_field_bisectors(
-  const Eigen::MatrixBase<DerivedV>& V,
-  const Eigen::MatrixBase<DerivedF>& F,
-  const Eigen::MatrixBase<DerivedV>& B1,
-  const Eigen::MatrixBase<DerivedV>& B2,
-  const Eigen::MatrixBase<DerivedV>& PD1,
-  const Eigen::MatrixBase<DerivedV>& PD2,
-  Eigen::PlainObjectBase<DerivedV>& BIS1,
-  Eigen::PlainObjectBase<DerivedV>& BIS2)
-{
-  BIS1.resize(PD1.rows(),3);
-  BIS2.resize(PD1.rows(),3);
-
-  for (unsigned i=0; i<PD1.rows();++i)
-  {
-    // project onto the tangent plane and convert to angle
-    // Convert to angle
-    double a1 = atan2(B2.row(i).dot(PD1.row(i)),B1.row(i).dot(PD1.row(i)));
-    //make it positive by adding some multiple of 2pi
-    a1 += std::ceil (std::max(0., -a1) / (igl::PI*2.)) * (igl::PI*2.);
-    //take modulo 2pi
-    a1 = fmod(a1, (igl::PI*2.));
-    double a2 = atan2(B2.row(i).dot(PD2.row(i)),B1.row(i).dot(PD2.row(i)));
-    //make it positive by adding some multiple of 2pi
-    a2 += std::ceil (std::max(0., -a2) / (igl::PI*2.)) * (igl::PI*2.);
-    //take modulo 2pi
-    a2 = fmod(a2, (igl::PI*2.));
-
-    double b1 = (a1+a2)/2.0;
-    //make it positive by adding some multiple of 2pi
-    b1 += std::ceil (std::max(0., -b1) / (igl::PI*2.)) * (igl::PI*2.);
-    //take modulo 2pi
-    b1 = fmod(b1, (igl::PI*2.));
-
-    double b2 = b1+(igl::PI/2.);
-    //make it positive by adding some multiple of 2pi
-    b2 += std::ceil (std::max(0., -b2) / (igl::PI*2.)) * (igl::PI*2.);
-    //take modulo 2pi
-    b2 = fmod(b2, (igl::PI*2.));
-
-    BIS1.row(i) = cos(b1) * B1.row(i) + sin(b1) * B2.row(i);
-    BIS2.row(i) = cos(b2) * B1.row(i) + sin(b2) * B2.row(i);
-
-  }
-}
-
-template <typename DerivedV, typename DerivedF>
-IGL_INLINE void igl::compute_frame_field_bisectors(
-                                                   const Eigen::MatrixBase<DerivedV>& V,
-                                                   const Eigen::MatrixBase<DerivedF>& F,
-                                                   const Eigen::MatrixBase<DerivedV>& PD1,
-                                                   const Eigen::MatrixBase<DerivedV>& PD2,
-                                                   Eigen::PlainObjectBase<DerivedV>& BIS1,
-                                                   Eigen::PlainObjectBase<DerivedV>& BIS2)
-{
-  DerivedV B1, B2, B3;
-  igl::local_basis(V,F,B1,B2,B3);
-
-  compute_frame_field_bisectors( V, F, B1, B2, PD1, PD2, BIS1, BIS2);
-
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::compute_frame_field_bisectors<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::compute_frame_field_bisectors<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::compute_frame_field_bisectors<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 55
include/igl/connect_boundary_to_infinity.cpp

@@ -1,55 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "connect_boundary_to_infinity.h"
-#include "boundary_facets.h"
-
-template <typename DerivedF, typename DerivedFO>
-IGL_INLINE void igl::connect_boundary_to_infinity(
-  const Eigen::MatrixBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedFO> & FO)
-{
-  return connect_boundary_to_infinity(F,F.maxCoeff(),FO);
-}
-template <typename DerivedF, typename DerivedFO>
-IGL_INLINE void igl::connect_boundary_to_infinity(
-  const Eigen::MatrixBase<DerivedF> & F,
-  const typename DerivedF::Scalar inf_index,
-  Eigen::PlainObjectBase<DerivedFO> & FO)
-{
-  // Determine boundary edges
-  Eigen::Matrix<typename DerivedFO::Scalar,Eigen::Dynamic,Eigen::Dynamic> O;
-  boundary_facets(F,O);
-  FO.resize(F.rows()+O.rows(),F.cols());
-  typedef Eigen::Matrix<typename DerivedFO::Scalar,Eigen::Dynamic,1> VectorXI;
-  FO.topLeftCorner(F.rows(),F.cols()) = F;
-  FO.bottomLeftCorner(O.rows(),O.cols()) = O.rowwise().reverse();
-  FO.bottomRightCorner(O.rows(),1).setConstant(inf_index);
-}
-
-template <
-  typename DerivedV, 
-  typename DerivedF, 
-  typename DerivedVO, 
-  typename DerivedFO>
-IGL_INLINE void igl::connect_boundary_to_infinity(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedVO> & VO,
-  Eigen::PlainObjectBase<DerivedFO> & FO)
-{
-  typename DerivedV::Index inf_index = V.rows();
-  connect_boundary_to_infinity(F,inf_index,FO);
-  VO.resize(V.rows()+1,V.cols());
-  VO.topLeftCorner(V.rows(),V.cols()) = V;
-  auto inf = std::numeric_limits<typename DerivedVO::Scalar>::infinity();
-  VO.row(V.rows()).setConstant(inf);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-template void igl::connect_boundary_to_infinity<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 63
include/igl/connected_components.cpp

@@ -1,63 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2020 Alec Jacobson <[email protected]>
-//
-// 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/.
-
-#include "connected_components.h"
-#include <queue>
-
-template < typename Atype, typename DerivedC, typename DerivedK>
-IGL_INLINE int igl::connected_components(
-  const Eigen::SparseMatrix<Atype> & A,
-  Eigen::PlainObjectBase<DerivedC> & C,
-  Eigen::PlainObjectBase<DerivedK> & K)
-{
-  typedef typename Eigen::SparseMatrix<Atype>::Index Index;
-  const auto m = A.rows();
-  assert(A.cols() == A.rows() && "A should be square");
-  // 1.1 sec
-  // m  means not yet visited
-  C.setConstant(m,1,m);
-  // Could use amortized dynamic array but didn't see real win.
-  K.setZero(m,1);
-  typename DerivedC::Scalar c = 0;
-  for(Eigen::Index f = 0;f<m;f++)
-  {
-    // already seen
-    if(C(f)<m) continue;
-    // start bfs
-    std::queue<Index> Q;
-    Q.push(f);
-    while(!Q.empty())
-    {
-      const Index g = Q.front();
-      Q.pop();
-      // already seen
-      if(C(g)<m) continue;
-      // see it
-      C(g) = c;
-      K(c)++;
-      for(typename Eigen::SparseMatrix<Atype>::InnerIterator it (A,g); it; ++it)
-      {
-        const Index n = it.index();
-        // already seen
-        if(C(n)<m) continue;
-        Q.push(n);
-      }
-    }
-    c++;
-  }
-  K.conservativeResize(c,1);
-  return c;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template int igl::connected_components<bool, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<bool, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-// generated by autoexplicit.sh
-template int igl::connected_components<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<int, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 88
include/igl/copyleft/cgal/assign.cpp

@@ -1,88 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "assign.h"
-#include "../../parallel_for.h"
-#include "assign_scalar.h"
-
-template <typename DerivedC, typename DerivedD>
-IGL_INLINE void igl::copyleft::cgal::assign(
-  const Eigen::MatrixBase<DerivedC> & C,
-  const bool slow_and_more_precise,
-  Eigen::PlainObjectBase<DerivedD> & D)
-{
-  D.resizeLike(C);
-  igl::parallel_for(C.size(),[&](Eigen::Index k)
-  {
-    const Eigen::Index i = k%C.rows();
-    const Eigen::Index j = k/C.rows();
-    assign_scalar(C(i,j),slow_and_more_precise,D(i,j));
-  },1000);
-}
-template <typename DerivedC, typename DerivedD>
-IGL_INLINE void igl::copyleft::cgal::assign(
-  const Eigen::MatrixBase<DerivedC> & C,
-  Eigen::PlainObjectBase<DerivedD> & D)
-{
-  const bool slow_and_more_precise = false;
-  return assign(C,slow_and_more_precise,D);
-}
-
-template <typename ReturnScalar, typename DerivedC>
-IGL_INLINE
-Eigen::Matrix<
-  ReturnScalar,
-  DerivedC::RowsAtCompileTime,
-  DerivedC::ColsAtCompileTime,
-  1,
-  DerivedC::MaxRowsAtCompileTime,
-  DerivedC::MaxColsAtCompileTime>
-igl::copyleft::cgal::assign(
-  const Eigen::MatrixBase<DerivedC> & C)
-{
-  Eigen::Matrix<
-    ReturnScalar,
-    DerivedC::RowsAtCompileTime,
-    DerivedC::ColsAtCompileTime,
-    1,
-    DerivedC::MaxRowsAtCompileTime,
-    DerivedC::MaxColsAtCompileTime> D;
-  assign(C,D);
-  return D;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>,  Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<double, 8, 3, 0, 8, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 8, 3, 0, 8, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&);
-#endif

+ 0 - 199
include/igl/copyleft/cgal/assign_scalar.cpp

@@ -1,199 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "assign_scalar.h"
-
-template <>
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Epeck::FT & rhs,
-  const bool & slow_and_more_precise,
-  double & lhs)
-{
-  if(slow_and_more_precise)
-  {
-    return assign_scalar(rhs,lhs);
-  }else
-  {
-    // While this is significantly faster (100x), this does not guarantee that
-    // two equivalent rationals produce the same double (e.g.,
-    // CGAL::to_double(⅓) ≠ CGAL::to_double(1-⅔))
-    // https://github.com/CGAL/cgal/discussions/6000 For remesh_intersections,
-    // `unique` is called _after_ rounding to floats, avoiding more expensive
-    // rational equality tests. To operate correctly, we need that a=b ⇒
-    // double(a)=double(b). Alternatively, we could require that
-    // remesh_intersections conduct its `unique` operation on rationals. This is
-    // even more expensive (4x) and most of the time probably overkill, though
-    // it is argueably more correct in terms of producing the correct topology
-    // (despite degeneracies that appear during rounding). On the other hand,
-    // this rounding-before-unique only occurs if the requested output is float,
-    // so its a question of combinatorial vs geometric degeneracies. Argueably,
-    // combinatorial degeneracies are more reliably detected.
-    //
-    //lhs = CGAL::to_double(rhs);
-    lhs = CGAL::to_double(rhs.exact());
-  }
-}
-
-template <>
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Epeck::FT & rhs,
-  const bool & slow_and_more_precise,
-  float & lhs)
-{
-  double d;
-  igl::copyleft::cgal::assign_scalar(rhs,slow_and_more_precise,d);
-  lhs = float(d);
-}
-
-// If we haven't specialized the types then `slow_and_more_precise` doesn't make sense.
-template <typename RHS, typename LHS>
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const RHS & rhs,
-  const bool & slow_and_more_precise,
-  LHS & lhs)
-{
-  return assign_scalar(rhs,lhs);
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Epeck::FT & cgal,
-  CGAL::Epeck::FT & d)
-{
-  d = cgal;
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Epeck::FT & _cgal,
-  double & d)
-{
-  // FORCE evaluation of the exact type otherwise interval might be huge.
-  const CGAL::Epeck::FT cgal = _cgal.exact();
-  const auto interval = CGAL::to_interval(cgal);
-  d = interval.first;
-  do {
-      const double next = nextafter(d, interval.second);
-      if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
-      d = next;
-  } while (d < interval.second);
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Epeck::FT & _cgal,
-  float& d)
-{
-  // FORCE evaluation of the exact type otherwise interval might be huge.
-  const CGAL::Epeck::FT cgal = _cgal.exact();
-  const auto interval = CGAL::to_interval(cgal);
-  d = interval.first;
-  do {
-      const float next = nextafter(d, float(interval.second));
-      if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
-      d = next;
-  } while (d < float(interval.second));
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const double & c,
-  double & d)
-{
-  d = c;
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const float& c,
-  float& d)
-{
-  d = c;
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const float& c,
-  double& d)
-{
-  d = c;
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & cgal,
-  CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & d)
-{
-  d = cgal;
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & cgal,
-  double & d)
-{
-  const auto interval = CGAL::to_interval(cgal);
-  d = interval.first;
-  do {
-      const double next = nextafter(d, interval.second);
-      if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
-      d = next;
-  } while (d < interval.second);
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & cgal,
-  float& d)
-{
-  const auto interval = CGAL::to_interval(cgal);
-  d = interval.first;
-  do {
-      const float next = nextafter(d, float(interval.second));
-      if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
-      d = next;
-  } while (d < float(interval.second));
-}
-
-#ifndef WIN32
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
-  CGAL::Simple_cartesian<mpq_class>::FT & d)
-{
-  d = cgal;
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
-  double & d)
-{
-  const auto interval = CGAL::to_interval(cgal);
-  d = interval.first;
-  do {
-      const double next = nextafter(d, interval.second);
-      if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
-      d = next;
-  } while (d < interval.second);
-}
-
-IGL_INLINE void igl::copyleft::cgal::assign_scalar(
-  const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
-  float& d)
-{
-  const auto interval = CGAL::to_interval(cgal);
-  d = interval.first;
-  do {
-      const float next = nextafter(d, float(interval.second));
-      if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
-      d = next;
-  } while (d < float(interval.second));
-}
-
-#endif // WIN32
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::assign_scalar<float, double>(float const&, bool const&, double&);
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::assign_scalar<float, CGAL::Epeck::FT >(float const&, bool const&, CGAL::Epeck::FT&);
-template void igl::copyleft::cgal::assign_scalar<double, double>(double const&, bool const&, double&);
-template void igl::copyleft::cgal::assign_scalar<double, CGAL::Epeck::FT >(double const&, bool const&, CGAL::Epeck::FT&);
-template void igl::copyleft::cgal::assign_scalar<CGAL::Epeck::FT, CGAL::Epeck::FT >(CGAL::Epeck::FT const&, bool const&, CGAL::Epeck::FT&);
-#endif

+ 0 - 16
include/igl/copyleft/cgal/barycenter.cpp

@@ -1,16 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2017 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "../../barycenter.h"
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#ifdef IGL_STATIC_LIBRARY
-#undef IGL_STATIC_LIBRARY
-#include "../../barycenter.cpp"
-// Explicit template instantiation
-template void igl::barycenter<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 36
include/igl/copyleft/cgal/cell_adjacency.cpp

@@ -1,36 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Qingnan Zhou <[email protected]>
-// 
-// 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/.
-//
-
-#include "cell_adjacency.h"
-
-template <typename DerivedC>
-IGL_INLINE void igl::copyleft::cgal::cell_adjacency(
-    const Eigen::PlainObjectBase<DerivedC>& per_patch_cells,
-    const size_t num_cells,
-    std::vector<std::set<std::tuple<typename DerivedC::Scalar, bool, size_t> > >&
-    adjacency_list) {
-
-  const size_t num_patches = per_patch_cells.rows();
-  adjacency_list.resize(num_cells);
-  for (size_t i=0; i<num_patches; i++) {
-    const int positive_cell = per_patch_cells(i,0);
-    const int negative_cell = per_patch_cells(i,1);
-    adjacency_list[positive_cell].emplace(negative_cell, false, i);
-    adjacency_list[negative_cell].emplace(positive_cell, true, i);
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::cell_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, std::vector<std::set<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long>, std::less<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> >, std::allocator<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> > >, std::allocator<std::set<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long>, std::less<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> >, std::allocator<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> > > > >&);
-#ifdef WIN32
-template void igl::copyleft::cgal::cell_adjacency<class Eigen::Matrix<int, -1, -1, 0, -1, -1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, unsigned __int64, class std::vector<class std::set<class std::tuple<int, bool, unsigned __int64>, struct std::less<class std::tuple<int, bool, unsigned __int64>>, class std::allocator<class std::tuple<int, bool, unsigned __int64>>>, class std::allocator<class std::set<class std::tuple<int, bool, unsigned __int64>, struct std::less<class std::tuple<int, bool, unsigned __int64>>, class std::allocator<class std::tuple<int, bool, unsigned __int64>>>>> &);
-#endif
-#endif

+ 0 - 509
include/igl/copyleft/cgal/closest_facet.cpp

@@ -1,509 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Qingnan Zhou <[email protected]>
-// 
-// 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/.
-//
-#include "closest_facet.h"
-
-#include <vector>
-#include <stdexcept>
-#include <unordered_map>
-
-#include "order_facets_around_edge.h"
-#include "submesh_aabb_tree.h"
-#include "../../vertex_triangle_adjacency.h"
-#include "../../LinSpaced.h"
-//#include "../../writePLY.h"
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedI,
-  typename DerivedP,
-  typename DerivedEMAP,
-  typename DeriveduEC,
-  typename DeriveduEE,
-  typename Kernel,
-  typename DerivedR,
-  typename DerivedS >
-IGL_INLINE void igl::copyleft::cgal::closest_facet(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    const Eigen::PlainObjectBase<DerivedI>& I,
-    const Eigen::PlainObjectBase<DerivedP>& P,
-    const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
-    const Eigen::PlainObjectBase<DeriveduEC>& uEC,
-    const Eigen::PlainObjectBase<DeriveduEE>& uEE,
-    const std::vector<std::vector<size_t> > & VF,
-    const std::vector<std::vector<size_t> > & VFi,
-    const CGAL::AABB_tree<
-      CGAL::AABB_traits<
-        Kernel, 
-        CGAL::AABB_triangle_primitive<
-          Kernel, typename std::vector<
-            typename Kernel::Triangle_3 >::iterator > > > & tree,
-    const std::vector<typename Kernel::Triangle_3 > & triangles,
-    const std::vector<bool> & in_I,
-    Eigen::PlainObjectBase<DerivedR>& R,
-    Eigen::PlainObjectBase<DerivedS>& S)
-{
-  typedef typename Kernel::Point_3 Point_3;
-  typedef typename Kernel::Plane_3 Plane_3;
-  typedef typename Kernel::Segment_3 Segment_3;
-  typedef typename Kernel::Triangle_3 Triangle;
-  typedef typename std::vector<Triangle>::iterator Iterator;
-  typedef typename CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
-  typedef typename CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
-  typedef typename CGAL::AABB_tree<AABB_triangle_traits> Tree;
-
-  const size_t num_faces = I.rows();
-  if (F.rows() <= 0 || I.rows() <= 0) {
-    throw std::runtime_error(
-        "Closest facet cannot be computed on empty mesh.");
-  }
-
-  auto on_the_positive_side = [&](size_t fid, const Point_3& p) -> bool
-  {
-    const auto& f = F.row(fid).eval();
-    Point_3 v0(V(f[0], 0), V(f[0], 1), V(f[0], 2));
-    Point_3 v1(V(f[1], 0), V(f[1], 1), V(f[1], 2));
-    Point_3 v2(V(f[2], 0), V(f[2], 1), V(f[2], 2));
-    auto ori = CGAL::orientation(v0, v1, v2, p);
-    switch (ori) {
-      case CGAL::POSITIVE:
-        return true;
-      case CGAL::NEGATIVE:
-        return false;
-      case CGAL::COPLANAR:
-        // Warning:
-        // This can only happen if fid contains a boundary edge.
-        // Categorized this ambiguous case as negative side.
-        return false;
-      default:
-        throw std::runtime_error("Unknown CGAL state.");
-    }
-    return false;
-  };
-
-  auto get_orientation = [&](size_t fid, size_t s, size_t d) -> bool 
-  {
-    const auto& f = F.row(fid);
-    if      ((size_t)f[0] == s && (size_t)f[1] == d) return false;
-    else if ((size_t)f[1] == s && (size_t)f[2] == d) return false;
-    else if ((size_t)f[2] == s && (size_t)f[0] == d) return false;
-    else if ((size_t)f[0] == d && (size_t)f[1] == s) return true;
-    else if ((size_t)f[1] == d && (size_t)f[2] == s) return true;
-    else if ((size_t)f[2] == d && (size_t)f[0] == s) return true;
-    else {
-      throw std::runtime_error(
-          "Cannot compute orientation due to incorrect connectivity");
-      return false;
-    }
-  };
-  auto index_to_signed_index = [&](size_t index, bool ori) -> int{
-    return (index+1) * (ori? 1:-1);
-  };
-  //auto signed_index_to_index = [&](int signed_index) -> size_t {
-  //    return abs(signed_index) - 1;
-  //};
-
-  enum ElementType { VERTEX, EDGE, FACE };
-  auto determine_element_type = [&](const Point_3& p, const size_t fid,
-      size_t& element_index) -> ElementType {
-    const auto& tri = triangles[fid];
-    const Point_3 p0 = tri[0];
-    const Point_3 p1 = tri[1];
-    const Point_3 p2 = tri[2];
-
-    if (p == p0) { element_index = 0; return VERTEX; }
-    if (p == p1) { element_index = 1; return VERTEX; }
-    if (p == p2) { element_index = 2; return VERTEX; }
-    if (CGAL::collinear(p0, p1, p)) { element_index = 2; return EDGE; }
-    if (CGAL::collinear(p1, p2, p)) { element_index = 0; return EDGE; }
-    if (CGAL::collinear(p2, p0, p)) { element_index = 1; return EDGE; }
-
-    element_index = 0;
-    return FACE;
-  };
-
-  auto process_edge_case = [&](
-      size_t query_idx,
-      const size_t s, const size_t d,
-      size_t preferred_facet,
-      bool& orientation) -> size_t 
-  {
-    Point_3 query_point(
-      P(query_idx, 0),
-      P(query_idx, 1),
-      P(query_idx, 2));
-
-    size_t corner_idx = std::numeric_limits<size_t>::max();
-    if ((s == F(preferred_facet, 0) && d == F(preferred_facet, 1)) ||
-        (s == F(preferred_facet, 1) && d == F(preferred_facet, 0))) 
-    {
-      corner_idx = 2;
-    } else if ((s == F(preferred_facet, 0) && d == F(preferred_facet, 2)) ||
-        (s == F(preferred_facet, 2) && d == F(preferred_facet, 0))) 
-    {
-      corner_idx = 1;
-    } else if ((s == F(preferred_facet, 1) && d == F(preferred_facet, 2)) ||
-        (s == F(preferred_facet, 2) && d == F(preferred_facet, 1))) 
-    {
-      corner_idx = 0;
-    } else 
-    {
-      std::cerr << "s: " << s << "\t d:" << d << std::endl;
-      std::cerr << F.row(preferred_facet) << std::endl;
-      throw std::runtime_error(
-          "Invalid connectivity, edge does not belong to facet");
-    }
-
-    auto ueid = EMAP(preferred_facet + corner_idx * F.rows());
-    std::vector<size_t> intersected_face_indices;
-    //auto eids = uE2E[ueid];
-    //for (auto eid : eids) 
-    for(size_t j = uEC(ueid);j<uEC(ueid+1);j++)
-    {
-      const size_t eid = uEE(j);
-      const size_t fid = eid % F.rows();
-      if (in_I[fid]) 
-      {
-        intersected_face_indices.push_back(fid);
-      }
-    }
-
-    const size_t num_intersected_faces = intersected_face_indices.size();
-    std::vector<int> intersected_face_signed_indices(num_intersected_faces);
-    std::transform(
-        intersected_face_indices.begin(),
-        intersected_face_indices.end(),
-        intersected_face_signed_indices.begin(),
-        [&](size_t index) {
-        return index_to_signed_index(
-          index, get_orientation(index, s,d));
-        });
-
-    assert(num_intersected_faces >= 1);
-    if (num_intersected_faces == 1) 
-    {
-      // The edge must be a boundary edge.  Thus, the orientation can be
-      // simply determined by checking if the query point is on the
-      // positive side of the facet.
-      const size_t fid = intersected_face_indices[0];
-      orientation = on_the_positive_side(fid, query_point);
-      return fid;
-    }
-
-    Eigen::VectorXi order;
-    DerivedP pivot = P.row(query_idx).eval();
-    igl::copyleft::cgal::order_facets_around_edge(V, F, s, d,
-      intersected_face_signed_indices,
-      pivot, order);
-
-    // Although first and last are equivalent, make the choice based on
-    // preferred_facet.
-    const size_t first = order[0];
-    const size_t last = order[num_intersected_faces-1];
-    if (intersected_face_indices[first] == preferred_facet) {
-      orientation = intersected_face_signed_indices[first] < 0;
-      return intersected_face_indices[first];
-    } else if (intersected_face_indices[last] == preferred_facet) {
-      orientation = intersected_face_signed_indices[last] > 0;
-      return intersected_face_indices[last];
-    } else {
-      orientation = intersected_face_signed_indices[order[0]] < 0;
-      return intersected_face_indices[order[0]];
-    }
-  };
-
-  auto process_face_case = [&](
-      const size_t query_idx, const Point_3& closest_point,
-      const size_t fid, bool& orientation) -> size_t {
-    const auto& f = F.row(I(fid, 0));
-    return process_edge_case(query_idx, f[0], f[1], I(fid, 0), orientation);
-  };
-
-  // Given that the closest point to query point P(query_idx,:) on (V,F(I,:))
-  // is the vertex at V(s,:) which is incident at least on triangle
-  // F(preferred_facet,:), determine a facet incident on V(s,:) that is
-  // _exposed_ to the query point and determine whether that facet is facing
-  // _toward_ or _away_ from the query point.
-  //
-  // Inputs:
-  //   query_idx  index into P of query point
-  //   s  index into V of closest point at vertex
-  //   preferred_facet  facet incident on s
-  // Outputs:
-  //   orientation  whether returned face is facing toward or away from
-  //     query (parity unclear)
-  // Returns face guaranteed to be "exposed" to P(query_idx,:)
-  auto process_vertex_case = [&](
-    const size_t query_idx, 
-    size_t s,
-    size_t preferred_facet, 
-    bool& orientation) -> size_t
-  {
-    const Point_3 query_point(
-        P(query_idx, 0), P(query_idx, 1), P(query_idx, 2));
-    const Point_3 closest_point(V(s, 0), V(s, 1), V(s, 2));
-    std::vector<size_t> adj_faces;
-    std::vector<size_t> adj_face_corners;
-    {
-      // Gather adj faces to s within I.
-      const auto& all_adj_faces = VF[s];
-      const auto& all_adj_face_corners = VFi[s];
-      const size_t num_all_adj_faces = all_adj_faces.size();
-      for (size_t i=0; i<num_all_adj_faces; i++) 
-      {
-        const size_t fid = all_adj_faces[i];
-        // Shouldn't this always be true if I is a full connected component?
-        if (in_I[fid]) 
-        {
-          adj_faces.push_back(fid);
-          adj_face_corners.push_back(all_adj_face_corners[i]);
-        }
-      }
-    }
-    const size_t num_adj_faces = adj_faces.size();
-    assert(num_adj_faces > 0);
-
-    std::set<size_t> adj_vertices_set;
-    std::unordered_multimap<size_t, size_t> v2f;
-    for (size_t i=0; i<num_adj_faces; i++) 
-    {
-      const size_t fid = adj_faces[i];
-      const size_t cid = adj_face_corners[i];
-      const auto& f = F.row(adj_faces[i]);
-      const size_t next = f[(cid+1)%3];
-      const size_t prev = f[(cid+2)%3];
-      adj_vertices_set.insert(next);
-      adj_vertices_set.insert(prev);
-      v2f.insert({{next, fid}, {prev, fid}});
-    }
-    const size_t num_adj_vertices = adj_vertices_set.size();
-    std::vector<size_t> adj_vertices(num_adj_vertices);
-    std::copy(adj_vertices_set.begin(), adj_vertices_set.end(),
-        adj_vertices.begin());
-
-    std::vector<Point_3> adj_points;
-    for (size_t vid : adj_vertices) 
-    {
-      adj_points.emplace_back(V(vid,0), V(vid,1), V(vid,2));
-    }
-
-    // A plane is on the exterior if all adj_points lies on or to
-    // one side of the plane.
-    auto is_on_exterior = [&](const Plane_3& separator) -> bool{
-      size_t positive=0;
-      size_t negative=0;
-      size_t coplanar=0;
-      for (const auto& point : adj_points) {
-        switch(separator.oriented_side(point)) {
-          case CGAL::ON_POSITIVE_SIDE:
-            positive++;
-            break;
-          case CGAL::ON_NEGATIVE_SIDE:
-            negative++;
-            break;
-          case CGAL::ON_ORIENTED_BOUNDARY:
-            coplanar++;
-            break;
-          default:
-            throw "Unknown plane-point orientation";
-        }
-      }
-      auto query_orientation = separator.oriented_side(query_point);
-      if (query_orientation == CGAL::ON_ORIENTED_BOUNDARY &&
-          (positive == 0 && negative == 0)) {
-        // All adj vertices and query point are coplanar.
-        // In this case, all separators are equally valid.
-        return true;
-      } else {
-        bool r = (positive == 0 && query_orientation == CGAL::POSITIVE)
-          || (negative == 0 && query_orientation == CGAL::NEGATIVE);
-        return r;
-      }
-    };
-
-    size_t d = std::numeric_limits<size_t>::max();
-    for (size_t i=0; i<num_adj_vertices; i++) {
-      const size_t vi = adj_vertices[i];
-      for (size_t j=i+1; j<num_adj_vertices; j++) {
-        Plane_3 separator(closest_point, adj_points[i], adj_points[j]);
-        if (separator.is_degenerate()) {
-          continue;
-        }
-        if (is_on_exterior(separator)) {
-          if (!CGAL::collinear(
-                query_point, adj_points[i], closest_point)) {
-            d = vi;
-            break;
-          } else {
-            d = adj_vertices[j];
-            assert(!CGAL::collinear(
-                  query_point, adj_points[j], closest_point));
-            break;
-          }
-        }
-      }
-    }
-    if (d == std::numeric_limits<size_t>::max()) {
-      Eigen::MatrixXd tmp_vertices(V.rows(), V.cols());
-      for (size_t i=0; i<V.rows(); i++) {
-        for (size_t j=0; j<V.cols(); j++) {
-          tmp_vertices(i,j) = CGAL::to_double(V(i,j));
-        }
-      }
-      Eigen::MatrixXi tmp_faces(adj_faces.size(), 3);
-      for (size_t i=0; i<adj_faces.size(); i++) {
-        tmp_faces.row(i) = F.row(adj_faces[i]);
-      }
-      //igl::writePLY("debug.ply", tmp_vertices, tmp_faces, false);
-      throw std::runtime_error("Invalid vertex neighborhood");
-    }
-    const auto itr = v2f.equal_range(d);
-    assert(itr.first != itr.second);
-
-    return process_edge_case(query_idx, s, d, itr.first->second, orientation);
-  };
-
-  const size_t num_queries = P.rows();
-  R.resize(num_queries, 1);
-  S.resize(num_queries, 1);
-  for (size_t i=0; i<num_queries; i++) {
-    const Point_3 query(P(i,0), P(i,1), P(i,2));
-    auto projection = tree.closest_point_and_primitive(query);
-    const Point_3 closest_point = projection.first;
-    size_t fid = projection.second - triangles.begin();
-    bool fid_ori = false;
-
-    // Gether all facets sharing the closest point.
-    typename std::vector<typename Tree::Primitive_id> intersected_faces;
-    tree.all_intersected_primitives(Segment_3(closest_point, query),
-        std::back_inserter(intersected_faces));
-    const size_t num_intersected_faces = intersected_faces.size();
-    std::vector<size_t> intersected_face_indices(num_intersected_faces);
-    std::transform(intersected_faces.begin(),
-        intersected_faces.end(),
-        intersected_face_indices.begin(),
-        [&](const typename Tree::Primitive_id& itr) -> size_t
-        { return I(itr-triangles.begin(), 0); });
-
-    size_t element_index;
-    auto element_type = determine_element_type(closest_point, fid,
-        element_index);
-    switch(element_type) {
-      case VERTEX:
-        {
-          const auto& f = F.row(I(fid, 0));
-          const size_t s = f[element_index];
-          fid = process_vertex_case(i, s, I(fid, 0), fid_ori);
-        }
-        break;
-      case EDGE:
-        {
-          const auto& f = F.row(I(fid, 0));
-          const size_t s = f[(element_index+1)%3];
-          const size_t d = f[(element_index+2)%3];
-          fid = process_edge_case(i, s, d, I(fid, 0), fid_ori);
-        }
-        break;
-      case FACE:
-        {
-          fid = process_face_case(i, closest_point, fid, fid_ori);
-        }
-        break;
-      default:
-        throw std::runtime_error("Unknown element type.");
-    }
-
-
-    R(i,0) = fid;
-    S(i,0) = fid_ori;
-  }
-}
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedI,
-  typename DerivedP,
-  typename DerivedEMAP,
-  typename DeriveduEC,
-  typename DeriveduEE,
-  typename DerivedR,
-  typename DerivedS >
-IGL_INLINE void igl::copyleft::cgal::closest_facet(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    const Eigen::PlainObjectBase<DerivedI>& I,
-    const Eigen::PlainObjectBase<DerivedP>& P,
-    const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
-    const Eigen::PlainObjectBase<DeriveduEC>& uEC,
-    const Eigen::PlainObjectBase<DeriveduEE>& uEE,
-    Eigen::PlainObjectBase<DerivedR>& R,
-    Eigen::PlainObjectBase<DerivedS>& S)
-{
-
-  typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
-  typedef Kernel::Point_3 Point_3;
-  typedef Kernel::Plane_3 Plane_3;
-  typedef Kernel::Segment_3 Segment_3;
-  typedef Kernel::Triangle_3 Triangle;
-  typedef std::vector<Triangle>::iterator Iterator;
-  typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
-  typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
-  typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
-
-  if (F.rows() <= 0 || I.rows() <= 0) {
-    throw std::runtime_error(
-        "Closest facet cannot be computed on empty mesh.");
-  }
-
-  std::vector<std::vector<size_t> > VF, VFi;
-  igl::vertex_triangle_adjacency(V.rows(), F, VF, VFi);
-  std::vector<bool> in_I;
-  std::vector<Triangle> triangles;
-  Tree tree;
-  submesh_aabb_tree(V,F,I,tree,triangles,in_I);
-
-  return closest_facet(
-    V,F,I,P,EMAP,uEC,uEE,VF,VFi,tree,triangles,in_I,R,S);
-}
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedP,
-  typename DerivedEMAP,
-  typename DeriveduEC,
-  typename DeriveduEE,
-  typename DerivedR,
-  typename DerivedS >
-IGL_INLINE void igl::copyleft::cgal::closest_facet(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    const Eigen::PlainObjectBase<DerivedP>& P,
-    const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
-    const Eigen::PlainObjectBase<DeriveduEC>& uEC,
-    const Eigen::PlainObjectBase<DeriveduEE>& uEE,
-    Eigen::PlainObjectBase<DerivedR>& R,
-    Eigen::PlainObjectBase<DerivedS>& S) {
-  const size_t num_faces = F.rows();
-  Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi>(num_faces, 0, num_faces-1);
-  igl::copyleft::cgal::closest_facet(V, F, I, P, EMAP, uEC, uEE, R, S);
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -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>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#include <cstdint>
-template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Epeck::FT, -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>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 153
include/igl/copyleft/cgal/complex_to_mesh.cpp

@@ -1,153 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2014 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "complex_to_mesh.h"
-
-#include "../../centroid.h"
-#include "../../remove_unreferenced.h"
-
-#include <CGAL/Surface_mesh_default_triangulation_3.h>
-#include <CGAL/Delaunay_triangulation_cell_base_with_circumcenter_3.h>
-#include <set>
-#include <stack>
-
-template <typename Tr, typename DerivedV, typename DerivedF>
-IGL_INLINE bool igl::copyleft::cgal::complex_to_mesh(
-  const CGAL::Complex_2_in_triangulation_3<Tr> & c2t3,
-  Eigen::PlainObjectBase<DerivedV> & V, 
-  Eigen::PlainObjectBase<DerivedF> & F)
-{
-  using namespace Eigen;
-  // CGAL/IO/Complex_2_in_triangulation_3_file_writer.h
-  using CGAL::Surface_mesher::number_of_facets_on_surface;
-
-  typedef typename CGAL::Complex_2_in_triangulation_3<Tr> C2t3;
-  typedef typename Tr::Finite_facets_iterator Finite_facets_iterator;
-  typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
-  typedef typename Tr::Facet Facet;
-  typedef typename Tr::Edge Edge;
-  typedef typename Tr::Vertex_handle Vertex_handle;
-
-  // Header.
-  const Tr& tr = c2t3.triangulation();
-
-  bool success = true;
-
-  const int n = tr.number_of_vertices();
-  const int m = c2t3.number_of_facets();
-
-  assert(m == number_of_facets_on_surface(tr));
-  
-  // Finite vertices coordinates.
-  std::map<Vertex_handle, int> v2i;
-  V.resize(n,3);
-  {
-    int v = 0;
-    for(Finite_vertices_iterator vit = tr.finite_vertices_begin();
-        vit != tr.finite_vertices_end();
-        ++vit)
-    {
-      V(v,0) = vit->point().x(); 
-      V(v,1) = vit->point().y(); 
-      V(v,2) = vit->point().z(); 
-      v2i[vit] = v++;
-    }
-  }
-
-  {
-    Finite_facets_iterator fit = tr.finite_facets_begin();
-    std::set<Facet> oriented_set;
-    std::stack<Facet> stack;
-
-    while ((int)oriented_set.size() != m) 
-    {
-      while ( fit->first->is_facet_on_surface(fit->second) == false ||
-        oriented_set.find(*fit) != oriented_set.end() ||
-        oriented_set.find(c2t3.opposite_facet(*fit)) !=
-        oriented_set.end() ) 
-      {
-        ++fit;
-      }
-      oriented_set.insert(*fit);
-      stack.push(*fit);
-      while(! stack.empty() )
-      {
-        Facet f = stack.top();
-        stack.pop();
-        for(int ih = 0 ; ih < 3 ; ++ih)
-        {
-          const int i1  = tr.vertex_triple_index(f.second, tr. cw(ih));
-          const int i2  = tr.vertex_triple_index(f.second, tr.ccw(ih));
-
-          const typename C2t3::Face_status face_status
-            = c2t3.face_status(Edge(f.first, i1, i2));
-          if(face_status == C2t3::REGULAR) 
-          {
-            Facet fn = c2t3.neighbor(f, ih);
-            if (oriented_set.find(fn) == oriented_set.end())
-            {
-              if(oriented_set.find(c2t3.opposite_facet(fn)) == oriented_set.end())
-              {
-                oriented_set.insert(fn);
-                stack.push(fn);
-              }else {
-                success = false; // non-orientable
-              }
-            }
-          }else if(face_status != C2t3::BOUNDARY)
-          {
-            success = false; // non manifold, thus non-orientable
-          }
-        } // end "for each neighbor of f"
-      } // end "stack non empty"
-    } // end "oriented_set not full"
-
-    F.resize(m,3);
-    int f = 0;
-    for(typename std::set<Facet>::const_iterator fit = 
-        oriented_set.begin();
-        fit != oriented_set.end();
-        ++fit)
-    {
-      const typename Tr::Cell_handle cell = fit->first;
-      const int& index = fit->second;
-      const int index1 = v2i[cell->vertex(tr.vertex_triple_index(index, 0))];
-      const int index2 = v2i[cell->vertex(tr.vertex_triple_index(index, 1))];
-      const int index3 = v2i[cell->vertex(tr.vertex_triple_index(index, 2))];
-      // This order is flipped
-      F(f,0) = index1;
-      F(f,1) = index2;
-      F(f,2) = index3;
-      f++;
-    }
-    assert(f == m);
-  } // end if(facets must be oriented)
-
-  // This CGAL code seems to randomly assign the global orientation
-  // Flip based on the signed volume.
-  Eigen::Vector3d cen;
-  double vol;
-  igl::centroid(V,F,cen,vol);
-  if(vol < 0)
-  {
-    // Flip
-    F = F.rowwise().reverse().eval();
-  }
-
-  // CGAL code somehow can end up with unreferenced vertices
-  {
-    VectorXi _1;
-    remove_unreferenced( MatrixXd(V), MatrixXi(F), V,F,_1);
-  }
-
-  return success;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::copyleft::cgal::complex_to_mesh<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > >, CGAL::Sequential_tag>, CGAL::Default, CGAL::Default>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Complex_2_in_triangulation_3<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > >, CGAL::Sequential_tag>, CGAL::Default, CGAL::Default>, void> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 67
include/igl/copyleft/cgal/component_inside_component.cpp

@@ -1,67 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Qingnan Zhou <[email protected]>
-// 
-// 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/.
-#include "component_inside_component.h"
-
-#include "order_facets_around_edge.h"
-#include "../../LinSpaced.h"
-#include "points_inside_component.h"
-
-#include <CGAL/AABB_tree.h>
-#include <CGAL/AABB_traits.h>
-#include <CGAL/AABB_triangle_primitive.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-#include <cassert>
-#include <list>
-#include <limits>
-#include <vector>
-
-template <typename DerivedV, typename DerivedF, typename DerivedI>
-IGL_INLINE bool igl::copyleft::cgal::component_inside_component(
-        const Eigen::PlainObjectBase<DerivedV>& V1,
-        const Eigen::PlainObjectBase<DerivedF>& F1,
-        const Eigen::PlainObjectBase<DerivedI>& I1,
-        const Eigen::PlainObjectBase<DerivedV>& V2,
-        const Eigen::PlainObjectBase<DerivedF>& F2,
-        const Eigen::PlainObjectBase<DerivedI>& I2) {
-    if (F1.rows() <= 0 || I1.rows() <= 0 || F2.rows() <= 0 || I2.rows() <= 0) {
-        throw "Component inside test cannot be done on empty component!";
-    }
-
-    const Eigen::Vector3i& f = F1.row(I1(0, 0));
-    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> query(
-            (V1(f[0],0) + V1(f[1],0) + V1(f[2],0))/3.0,
-            (V1(f[0],1) + V1(f[1],1) + V1(f[2],1))/3.0,
-            (V1(f[0],2) + V1(f[1],2) + V1(f[2],2))/3.0);
-    Eigen::VectorXi inside;
-    igl::copyleft::cgal::points_inside_component(V2, F2, I2, query, inside);
-    assert(inside.size() == 1);
-    return inside[0];
-}
-
-template<typename DerivedV, typename DerivedF>
-IGL_INLINE bool igl::copyleft::cgal::component_inside_component(
-        const Eigen::PlainObjectBase<DerivedV>& V1,
-        const Eigen::PlainObjectBase<DerivedF>& F1,
-        const Eigen::PlainObjectBase<DerivedV>& V2,
-        const Eigen::PlainObjectBase<DerivedF>& F2) {
-    if (F1.rows() <= 0 || F2.rows() <= 0) {
-        throw "Component inside test cannot be done on empty component!";
-    }
-    Eigen::VectorXi I1(F1.rows()), I2(F2.rows());
-    I1 = igl::LinSpaced<Eigen::VectorXi>(F1.rows(), 0, F1.rows()-1);
-    I2 = igl::LinSpaced<Eigen::VectorXi>(F2.rows(), 0, F2.rows()-1);
-    return igl::copyleft::cgal::component_inside_component(V1, F1, I1, V2, F2, I2);
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::copyleft::cgal::component_inside_component<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::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> > const&);
-template bool igl::copyleft::cgal::component_inside_component<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&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> > const&);
-#endif

+ 0 - 103
include/igl/copyleft/cgal/convex_hull.cpp

@@ -1,103 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2017 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "convex_hull.h"
-#include "../../ismember_rows.h"
-#include "polyhedron_to_mesh.h"
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-#include <CGAL/Polyhedron_3.h>
-#include <CGAL/Surface_mesh.h>
-#include <CGAL/convex_hull_3.h>
-#include <vector>
-
-template <
-  typename DerivedV,
-  typename DerivedW,
-  typename DerivedG>
-IGL_INLINE void igl::copyleft::cgal::convex_hull(
-  const Eigen::MatrixBase<DerivedV> & V,
-  Eigen::PlainObjectBase<DerivedW> & W,
-  Eigen::PlainObjectBase<DerivedG> & G)
-{
-  typedef CGAL::Exact_predicates_inexact_constructions_kernel      K;
-  switch(V.cols())
-  {
-    case 3:
-    {
-      typedef K::Point_3                                              Point_3;
-      //typedef CGAL::Delaunay_triangulation_3<K>                       Delaunay;
-      //typedef Delaunay::Vertex_handle                                 Vertex_handle;
-      //typedef CGAL::Surface_mesh<Point_3>                             Surface_mesh;
-      typedef CGAL::Polyhedron_3<K>                             Polyhedron_3;
-      std::vector<Point_3> points(V.rows());
-      for(int i = 0;i<V.rows();i++)
-      {
-        points[i] = Point_3(V(i,0),V(i,1),V(i,2));
-      }
-      Polyhedron_3 poly;
-      CGAL::convex_hull_3(points.begin(),points.end(),poly);
-      assert(poly.is_pure_triangle() && "Assuming CGAL outputs a triangle mesh");
-      polyhedron_to_mesh(poly,W,G);
-      break;
-    }
-    case 2:
-    {
-      typedef K::Point_2 Point_2;
-      std::vector<Point_2> points(V.rows());
-      std::vector<Point_2> result;
-      for(int i = 0;i<V.rows();i++)
-      {
-        points[i] = Point_2(V(i,0),V(i,1));
-      }
-      CGAL::convex_hull_2(points.begin(),points.end(),std::back_inserter(result));
-      W.resize(result.size(),2);
-      G.resize(result.size(),2);
-      for(int i = 0;i<result.size();i++)
-      {
-        W(i,0) = result[i].x();
-        W(i,1) = result[i].y();
-        G(i,0) = i;
-        G(i,1) = (i+1)%result.size();
-      }
-      break;
-    }
-  }
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF>
-IGL_INLINE void igl::copyleft::cgal::convex_hull(
-  const Eigen::MatrixBase<DerivedV> & V,
-  Eigen::PlainObjectBase<DerivedF> & F)
-{
-  Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> W;
-  Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> G;
-  convex_hull(V,W,G);
-  // This is a lazy way to reindex into the original mesh
-  Eigen::Matrix<bool,Eigen::Dynamic,1> I;
-  Eigen::VectorXi J;
-  igl::ismember_rows(W,V,I,J);
-  assert(I.all() && "Should find all W in V");
-  F.resizeLike(G);
-  for(int f = 0;f<G.rows();f++)
-  {
-    for(int c = 0;c<3;c++)
-    {
-      F(f,c) = J(G(f,c));
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 48
include/igl/copyleft/cgal/coplanar.cpp

@@ -1,48 +0,0 @@
-#include "coplanar.h"
-#include "row_to_point.h"
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-#include <CGAL/Point_3.h>
-
-template <typename DerivedV>
-IGL_INLINE bool igl::copyleft::cgal::coplanar(
-  const Eigen::MatrixBase<DerivedV> & V)
-{
-  // 3 points in 3D are always coplanar
-  if(V.rows() < 4){ return true; }
-  // spanning points found so far
-  std::vector<CGAL::Point_3<CGAL::Epick> > p;
-  for(int i = 0;i<V.rows();i++)
-  {
-    const CGAL::Point_3<CGAL::Epick> pi(V(i,0), V(i,1), V(i,2));
-    switch(p.size())
-    {
-      case 0:
-        p.push_back(pi);
-        break;
-      case 1:
-        if(p[0] != pi)
-        {
-          p.push_back(pi);
-        }
-        break;
-      case 2:
-        if(!CGAL::collinear(p[0],p[1],pi))
-        {
-          p.push_back(pi);
-        }
-        break;
-      case 3:
-        if(!CGAL::coplanar(p[0],p[1],p[2],pi))
-        {
-          return false;
-        }
-        break;
-    }
-  }
-  return true;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::copyleft::cgal::coplanar<Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&);
-#endif

+ 0 - 67
include/igl/copyleft/cgal/delaunay_triangulation.cpp

@@ -1,67 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2018 Alec Jacobson
-// Copyright (C) 2016 Qingnan Zhou <[email protected]>
-//
-// 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/.
-
-#include "delaunay_triangulation.h"
-#include "../../delaunay_triangulation.h"
-#include "orient2D.h"
-#include "incircle.h"
-
-template<
-  typename DerivedV,
-  typename DerivedF>
-IGL_INLINE void igl::copyleft::cgal::delaunay_triangulation(
-    const Eigen::MatrixBase<DerivedV>& V,
-    Eigen::PlainObjectBase<DerivedF>& F)
-{
-  typedef typename DerivedV::Scalar Scalar;
-  igl::delaunay_triangulation(V, orient2D<Scalar>, incircle<Scalar>, F);
-  // This function really exists to test our igl::delaunay_triangulation
-  // 
-  // It's currently much faster to call cgal's native Delaunay routine
-  //
-//#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-//#include <CGAL/Delaunay_triangulation_2.h>
-//#include <CGAL/Triangulation_vertex_base_with_info_2.h>
-//#include <vector>
-//  const auto delaunay = 
-//    [&](const Eigen::MatrixXd & V,Eigen::MatrixXi & F)
-//  {
-//    typedef CGAL::Exact_predicates_inexact_constructions_kernel            Kernel;
-//    typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Kernel> Vb;
-//    typedef CGAL::Triangulation_data_structure_2<Vb>                       Tds;
-//    typedef CGAL::Delaunay_triangulation_2<Kernel, Tds>                    Delaunay;
-//    typedef Kernel::Point_2                                                Point;
-//    std::vector< std::pair<Point,unsigned> > points(V.rows());
-//    for(int i = 0;i<V.rows();i++)
-//    {
-//      points[i] = std::make_pair(Point(V(i,0),V(i,1)),i);
-//    }
-//    Delaunay triangulation;
-//    triangulation.insert(points.begin(),points.end());
-//    F.resize(triangulation.number_of_faces(),3);
-//    {
-//      int j = 0;
-//      for(Delaunay::Finite_faces_iterator fit = triangulation.finite_faces_begin();
-//          fit != triangulation.finite_faces_end(); ++fit) 
-//      {
-//        Delaunay::Face_handle face = fit;
-//        F(j,0) = face->vertex(0)->info();
-//        F(j,1) = face->vertex(1)->info();
-//        F(j,2) = face->vertex(2)->info();
-//        j++;
-//      }
-//    }
-//  };
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::delaunay_triangulation<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 397
include/igl/copyleft/cgal/extract_cells.cpp

@@ -1,397 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Qingnan Zhou <[email protected]>
-// 
-// 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/.
-//
-#include "extract_cells.h"
-#include "extract_cells_single_component.h"
-#include "closest_facet.h"
-#include "outer_facet.h"
-#include "submesh_aabb_tree.h"
-#include "../../extract_manifold_patches.h"
-#include "../../facet_components.h"
-#include "../../parallel_for.h"
-#include "../../get_seconds.h"
-#include "../../triangle_triangle_adjacency.h"
-#include "../../unique_edge_map.h"
-#include "../../C_STR.h"
-#include "../../vertex_triangle_adjacency.h"
-
-#include <CGAL/AABB_tree.h>
-#include <CGAL/AABB_traits.h>
-#include <CGAL/AABB_triangle_primitive.h>
-#include <CGAL/intersections.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-#include <iostream>
-#include <vector>
-#include <queue>
-#include <map>
-#include <set>
-
-//#define EXTRACT_CELLS_TIMING
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedC >
-IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
-  const Eigen::PlainObjectBase<DerivedV>& V,
-  const Eigen::PlainObjectBase<DerivedF>& F,
-  Eigen::PlainObjectBase<DerivedC>& cells)
-{
-  const size_t num_faces = F.rows();
-  // Construct edge adjacency
-  Eigen::MatrixXi E, uE;
-  Eigen::VectorXi EMAP;
-  Eigen::VectorXi uEC,uEE;
-  igl::unique_edge_map(F, E, uE, EMAP, uEC, uEE);
-  // Cluster into manifold patches
-  Eigen::VectorXi P;
-  igl::extract_manifold_patches(F, EMAP, uEC, uEE, P);
-  // Extract cells
-  DerivedC per_patch_cells;
-  const size_t ncells = extract_cells(V,F,P,E,uE,EMAP,uEC,uEE,per_patch_cells);
-  // Distribute per-patch cell information to each face
-  cells.resize(num_faces, 2);
-  for (size_t i=0; i<num_faces; i++)
-  {
-    cells.row(i) = per_patch_cells.row(P[i]);
-  }
-  return ncells;
-}
-
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedP,
-  typename DerivedE,
-  typename DeriveduE,
-  typename DerivedEMAP,
-  typename DeriveduEC,
-  typename DeriveduEE,
-  typename DerivedC >
-IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
-  const Eigen::PlainObjectBase<DerivedV>& V,
-  const Eigen::PlainObjectBase<DerivedF>& F,
-  const Eigen::PlainObjectBase<DerivedP>& P,
-  const Eigen::PlainObjectBase<DerivedE>& E,
-  const Eigen::PlainObjectBase<DeriveduE>& uE,
-  const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
-  const Eigen::PlainObjectBase<DeriveduEC>& uEC,
-  const Eigen::PlainObjectBase<DeriveduEE>& uEE,
-  Eigen::PlainObjectBase<DerivedC>& cells)
-{
-  // Trivial base case
-  if(P.size() == 0)
-  {
-    assert(F.size() == 0);
-    cells.resize(0,2);
-    return 0;
-  }
-
-  typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
-  typedef Kernel::Point_3 Point_3;
-  typedef Kernel::Plane_3 Plane_3;
-  typedef Kernel::Segment_3 Segment_3;
-  typedef Kernel::Triangle_3 Triangle;
-  typedef std::vector<Triangle>::iterator Iterator;
-  typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
-  typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
-  typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
-
-#ifdef EXTRACT_CELLS_TIMING
-  const auto & tictoc = []() -> double
-  {
-    static double t_start = igl::get_seconds();
-    double diff = igl::get_seconds()-t_start;
-    t_start += diff;
-    return diff;
-  };
-  const auto log_time = [&](const std::string& label) -> void {
-    printf("%50s: %0.5lf\n",
-      C_STR("extract_cells." << label),tictoc());
-  };
-  tictoc();
-#else
-  // no-op
-  const auto log_time = [](const std::string){};
-#endif
-  const size_t num_faces = F.rows();
-  typedef typename DerivedF::Scalar Index;
-  assert(P.size() > 0);
-  const size_t num_patches = P.maxCoeff()+1;
-
-  // Extract all cells...
-  DerivedC raw_cells;
-  const size_t num_raw_cells =
-    extract_cells_single_component(V,F,P,uE,EMAP,uEC,uEE,raw_cells);
-  log_time("extract_cells_single_component");
-
-  // Compute triangle-triangle adjacency data-structure
-  std::vector<std::vector<std::vector<Index > > > TT,_1;
-  igl::triangle_triangle_adjacency(EMAP, uEC, uEE, false, TT, _1);
-  log_time("compute_face_adjacency");
-
-  // Compute connected components of the mesh
-  Eigen::VectorXi C, counts;
-  igl::facet_components(TT, C, counts);
-  log_time("form_components");
-
-  const size_t num_components = counts.size();
-  // components[c] --> list of face indices into F of faces in component c
-  std::vector<std::vector<size_t> > components(num_components);
-  // Loop over all faces
-  for (size_t i=0; i<num_faces; i++)
-  {
-    components[C[i]].push_back(i);
-  }
-  // Convert vector lists to Eigen lists...
-  // and precompute data-structures for each component
-  std::vector<std::vector<size_t> > VF,VFi;
-  igl::vertex_triangle_adjacency(V.rows(), F, VF, VFi);
-  std::vector<Eigen::VectorXi> Is(num_components);
-  std::vector<
-    CGAL::AABB_tree<
-      CGAL::AABB_traits<
-        Kernel,
-        CGAL::AABB_triangle_primitive<
-          Kernel, std::vector<
-            Kernel::Triangle_3 >::iterator > > > > trees(num_components);
-  std::vector< std::vector<Kernel::Triangle_3 > >
-    triangle_lists(num_components);
-  // O(num_components * num_faces) 
-  // In general, extract_cells appears to have O(num_components * num_faces)
-  // performance. This could be painfully tested by a processing a cloud of
-  // tetrahedra.
-  std::vector<std::vector<bool> > in_Is(num_components);
-
-  // Find outer facets, their orientations and cells for each component
-  Eigen::VectorXi outer_facets(num_components);
-  Eigen::VectorXi outer_facet_orientation(num_components);
-  Eigen::VectorXi outer_cells(num_components);
-  igl::parallel_for(num_components,[&](size_t i)
-  {
-    Is[i].resize(components[i].size());
-    std::copy(components[i].begin(), components[i].end(),Is[i].data());
-    bool flipped;
-    igl::copyleft::cgal::outer_facet(V, F, Is[i], outer_facets[i], flipped);
-    outer_facet_orientation[i] = flipped?1:0;
-    outer_cells[i] = raw_cells(P[outer_facets[i]], outer_facet_orientation[i]);
-  },1000);
-#ifdef EXTRACT_CELLS_TIMING
-  log_time("outer_facet_per_component");
-#endif
-
-  // Compute barycenter of a triangle in mesh (V,F)
-  //
-  // Inputs:
-  //   fid  index into F
-  // Returns row-vector of barycenter coordinates
-  const auto get_triangle_center = [&V,&F](const size_t fid)
-  {
-    return ((V.row(F(fid,0))+V.row(F(fid,1))+V.row(F(fid,2)))/3.0).eval();
-  };
-  std::vector<std::vector<size_t> > nested_cells(num_raw_cells);
-  std::vector<std::vector<size_t> > ambient_cells(num_raw_cells);
-  std::vector<std::vector<size_t> > ambient_comps(num_components);
-  // Only bother if there's more than one component
-  if(num_components > 1)
-  {
-    // construct bounding boxes for each component
-    DerivedV bbox_min(num_components, 3);
-    DerivedV bbox_max(num_components, 3);
-    // Assuming our mesh (in exact numbers) fits in the range of double.
-    bbox_min.setConstant(std::numeric_limits<double>::max());
-    bbox_max.setConstant(std::numeric_limits<double>::lowest());
-    // Loop over faces
-    for (size_t i=0; i<num_faces; i++)
-    {
-      // component of this face
-      const auto comp_id = C[i];
-      const auto& f = F.row(i);
-      for (size_t j=0; j<3; j++)
-      {
-        for(size_t d=0;d<3;d++)
-        {
-          bbox_min(comp_id,d) = std::min(bbox_min(comp_id,d), V(f[j],d));
-          bbox_max(comp_id,d) = std::max(bbox_max(comp_id,d), V(f[j],d));
-        }
-      }
-    }
-    // Return true if box of component ci intersects that of cj
-    const auto bbox_intersects = [&bbox_max,&bbox_min](size_t ci, size_t cj)
-    {
-      return !(
-        bbox_max(ci,0) < bbox_min(cj,0) ||
-        bbox_max(ci,1) < bbox_min(cj,1) ||
-        bbox_max(ci,2) < bbox_min(cj,2) ||
-        bbox_max(cj,0) < bbox_min(ci,0) ||
-        bbox_max(cj,1) < bbox_min(ci,1) ||
-        bbox_max(cj,2) < bbox_min(ci,2));
-    };
-
-    // Loop over components. This section is O(m²)
-    for (size_t i=0; i<num_components; i++)
-    {
-      // List of components that could overlap with component i
-      std::vector<size_t> candidate_comps;
-      candidate_comps.reserve(num_components);
-      // Loop over components
-      for (size_t j=0; j<num_components; j++)
-      {
-        if (i == j) continue;
-        if (bbox_intersects(i,j)) candidate_comps.push_back(j);
-      }
-
-      const size_t num_candidate_comps = candidate_comps.size();
-      if (num_candidate_comps == 0) continue;
-
-      // Build aabb tree for this component.
-      submesh_aabb_tree(V,F,Is[i],trees[i],triangle_lists[i],in_Is[i]);
-
-      // Get query points on each candidate component: barycenter of
-      // outer-facet
-      DerivedV queries(num_candidate_comps, 3);
-      for (size_t j=0; j<num_candidate_comps; j++)
-      {
-        const size_t index = candidate_comps[j];
-        queries.row(j) = get_triangle_center(outer_facets[index]);
-      }
-
-      // Gather closest facets in ith component to each query point and their
-      // orientations
-      const auto& I = Is[i];
-      const auto& tree = trees[i];
-      const auto& in_I = in_Is[i];
-      const auto& triangles = triangle_lists[i];
-
-      Eigen::VectorXi closest_facets, closest_facet_orientations;
-      closest_facet(
-        V,
-        F,
-        I,
-        queries,
-        EMAP,
-        uEC,
-        uEE,
-        VF,
-        VFi,
-        tree,
-        triangles,
-        in_I,
-        closest_facets,
-        closest_facet_orientations);
-      // Loop over all candidates
-      for (size_t j=0; j<num_candidate_comps; j++)
-      {
-        const size_t index = candidate_comps[j];
-        const size_t closest_patch = P[closest_facets[j]];
-        const size_t closest_patch_side = closest_facet_orientations[j] ? 0:1;
-        // The cell id of the closest patch
-        const size_t ambient_cell =
-          raw_cells(closest_patch,closest_patch_side);
-        if (ambient_cell != (size_t)outer_cells[i])
-        {
-          // ---> component index inside component i, because the cell of the
-          // closest facet on i to component index is **not** the same as the
-          // "outer cell" of component i: component index is **not** outside of
-          // component i (therefore it's inside).
-          nested_cells[ambient_cell].push_back(outer_cells[index]);
-          ambient_cells[outer_cells[index]].push_back(ambient_cell);
-          ambient_comps[index].push_back(i);
-        }
-      }
-    }
-  }
-
-#ifdef EXTRACT_CELLS_TIMING
-    log_time("nested_relationship");
-#endif
-
-    const size_t INVALID = std::numeric_limits<size_t>::max();
-    const size_t INFINITE_CELL = num_raw_cells;
-    std::vector<size_t> embedded_cells(num_raw_cells, INVALID);
-    for (size_t i=0; i<num_components; i++) {
-        const size_t outer_cell = outer_cells[i];
-        const auto& ambient_comps_i = ambient_comps[i];
-        const auto& ambient_cells_i = ambient_cells[outer_cell];
-        const size_t num_ambient_comps = ambient_comps_i.size();
-        assert(num_ambient_comps == ambient_cells_i.size());
-        if (num_ambient_comps > 0) {
-            size_t embedded_comp = INVALID;
-            size_t embedded_cell = INVALID;
-            for (size_t j=0; j<num_ambient_comps; j++) {
-                if (ambient_comps[ambient_comps_i[j]].size() ==
-                        num_ambient_comps-1) {
-                    embedded_comp = ambient_comps_i[j];
-                    embedded_cell = ambient_cells_i[j];
-                    break;
-                }
-            }
-            assert(embedded_comp != INVALID);
-            assert(embedded_cell != INVALID);
-            embedded_cells[outer_cell] = embedded_cell;
-        } else {
-            embedded_cells[outer_cell] = INFINITE_CELL;
-        }
-    }
-    for (size_t i=0; i<num_patches; i++) {
-        if (embedded_cells[raw_cells(i,0)] != INVALID) {
-            raw_cells(i,0) = embedded_cells[raw_cells(i, 0)];
-        }
-        if (embedded_cells[raw_cells(i,1)] != INVALID) {
-            raw_cells(i,1) = embedded_cells[raw_cells(i, 1)];
-        }
-    }
-
-    size_t count = 0;
-    std::vector<size_t> mapped_indices(num_raw_cells+1, INVALID);
-    // Always map infinite cell to index 0.
-    mapped_indices[INFINITE_CELL] = count;
-    count++;
-
-    for (size_t i=0; i<num_patches; i++) {
-        const size_t old_positive_cell_id = raw_cells(i, 0);
-        const size_t old_negative_cell_id = raw_cells(i, 1);
-        size_t positive_cell_id, negative_cell_id;
-        if (mapped_indices[old_positive_cell_id] == INVALID) {
-            mapped_indices[old_positive_cell_id] = count;
-            positive_cell_id = count;
-            count++;
-        } else {
-            positive_cell_id = mapped_indices[old_positive_cell_id];
-        }
-        if (mapped_indices[old_negative_cell_id] == INVALID) {
-            mapped_indices[old_negative_cell_id] = count;
-            negative_cell_id = count;
-            count++;
-        } else {
-            negative_cell_id = mapped_indices[old_negative_cell_id];
-        }
-        raw_cells(i, 0) = positive_cell_id;
-        raw_cells(i, 1) = negative_cell_id;
-    }
-    cells = raw_cells;
-#ifdef EXTRACT_CELLS_TIMING
-    log_time("finalize");
-#endif
-    return count;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template size_t igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -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::Matrix<int, -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::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template size_t igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Epeck::FT, -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<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-template size_t igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Epeck::FT, -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::Matrix<int, -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::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 233
include/igl/copyleft/cgal/extract_cells_single_component.cpp

@@ -1,233 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Qingnan Zhou <[email protected]>
-// 
-// 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/.
-//
-#include "extract_cells_single_component.h"
-#include "order_facets_around_edge.h"
-#include "../../C_STR.h"
-#include "../../get_seconds.h"
-#include <limits>
-#include <vector>
-#include <set>
-#include <map>
-#include <queue>
-
-//#define EXTRACT_CELLS_SINGLE_COMPONENT_TIMING
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedP,
-  typename DeriveduE,
-  typename DerivedEMAP,
-  typename DeriveduEC,
-  typename DeriveduEE,
-  typename DerivedC>
-IGL_INLINE size_t igl::copyleft::cgal::extract_cells_single_component(
-  const Eigen::PlainObjectBase<DerivedV>& V,
-  const Eigen::PlainObjectBase<DerivedF>& F,
-  const Eigen::PlainObjectBase<DerivedP>& P,
-  const Eigen::PlainObjectBase<DeriveduE>& uE,
-  const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
-  const Eigen::PlainObjectBase<DeriveduEC>& uEC,
-  const Eigen::PlainObjectBase<DeriveduEE>& uEE,
-  Eigen::PlainObjectBase<DerivedC>& cells)
-{
-#ifdef EXTRACT_CELLS_SINGLE_COMPONENT_TIMING
-  const auto & tictoc = []() -> double
-  {
-    static double t_start = igl::get_seconds();
-    double diff = igl::get_seconds()-t_start;
-    t_start += diff;
-    return diff;
-  };
-  const auto log_time = [&](const std::string& label) -> void {
-    printf("%50s: %0.5lf\n",
-      C_STR("extrac*_single_component." << label),tictoc());
-  };
-  tictoc();
-#else
-  // no-op
-  const auto log_time = [](const std::string){};
-#endif
-  const size_t num_faces = F.rows();
-  // Input:
-  //   index  index into #F*3 list of undirect edges
-  // Returns index into face
-  const auto e2f = [&num_faces](size_t index) { return index % num_faces; };
-  // Determine if a face (containing undirected edge {s,d} is consistently
-  // oriented with directed edge {s,d} (or otherwise it is with {d,s})
-  //
-  // Inputs:
-  //   fid  face index into F
-  //   s  source index of edge
-  //   d  destination index of edge
-  // Returns true if face F(fid,:) is consistent with {s,d}
-  const auto is_consistent =
-    [&F](const size_t fid, const size_t s, const size_t d) -> bool
-  {
-    if ((size_t)F(fid, 0) == s && (size_t)F(fid, 1) == d) return false;
-    if ((size_t)F(fid, 1) == s && (size_t)F(fid, 2) == d) return false;
-    if ((size_t)F(fid, 2) == s && (size_t)F(fid, 0) == d) return false;
-
-    if ((size_t)F(fid, 0) == d && (size_t)F(fid, 1) == s) return true;
-    if ((size_t)F(fid, 1) == d && (size_t)F(fid, 2) == s) return true;
-    if ((size_t)F(fid, 2) == d && (size_t)F(fid, 0) == s) return true;
-    throw "Invalid face!";
-    return false;
-  };
-
-  const size_t num_unique_edges = uE.rows();
-  const size_t num_patches = P.maxCoeff() + 1;
-
-  // Build patch-patch adjacency list.
-  //
-  // Does this really need to be a map? Or do I just want a list of neighbors
-  // and for each neighbor an index to a unique edge? (i.e., a sparse matrix)
-  std::vector<std::map<size_t, size_t> > patch_adj(num_patches);
-  for (size_t i=0; i<num_unique_edges; i++)
-  {
-    const size_t s = uE(i,0);
-    const size_t d = uE(i,1);
-    //const auto adj_faces = uE2E[i];
-    //const size_t num_adj_faces = adj_faces.size();
-    const size_t num_adj_faces = uEC(i+1)-uEC(i);
-    if (num_adj_faces > 2)
-    {
-      //for (size_t j=0; j<num_adj_faces; j++) {
-      //  const auto aj = adj_faces[j];
-      for (size_t ij=uEC(i); ij<uEC(i+1); ij++) 
-      {
-        const auto aj = uEE(ij);
-        const size_t patch_j = P[e2f(aj)];
-        //for (size_t k=j+1; k<num_adj_faces; k++) {
-        //  const auto ak = adj_faces[k];
-        for (size_t ik=ij+1; ik<uEC(i+1); ik++) 
-        {
-          const auto ak = uEE(ik);
-          const size_t patch_k = P[e2f(ak)];
-          if (patch_adj[patch_j].find(patch_k) == patch_adj[patch_j].end())
-          {
-            patch_adj[patch_j].insert({patch_k, i});
-          }
-          if (patch_adj[patch_k].find(patch_j) == patch_adj[patch_k].end())
-          {
-            patch_adj[patch_k].insert({patch_j, i});
-          }
-        }
-      }
-    }
-  }
-  log_time("patch-adjacency");
-
-
-  const int INVALID = std::numeric_limits<int>::max();
-  //std::vector<size_t> cell_labels(num_patches * 2);
-  //for (size_t i=0; i<num_patches; i++) cell_labels[i] = i;
-  std::vector<std::set<size_t> > equivalent_cells(num_patches*2);
-  std::vector<bool> processed(num_unique_edges, false);
-
-  size_t label_count=0;
-  size_t order_facets_around_edge_calls = 0;
-  // bottleneck appears to be `order_facets_around_edge`
-  for (size_t i=0; i<num_patches; i++) 
-  {
-    for (const auto& entry : patch_adj[i]) 
-    {
-      const size_t neighbor_patch = entry.first;
-      const size_t uei = entry.second;
-      if (processed[uei]) continue;
-      processed[uei] = true;
-
-      //const auto& adj_faces = uE2E[uei];
-      //const size_t num_adj_faces = adj_faces.size();
-      const size_t num_adj_faces = uEC(uei+1)-uEC(uei);
-      assert(num_adj_faces > 2);
-
-      const size_t s = uE(uei,0);
-      const size_t d = uE(uei,1);
-
-      std::vector<int> signed_adj_faces;
-      //for (auto ej : adj_faces)
-      for(size_t ij = uEC(uei);ij<uEC(uei+1);ij++)
-      {
-        const size_t ej = uEE(ij);
-        const size_t fid = e2f(ej);
-        bool cons = is_consistent(fid, s, d);
-        signed_adj_faces.push_back((fid+1)*(cons ? 1:-1));
-      }
-      {
-        // Sort adjacent faces cyclically around {s,d}
-        Eigen::VectorXi order;
-        // order[f] will reveal the order of face f in signed_adj_faces
-        order_facets_around_edge(V, F, s, d, signed_adj_faces, order);
-        order_facets_around_edge_calls++;
-        for (size_t j=0; j<num_adj_faces; j++) 
-        {
-          const size_t curr_idx = j;
-          const size_t next_idx = (j+1)%num_adj_faces;
-          //const size_t curr_patch_idx = P[e2f(adj_faces[order[curr_idx]])];
-          //const size_t next_patch_idx = P[e2f(adj_faces[order[next_idx]])];
-          const size_t curr_patch_idx = P[e2f( uEE(uEC(uei)+order[curr_idx]) )];
-          const size_t next_patch_idx = P[e2f( uEE(uEC(uei)+order[next_idx]) )];
-          const bool curr_cons = signed_adj_faces[order[curr_idx]] > 0;
-          const bool next_cons = signed_adj_faces[order[next_idx]] > 0;
-          const size_t curr_cell_idx = curr_patch_idx*2 + (curr_cons?0:1);
-          const size_t next_cell_idx = next_patch_idx*2 + (next_cons?1:0);
-          equivalent_cells[curr_cell_idx].insert(next_cell_idx);
-          equivalent_cells[next_cell_idx].insert(curr_cell_idx);
-        }
-      }
-    }
-  }
-#ifdef EXTRACT_CELLS_SINGLE_COMPONENT_TIMING
-  log_time("equivalent_cells");
-#endif 
-
-  size_t count=0;
-  cells.resize(num_patches, 2);
-  cells.setConstant(INVALID);
-  const auto extract_equivalent_cells = [&](size_t i) {
-    if (cells(i/2, i%2) != INVALID) return;
-    std::queue<size_t> Q;
-    Q.push(i);
-    cells(i/2, i%2) = count;
-    while (!Q.empty()) {
-      const size_t index = Q.front();
-      Q.pop();
-      for (const auto j : equivalent_cells[index]) {
-        if (cells(j/2, j%2) == INVALID) {
-          cells(j/2, j%2) = count;
-          Q.push(j);
-        }
-      }
-    }
-    count++;
-  };
-  for (size_t i=0; i<num_patches; i++) {
-    extract_equivalent_cells(i*2);
-    extract_equivalent_cells(i*2+1);
-  }
-  log_time("extract-equivalent_cells");
-
-  assert((cells.array() != INVALID).all());
-  return count;
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template size_t igl::copyleft::cgal::extract_cells_single_component<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -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::Matrix<int, -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<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
-#include <cstdint>
-template size_t igl::copyleft::cgal::extract_cells_single_component<Eigen::Matrix<CGAL::Epeck::FT, -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::Matrix<int, -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<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#ifdef WIN32
-template uint64_t igl::copyleft::cgal::extract_cells_single_component<Eigen::Matrix<CGAL::Epeck::FT, -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::Matrix<int, -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<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#endif
-#endif

+ 0 - 124
include/igl/copyleft/cgal/extract_feature.cpp

@@ -1,124 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Qingnan Zhou <[email protected]>
-// 
-// 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/.
-
-#include "extract_feature.h"
-#include "../../unique_edge_map.h"
-#include "../../PI.h"
-#include <CGAL/Kernel/global_functions.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedE >
-IGL_INLINE void igl::copyleft::cgal::extract_feature(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    const double tol,
-    Eigen::PlainObjectBase<DerivedE>& feature_edges) {
-
-  using IndexType = typename DerivedE::Scalar;
-  DerivedE E, uE;
-  Eigen::VectorXi EMAP;
-  std::vector<std::vector<IndexType> > uE2E;
-  igl::unique_edge_map(F, E, uE, EMAP, uE2E);
-
-  igl::copyleft::cgal::extract_feature(V, F, tol, E, uE, uE2E, feature_edges);
-}
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedE >
-IGL_INLINE void igl::copyleft::cgal::extract_feature(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    const double tol,
-    const Eigen::PlainObjectBase<DerivedE>& E,
-    const Eigen::PlainObjectBase<DerivedE>& uE,
-    const std::vector<std::vector<typename DerivedE::Scalar> >& uE2E,
-    Eigen::PlainObjectBase<DerivedE>& feature_edges) {
-
-  assert(V.cols() == 3);
-  assert(F.cols() == 3);
-  using Scalar = typename DerivedV::Scalar;
-  using IndexType = typename DerivedE::Scalar;
-  using Vertex = Eigen::Matrix<Scalar, 3, 1>;
-  using Kernel = typename CGAL::Exact_predicates_exact_constructions_kernel;
-  using Point = typename Kernel::Point_3;
-
-  const size_t num_unique_edges = uE.rows();
-  const size_t num_faces = F.rows();
-  // NOTE: CGAL's definition of dihedral angle measures the angle between two
-  // facets instead of facet normals.
-  const double cos_tol = cos(igl::PI - tol);
-  std::vector<size_t> result; // Indices into uE
-
-  auto is_non_manifold = [&uE2E](size_t ei) -> bool {
-    return uE2E[ei].size() > 2;
-  };
-
-  auto is_boundary = [&uE2E](size_t ei) -> bool {
-    return uE2E[ei].size() == 1;
-  };
-
-  auto opposite_vertex = [&uE, &F](size_t ei, size_t fi) -> IndexType {
-    const size_t v0 = uE(ei, 0);
-    const size_t v1 = uE(ei, 1);
-    for (size_t i=0; i<3; i++) {
-      const size_t v = F(fi, i);
-      if (v != v0 && v != v1) { return v; }
-    }
-    throw "Input face must be topologically degenerate!";
-  };
-
-  auto is_feature = [&V, &F, &uE, &uE2E, &opposite_vertex, num_faces](
-      size_t ei, double cos_tol) -> bool {
-    auto adj_faces = uE2E[ei];
-    assert(adj_faces.size() == 2);
-    const Vertex v0 = V.row(uE(ei, 0));
-    const Vertex v1 = V.row(uE(ei, 1));
-    const Vertex v2 = V.row(opposite_vertex(ei, adj_faces[0] % num_faces));
-    const Vertex v3 = V.row(opposite_vertex(ei, adj_faces[1] % num_faces));
-    const Point p0(v0[0], v0[1], v0[2]);
-    const Point p1(v1[0], v1[1], v1[2]);
-    const Point p2(v2[0], v2[1], v2[2]);
-    const Point p3(v3[0], v3[1], v3[2]);
-    const auto ori = CGAL::orientation(p0, p1, p2, p3);
-    switch (ori) {
-      case CGAL::POSITIVE:
-        return CGAL::compare_dihedral_angle(p0, p1, p2, p3, cos_tol) ==
-          CGAL::SMALLER;
-      case CGAL::NEGATIVE:
-        return CGAL::compare_dihedral_angle(p0, p1, p3, p2, cos_tol) ==
-          CGAL::SMALLER;
-      case CGAL::COPLANAR:
-        if (!CGAL::collinear(p0, p1, p2) && !CGAL::collinear(p0, p1, p3)) {
-          return CGAL::compare_dihedral_angle(p0, p1, p2, p3, cos_tol) ==
-            CGAL::SMALLER;
-        } else {
-          throw "Dihedral angle (and feature edge) is not well defined for"
-              " degenerate triangles!";
-        }
-      default:
-        throw "Unknown CGAL orientation";
-    }
-  };
-
-  for (size_t i=0; i<num_unique_edges; i++) {
-    if (is_boundary(i) || is_non_manifold(i) || is_feature(i, cos_tol)) {
-      result.push_back(i);
-    }
-  }
-
-  const size_t num_feature_edges = result.size();
-  feature_edges.resize(num_feature_edges, 2);
-  for (size_t i=0; i<num_feature_edges; i++) {
-    feature_edges.row(i) = uE.row(result[i]);
-  }
-}

+ 0 - 65
include/igl/copyleft/cgal/fast_winding_number.cpp

@@ -1,65 +0,0 @@
-#include "fast_winding_number.h"
-#include "../../fast_winding_number.h"
-#include "../../octree.h"
-#include "../../knn.h"
-#include "../../parallel_for.h"
-#include "point_areas.h"
-#include <vector>
-
-template <
-  typename DerivedP, 
-  typename DerivedN, 
-  typename DerivedQ,
-  typename BetaType, 
-  typename DerivedWN>
-IGL_INLINE void igl::copyleft::cgal::fast_winding_number(
-  const Eigen::MatrixBase<DerivedP>& P,
-  const Eigen::MatrixBase<DerivedN>& N,
-  const Eigen::MatrixBase<DerivedQ>& Q,
-  const int expansion_order,
-  const BetaType beta,
-  Eigen::PlainObjectBase<DerivedWN>& WN)
-{
-  typedef typename DerivedWN::Scalar real;
-  typedef typename Eigen::Matrix<real,Eigen::Dynamic,Eigen::Dynamic>
-    RealMatrix;
-        
-  std::vector<std::vector<int> > point_indices;
-  Eigen::Matrix<int,Eigen::Dynamic,8> CH;
-  Eigen::Matrix<real,Eigen::Dynamic,3> CN;
-  Eigen::Matrix<real,Eigen::Dynamic,1> W;
-  Eigen::MatrixXi I;
-  Eigen::Matrix<real,Eigen::Dynamic,1> A;
-  
-  octree(P,point_indices,CH,CN,W);
-  knn(P,21,point_indices,CH,CN,W,I);
-  point_areas(P,I,N,A);
-  
-  Eigen::Matrix<real,Eigen::Dynamic,Eigen::Dynamic> EC;
-  Eigen::Matrix<real,Eigen::Dynamic,3> CM;
-  Eigen::Matrix<real,Eigen::Dynamic,1> R;
-  
-  igl::fast_winding_number(
-    P,N,A,point_indices,CH,expansion_order,CM,R,EC);
-  igl::fast_winding_number(
-    P,N,A,point_indices,CH,CM,R,EC,Q,beta,WN);
-}
-      
-template <
-  typename DerivedP, 
-  typename DerivedN, 
-  typename DerivedQ, 
-  typename DerivedWN>
-IGL_INLINE void igl::copyleft::cgal::fast_winding_number(
-  const Eigen::MatrixBase<DerivedP>& P,
-  const Eigen::MatrixBase<DerivedN>& N,
-  const Eigen::MatrixBase<DerivedQ>& Q,
-  Eigen::PlainObjectBase<DerivedWN>& WN)
-{
-  fast_winding_number(P,N,Q,2,2.0,WN);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::copyleft::cgal::fast_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, double, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-#endif

+ 0 - 122
include/igl/copyleft/cgal/half_space_box.cpp

@@ -1,122 +0,0 @@
-#include "half_space_box.h"
-#include "assign_scalar.h"
-#include <CGAL/Point_3.h>
-#include <CGAL/Vector_3.h>
-
-template <typename DerivedV>
-IGL_INLINE void igl::copyleft::cgal::half_space_box(
-  const CGAL::Plane_3<CGAL::Epeck> & P,
-  const Eigen::MatrixBase<DerivedV> & V,
-  Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
-  Eigen::Matrix<int,12,3> & BF)
-{
-  typedef CGAL::Plane_3<CGAL::Epeck> Plane;
-  typedef CGAL::Point_3<CGAL::Epeck> Point;
-  typedef CGAL::Vector_3<CGAL::Epeck> Vector;
-  typedef CGAL::Epeck::FT EScalar;
-  Eigen::Matrix<typename DerivedV::Scalar,1,3> avg(0,0,0);
-  for(int v = 0;v<V.rows();v++) for(int c = 0;c<V.cols();c++) avg(c) += V(v,c);
-  avg /= V.rows();
-
-  Point o3(avg(0),avg(1),avg(2));
-  Point o2 = P.projection(o3);
-  Vector u;
-  EScalar max_sqrd = -1;
-  for(int v = 0;v<V.rows();v++)
-  {
-    Vector v2 = P.projection(Point(V(v,0),V(v,1),V(v,2))) - o2;
-    const EScalar sqrd = v2.squared_length();
-    if(max_sqrd<0 || sqrd < max_sqrd)
-    {
-      u = v2;
-      max_sqrd = sqrd;
-    }
-  }
-  // L1 bbd 
-  const EScalar bbd = 
-    (EScalar(V.col(0).maxCoeff())- EScalar(V.col(0).minCoeff())) + 
-    (EScalar(V.col(1).maxCoeff())- EScalar(V.col(1).minCoeff())) + 
-    (EScalar(V.col(2).maxCoeff())- EScalar(V.col(2).minCoeff()));
-  Vector n = P.orthogonal_vector();
-  // now we have a center o2 and a vector u to the farthest point on the plane 
-  std::vector<Point> vBV;vBV.reserve(8);
-  Vector v = CGAL::cross_product(u,n);
-  // Scale u,v,n to be longer than bbd
-  const auto & longer_than = [](const EScalar min_sqr, Vector & x)
-  {
-    assert(x.squared_length() > 0);
-    while(x.squared_length() < min_sqr)
-    {
-      x = 2.*x;
-    }
-  };
-  longer_than(bbd*bbd,u);
-  longer_than(bbd*bbd,v);
-  longer_than(bbd*bbd,n);
-  vBV.emplace_back( o2 + u + v);
-  vBV.emplace_back( o2 - u + v);
-  vBV.emplace_back( o2 - u - v);
-  vBV.emplace_back( o2 + u - v);
-  vBV.emplace_back( o2 + u + v - n);
-  vBV.emplace_back( o2 - u + v - n);
-  vBV.emplace_back( o2 - u - v - n);
-  vBV.emplace_back( o2 + u - v - n);
-  BV.resize(8,3);
-  for(int b = 0;b<8;b++)
-  {
-    igl::copyleft::cgal::assign_scalar(vBV[b].x(),BV(b,0));
-    igl::copyleft::cgal::assign_scalar(vBV[b].y(),BV(b,1));
-    igl::copyleft::cgal::assign_scalar(vBV[b].z(),BV(b,2));
-  }
-  BF.resize(12,3);
-  BF<<
-    1,0,2,
-    2,0,3,
-    4,5,6,
-    4,6,7,
-    0,1,4,
-    4,1,5,
-    1,2,5,
-    5,2,6,
-    2,3,6,
-    6,3,7,
-    3,0,7,
-    7,0,4;
-}
-
-template <typename Derivedp, typename Derivedn, typename DerivedV>
-IGL_INLINE void igl::copyleft::cgal::half_space_box(
-  const Eigen::MatrixBase<Derivedp> & p,
-  const Eigen::MatrixBase<Derivedn> & n,
-  const Eigen::MatrixBase<DerivedV> & V,
-  Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
-  Eigen::Matrix<int,12,3> & BF)
-{
-  typedef CGAL::Plane_3<CGAL::Epeck> Plane;
-  typedef CGAL::Point_3<CGAL::Epeck> Point;
-  typedef CGAL::Vector_3<CGAL::Epeck> Vector;
-  Plane P(Point(p(0),p(1),p(2)),Vector(n(0),n(1),n(2)));
-  return half_space_box(P,V,BV,BF);
-}
-
-template <typename Derivedequ, typename DerivedV>
-IGL_INLINE void igl::copyleft::cgal::half_space_box(
-  const Eigen::MatrixBase<Derivedequ> & equ,
-  const Eigen::MatrixBase<DerivedV> & V,
-  Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
-  Eigen::Matrix<int,12,3> & BF)
-{
-  typedef CGAL::Plane_3<CGAL::Epeck> Plane;
-  Plane P(equ(0),equ(1),equ(2),equ(3));
-  return half_space_box(P,V,BV,BF);
-}
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, -1, 3, 1, -1, 3> >(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<float, -1, 3, 1, -1, 3> >(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
-template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
-template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Epeck::FT, -1, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 4, 0, -1, 4> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
-template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
-template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
-#endif

+ 0 - 45
include/igl/copyleft/cgal/hausdorff.cpp

@@ -1,45 +0,0 @@
-#include "hausdorff.h"
-#include "../../hausdorff.h"
-#include <functional>
-
-template <
-  typename DerivedV,
-  typename Kernel,
-  typename Scalar>
-IGL_INLINE void igl::copyleft::cgal::hausdorff(
-  const Eigen::MatrixBase<DerivedV>& V,
-  const CGAL::AABB_tree<
-    CGAL::AABB_traits<Kernel, 
-      CGAL::AABB_triangle_primitive<Kernel, 
-        typename std::vector<CGAL::Triangle_3<Kernel> >::iterator
-      >
-    >
-  > & treeB,
-  const std::vector<CGAL::Triangle_3<Kernel> > & /*TB*/,
-  Scalar & l,
-  Scalar & u)
-{
-  // Not sure why using `auto` here doesn't work with the `hausdorff` function
-  // parameter but explicitly naming the type does...
-  const std::function<double(const double &,const double &,const double &)> 
-    dist_to_B = [&treeB](
-    const double & x, const double & y, const double & z)->double
-  {
-    CGAL::Point_3<Kernel> query(x,y,z);
-    typename CGAL::AABB_tree<
-      CGAL::AABB_traits<Kernel, 
-        CGAL::AABB_triangle_primitive<Kernel, 
-          typename std::vector<CGAL::Triangle_3<Kernel> >::iterator
-        >
-      >
-    >::Point_and_primitive_id pp = treeB.closest_point_and_primitive(query);
-    return std::sqrt((query-pp.first).squared_length());
-  };
-  return igl::hausdorff(V,dist_to_B,l,u);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::hausdorff<Eigen::Matrix<double, -1, -1, 0, -1, -1>, CGAL::Simple_cartesian<double>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > > const&, double&, double&);
-#endif

+ 0 - 48
include/igl/copyleft/cgal/incircle.cpp

@@ -1,48 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2016 Qingan Zhou <[email protected]>
-//
-// 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/.
-
-#include "incircle.h"
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-
-template<typename Scalar>
-IGL_INLINE short igl::copyleft::cgal::incircle(
-    const Scalar *pa,
-    const Scalar *pb,
-    const Scalar *pc,
-    const Scalar *pd)
-{
-  typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
-  typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
-  typedef typename std::conditional<std::is_same<Scalar, Epeck::FT>::value,
-          Epeck, Epick>::type Kernel;
-
-  switch(CGAL::side_of_oriented_circle(
-        typename Kernel::Point_2(pa[0], pa[1]),
-        typename Kernel::Point_2(pb[0], pb[1]),
-        typename Kernel::Point_2(pc[0], pc[1]),
-        typename Kernel::Point_2(pd[0], pd[1]))) {
-    case CGAL::ON_POSITIVE_SIDE:
-      return 1;
-    case CGAL::ON_NEGATIVE_SIDE:
-      return -1;
-    case CGAL::ON_ORIENTED_BOUNDARY:
-      return 0;
-    default:
-      throw "Invalid incircle result";
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template short igl::copyleft::cgal::incircle<double>(double const*, double const*, double const*, double const*);
-#ifdef WIN32
-template short igl::copyleft::cgal::incircle<double>(double const * const,double const * const,double const * const,double const * const);
-#endif
-#endif

+ 0 - 68
include/igl/copyleft/cgal/insert_into_cdt.cpp

@@ -1,68 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2016 Alec Jacobson
-//
-// 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/.
-#include "insert_into_cdt.h"
-#include <CGAL/Point_3.h>
-#include <CGAL/Segment_3.h>
-#include <CGAL/Triangle_3.h>
-
-template <typename Kernel>
-IGL_INLINE void igl::copyleft::cgal::insert_into_cdt(
-  const CGAL::Object & obj,
-  const CGAL::Plane_3<Kernel> & P,
-  CGAL::Constrained_triangulation_plus_2<
-    CGAL::Constrained_Delaunay_triangulation_2<
-      Kernel,
-      CGAL::Triangulation_data_structure_2<
-        CGAL::Triangulation_vertex_base_2<Kernel>,
-        CGAL::Constrained_triangulation_face_base_2< Kernel>
-      >,
-      CGAL::Exact_intersections_tag
-    >
-  >
-  & cdt)
-{
-  typedef CGAL::Point_3<Kernel>    Point_3;
-  typedef CGAL::Segment_3<Kernel>  Segment_3;
-  typedef CGAL::Triangle_3<Kernel> Triangle_3;
-
-  if(const Segment_3 *iseg = CGAL::object_cast<Segment_3 >(&obj))
-  {
-    // Add segment constraint
-    cdt.insert_constraint( P.to_2d(iseg->vertex(0)),P.to_2d(iseg->vertex(1)));
-  }else if(const Point_3 *ipoint = CGAL::object_cast<Point_3 >(&obj))
-  {
-    // Add point
-    cdt.insert(P.to_2d(*ipoint));
-  } else if(const Triangle_3 *itri = CGAL::object_cast<Triangle_3 >(&obj))
-  {
-    // Add 3 segment constraints
-    cdt.insert_constraint( P.to_2d(itri->vertex(0)),P.to_2d(itri->vertex(1)));
-    cdt.insert_constraint( P.to_2d(itri->vertex(1)),P.to_2d(itri->vertex(2)));
-    cdt.insert_constraint( P.to_2d(itri->vertex(2)),P.to_2d(itri->vertex(0)));
-  } else if(const std::vector<Point_3 > *polyp =
-      CGAL::object_cast< std::vector<Point_3 > >(&obj))
-  {
-    const std::vector<Point_3 > & poly = *polyp;
-    const size_t m = poly.size();
-    assert(m>=2);
-    for(size_t p = 0;p<m;p++)
-    {
-      const size_t np = (p+1)%m;
-      cdt.insert_constraint(P.to_2d(poly[p]),P.to_2d(poly[np]));
-    }
-  }else {
-    throw std::runtime_error("Unknown intersection object!");
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-// Explicit template instantiation
-template void igl::copyleft::cgal::insert_into_cdt<CGAL::Epick>(CGAL::Object const&, CGAL::Plane_3<CGAL::Epick> const&, CGAL::Constrained_triangulation_plus_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epick, CGAL::Triangulation_data_structure_2<CGAL::Triangulation_vertex_base_2<CGAL::Epick, CGAL::Triangulation_ds_vertex_base_2<void> >, CGAL::Constrained_triangulation_face_base_2<CGAL::Epick, CGAL::Triangulation_face_base_2<CGAL::Epick, CGAL::Triangulation_ds_face_base_2<void> > > >, CGAL::Exact_intersections_tag> >&);
-template void igl::copyleft::cgal::insert_into_cdt<CGAL::Epeck>(CGAL::Object const&, CGAL::Plane_3<CGAL::Epeck> const&, CGAL::Constrained_triangulation_plus_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epeck, CGAL::Triangulation_data_structure_2<CGAL::Triangulation_vertex_base_2<CGAL::Epeck, CGAL::Triangulation_ds_vertex_base_2<void> >, CGAL::Constrained_triangulation_face_base_2<CGAL::Epeck, CGAL::Triangulation_face_base_2<CGAL::Epeck, CGAL::Triangulation_ds_face_base_2<void> > > >, CGAL::Exact_intersections_tag> >&);
-#endif

+ 0 - 41
include/igl/copyleft/cgal/insphere.cpp

@@ -1,41 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Qingan Zhou <[email protected]>
-// 
-// 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/.
-
-#include "insphere.h"
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-
-template<typename Scalar>
-IGL_INLINE short igl::copyleft::cgal::insphere(
-    const Scalar pa[3],
-    const Scalar pb[3],
-    const Scalar pc[3],
-    const Scalar pd[3],
-    const Scalar pe[3])
-{
-  typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
-  typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
-  typedef typename std::conditional<std::is_same<Scalar, Epeck::FT>::value,
-          Epeck, Epick>::type Kernel;
-
-  switch(CGAL::side_of_oriented_sphere(
-        typename Kernel::Point_3(pa[0], pa[1], pa[2]),
-        typename Kernel::Point_3(pb[0], pb[1], pb[2]),
-        typename Kernel::Point_3(pc[0], pc[1], pc[2]),
-        typename Kernel::Point_3(pd[0], pd[1], pd[2]),
-        typename Kernel::Point_3(pe[0], pe[1], pe[2]))) {
-    case CGAL::ON_POSITIVE_SIDE:
-      return 1;
-    case CGAL::ON_NEGATIVE_SIDE:
-      return -1;
-    case CGAL::ON_ORIENTED_BOUNDARY:
-      return 0;
-    default:
-      throw "Invalid incircle result";
-  }
-}

+ 0 - 295
include/igl/copyleft/cgal/intersect_other.cpp

@@ -1,295 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2014 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "intersect_other.h"
-#include "CGAL_includes.hpp"
-#include "mesh_to_cgal_triangle_list.h"
-#include "remesh_intersections.h"
-#include "../../slice_mask.h"
-#include "../../remove_unreferenced.h"
-
-#ifndef IGL_FIRST_HIT_EXCEPTION
-#define IGL_FIRST_HIT_EXCEPTION 10
-#endif
-
-// Un-exposed helper functions
-namespace igl
-{
-  namespace copyleft
-  {
-    namespace cgal
-    {
-      template <typename DerivedF>
-      static IGL_INLINE void push_result(
-        const Eigen::PlainObjectBase<DerivedF> & F,
-        const int f,
-        const int f_other,
-        const CGAL::Object & result,
-        std::map<
-          typename DerivedF::Index,
-          std::vector<std::pair<typename DerivedF::Index, CGAL::Object> > > &
-          offending)
-        //std::map<
-        //  std::pair<typename DerivedF::Index,typename DerivedF::Index>,
-        //  std::vector<typename DerivedF::Index> > & edge2faces)
-      {
-        typedef typename DerivedF::Index Index;
-        typedef std::pair<Index,Index> EMK;
-        if(offending.count(f) == 0)
-        {
-          // first time marking, initialize with new id and empty list
-          offending[f] = {};
-          for(Index e = 0; e<3;e++)
-          {
-            // append face to edge's list
-            Index i = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+1)%3) : F(f,(e+2)%3);
-            Index j = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+2)%3) : F(f,(e+1)%3);
-            //edge2faces[EMK(i,j)].push_back(f);
-          }
-        }
-        offending[f].push_back({f_other,result});
-      }
-      template <
-        typename Kernel,
-        typename DerivedVA,
-        typename DerivedFA,
-        typename DerivedVB,
-        typename DerivedFB,
-        typename DerivedIF,
-        typename DerivedVVAB,
-        typename DerivedFFAB,
-        typename DerivedJAB,
-        typename DerivedIMAB>
-      static IGL_INLINE bool intersect_other_helper(
-        const Eigen::PlainObjectBase<DerivedVA> & VA,
-        const Eigen::PlainObjectBase<DerivedFA> & FA,
-        const Eigen::PlainObjectBase<DerivedVB> & VB,
-        const Eigen::PlainObjectBase<DerivedFB> & FB,
-        const RemeshSelfIntersectionsParam & params,
-        Eigen::PlainObjectBase<DerivedIF> & IF,
-        Eigen::PlainObjectBase<DerivedVVAB> & VVAB,
-        Eigen::PlainObjectBase<DerivedFFAB> & FFAB,
-        Eigen::PlainObjectBase<DerivedJAB>  & JAB,
-        Eigen::PlainObjectBase<DerivedIMAB> & IMAB)
-      {
-
-        using namespace std;
-        using namespace Eigen;
-
-        typedef typename DerivedFA::Index Index;
-        // 3D Primitives
-        typedef CGAL::Point_3<Kernel>    Point_3;
-        typedef CGAL::Segment_3<Kernel>  Segment_3; 
-        typedef CGAL::Triangle_3<Kernel> Triangle_3; 
-        typedef CGAL::Plane_3<Kernel>    Plane_3;
-        typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3; 
-        // 2D Primitives
-        typedef CGAL::Point_2<Kernel>    Point_2;
-        typedef CGAL::Segment_2<Kernel>  Segment_2; 
-        typedef CGAL::Triangle_2<Kernel> Triangle_2; 
-        // 2D Constrained Delaunay Triangulation types
-        typedef CGAL::Triangulation_vertex_base_2<Kernel>  TVB_2;
-        typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTAB_2;
-        typedef CGAL::Triangulation_data_structure_2<TVB_2,CTAB_2> TDS_2;
-        typedef CGAL::Exact_intersections_tag Itag;
-        // Axis-align boxes for all-pairs self-intersection detection
-        typedef std::vector<Triangle_3> Triangles;
-        typedef typename Triangles::iterator TrianglesIterator;
-        typedef typename Triangles::const_iterator TrianglesConstIterator;
-        typedef 
-          CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator> 
-          Box;
-        typedef 
-          std::map<Index,std::vector<std::pair<Index,CGAL::Object> > > 
-          OffendingMap;
-        typedef std::map<std::pair<Index,Index>,std::vector<Index> >  EdgeMap;
-        typedef std::pair<Index,Index> EMK;
-
-        Triangles TA,TB;
-        // Compute and process self intersections
-        mesh_to_cgal_triangle_list(VA,FA,TA);
-        mesh_to_cgal_triangle_list(VB,FB,TB);
-        // http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Box_intersection_d/Chapter_main.html#Section_63.5 
-        // Create the corresponding vector of bounding boxes
-        std::vector<Box> A_boxes,B_boxes;
-        const auto box_up = [](Triangles & T, std::vector<Box> & boxes) -> void
-        {
-          boxes.reserve(T.size());
-          for ( 
-            TrianglesIterator tit = T.begin(); 
-            tit != T.end(); 
-            ++tit)
-          {
-            boxes.push_back(Box(tit->bbox(), tit));
-          }
-        };
-        box_up(TA,A_boxes);
-        box_up(TB,B_boxes);
-        OffendingMap offendingA,offendingB;
-        //EdgeMap edge2facesA,edge2facesB;
-
-        std::list<int> lIF;
-        const auto cb = [&](const Box &a, const Box &b) -> void
-        {
-          using namespace std;
-          // index in F and T
-          int fa = a.handle()-TA.begin();
-          int fb = b.handle()-TB.begin();
-          const Triangle_3 & A = *a.handle();
-          const Triangle_3 & B = *b.handle();
-          if(CGAL::do_intersect(A,B))
-          {
-            // There was an intersection
-            lIF.push_back(fa);
-            lIF.push_back(fb);
-            if(params.first_only)
-            {
-              throw IGL_FIRST_HIT_EXCEPTION;
-            }
-            if(!params.detect_only)
-            {
-              CGAL::Object result = CGAL::intersection(A,B);
-
-              push_result(FA,fa,fb,result,offendingA);
-              push_result(FB,fb,fa,result,offendingB);
-            }
-          }
-        };
-        try{
-          CGAL::box_intersection_d(
-            A_boxes.begin(), A_boxes.end(),
-            B_boxes.begin(), B_boxes.end(),
-            cb);
-        }catch(int e)
-        {
-          // Rethrow if not FIRST_HIT_EXCEPTION
-          if(e != IGL_FIRST_HIT_EXCEPTION)
-          {
-            throw e;
-          }
-          // Otherwise just fall through
-        }
-
-        // Convert lIF to Eigen matrix
-        assert(lIF.size()%2 == 0);
-        IF.resize(lIF.size()/2,2);
-        {
-          int i=0;
-          for(
-            list<int>::const_iterator ifit = lIF.begin();
-            ifit!=lIF.end();
-            )
-          {
-            IF(i,0) = (*ifit);
-            ifit++; 
-            IF(i,1) = (*ifit);
-            ifit++;
-            i++;
-          }
-        }
-        if(!params.detect_only)
-        {
-          // Obsolete, now remesh_intersections expects a single mesh
-          // remesh_intersections(VA,FA,TA,offendingA,VVA,FFA,JA,IMA);
-          // remesh_intersections(VB,FB,TB,offendingB,VVB,FFB,JB,IMB);
-          // Combine mesh and offending maps
-          DerivedVA VAB(VA.rows()+VB.rows(),3);
-          VAB<<VA,VB;
-          DerivedFA FAB(FA.rows()+FB.rows(),3);
-          FAB<<FA,(FB.array()+VA.rows());
-          Triangles TAB;
-          TAB.reserve(TA.size()+TB.size());
-          TAB.insert(TAB.end(),TA.begin(),TA.end());
-          TAB.insert(TAB.end(),TB.begin(),TB.end());
-          OffendingMap offending;
-          //offending.reserve(offendingA.size() + offendingB.size());
-          for (const auto itr : offendingA)
-          {
-            // Remap offenders in FB to FAB
-            auto offenders = itr.second;
-            for(auto & offender : offenders)
-            {
-              offender.first += FA.rows();
-            }
-            offending[itr.first] = offenders;
-          }
-          for (const auto itr : offendingB)
-          {
-            // Store offenders for FB according to place in FAB
-            offending[FA.rows() + itr.first] = itr.second;
-          }
-
-          remesh_intersections(
-            VAB,FAB,TAB,offending,
-            params.stitch_all,params.slow_and_more_precise_rounding,
-            VVAB,FFAB,JAB,IMAB);
-        }
-
-        return IF.rows() > 0;
-      }
-    }
-  }
-}
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename DerivedIF,
-  typename DerivedVVAB,
-  typename DerivedFFAB,
-  typename DerivedJAB,
-  typename DerivedIMAB>
-IGL_INLINE bool igl::copyleft::cgal::intersect_other(
-    const Eigen::PlainObjectBase<DerivedVA> & VA,
-    const Eigen::PlainObjectBase<DerivedFA> & FA,
-    const Eigen::PlainObjectBase<DerivedVB> & VB,
-    const Eigen::PlainObjectBase<DerivedFB> & FB,
-    const RemeshSelfIntersectionsParam & params,
-    Eigen::PlainObjectBase<DerivedIF> & IF,
-    Eigen::PlainObjectBase<DerivedVVAB> & VVAB,
-    Eigen::PlainObjectBase<DerivedFFAB> & FFAB,
-    Eigen::PlainObjectBase<DerivedJAB>  & JAB,
-    Eigen::PlainObjectBase<DerivedIMAB> & IMAB)
-{
-  typedef typename DerivedVA::Scalar VAScalar;
-  typedef typename DerivedVB::Scalar VBScalar;
-  if(params.detect_only && ! (
-    std::is_same<VAScalar,CGAL::Epeck::FT>::value ||
-    std::is_same<VBScalar,CGAL::Epeck::FT>::value
-    ))
-  {
-    return intersect_other_helper<CGAL::Epick>
-      (VA,FA,VB,FB,params,IF,VVAB,FFAB,JAB,IMAB);
-  }else
-  {
-    return intersect_other_helper<CGAL::Epeck>
-      (VA,FA,VB,FB,params,IF,VVAB,FFAB,JAB,IMAB);
-  }
-}
-
-IGL_INLINE bool igl::copyleft::cgal::intersect_other(
-  const Eigen::MatrixXd & VA,
-  const Eigen::MatrixXi & FA,
-  const Eigen::MatrixXd & VB,
-  const Eigen::MatrixXi & FB,
-  const bool first_only,
-  Eigen::MatrixXi & IF)
-{
-  Eigen::MatrixXd VVAB;
-  Eigen::MatrixXi FFAB;
-  Eigen::VectorXi JAB,IMAB;
-  return intersect_other(
-    VA,FA,VB,FB,{true,first_only},IF,VVAB,FFAB,JAB,IMAB);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::copyleft::cgal::intersect_other<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<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, 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&,   Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,   igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&,   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> >&);
-template bool igl::copyleft::cgal::intersect_other<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -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<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -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

+ 0 - 84
include/igl/copyleft/cgal/intersect_with_half_space.cpp

@@ -1,84 +0,0 @@
-#include "intersect_with_half_space.h"
-#include "mesh_boolean.h"
-#include "half_space_box.h"
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Derivedp,
-  typename Derivedn,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::intersect_with_half_space(
-  const Eigen::MatrixBase<DerivedV > & V,
-  const Eigen::MatrixBase<DerivedF > & F,
-  const Eigen::MatrixBase<Derivedp > & p,
-  const Eigen::MatrixBase<Derivedn > & n,
-  Eigen::PlainObjectBase<DerivedVC > & VC,
-  Eigen::PlainObjectBase<DerivedFC > & FC,
-  Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  typedef CGAL::Plane_3<CGAL::Epeck> Plane;
-  typedef CGAL::Point_3<CGAL::Epeck> Point;
-  typedef CGAL::Vector_3<CGAL::Epeck> Vector;
-  Plane P(Point(p(0),p(1),p(2)),Vector(n(0),n(1),n(2)));
-  return intersect_with_half_space(V,F,P,VC,FC,J);
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Derivedequ,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::intersect_with_half_space(
-  const Eigen::MatrixBase<DerivedV > & V,
-  const Eigen::MatrixBase<DerivedF > & F,
-  const Eigen::MatrixBase<Derivedequ > & equ,
-  Eigen::PlainObjectBase<DerivedVC > & VC,
-  Eigen::PlainObjectBase<DerivedFC > & FC,
-  Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  typedef CGAL::Plane_3<CGAL::Epeck> Plane;
-  Plane P(equ(0),equ(1),equ(2),equ(3));
-  return intersect_with_half_space(V,F,P,VC,FC,J);
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::intersect_with_half_space(
-  const Eigen::MatrixBase<DerivedV > & V,
-  const Eigen::MatrixBase<DerivedF > & F,
-  const CGAL::Plane_3<CGAL::Epeck> & P,
-  Eigen::PlainObjectBase<DerivedVC > & VC,
-  Eigen::PlainObjectBase<DerivedFC > & FC,
-  Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  Eigen::Matrix<CGAL::Epeck::FT,8,3> BV;
-  Eigen::Matrix<int,12,3> BF;
-  half_space_box(P,V,BV,BF);
-  // Disturbingly, (BV,BF) must be first argument
-  const bool ret = mesh_boolean(BV,BF,V,F,MESH_BOOLEAN_TYPE_INTERSECT,VC,FC,J);
-  // But now J is wrong...
-  std::for_each(
-    J.data(),
-    J.data()+J.size(),
-    [&BF,&F](typename DerivedJ::Scalar & j)
-      {j = (j<BF.rows()?F.rows()+j:j-BF.rows());}
-    );
-  return ret;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<double>, Eigen::Matrix<double, 1, 3, 1, 1, 3> const>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<double>, Eigen::Matrix<double, 1, 3, 1, 1, 3> const> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, Eigen::Matrix<float, 1, 3, 1, 1, 3> const>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, Eigen::Matrix<float, 1, 3, 1, 1, 3> const> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#endif

+ 0 - 24
include/igl/copyleft/cgal/lexicographic_triangulation.cpp

@@ -1,24 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-//                    Qingan Zhou <[email protected]>
-// 
-// 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/.
-
-#include "lexicographic_triangulation.h"
-#include "../../lexicographic_triangulation.h"
-#include "orient2D.h"
-
-template<
-  typename DerivedP,
-  typename DerivedF
-  >
-IGL_INLINE void igl::copyleft::cgal::lexicographic_triangulation(
-    const Eigen::PlainObjectBase<DerivedP>& P,
-    Eigen::PlainObjectBase<DerivedF>& F)
-{
-  typedef typename DerivedP::Scalar Scalar;
-  igl::lexicographic_triangulation(P, orient2D<Scalar>, F);
-}

+ 0 - 15
include/igl/copyleft/cgal/list_to_matrix.cpp

@@ -1,15 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2017 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "../../list_to_matrix.h"
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#ifdef IGL_STATIC_LIBRARY
-#undef IGL_STATIC_LIBRARY
-#include "../../list_to_matrix.cpp"
-template bool igl::list_to_matrix<CGAL::Epeck::FT, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(std::vector<std::vector<CGAL::Epeck::FT, std::allocator<CGAL::Epeck::FT > >, std::allocator<std::vector<CGAL::Epeck::FT, std::allocator<CGAL::Epeck::FT > > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
-#endif

+ 0 - 459
include/igl/copyleft/cgal/mesh_boolean.cpp

@@ -1,459 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-//                    Qingnan Zhou <[email protected]>
-// 
-// 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/.
-//
-#include "mesh_boolean.h"
-#include "assign_scalar.h"
-#include "extract_cells.h"
-#include "mesh_boolean_type_to_funcs.h"
-#include "propagate_winding_numbers.h"
-#include "relabel_small_immersed_cells.h"
-#include "remesh_self_intersections.h"
-#include "string_to_mesh_boolean_type.h"
-#include "../../combine.h"
-#include "../../cumsum.h"
-#include "../../extract_manifold_patches.h"
-#include "../../get_seconds.h"
-#include "../../parallel_for.h"
-#include "../../remove_unreferenced.h"
-#include "../../resolve_duplicated_faces.h"
-#include "../../slice.h"
-#include "../../unique_edge_map.h"
-#include "../../unique_simplices.h"
-#include "../../C_STR.h"
-
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <algorithm>
-
-//#define MESH_BOOLEAN_TIMING
-//#define DOUBLE_CHECK_EXACT_OUTPUT
-//#define SMALL_CELL_REMOVAL
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-    const Eigen::MatrixBase<DerivedVA > & VA,
-    const Eigen::MatrixBase<DerivedFA > & FA,
-    const Eigen::MatrixBase<DerivedVB > & VB,
-    const Eigen::MatrixBase<DerivedFB > & FB,
-    const MeshBooleanType & type,
-    Eigen::PlainObjectBase<DerivedVC > & VC,
-    Eigen::PlainObjectBase<DerivedFC > & FC,
-    Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  std::function<int(const int, const int)> keep;
-  std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) > wind_num_op;
-  mesh_boolean_type_to_funcs(type,wind_num_op,keep);
-  return mesh_boolean(VA,FA,VB,FB,wind_num_op,keep,VC,FC,J);
-}
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-  const Eigen::MatrixBase<DerivedVA > & VA,
-  const Eigen::MatrixBase<DerivedFA > & FA,
-  const Eigen::MatrixBase<DerivedVB > & VB,
-  const Eigen::MatrixBase<DerivedFB > & FB,
-  const std::string & type_str,
-  Eigen::PlainObjectBase<DerivedVC > & VC,
-  Eigen::PlainObjectBase<DerivedFC > & FC,
-  Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  return mesh_boolean(
-    VA,FA,VB,FB,string_to_mesh_boolean_type(type_str),VC,FC,J);
-}
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-    const Eigen::MatrixBase<DerivedVA> & VA,
-    const Eigen::MatrixBase<DerivedFA> & FA,
-    const Eigen::MatrixBase<DerivedVB> & VB,
-    const Eigen::MatrixBase<DerivedFB> & FB,
-    const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
-    const std::function<int(const int, const int)> & keep,
-    Eigen::PlainObjectBase<DerivedVC > & VC,
-    Eigen::PlainObjectBase<DerivedFC > & FC,
-    Eigen::PlainObjectBase<DerivedJ > & J) 
-{
-  // Generate combined mesh (VA,FA,VB,FB) -> (V,F)
-  Eigen::Matrix<size_t,2,1> sizes(FA.rows(),FB.rows());
-  // TODO: This is a precision template **bug** that results in failure to
-  // compile. If DerivedVA::Scalar is double and DerivedVB::Scalar is
-  // CGAL::Epeck::FT then the following assignment will not compile. This
-  // implies that VA must have the trumping precision (and a valid assignment
-  // operator from VB's type).
-  Eigen::Matrix<typename DerivedVA::Scalar,Eigen::Dynamic,3> VV(VA.rows() + VB.rows(), 3);
-  Eigen::Matrix<typename DerivedFA::Scalar,Eigen::Dynamic,3> FF(FA.rows() + FB.rows(), 3);
-  // Can't use comma initializer
-  for(int a = 0;a<VA.rows();a++)
-  {
-    for(int d = 0;d<3;d++) VV(a,d) = VA(a,d);
-  }
-  for(int b = 0;b<VB.rows();b++)
-  {
-    for(int d = 0;d<3;d++) VV(VA.rows()+b,d) = VB(b,d);
-  }
-  FF.block(0, 0, FA.rows(), 3) = FA;
-  // Eigen struggles to assign nothing to nothing and will assert if FB is empty
-  if(FB.rows() > 0)
-  {
-    FF.block(FA.rows(), 0, FB.rows(), 3) = FB.array() + VA.rows();
-  }
-  return mesh_boolean(VV,FF,sizes,wind_num_op,keep,VC,FC,J);
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-    const std::vector<DerivedV > & Vlist,
-    const std::vector<DerivedF > & Flist,
-    const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
-    const std::function<int(const int, const int)> & keep,
-    Eigen::PlainObjectBase<DerivedVC > & VC,
-    Eigen::PlainObjectBase<DerivedFC > & FC,
-    Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  DerivedV VV;
-  DerivedF FF;
-  Eigen::Matrix<size_t,Eigen::Dynamic,1> Vsizes,Fsizes;
-  igl::combine(Vlist,Flist,VV,FF,Vsizes,Fsizes);
-  return mesh_boolean(VV,FF,Fsizes,wind_num_op,keep,VC,FC,J);
-}
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-    const std::vector<DerivedV > & Vlist,
-    const std::vector<DerivedF > & Flist,
-    const MeshBooleanType & type,
-    Eigen::PlainObjectBase<DerivedVC > & VC,
-    Eigen::PlainObjectBase<DerivedFC > & FC,
-    Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  DerivedV VV;
-  DerivedF FF;
-  Eigen::Matrix<size_t,Eigen::Dynamic,1> Vsizes,Fsizes;
-  igl::combine(Vlist,Flist,VV,FF,Vsizes,Fsizes);
-  std::function<int(const int, const int)> keep;
-  std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) > wind_num_op;
-  mesh_boolean_type_to_funcs(type,wind_num_op,keep);
-  return mesh_boolean(VV,FF,Fsizes,wind_num_op,keep,VC,FC,J);
-}
-
-template <
-  typename DerivedVV,
-  typename DerivedFF,
-  typename Derivedsizes,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-    const Eigen::MatrixBase<DerivedVV > & VV,
-    const Eigen::MatrixBase<DerivedFF > & FF,
-    const Eigen::MatrixBase<Derivedsizes> & sizes,
-    const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
-    const std::function<int(const int, const int)> & keep,
-    Eigen::PlainObjectBase<DerivedVC > & VC,
-    Eigen::PlainObjectBase<DerivedFC > & FC,
-    Eigen::PlainObjectBase<DerivedJ > & J)
-{
-#ifdef MESH_BOOLEAN_TIMING
-  const auto & tictoc = []() -> double
-  {
-    static double t_start = igl::get_seconds();
-    double diff = igl::get_seconds()-t_start;
-    t_start += diff;
-    return diff;
-  };
-  const auto log_time = [&](const std::string& label) -> void {
-    printf("%50s: %0.5lf\n",
-      C_STR("mesh_boolean." << label),tictoc());
-  };
-  tictoc();
-#endif
-  typedef typename DerivedVC::Scalar Scalar;
-  typedef CGAL::Epeck Kernel;
-  typedef Kernel::FT ExactScalar;
-  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3> MatrixX3S;
-  typedef Eigen::Matrix<typename DerivedJ::Scalar,Eigen::Dynamic,1> VectorXJ;
-  typedef Eigen::Matrix<
-    ExactScalar,
-    Eigen::Dynamic,
-    Eigen::Dynamic,
-    DerivedVC::IsRowMajor> MatrixXES;
-  MatrixXES V;
-  DerivedFC F;
-  VectorXJ  CJ;
-  {
-    Eigen::VectorXi I;
-    igl::copyleft::cgal::RemeshSelfIntersectionsParam params;
-    params.stitch_all = true;
-    MatrixXES Vr;
-    DerivedFC Fr;
-    Eigen::MatrixXi IF;
-    igl::copyleft::cgal::remesh_self_intersections(
-        VV, FF, params, Vr, Fr, IF, CJ, I);
-    assert(I.size() == Vr.rows());
-    // Merge coinciding vertices into non-manifold vertices.
-    std::for_each(Fr.data(), Fr.data()+Fr.size(),
-          [&I](typename DerivedFC::Scalar& a) { a=I[a]; });
-      // Remove unreferenced vertices.
-      Eigen::VectorXi UIM;
-      igl::remove_unreferenced(Vr, Fr, V, F, UIM);
-   }
-#ifdef MESH_BOOLEAN_TIMING
-  log_time("resolve_self_intersection");
-#endif
-
-  Eigen::MatrixXi E, uE;
-  Eigen::VectorXi EMAP, uEC, uEE;
-  igl::unique_edge_map(F, E, uE, EMAP, uEC, uEE);
-
-  // Compute patches (F,EMAP,uEC,uEE) --> (P)
-  Eigen::VectorXi P;
-  const size_t num_patches = igl::extract_manifold_patches(F,EMAP,uEC,uEE,P);
-#ifdef MESH_BOOLEAN_TIMING
-  log_time("patch_extraction");
-#endif
-
-  // Compute cells (V,F,P,E,uE,EMAP) -> (per_patch_cells)
-  Eigen::MatrixXi per_patch_cells;
-  const size_t num_cells =
-  extract_cells( V, F, P, E, uE, EMAP, uEC, uEE, per_patch_cells);
-#ifdef MESH_BOOLEAN_TIMING
-  log_time("cell_extraction");
-#endif
-
-  // Compute winding numbers on each side of each facet.
-  const size_t num_faces = F.rows();
-  // W(f,:) --> [w1out,w1in,w2out,w2in, ... wnout,wnint] winding numbers above
-  // and below each face w.r.t. each input mesh, so that W(f,2*i) is the
-  // winding number above face f w.r.t. input i, and W(f,2*i+1) is the winding
-  // number below face f w.r.t. input i.
-  Eigen::MatrixXi W;
-  // labels(f) = i means that face f comes from mesh i
-  Eigen::VectorXi labels(num_faces);
-  // cumulative sizes
-  Derivedsizes cumsizes;
-  igl::cumsum(sizes,1,cumsizes);
-  const size_t num_inputs = sizes.size();
-  std::transform(
-    CJ.data(), 
-    CJ.data()+CJ.size(), 
-    labels.data(),
-    // Determine which input mesh birth face i comes from
-    [&num_inputs,&cumsizes](int i)->int
-    { 
-      for(int k = 0;k<num_inputs;k++)
-      {
-        if(i<cumsizes(k)) return k;
-      }
-      assert(false && "Birth parent index out of range");
-      return -1;
-    });
-  bool valid = true;
-  if (num_faces > 0) 
-  {
-    valid = valid && propagate_winding_numbers(
-      V,F,uE,uEC,uEE,num_patches,P,num_cells,per_patch_cells,labels,W);
-  } else 
-  {
-    W.resize(0, 2*num_inputs);
-  }
-  assert((size_t)W.rows() == num_faces);
-  // If W doesn't have enough columns, pad with zeros
-  if (W.cols() <= 2*num_inputs) 
-  {
-    const int old_ncols = W.cols();
-    W.conservativeResize(num_faces,2*num_inputs);
-    W.rightCols(2*num_inputs-old_ncols).setConstant(0);
-  }
-  assert((size_t)W.cols() == 2*num_inputs);
-#ifdef MESH_BOOLEAN_TIMING
-  log_time("propagate_input_winding_number");
-#endif
-
-  // Compute resulting winding number.
-  Eigen::MatrixXi Wr(num_faces, 2);
-  for (size_t i=0; i<num_faces; i++) 
-  {
-    // Winding number vectors above and below
-    Eigen::RowVectorXi w_out(1,num_inputs), w_in(1,num_inputs);
-    for(size_t k =0;k<num_inputs;k++)
-    {
-      w_out(k) = W(i,2*k+0);
-      w_in(k) = W(i,2*k+1);
-    }
-    Wr(i,0) = wind_num_op(w_out);
-    Wr(i,1) = wind_num_op(w_in);
-  }
-#ifdef MESH_BOOLEAN_TIMING
-  log_time("compute_output_winding_number");
-#endif
-
-#ifdef SMALL_CELL_REMOVAL
-  igl::copyleft::cgal::relabel_small_immersed_cells(
-    V, F, num_patches, P, num_cells, per_patch_cells, 1e-3, Wr);
-#endif
-
-  // Extract boundary separating inside from outside.
-  auto index_to_signed_index = [&](size_t i, bool ori) -> int
-  {
-    return (i+1)*(ori?1:-1);
-  };
-  //auto signed_index_to_index = [&](int i) -> size_t {
-  //    return abs(i) - 1;
-  //};
-  std::vector<int> selected;
-  for(size_t i=0; i<num_faces; i++) 
-  {
-    auto should_keep = keep(Wr(i,0), Wr(i,1));
-    if (should_keep > 0) 
-    {
-      selected.push_back(index_to_signed_index(i, true));
-    } else if (should_keep < 0) 
-    {
-      selected.push_back(index_to_signed_index(i, false));
-    }
-  }
-
-  const size_t num_selected = selected.size();
-  DerivedFC kept_faces(num_selected, 3);
-  DerivedJ  kept_face_indices(num_selected, 1);
-  for (size_t i=0; i<num_selected; i++) 
-  {
-    size_t idx = abs(selected[i]) - 1;
-    if (selected[i] > 0) 
-    {
-      kept_faces.row(i) = F.row(idx);
-    } else 
-    {
-      kept_faces.row(i) = F.row(idx).reverse();
-    }
-    kept_face_indices(i, 0) = CJ[idx];
-  }
-#ifdef MESH_BOOLEAN_TIMING
-  log_time("extract_output");
-#endif
-
-  // Finally, remove duplicated faces and unreferenced vertices.
-  {
-    DerivedFC G;
-    DerivedJ JJ;
-    igl::resolve_duplicated_faces(kept_faces, G, JJ);
-    igl::slice(kept_face_indices, JJ, 1, J);
-
-#ifdef DOUBLE_CHECK_EXACT_OUTPUT
-    {
-      // Sanity check on exact output.
-      igl::copyleft::cgal::RemeshSelfIntersectionsParam params;
-      params.detect_only = true;
-      params.first_only = true;
-      MatrixXES dummy_VV;
-      DerivedFC dummy_FF, dummy_IF;
-      Eigen::VectorXi dummy_J, dummy_IM;
-      igl::copyleft::cgal::SelfIntersectMesh<
-        Kernel,
-        MatrixXES, DerivedFC,
-        MatrixXES, DerivedFC,
-        DerivedFC,
-        Eigen::VectorXi,
-        Eigen::VectorXi
-      > checker(V, G, params,
-          dummy_VV, dummy_FF, dummy_IF, dummy_J, dummy_IM);
-      if (checker.count != 0) 
-      {
-        throw "Self-intersection not fully resolved.";
-      }
-    }
-#endif
-
-    // `assign` _after_ removing unreferenced vertices
-    {
-      Eigen::VectorXi I,J;
-      igl::remove_unreferenced(V.rows(),G,I,J);
-      FC = G;
-      std::for_each(FC.data(),FC.data()+FC.size(),
-          [&I](typename DerivedFC::Scalar & a){a=I(a);});
-      const bool slow_and_more_precise = false;
-      VC.resize(J.size(),3);
-      igl::parallel_for(J.size(),[&](Eigen::Index i)
-      {
-        for(Eigen::Index c = 0;c<3;c++)
-        {
-          assign_scalar(V(J(i),c),slow_and_more_precise,VC(i,c));
-        }
-      },1000);
-    }
-
-
-  }
-#ifdef MESH_BOOLEAN_TIMING
-  log_time("clean_up");
-#endif
-  return valid;
-}
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename DerivedVC,
-  typename DerivedFC>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-  const Eigen::MatrixBase<DerivedVA > & VA,
-  const Eigen::MatrixBase<DerivedFA > & FA,
-  const Eigen::MatrixBase<DerivedVB > & VB,
-  const Eigen::MatrixBase<DerivedFB > & FB,
-  const MeshBooleanType & type,
-  Eigen::PlainObjectBase<DerivedVC > & VC,
-  Eigen::PlainObjectBase<DerivedFC > & FC) 
-{
-  Eigen::Matrix<typename DerivedFC::Scalar, Eigen::Dynamic,1> J;
-  return igl::copyleft::cgal::mesh_boolean(VA,FA,VB,FB,type,VC,FC,J);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-// generated by autoexplicit.sh
-template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-// generated by autoexplicit.sh
-template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template bool igl::copyleft::cgal::mesh_boolean<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, 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> >&);
-template bool igl::copyleft::cgal::mesh_boolean<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 39
include/igl/copyleft/cgal/mesh_boolean_type_to_funcs.cpp

@@ -1,39 +0,0 @@
-#include "mesh_boolean_type_to_funcs.h"
-#include "BinaryWindingNumberOperations.h"
-
-IGL_INLINE void igl::copyleft::cgal::mesh_boolean_type_to_funcs(
-  const MeshBooleanType & type,
-  std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
-  std::function<int(const int, const int)> & keep)
-{
-  switch (type) 
-  {
-    case MESH_BOOLEAN_TYPE_UNION:
-      wind_num_op = BinaryUnion();
-      keep = KeepInside();
-      return;
-    case MESH_BOOLEAN_TYPE_INTERSECT:
-      wind_num_op = BinaryIntersect();
-      keep = KeepInside();
-      return;
-    case MESH_BOOLEAN_TYPE_MINUS:
-      wind_num_op = BinaryMinus();
-      keep = KeepInside();
-      return;
-    case MESH_BOOLEAN_TYPE_XOR:
-      wind_num_op = BinaryXor();
-      keep = KeepInside();
-      return;
-    case MESH_BOOLEAN_TYPE_RESOLVE:
-      wind_num_op = BinaryResolve();
-      keep = KeepAll();
-      return;
-    default:
-      assert(false && "Unsupported boolean type.");
-      return;
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#endif

+ 0 - 81
include/igl/copyleft/cgal/mesh_to_cgal_triangle_list.cpp

@@ -1,81 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2014 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "mesh_to_cgal_triangle_list.h"
-#include "assign.h"
-#include "../../parallel_for.h"
-#include "../../get_seconds.h"
-
-#include <cassert>
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Kernel>
-IGL_INLINE void igl::copyleft::cgal::mesh_to_cgal_triangle_list(
-  const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixBase<DerivedF> & F,
-  std::vector<CGAL::Triangle_3<Kernel> > & T)
-{
-  const auto & tictoc = []()
-  {
-    static double t_start = igl::get_seconds();
-    double diff = igl::get_seconds()-t_start;
-    t_start += diff;
-    return diff;
-  };
-  tictoc();
-  typedef CGAL::Point_3<Kernel>    Point_3;
-  typedef CGAL::Triangle_3<Kernel> Triangle_3; 
-  // Must be 3D
-  assert(V.cols() == 3);
-  // **Copy** to convert to output type (this is especially/only needed if the
-  // input type DerivedV::Scalar is CGAL::Epeck
-  Eigen::Matrix<
-    typename Kernel::FT,
-    DerivedV::RowsAtCompileTime,
-    DerivedV::ColsAtCompileTime> 
-    KV(V.rows(),V.cols());
-  assign(V,KV);
-  // Must be triangles
-  assert(F.cols() == 3);
-  T.resize(F.rows());
-  igl::parallel_for(F.rows(),[&](const Eigen::Index f)
-  {
-    T[f] = 
-      Triangle_3(
-        Point_3( KV(F(f,0),0), KV(F(f,0),1), KV(F(f,0),2)),
-        Point_3( KV(F(f,1),0), KV(F(f,1),1), KV(F(f,1),2)),
-        Point_3( KV(F(f,2),0), KV(F(f,2),1), KV(F(f,2),2)));
-  },1000);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Simple_cartesian<double> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Simple_cartesian<double> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
-template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-#endif

+ 0 - 58
include/igl/copyleft/cgal/mesh_to_polyhedron.cpp

@@ -1,58 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "mesh_to_polyhedron.h"
-#include <CGAL/Polyhedron_3.h>
-#include <CGAL/Polyhedron_incremental_builder_3.h>
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Polyhedron>
-IGL_INLINE bool igl::copyleft::cgal::mesh_to_polyhedron(
-  const Eigen::MatrixBase<DerivedV>& V, 
-  const Eigen::MatrixBase<DerivedF>& F,
-  Polyhedron& poly) 
-{
-  typedef typename Polyhedron::HalfedgeDS HalfedgeDS;
-  // Postcondition: hds is a valid polyhedral surface.
-  CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> B(poly.hds());
-  B.begin_surface(V.rows(),F.rows());
-  typedef typename HalfedgeDS::Vertex   Vertex;
-  typedef typename Vertex::Point Point;
-  assert(V.cols() == 3 && "V must be #V by 3");
-  for(int v = 0;v<V.rows();v++)
-  {
-    B.add_vertex(Point(V(v,0),V(v,1),V(v,2)));
-  }
-  assert(F.cols() == 3 && "F must be #F by 3");
-  for(int f=0;f<F.rows();f++)
-  {
-    B.begin_facet();
-    for(int c = 0;c<3;c++)
-    {
-      B.add_vertex_to_facet(F(f,c));
-    }
-    B.end_facet();
-  }
-  if(B.error())
-  {
-    B.rollback();
-    return false;
-  }
-  B.end_surface();
-  return poly.is_valid();
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#include <CGAL/Simple_cartesian.h>
-#include <CGAL/Polyhedron_items_with_id_3.h>
-#include <CGAL/Polyhedron_3.h>
-// generated by autoexplicit.sh
-template bool igl::copyleft::cgal::mesh_to_polyhedron<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >&);
-#endif

+ 0 - 387
include/igl/copyleft/cgal/minkowski_sum.cpp

@@ -1,387 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Alec Jacobson <[email protected]>
-// 
-// 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/.
-#include "minkowski_sum.h"
-#include "mesh_boolean.h"
-
-#include "../../slice.h"
-#include "../../slice_mask.h"
-#include "../../LinSpaced.h"
-#include "../../unique_rows.h"
-#include "../../get_seconds.h"
-#include "../../edges.h"
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <cassert>
-#include <vector>
-#include <iostream>
-
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename DerivedW,
-  typename DerivedG,
-  typename DerivedJ>
-IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
-  const Eigen::MatrixBase<DerivedVA> & VA,
-  const Eigen::MatrixBase<DerivedFA> & FA,
-  const Eigen::MatrixBase<DerivedVB> & VB,
-  const Eigen::MatrixBase<DerivedFB> & FB,
-  const bool resolve_overlaps,
-  Eigen::PlainObjectBase<DerivedW> & W,
-  Eigen::PlainObjectBase<DerivedG> & G,
-  Eigen::PlainObjectBase<DerivedJ> & J)
-{
-  using namespace std;
-  using namespace Eigen;
-  assert(FA.cols() == 3 && "FA must contain a closed triangle mesh");
-  assert(FB.cols() <= FA.cols() && 
-    "FB must contain lower diemnsional simplices than FA");
-  const auto tictoc = []()->double
-  {
-    static double t_start;
-    double now = igl::get_seconds();
-    double interval = now-t_start;
-    t_start = now;
-    return interval;
-  };
-  tictoc();
-  Matrix<typename DerivedFB::Scalar,Dynamic,2> EB;
-  edges(FB,EB);
-  Matrix<typename DerivedFA::Scalar,Dynamic,2> EA(0,2);
-  if(FB.cols() == 3)
-  {
-    edges(FA,EA);
-  }
-  // number of copies of A along edges of B
-  const int n_ab = EB.rows();
-  // number of copies of B along edges of A
-  const int n_ba = EA.rows();
-
-  vector<DerivedW> vW(n_ab + n_ba);
-  vector<DerivedG> vG(n_ab + n_ba);
-  vector<DerivedJ> vJ(n_ab + n_ba);
-  vector<int> offsets(n_ab + n_ba + 1);
-  offsets[0] = 0;
-  // sweep A along edges of B
-  for(int e = 0;e<n_ab;e++)
-  {
-    Matrix<typename DerivedJ::Scalar,Dynamic,1> eJ;
-    minkowski_sum(
-      VA,
-      FA,
-      VB.row(EB(e,0)).eval(),
-      VB.row(EB(e,1)).eval(),
-      false,
-      vW[e],
-      vG[e],
-      eJ);
-    assert(vG[e].rows() == eJ.rows());
-    assert(eJ.cols() == 1);
-    vJ[e].resize(vG[e].rows(),2);
-    vJ[e].col(0) = eJ;
-    vJ[e].col(1).setConstant(e);
-    offsets[e+1] = offsets[e] + vW[e].rows();
-  }
-  // sweep B along edges of A
-  for(int e = 0;e<n_ba;e++)
-  {
-    Matrix<typename DerivedJ::Scalar,Dynamic,1> eJ;
-    const int ee = n_ab+e;
-    minkowski_sum(
-      VB,
-      FB,
-      VA.row(EA(e,0)).eval(),
-      VA.row(EA(e,1)).eval(),
-      false,
-      vW[ee],
-      vG[ee],
-      eJ);
-    vJ[ee].resize(vG[ee].rows(),2);
-    vJ[ee].col(0) = eJ.array() + (FA.rows()+1);
-    vJ[ee].col(1).setConstant(ee);
-    offsets[ee+1] = offsets[ee] + vW[ee].rows();
-  }
-  // Combine meshes
-  int n=0,m=0;
-  for_each(vW.begin(),vW.end(),[&n](const DerivedW & w){n+=w.rows();});
-  for_each(vG.begin(),vG.end(),[&m](const DerivedG & g){m+=g.rows();});
-  assert(n == offsets.back());
-
-  W.resize(n,3);
-  G.resize(m,3);
-  J.resize(m,2);
-  {
-    int m_off = 0,n_off = 0;
-    for(int i = 0;i<vG.size();i++)
-    {
-      W.block(n_off,0,vW[i].rows(),3) = vW[i];
-      G.block(m_off,0,vG[i].rows(),3) = vG[i].array()+offsets[i];
-      J.block(m_off,0,vJ[i].rows(),2) = vJ[i];
-      n_off += vW[i].rows();
-      m_off += vG[i].rows();
-    }
-    assert(n == n_off);
-    assert(m == m_off);
-  }
-  if(resolve_overlaps)
-  {
-    Eigen::Matrix<typename DerivedJ::Scalar, Eigen::Dynamic,1> SJ;
-    mesh_boolean(
-      DerivedW(W),
-      DerivedG(G),
-      Matrix<typename DerivedW::Scalar,Dynamic,Dynamic>(),
-      Matrix<typename DerivedG::Scalar,Dynamic,Dynamic>(),
-      MESH_BOOLEAN_TYPE_UNION,
-      W,
-      G,
-      SJ);
-    slice(DerivedJ(J),SJ,1,J);
-  }
-}
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename sType, int sCols, int sOptions,
-  typename dType, int dCols, int dOptions,
-  typename DerivedW,
-  typename DerivedG,
-  typename DerivedJ>
-IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
-  const Eigen::MatrixBase<DerivedVA> & VA,
-  const Eigen::MatrixBase<DerivedFA> & FA,
-  const Eigen::Matrix<sType,1,sCols,sOptions> & s,
-  const Eigen::Matrix<dType,1,dCols,dOptions> & d,
-  const bool resolve_overlaps, 
-  Eigen::PlainObjectBase<DerivedW> & W,
-  Eigen::PlainObjectBase<DerivedG> & G,
-  Eigen::PlainObjectBase<DerivedJ> & J)
-{
-  using namespace Eigen;
-  using namespace std;
-  assert(s.cols() == 3 && "s should be a 3d point");
-  assert(d.cols() == 3 && "d should be a 3d point");
-  // silly base case
-  if(FA.size() == 0)
-  {
-    W.resize(0,3);
-    G.resize(0,3);
-    return;
-  }
-  const int dim = VA.cols();
-  assert(dim == 3 && "dim must be 3D");
-  assert(s.size() == 3 && "s must be 3D point");
-  assert(d.size() == 3 && "d must be 3D point");
-  // segment vector
-  const CGAL::Vector_3<CGAL::Epeck> v(d(0)-s(0),d(1)-s(1),d(2)-s(2));
-  // number of vertices
-  const int n = VA.rows();
-  // duplicate vertices at s and d, we'll remove unreferernced later
-  W.resize(2*n,dim);
-  for(int i = 0;i<n;i++)
-  {
-    for(int j = 0;j<dim;j++)
-    {
-      W  (i,j) = VA(i,j) + s(j);
-      W(i+n,j) = VA(i,j) + d(j);
-    }
-  }
-  // number of faces
-  const int m = FA.rows();
-  //// Mask whether positive dot product, or negative: because of exactly zero,
-  //// these are not necessarily complementary
-  // Nevermind, actually P = !N
-  Matrix<bool,Dynamic,1> P(m,1),N(m,1);
-  // loop over faces
-  int mp = 0,mn = 0;
-  for(int f = 0;f<m;f++)
-  {
-    const CGAL::Plane_3<CGAL::Epeck> plane(
-      CGAL::Point_3<CGAL::Epeck>(VA(FA(f,0),0),VA(FA(f,0),1),VA(FA(f,0),2)),
-      CGAL::Point_3<CGAL::Epeck>(VA(FA(f,1),0),VA(FA(f,1),1),VA(FA(f,1),2)),
-      CGAL::Point_3<CGAL::Epeck>(VA(FA(f,2),0),VA(FA(f,2),1),VA(FA(f,2),2)));
-    const auto normal = plane.orthogonal_vector();
-    const auto dt = normal * v;
-    if(dt > 0)
-    {
-      P(f) = true;
-      N(f) = false;
-      mp++;
-    }else
-    //}else if(dt < 0)
-    {
-      P(f) = false;
-      N(f) = true;
-      mn++;
-    //}else
-    //{
-    //  P(f) = false;
-    //  N(f) = false;
-    }
-  }
-
-  typedef Matrix<typename DerivedG::Scalar,Dynamic,Dynamic> MatrixXI;
-  typedef Matrix<typename DerivedG::Scalar,Dynamic,1> VectorXI;
-  MatrixXI GT(mp+mn,3);
-  GT<< slice_mask(FA,N,1), slice_mask((FA.array()+n).eval(),P,1);
-  // J indexes FA for parts at s and m+FA for parts at d
-  J.derived() = igl::LinSpaced<DerivedJ >(m,0,m-1);
-  DerivedJ JT(mp+mn);
-  JT << slice_mask(J,P,1), slice_mask(J,N,1);
-  JT.block(mp,0,mn,1).array()+=m;
-
-  // Original non-co-planar faces with positively oriented reversed
-  MatrixXI BA(mp+mn,3);
-  BA << slice_mask(FA,P,1).rowwise().reverse(), slice_mask(FA,N,1);
-  // Quads along **all** sides
-  MatrixXI GQ((mp+mn)*3,4);
-  GQ<< 
-    BA.col(1), BA.col(0), BA.col(0).array()+n, BA.col(1).array()+n,
-    BA.col(2), BA.col(1), BA.col(1).array()+n, BA.col(2).array()+n,
-    BA.col(0), BA.col(2), BA.col(2).array()+n, BA.col(0).array()+n;
-
-  MatrixXI uGQ;
-  VectorXI S,sI,sJ;
-  // Inputs:
-  //   F  #F by d list of polygons
-  // Outputs:
-  //   S  #uF list of signed incidences for each unique face
-  //  uF  #uF by d list of unique faces
-  //   I  #uF index vector so that uF = sort(F,2)(I,:)
-  //   J  #F index vector so that sort(F,2) = uF(J,:)
-  [](
-      const MatrixXI & F,
-      VectorXI & S,
-      MatrixXI & uF,
-      VectorXI & I,
-      VectorXI & J)
-  {
-    const int m = F.rows();
-    const int d = F.cols();
-    MatrixXI sF = F;
-    const auto MN = sF.rowwise().minCoeff().eval();
-    // rotate until smallest index is first
-    for(int p = 0;p<d;p++)
-    {
-      for(int f = 0;f<m;f++)
-      {
-        if(sF(f,0) != MN(f))
-        {
-          for(int r = 0;r<d-1;r++)
-          {
-            std::swap(sF(f,r),sF(f,r+1));
-          }
-        }
-      }
-    }
-    // swap orienation so that last index is greater than first
-    for(int f = 0;f<m;f++)
-    {
-      if(sF(f,d-1) < sF(f,1))
-      {
-        sF.block(f,1,1,d-1) = sF.block(f,1,1,d-1).reverse().eval();
-      }
-    }
-    Matrix<bool,Dynamic,1> M = Matrix<bool,Dynamic,1>::Zero(m,1);
-    {
-      VectorXI P = igl::LinSpaced<VectorXI >(d,0,d-1);
-      for(int p = 0;p<d;p++)
-      {
-        for(int f = 0;f<m;f++)
-        {
-          bool all = true;
-          for(int r = 0;r<d;r++)
-          {
-            all = all && (sF(f,P(r)) == F(f,r));
-          }
-          M(f) = M(f) || all;
-        }
-        for(int r = 0;r<d-1;r++)
-        {
-          std::swap(P(r),P(r+1));
-        }
-      }
-    }
-    unique_rows(sF,uF,I,J);
-    S = VectorXI::Zero(uF.rows(),1);
-    assert(m == J.rows());
-    for(int f = 0;f<m;f++)
-    {
-      S(J(f)) += M(f) ? 1 : -1;
-    }
-  }(MatrixXI(GQ),S,uGQ,sI,sJ);
-  assert(S.rows() == uGQ.rows());
-  const int nq = (S.array().abs()==2).count();
-  GQ.resize(nq,4);
-  {
-    int k = 0;
-    for(int q = 0;q<uGQ.rows();q++)
-    {
-      switch(S(q))
-      {
-        case -2:
-          GQ.row(k++) = uGQ.row(q).reverse().eval();
-          break;
-        case 2:
-          GQ.row(k++) = uGQ.row(q);
-          break;
-        default:
-        // do not add
-          break;
-      }
-    }
-    assert(nq == k);
-  }
-
-  G.resize(GT.rows()+2*GQ.rows(),3);
-  G<< 
-    GT,
-    GQ.col(0), GQ.col(1), GQ.col(2), 
-    GQ.col(0), GQ.col(2), GQ.col(3);
-  J.resize(JT.rows()+2*GQ.rows(),1);
-  J<<JT,DerivedJ::Constant(2*GQ.rows(),1,2*m+1);
-  if(resolve_overlaps)
-  {
-    Eigen::Matrix<typename DerivedJ::Scalar, Eigen::Dynamic,1> SJ;
-    mesh_boolean(
-      DerivedW(W),DerivedG(G),
-      Matrix<typename DerivedVA::Scalar,Dynamic,Dynamic>(),MatrixXI(),
-      MESH_BOOLEAN_TYPE_UNION,
-      W,G,SJ);
-    J.derived() = slice(DerivedJ(J),SJ,1);
-  }
-}
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename sType, int sCols, int sOptions,
-  typename dType, int dCols, int dOptions,
-  typename DerivedW,
-  typename DerivedG,
-  typename DerivedJ>
-IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
-  const Eigen::MatrixBase<DerivedVA> & VA,
-  const Eigen::MatrixBase<DerivedFA> & FA,
-  const Eigen::Matrix<sType,1,sCols,sOptions> & s,
-  const Eigen::Matrix<dType,1,dCols,dOptions> & d,
-  Eigen::PlainObjectBase<DerivedW> & W,
-  Eigen::PlainObjectBase<DerivedG> & G,
-  Eigen::PlainObjectBase<DerivedJ> & J)
-{
-  return minkowski_sum(VA,FA,s,d,true,W,G,J);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck::FT, 3, 1, CGAL::Epeck::FT, 3, 1, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> const&, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::minkowski_sum<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, bool, 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> >&);
-template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, 3, 1, double, 3, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, bool, 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> >&);
-#endif

+ 0 - 418
include/igl/copyleft/cgal/order_facets_around_edge.cpp

@@ -1,418 +0,0 @@
-#include "order_facets_around_edge.h"
-#include <Eigen/Geometry>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-#include <stdexcept>
-
-// adj_faces contains signed index starting from +- 1.
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedI >
-void igl::copyleft::cgal::order_facets_around_edge(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    size_t s,
-    size_t d, 
-    const std::vector<int>& adj_faces,
-    Eigen::PlainObjectBase<DerivedI>& order, bool debug)
-{
-  // Although we only need exact predicates in the algorithm,
-  // exact constructions are needed to avoid degeneracies due to
-  // casting to double.
-  typedef CGAL::Exact_predicates_exact_constructions_kernel K;
-  typedef K::Point_3 Point_3;
-  typedef K::Plane_3 Plane_3;
-
-  auto get_face_index = [&](int adj_f)->size_t
-  {
-    return abs(adj_f) - 1;
-  };
-
-  auto get_opposite_vertex = [&](size_t fid)->size_t
-  {
-    typedef typename DerivedF::Scalar Index;
-    if (F(fid, 0) != (Index)s && F(fid, 0) != (Index)d) return F(fid, 0);
-    if (F(fid, 1) != (Index)s && F(fid, 1) != (Index)d) return F(fid, 1);
-    if (F(fid, 2) != (Index)s && F(fid, 2) != (Index)d) return F(fid, 2);
-    assert(false);
-    return -1;
-  };
-
-  // Handle base cases
-  if (adj_faces.size() == 0) 
-  {
-    order.resize(0, 1);
-    return;
-  } else if (adj_faces.size() == 1)
-  {
-    order.resize(1, 1);
-    order(0, 0) = 0;
-    return;
-  } else if (adj_faces.size() == 2)
-  {
-    const size_t o1 = get_opposite_vertex(get_face_index(adj_faces[0]));
-    const size_t o2 = get_opposite_vertex(get_face_index(adj_faces[1]));
-    const Point_3 ps(V(s, 0), V(s, 1), V(s, 2));
-    const Point_3 pd(V(d, 0), V(d, 1), V(d, 2));
-    const Point_3 p1(V(o1, 0), V(o1, 1), V(o1, 2));
-    const Point_3 p2(V(o2, 0), V(o2, 1), V(o2, 2));
-    order.resize(2, 1);
-    switch (CGAL::orientation(ps, pd, p1, p2))
-    {
-      case CGAL::POSITIVE:
-        order(0, 0) = 1;
-        order(1, 0) = 0;
-        break;
-      case CGAL::NEGATIVE:
-        order(0, 0) = 0;
-        order(1, 0) = 1;
-        break;
-      case CGAL::COPLANAR:
-        {
-          switch (CGAL::coplanar_orientation(ps, pd, p1, p2)) {
-            case CGAL::POSITIVE:
-              // Duplicated face, use index to break tie.
-              order(0, 0) = adj_faces[0] < adj_faces[1] ? 0:1;
-              order(1, 0) = adj_faces[0] < adj_faces[1] ? 1:0;
-              break;
-            case CGAL::NEGATIVE:
-              // Coplanar faces, one on each side of the edge.
-              // It is equally valid to order them (0, 1) or (1, 0).
-              // I cannot think of any reason to prefer one to the
-              // other.  So just use (0, 1) ordering by default.
-              order(0, 0) = 0;
-              order(1, 0) = 1;
-              break;
-            case CGAL::COLLINEAR:
-              std::cerr << "Degenerated triangle detected." <<
-                std::endl;
-              assert(false);
-              break;
-            default:
-              assert(false);
-          }
-        }
-        break;
-      default:
-        assert(false);
-    }
-    return;
-  }
-
-  const size_t num_adj_faces = adj_faces.size();
-  const size_t o = get_opposite_vertex( get_face_index(adj_faces[0]));
-  const Point_3 p_s(V(s, 0), V(s, 1), V(s, 2));
-  const Point_3 p_d(V(d, 0), V(d, 1), V(d, 2));
-  const Point_3 p_o(V(o, 0), V(o, 1), V(o, 2));
-  const Plane_3 separator(p_s, p_d, p_o);
-  if (separator.is_degenerate()) {
-    throw std::runtime_error(
-        "Cannot order facets around edge due to degenerated facets");
-  }
-
-  std::vector<Point_3> opposite_vertices;
-  for (size_t i=0; i<num_adj_faces; i++)
-  {
-    const size_t o = get_opposite_vertex( get_face_index(adj_faces[i]));
-    opposite_vertices.emplace_back(
-        V(o, 0), V(o, 1), V(o, 2));
-  }
-
-  std::vector<int> positive_side;
-  std::vector<int> negative_side;
-  std::vector<int> tie_positive_oriented;
-  std::vector<int> tie_negative_oriented;
-
-  std::vector<size_t> positive_side_index;
-  std::vector<size_t> negative_side_index;
-  std::vector<size_t> tie_positive_oriented_index;
-  std::vector<size_t> tie_negative_oriented_index;
-
-  for (size_t i=0; i<num_adj_faces; i++)
-  {
-    const int f = adj_faces[i];
-    const Point_3& p_a = opposite_vertices[i];
-    auto orientation = separator.oriented_side(p_a);
-    switch (orientation) {
-      case CGAL::ON_POSITIVE_SIDE:
-        positive_side.push_back(f);
-        positive_side_index.push_back(i);
-        break;
-      case CGAL::ON_NEGATIVE_SIDE:
-        negative_side.push_back(f);
-        negative_side_index.push_back(i);
-        break;
-      case CGAL::ON_ORIENTED_BOUNDARY:
-        {
-          auto inplane_orientation = CGAL::coplanar_orientation(
-              p_s, p_d, p_o, p_a);
-          switch (inplane_orientation) {
-            case CGAL::POSITIVE:
-              tie_positive_oriented.push_back(f);
-              tie_positive_oriented_index.push_back(i);
-              break;
-            case CGAL::NEGATIVE:
-              tie_negative_oriented.push_back(f);
-              tie_negative_oriented_index.push_back(i);
-              break;
-            case CGAL::COLLINEAR:
-            default:
-              throw std::runtime_error(
-                  "Degenerated facet detected.");
-              break;
-          }
-        }
-        break;
-      default:
-        // Should not be here.
-        throw std::runtime_error("Unknown CGAL state detected.");
-    }
-  }
-  if (debug) {
-    std::cout << "tie positive: " << std::endl;
-    for (auto& f : tie_positive_oriented) {
-      std::cout << get_face_index(f) << " ";
-    }
-    std::cout << std::endl;
-    std::cout << "positive side: " << std::endl;
-    for (auto& f : positive_side) {
-      std::cout << get_face_index(f) << " ";
-    }
-    std::cout << std::endl;
-    std::cout << "tie negative: " << std::endl;
-    for (auto& f : tie_negative_oriented) {
-      std::cout << get_face_index(f) << " ";
-    }
-    std::cout << std::endl;
-    std::cout << "negative side: " << std::endl;
-    for (auto& f : negative_side) {
-      std::cout << get_face_index(f) << " ";
-    }
-    std::cout << std::endl;
-  }
-
-  auto index_sort = [](std::vector<int>& data) -> std::vector<size_t>{
-    const size_t len = data.size();
-    std::vector<size_t> order(len);
-    for (size_t i=0; i<len; i++) { order[i] = i; }
-    auto comp = [&](size_t i, size_t j) { return data[i] < data[j]; };
-    std::sort(order.begin(), order.end(), comp);
-    return order;
-  };
-
-  DerivedI positive_order, negative_order;
-  order_facets_around_edge(V, F, s, d, positive_side, positive_order, debug);
-  order_facets_around_edge(V, F, s, d, negative_side, negative_order, debug);
-  std::vector<size_t> tie_positive_order = index_sort(tie_positive_oriented);
-  std::vector<size_t> tie_negative_order = index_sort(tie_negative_oriented);
-
-  // Copy results into order vector.
-  const size_t tie_positive_size = tie_positive_oriented.size();
-  const size_t tie_negative_size = tie_negative_oriented.size();
-  const size_t positive_size = positive_order.size();
-  const size_t negative_size = negative_order.size();
-
-  order.resize(
-      tie_positive_size + positive_size + tie_negative_size + negative_size,1);
-
-  size_t count=0;
-  for (size_t i=0; i<tie_positive_size; i++)
-  {
-    order(count+i, 0) = tie_positive_oriented_index[tie_positive_order[i]];
-  }
-  count += tie_positive_size;
-
-  for (size_t i=0; i<negative_size; i++) 
-  {
-    order(count+i, 0) = negative_side_index[negative_order(i, 0)];
-  }
-  count += negative_size;
-
-  for (size_t i=0; i<tie_negative_size; i++)
-  {
-    order(count+i, 0) = tie_negative_oriented_index[tie_negative_order[i]];
-  }
-  count += tie_negative_size;
-
-  for (size_t i=0; i<positive_size; i++)
-  {
-    order(count+i, 0) = positive_side_index[positive_order(i, 0)];
-  }
-  count += positive_size;
-  assert(count == num_adj_faces);
-
-  // Find the correct start point.
-  size_t start_idx = 0;
-  for (size_t i=0; i<num_adj_faces; i++)
-  {
-    const Point_3& p_a = opposite_vertices[order(i, 0)];
-    const Point_3& p_b =
-      opposite_vertices[order((i+1)%num_adj_faces, 0)];
-    auto orientation = CGAL::orientation(p_s, p_d, p_a, p_b);
-    if (orientation == CGAL::POSITIVE)
-    {
-      // Angle between triangle (p_s, p_d, p_a) and (p_s, p_d, p_b) is
-      // more than 180 degrees.
-      start_idx = (i+1)%num_adj_faces;
-      break;
-    } else if (orientation == CGAL::COPLANAR &&
-        Plane_3(p_s, p_d, p_a).orthogonal_direction() !=
-        Plane_3(p_s, p_d, p_b).orthogonal_direction())
-    {
-      // All 4 points are coplanar, but p_a and p_b are on each side of
-      // the edge (p_s, p_d).  This means the angle between triangle
-      // (p_s, p_d, p_a) and (p_s, p_d, p_b) is exactly 180 degrees.
-      start_idx = (i+1)%num_adj_faces;
-      break;
-    }
-  }
-  DerivedI circular_order = order;
-  for (size_t i=0; i<num_adj_faces; i++)
-  {
-    order(i, 0) = circular_order((start_idx + i)%num_adj_faces, 0);
-  }
-}
-
-template<
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedI>
-IGL_INLINE
-void igl::copyleft::cgal::order_facets_around_edge(
-  const Eigen::PlainObjectBase<DerivedV>& V,
-  const Eigen::PlainObjectBase<DerivedF>& F,
-  size_t s,
-  size_t d, 
-  const std::vector<int>& adj_faces,
-  const Eigen::PlainObjectBase<DerivedV>& pivot_point,
-  Eigen::PlainObjectBase<DerivedI>& order)
-{
-  assert(V.cols() == 3);
-  assert(F.cols() == 3);
-  assert(pivot_point.cols() == 3);
-  auto signed_index_to_index = [&](int signed_idx)
-  {
-      return abs(signed_idx) -1;
-  };
-  auto get_opposite_vertex_index = [&](size_t fid) -> typename DerivedF::Scalar
-  {
-      typedef typename DerivedF::Scalar Index;
-      if (F(fid, 0) != (Index)s && F(fid, 0) != (Index)d) return F(fid, 0);
-      if (F(fid, 1) != (Index)s && F(fid, 1) != (Index)d) return F(fid, 1);
-      if (F(fid, 2) != (Index)s && F(fid, 2) != (Index)d) return F(fid, 2);
-      assert(false);
-      // avoid warning
-      return -1;
-  };
-
-  {
-    // Check if s, d and pivot are collinear.
-    typedef CGAL::Exact_predicates_exact_constructions_kernel K;
-    K::Point_3 ps(V(s,0), V(s,1), V(s,2));
-    K::Point_3 pd(V(d,0), V(d,1), V(d,2));
-    K::Point_3 pp(pivot_point(0,0), pivot_point(0,1), pivot_point(0,2));
-    if (CGAL::collinear(ps, pd, pp)) {
-        throw std::runtime_error(
-                "Pivot point is collinear with the outer edge!");
-    }
-  }
-
-  const size_t N = adj_faces.size();
-  const size_t num_faces = N + 1; // N adj faces + 1 pivot face
-
-  // Because face indices are used for tie breaking, the original face indices
-  // in the new faces array must be ascending.
-  auto comp = [&](int i, int j) 
-  {
-    return signed_index_to_index(adj_faces[i]) <
-      signed_index_to_index(adj_faces[j]);
-  };
-  std::vector<size_t> adj_order(N);
-  for (size_t i=0; i<N; i++) adj_order[i] = i;
-  std::sort(adj_order.begin(), adj_order.end(), comp);
-
-  DerivedV vertices(num_faces + 2, 3);
-  for (size_t i=0; i<N; i++) 
-  {
-    const size_t fid = signed_index_to_index(adj_faces[adj_order[i]]);
-    vertices.row(i) = V.row(get_opposite_vertex_index(fid));
-  }
-  vertices.row(N  ) = pivot_point;
-  vertices.row(N+1) = V.row(s);
-  vertices.row(N+2) = V.row(d);
-
-  DerivedF faces(num_faces, 3);
-  for (size_t i=0; i<N; i++)
-  {
-    if (adj_faces[adj_order[i]] < 0) 
-    {
-      faces(i,0) = N+1; // s
-      faces(i,1) = N+2; // d
-      faces(i,2) = i  ;
-    } else 
-    {
-      faces(i,0) = N+2; // d
-      faces(i,1) = N+1; // s
-      faces(i,2) = i  ;
-    }
-  }
-  // Last face is the pivot face.
-  faces(N, 0) = N+1;
-  faces(N, 1) = N+2;
-  faces(N, 2) = N;
-
-  std::vector<int> adj_faces_with_pivot(num_faces);
-  for (size_t i=0; i<num_faces; i++)
-  {
-    if ((size_t)faces(i,0) == N+1 && (size_t)faces(i,1) == N+2)
-    {
-        adj_faces_with_pivot[i] = int(i+1) * -1;
-    } else
-    {
-        adj_faces_with_pivot[i] = int(i+1);
-    }
-  }
-
-  DerivedI order_with_pivot;
-  order_facets_around_edge(
-    vertices, faces, N+1, N+2, adj_faces_with_pivot, order_with_pivot);
-
-  assert((size_t)order_with_pivot.size() == num_faces);
-  order.resize(N);
-  size_t pivot_index = num_faces + 1;
-  for (size_t i=0; i<num_faces; i++)
-  {
-    if ((size_t)order_with_pivot[i] == N)
-    {
-      pivot_index = i;
-      break;
-    }
-  }
-  assert(pivot_index < num_faces);
-
-  for (size_t i=0; i<N; i++)
-  {
-    order[i] = adj_order[order_with_pivot[(pivot_index+i+1)%num_faces]];
-  }
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#include <cstdint>
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -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<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -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<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
-template void igl::copyleft::cgal::order_facets_around_edge<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::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::order_facets_around_edge<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::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, size_t, size_t, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 333
include/igl/copyleft/cgal/order_facets_around_edges.cpp

@@ -1,333 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "order_facets_around_edges.h"
-#include "order_facets_around_edge.h"
-#include "../../sort_angles.h"
-#include <Eigen/Geometry>
-#include <type_traits>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-template<
-    typename DerivedV,
-    typename DerivedF,
-    typename DerivedN,
-    typename DeriveduE,
-    typename uE2EType,
-    typename uE2oEType,
-    typename uE2CType >
-IGL_INLINE
-typename std::enable_if<!std::is_same<typename DerivedV::Scalar,
-typename CGAL::Exact_predicates_exact_constructions_kernel::FT>::value, void>::type
-igl::copyleft::cgal::order_facets_around_edges(
-        const Eigen::PlainObjectBase<DerivedV>& V,
-        const Eigen::PlainObjectBase<DerivedF>& F,
-        const Eigen::PlainObjectBase<DerivedN>& N,
-        const Eigen::PlainObjectBase<DeriveduE>& uE,
-        const std::vector<std::vector<uE2EType> >& uE2E,
-        std::vector<std::vector<uE2oEType> >& uE2oE,
-        std::vector<std::vector<uE2CType > >& uE2C ) {
-
-    typedef Eigen::Matrix<typename DerivedN::Scalar, 3, 1> Vector3F;
-    const typename DerivedV::Scalar EPS = 1e-12;
-    const size_t num_faces = F.rows();
-    const size_t num_undirected_edges = uE.rows();
-
-    auto edge_index_to_face_index = [&](size_t ei) { return ei % num_faces; };
-    auto edge_index_to_corner_index = [&](size_t ei) { return ei / num_faces; };
-
-    uE2oE.resize(num_undirected_edges);
-    uE2C.resize(num_undirected_edges);
-
-    for(size_t ui = 0;ui<num_undirected_edges;ui++)
-    {
-        const auto& adj_edges = uE2E[ui];
-        const size_t edge_valance = adj_edges.size();
-        assert(edge_valance > 0);
-
-        const auto ref_edge = adj_edges[0];
-        const auto ref_face = edge_index_to_face_index(ref_edge);
-        Vector3F ref_normal = N.row(ref_face);
-
-        const auto ref_corner_o = edge_index_to_corner_index(ref_edge);
-        const auto ref_corner_s = (ref_corner_o+1)%3;
-        const auto ref_corner_d = (ref_corner_o+2)%3;
-
-        const typename DerivedF::Scalar o = F(ref_face, ref_corner_o);
-        const typename DerivedF::Scalar s = F(ref_face, ref_corner_s);
-        const typename DerivedF::Scalar d = F(ref_face, ref_corner_d);
-
-        Vector3F edge = V.row(d) - V.row(s);
-        auto edge_len = edge.norm();
-        bool degenerated = edge_len < EPS;
-        if (degenerated) {
-            if (edge_valance <= 2) {
-                // There is only one way to order 2 or less faces.
-                edge.setZero();
-            } else {
-                edge.setZero();
-                Eigen::Matrix<typename DerivedN::Scalar, Eigen::Dynamic, 3>
-                    normals(edge_valance, 3);
-                for (size_t fei=0; fei<edge_valance; fei++) {
-                    const auto fe = adj_edges[fei];
-                    const auto f = edge_index_to_face_index(fe);
-                    normals.row(fei) = N.row(f);
-                }
-                for (size_t i=0; i<edge_valance; i++) {
-                    size_t j = (i+1) % edge_valance;
-                    Vector3F ni = normals.row(i);
-                    Vector3F nj = normals.row(j);
-                    edge = ni.cross(nj);
-                    edge_len = edge.norm();
-                    if (edge_len >= EPS) {
-                        edge.normalize();
-                        break;
-                    }
-                }
-
-                // Ensure edge direction are consistent with reference face.
-                Vector3F in_face_vec = V.row(o) - V.row(s);
-                if (edge.cross(in_face_vec).dot(ref_normal) < 0) {
-                    edge *= -1;
-                }
-
-                if (edge.norm() < EPS) {
-                    std::cerr << "=====================================" << std::endl;
-                    std::cerr << "  ui: " << ui << std::endl;
-                    std::cerr << "edge: " << ref_edge << std::endl;
-                    std::cerr << "face: " << ref_face << std::endl;
-                    std::cerr << "  vs: " << V.row(s) << std::endl;
-                    std::cerr << "  vd: " << V.row(d) << std::endl;
-                    std::cerr << "adj face normals: " << std::endl;
-                    std::cerr << normals << std::endl;
-                    std::cerr << "Very degenerated case detected:" << std::endl;
-                    std::cerr << "Near zero edge surrounded by "
-                        << edge_valance << " neearly colinear faces" <<
-                        std::endl;
-                    std::cerr << "=====================================" << std::endl;
-                }
-            }
-        } else {
-            edge.normalize();
-        }
-
-        Eigen::MatrixXd angle_data(edge_valance, 3);
-        std::vector<bool> cons(edge_valance);
-
-        for (size_t fei=0; fei<edge_valance; fei++) {
-            const auto fe = adj_edges[fei];
-            const auto f = edge_index_to_face_index(fe);
-            const auto c = edge_index_to_corner_index(fe);
-            cons[fei] = (d == F(f, (c+1)%3));
-            assert( cons[fei] ||  (d == F(f,(c+2)%3)));
-            assert(!cons[fei] || (s == F(f,(c+2)%3)));
-            assert(!cons[fei] || (d == F(f,(c+1)%3)));
-            Vector3F n = N.row(f);
-            angle_data(fei, 0) = ref_normal.cross(n).dot(edge);
-            angle_data(fei, 1) = ref_normal.dot(n);
-            if (cons[fei]) {
-                angle_data(fei, 0) *= -1;
-                angle_data(fei, 1) *= -1;
-            }
-            angle_data(fei, 0) *= -1; // Sort clockwise.
-            angle_data(fei, 2) = (cons[fei]?1.:-1.)*(f+1);
-        }
-
-        Eigen::VectorXi order;
-        igl::sort_angles(angle_data, order);
-
-        auto& ordered_edges = uE2oE[ui];
-        auto& consistency = uE2C[ui];
-
-        ordered_edges.resize(edge_valance);
-        consistency.resize(edge_valance);
-        for (size_t fei=0; fei<edge_valance; fei++) {
-            ordered_edges[fei] = adj_edges[order[fei]];
-            consistency[fei] = cons[order[fei]];
-        }
-    }
-}
-
-template<
-    typename DerivedV,
-    typename DerivedF,
-    typename DerivedN,
-    typename DeriveduE,
-    typename uE2EType,
-    typename uE2oEType,
-    typename uE2CType >
-IGL_INLINE
-typename std::enable_if<std::is_same<typename DerivedV::Scalar,
-typename CGAL::Exact_predicates_exact_constructions_kernel::FT>::value, void>::type
-igl::copyleft::cgal::order_facets_around_edges(
-        const Eigen::PlainObjectBase<DerivedV>& V,
-        const Eigen::PlainObjectBase<DerivedF>& F,
-        const Eigen::PlainObjectBase<DerivedN>& N,
-        const Eigen::PlainObjectBase<DeriveduE>& uE,
-        const std::vector<std::vector<uE2EType> >& uE2E,
-        std::vector<std::vector<uE2oEType> >& uE2oE,
-        std::vector<std::vector<uE2CType > >& uE2C ) {
-
-    typedef Eigen::Matrix<typename DerivedN::Scalar, 3, 1> Vector3F;
-    typedef Eigen::Matrix<typename DerivedV::Scalar, 3, 1> Vector3E;
-    const typename DerivedV::Scalar EPS = 1e-12;
-    const size_t num_faces = F.rows();
-    const size_t num_undirected_edges = uE.rows();
-
-    auto edge_index_to_face_index = [&](size_t ei) { return ei % num_faces; };
-    auto edge_index_to_corner_index = [&](size_t ei) { return ei / num_faces; };
-
-    uE2oE.resize(num_undirected_edges);
-    uE2C.resize(num_undirected_edges);
-
-    for(size_t ui = 0;ui<num_undirected_edges;ui++)
-    {
-        const auto& adj_edges = uE2E[ui];
-        const size_t edge_valance = adj_edges.size();
-        assert(edge_valance > 0);
-
-        const auto ref_edge = adj_edges[0];
-        const auto ref_face = edge_index_to_face_index(ref_edge);
-        Vector3F ref_normal = N.row(ref_face);
-
-        const auto ref_corner_o = edge_index_to_corner_index(ref_edge);
-        const auto ref_corner_s = (ref_corner_o+1)%3;
-        const auto ref_corner_d = (ref_corner_o+2)%3;
-
-        const typename DerivedF::Scalar o = F(ref_face, ref_corner_o);
-        const typename DerivedF::Scalar s = F(ref_face, ref_corner_s);
-        const typename DerivedF::Scalar d = F(ref_face, ref_corner_d);
-
-        Vector3E exact_edge = V.row(d) - V.row(s);
-        exact_edge.array() /= exact_edge.squaredNorm();
-        Vector3F edge(
-                CGAL::to_double(exact_edge[0]),
-                CGAL::to_double(exact_edge[1]),
-                CGAL::to_double(exact_edge[2]));
-        edge.normalize();
-
-        Eigen::MatrixXd angle_data(edge_valance, 3);
-        std::vector<bool> cons(edge_valance);
-
-        for (size_t fei=0; fei<edge_valance; fei++) {
-            const auto fe = adj_edges[fei];
-            const auto f = edge_index_to_face_index(fe);
-            const auto c = edge_index_to_corner_index(fe);
-            cons[fei] = (d == F(f, (c+1)%3));
-            assert( cons[fei] ||  (d == F(f,(c+2)%3)));
-            assert(!cons[fei] || (s == F(f,(c+2)%3)));
-            assert(!cons[fei] || (d == F(f,(c+1)%3)));
-            Vector3F n = N.row(f);
-            angle_data(fei, 0) = ref_normal.cross(n).dot(edge);
-            angle_data(fei, 1) = ref_normal.dot(n);
-            if (cons[fei]) {
-                angle_data(fei, 0) *= -1;
-                angle_data(fei, 1) *= -1;
-            }
-            angle_data(fei, 0) *= -1; // Sort clockwise.
-            angle_data(fei, 2) = (cons[fei]?1.:-1.)*(f+1);
-        }
-
-        Eigen::VectorXi order;
-        igl::sort_angles(angle_data, order);
-
-        auto& ordered_edges = uE2oE[ui];
-        auto& consistency = uE2C[ui];
-
-        ordered_edges.resize(edge_valance);
-        consistency.resize(edge_valance);
-        for (size_t fei=0; fei<edge_valance; fei++) {
-            ordered_edges[fei] = adj_edges[order[fei]];
-            consistency[fei] = cons[order[fei]];
-        }
-    }
-}
-
-template<
-    typename DerivedV,
-    typename DerivedF,
-    typename DeriveduE,
-    typename uE2EType,
-    typename uE2oEType,
-    typename uE2CType >
-IGL_INLINE void igl::copyleft::cgal::order_facets_around_edges(
-        const Eigen::PlainObjectBase<DerivedV>& V,
-        const Eigen::PlainObjectBase<DerivedF>& F,
-        const Eigen::PlainObjectBase<DeriveduE>& uE,
-        const std::vector<std::vector<uE2EType> >& uE2E,
-        std::vector<std::vector<uE2oEType> >& uE2oE,
-        std::vector<std::vector<uE2CType > >& uE2C ) {
-
-    //typedef Eigen::Matrix<typename DerivedV::Scalar, 3, 1> Vector3E;
-    const size_t num_faces = F.rows();
-    const size_t num_undirected_edges = uE.rows();
-
-    auto edge_index_to_face_index = [&](size_t ei) { return ei % num_faces; };
-    auto edge_index_to_corner_index = [&](size_t ei) { return ei / num_faces; };
-
-    uE2oE.resize(num_undirected_edges);
-    uE2C.resize(num_undirected_edges);
-
-    for(size_t ui = 0;ui<num_undirected_edges;ui++)
-    {
-        const auto& adj_edges = uE2E[ui];
-        const size_t edge_valance = adj_edges.size();
-        assert(edge_valance > 0);
-
-        const auto ref_edge = adj_edges[0];
-        const auto ref_face = edge_index_to_face_index(ref_edge);
-
-        const auto ref_corner_o = edge_index_to_corner_index(ref_edge);
-        const auto ref_corner_s = (ref_corner_o+1)%3;
-        const auto ref_corner_d = (ref_corner_o+2)%3;
-
-        //const typename DerivedF::Scalar o = F(ref_face, ref_corner_o);
-        const typename DerivedF::Scalar s = F(ref_face, ref_corner_s);
-        const typename DerivedF::Scalar d = F(ref_face, ref_corner_d);
-
-        std::vector<bool> cons(edge_valance);
-        std::vector<int> adj_faces(edge_valance);
-        for (size_t fei=0; fei<edge_valance; fei++) {
-            const auto fe = adj_edges[fei];
-            const auto f = edge_index_to_face_index(fe);
-            const auto c = edge_index_to_corner_index(fe);
-            cons[fei] = (d == F(f, (c+1)%3));
-            adj_faces[fei] = (f+1) * (cons[fei] ? 1:-1);
-
-            assert( cons[fei] ||  (d == F(f,(c+2)%3)));
-            assert(!cons[fei] || (s == F(f,(c+2)%3)));
-            assert(!cons[fei] || (d == F(f,(c+1)%3)));
-        }
-
-        Eigen::VectorXi order;
-        order_facets_around_edge(V, F, s, d, adj_faces, order);
-        assert((size_t)order.size() == edge_valance);
-
-        auto& ordered_edges = uE2oE[ui];
-        auto& consistency = uE2C[ui];
-
-        ordered_edges.resize(edge_valance);
-        consistency.resize(edge_valance);
-        for (size_t fei=0; fei<edge_valance; fei++) {
-            ordered_edges[fei] = adj_edges[order[fei]];
-            consistency[fei] = cons[order[fei]];
-        }
-    }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#include <cstdint>
-template std::enable_if<!(std::is_same<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, CGAL::Epeck::FT >::value), void>::type igl::copyleft::cgal::order_facets_around_edges<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>, int, int, bool>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
-template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
-template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
-template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, int, bool>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
-template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
-template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 46
include/igl/copyleft/cgal/orient2D.cpp

@@ -1,46 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2016 Qingan Zhou <[email protected]>
-//
-// 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/.
-
-#include "orient2D.h"
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-
-template<typename Scalar>
-IGL_INLINE short igl::copyleft::cgal::orient2D(
-    const Scalar *pa,
-    const Scalar *pb,
-    const Scalar *pc)
-{
-  typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
-  typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
-  typedef typename std::conditional<std::is_same<Scalar, Epeck::FT>::value,
-          Epeck, Epick>::type Kernel;
-
-  switch(CGAL::orientation(
-        typename Kernel::Point_2(pa[0], pa[1]),
-        typename Kernel::Point_2(pb[0], pb[1]),
-        typename Kernel::Point_2(pc[0], pc[1])))
-  {
-    case CGAL::LEFT_TURN:
-      return 1;
-    case CGAL::RIGHT_TURN:
-      return -1;
-    case CGAL::COLLINEAR:
-      return 0;
-    default:
-      throw "Invalid orientation";
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template short igl::copyleft::cgal::orient2D<double>(double const*, double const*, double const*);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 39
include/igl/copyleft/cgal/orient3D.cpp

@@ -1,39 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2016 Qingan Zhou <[email protected]>
-// 
-// 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/.
-
-#include "orient3D.h"
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-
-template<typename Scalar>
-IGL_INLINE short igl::copyleft::cgal::orient3D(
-    const Scalar pa[3],
-    const Scalar pb[3],
-    const Scalar pc[3],
-    const Scalar pd[3])
-{
-  typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
-  typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
-  typedef typename std::conditional<std::is_same<Scalar, Epeck::FT>::value,
-          Epeck, Epick>::type Kernel;
-
-  switch(CGAL::orientation(
-        typename Kernel::Point_3(pa[0], pa[1], pa[2]),
-        typename Kernel::Point_3(pb[0], pb[1], pb[2]),
-        typename Kernel::Point_3(pc[0], pc[1], pc[2]),
-        typename Kernel::Point_3(pd[0], pd[1], pd[2]))) {
-    case CGAL::POSITIVE:
-      return 1;
-    case CGAL::NEGATIVE:
-      return -1;
-    case CGAL::COPLANAR:
-      return 0;
-    default:
-      throw "Invalid orientation";
-  }
-}

+ 0 - 159
include/igl/copyleft/cgal/outer_edge.cpp

@@ -1,159 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Qingnan Zhou <[email protected]>
-// Copyright (C) 2021 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "outer_edge.h"
-#include "outer_vertex.h"
-#include <iostream>
-#include <vector>
-
-template<
-    typename DerivedV,
-    typename DerivedF,
-    typename DerivedI,
-    typename IndexType,
-    typename DerivedA
-    >
-IGL_INLINE void igl::copyleft::cgal::outer_edge(
-        const Eigen::PlainObjectBase<DerivedV> & V,
-        const Eigen::PlainObjectBase<DerivedF> & F,
-        const Eigen::PlainObjectBase<DerivedI> & I,
-        IndexType & v1,
-        IndexType & v2,
-        Eigen::PlainObjectBase<DerivedA> & A) {
-    // Algorithm:
-    //    Find an outer vertex first.
-    //    Find the incident edge with largest abs slope when projected onto XY plane.
-    //    If there is a tie, check the signed slope and use the positive one.
-    //    If there is still a tie, break it using the projected slope onto ZX plane.
-    //    If there is still a tie, again check the signed slope and use the positive one.
-    //    If there is still a tie, then there are multiple overlapping edges,
-    //    which violates the precondition.
-    typedef typename DerivedV::Scalar Scalar;
-    typedef typename DerivedV::Index Index;
-    typedef typename Eigen::Matrix<Scalar, 3, 1> ScalarArray3;
-    typedef typename Eigen::Matrix<typename DerivedF::Scalar, 3, 1> IndexArray3;
-    const Index INVALID = std::numeric_limits<Index>::max();
-
-    Index outer_vid;
-    Eigen::Matrix<Index,Eigen::Dynamic,1> candidate_faces;
-    outer_vertex(V, F, I, outer_vid, candidate_faces);
-    const ScalarArray3& outer_v = V.row(outer_vid);
-    assert(candidate_faces.size() > 0);
-
-    auto get_vertex_index = [&](const IndexArray3& f, Index vid) -> Index
-    {
-        if (f[0] == vid) return 0;
-        if (f[1] == vid) return 1;
-        if (f[2] == vid) return 2;
-        assert(false);
-        return -1;
-    };
-
-    auto unsigned_value = [](Scalar v) -> Scalar {
-        if (v < 0) return v * -1;
-        else return v;
-    };
-
-    Scalar outer_slope_YX = 0;
-    Scalar outer_slope_ZX = 0;
-    Index outer_opp_vid = INVALID;
-    bool infinite_slope_detected = false;
-    std::vector<Index> incident_faces;
-    auto check_and_update_outer_edge = [&](Index opp_vid, Index fid) -> void {
-        if (opp_vid == outer_opp_vid)
-        {
-            incident_faces.push_back(fid);
-            return;
-        }
-
-        const ScalarArray3 opp_v = V.row(opp_vid);
-        if (!infinite_slope_detected && outer_v[0] != opp_v[0])
-        {
-            // Finite slope
-            const ScalarArray3 diff = opp_v - outer_v;
-            const Scalar slope_YX = diff[1] / diff[0];
-            const Scalar slope_ZX = diff[2] / diff[0];
-            const Scalar u_slope_YX = unsigned_value(slope_YX);
-            const Scalar u_slope_ZX = unsigned_value(slope_ZX);
-            bool update = false;
-            if (outer_opp_vid == INVALID) {
-                update = true;
-            } else {
-                const Scalar u_outer_slope_YX = unsigned_value(outer_slope_YX);
-                if (u_slope_YX > u_outer_slope_YX) {
-                    update = true;
-                } else if (u_slope_YX == u_outer_slope_YX &&
-                        slope_YX > outer_slope_YX) {
-                    update = true;
-                } else if (slope_YX == outer_slope_YX) {
-                    const Scalar u_outer_slope_ZX =
-                        unsigned_value(outer_slope_ZX);
-                    if (u_slope_ZX > u_outer_slope_ZX) {
-                        update = true;
-                    } else if (u_slope_ZX == u_outer_slope_ZX &&
-                            slope_ZX > outer_slope_ZX) {
-                        update = true;
-                    } else if (slope_ZX == u_outer_slope_ZX) {
-                        assert(false);
-                    }
-                }
-            }
-
-            if (update) {
-                outer_opp_vid = opp_vid;
-                outer_slope_YX = slope_YX;
-                outer_slope_ZX = slope_ZX;
-                incident_faces = {fid};
-            }
-        } else if (!infinite_slope_detected)
-        {
-            // Infinite slope
-            outer_opp_vid = opp_vid;
-            infinite_slope_detected = true;
-            incident_faces = {fid};
-        }
-    };
-
-    const size_t num_candidate_faces = candidate_faces.size();
-    for (size_t i=0; i<num_candidate_faces; i++)
-    {
-        const Index fid = candidate_faces(i);
-        const IndexArray3& f = F.row(fid);
-        size_t id = get_vertex_index(f, outer_vid);
-        Index next_vid = f((id+1)%3);
-        Index prev_vid = f((id+2)%3);
-        check_and_update_outer_edge(next_vid, fid);
-        check_and_update_outer_edge(prev_vid, fid);
-    }
-
-    v1 = outer_vid;
-    v2 = outer_opp_vid;
-    A.resize(incident_faces.size());
-    std::copy(incident_faces.begin(), incident_faces.end(), A.data());
-}
-
-
-
-#ifdef IGL_STATIC_LIBRARY
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-// Explicit template instantiation
-// generated by autoexplicit.sh
-#include <cstdint>
-template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
-template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
-template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-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&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
-template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-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&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
-template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<int,-1,3,0,-1,3>,Eigen::Matrix<int,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::PlainObjectBase<Eigen::Matrix<double,-1,3,0,-1,3> > const &,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,3,0,-1,3> > const &,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> > const &,std::ptrdiff_t &,std::ptrdiff_t &,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > &);
-template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<int,-1,3,0,-1,3>,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::PlainObjectBase<Eigen::Matrix<double,-1,3,0,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,3,0,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
-
-#ifdef WIN32
-template void __cdecl igl::copyleft::cgal::outer_edge<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<long,-1,1,0,-1,1>,std::ptrdiff_t,class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,std::ptrdiff_t &,std::ptrdiff_t &,class Eigen::PlainObjectBase<class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > &);
-template void __cdecl igl::copyleft::cgal::outer_edge<class Eigen::Matrix<double,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,3,0,-1,3>,class Eigen::Matrix<long,-1,1,0,-1,1>,std::ptrdiff_t,class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,3,0,-1,3> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,std::ptrdiff_t &,std::ptrdiff_t &,class Eigen::PlainObjectBase<class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > &);
-#endif
-#endif

+ 0 - 168
include/igl/copyleft/cgal/outer_facet.cpp

@@ -1,168 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Qingnan Zhou <[email protected]>
-//
-// 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/.
-
-#include "outer_facet.h"
-#include "outer_edge.h"
-#include "order_facets_around_edge.h"
-#include <algorithm>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-template<
-    typename DerivedV,
-    typename DerivedF,
-    typename DerivedI,
-    typename IndexType
-    >
-IGL_INLINE void igl::copyleft::cgal::outer_facet(
-        const Eigen::PlainObjectBase<DerivedV> & V,
-        const Eigen::PlainObjectBase<DerivedF> & F,
-        const Eigen::PlainObjectBase<DerivedI> & I,
-        IndexType & f,
-        bool & flipped) {
-
-    // Algorithm:
-    //
-    //    1. Find an outer edge (s, d).
-    //
-    //    2. Order adjacent facets around this edge. Because the edge is an
-    //    outer edge, there exists a plane passing through it such that all its
-    //    adjacent facets lie on the same side. The implementation of
-    //    order_facets_around_edge() will find a natural start facet such that
-    //    The first and last facets according to this order are on the outside.
-    //
-    //    3. Because the vertex s is an outer vertex by construction (see
-    //    implemnetation of outer_edge()). The first adjacent facet is facing
-    //    outside (i.e. flipped=false) if it has positive X normal component.
-    //    If it has zero normal component, it is facing outside if it contains
-    //    directed edge (s, d).
-
-    //typedef typename DerivedV::Scalar Scalar;
-    typedef typename DerivedV::Index Index;
-
-    Index s,d;
-    Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
-    outer_edge(V, F, I, s, d, incident_faces);
-    assert(incident_faces.size() > 0);
-
-    auto convert_to_signed_index = [&](size_t fid) -> int{
-        if ((F(fid, 0) == s && F(fid, 1) == d) ||
-            (F(fid, 1) == s && F(fid, 2) == d) ||
-            (F(fid, 2) == s && F(fid, 0) == d) ) {
-            return int(fid+1) * -1;
-        } else {
-            return int(fid+1);
-        }
-    };
-
-    auto signed_index_to_index = [&](int signed_id) -> size_t {
-        return size_t(abs(signed_id) - 1);
-    };
-
-    std::vector<int> adj_faces(incident_faces.size());
-    std::transform(incident_faces.data(),
-            incident_faces.data() + incident_faces.size(),
-            adj_faces.begin(),
-            convert_to_signed_index);
-
-    DerivedV pivot_point = V.row(s);
-    pivot_point(0, 0) += 1.0;
-
-    Eigen::VectorXi order;
-    order_facets_around_edge(V, F, s, d, adj_faces, pivot_point, order);
-
-    f = signed_index_to_index(adj_faces[order[0]]);
-    flipped = adj_faces[order[0]] > 0;
-}
-
-
-
-template<
-    typename DerivedV,
-    typename DerivedF,
-    typename DerivedN,
-    typename DerivedI,
-    typename IndexType
-    >
-IGL_INLINE void igl::copyleft::cgal::outer_facet(
-        const Eigen::PlainObjectBase<DerivedV> & V,
-        const Eigen::PlainObjectBase<DerivedF> & F,
-        const Eigen::PlainObjectBase<DerivedN> & N,
-        const Eigen::PlainObjectBase<DerivedI> & I,
-        IndexType & f,
-        bool & flipped) {
-    // Algorithm:
-    //    Find an outer edge.
-    //    Find the incident facet with the largest absolute X normal component.
-    //    If there is a tie, keep the one with positive X component.
-    //    If there is still a tie, pick the face with the larger signed index
-    //    (flipped face has negative index).
-    typedef typename DerivedV::Scalar Scalar;
-    typedef typename DerivedV::Index Index;
-    const size_t INVALID = std::numeric_limits<size_t>::max();
-
-    Index v1,v2;
-    Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
-    outer_edge(V, F, I, v1, v2, incident_faces);
-    assert(incident_faces.size() > 0);
-
-    auto generic_fabs = [&](const Scalar& val) -> const Scalar {
-        if (val >= 0) return val;
-        else return -val;
-    };
-
-    Scalar max_nx = 0;
-    size_t outer_fid = INVALID;
-    const size_t num_incident_faces = incident_faces.size();
-    for (size_t i=0; i<num_incident_faces; i++)
-    {
-        const auto& fid = incident_faces(i);
-        const Scalar nx = N(fid, 0);
-        if (outer_fid == INVALID) {
-            max_nx = nx;
-            outer_fid = fid;
-        } else {
-            if (generic_fabs(nx) > generic_fabs(max_nx)) {
-                max_nx = nx;
-                outer_fid = fid;
-            } else if (nx == -max_nx && nx > 0) {
-                max_nx = nx;
-                outer_fid = fid;
-            } else if (nx == max_nx) {
-                if ((max_nx >= 0 && outer_fid < fid) ||
-                    (max_nx <  0 && outer_fid > fid)) {
-                    max_nx = nx;
-                    outer_fid = fid;
-                }
-            }
-        }
-    }
-
-    assert(outer_fid != INVALID);
-    f = outer_fid;
-    flipped = max_nx < 0;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-// Explicit template instantiation
-// generated by autoexplicit.sh
-#include <cstdint>
-template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, bool&);
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
-template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Index>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Index &, bool&);
-template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
-template void igl::copyleft::cgal::outer_facet<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::Index>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Index&, bool&);
-template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int&, bool&);
-template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
-//template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
-//template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 109
include/igl/copyleft/cgal/outer_hull.cpp

@@ -1,109 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "outer_hull.h"
-#include "extract_cells.h"
-#include "remesh_self_intersections.h"
-#include "assign.h"
-#include "../../remove_unreferenced.h"
-
-#include <CGAL/AABB_tree.h>
-#include <CGAL/AABB_traits.h>
-#include <CGAL/AABB_triangle_primitive.h>
-#include <CGAL/intersections.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedHV,
-  typename DerivedHF,
-  typename DerivedJ,
-  typename Derivedflip>
-IGL_INLINE void igl::copyleft::cgal::outer_hull(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedHV> & HV,
-  Eigen::PlainObjectBase<DerivedHF> & HF,
-  Eigen::PlainObjectBase<DerivedJ> & J,
-  Eigen::PlainObjectBase<Derivedflip> & flip)
-{
-  // Exact types
-  typedef CGAL::Epeck Kernel;
-  typedef Kernel::FT ExactScalar;
-  typedef
-    Eigen::Matrix<
-    ExactScalar,
-    Eigen::Dynamic,
-    Eigen::Dynamic,
-    DerivedHV::IsRowMajor>
-      MatrixXES;
-  // Remesh self-intersections
-  MatrixXES Vr;
-  DerivedHF Fr;
-  DerivedJ Jr;
-  {
-    RemeshSelfIntersectionsParam params;
-    params.stitch_all = true;
-    Eigen::VectorXi I;
-    Eigen::MatrixXi IF;
-    remesh_self_intersections(V, F, params, Vr, Fr, IF, Jr, I);
-    // Merge coinciding vertices into non-manifold vertices.
-    std::for_each(Fr.data(), Fr.data()+Fr.size(),
-      [&I](typename DerivedHF::Scalar& a) { a=I[a]; });
-      // Remove unreferenced vertices.
-    Eigen::VectorXi UIM;
-    remove_unreferenced(MatrixXES(Vr),DerivedHF(Fr), Vr, Fr, UIM);
-  }
-  // Extract cells for each face
-  Eigen::MatrixXi C;
-  extract_cells(Vr,Fr,C);
-  // Extract faces on ambient cell
-  int num_outer = 0;
-  for(int i = 0;i<C.rows();i++)
-  {
-    num_outer += ( C(i,0) == 0 || C(i,1) == 0 ) ? 1 : 0;
-  }
-  HF.resize(num_outer,3);
-  J.resize(num_outer,1);
-  flip.resize(num_outer,1);
-  {
-    int h = 0;
-    for(int i = 0;i<C.rows();i++)
-    {
-      if(C(i,0)==0)
-      {
-        HF.row(h) = Fr.row(i);
-        J(h) = Jr(i);
-        flip(h) = false;
-        h++;
-      }else if(C(i,1) == 0)
-      {
-        HF.row(h) = Fr.row(i).reverse();
-        J(h) = Jr(i);
-        flip(h) = true;
-        h++;
-      }
-    }
-    assert(h == num_outer);
-  }
-  // Remove unreferenced vertices and re-index faces
-  {
-    // Cast to output type
-    DerivedHV Vr_cast;
-    assign(Vr,Vr_cast);
-    Eigen::VectorXi I;
-    remove_unreferenced(Vr_cast,DerivedHF(HF),HV,HF,I);
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::copyleft::cgal::outer_hull<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&, 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> >&);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 452
include/igl/copyleft/cgal/outer_hull_legacy.cpp

@@ -1,452 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "outer_hull_legacy.h"
-#include "extract_cells.h"
-#include "remesh_self_intersections.h"
-#include "assign.h"
-#include "../../remove_unreferenced.h"
-
-#include <CGAL/AABB_tree.h>
-#include <CGAL/AABB_traits.h>
-#include <CGAL/AABB_triangle_primitive.h>
-#include <CGAL/intersections.h>
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-
-#include "points_inside_component.h"
-#include "order_facets_around_edges.h"
-#include "outer_facet.h"
-#include "../../sortrows.h"
-#include "../../facet_components.h"
-#include "../../winding_number.h"
-#include "../../triangle_triangle_adjacency.h"
-#include "../../unique_edge_map.h"
-#include "../../barycenter.h"
-#include "../../per_face_normals.h"
-#include "../../sort_angles.h"
-#include <Eigen/Geometry>
-#include <vector>
-#include <map>
-#include <queue>
-#include <iostream>
-#include <type_traits>
-#include <CGAL/number_utils.h>
-//#define IGL_OUTER_HULL_DEBUG
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedG,
-  typename DerivedJ,
-  typename Derivedflip>
-IGL_INLINE void igl::copyleft::cgal::outer_hull_legacy(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedG> & G,
-  Eigen::PlainObjectBase<DerivedJ> & J,
-  Eigen::PlainObjectBase<Derivedflip> & flip)
-{
-#ifdef IGL_OUTER_HULL_DEBUG
-  std::cerr << "Extracting outer hull" << std::endl;
-#endif
-  using namespace Eigen;
-  using namespace std;
-  typedef typename DerivedF::Index Index;
-  Matrix<Index,DerivedF::RowsAtCompileTime,1> C;
-  typedef Matrix<typename DerivedV::Scalar,Dynamic,DerivedV::ColsAtCompileTime> MatrixXV;
-  //typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
-  typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
-  typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
-  const Index m = F.rows();
-
-  // UNUSED:
-  //const auto & duplicate_simplex = [&F](const int f, const int g)->bool
-  //{
-  //  return
-  //    (F(f,0) == F(g,0) && F(f,1) == F(g,1) && F(f,2) == F(g,2)) ||
-  //    (F(f,1) == F(g,0) && F(f,2) == F(g,1) && F(f,0) == F(g,2)) ||
-  //    (F(f,2) == F(g,0) && F(f,0) == F(g,1) && F(f,1) == F(g,2)) ||
-  //    (F(f,0) == F(g,2) && F(f,1) == F(g,1) && F(f,2) == F(g,0)) ||
-  //    (F(f,1) == F(g,2) && F(f,2) == F(g,1) && F(f,0) == F(g,0)) ||
-  //    (F(f,2) == F(g,2) && F(f,0) == F(g,1) && F(f,1) == F(g,0));
-  //};
-
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"outer hull..."<<endl;
-#endif
-
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"edge map..."<<endl;
-#endif
-  typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
-  typedef Matrix<typename DerivedF::Index,Dynamic,1> VectorXI;
-  //typedef Matrix<typename DerivedV::Scalar, 3, 1> Vector3F;
-  MatrixX2I E,uE;
-  VectorXI EMAP;
-  vector<vector<typename DerivedF::Index> > uE2E;
-  unique_edge_map(F,E,uE,EMAP,uE2E);
-#ifdef IGL_OUTER_HULL_DEBUG
-  for (size_t ui=0; ui<uE.rows(); ui++) {
-      std::cout << ui << ": " << uE2E[ui].size() << " -- (";
-      for (size_t i=0; i<uE2E[ui].size(); i++) {
-          std::cout << uE2E[ui][i] << ", ";
-      }
-      std::cout << ")" << std::endl;
-  }
-#endif
-
-  std::vector<std::vector<typename DerivedF::Index> > uE2oE;
-  std::vector<std::vector<bool> > uE2C;
-  order_facets_around_edges(V, F, uE, uE2E, uE2oE, uE2C);
-  uE2E = uE2oE;
-  VectorXI diIM(3*m);
-  for (auto ue : uE2E) {
-      for (size_t i=0; i<ue.size(); i++) {
-          auto fe = ue[i];
-          diIM[fe] = i;
-      }
-  }
-
-  vector<vector<vector<Index > > > TT,_1;
-  triangle_triangle_adjacency(E,EMAP,uE2E,false,TT,_1);
-  VectorXI counts;
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"facet components..."<<endl;
-#endif
-  facet_components(TT,C,counts);
-  assert(C.maxCoeff()+1 == counts.rows());
-  const size_t ncc = counts.rows();
-  G.resize(0,F.cols());
-  J.resize(0,1);
-  flip.setConstant(m,1,false);
-
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"reindex..."<<endl;
-#endif
-  // H contains list of faces on outer hull;
-  vector<bool> FH(m,false);
-  vector<bool> EH(3*m,false);
-  vector<MatrixXG> vG(ncc);
-  vector<MatrixXJ> vJ(ncc);
-  vector<MatrixXJ> vIM(ncc);
-  //size_t face_count = 0;
-  for(size_t id = 0;id<ncc;id++)
-  {
-    vIM[id].resize(counts[id],1);
-  }
-  // current index into each IM
-  vector<size_t> g(ncc,0);
-  // place order of each face in its respective component
-  for(Index f = 0;f<m;f++)
-  {
-    vIM[C(f)](g[C(f)]++) = f;
-  }
-
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"barycenters..."<<endl;
-#endif
-  // assumes that "resolve" has handled any coplanar cases correctly and nearly
-  // coplanar cases can be sorted based on barycenter.
-  MatrixXV BC;
-  barycenter(V,F,BC);
-
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"loop over CCs (="<<ncc<<")..."<<endl;
-#endif
-  for(Index id = 0;id<(Index)ncc;id++)
-  {
-    auto & IM = vIM[id];
-    // starting face that's guaranteed to be on the outer hull and in this
-    // component
-    int f;
-    bool f_flip;
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"outer facet..."<<endl;
-#endif
-  igl::copyleft::cgal::outer_facet(V,F,IM,f,f_flip);
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"outer facet: "<<f<<endl;
-  //cout << V.row(F(f, 0)) << std::endl;
-  //cout << V.row(F(f, 1)) << std::endl;
-  //cout << V.row(F(f, 2)) << std::endl;
-#endif
-    int FHcount = 1;
-    FH[f] = true;
-    // Q contains list of face edges to continue traversing upong
-    queue<int> Q;
-    Q.push(f+0*m);
-    Q.push(f+1*m);
-    Q.push(f+2*m);
-    flip(f) = f_flip;
-    //std::cout << "face " << face_count++ << ": " << f << std::endl;
-    //std::cout << "f " << F.row(f).array()+1 << std::endl;
-    //cout<<"flip("<<f<<") = "<<(flip(f)?"true":"false")<<endl;
-#ifdef IGL_OUTER_HULL_DEBUG
-  cout<<"BFS..."<<endl;
-#endif
-    while(!Q.empty())
-    {
-      // face-edge
-      const int e = Q.front();
-      Q.pop();
-      // face
-      const int f = e%m;
-      // corner
-      const int c = e/m;
-#ifdef IGL_OUTER_HULL_DEBUG
-      std::cout << "edge: " << e << ", ue: " << EMAP(e) << std::endl;
-      std::cout << "face: " << f << std::endl;
-      std::cout << "corner: " << c << std::endl;
-      std::cout << "consistent: " << uE2C[EMAP(e)][diIM[e]] << std::endl;
-#endif
-      // Should never see edge again...
-      if(EH[e] == true)
-      {
-        continue;
-      }
-      EH[e] = true;
-      // source of edge according to f
-      const int fs = flip(f)?F(f,(c+2)%3):F(f,(c+1)%3);
-      // destination of edge according to f
-      const int fd = flip(f)?F(f,(c+1)%3):F(f,(c+2)%3);
-      // edge valence
-      const size_t val = uE2E[EMAP(e)].size();
-#ifdef IGL_OUTER_HULL_DEBUG
-      //std::cout << "vd: " << V.row(fd) << std::endl;
-      //std::cout << "vs: " << V.row(fs) << std::endl;
-      //std::cout << "edge: " << V.row(fd) - V.row(fs) << std::endl;
-      for (size_t i=0; i<val; i++) {
-          if (i == diIM(e)) {
-              std::cout << "* ";
-          } else {
-              std::cout << "  ";
-          }
-          std::cout << i << ": "
-              << " (e: " << uE2E[EMAP(e)][i] << ", f: "
-              << uE2E[EMAP(e)][i] % m * (uE2C[EMAP(e)][i] ? 1:-1) << ")" << std::endl;
-      }
-#endif
-
-      // is edge consistent with edge of face used for sorting
-      const int e_cons = (uE2C[EMAP(e)][diIM(e)] ? 1: -1);
-      int nfei = -1;
-      // Loop once around trying to find suitable next face
-      for(size_t step = 1; step<val+2;step++)
-      {
-        const int nfei_new = (diIM(e) + 2*val + e_cons*step*(flip(f)?-1:1))%val;
-        const int nf = uE2E[EMAP(e)][nfei_new] % m;
-        {
-#ifdef IGL_OUTER_HULL_DEBUG
-        //cout<<"Next facet: "<<(f+1)<<" --> "<<(nf+1)<<", |"<<
-        //  di[EMAP(e)][diIM(e)]<<" - "<<di[EMAP(e)][nfei_new]<<"| = "<<
-        //    abs(di[EMAP(e)][diIM(e)] - di[EMAP(e)][nfei_new])
-        //    <<endl;
-#endif
-
-
-
-          // Only use this face if not already seen
-          if(!FH[nf])
-          {
-            nfei = nfei_new;
-          //} else {
-          //    std::cout << "skipping face " << nfei_new << " because it is seen before"
-          //        << std::endl;
-          }
-          break;
-        //} else {
-        //    std::cout << di[EMAP(e)][diIM(e)].transpose() << std::endl;
-        //    std::cout << di[EMAP(e)][diIM(nfei_new)].transpose() << std::endl;
-        //    std::cout << "skipping face " << nfei_new << " with identical dihedral angle"
-        //        << std::endl;
-        }
-//#ifdef IGL_OUTER_HULL_DEBUG
-//        cout<<"Skipping co-planar facet: "<<(f+1)<<" --> "<<(nf+1)<<endl;
-//#endif
-      }
-
-      int max_ne = -1;
-      if(nfei >= 0)
-      {
-        max_ne = uE2E[EMAP(e)][nfei];
-      }
-
-      if(max_ne>=0)
-      {
-        // face of neighbor
-        const int nf = max_ne%m;
-#ifdef IGL_OUTER_HULL_DEBUG
-        if(!FH[nf])
-        {
-          // first time seeing face
-          cout<<(f+1)<<" --> "<<(nf+1)<<endl;
-        }
-#endif
-        FH[nf] = true;
-        //std::cout << "face " << face_count++ << ": " << nf << std::endl;
-        //std::cout << "f " << F.row(nf).array()+1 << std::endl;
-        FHcount++;
-        // corner of neighbor
-        const int nc = max_ne/m;
-        const int nd = F(nf,(nc+2)%3);
-        const bool cons = (flip(f)?fd:fs) == nd;
-        flip(nf) = (cons ? flip(f) : !flip(f));
-        //cout<<"flip("<<nf<<") = "<<(flip(nf)?"true":"false")<<endl;
-        const int ne1 = nf+((nc+1)%3)*m;
-        const int ne2 = nf+((nc+2)%3)*m;
-        if(!EH[ne1])
-        {
-          Q.push(ne1);
-        }
-        if(!EH[ne2])
-        {
-          Q.push(ne2);
-        }
-      }
-    }
-
-    {
-      vG[id].resize(FHcount,3);
-      vJ[id].resize(FHcount,1);
-      //nG += FHcount;
-      size_t h = 0;
-      assert(counts(id) == IM.rows());
-      for(int i = 0;i<counts(id);i++)
-      {
-        const size_t f = IM(i);
-        //if(f_flip)
-        //{
-        //  flip(f) = !flip(f);
-        //}
-        if(FH[f])
-        {
-          vG[id].row(h) = (flip(f)?F.row(f).reverse().eval():F.row(f));
-          vJ[id](h,0) = f;
-          h++;
-        }
-      }
-      assert((int)h == FHcount);
-    }
-  }
-
-  // Is A inside B? Assuming A and B are consistently oriented but closed and
-  // non-intersecting.
-  const auto & has_overlapping_bbox = [](
-    const Eigen::PlainObjectBase<DerivedV> & V,
-    const MatrixXG & A,
-    const MatrixXG & B)->bool
-  {
-    const auto & bounding_box = [](
-      const Eigen::PlainObjectBase<DerivedV> & V,
-      const MatrixXG & F)->
-        DerivedV
-    {
-      DerivedV BB(2,3);
-      BB<<
-         1e26,1e26,1e26,
-        -1e26,-1e26,-1e26;
-      const size_t m = F.rows();
-      for(size_t f = 0;f<m;f++)
-      {
-        for(size_t c = 0;c<3;c++)
-        {
-          const auto & vfc = V.row(F(f,c)).eval();
-          BB(0,0) = std::min(BB(0,0), vfc(0,0));
-          BB(0,1) = std::min(BB(0,1), vfc(0,1));
-          BB(0,2) = std::min(BB(0,2), vfc(0,2));
-          BB(1,0) = std::max(BB(1,0), vfc(0,0));
-          BB(1,1) = std::max(BB(1,1), vfc(0,1));
-          BB(1,2) = std::max(BB(1,2), vfc(0,2));
-        }
-      }
-      return BB;
-    };
-    // A lot of the time we're dealing with unrelated, distant components: cull
-    // them.
-    DerivedV ABB = bounding_box(V,A);
-    DerivedV BBB = bounding_box(V,B);
-    if( (BBB.row(0)-ABB.row(1)).maxCoeff()>0  ||
-        (ABB.row(0)-BBB.row(1)).maxCoeff()>0 )
-    {
-      // bounding boxes do not overlap
-      return false;
-    } else {
-      return true;
-    }
-  };
-
-  // Reject components which are completely inside other components
-  vector<bool> keep(ncc,true);
-  size_t nG = 0;
-  // This is O( ncc * ncc * m)
-  for(size_t id = 0;id<ncc;id++)
-  {
-    if (!keep[id]) continue;
-    std::vector<size_t> unresolved;
-    for(size_t oid = 0;oid<ncc;oid++)
-    {
-      if(id == oid || !keep[oid])
-      {
-        continue;
-      }
-      if (has_overlapping_bbox(V, vG[id], vG[oid])) {
-          unresolved.push_back(oid);
-      }
-    }
-    const size_t num_unresolved_components = unresolved.size();
-    DerivedV query_points(num_unresolved_components, 3);
-    for (size_t i=0; i<num_unresolved_components; i++) {
-        const size_t oid = unresolved[i];
-        DerivedF f = vG[oid].row(0);
-        query_points(i,0) = (V(f(0,0), 0) + V(f(0,1), 0) + V(f(0,2), 0))/3.0;
-        query_points(i,1) = (V(f(0,0), 1) + V(f(0,1), 1) + V(f(0,2), 1))/3.0;
-        query_points(i,2) = (V(f(0,0), 2) + V(f(0,1), 2) + V(f(0,2), 2))/3.0;
-    }
-    Eigen::VectorXi inside;
-    igl::copyleft::cgal::points_inside_component(V, vG[id], query_points, inside);
-    assert((size_t)inside.size() == num_unresolved_components);
-    for (size_t i=0; i<num_unresolved_components; i++) {
-        if (inside(i, 0)) {
-            const size_t oid = unresolved[i];
-            keep[oid] = false;
-        }
-    }
-  }
-  for (size_t id = 0; id<ncc; id++) {
-      if (keep[id]) {
-          nG += vJ[id].rows();
-      }
-  }
-
-  // collect G and J across components
-  G.resize(nG,3);
-  J.resize(nG,1);
-  {
-    size_t off = 0;
-    for(Index id = 0;id<(Index)ncc;id++)
-    {
-      if(keep[id])
-      {
-        assert(vG[id].rows() == vJ[id].rows());
-        G.block(off,0,vG[id].rows(),vG[id].cols()) = vG[id];
-        J.block(off,0,vJ[id].rows(),vJ[id].cols()) = vJ[id];
-        off += vG[id].rows();
-      }
-    }
-  }
-}
-
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-// generated by autoexplicit.sh
-template void igl::copyleft::cgal::outer_hull_legacy<Eigen::Matrix<CGAL::Epeck::FT, -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::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, 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> >&);
-template void igl::copyleft::cgal::outer_hull_legacy< 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::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&, 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> > &);
-template void igl::copyleft::cgal::outer_hull_legacy<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::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&, 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> >&);
-#ifdef WIN32
-#endif
-#endif

+ 0 - 103
include/igl/copyleft/cgal/outer_vertex.cpp

@@ -1,103 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Qingnan Zhou <[email protected]>
-// Copyright (C) 2021 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "outer_vertex.h"
-#include "outer_edge.h"
-#include <iostream>
-#include <vector>
-
-template <
-     typename DerivedV,
-     typename DerivedF,
-     typename DerivedI,
-     typename IndexType,
-     typename DerivedA
-     >
-IGL_INLINE void igl::copyleft::cgal::outer_vertex(
-        const Eigen::PlainObjectBase<DerivedV> & V,
-        const Eigen::PlainObjectBase<DerivedF> & F,
-        const Eigen::PlainObjectBase<DerivedI> & I,
-        IndexType & v_index,
-        Eigen::PlainObjectBase<DerivedA> & A)
-{
-    // Algorithm:
-    //    Find an outer vertex (i.e. vertex reachable from infinity)
-    //    Return the vertex with the largest X value.
-    //    If there is a tie, pick the one with largest Y value.
-    //    If there is still a tie, pick the one with the largest Z value.
-    //    If there is still a tie, then there are duplicated vertices within the
-    //    mesh, which violates the precondition.
-    typedef typename DerivedF::Scalar Index;
-    const Index INVALID = std::numeric_limits<Index>::max();
-    const size_t num_selected_faces = I.rows();
-    std::vector<size_t> candidate_faces;
-    Index outer_vid = INVALID;
-    typename DerivedV::Scalar outer_val = 0;
-    for (size_t i=0; i<num_selected_faces; i++)
-    {
-        size_t f = I(i);
-        for (size_t j=0; j<3; j++)
-        {
-            Index v = F(f, j);
-            auto vx = V(v, 0);
-            if (outer_vid == INVALID || vx > outer_val)
-            {
-                outer_val = vx;
-                outer_vid = v;
-                candidate_faces = {f};
-            } else if (v == outer_vid)
-            {
-                candidate_faces.push_back(f);
-            } else if (vx == outer_val)
-            {
-                // Break tie.
-                auto vy = V(v,1);
-                auto vz = V(v, 2);
-                auto outer_y = V(outer_vid, 1);
-                auto outer_z = V(outer_vid, 2);
-                assert(!(vy == outer_y && vz == outer_z));
-                bool replace = (vy > outer_y) ||
-                    ((vy == outer_y) && (vz > outer_z));
-                if (replace)
-                {
-                    outer_val = vx;
-                    outer_vid = v;
-                    candidate_faces = {f};
-                }
-            }
-        }
-    }
-
-    assert(outer_vid != INVALID);
-    assert(candidate_faces.size() > 0);
-    v_index = outer_vid;
-    A.resize(candidate_faces.size());
-    std::copy(candidate_faces.begin(), candidate_faces.end(), A.data());
-}
-
-#ifdef IGL_STATIC_LIBRARY
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-// Explicit template instantiation
-// generated by autoexplicit.sh
-#include <cstdint>
-template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -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&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -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&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-// Linux
-template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
-#ifdef WIN32
-
-template void __cdecl igl::copyleft::cgal::outer_vertex<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<long,-1,1,0,-1,1>,__int64,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,__int64 &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
-template void __cdecl igl::copyleft::cgal::outer_vertex<class Eigen::Matrix<double,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,1,0,-1,1>,__int64,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,3,0,-1,3> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,1,0,-1,1> > const &,__int64 &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
-template void __cdecl igl::copyleft::cgal::outer_vertex<class Eigen::Matrix<double,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,3,0,-1,3>,class Eigen::Matrix<long,-1,1,0,-1,1>,__int64,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,3,0,-1,3> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,__int64 &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
-
-#endif
-#endif

+ 0 - 127
include/igl/copyleft/cgal/peel_outer_hull_layers.cpp

@@ -1,127 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <[email protected]>
-//
-// 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/.
-#include "peel_outer_hull_layers.h"
-#include "outer_hull_legacy.h"
-#include "../../LinSpaced.h"
-#include <vector>
-#include <iostream>
-//#define IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-#include "../../writePLY.h"
-#include "../../writeDMAT.h"
-#include "../../STR.h"
-#endif
-
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedI,
-  typename Derivedflip>
-IGL_INLINE size_t igl::copyleft::cgal::peel_outer_hull_layers(
-  const Eigen::PlainObjectBase<DerivedV > & V,
-  const Eigen::PlainObjectBase<DerivedF > & F,
-  Eigen::PlainObjectBase<DerivedI> & I,
-  Eigen::PlainObjectBase<Derivedflip > & flip)
-{
-  using namespace Eigen;
-  using namespace std;
-  typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
-  typedef typename DerivedF::Scalar Index;
-  typedef Matrix<Index,Dynamic,1> MatrixXI;
-  typedef Matrix<typename Derivedflip::Scalar,Dynamic,Derivedflip::ColsAtCompileTime> MatrixXflip;
-  const Index m = F.rows();
-#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-  cout<<"peel outer hull layers..."<<endl;
-#endif
-#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-  cout<<"calling outer hull..."<<endl;
-  writePLY(STR("peel-outer-hull-input.ply"),V,F);
-#endif
-
-#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-  cout<<"resize output ..."<<endl;
-#endif
-  // keep track of iteration parity and whether flipped in hull
-  MatrixXF Fr = F;
-  I.resize(m,1);
-  flip.resize(m,1);
-  // Keep track of index map
-  MatrixXI IM = igl::LinSpaced<MatrixXI >(m,0,m-1);
-  // This is O(n * layers)
-  MatrixXI P(m,1);
-  Index iter = 0;
-  while(Fr.size() > 0)
-  {
-    assert(Fr.rows() == IM.rows());
-    // Compute outer hull of current Fr
-    MatrixXF Fo;
-    MatrixXI Jo;
-    MatrixXflip flipr;
-#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-  {
-      cout<<"calling outer hull..." << iter <<endl;
-      std::stringstream ss;
-      ss << "outer_hull_" << iter << ".ply";
-      Eigen::MatrixXd vertices(V.rows(), V.cols());
-      std::transform(V.data(), V.data() + V.rows()*V.cols(),
-              vertices.data(),
-              [](typename DerivedV::Scalar val)
-              {return CGAL::to_double(val); });
-      writePLY(ss.str(), vertices, Fr);
-  }
-#endif
-    outer_hull_legacy(V,Fr,Fo,Jo,flipr);
-#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-  writePLY(STR("outer-hull-output-"<<iter<<".ply"),V,Fo);
-  cout<<"reindex, flip..."<<endl;
-#endif
-    assert(Fo.rows() != 0);
-    assert(Fo.rows() == Jo.rows());
-    // all faces in Fo of Fr
-    vector<bool> in_outer(Fr.rows(),false);
-    for(Index g = 0;g<Jo.rows();g++)
-    {
-      I(IM(Jo(g))) = iter;
-      P(IM(Jo(g))) = iter;
-      in_outer[Jo(g)] = true;
-      flip(IM(Jo(g))) = flipr(Jo(g));
-    }
-    // Fr = Fr - Fo
-    // update IM
-    MatrixXF prev_Fr = Fr;
-    MatrixXI prev_IM = IM;
-    Fr.resize(prev_Fr.rows() - Fo.rows(),F.cols());
-    IM.resize(Fr.rows());
-    {
-      Index g = 0;
-      for(Index f = 0;f<prev_Fr.rows();f++)
-      {
-        if(!in_outer[f])
-        {
-          Fr.row(g) = prev_Fr.row(f);
-          IM(g) = prev_IM(f);
-          g++;
-        }
-      }
-    }
-    iter++;
-  }
-  return iter;
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-// generated by autoexplicit.sh
-template size_t igl::copyleft::cgal::peel_outer_hull_layers<Eigen::Matrix<CGAL::Epeck::FT, -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<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#include <cstdint>
-#ifdef WIN32
-template uint64_t igl::copyleft::cgal::peel_outer_hull_layers<Eigen::Matrix<CGAL::Epeck::FT, -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<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-#endif
-#endif

+ 0 - 33
include/igl/copyleft/cgal/peel_winding_number_layers.cpp

@@ -1,33 +0,0 @@
-#include "peel_winding_number_layers.h"
-
-#include <cassert>
-
-#include "propagate_winding_numbers.h"
-
-template<
-typename DerivedV,
-typename DerivedF,
-typename DerivedW >
-IGL_INLINE size_t igl::copyleft::cgal::peel_winding_number_layers(
-        const Eigen::PlainObjectBase<DerivedV > & V,
-        const Eigen::PlainObjectBase<DerivedF > & F,
-        Eigen::PlainObjectBase<DerivedW>& W) {
-    const size_t num_faces = F.rows();
-    Eigen::VectorXi labels(num_faces);
-    labels.setZero();
-
-    Eigen::MatrixXi winding_numbers;
-    igl::copyleft::cgal::propagate_winding_numbers(V, F, labels, winding_numbers);
-    assert(winding_numbers.rows() == num_faces);
-    assert(winding_numbers.cols() == 2);
-
-    int min_w = winding_numbers.minCoeff();
-    int max_w = winding_numbers.maxCoeff();
-    assert(max_w > min_w);
-
-    W.resize(num_faces, 1);
-    for (size_t i=0; i<num_faces; i++) {
-        W(i, 0) = winding_numbers(i, 1);
-    }
-    return max_w - min_w;
-}

Some files were not shown because too many files changed in this diff