Эх сурвалжийг харах

parity mode, more verbose message

Former-commit-id: ef64f01f4514887fb16dc8b18de1d66b43c42420
Kenshi Takayama (kenshi 11 жил өмнө
parent
commit
2a4f046280

+ 35 - 15
include/igl/embree/reorient_facets_raycast.cpp

@@ -25,6 +25,7 @@
     const Eigen::PlainObjectBase<DerivedV> & V,
     const Eigen::PlainObjectBase<DerivedF> & F,
     int num_rays,
+    bool use_parity,
     bool is_verbose,
     Eigen::PlainObjectBase<DerivedI> & I)
 {
@@ -40,6 +41,7 @@
   VectorXi C;
   MatrixXi FF = F;
   bfs_orient(F,FF,C);
+  if (is_verbose) cout << (C.maxCoeff() + 1)  << " components. ";
   
   // number of patches
   const int num_cc = C.maxCoeff()+1;
@@ -75,6 +77,7 @@
   {
     num_rays_per_component(c) += static_cast<int>(num_rays * area_per_component(c) / area_total);
   }
+  num_rays = num_rays_per_component.sum();
   
   // generate all the rays
   if (is_verbose) cout << "generating rays... ";
@@ -137,12 +140,16 @@
       ray_face.push_back(f);
       ray_ori .push_back(p);
       ray_dir .push_back(d);
+
+      if (is_verbose && ray_face.size() % (num_rays / 10) == 0) cout << ".";
     }
   }
+  if (is_verbose) cout << ray_face.size()  << " rays. ";
   
   // per component voting: first=front, second=back
-  vector<pair<float, float>> C_vote_distance(num_cc, make_pair(0, 0));     // sum of distance between ray origin and intersection
-  vector<pair<int  , int  >> C_vote_infinity(num_cc, make_pair(0, 0));     // number of rays reaching infinity
+  vector<pair<float, float>> C_vote_distance(num_cc, make_pair(0, 0));      // sum of distance between ray origin and intersection
+  vector<pair<int  , int  >> C_vote_infinity(num_cc, make_pair(0, 0));      // number of rays reaching infinity
+  vector<pair<int  , int  >> C_vote_parity(num_cc, make_pair(0, 0));        // sum of parity count for each ray
   
   if (is_verbose) cout << "shooting rays... ";
 #pragma omp parallel for
@@ -163,22 +170,30 @@
     if (!hits_front.empty() && hits_front[0].id == f) hits_front.erase(hits_front.begin());
     if (!hits_back .empty() && hits_back [0].id == f) hits_back .erase(hits_back .begin());
     
-    if (hits_front.empty())
-    {
+    if (use_parity) {
 #pragma omp atomic
-      C_vote_infinity[c].first++;
+      C_vote_parity[c].first  += hits_front.size() % 2;
+#pragma omp atomic
+      C_vote_parity[c].second += hits_back .size() % 2;
+    
     } else {
+      if (hits_front.empty())
+      {
 #pragma omp atomic
-      C_vote_distance[c].first += hits_front[0].t;
-    }
+        C_vote_infinity[c].first++;
+      } else {
+#pragma omp atomic
+        C_vote_distance[c].first += hits_front[0].t;
+      }
     
-    if (hits_back.empty())
-    {
+      if (hits_back.empty())
+      {
 #pragma omp atomic
-      C_vote_infinity[c].second++;
-    } else {
+        C_vote_infinity[c].second++;
+      } else {
 #pragma omp atomic
-      C_vote_distance[c].second += hits_back[0].t;
+        C_vote_distance[c].second += hits_back[0].t;
+      }
     }
   }
   
@@ -186,9 +201,14 @@
   for(int f = 0; f < m; ++f)
   {
     int c = C(f);
-    I(f) = (C_vote_infinity[c].first == C_vote_infinity[c].second && C_vote_distance[c].first <  C_vote_distance[c].second) ||
-            C_vote_infinity[c].first <  C_vote_infinity[c].second
-            ? 1 : 0;
+    if (use_parity) {
+      I(f) = C_vote_parity[c].first > C_vote_parity[c].second ? 1 : 0;      // Ideally, parity for the front/back side should be 1/0 (i.e., parity sum for all rays should be smaller on the front side)
+    
+    } else {
+      I(f) = (C_vote_infinity[c].first == C_vote_infinity[c].second && C_vote_distance[c].first <  C_vote_distance[c].second) ||
+              C_vote_infinity[c].first <  C_vote_infinity[c].second
+              ? 1 : 0;
+    }
   }
   if (is_verbose) cout << "done!" << endl;
 }

+ 1 - 0
include/igl/embree/reorient_facets_raycast.h

@@ -28,6 +28,7 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedV> & V,
     const Eigen::PlainObjectBase<DerivedF> & F,
     int num_rays,
+    bool use_parity,
     bool is_verbose,
     Eigen::PlainObjectBase<DerivedI> & I);
 };