|
@@ -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;
|
|
|
}
|
|
|
}
|
|
|
|