|
|
@ -1,7 +1,6 @@ |
|
|
|
#include "SingularityJudger.h" |
|
|
|
|
|
|
|
#include <utility> |
|
|
|
#include "loop_detector.h" |
|
|
|
#include "C2C4.h" |
|
|
|
#include "set" |
|
|
|
#include "utils.h" |
|
|
@ -55,8 +54,8 @@ SingularityJudger(RationalSurface<float> &srf1_, RationalSurface<float> &srf2_, |
|
|
|
: srf1(srf1_), srf2(srf2_), mesh1(mesh1_), mesh2(mesh2_), |
|
|
|
gaussMap1(GaussMap(mesh1_.normal)), gaussMap2(GaussMap(mesh2_.normal)) { |
|
|
|
gaussMapTimeCost = utils::get_time(); |
|
|
|
gaussMap1.build(); |
|
|
|
gaussMap2.build(); |
|
|
|
// gaussMap1.build();
|
|
|
|
// gaussMap2.build();
|
|
|
|
gaussMapTimeCost = utils::get_time() - gaussMapTimeCost; |
|
|
|
} |
|
|
|
|
|
|
@ -73,8 +72,8 @@ void SingularityJudger::judge2(pair<int, int> focusRange_u1, pair<int, int> focu |
|
|
|
c2C4.c2OrC4(focusRange_u1.first, focusRange_v1.first, focusRange_u2.first, focusRange_v2.first).first); |
|
|
|
} |
|
|
|
|
|
|
|
bool hasPair(vector<pair<pair<int, int>, pair<int, int>>> pairs, pair<int, int> p) { |
|
|
|
for (auto e: pairs) { |
|
|
|
bool hasPair(const map<pair<int, int>, set<pair<int, int>>> &pairs, pair<int, int> p) { |
|
|
|
for (const auto &e: pairs) { |
|
|
|
if (p == e.first)return true; |
|
|
|
} |
|
|
|
return false; |
|
|
@ -89,55 +88,83 @@ judge(const vector<pair<pair<int, int>, pair<int, int>>> &intersectBoxPairs, |
|
|
|
int keepCnt = 0; |
|
|
|
map<pair<int, int>, set<pair<int, int>>> pairMap; |
|
|
|
double time_record = utils::get_time(); |
|
|
|
// auto gmPairMap = getOverlapLeafNodes(gaussMap1, gaussMap2);
|
|
|
|
for (const auto &boxPair: intersectBoxPairs) { |
|
|
|
if (isGaussMapsOverlapped(gaussMap1, gaussMap2, {boxPair.first.first, boxPair.first.first}, |
|
|
|
{boxPair.second.first, boxPair.second.first}, |
|
|
|
{boxPair.first.second, boxPair.first.second}, |
|
|
|
{boxPair.second.second, boxPair.second.second})) { |
|
|
|
if (isLeafNodesOverlapped(gaussMap1, gaussMap2, boxPair.first, boxPair.second)) { |
|
|
|
pairMap[boxPair.first].insert(boxPair.second); |
|
|
|
keepCnt++; |
|
|
|
} |
|
|
|
// if (isGaussMapsOverlapped(gaussMap1, gaussMap2, {boxPair.first.first, boxPair.first.first},
|
|
|
|
// {boxPair.second.first, boxPair.second.first},
|
|
|
|
// {boxPair.first.second, boxPair.first.second},
|
|
|
|
// {boxPair.second.second, boxPair.second.second})) {
|
|
|
|
// pairMap[boxPair.first].insert(boxPair.second);
|
|
|
|
// keepCnt++;
|
|
|
|
// }
|
|
|
|
// if (isGaussMapsOverlapped(gaussMap1, gaussMap2, {boxPair.first.first, boxPair.first.first},
|
|
|
|
// {boxPair.first.second, boxPair.first.second},
|
|
|
|
// {boxPair.second.first, boxPair.second.first},
|
|
|
|
// {boxPair.second.second, boxPair.second.second})) {
|
|
|
|
// pairMap[boxPair.first].insert(boxPair.second);
|
|
|
|
// keepCnt++;
|
|
|
|
// }
|
|
|
|
// if (true) {
|
|
|
|
// pairMap[boxPair.first].insert(boxPair.second);
|
|
|
|
// keepCnt++;
|
|
|
|
// }
|
|
|
|
// if (gmPairMap.find(boxPair.first) != gmPairMap.end() &&
|
|
|
|
// gmPairMap[boxPair.first].find(boxPair.second) != gmPairMap[boxPair.first].end()) {
|
|
|
|
// pairMap[boxPair.first].insert(boxPair.second);
|
|
|
|
// keepCnt++;
|
|
|
|
// }
|
|
|
|
} |
|
|
|
gaussMapTimeCost += utils::get_time() - time_record; |
|
|
|
printf("time cost of Gauss Map: %lf\n", gaussMapTimeCost); |
|
|
|
printf("the gauss map kept %d boxes in totally %lld.\n", keepCnt, originBoxCnt); |
|
|
|
// if (!isGaussMapsOverlapped(gaussMap1, gaussMap2, focusRange_u1, focusRange_u2, focusRange_v1, focusRange_v2)) {
|
|
|
|
// // 一定没有交
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// TODO loop detection to retain patch pair that must have loop or singular intersection
|
|
|
|
LoopDetector loopDetector(mesh1.evaluation, mesh2.evaluation, mesh1.tangent_u, mesh2.tangent_u, mesh1.tangent_v, |
|
|
|
mesh2.tangent_v, mesh1.normal, mesh2.normal, srf1); |
|
|
|
loopDetector.detect(intersectBoxPairs, focusRange_u1, focusRange_v1, focusRange_u2, focusRange_v2); |
|
|
|
loopDetector.detect(pairMap, focusRange_u1, focusRange_v1, focusRange_u2, focusRange_v2); |
|
|
|
judgeRes = vector<vector<char>>(loopDetector.s_subPatchEdgeSampleCnt_u - 1, |
|
|
|
vector<char>(loopDetector.s_subPatchEdgeSampleCnt_v - 1, 0)); |
|
|
|
// TODO c2 determination for tangency case
|
|
|
|
bool hasLoop = false; |
|
|
|
C2C4 c2C4(mesh1, mesh2, srf1, srf2); |
|
|
|
for (int i = 0; i < judgeRes.size(); i++) { |
|
|
|
for (int j = 0; j < judgeRes[0].size(); j++) { |
|
|
|
if (loopDetector.rotationNumbers[i][j] != 0) { |
|
|
|
if (!hasPair(intersectBoxPairs, {focusRange_u1.first + i, focusRange_v1.first + j})) { |
|
|
|
// 不在相交box pairs中
|
|
|
|
continue; |
|
|
|
} |
|
|
|
hasLoop = true; |
|
|
|
|
|
|
|
printf("(%d, %d) ", focusRange_u1.first + i, focusRange_v1.first + j); |
|
|
|
// 非零,有loop
|
|
|
|
// 依次测试C2
|
|
|
|
// auto accordPointOnF = loopDetector.selectedPointsIdx[i][j]; // 有向距离最短的,f曲面上的对应面片的坐标
|
|
|
|
// if (c2C4.c2OrC4(focusRange_u1.first + i, focusRange_v1.first + j,
|
|
|
|
// focusRange_u2.first + accordPointOnF.first,
|
|
|
|
// focusRange_v2.first + accordPointOnF.second).first) {
|
|
|
|
// //C2
|
|
|
|
// judgeRes[i][j] = -1;
|
|
|
|
// printf("singular point: s:(%d,%d), f:(%d,%d)\n", focusRange_u1.first + i, focusRange_v1.first + j,
|
|
|
|
// focusRange_u2.first + accordPointOnF.first, focusRange_v2.first + accordPointOnF.second);
|
|
|
|
// } else judgeRes[i][j] = 1; // 圆环
|
|
|
|
} else { |
|
|
|
judgeRes[i][j] = 0; // 0表示啥也没有
|
|
|
|
} |
|
|
|
|
|
|
|
for (auto targetCell: loopDetector.targetCells) { |
|
|
|
printf("{%d, %d}, ", targetCell.first, targetCell.second); |
|
|
|
} |
|
|
|
printf("\ntarget cells cnt: %lld\n", loopDetector.targetCells.size()); |
|
|
|
|
|
|
|
/**
|
|
|
|
* 合并相邻盒子 |
|
|
|
*/ |
|
|
|
vector<vector<pair<int, int>>> cellGroups; |
|
|
|
set<pair<int, int>> book; |
|
|
|
int groupNum = 0; |
|
|
|
for (auto targetCell: loopDetector.targetCells) { |
|
|
|
if (book.find(targetCell) != book.end()) continue; |
|
|
|
cellGroups.emplace_back(); |
|
|
|
dfs(book, cellGroups, loopDetector, groupNum++, targetCell.first, targetCell.second); |
|
|
|
} |
|
|
|
for(const auto& cellGroup: cellGroups) |
|
|
|
{ |
|
|
|
printf("{"); |
|
|
|
for(int i = 0; i < cellGroup.size(); i++) { |
|
|
|
printf("{%d, %d}", cellGroup[i].first, cellGroup[i].second); |
|
|
|
if(i != cellGroup.size()-1)printf(", "); |
|
|
|
} |
|
|
|
printf("},\n"); |
|
|
|
} |
|
|
|
// TODO c2 determination for tangency case
|
|
|
|
// C2C4 c2C4(mesh1, mesh2, srf1, srf2);
|
|
|
|
} |
|
|
|
|
|
|
|
void SingularityJudger::dfs(set<pair<int, int>> &book, vector<vector<pair<int, int>>> &cellGroups, |
|
|
|
const LoopDetector &loopDetector, int i, int x, int y) { |
|
|
|
book.insert({x, y}); |
|
|
|
cellGroups[i].emplace_back(pair<int, int>(x, y)); |
|
|
|
for (auto dir: dirs) { |
|
|
|
auto nx = x + dir[0], ny = y + dir[1]; |
|
|
|
if (book.find({nx, ny}) != book.end() || loopDetector.rotationNumbers[nx][ny] == 0)continue; |
|
|
|
dfs(book, cellGroups, loopDetector, i, nx, ny); |
|
|
|
} |
|
|
|
} |