diff --git a/CMakeLists.txt b/CMakeLists.txt index 213f296..683c299 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,16 +10,15 @@ include_directories(E:/CLib/tinynurbs/include E:/CLib/glm) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) +AUX_SOURCE_DIRECTORY(src DIR_SRCS) +AUX_SOURCE_DIRECTORY(include DIR_INCLUDE) -add_executable(SingularityJudger main.cpp - include/loop_detector.h src/loop_detector.cpp - include/gauss_map.h src/gauss_map.cpp - include/aabb.h src/aabb.cpp - include/C2C4.h src/C2C4.cpp - include/Range.h src/Range.cpp - include/bvh.h src/bvh.cpp - include/utils.h src/utils.cpp - src/SingularityJudger.cpp include/SingularityJudger.h src/srf_mesh.cpp include/srf_mesh.h) +# 生成可执行文件 +add_executable(SingularityJudger main.cpp ${DIR_SRCS} ${DIR_INCLUDE}) + +# 生成静态库 +#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +#add_library(SingularityJudger ${DIR_SRCS}) # 将intersectTest的内容拷贝到build文件夹下 # 参考https://stackoverflow.com/questions/13429656/how-to-copy-contents-of-a-directory-into-build-directory-after-make-with-cmake diff --git a/README.md b/README.md index 93b6a1e..d11951b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,59 @@ # SingularityJudger -Integration of gauss map, osculating toroidal patches, loop detection and C2 judgement to figure out the singular or loop intersection. \ No newline at end of file +Integration of gauss map, osculating toroidal patches, loop detection and C2 judgement to figure out the singular or loop intersection. + +## Usage +CmakeLists.txt中将以下两行改为自己tinynurbs和glm的依赖路径 +```cmake +include_directories(E:/CLib/tinynurbs/include E:/CLib/glm) +``` +### 直接运行 +直接cmake构建,make编译链接,运行可执行文件即可 +### 生成依赖库 +1. CMakeLists.txt中注释以下代码 +```cmake +add_executable(SingularityJudger main.cpp ${DIR_SRCS} ${DIR_INCLUDE}) + +# 下面两个仅仅是main文件的依赖,用于对读取的曲面文本文件做字符串处理 +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) +``` +2. CMakeLists.txt中取消注释以下代码 +```cmake +#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +#add_library(SingularityJudger ${DIR_SRCS}) +``` +3. CMake构建,make生成 +### 具体使用 +```c++ +#include "bvh.h" +#include "singularityJudger.h" +// 创建两个曲面 +tinynursb::RationalSurface s; +tinynursb::RationalSurface f; +// 曲面初始化 +... + +// 采样层数 +int level = 6; +// 得到两个曲面level层的采样信息 +// 如果已经采样过,这里用SrfMesh的无参构造,然后把采样的网格数据传入,避免重复采样 +auto mesh1 = SrfMesh(s, level); +auto mesh2 = SrfMesh(f, level); + +// 构建BVH +BVH bvh1(mesh1.evaluation); +BVH bvh2(mesh2.evaluation); +bvh1.build(); +bvh2.build(); +// bvh判交,获得重叠盒子对 +auto intersectBoxPairs = getOverlapLeafNodes(bvh1, bvh2); // return [{{u1, v1}, {u2, v2}}] + +// 创建SingularityJudger对象 +SingularityJudger singularityJudger(s, f, mesh1, mesh2); + +// 对于两个曲面各自的参数下标范围所确定的两个子面片,判断哪些小格子内存在critical point +// 一般就用完整的参数下标范围,即{0, pow(2, level - 1) - 1} +pair cellIdxFullRange = {0, pow(2, level - 1) - 1}; +auto cellsWithCriticalPts = singularityJudger.judge(intersectBoxPairs, cellIdxFullRange, cellIdxFullRange, cellIdxFullRange, cellIdxFullRange); +``` \ No newline at end of file diff --git a/include/SingularityJudger.h b/include/SingularityJudger.h index 78c0ce1..aaf8606 100644 --- a/include/SingularityJudger.h +++ b/include/SingularityJudger.h @@ -37,7 +37,7 @@ public: void judge2(pair focusRange_u1, pair focusRange_v1, pair focusRange_u2, pair focusRange_v2); - void judge(const vector, pair>> &intersectBoxPairs, + vector> judge(const vector, pair>> &intersectBoxPairs, pair focusRange_u1, pair focusRange_v1, pair focusRange_u2, pair focusRange_v2); diff --git a/include/srf_mesh.h b/include/srf_mesh.h index f1f0b5f..01468f8 100644 --- a/include/srf_mesh.h +++ b/include/srf_mesh.h @@ -3,10 +3,14 @@ #include "vector" #include "glm/glm.hpp" +#include "tinynurbs/tinynurbs.h" + using namespace std; // 用采样网格表示的一个曲面 class SrfMesh { public: + SrfMesh(const tinynurbs::RationalSurface &s, int sampleLevel_); + SrfMesh() = default; int sampleLevel; // 采样层级;每多一层,uv方向的网格数都分别x2,整个mesh的网格数x4;sampleLevel为1时,采样整个面,仅有一个网格 int sampleCntOnSingleDir; vector> evaluation; diff --git a/main.cpp b/main.cpp index 38b3982..2fc0c0d 100644 --- a/main.cpp +++ b/main.cpp @@ -162,49 +162,6 @@ void sampleTimeTestNonRational(const RationalSurface &s_, int sampleLevel } -SrfMesh getMesh(const RationalSurface &s, int sampleLevel) { - SrfMesh res; - res.sampleLevel = sampleLevel; - auto sampleCnt = res.sampleCntOnSingleDir = int(pow(2, sampleLevel - 1) + 1); - res.evaluation = vector>(res.sampleCntOnSingleDir, vector(res.sampleCntOnSingleDir)); - res.tangent_u = vector>(res.sampleCntOnSingleDir, vector(res.sampleCntOnSingleDir)); - res.tangent_v = vector>(res.sampleCntOnSingleDir, vector(res.sampleCntOnSingleDir)); - res.normal = vector>(res.sampleCntOnSingleDir, vector(res.sampleCntOnSingleDir)); - - auto s_first_u = *(s.knots_u.begin()); - auto s_first_v = *(s.knots_v.begin()); - auto s_step_u = (*(s.knots_u.end() - 1) - s_first_u) / float(res.sampleCntOnSingleDir - 1); - auto s_step_v = (*(s.knots_v.end() - 1) - s_first_v) / float(res.sampleCntOnSingleDir - 1); - - // evaluation correction test - auto u = 0.35f; - auto v = 0.35f; - auto pt = tinynurbs::surfacePoint(s, u, v); - printf("pt on u = %g, v = %g is (%f, %f, %f)\n", u, v, pt.x, pt.y, pt.z); - auto der = tinynurbs::surfaceDerivatives(s, 1, u, v); - auto du = der(1, 0); - auto dv = der(0, 1); - printf("derivatives of u when u = %g, v = %g is (%f, %f, %f)\n", u, v, du.x, du.y, du.z); - printf("derivatives of v when u = %g, v = %g is (%f, %f, %f)\n", u, v, dv.x, dv.y, dv.z); - // end of correction test - - for (int i = 0; i < sampleCnt; i++) { - auto u = s_first_u + s_step_u * float(i); - for (int j = 0; j < sampleCnt; j++) { - auto v = s_first_v + s_step_v * float(j); - res.evaluation[i][j] = tinynurbs::surfacePoint(s, u, v); - auto der = tinynurbs::surfaceDerivatives(s, 1, u, v); -// if(der(0, 0) == res.evaluation[i][j]) cout<<"amazing"< s; RationalSurface f; - int level = 6; printf("level: %d, sample cnt: %d * %d\n", level, int(pow(2, level - 1)), int(pow(2, level - 1))); @@ -307,8 +263,8 @@ int main() { // sampleTimeTestNonRational(s, level); sampleTimeTest(s, level); - auto mesh1 = getMesh(s, level); - auto mesh2 = getMesh(f, level); + auto mesh1 = SrfMesh(s, level); + auto mesh2 = SrfMesh(f, level); BVH bvh1(mesh1.evaluation); BVH bvh2(mesh2.evaluation); @@ -345,7 +301,7 @@ int main() { SingularityJudger singularityJudger(s, f, mesh1, mesh2); pair cellIdxFullRange = {0, pow(2, level - 1) - 1}; - singularityJudger.judge(intersectBoxPairs, cellIdxFullRange, cellIdxFullRange, cellIdxFullRange, cellIdxFullRange); + auto cellsWithCriticalPts = singularityJudger.judge(intersectBoxPairs, cellIdxFullRange, cellIdxFullRange, cellIdxFullRange, cellIdxFullRange); time_cost = utils::get_time() - time_cost; printf("time cost of singularityJudger: %lf\n", time_cost); diff --git a/src/SingularityJudger.cpp b/src/SingularityJudger.cpp index 066708c..6be6b2f 100644 --- a/src/SingularityJudger.cpp +++ b/src/SingularityJudger.cpp @@ -81,7 +81,7 @@ bool hasPair(const map, set>> &pairs, pair> SingularityJudger:: judge(const vector, pair>> &intersectBoxPairs, pair focusRange_u1, pair focusRange_v1, pair focusRange_u2, pair focusRange_v2) { @@ -163,6 +163,7 @@ judge(const vector, pair>> &intersectBoxPairs, // } // TODO c2 determination for tangency case // C2C4 c2C4(mesh1, mesh2, srf1, srf2); + return loopDetector.targetCells; } void SingularityJudger:: dfs(set> &book, vector>> &cellGroups, diff --git a/src/srf_mesh.cpp b/src/srf_mesh.cpp index 45f5aa8..ac8e6f0 100644 --- a/src/srf_mesh.cpp +++ b/src/srf_mesh.cpp @@ -1 +1,40 @@ #include "srf_mesh.h" + +SrfMesh::SrfMesh(const tinynurbs::RationalSurface &s, int sampleLevel_): sampleLevel(sampleLevel_) { + auto sampleCnt = sampleCntOnSingleDir = int(pow(2, sampleLevel - 1) + 1); + evaluation = vector>(sampleCntOnSingleDir, vector(sampleCntOnSingleDir)); + tangent_u = vector>(sampleCntOnSingleDir, vector(sampleCntOnSingleDir)); + tangent_v = vector>(sampleCntOnSingleDir, vector(sampleCntOnSingleDir)); + normal = vector>(sampleCntOnSingleDir, vector(sampleCntOnSingleDir)); + + auto s_first_u = *(s.knots_u.begin()); + auto s_first_v = *(s.knots_v.begin()); + auto s_step_u = (*(s.knots_u.end() - 1) - s_first_u) / float(sampleCntOnSingleDir - 1); + auto s_step_v = (*(s.knots_v.end() - 1) - s_first_v) / float(sampleCntOnSingleDir - 1); + + // evaluation correction test + auto u = 0.35f; + auto v = 0.35f; + auto pt = tinynurbs::surfacePoint(s, u, v); + printf("pt on u = %g, v = %g is (%f, %f, %f)\n", u, v, pt.x, pt.y, pt.z); + auto der = tinynurbs::surfaceDerivatives(s, 1, u, v); + auto du = der(1, 0); + auto dv = der(0, 1); + printf("derivatives of u when u = %g, v = %g is (%f, %f, %f)\n", u, v, du.x, du.y, du.z); + printf("derivatives of v when u = %g, v = %g is (%f, %f, %f)\n", u, v, dv.x, dv.y, dv.z); + // end of correction test + + for (int i = 0; i < sampleCnt; i++) { + auto u = s_first_u + s_step_u * float(i); + for (int j = 0; j < sampleCnt; j++) { + auto v = s_first_v + s_step_v * float(j); + evaluation[i][j] = tinynurbs::surfacePoint(s, u, v); + auto der = tinynurbs::surfaceDerivatives(s, 1, u, v); +// if(der(0, 0) == evaluation[i][j]) cout<<"amazing"<