فهرست منبع

Remove duplicated integer variable across seams. Doesn't converge.

Former-commit-id: e1fb1f054c5a4d79e260960d60e757726c20da97
wkevin 9 سال پیش
والد
کامیت
700e8762df
1فایلهای تغییر یافته به همراه52 افزوده شده و 6 حذف شده
  1. 52 6
      include/igl/comiso/miq.cpp

+ 52 - 6
include/igl/comiso/miq.cpp

@@ -480,6 +480,7 @@ template <typename DerivedV, typename DerivedF>
 IGL_INLINE void igl::comiso::VertexIndexing<DerivedV, DerivedF>::InitSeamInfo()
 {
   Handle_SystemInfo.EdgeSeamInfo.clear();
+  std::set<int> hasConstraint;
   int intVar = 0;
   for (unsigned int f0=0;f0<F.rows();f0++)
   {
@@ -491,18 +492,23 @@ IGL_INLINE void igl::comiso::VertexIndexing<DerivedV, DerivedF>::InitSeamInfo()
         continue;
 
       bool seam = Handle_Seams(f0,k);
-      if (seam)
+      auto search = hasConstraint.find(3*f0 + k);
+      if (seam && search == hasConstraint.end())
       {
         int v0,v0p,v1,v1p;
         unsigned char MM;
         int integerVar;
         GetSeamInfo(f0,f1,k,v0,v1,v0p,v1p,MM);
         Handle_SystemInfo.EdgeSeamInfo.push_back(SeamInfo(v0,v1,v0p,v1p,MM,intVar));
+
+        // mark this face-edge pair and face-edge pair across seam as constrained
+        hasConstraint.insert(3*f0 + k);
+        hasConstraint.insert(3*f1 + TTi(f0,k));
         intVar++;
       }
     }
   }
-  assert(intVar == Handle_SystemInfo.num_integer_cuts);
+  assert(intVar == Handle_SystemInfo.num_integer_cuts / 2);
 }
 
 
@@ -795,7 +801,7 @@ IGL_INLINE void igl::comiso::PoissonSolver<DerivedV, DerivedF>::FindSizes()
 
   ///INTEGER PART
   ///the total number of integer variables
-  n_integer_vars = Handle_SystemInfo.num_integer_cuts;
+  n_integer_vars = Handle_SystemInfo.num_integer_cuts / 2;
 
   ///CONSTRAINT PART
   num_cut_constraint = Handle_SystemInfo.EdgeSeamInfo.size()*2;
@@ -905,7 +911,7 @@ IGL_INLINE void igl::comiso::PoissonSolver<DerivedV, DerivedF>::BuildSeamConstra
   ///current constraint row
   int constr_row = 0;
 
-  for (unsigned int i=0; i<num_cut_constraint/2; i++)
+  for (unsigned int i=0; i<num_cut_constraint/4; i++)
   {
     unsigned char interval = Handle_SystemInfo.EdgeSeamInfo[i].MMatch;
     if (interval==1)
@@ -920,6 +926,7 @@ IGL_INLINE void igl::comiso::PoissonSolver<DerivedV, DerivedF>::BuildSeamConstra
     int p1p = Handle_SystemInfo.EdgeSeamInfo[i].v1p;
 
     std::complex<double> rot = GetRotationComplex(interval);
+    std::complex<double> counterRot = GetRotationComplex((interval % 2 == 0 ) ? interval : (interval + 2) % 4);
 
     ///get the integer variable
     int integerVar = n_vert_vars + Handle_SystemInfo.EdgeSeamInfo[i].integerVar;
@@ -930,8 +937,9 @@ IGL_INLINE void igl::comiso::PoissonSolver<DerivedV, DerivedF>::BuildSeamConstra
       ids_to_round.push_back(integerVar*2+1);
     }
 
+    // TODO: exploit fact that rotations have either zeros on diagonal (real) or off-diagonal (imag). don't explicitly store the zeros.
     // cross boundary compatibility conditions
-    // constraints for one end of edge
+    // constraints for start vertex of edge
     Constraints.coeffRef(constr_row,   2*p0)   +=  rot.real();
     Constraints.coeffRef(constr_row,   2*p0+1) += -rot.imag();
     Constraints.coeffRef(constr_row+1, 2*p0)   +=  rot.imag();
@@ -948,7 +956,26 @@ IGL_INLINE void igl::comiso::PoissonSolver<DerivedV, DerivedF>::BuildSeamConstra
 
     constr_row += 2;
 
-    // constraints for other end of edge
+    // constraints for start vertex across edge
+    Constraints.coeffRef(constr_row,   2*p0)   += 1;
+    Constraints.coeffRef(constr_row+1, 2*p0+1) += 1;
+
+    Constraints.coeffRef(constr_row,   2*p0p)   += -counterRot.real();
+    Constraints.coeffRef(constr_row,   2*p0p+1) +=  counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*p0p)   += -counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*p0p+1) += -counterRot.real();
+
+    Constraints.coeffRef(constr_row,   2*integerVar)   +=  counterRot.real();
+    Constraints.coeffRef(constr_row,   2*integerVar+1) += -counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*integerVar)   +=  counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*integerVar+1) +=  counterRot.real();
+
+    constraints_rhs[constr_row]   = 0;
+    constraints_rhs[constr_row+1] = 0;
+
+    constr_row += 2;
+
+    // constraints for end vertex of edge
     Constraints.coeffRef(constr_row,   2*p1)   +=  rot.real();
     Constraints.coeffRef(constr_row,   2*p1+1) += -rot.imag();
     Constraints.coeffRef(constr_row+1, 2*p1)   +=  rot.imag();
@@ -964,6 +991,25 @@ IGL_INLINE void igl::comiso::PoissonSolver<DerivedV, DerivedF>::BuildSeamConstra
     constraints_rhs[constr_row+1] = 0;
 
     constr_row += 2;
+
+    // constraints for end vertex across edge
+    Constraints.coeffRef(constr_row,   2*p1)   += 1;
+    Constraints.coeffRef(constr_row+1, 2*p1+1) += 1;
+
+    Constraints.coeffRef(constr_row,   2*p1p)   += -counterRot.real();
+    Constraints.coeffRef(constr_row,   2*p1p+1) +=  counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*p1p)   += -counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*p1p+1) += -counterRot.real();
+
+    Constraints.coeffRef(constr_row,   2*integerVar)   +=  counterRot.real();
+    Constraints.coeffRef(constr_row,   2*integerVar+1) += -counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*integerVar)   +=  counterRot.imag();
+    Constraints.coeffRef(constr_row+1, 2*integerVar+1) +=  counterRot.real();
+
+    constraints_rhs[constr_row]   = 0;
+    constraints_rhs[constr_row+1] = 0;
+
+    constr_row += 2;
   }
 }