Browse Source

update stype and add doc

hanxiao 6 years ago
parent
commit
c4813053b2

+ 36 - 38
include/igl/predicates/ear_clipping.cpp

@@ -4,47 +4,45 @@
 #include "point_inside_polygon.h"
 #include "point_inside_polygon.h"
 #include "predicates.h"
 #include "predicates.h"
 
 
-template <typename DerivedP>
-IGL_INLINE bool igl::predicates::is_ear(
-  const Eigen::MatrixBase<DerivedP>& P,
-  const Eigen::VectorXi& RT,
-  const Eigen::VectorXi& L,
-  const Eigen::VectorXi& R,
-  const int i
-){
-  typedef typename DerivedP::Scalar Scalar;
-
-  int a = L(i), b = R(i);
-  if(RT(i) != 0 || RT(a) != 0 || RT(b) != 0) return false;
-  Eigen::RowVector2d pa = P.row(a);
-  Eigen::RowVector2d pb = P.row(b);
-  Eigen::RowVector2d pi = P.row(i);
-  auto r = igl::predicates::orient2d(pa,pi,pb);
-  if(r == igl::predicates::Orientation::NEGATIVE || 
-     r == igl::predicates::Orientation::COLLINEAR) return false;
-  
-  // check if any vertex is lying inside triangle (a,b,i);
-  int k=R(b);
-  while(k!=a){
-    Eigen::MatrixX2d T(3,2);
-    T<<P.row(a),P.row(i),P.row(b);
-    Eigen::RowVector2d q=P.row(k);
-    if(point_inside_polygon(T,q)) 
-      return false;
-    k=R(k);
-  }
-  return true;
-}
-
-// https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
-template <typename DerivedP>
+template <typename DerivedP, typename DerivedRT,
+          typename DerivedF, typename DerivedI>
 IGL_INLINE void igl::predicates::ear_clipping(
 IGL_INLINE void igl::predicates::ear_clipping(
   const Eigen::MatrixBase<DerivedP>& P,
   const Eigen::MatrixBase<DerivedP>& P,
-  const Eigen::VectorXi& RT,
-  Eigen::VectorXi& I,
-  Eigen::MatrixXi& eF, 
+  const Eigen::MatrixBase<DerivedRT>& RT,
+  Eigen::PlainObjectBase<DerivedI>& I,
+  Eigen::PlainObjectBase<DerivedF>& eF,
   Eigen::PlainObjectBase<DerivedP>& nP
   Eigen::PlainObjectBase<DerivedP>& nP
 ){
 ){
+  
+  // check whether vertex i is an ear
+  auto is_ear = [](
+    const Eigen::MatrixBase<DerivedP>& P,
+    const Eigen::MatrixBase<DerivedRT>& RT,
+    const Eigen::VectorXi& L,
+    const Eigen::VectorXi& R,
+    const int i
+  ){
+    int a = L(i), b = R(i);
+    if(RT(i) != 0 || RT(a) != 0 || RT(b) != 0) return false;
+    Eigen::RowVector2d pa = P.row(a);
+    Eigen::RowVector2d pb = P.row(b);
+    Eigen::RowVector2d pi = P.row(i);
+    auto r = igl::predicates::orient2d(pa,pi,pb);
+    if(r == igl::predicates::Orientation::NEGATIVE || 
+       r == igl::predicates::Orientation::COLLINEAR) return false;
+    
+    // check if any vertex is lying inside triangle (a,b,i);
+    int k=R(b);
+    while(k!=a){
+      Eigen::MatrixX2d T(3,2);
+      T<<P.row(a),P.row(i),P.row(b);
+      Eigen::RowVector2d q=P.row(k);
+      if(igl::predicates::point_inside_polygon(T,q)) 
+        return false;
+      k=R(k);
+    }
+    return true;
+  };
 
 
   Eigen::VectorXi L(P.rows());
   Eigen::VectorXi L(P.rows());
   Eigen::VectorXi R(P.rows());
   Eigen::VectorXi R(P.rows());
@@ -109,5 +107,5 @@ IGL_INLINE void igl::predicates::ear_clipping(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-template void igl::predicates::ear_clipping<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, 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> >&);
+template void igl::predicates::ear_clipping<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::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<int, -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> >&);
 #endif
 #endif

+ 19 - 12
include/igl/predicates/ear_clipping.h

@@ -16,23 +16,30 @@ namespace igl
 {
 {
   namespace predicates
   namespace predicates
   {
   {
-    template <typename DerivedP>
+
+    // Implementation of ear clipping triangulation algorithm for a 2D polygon.
+    // https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
+    // If the polygon is simple, all vertices will be clipped and the result mesh is (P,eF)
+    // Otherwise, the function will try to clip as many ears as possible.
+    //
+    // Input:
+    // P : n*2, size n 2D polygon
+    // RT: n*1, preserved vertices (do not clip) marked as 1, otherwise 0
+    // Output:
+    // I : size #nP vector, maps index from nP to P, e.g. nP's ith vertex is origianlly I(i) in P
+    // eF: clipped ears, in original index of P
+    // nP: leftover vertices after clipping
+
+    template <typename DerivedP, typename DerivedRT,
+              typename DerivedF, typename DerivedI>
     IGL_INLINE void ear_clipping(
     IGL_INLINE void ear_clipping(
       const Eigen::MatrixBase<DerivedP>& P,
       const Eigen::MatrixBase<DerivedP>& P,
-      const Eigen::VectorXi& RT,
-      Eigen::VectorXi& I,
-      Eigen::MatrixXi& eF, 
+      const Eigen::MatrixBase<DerivedRT>& RT,
+      Eigen::PlainObjectBase<DerivedI>& I,
+      Eigen::PlainObjectBase<DerivedF>& eF, 
       Eigen::PlainObjectBase<DerivedP>& nP
       Eigen::PlainObjectBase<DerivedP>& nP
     );
     );
 
 
-    template <typename DerivedP>
-    IGL_INLINE bool is_ear(
-      const Eigen::MatrixBase<DerivedP>& P,
-      const Eigen::VectorXi& RT,
-      const Eigen::VectorXi& L,
-      const Eigen::VectorXi& R, 
-      const int i
-    );
   }
   }
 }
 }
 
 

+ 5 - 5
include/igl/predicates/point_inside_polygon.cpp

@@ -8,10 +8,10 @@
 
 
 #include "point_inside_polygon.h"
 #include "point_inside_polygon.h"
 
 
-template <typename Scalar>
-bool igl::predicates::point_inside_polygon(
-    const Eigen::Matrix<Scalar,-1,2>& P,
-    const Eigen::Matrix<Scalar,1,2>& q
+template <typename DerivedP, typename DerivedQ>
+IGL_INLINE bool igl::predicates::point_inside_polygon(
+  const Eigen::MatrixBase<DerivedP>& P,
+  const Eigen::MatrixBase<DerivedQ>& q
 ){
 ){
   for(int i=0;i<P.rows();i++){
   for(int i=0;i<P.rows();i++){
     int i_1 = (i+1) % P.rows();
     int i_1 = (i+1) % P.rows();
@@ -26,5 +26,5 @@ bool igl::predicates::point_inside_polygon(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-template bool igl::predicates::point_inside_polygon<double>(Eigen::Matrix<double, -1, 2, 0, -1, 2> const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&);
+template bool igl::predicates::point_inside_polygon<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&);
 #endif
 #endif

+ 10 - 10
include/igl/predicates/point_inside_polygon.h

@@ -19,16 +19,16 @@ namespace igl
 {
 {
   namespace predicates
   namespace predicates
   {
   {
-      // check whether 2d point lies inside 2d polygon
-      // Inputs:
-      //   P: n*2 polygon, n >= 3
-      //   q: 2d query point
-      // Returns true if point is inside polygon
-      template <typename Scalar>
-      bool point_inside_polygon(
-          const Eigen::Matrix<Scalar,-1,2>& P,
-          const Eigen::Matrix<Scalar,1,2>& q
-      );
+    // check whether 2d point lies inside 2d polygon
+    // Inputs:
+    //   P: n*2 polygon, n >= 3
+    //   q: 2d query point
+    // Returns true if point is inside polygon
+    template <typename DerivedP, typename DerivedQ>
+    IGL_INLINE bool point_inside_polygon(
+        const Eigen::MatrixBase<DerivedP>& P,
+        const Eigen::MatrixBase<DerivedQ>& q
+    );
   }
   }
 }
 }
 
 

+ 4 - 6
include/igl/predicates/segment_segment_intersect.h

@@ -14,18 +14,17 @@
 #include <igl/predicates/predicates.h>
 #include <igl/predicates/predicates.h>
 namespace igl
 namespace igl
 {
 {
-namespace predicates
-{
+  namespace predicates
+  {
   
   
     // Given two segments in 2d test whether they intersect each other
     // Given two segments in 2d test whether they intersect each other
-    // using orient2D
+    // using predicates orient2d
     // 
     // 
     // Inputs:
     // Inputs:
     //   A:   1st endpoint of segment 1
     //   A:   1st endpoint of segment 1
     //   B:   2st endpoint of segment 1
     //   B:   2st endpoint of segment 1
     //   C:   1st endpoint of segment 2
     //   C:   1st endpoint of segment 2
     //   D:   2st endpoint of segment 2
     //   D:   2st endpoint of segment 2
-    //   eps: precision used for colinear case
     // Returns true if they intersect
     // Returns true if they intersect
     
     
     template <typename DerivedP>
     template <typename DerivedP>
@@ -37,8 +36,7 @@ namespace predicates
       const Eigen::MatrixBase<DerivedP>& D
       const Eigen::MatrixBase<DerivedP>& D
     );
     );
 
 
-}
-
+  }
 }
 }
 #ifndef IGL_STATIC_LIBRARY
 #ifndef IGL_STATIC_LIBRARY
 #   include "segment_segment_intersect.cpp"
 #   include "segment_segment_intersect.cpp"