|
@@ -1,9 +1,12 @@
|
|
#include "exterior_edges.h"
|
|
#include "exterior_edges.h"
|
|
#include "all_edges.h"
|
|
#include "all_edges.h"
|
|
|
|
+#include "sort.h"
|
|
|
|
+#include "unique.h"
|
|
|
|
|
|
#include <cassert>
|
|
#include <cassert>
|
|
#include <unordered_map>
|
|
#include <unordered_map>
|
|
#include <utility>
|
|
#include <utility>
|
|
|
|
+#include <iostream>
|
|
|
|
|
|
//template <typename T> inline int sgn(T val) {
|
|
//template <typename T> inline int sgn(T val) {
|
|
// return (T(0) < val) - (val < T(0));
|
|
// return (T(0) < val) - (val < T(0));
|
|
@@ -38,68 +41,53 @@ IGL_INLINE void igl::exterior_edges(
|
|
using namespace Eigen;
|
|
using namespace Eigen;
|
|
using namespace std;
|
|
using namespace std;
|
|
assert(F.cols() == 3);
|
|
assert(F.cols() == 3);
|
|
- MatrixXi all_E;
|
|
|
|
|
|
+ const size_t m = F.rows();
|
|
|
|
+ MatrixXi all_E,sall_E,sort_order;
|
|
|
|
+ // Sort each edge by index
|
|
all_edges(F,all_E);
|
|
all_edges(F,all_E);
|
|
- long int n = F.maxCoeff()+1;
|
|
|
|
- int m = F.minCoeff();
|
|
|
|
- const auto & compress = [n,m](const int i, const int j)->long int
|
|
|
|
|
|
+ sort(all_E,2,true,sall_E,sort_order);
|
|
|
|
+ // Find unique edges
|
|
|
|
+ MatrixXi uE;
|
|
|
|
+ VectorXi IA,EMAP;
|
|
|
|
+ unique_rows(sall_E,uE,IA,EMAP);
|
|
|
|
+ VectorXi counts = VectorXi::Zero(uE.rows());
|
|
|
|
+ for(size_t a = 0;a<3*m;a++)
|
|
{
|
|
{
|
|
- return n*(i-m)+(j-m);
|
|
|
|
- };
|
|
|
|
- const auto & decompress = [n,m](const long int l,int & i, int & j)
|
|
|
|
- {
|
|
|
|
- i = (l / n) + m;
|
|
|
|
- j = (l % n) + m;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // Count occurances looking only at pairs (i,j) where i<j, so we count and
|
|
|
|
- // edge i-->j as +1 and j-->i as -1
|
|
|
|
- unordered_map<long int,int> C;
|
|
|
|
- // Loop over edges
|
|
|
|
- for(int e = 0;e<all_E.rows();e++)
|
|
|
|
- {
|
|
|
|
- int i = all_E(e,0);
|
|
|
|
- int j = all_E(e,1);
|
|
|
|
- if(i<j)
|
|
|
|
- {
|
|
|
|
- // Forward direction --> +1
|
|
|
|
- C[compress(i,j)]++;
|
|
|
|
- }else
|
|
|
|
- {
|
|
|
|
- // Backward direction --> -1
|
|
|
|
- C[compress(j,i)]--;
|
|
|
|
- }
|
|
|
|
|
|
+ counts(EMAP(a)) += (sort_order(a)==0?1:-1);
|
|
}
|
|
}
|
|
- // Q: Why mod off factors of 2? +1/-1 already takes care of interior edges?
|
|
|
|
- //// Mod off any factors of 2
|
|
|
|
- //for_each(C.begin(),C.end(),mod2);
|
|
|
|
- //int zeros = (int) count(C.begin(),C.end(),Compare(0));
|
|
|
|
- //E.resize(C.size() - zeros,2);
|
|
|
|
- E.resize(all_E.rows(),all_E.cols());
|
|
|
|
- int e = 0;
|
|
|
|
- // Find all edges with -1 or 1 occurances, flipping direction for -1
|
|
|
|
- for(const auto & cit : C)
|
|
|
|
|
|
+
|
|
|
|
+ E.resize(all_E.rows(),2);
|
|
{
|
|
{
|
|
- int i,j;
|
|
|
|
- if(cit.second > 0)
|
|
|
|
- {
|
|
|
|
- decompress(cit.first,i,j);
|
|
|
|
- } else if(cit.second < 0)
|
|
|
|
- {
|
|
|
|
- decompress(cit.first,j,i);
|
|
|
|
- } else if(cit.second == 0)
|
|
|
|
- {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- for(int k = 0;k<abs(cit.second);k++)
|
|
|
|
|
|
+ int e = 0;
|
|
|
|
+ const size_t nue = uE.rows();
|
|
|
|
+ // Append each unique edge with a non-zero amount of signed occurances
|
|
|
|
+ for(size_t ue = 0; ue<nue; ue++)
|
|
{
|
|
{
|
|
- E(e,0) = i;
|
|
|
|
- E(e,1) = j;
|
|
|
|
- e++;
|
|
|
|
|
|
+ const int count = counts(ue);
|
|
|
|
+ size_t i,j;
|
|
|
|
+ if(count == 0)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }else if(count < 0)
|
|
|
|
+ {
|
|
|
|
+ i = uE(ue,1);
|
|
|
|
+ j = uE(ue,0);
|
|
|
|
+ }else if(count > 0)
|
|
|
|
+ {
|
|
|
|
+ i = uE(ue,0);
|
|
|
|
+ j = uE(ue,1);
|
|
|
|
+ }
|
|
|
|
+ // Append edge for every repeated entry
|
|
|
|
+ const int abs_count = abs(count);
|
|
|
|
+ for(size_t k = 0;k<abs_count;k++)
|
|
|
|
+ {
|
|
|
|
+ E(e,0) = i;
|
|
|
|
+ E(e,1) = j;
|
|
|
|
+ e++;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ E.conservativeResize(e,2);
|
|
}
|
|
}
|
|
- E.conservativeResize(e,2);
|
|
|
|
- assert(e == E.rows());
|
|
|
|
}
|
|
}
|
|
|
|
|
|
IGL_INLINE Eigen::MatrixXi igl::exterior_edges( const Eigen::MatrixXi & F)
|
|
IGL_INLINE Eigen::MatrixXi igl::exterior_edges( const Eigen::MatrixXi & F)
|