|
|
@ -4,22 +4,22 @@ |
|
|
|
const float PI = 3.1415927; |
|
|
|
|
|
|
|
LoopDetector:: |
|
|
|
LoopDetector(const vector<vector<glm::vec3>> &s_evaluation_, const vector<vector<glm::vec3>> &f_evaluation_, |
|
|
|
const vector<vector<glm::vec3>> &s_tangent_u_, const vector<vector<glm::vec3>> &f_tangent_u_, |
|
|
|
const vector<vector<glm::vec3>> &s_tangent_v_, const vector<vector<glm::vec3>> &f_tangent_v_, |
|
|
|
const vector<vector<glm::vec3>> &s_normal_, const vector<vector<glm::vec3>> &f_normal_, |
|
|
|
const tinynurbs::RationalSurface<float> &s_) |
|
|
|
: s_evaluation(s_evaluation_), f_evaluation(f_evaluation_), |
|
|
|
s_tangent_u(s_tangent_u_), s_tangent_v(s_tangent_v_), |
|
|
|
f_tangent_u(f_tangent_u_), f_tangent_v(f_tangent_v_), |
|
|
|
s_normal(s_normal_), f_normal(f_normal_), s(s_) {} |
|
|
|
LoopDetector(const vector<vector<glm::vec3> > &s_evaluation_, const vector<vector<glm::vec3> > &f_evaluation_, |
|
|
|
const vector<vector<glm::vec3> > &s_tangent_u_, const vector<vector<glm::vec3> > &f_tangent_u_, |
|
|
|
const vector<vector<glm::vec3> > &s_tangent_v_, const vector<vector<glm::vec3> > &f_tangent_v_, |
|
|
|
const vector<vector<glm::vec3> > &s_normal_, const vector<vector<glm::vec3> > &f_normal_, |
|
|
|
const tinynurbs::RationalSurface<float> &s_, const tinynurbs::RationalSurface<float> &f_) |
|
|
|
: s_evaluation(s_evaluation_), f_evaluation(f_evaluation_), |
|
|
|
s_tangent_u(s_tangent_u_), s_tangent_v(s_tangent_v_), |
|
|
|
f_tangent_u(f_tangent_u_), f_tangent_v(f_tangent_v_), |
|
|
|
s_normal(s_normal_), f_normal(f_normal_), s(s_), f(f_) { |
|
|
|
} |
|
|
|
|
|
|
|
// old version
|
|
|
|
void LoopDetector::initOrientedDistance() { |
|
|
|
|
|
|
|
selectedPointsIdx = vector<vector<pair<int, int>>>(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<pair<int, int>>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
// distance = vector<vector<glm::vec3>>(s_subPatchEdgeSampleCnt_u, vector<glm::vec3>(s_subPatchEdgeSampleCnt_v));
|
|
|
|
selectedPointsIdx = vector<vector<pair<int, int> > >(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<pair<int, int> >(s_subPatchEdgeSampleCnt_v)); |
|
|
|
// distance = vector<vector<glm::vec3>>(s_subPatchEdgeSampleCnt_u, vector<glm::vec3>(s_subPatchEdgeSampleCnt_v));
|
|
|
|
|
|
|
|
for (int i = 0; i < s_subPatchEdgeSampleCnt_u; i++) { |
|
|
|
for (int j = 0; j < s_subPatchEdgeSampleCnt_v; j++) { |
|
|
@ -28,8 +28,8 @@ void LoopDetector::initOrientedDistance() { |
|
|
|
for (int k = 0; k < f_subPatchEdgeSampleCnt_u; k++) { |
|
|
|
for (int l = 0; l < f_subPatchEdgeSampleCnt_v; l++) { |
|
|
|
auto dis = glm::distance( |
|
|
|
s_evaluation[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j], |
|
|
|
f_evaluation[f_subPatchIdxRange_u.first + k][f_subPatchIdxRange_v.first + l]); |
|
|
|
s_evaluation[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j], |
|
|
|
f_evaluation[f_subPatchIdxRange_u.first + k][f_subPatchIdxRange_v.first + l]); |
|
|
|
// 确定f上的对应点时,依据的最小欧氏距离,而不是有向距离
|
|
|
|
if (dis < minDis) { |
|
|
|
minDis = dis; |
|
|
@ -38,25 +38,28 @@ void LoopDetector::initOrientedDistance() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// auto N = glm::normalize(s_evaluation[i][j] - f_evaluation[minDisFIdx_u][minDisFIdx_v]);
|
|
|
|
// // 直接normalize得到的单位向量总是与SF同向,但实际上N应当总是与f的一侧法向量成锐角
|
|
|
|
// auto testAngle = N * glm::cross(f_tangent_u[minDisFIdx_u][minDisFIdx_v], f_tangent_v[minDisFIdx_u][minDisFIdx_v]);
|
|
|
|
// N = testAngle.x + testAngle.y + testAngle.z > 0 ? N : -N;
|
|
|
|
// distance[i][j] = N * (s_evaluation[i][j] - f_evaluation[minDisFIdx_u][minDisFIdx_v]);
|
|
|
|
// auto N = glm::normalize(s_evaluation[i][j] - f_evaluation[minDisFIdx_u][minDisFIdx_v]);
|
|
|
|
// // 直接normalize得到的单位向量总是与SF同向,但实际上N应当总是与f的一侧法向量成锐角
|
|
|
|
// auto testAngle = N * glm::cross(f_tangent_u[minDisFIdx_u][minDisFIdx_v], f_tangent_v[minDisFIdx_u][minDisFIdx_v]);
|
|
|
|
// N = testAngle.x + testAngle.y + testAngle.z > 0 ? N : -N;
|
|
|
|
// distance[i][j] = N * (s_evaluation[i][j] - f_evaluation[minDisFIdx_u][minDisFIdx_v]);
|
|
|
|
selectedPointsIdx[i][j] = {minDisFIdx_u, minDisFIdx_v}; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// old version
|
|
|
|
void LoopDetector::initOrientedDisAndVecFields(const vector<pair<pair<int, int>, pair<int, int>>> &intersectBoxPairs) { |
|
|
|
selectedPointsIdx = vector<vector<pair<int, int>>>(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<pair<int, int>>(s_subPatchEdgeSampleCnt_v, {-1, -1})); |
|
|
|
vectorFields = vector<vector<glm::vec2>>(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
int neighborIdxes[4][2] = {{1, 0}, |
|
|
|
{0, 1}, |
|
|
|
{-1, 0}, |
|
|
|
{0, -1}}; |
|
|
|
void LoopDetector::initOrientedDisAndVecFields( |
|
|
|
const vector<pair<pair<int, int>, pair<int, int> > > &intersectBoxPairs) { |
|
|
|
selectedPointsIdx = vector<vector<pair<int, int> > >(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<pair<int, int> >(s_subPatchEdgeSampleCnt_v, {-1, -1})); |
|
|
|
vectorFields = vector<vector<glm::vec2> >(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
int neighborIdxes[4][2] = { |
|
|
|
{1, 0}, |
|
|
|
{0, 1}, |
|
|
|
{-1, 0}, |
|
|
|
{0, -1} |
|
|
|
}; |
|
|
|
for (const auto &boxPair: intersectBoxPairs) { |
|
|
|
float minDis = FLT_MAX; |
|
|
|
int minDisFIdx_u = -1, minDisFIdx_v = -1; |
|
|
@ -77,8 +80,8 @@ void LoopDetector::initOrientedDisAndVecFields(const vector<pair<pair<int, int>, |
|
|
|
for (int k = 0; k < f_subPatchEdgeSampleCnt_u; k++) { |
|
|
|
for (int l = 0; l < f_subPatchEdgeSampleCnt_v; l++) { |
|
|
|
auto dis = glm::distance( |
|
|
|
s_evaluation[idxI][idxJ], |
|
|
|
f_evaluation[f_subPatchIdxRange_u.first + k][f_subPatchIdxRange_v.first + l]); |
|
|
|
s_evaluation[idxI][idxJ], |
|
|
|
f_evaluation[f_subPatchIdxRange_u.first + k][f_subPatchIdxRange_v.first + l]); |
|
|
|
// 确定f上的对应点时,依据的最小欧氏距离,而不是有向距离
|
|
|
|
if (dis < minDis) { |
|
|
|
minDis = dis; |
|
|
@ -93,7 +96,7 @@ void LoopDetector::initOrientedDisAndVecFields(const vector<pair<pair<int, int>, |
|
|
|
// 计算vector fields
|
|
|
|
auto fPtRelatedIdx = pair<int, int>(minDisFIdx_u, minDisFIdx_v); |
|
|
|
auto n2 = f_normal[f_subPatchIdxRange_u.first + fPtRelatedIdx.first][f_subPatchIdxRange_v.first + |
|
|
|
fPtRelatedIdx.second]; |
|
|
|
fPtRelatedIdx.second]; |
|
|
|
auto ps_pu = s_tangent_u[idxI][idxJ]; |
|
|
|
auto ps_pv = s_tangent_v[idxI][idxJ]; |
|
|
|
vectorFields[idxI - s_subPatchIdxRange_u.first][idxJ - s_subPatchIdxRange_v.first] |
|
|
@ -104,17 +107,23 @@ void LoopDetector::initOrientedDisAndVecFields(const vector<pair<pair<int, int>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void LoopDetector::initOrientedDisAndVecFields(const map<pair<int, int>, set<pair<int, int>>> &intersectBoxPairs) { |
|
|
|
|
|
|
|
selectedPointsIdx = vector<vector<pair<int, int>>>(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<pair<int, int>>(s_subPatchEdgeSampleCnt_v, {-1, -1})); |
|
|
|
vectorFields = vector<vector<glm::vec2>>(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
int neighborIdxes[4][2] = {{1, 0}, |
|
|
|
{0, 1}, |
|
|
|
{-1, 0}, |
|
|
|
{0, -1}}; |
|
|
|
int dirs[2][2][2] = {{{-1, 1}, {1, 1}}, |
|
|
|
{{-1, -1}, {1, -1}}}; // 必须是左上,右上,左下,右下的顺序
|
|
|
|
// without newton iteration and with wrong approximate
|
|
|
|
void LoopDetector::initOrientedDisAndVecFields_deprecated( |
|
|
|
const map<pair<int, int>, set<pair<int, int> > > &intersectBoxPairs) { |
|
|
|
selectedPointsIdx = vector<vector<pair<int, int> > >(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<pair<int, int> >(s_subPatchEdgeSampleCnt_v, {-1, -1})); |
|
|
|
vectorFields = vector<vector<glm::vec2> >(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
auto vectorFieldsCalculated = vector<vector<int> >(s_subPatchEdgeSampleCnt_u, vector<int>(0)); |
|
|
|
int neighborIdxes[4][2] = { |
|
|
|
{1, 0}, |
|
|
|
{0, 1}, |
|
|
|
{-1, 0}, |
|
|
|
{0, -1} |
|
|
|
}; |
|
|
|
int dirs[2][2][2] = { |
|
|
|
{{-1, 1}, {1, 1}}, |
|
|
|
{{-1, -1}, {1, -1}} |
|
|
|
}; // 必须是左上,右上,左下,右下的顺序
|
|
|
|
for (const auto &boxPair: intersectBoxPairs) { |
|
|
|
for (int i = 0; i < 2; i++) { |
|
|
|
for (int j = 0; j < 2; j++) { |
|
|
@ -137,7 +146,6 @@ void LoopDetector::initOrientedDisAndVecFields(const map<pair<int, int>, set<pai |
|
|
|
for (int l = 0; l < 2; l++) { |
|
|
|
for (int step_u = 0; step_u <= 2; step_u++) { |
|
|
|
for (int step_v = 0; step_v + step_u <= 2; step_v++) { |
|
|
|
|
|
|
|
int fIdx_u = relatedBox.first + k + step_u * dirs[k][l][0]; |
|
|
|
int fIdx_v = relatedBox.second + l + step_v * dirs[k][l][1]; |
|
|
|
if (fIdx_u < 0 || fIdx_u >= f_evaluation.size() || |
|
|
@ -168,10 +176,76 @@ void LoopDetector::initOrientedDisAndVecFields(const map<pair<int, int>, set<pai |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void LoopDetector::initOrientedDisAndVecFields(const map<pair<int, int>, set<pair<int, int> > > &intersectBoxPairs) { |
|
|
|
selectedPointsIdx = vector(s_subPatchEdgeSampleCnt_u, vector<pair<int, int> >(s_subPatchEdgeSampleCnt_v, {-1, -1})); |
|
|
|
vectorFields = vector(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
auto vectorFieldsCalculated = vector(s_subPatchEdgeSampleCnt_u, vector<int>(0)); |
|
|
|
int dirs[2][2][2] = { |
|
|
|
{{-1, -1}, {-1, 1}}, |
|
|
|
{{1, -1}, {1, 1}} |
|
|
|
}; // 必须是左上,右上,左下,右下的顺序
|
|
|
|
for (const auto &boxPair: intersectBoxPairs) { |
|
|
|
for (int i = 0; i < 2; i++) { |
|
|
|
for (int j = 0; j < 2; j++) { |
|
|
|
float minDis = FLT_MAX; |
|
|
|
int minDisFIdx_u = -1, minDisFIdx_v = -1; |
|
|
|
int idxI = boxPair.first.first + i; |
|
|
|
int idxJ = boxPair.first.second + j; |
|
|
|
if (idxI - s_subPatchIdxRange_u.first < 0 || |
|
|
|
idxI - s_subPatchIdxRange_u.first >= s_subPatchEdgeSampleCnt_u || |
|
|
|
idxJ - s_subPatchIdxRange_v.first < 0 || |
|
|
|
idxJ - s_subPatchIdxRange_v.first >= s_subPatchEdgeSampleCnt_v || |
|
|
|
selectedPointsIdx[idxI - s_subPatchIdxRange_u.first][idxJ - s_subPatchIdxRange_v.first] != |
|
|
|
pair<int, int>(-1, -1)) { |
|
|
|
// 不重复计算
|
|
|
|
continue; |
|
|
|
} |
|
|
|
for (auto relatedBox: boxPair.second) { |
|
|
|
for (int k = 0; k < 2; k++) { |
|
|
|
for (int l = 0; l < 2; l++) { |
|
|
|
for (int step_u = 0; step_u <= 4; step_u++) { |
|
|
|
for (int step_v = 0; step_v + step_u <= 4; step_v++) { |
|
|
|
int fIdx_u = relatedBox.first + k + step_u * dirs[k][l][0]; |
|
|
|
int fIdx_v = relatedBox.second + l + step_v * dirs[k][l][1]; |
|
|
|
if (fIdx_u < 0 || fIdx_u >= f_evaluation.size() || |
|
|
|
fIdx_v < 0 || fIdx_v >= f_evaluation[0].size()) |
|
|
|
continue; |
|
|
|
auto dis = glm::distance(s_evaluation[idxI][idxJ], |
|
|
|
f_evaluation[fIdx_u][fIdx_v]); |
|
|
|
if (dis < minDis) { |
|
|
|
minDis = dis; |
|
|
|
minDisFIdx_u = fIdx_u; |
|
|
|
minDisFIdx_v = fIdx_v; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
selectedPointsIdx[idxI - s_subPatchIdxRange_u.first][idxJ - s_subPatchIdxRange_v.first] |
|
|
|
= {minDisFIdx_u - f_subPatchIdxRange_u.first, minDisFIdx_v - f_subPatchIdxRange_v.first}; |
|
|
|
pair<int, int> selectedIdx = {minDisFIdx_u - f_subPatchIdxRange_u.first, minDisFIdx_v - f_subPatchIdxRange_v.first}; |
|
|
|
pair<float, float> fURange = {f.knots_u[0], f.knots_u[f.knots_u.size() - 1]}; |
|
|
|
pair<float, float> fVRange = {f.knots_v[0], f.knots_v[f.knots_v.size() - 1]}; |
|
|
|
pair<float, float> selectedParam = { |
|
|
|
fURange.first + (fURange.second - fURange.first) / static_cast<float>(f_evaluation.size() - 1) * static_cast<float>(selectedIdx.first), |
|
|
|
fVRange.first + (fVRange.second - fVRange.first) / static_cast<float>(f_evaluation[0].size() - 1) * static_cast<float>(selectedIdx.second) |
|
|
|
}; |
|
|
|
auto n2 = f_normal[minDisFIdx_u][minDisFIdx_v]; |
|
|
|
auto ps_pu = s_tangent_u[idxI][idxJ]; |
|
|
|
auto ps_pv = s_tangent_v[idxI][idxJ]; |
|
|
|
vectorFields[idxI - s_subPatchIdxRange_u.first][idxJ - s_subPatchIdxRange_v.first] |
|
|
|
= glm::vec2(glm::dot(n2, ps_pu), glm::dot(n2, ps_pv)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Yawei Ma的文章中的做法
|
|
|
|
// old version
|
|
|
|
void LoopDetector::initVectorField0() { |
|
|
|
vectorFields = vector<vector<glm::vec2>>(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
vectorFields = vector<vector<glm::vec2> >(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
for (int i = 0; i < s_subPatchEdgeSampleCnt_u; i++) { |
|
|
|
for (int j = 0; j < s_subPatchEdgeSampleCnt_v; j++) { |
|
|
|
auto fPointIdx = selectedPointsIdx[i][j]; |
|
|
@ -181,9 +255,9 @@ void LoopDetector::initVectorField0() { |
|
|
|
if (isnan(N.x) || isnan(N.y) || isnan(N.z)) { |
|
|
|
// 绝了,曲面s和f的交线正好经过采样点,此时就无法定义向量N
|
|
|
|
// 这里取两个曲面在交点的法向量的平均做近似
|
|
|
|
// auto tmp1 = glm::cross(s_tangent_u[i][j], s_tangent_v[i][j]);
|
|
|
|
// auto tmp2 = glm::cross(f_tangent_u[fPointIdx.first][fPointIdx.second],
|
|
|
|
// f_tangent_v[fPointIdx.first][fPointIdx.second]);
|
|
|
|
// auto tmp1 = glm::cross(s_tangent_u[i][j], s_tangent_v[i][j]);
|
|
|
|
// auto tmp2 = glm::cross(f_tangent_u[fPointIdx.first][fPointIdx.second],
|
|
|
|
// f_tangent_v[fPointIdx.first][fPointIdx.second]);
|
|
|
|
N = glm::normalize(s_normal[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j] + |
|
|
|
f_normal[f_subPatchIdxRange_u.first + fPointIdx.first] |
|
|
|
[f_subPatchIdxRange_v.first + fPointIdx.second]); |
|
|
@ -197,14 +271,14 @@ void LoopDetector::initVectorField0() { |
|
|
|
auto u2 = glm::normalize(glm::cross(N, u1)); |
|
|
|
// s,f曲面在两个方向上的偏导
|
|
|
|
auto ps_pu = s_tangent_u[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j] |
|
|
|
, ps_pv = s_tangent_v[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j]; |
|
|
|
, ps_pv = s_tangent_v[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j]; |
|
|
|
auto pf_pp = f_tangent_u[f_subPatchIdxRange_u.first + fPointIdx.first] |
|
|
|
[f_subPatchIdxRange_v.first + fPointIdx.second], pf_pq = f_tangent_v[f_subPatchIdxRange_u.first + |
|
|
|
fPointIdx.first] |
|
|
|
[f_subPatchIdxRange_v.first + fPointIdx.second]; |
|
|
|
[f_subPatchIdxRange_v.first + fPointIdx.second], pf_pq = f_tangent_v[f_subPatchIdxRange_u.first + |
|
|
|
fPointIdx.first] |
|
|
|
[f_subPatchIdxRange_v.first + fPointIdx.second]; |
|
|
|
// 构造Aij矩阵,见<Detection of loops and singularities of surface intersections> APPENDIX (A7)
|
|
|
|
auto inverseAij = glm::inverse( |
|
|
|
glm::mat2x2(glm::dot(u1, pf_pp), glm::dot(u1, pf_pq), glm::dot(u2, pf_pp), glm::dot(u2, pf_pq)) |
|
|
|
glm::mat2x2(glm::dot(u1, pf_pp), glm::dot(u1, pf_pq), glm::dot(u2, pf_pp), glm::dot(u2, pf_pq)) |
|
|
|
); |
|
|
|
auto mBmn = glm::mat2x2(glm::dot(u1, ps_pu), glm::dot(u1, ps_pv), glm::dot(u2, ps_pu), glm::dot(u2, ps_pv)); |
|
|
|
auto tmp = glm::vec2(glm::dot(N, pf_pp), glm::dot(N, pf_pq)); |
|
|
@ -223,13 +297,13 @@ void LoopDetector::initVectorField0() { |
|
|
|
// G A Kriezis的文章中的做法
|
|
|
|
// old version
|
|
|
|
void LoopDetector::initVectorField() { |
|
|
|
vectorFields = vector<vector<glm::vec2>>(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
vectorFields = vector<vector<glm::vec2> >(s_subPatchEdgeSampleCnt_u, vector<glm::vec2>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
for (int i = 0; i < s_subPatchEdgeSampleCnt_u; i++) { |
|
|
|
for (int j = 0; j < s_subPatchEdgeSampleCnt_v; j++) { |
|
|
|
auto fPtRelatedIdx = selectedPointsIdx[i][j]; |
|
|
|
auto n2 = f_normal[f_subPatchIdxRange_u.first + fPtRelatedIdx.first][f_subPatchIdxRange_v.first + |
|
|
|
fPtRelatedIdx.second]; |
|
|
|
// glm::vec3 n2(1.,0.,0.);
|
|
|
|
fPtRelatedIdx.second]; |
|
|
|
// glm::vec3 n2(1.,0.,0.);
|
|
|
|
auto ps_pu = s_tangent_u[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j]; |
|
|
|
auto ps_pv = s_tangent_v[s_subPatchIdxRange_u.first + i][s_subPatchIdxRange_v.first + j]; |
|
|
|
vectorFields[i][j] = glm::vec2(glm::dot(n2, ps_pu), glm::dot(n2, ps_pv)); |
|
|
@ -243,12 +317,12 @@ void LoopDetector::getRotationNumber() { |
|
|
|
auto edgeSampleCnt = s_evaluation.size(); |
|
|
|
auto uParamCellSize = (*(s.knots_u.end() - 1) - *s.knots_u.begin()) / (float) edgeSampleCnt; |
|
|
|
auto vParamCellSize = (*(s.knots_v.end() - 1) - *s.knots_v.begin()) / (float) edgeSampleCnt; |
|
|
|
// vector<vector<float>> pu_pt = {{0., 1.},
|
|
|
|
// {-1., 0.}};
|
|
|
|
// vector<vector<float>> pv_pt = {{1., 0.},
|
|
|
|
// {0., -1.}};
|
|
|
|
rotationNumbers = vector<vector<int>>(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<int>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
// vector<vector<float>> pu_pt = {{0., 1.},
|
|
|
|
// {-1., 0.}};
|
|
|
|
// vector<vector<float>> pv_pt = {{1., 0.},
|
|
|
|
// {0., -1.}};
|
|
|
|
rotationNumbers = vector<vector<int> >(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<int>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
|
|
|
|
// 以小格子为单位遍历
|
|
|
|
for (int i = 0; i < s_subPatchEdgeSampleCnt_u - 1; i++) { |
|
|
@ -261,11 +335,11 @@ void LoopDetector::getRotationNumber() { |
|
|
|
auto v = vectorFields[idxI][idxJ]; |
|
|
|
auto vSquareSum = v.x * v.x + v.y * v.y; |
|
|
|
auto pTheta_pChi = -v.y / vSquareSum; |
|
|
|
auto pTheta_pPhi = v.x / vSquareSum; |
|
|
|
// auto pChi_pu =
|
|
|
|
// (vectorFields[idxI + 1][idxJ].x - vectorFields[idxI - 1][idxJ].x) / (2 * uParamCellSize);
|
|
|
|
// auto pChi_pv =
|
|
|
|
// (vectorFields[idxI][idxJ + 1].x - vectorFields[idxI][idxJ - 1].x) / (2 * vParamCellSize);
|
|
|
|
auto pTheta_pPsi = v.x / vSquareSum; |
|
|
|
// auto pChi_pu =
|
|
|
|
// (vectorFields[idxI + 1][idxJ].x - vectorFields[idxI - 1][idxJ].x) / (2 * uParamCellSize);
|
|
|
|
// auto pChi_pv =
|
|
|
|
// (vectorFields[idxI][idxJ + 1].x - vectorFields[idxI][idxJ - 1].x) / (2 * vParamCellSize);
|
|
|
|
glm::vec2 pV_pu; |
|
|
|
glm::vec2 pV_pv; |
|
|
|
if (idxI == 0) |
|
|
@ -280,27 +354,27 @@ void LoopDetector::getRotationNumber() { |
|
|
|
pV_pv = (vectorFields[idxI][idxJ] - vectorFields[idxI][idxJ - 1]) / vParamCellSize; |
|
|
|
else |
|
|
|
pV_pv = (vectorFields[idxI][idxJ + 1] - vectorFields[idxI][idxJ - 1]) / (2 * vParamCellSize); |
|
|
|
F[biasI][biasJ] = pTheta_pChi * pV_pu.x + pTheta_pPhi * pV_pu.y; |
|
|
|
G[biasI][biasJ] = pTheta_pChi * pV_pv.x + pTheta_pPhi * pV_pv.y; |
|
|
|
F[biasI][biasJ] = pTheta_pChi * pV_pu.x + pTheta_pPsi * pV_pu.y; |
|
|
|
G[biasI][biasJ] = pTheta_pChi * pV_pv.x + pTheta_pPsi * pV_pv.y; |
|
|
|
} |
|
|
|
} |
|
|
|
rotationNumbers[i][j] = int( |
|
|
|
round(((F[0][1] + F[1][1] - F[0][0] - F[1][0]) * uParamCellSize + |
|
|
|
(G[0][0] + G[0][1] - G[1][0] - G[1][1]) * vParamCellSize)) / 2.); |
|
|
|
round(((F[0][1] + F[1][1] - F[0][0] - F[1][0]) * uParamCellSize + |
|
|
|
(G[0][0] + G[0][1] - G[1][0] - G[1][1]) * vParamCellSize)) / 2.); |
|
|
|
} |
|
|
|
} |
|
|
|
// int a = 3;
|
|
|
|
// int b = 1;
|
|
|
|
// int a = 3;
|
|
|
|
// int b = 1;
|
|
|
|
} |
|
|
|
|
|
|
|
// old version
|
|
|
|
void LoopDetector::getRotationNumber(const vector<pair<pair<int, int>, pair<int, int>>> &intersectBoxPairs) { |
|
|
|
void LoopDetector::getRotationNumber(const vector<pair<pair<int, int>, pair<int, int> > > &intersectBoxPairs) { |
|
|
|
// vectorFields的参数域是与s(第一个曲面)一致的
|
|
|
|
auto edgeSampleCnt = s_evaluation.size(); |
|
|
|
auto uParamCellSize = (*(s.knots_u.end() - 1) - *s.knots_u.begin()) / (float) edgeSampleCnt; |
|
|
|
auto vParamCellSize = (*(s.knots_v.end() - 1) - *s.knots_v.begin()) / (float) edgeSampleCnt; |
|
|
|
rotationNumbers = vector<vector<int>>(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<int>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
rotationNumbers = vector<vector<int> >(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<int>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
// 以小格子为单位遍历
|
|
|
|
for (const auto &boxPair: intersectBoxPairs) { |
|
|
|
float F[2][2], G[2][2]; |
|
|
@ -311,11 +385,11 @@ void LoopDetector::getRotationNumber(const vector<pair<pair<int, int>, pair<int, |
|
|
|
auto v = vectorFields[idxI][idxJ]; |
|
|
|
auto vSquareSum = v.x * v.x + v.y * v.y; |
|
|
|
auto pTheta_pChi = -v.y / vSquareSum; |
|
|
|
auto pTheta_pPhi = v.x / vSquareSum; |
|
|
|
// auto pChi_pu =
|
|
|
|
// (vectorFields[idxI + 1][idxJ].x - vectorFields[idxI - 1][idxJ].x) / (2 * uParamCellSize);
|
|
|
|
// auto pChi_pv =
|
|
|
|
// (vectorFields[idxI][idxJ + 1].x - vectorFields[idxI][idxJ - 1].x) / (2 * vParamCellSize);
|
|
|
|
auto pTheta_pPsi = v.x / vSquareSum; |
|
|
|
// auto pChi_pu =
|
|
|
|
// (vectorFields[idxI + 1][idxJ].x - vectorFields[idxI - 1][idxJ].x) / (2 * uParamCellSize);
|
|
|
|
// auto pChi_pv =
|
|
|
|
// (vectorFields[idxI][idxJ + 1].x - vectorFields[idxI][idxJ - 1].x) / (2 * vParamCellSize);
|
|
|
|
glm::vec2 pV_pu; |
|
|
|
glm::vec2 pV_pv; |
|
|
|
if (idxI == 0) |
|
|
@ -330,30 +404,27 @@ void LoopDetector::getRotationNumber(const vector<pair<pair<int, int>, pair<int, |
|
|
|
pV_pv = (vectorFields[idxI][idxJ] - vectorFields[idxI][idxJ - 1]) / vParamCellSize; |
|
|
|
else |
|
|
|
pV_pv = (vectorFields[idxI][idxJ + 1] - vectorFields[idxI][idxJ - 1]) / (2 * vParamCellSize); |
|
|
|
F[biasI][biasJ] = pTheta_pChi * pV_pu.x + pTheta_pPhi * pV_pu.y; |
|
|
|
G[biasI][biasJ] = pTheta_pChi * pV_pv.x + pTheta_pPhi * pV_pv.y; |
|
|
|
F[biasI][biasJ] = pTheta_pChi * pV_pu.x + pTheta_pPsi * pV_pu.y; |
|
|
|
G[biasI][biasJ] = pTheta_pChi * pV_pv.x + pTheta_pPsi * pV_pv.y; |
|
|
|
} |
|
|
|
} |
|
|
|
rotationNumbers[boxPair.first.first - s_subPatchIdxRange_u.first][boxPair.first.second - |
|
|
|
s_subPatchIdxRange_v.first] = int( |
|
|
|
round(((F[0][1] + F[1][1] - F[0][0] - F[1][0]) * uParamCellSize + |
|
|
|
(G[0][0] + G[0][1] - G[1][0] - G[1][1]) * vParamCellSize)) / 2.); |
|
|
|
round(((F[0][1] + F[1][1] - F[0][0] - F[1][0]) * uParamCellSize + |
|
|
|
(G[0][0] + G[0][1] - G[1][0] - G[1][1]) * vParamCellSize)) / 2.); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void LoopDetector::getRotationNumber(const map<pair<int, int>, set<pair<int, int>>> &intersectBoxPairs) { |
|
|
|
void LoopDetector::getRotationNumber(const map<pair<int, int>, set<pair<int, int> > > &intersectBoxPairs) { |
|
|
|
// vectorFields的参数域是与s(第一个曲面)一致的
|
|
|
|
auto edgeSampleCnt = s_evaluation.size(); |
|
|
|
auto uParamCellSize = (*(s.knots_u.end() - 1) - *s.knots_u.begin()) / (float) edgeSampleCnt; |
|
|
|
auto vParamCellSize = (*(s.knots_v.end() - 1) - *s.knots_v.begin()) / (float) edgeSampleCnt; |
|
|
|
rotationNumbers = vector<vector<int>>(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<int>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
rotationNumbers = vector<vector<int> >(s_subPatchEdgeSampleCnt_u, |
|
|
|
vector<int>(s_subPatchEdgeSampleCnt_v)); |
|
|
|
targetCells = {}; |
|
|
|
// 以小格子为单位遍历
|
|
|
|
for (const auto &boxPair: intersectBoxPairs) { |
|
|
|
if (boxPair.first.first == 127 && boxPair.first.second == 0) { |
|
|
|
int haha = 1; |
|
|
|
} |
|
|
|
float F[2][2], G[2][2]; |
|
|
|
for (int biasI = 0; biasI < 2; biasI++) { |
|
|
|
for (int biasJ = 0; biasJ < 2; biasJ++) { |
|
|
@ -361,12 +432,16 @@ void LoopDetector::getRotationNumber(const map<pair<int, int>, set<pair<int, int |
|
|
|
auto idxJ = boxPair.first.second + biasJ - s_subPatchIdxRange_v.first; |
|
|
|
auto v = vectorFields[idxI][idxJ]; |
|
|
|
auto vSquareSum = v.x * v.x + v.y * v.y; |
|
|
|
auto pTheta_pChi = -v.y / vSquareSum; |
|
|
|
auto pTheta_pPhi = v.x / vSquareSum; |
|
|
|
// auto pChi_pu =
|
|
|
|
// (vectorFields[idxI + 1][idxJ].x - vectorFields[idxI - 1][idxJ].x) / (2 * uParamCellSize);
|
|
|
|
// auto pChi_pv =
|
|
|
|
// (vectorFields[idxI][idxJ + 1].x - vectorFields[idxI][idxJ - 1].x) / (2 * vParamCellSize);
|
|
|
|
float pTheta_pChi = -1e6; |
|
|
|
float pTheta_pPsi = 1e6; |
|
|
|
if (vSquareSum != 0) { |
|
|
|
pTheta_pChi = -v.y / vSquareSum; |
|
|
|
pTheta_pPsi = v.x / vSquareSum; |
|
|
|
} |
|
|
|
// auto pChi_pu =
|
|
|
|
// (vectorFields[idxI + 1][idxJ].x - vectorFields[idxI - 1][idxJ].x) / (2 * uParamCellSize);
|
|
|
|
// auto pChi_pv =
|
|
|
|
// (vectorFields[idxI][idxJ + 1].x - vectorFields[idxI][idxJ - 1].x) / (2 * vParamCellSize);
|
|
|
|
glm::vec2 pV_pu; |
|
|
|
glm::vec2 pV_pv; |
|
|
|
if (idxI == 0) |
|
|
@ -381,26 +456,25 @@ void LoopDetector::getRotationNumber(const map<pair<int, int>, set<pair<int, int |
|
|
|
pV_pv = (vectorFields[idxI][idxJ] - vectorFields[idxI][idxJ - 1]) / vParamCellSize; |
|
|
|
else |
|
|
|
pV_pv = (vectorFields[idxI][idxJ + 1] - vectorFields[idxI][idxJ - 1]) / (2 * vParamCellSize); |
|
|
|
F[biasI][biasJ] = pTheta_pChi * pV_pu.x + pTheta_pPhi * pV_pu.y; |
|
|
|
G[biasI][biasJ] = pTheta_pChi * pV_pv.x + pTheta_pPhi * pV_pv.y; |
|
|
|
F[biasI][biasJ] = pTheta_pChi * pV_pu.x + pTheta_pPsi * pV_pu.y; |
|
|
|
G[biasI][biasJ] = pTheta_pChi * pV_pv.x + pTheta_pPsi * pV_pv.y; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int rotationNumber = int(round(((F[0][1] + F[1][1] - F[0][0] - F[1][0]) * uParamCellSize + |
|
|
|
(G[0][0] + G[0][1] - G[1][0] - G[1][1]) * vParamCellSize)) / 2.); |
|
|
|
(G[0][0] + G[0][1] - G[1][0] - G[1][1]) * vParamCellSize)) / (2.)); |
|
|
|
rotationNumbers[boxPair.first.first - s_subPatchIdxRange_u.first][boxPair.first.second - |
|
|
|
s_subPatchIdxRange_v.first] = rotationNumber; |
|
|
|
if (rotationNumber != 0) { |
|
|
|
targetCells.insert({{boxPair.first.first, boxPair.first.second}, rotationNumber}); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// old version
|
|
|
|
vector<pair<int, int>> LoopDetector::detect(pair<int, int> _s_subPatchIdxRange_u, pair<int, int> _s_subPatchIdxRange_v, |
|
|
|
pair<int, int> _f_subPatchIdxRange_u, |
|
|
|
pair<int, int> _f_subPatchIdxRange_v) { |
|
|
|
vector<pair<int, int> > LoopDetector::detect(pair<int, int> _s_subPatchIdxRange_u, pair<int, int> _s_subPatchIdxRange_v, |
|
|
|
pair<int, int> _f_subPatchIdxRange_u, |
|
|
|
pair<int, int> _f_subPatchIdxRange_v) { |
|
|
|
s_subPatchIdxRange_u = _s_subPatchIdxRange_u; |
|
|
|
s_subPatchIdxRange_v = _s_subPatchIdxRange_v; |
|
|
|
f_subPatchIdxRange_u = _f_subPatchIdxRange_u; |
|
|
@ -418,10 +492,10 @@ vector<pair<int, int>> LoopDetector::detect(pair<int, int> _s_subPatchIdxRange_u |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
vector<pair<int, int>> LoopDetector::detect(const map<pair<int, int>, set<pair<int, int>>> &intersectBoxPairs, |
|
|
|
pair<int, int> _s_subPatchIdxRange_u, pair<int, int> _s_subPatchIdxRange_v, |
|
|
|
pair<int, int> _f_subPatchIdxRange_u, |
|
|
|
pair<int, int> _f_subPatchIdxRange_v) { |
|
|
|
vector<pair<int, int> > LoopDetector::detect(const map<pair<int, int>, set<pair<int, int> > > &intersectBoxPairs, |
|
|
|
pair<int, int> _s_subPatchIdxRange_u, pair<int, int> _s_subPatchIdxRange_v, |
|
|
|
pair<int, int> _f_subPatchIdxRange_u, |
|
|
|
pair<int, int> _f_subPatchIdxRange_v) { |
|
|
|
s_subPatchIdxRange_u = _s_subPatchIdxRange_u; |
|
|
|
s_subPatchIdxRange_v = _s_subPatchIdxRange_v; |
|
|
|
f_subPatchIdxRange_u = _f_subPatchIdxRange_u; |
|
|
@ -437,5 +511,3 @@ vector<pair<int, int>> LoopDetector::detect(const map<pair<int, int>, set<pair<i |
|
|
|
getRotationNumber(intersectBoxPairs); |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|