Ver Fonte

Merge branch 'master' of https://github.com/libigl/libigl

Former-commit-id: 0514ce8860c10d9ded3ee84e2d98ef0b944e9ef9
Daniele Panozzo há 10 anos atrás
pai
commit
5beb633851

+ 3 - 4
include/igl/cgal/CGAL_includes.hpp

@@ -31,10 +31,9 @@
 #include <CGAL/AABB_traits.h>
 #include <CGAL/AABB_triangle_primitive.h>
 
-// ALEC: IS ANY IGL FUNCTION USING THESE?
-//// Boolean operations
-//#include <CGAL/Polyhedron_3.h>
-//#include <CGAL/Nef_polyhedron_3.h>
+// Boolean operations
+#include <CGAL/Polyhedron_3.h>
+#include <CGAL/Nef_polyhedron_3.h>
 
 // Delaunay Triangulation in 3D
 #include <CGAL/Delaunay_triangulation_3.h>

+ 1 - 1
include/igl/cgal/SelfIntersectMesh.h

@@ -911,7 +911,7 @@ inline bool igl::SelfIntersectMesh<
     try
     {
       CGAL::Object result = CGAL::intersection(A,B);
-      if(result)
+      if(!result.empty())
       {
         if(CGAL::object_cast<Segment_3 >(&result))
         {

+ 1 - 0
include/igl/cgal/complex_to_mesh.cpp

@@ -11,6 +11,7 @@
 #include <igl/remove_unreferenced.h>
 
 #include <CGAL/Surface_mesh_default_triangulation_3.h>
+#include <CGAL/Triangulation_cell_base_with_circumcenter_3.h>
 #include <set>
 #include <stack>
 

+ 45 - 0
include/igl/cgal/mesh_to_polyhedron.cpp

@@ -0,0 +1,45 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "mesh_to_polyhedron.h"
+#include <CGAL/Polyhedron_3.h>
+#include <CGAL/Polyhedron_incremental_builder_3.h>
+template <typename Polyhedron>
+IGL_INLINE bool igl::mesh_to_polyhedron(
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & 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();
+}

+ 36 - 0
include/igl/cgal/mesh_to_polyhedron.h

@@ -0,0 +1,36 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_MESH_TO_POLYHEDRON_H
+#define IGL_MESH_TO_POLYHEDRON_H
+#include <igl/igl_inline.h>
+#include <Eigen/Core>
+
+namespace igl
+{
+  // Convert a mesh (V,F) to a CGAL Polyhedron
+  //
+  // Templates:
+  //   Polyhedron  CGAL Polyhedron type (e.g. Polyhedron_3)
+  // Inputs:
+  //   V  #V by 3 list of vertex positions
+  //   F  #F by 3 list of triangle indices
+  // Outputs:
+  //   poly  cgal polyhedron
+  // Returns true only if (V,F) can be converted to a valid polyhedron (i.e. if
+  // (V,F) is vertex and edge manifold).
+  template <typename Polyhedron>
+  IGL_INLINE bool mesh_to_polyhedron(
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    Polyhedron & poly);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "mesh_to_polyhedron.cpp"
+#endif
+
+#endif

+ 12 - 2
include/igl/cgal/point_mesh_squared_distance.cpp

@@ -55,6 +55,16 @@ IGL_INLINE void igl::point_mesh_squared_distance_precompute(
   assert(V.cols() == 3);
   // Must be triangles
   assert(F.cols() == 3);
+
+  // WTF ALERT!!!! 
+  //
+  // There's a bug in clang probably or at least in cgal. Without calling this
+  // line (I guess invoking some compilation from <vector>), clang will vomit
+  // errors inside CGAL.
+  //
+  // http://stackoverflow.com/questions/27748442/is-clangs-c11-support-reliable
+  T.reserve(0);
+
   // Make list of cgal triangles
   mesh_to_cgal_triangle_list(V,F,T);
   tree.clear();
@@ -110,7 +120,7 @@ IGL_INLINE void igl::point_mesh_squared_distance(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
-template void igl::point_mesh_squared_distance<CGAL::Epeck>( const Eigen::MatrixXd & P, const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, Eigen::VectorXd & sqrD, Eigen::VectorXi & I, Eigen::MatrixXd & C);
 template void igl::point_mesh_squared_distance_precompute<CGAL::Epick>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epick, CGAL::AABB_triangle_primitive<CGAL::Epick, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >::iterator, CGAL::Boolean_tag<false> > > >&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
-
+template void igl::point_mesh_squared_distance<CGAL::Epeck>( const Eigen::MatrixXd & P, const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, Eigen::VectorXd & sqrD, Eigen::VectorXi & I, Eigen::MatrixXd & C);
+template void igl::point_mesh_squared_distance<CGAL::Epick>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, 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>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
 #endif

+ 57 - 0
include/igl/cgal/polyhedron_to_mesh.cpp

@@ -0,0 +1,57 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "polyhedron_to_mesh.h"
+#include <CGAL/Polyhedron_3.h>
+
+template <typename Polyhedron>
+IGL_INLINE void igl::polyhedron_to_mesh(
+  const Polyhedron & poly,
+  Eigen::MatrixXd & V,
+  Eigen::MatrixXi & F)
+{
+  using namespace std;
+  V.resize(poly.size_of_vertices(),3);
+  F.resize(poly.size_of_facets(),3);
+  typedef typename Polyhedron::Vertex_const_iterator Vertex_iterator;
+  std::map<Vertex_iterator,size_t> vertex_to_index;
+  {
+    size_t v = 0;
+    for(
+      typename Polyhedron::Vertex_const_iterator p = poly.vertices_begin();
+      p != poly.vertices_end();
+      p++)
+    {
+      V(v,0) = p->point().x();
+      V(v,1) = p->point().y();
+      V(v,2) = p->point().z();
+      vertex_to_index[p] = v;
+      v++;
+    }
+  }
+  {
+    size_t f = 0;
+    for(
+      typename Polyhedron::Facet_const_iterator facet = poly.facets_begin();
+      facet != poly.facets_end();
+      ++facet)
+    {
+      typename Polyhedron::Halfedge_around_facet_const_circulator he = 
+        facet->facet_begin();
+      // Facets in polyhedral surfaces are at least triangles.
+      assert(CGAL::circulator_size(he) == 3 && "Facets should be triangles");
+      size_t c = 0;
+      do {
+        //// This is stooopidly slow
+        // F(f,c) = std::distance(poly.vertices_begin(), he->vertex());
+        F(f,c) = vertex_to_index[he->vertex()];
+        c++;
+      } while ( ++he != facet->facet_begin());
+      f++;
+    }
+  }
+}

+ 34 - 0
include/igl/cgal/polyhedron_to_mesh.h

@@ -0,0 +1,34 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_POLYHEDRON_TO_MESH_H
+#define IGL_POLYHEDRON_TO_MESH_H
+#include <igl/igl_inline.h>
+#include <Eigen/Core>
+
+namespace igl
+{
+  // Convert a CGAL Polyhedron to a mesh (V,F)
+  //
+  // Templates:
+  //   Polyhedron  CGAL Polyhedron type (e.g. Polyhedron_3)
+  // Inputs:
+  //   poly  cgal polyhedron
+  // Outputs:
+  //   V  #V by 3 list of vertex positions
+  //   F  #F by 3 list of triangle indices
+  template <typename Polyhedron>
+  IGL_INLINE void polyhedron_to_mesh(
+    const Polyhedron & poly,
+    Eigen::MatrixXd & V,
+    Eigen::MatrixXi & F);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "polyhedron_to_mesh.cpp"
+#endif
+
+#endif

+ 3 - 0
include/igl/cgal/signed_distance.cpp

@@ -282,6 +282,9 @@ IGL_INLINE void igl::signed_distance_winding_number(
 }
 
 #ifdef IGL_STATIC_LIBRARY
+// This template is necessary for the others to compile with clang
+// http://stackoverflow.com/questions/27748442/is-clangs-c11-support-reliable
+template void igl::signed_distance<CGAL::Epick>( const Eigen::MatrixXd & , const Eigen::MatrixXd & , const Eigen::MatrixXi & , const SignedDistanceType , Eigen::VectorXd & , Eigen::VectorXi &, Eigen::MatrixXd & , Eigen::MatrixXd & );
 template CGAL::Epick::FT igl::signed_distance_winding_number<CGAL::Epick>(CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epick, CGAL::AABB_triangle_primitive<CGAL::Epick, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >::iterator, CGAL::Boolean_tag<false> > > > const&, igl::WindingNumberAABB<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, CGAL::Epick::Point_3 const&);
 template CGAL::Epick::FT igl::signed_distance_pseudonormal<CGAL::Epick>(CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epick, CGAL::AABB_triangle_primitive<CGAL::Epick, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >::iterator, CGAL::Boolean_tag<false> > > > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, CGAL::Epick::Point_3 const&);
 #endif

+ 132 - 0
include/igl/collapse_small_triangles.cpp

@@ -0,0 +1,132 @@
+#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,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.resize(rF.rows(),rF.cols());
+  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);
+}

+ 40 - 0
include/igl/collapse_small_triangles.h

@@ -0,0 +1,40 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_COLLAPSE_SMALL_TRIANGLES_H
+#define IGL_COLLAPSE_SMALL_TRIANGLES_H
+#include <Eigen/Dense>
+namespace igl
+{
+  // Given a triangle mesh (V,F) compute a new mesh (VV,FF) which contains the
+  // original faces and vertices of (V,F) except any small triangles have been
+  // removed via collapse.
+  //
+  // We are *not* following the rules in "Mesh Optimization" [Hoppe et al]
+  // Section 4.2. But for our purposes we don't care about this criteria.
+  //
+  // Inputs:
+  //   V  #V by 3 list of vertex positions
+  //   F  #F by 3 list of triangle indices into V
+  //   eps  epsilon for smallest allowed area treated as fraction of squared bounding box
+  //     diagonal
+  // Outputs:
+  //   FF  #FF by 3 list of triangle indices into V
+  //
+  //
+  void collapse_small_triangles(
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    const double eps,
+    Eigen::MatrixXi & FF);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "collapse_small_triangles.cpp"
+#endif
+  
+#endif

+ 0 - 0
include/igl/matlab/mexStream.h → include/igl/matlab/MexStream.h


+ 1 - 0
include/igl/writePLY.cpp

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "writePLY.h"
 #include <igl/ply.h>
+#include <vector>
 
 template <
   typename DerivedV,