Browse Source

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

Former-commit-id: 03285088db046c2e130f63cabe03e7290c565334
Daniele Panozzo 9 years ago
parent
commit
a6a04a62f2

+ 83 - 0
include/igl/cgal/component_inside_component.cpp

@@ -0,0 +1,83 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@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 "component_inside_component.h"
+
+#include <cassert>
+#include <list>
+#include <limits>
+#include <vector>
+
+#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 "order_facets_around_edge.h"
+#include "assign_scalar.h"
+#include "points_inside_component.h"
+
+template <typename DerivedV, typename DerivedF, typename DerivedI>
+IGL_INLINE bool igl::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::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::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.setLinSpaced(F1.rows(), 0, F1.rows()-1);
+    I2.setLinSpaced(F2.rows(), 0, F2.rows()-1);
+    return igl::cgal::component_inside_component(V1, F1, I1, V2, F2, I2);
+}
+
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template bool igl::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::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

+ 72 - 0
include/igl/cgal/component_inside_component.h

@@ -0,0 +1,72 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@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 COMONENT_INSIDE_COMPONENT
+#define COMONENT_INSIDE_COMPONENT
+
+#include "../igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+
+namespace igl {
+    namespace cgal {
+
+        // Determine if connected facet component (V1, F1, I1) is inside of
+        // connected facet component (V2, F2, I2).
+        //
+        // Precondition:
+        // Both components must represent closed, self-intersection free,
+        // non-degenerated surfaces that are the boundary of 3D volumes. In
+        // addition, (V1, F1, I1) must not intersect with (V2, F2, I2).
+        //
+        // Inputs:
+        //   V1  #V1 by 3 list of vertex position of mesh 1
+        //   F1  #F1 by 3 list of triangles indices into V1
+        //   I1  #I1 list of indices into F1, indicate the facets of component
+        //   V2  #V2 by 3 list of vertex position of mesh 2
+        //   F2  #F2 by 3 list of triangles indices into V2
+        //   I2  #I2 list of indices into F2, indicate the facets of component
+        //
+        // Outputs:
+        //   return true iff (V1, F1, I1) is entirely inside of (V2, F2, I2).
+        template<typename DerivedV, typename DerivedF, typename DerivedI>
+            IGL_INLINE bool 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);
+
+        // Determine if mesh (V1, F1) is inside of mesh (V2, F2).
+        //
+        // Precondition:
+        // Both meshes must be closed, self-intersection free, non-degenerated
+        // surfaces that are the boundary of 3D volumes.  They should not
+        // intersect each other.
+        //
+        // Inputs:
+        //   V1  #V1 by 3 list of vertex position of mesh 1
+        //   F1  #F1 by 3 list of triangles indices into V1
+        //   V2  #V2 by 3 list of vertex position of mesh 2
+        //   F2  #F2 by 3 list of triangles indices into V2
+        //
+        // Outputs:
+        //   return true iff (V1, F1) is entirely inside of (V2, F2).
+        template<typename DerivedV, typename DerivedF>
+            IGL_INLINE bool component_inside_component(
+                    const Eigen::PlainObjectBase<DerivedV>& V1,
+                    const Eigen::PlainObjectBase<DerivedF>& F1,
+                    const Eigen::PlainObjectBase<DerivedV>& V2,
+                    const Eigen::PlainObjectBase<DerivedF>& F2);
+    }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#include "component_inside_component.cpp"
+#endif
+#endif

+ 0 - 82
include/igl/cgal/is_inside.h

@@ -1,82 +0,0 @@
-#ifndef IS_INSIDE
-#define IS_INSIDE
-
-#include "../igl_inline.h"
-#include <Eigen/Core>
-
-namespace igl {
-    namespace cgal {
-
-        // Determine if mesh (V1, F1) is inside of mesh (V2, F2).
-        //
-        // Precondition:
-        // Both mesh must represent closed, self-intersection free,
-        // non-degenerated surfaces that
-        // are the boundary of 3D volumes. In addition, (V1, F1) must not
-        // intersect with (V2, F2).
-        //
-        // Inputs:
-        //   V1  #V1 by 3 list of vertex position of mesh 1
-        //   F1  #F1 by 3 list of triangles indices into V1
-        //   I1  #I1 list of indices into F1, faces to consider.
-        //   V2  #V2 by 3 list of vertex position of mesh 2
-        //   F2  #F2 by 3 list of triangles indices into V2
-        //   I2  #I2 list of indices into F2, faces to consider.
-        //
-        // Outputs:
-        //   return true iff (V1, F1) is entirely inside of (V2, F2).
-        template<typename DerivedV, typename DerivedF, typename DerivedI>
-            IGL_INLINE bool is_inside(
-                    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);
-
-        template<typename DerivedV, typename DerivedF>
-            IGL_INLINE bool is_inside(
-                    const Eigen::PlainObjectBase<DerivedV>& V1,
-                    const Eigen::PlainObjectBase<DerivedF>& F1,
-                    const Eigen::PlainObjectBase<DerivedV>& V2,
-                    const Eigen::PlainObjectBase<DerivedF>& F2);
-
-        // Determine if queries points are inside of mesh (V, F).
-        //
-        // Precondition:
-        // The input mesh must be a closed, self-intersection free,
-        // non-degenerated surface.  Queries points must be either inside or
-        // outside of the mesh.
-        //
-        // Inputs:
-        //   V  #V by 3 array of vertex positions.
-        //   F  #F by 3 array of triangles.
-        //   I  #I list of triangle indices to consider.
-        //   P  #P by 3 array of query points.
-        //
-        // Outputs:
-        //   inside  #P list of booleans that is true iff the corresponding
-        //           query point is inside of the mesh.
-        template<typename DerivedV, typename DerivedF, typename DerivedI,
-            typename DerivedP, typename DerivedB>
-            IGL_INLINE void is_inside(
-                    const Eigen::PlainObjectBase<DerivedV>& V,
-                    const Eigen::PlainObjectBase<DerivedF>& F,
-                    const Eigen::PlainObjectBase<DerivedI>& I,
-                    const Eigen::PlainObjectBase<DerivedP>& P,
-                    Eigen::PlainObjectBase<DerivedB>& inside);
-
-        template<typename DerivedV, typename DerivedF, typename DerivedP,
-            typename DerivedB>
-            IGL_INLINE void is_inside(
-                    const Eigen::PlainObjectBase<DerivedV>& V,
-                    const Eigen::PlainObjectBase<DerivedF>& F,
-                    const Eigen::PlainObjectBase<DerivedP>& P,
-                    Eigen::PlainObjectBase<DerivedB>& inside);
-    }
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#include "is_inside.cpp"
-#endif
-#endif

+ 3 - 3
include/igl/cgal/outer_hull.cpp

@@ -5,7 +5,7 @@
 // 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 "is_inside.h"
+#include "points_inside_component.h"
 #include "outer_hull.h"
 #include "order_facets_around_edges.h"
 #include "outer_facet.h"
@@ -401,10 +401,10 @@ IGL_INLINE void igl::cgal::outer_hull(
         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::cgal::is_inside(V, vG[id], query_points, inside);
+    igl::cgal::points_inside_component(V, vG[id], query_points, inside);
     assert(inside.size() == num_unresolved_components);
     for (size_t i=0; i<num_unresolved_components; i++) {
-        if (inside[i]) {
+        if (inside(i, 0)) {
             const size_t oid = unresolved[i];
             keep[oid] = false;
         }

+ 37 - 57
include/igl/cgal/is_inside.cpp → include/igl/cgal/points_inside_component.cpp

@@ -1,4 +1,11 @@
-#include "is_inside.h"
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@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 "points_inside_component.h"
 
 #include <cassert>
 #include <list>
@@ -15,7 +22,7 @@
 
 namespace igl {
     namespace cgal {
-        namespace is_inside_helper {
+        namespace points_inside_component_helper {
             typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
             typedef Kernel::Ray_3 Ray_3;
             typedef Kernel::Point_3 Point_3;
@@ -165,7 +172,7 @@ namespace igl {
                 } else {
                     throw "The input mesh does not represent a valid volume";
                 }
-                assert(false);
+                throw "The input mesh does not represent a valid volume";
                 return false;
             }
 
@@ -203,7 +210,7 @@ namespace igl {
                                 coplanar++;
                                 break;
                             default:
-                                assert(false);
+                                throw "Unknown plane-point orientation";
                         }
                     }
                     auto query_orientation = separator.oriented_side(query);
@@ -221,7 +228,9 @@ namespace igl {
                     for (size_t j=i+1; j<num_adj_vertices; j++) {
                         const size_t vj = adj_vertices[j];
                         Plane_3 separator(p, adj_points[i], adj_points[j]);
-                        assert(!separator.is_degenerate());
+                        if (separator.is_degenerate()) {
+                            throw "Input mesh contains degenerated faces";
+                        }
                         if (is_on_exterior(separator)) {
                             d = vi;
                             assert(!CGAL::collinear(p, adj_points[i], query));
@@ -251,60 +260,27 @@ namespace igl {
                 const Point_3 v1(V(f[1], 0), V(f[1], 1), V(f[1], 2));
                 const Point_3 v2(V(f[2], 0), V(f[2], 1), V(f[2], 2));
                 auto result = CGAL::orientation(v0, v1, v2, query);
-                assert(result != CGAL::COPLANAR);
+                if (result == CGAL::COPLANAR) {
+                    throw "Cannot determine inside/outside because query point lies exactly on the input surface.";
+                }
                 return result == CGAL::NEGATIVE;
             }
         }
     }
 }
 
-template <typename DerivedV, typename DerivedF, typename DerivedI>
-IGL_INLINE bool igl::cgal::is_inside(
-        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) {
-    assert(F1.rows() > 0);
-    assert(I1.rows() > 0);
-    assert(F2.rows() > 0);
-    assert(I2.rows() > 0);
-
-    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::cgal::is_inside(V2, F2, I2, query, inside);
-    assert(inside.size() == 1);
-    return inside[0];
-}
-
-template<typename DerivedV, typename DerivedF>
-IGL_INLINE bool igl::cgal::is_inside(
-        const Eigen::PlainObjectBase<DerivedV>& V1,
-        const Eigen::PlainObjectBase<DerivedF>& F1,
-        const Eigen::PlainObjectBase<DerivedV>& V2,
-        const Eigen::PlainObjectBase<DerivedF>& F2) {
-    Eigen::VectorXi I1(F1.rows()), I2(F2.rows());
-    I1.setLinSpaced(F1.rows(), 0, F1.rows()-1);
-    I2.setLinSpaced(F2.rows(), 0, F2.rows()-1);
-    return igl::cgal::is_inside(V1, F1, I1, V2, F2, I2);
-}
-
 template<typename DerivedV, typename DerivedF, typename DerivedI,
     typename DerivedP, typename DerivedB>
-IGL_INLINE void igl::cgal::is_inside(
+IGL_INLINE void igl::cgal::points_inside_component(
         const Eigen::PlainObjectBase<DerivedV>& V,
         const Eigen::PlainObjectBase<DerivedF>& F,
         const Eigen::PlainObjectBase<DerivedI>& I,
         const Eigen::PlainObjectBase<DerivedP>& P,
         Eigen::PlainObjectBase<DerivedB>& inside) {
-    using namespace igl::cgal::is_inside_helper;
-    assert(F.rows() > 0);
-    assert(I.rows() > 0);
+    using namespace igl::cgal::points_inside_component_helper;
+    if (F.rows() <= 0 || I.rows() <= 0) {
+        throw "Inside check cannot be done on empty facet component.";
+    }
 
     const size_t num_faces = I.rows();
     std::vector<Triangle> triangles;
@@ -314,13 +290,15 @@ IGL_INLINE void igl::cgal::is_inside(
                 Point_3(V(f[0], 0), V(f[0], 1), V(f[0], 2)),
                 Point_3(V(f[1], 0), V(f[1], 1), V(f[1], 2)),
                 Point_3(V(f[2], 0), V(f[2], 1), V(f[2], 2)));
-        assert(!triangles.back().is_degenerate());
+        if (triangles.back().is_degenerate()) {
+            throw "Input facet components contains degenerated triangles";
+        }
     }
     Tree tree(triangles.begin(), triangles.end());
     tree.accelerate_distance_queries();
 
     const size_t num_queries = P.rows();
-    inside.resize(num_queries);
+    inside.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);
@@ -333,7 +311,7 @@ IGL_INLINE void igl::cgal::is_inside(
             case VERTEX:
                 {
                     const size_t s = F(I(fid, 0), element_index);
-                    inside[i] = determine_point_vertex_orientation(
+                    inside(i,0) = determine_point_vertex_orientation(
                             V, F, I, query, s);
                 }
                 break;
@@ -341,34 +319,36 @@ IGL_INLINE void igl::cgal::is_inside(
                 {
                     const size_t s = F(I(fid, 0), (element_index+1)%3);
                     const size_t d = F(I(fid, 0), (element_index+2)%3);
-                    inside[i] = determine_point_edge_orientation(
+                    inside(i,0) = determine_point_edge_orientation(
                             V, F, I, query, s, d);
                 }
                 break;
             case FACE:
-                inside[i] = determine_point_face_orientation(V, F, I, query, fid);
+                inside(i,0) = determine_point_face_orientation(V, F, I, query, fid);
                 break;
             default:
-                assert(false);
+                throw "Unknow closest element type!";
         }
     }
 }
 
 template<typename DerivedV, typename DerivedF, typename DerivedP,
     typename DerivedB>
-IGL_INLINE void igl::cgal::is_inside(
+IGL_INLINE void igl::cgal::points_inside_component(
         const Eigen::PlainObjectBase<DerivedV>& V,
         const Eigen::PlainObjectBase<DerivedF>& F,
         const Eigen::PlainObjectBase<DerivedP>& P,
         Eigen::PlainObjectBase<DerivedB>& inside) {
     Eigen::VectorXi I(F.rows());
     I.setLinSpaced(F.rows(), 0, F.rows()-1);
-    igl::cgal::is_inside(V, F, I, P, inside);
+    igl::cgal::points_inside_component(V, F, I, P, inside);
 }
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
-template void igl::cgal::is_inside<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::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> >&);
-template void igl::cgal::is_inside<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::cgal::is_inside<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::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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::cgal::points_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::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<   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> >&);
+template void igl::cgal::points_inside_component< 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::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> >&);
+template void igl::cgal::points_inside_component<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::cgal::points_inside_component<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::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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::cgal::points_inside_component<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::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> >&);
 #endif

+ 59 - 0
include/igl/cgal/points_inside_component.h

@@ -0,0 +1,59 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@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 POINTS_INSIDE_COMPONENTS
+#define POINTS_INSIDE_COMPONENTS
+
+#include "../igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+
+namespace igl {
+    namespace cgal {
+
+        // Determine if queries points P are inside of connected facet component
+        // (V, F, I), where I indicates a subset of facets that forms the
+        // component.
+        //
+        // Precondition:
+        // The input mesh must be a closed, self-intersection free,
+        // non-degenerated surface.  Queries points must be either inside or
+        // outside of the mesh (i.e. not on the surface of the mesh).
+        //
+        // Inputs:
+        //   V  #V by 3 array of vertex positions.
+        //   F  #F by 3 array of triangles.
+        //   I  #I list of triangle indices to consider.
+        //   P  #P by 3 array of query points.
+        //
+        // Outputs:
+        //   inside  #P list of booleans that is true iff the corresponding
+        //           query point is inside of the mesh.
+        template<typename DerivedV, typename DerivedF, typename DerivedI,
+            typename DerivedP, typename DerivedB>
+            IGL_INLINE void points_inside_component(
+                    const Eigen::PlainObjectBase<DerivedV>& V,
+                    const Eigen::PlainObjectBase<DerivedF>& F,
+                    const Eigen::PlainObjectBase<DerivedI>& I,
+                    const Eigen::PlainObjectBase<DerivedP>& P,
+                    Eigen::PlainObjectBase<DerivedB>& inside);
+
+        // Determine if query points P is inside of the mesh (V, F).
+        // See above for precondition and I/O specs.
+        template<typename DerivedV, typename DerivedF, typename DerivedP, typename DerivedB>
+            IGL_INLINE void points_inside_component(
+                    const Eigen::PlainObjectBase<DerivedV>& V,
+                    const Eigen::PlainObjectBase<DerivedF>& F,
+                    const Eigen::PlainObjectBase<DerivedP>& P,
+                    Eigen::PlainObjectBase<DerivedB>& inside);
+    }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#include "points_inside_component.cpp"
+#endif
+#endif