From 50c2dad8367dc00326d377d62abae879c9ec44de Mon Sep 17 00:00:00 2001 From: Dtouch Date: Sun, 25 Dec 2022 21:26:42 +0800 Subject: [PATCH] Gauss map overlap judgement for sub-domains of parameter domain --- include/gauss_map.h | 51 ++++++++++++++++++++++++-- main.cpp | 25 +++++++------ src/gauss_map.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 15 deletions(-) diff --git a/include/gauss_map.h b/include/gauss_map.h index e5aa549..da99c22 100644 --- a/include/gauss_map.h +++ b/include/gauss_map.h @@ -4,6 +4,7 @@ #ifndef GAUSSMAP_GAUSS_MAP_H #define GAUSSMAP_GAUSS_MAP_H + #include "vector" #include "tinynurbs/tinynurbs.h" #include "glm/glm.hpp" @@ -18,20 +19,62 @@ struct GaussMapNode { }; class GaussMap { +public: int maxLevel; int leafSampleCnt; std::vector> normals; tinynurbs::RationalSurface srf; - void recursiveBuild(int level, int idx, int idx_u, int idx_v); -public: std::vector tree; + + void recursiveBuild(int level, int idx, int idx_u, int idx_v); + GaussMap(int maxLevel, tinynurbs::RationalSurface srf_); + void build(); + void normalInit(); + + void printQuadTree(); }; -std::vector> getOverlapLeafNodes(const GaussMap& gm1, const GaussMap& gm2); +std::vector> getOverlapLeafNodes(const GaussMap &gm1, const GaussMap &gm2); + +void recursiveGetOverlapLeafNodes(const GaussMap &gm1, const GaussMap &gm2, int idx1, int idx2, + std::vector> &pairs); + +/** + * 判断两个曲面的Gauss Map在指定的、各自的参数范围内有没有交 + * @param idxRange_u1 第一个gauss map的参数u范围对应的u方向上的采样网格的格子下标范围 + * @param idxRange_v1 第一个gauss map的参数v范围对应的u方向上的采样网格的格子下标范围 + * @param idxRange_u2 第而个gauss map的参数u范围对应的u方向上的采样网格的格子下标范围 + * @param idxRange_v2 第二个gauss map的参数v范围对应的u方向上的采样网格的格子下标范围 + * @return true:gauss map的包围盒有交集,说明gauss map<可能>有重合;false: gauss map一定没有重合 + */ +bool isGaussMapsOverlapped(const GaussMap &gm1, const GaussMap &gm2, std::pair idxRange_u1, + std::pair idxRange_v1, std::pair idxRange_u2, + std::pair idxRange_v2); + +/** + * 判断两个曲面的Gauss Map在指定的、各自的参数范围内有没有交 + * @param range_u1 第一个gauss map的参数u范围 + * @param range_v1 第一个gauss map的参数v范围 + * @param range_u2 第二个gauss map的参数u范围 + * @param range_v2 第二个gauss map的参数v范围 + * @param paramRange_u1 第一个gauss map的参数u定义域 + * @param paramRange_v1 第一个gauss map的参数v定义域 + * @param paramRange_u2 第二个gauss map的参数u定义域 + * @param paramRange_v2 第二个gauss map的参数v定义域 + * @return true:gauss map的包围盒有交集,说明gauss map<可能>有重合;false: gauss map一定没有重合 + */ +bool isGaussMapsOverlapped(const GaussMap &gm1, const GaussMap &gm2, std::pair range_u1, + std::pair range_v1, std::pair range_u2, + std::pair range_v2, std::pair paramRange_u1, + std::pair paramRange_v1, + std::pair paramRange_u2, + std::pair paramRange_v2); + +int getStartIdxOfLayerN(int layer); -void recursiveGetOverlapLeafNodes(const GaussMap& gm1, const GaussMap& gm2, int idx1, int idx2, std::vector>& pairs); +int getChildNodeIdx(int ix, int iy); #endif //GAUSSMAP_GAUSS_MAP_H diff --git a/main.cpp b/main.cpp index ba346f0..462b17b 100644 --- a/main.cpp +++ b/main.cpp @@ -5,10 +5,10 @@ int main() { tinynurbs::RationalSurface srf; srf.degree_u = 3; srf.degree_v = 3; - srf.knots_u = { 0, 0, 0, 0, 1, 1, 1, 1 }; - srf.knots_v = { 0, 0, 0, 0, 1, 1, 1, 1 }; + srf.knots_u = {0, 0, 0, 0, 1, 1, 1, 1}; + srf.knots_v = {0, 0, 0, 0, 1, 1, 1, 1}; - srf.control_points = { 4, 4, { + srf.control_points = {4, 4, { glm::vec3(2, -2, -2), glm::vec3(-2.5, -2.2, -1.5), glm::vec3(-2, -2, -0.5), glm::vec3(-2, -2, 1.5), glm::vec3(2, -1, -2), glm::vec3(-2.5, -1.2, -1.5), glm::vec3(-2, -1, -0.5), glm::vec3(-2, -1, 1.5), glm::vec3(3, 1.2, -2), glm::vec3(-2.5, 1.2, -1.5), glm::vec3(-2, 1.5, -0.5), glm::vec3(-2, 1.5, 1.5), @@ -16,17 +16,20 @@ int main() { } }; - srf.weights = { 4, 4, - { - 1, 3, 4, 2, - 2, 1, 1, 1, - 9, 1, 7, 4, - 1, 1, 7, 1, - } + srf.weights = {4, 4, + { + 1, 3, 4, 2, + 2, 1, 1, 1, + 9, 1, 7, 4, + 1, 1, 7, 1, + } }; - GaussMap gaussMap(6, srf); + GaussMap gaussMap(2, srf); gaussMap.build(); auto res = getOverlapLeafNodes(gaussMap, gaussMap); printf("overlap leaf nodes size: %llu\n", res.size()); + auto isRegionallyOverlapped = isGaussMapsOverlapped(gaussMap, gaussMap, {0.2, 0.3}, {0.2, 0.3}, {0.28, 0.38}, + {0.28, 0.38}, {0, 1}, {0, 1}, {0, 1}, {0, 1}); + printf("is guass map overlapped: %d\n", isRegionallyOverlapped); return 0; } diff --git a/src/gauss_map.cpp b/src/gauss_map.cpp index 57b3349..aa7e255 100644 --- a/src/gauss_map.cpp +++ b/src/gauss_map.cpp @@ -65,6 +65,18 @@ void GaussMap::build() { recursiveBuild(1, 0, 0, 0); } +void GaussMap::printQuadTree() { + for (int l = 1, levelNodesCnt = 1, baseIdx = 0; l <= maxLevel; l++, levelNodesCnt *= 4, baseIdx = baseIdx * 4 + 1) { + for (int biasIdx = 0; biasIdx < levelNodesCnt; biasIdx++) { + int idx = baseIdx + biasIdx; + auto pMax = tree[idx].nBound.pMax; + auto pMin = tree[idx].nBound.pMin; + printf("<<%g, %g, %g>,<%g, %g, %g>> ", pMin.x, pMin.y, pMin.z, pMax.x, pMax.y, pMax.z); + } + printf("\n =============$$$$$$$============= \n"); + } +} + std::vector> getOverlapLeafNodes(const GaussMap &gm1, const GaussMap &gm2) { std::vector> resPairs; recursiveGetOverlapLeafNodes(gm1, gm2, 0, 0, resPairs); @@ -104,3 +116,80 @@ void recursiveGetOverlapLeafNodes(const GaussMap &gm1, const GaussMap &gm2, int } } } + +bool isGaussMapsOverlapped(const GaussMap &gm1, const GaussMap &gm2, std::pair range_u1, + std::pair range_v1, std::pair range_u2, + std::pair range_v2, std::pair paramRange_u1, + std::pair paramRange_v1, std::pair paramRange_u2, + std::pair paramRange_v2) { + if (gm1.maxLevel != gm2.maxLevel || gm1.maxLevel <= 0) { + printf("BVH Layer error!\n"); + return false; + } + int edgeCellCnt = pow(2, gm1.maxLevel - 1); + // 根据所给参数的范围和参数的定义域范围,获得对应的采样网格中的范围 + auto getIdxRange = [](std::pair range, std::pair paramRange, int edgeCellCnt) { + float paramStep = (paramRange.second - paramRange.first) / edgeCellCnt; + return std::pair({int((range.first - paramRange.first) / paramStep), + int((range.second - paramRange.first) / paramStep)}); + }; + auto idxRange_u1 = getIdxRange(range_u1, paramRange_u1, edgeCellCnt); + auto idxRange_v1 = getIdxRange(range_v1, paramRange_v1, edgeCellCnt); + auto idxRange_u2 = getIdxRange(range_u2, paramRange_u2, edgeCellCnt); + auto idxRange_v2 = getIdxRange(range_v2, paramRange_v2, edgeCellCnt); + return isGaussMapsOverlapped(gm1, gm2, idxRange_u1, idxRange_v1, idxRange_u2, idxRange_v2); +} + +bool isGaussMapsOverlapped(const GaussMap &gm1, const GaussMap &gm2, std::pair idxRange_u1, + std::pair idxRange_v1, std::pair idxRange_u2, + std::pair idxRange_v2) { + if (gm1.maxLevel != gm2.maxLevel || gm1.maxLevel <= 0) { + printf("BVH Layer error!\n"); + return false; + } + int commonMaxLayer = gm1.maxLevel; + int edgeCellCnt = pow(2, commonMaxLayer - 1); + if (idxRange_u1.first < 0 || idxRange_u2.first < 0 || idxRange_v1.first < 0 || idxRange_v2.first < 0 || + idxRange_u1.second >= edgeCellCnt || idxRange_u2.second >= edgeCellCnt || + idxRange_v1.second >= edgeCellCnt || idxRange_v2.second >= edgeCellCnt) { + printf("Error when detecting overlapping: idx range invalid!\n"); + return false; + } + auto getRangedBox = [&commonMaxLayer](const GaussMap &gm, const std::pair &idxRange_u, + const std::pair idxRange_v) { + AABB bounding; + for (int i = idxRange_u.first; i <= idxRange_u.second; ++i) { + for (int j = idxRange_v.first; j <= idxRange_v.second; ++j) { + bounding = Union(bounding, + gm.tree[getStartIdxOfLayerN(commonMaxLayer) + getChildNodeIdx(i, j)].nBound); + } + } + return bounding; + }; + return IsOverlap(getRangedBox(gm1, idxRange_u1, idxRange_v1), getRangedBox(gm2, idxRange_u2, idxRange_v2)); +} + +int getStartIdxOfLayerN(int layer) { + if (layer == 1) return 0; + int num = 1; + // 找规律得出 + for (int i = 2; i < layer; i++) { + num = num * 4 + 1; + } + return num; +} + +int getChildNodeIdx(int ix, int iy) { + int idx = 0; + while (ix > 0) { + int log2XCeil = int(log2f(ix)); + idx += int(pow(4, log2XCeil)); + ix -= int(pow(2, log2XCeil)); + } + while (iy > 0) { + int log2XCeil = int(log2f(iy)); + idx += 2 * int(pow(4, log2XCeil)); + iy -= int(pow(2, log2XCeil)); + } + return idx; +} \ No newline at end of file