|
@ -7,6 +7,7 @@ |
|
|
#include "utils.h" |
|
|
#include "utils.h" |
|
|
#include "device/Nurbs/bvh.cuh" |
|
|
#include "device/Nurbs/bvh.cuh" |
|
|
#include "device/device_utils.cuh" |
|
|
#include "device/device_utils.cuh" |
|
|
|
|
|
#include "tinynurbs/tinynurbs.h" |
|
|
|
|
|
|
|
|
__global__ void |
|
|
__global__ void |
|
|
NurbsSurface::g_evaluate(float *res, const float *d_nTexture_u, const float *d_nTexture_v, const float *d_points, |
|
|
NurbsSurface::g_evaluate(float *res, const float *d_nTexture_u, const float *d_nTexture_v, const float *d_points, |
|
@ -266,8 +267,8 @@ NurbsSurface::g_curvature(const float *derivatives, const int sampleCnt_u, const |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__host__ NurbsSurface::Surface::Surface(std::vector<std::vector<std::vector<float>>> controlPoints, |
|
|
__host__ NurbsSurface::Surface::Surface(MeshPoints4 controlPoints, std::vector<float> knots_u, |
|
|
std::vector<float> knots_u, std::vector<float> knots_v) { |
|
|
std::vector<float> knots_v) { |
|
|
this->knots_u = std::move(knots_u); |
|
|
this->knots_u = std::move(knots_u); |
|
|
this->knots_v = std::move(knots_v); |
|
|
this->knots_v = std::move(knots_v); |
|
|
this->controlPoints = std::move(controlPoints); |
|
|
this->controlPoints = std::move(controlPoints); |
|
@ -284,24 +285,22 @@ __host__ NurbsSurface::Surface::Surface(std::vector<std::vector<std::vector<floa |
|
|
d_k = nullptr; |
|
|
d_k = nullptr; |
|
|
d_normals = nullptr; |
|
|
d_normals = nullptr; |
|
|
bvh.nodes = nullptr; |
|
|
bvh.nodes = nullptr; |
|
|
|
|
|
h_evaluations = nullptr; |
|
|
|
|
|
h_derivatives = nullptr; |
|
|
|
|
|
h_normals = nullptr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__host__ std::vector<std::vector<std::vector<float>>> |
|
|
__host__ void NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
|
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
|
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
|
|
|
return {}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 构造指向device的controlPoints |
|
|
// 构造指向device的controlPoints |
|
|
const int pointsCnt_u = controlPoints.size(), pointsCnt_v = controlPoints[0].size(); |
|
|
const int pointsCnt_u = controlPoints.size(), pointsCnt_v = controlPoints[0].size(); |
|
|
const int pointsBytes = pointsCnt_u * pointsCnt_v * POINT_SIZE * sizeof(float); |
|
|
const int pointsBytes = pointsCnt_u * pointsCnt_v * sizeof(glm::vec4); |
|
|
auto *h_points = (float *) malloc(pointsBytes); |
|
|
auto *h_points = (float *) malloc(pointsBytes); |
|
|
for (int i = 0; i < pointsCnt_u; i++) { |
|
|
for (int i = 0; i < pointsCnt_u; i++) { |
|
|
for (int j = 0; j < pointsCnt_v; j++) { |
|
|
for (int j = 0; j < pointsCnt_v; j++) { |
|
|
for (int k = 0; k < POINT_SIZE; k++) { |
|
|
for (int k = 0; k < POINT_SIZE; k++) { |
|
|
h_points[(i * pointsCnt_v + j) * POINT_SIZE + k] = controlPoints[i][j][k]; |
|
|
h_points[(i * pointsCnt_v + j) * POINT_SIZE + k] = controlPoints[i][j][k]; |
|
|
} |
|
|
} |
|
|
|
|
|
// printf("%f/ %f/ %f/ %f ", controlPoints[i][j][0], controlPoints[i][j][1], controlPoints[i][j][2], controlPoints[i][j][3]); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
cudaMalloc((void **) &d_points, pointsBytes); |
|
|
cudaMalloc((void **) &d_points, pointsBytes); |
|
@ -314,6 +313,8 @@ NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
for (int i = 0; i < knotsCnt_u; i++) h_knots_u[i] = knots_u[i]; |
|
|
for (int i = 0; i < knotsCnt_u; i++) h_knots_u[i] = knots_u[i]; |
|
|
for (int i = 0; i < knotsCnt_v; i++) h_knots_v[i] = knots_v[i]; |
|
|
for (int i = 0; i < knotsCnt_v; i++) h_knots_v[i] = knots_v[i]; |
|
|
|
|
|
|
|
|
|
|
|
safeCudaFree(d_knots_u); |
|
|
|
|
|
safeCudaFree(d_knots_v); |
|
|
cudaMalloc((void **) &d_knots_u, knotsBytes_u); |
|
|
cudaMalloc((void **) &d_knots_u, knotsBytes_u); |
|
|
cudaMalloc((void **) &d_knots_v, knotsBytes_v); |
|
|
cudaMalloc((void **) &d_knots_v, knotsBytes_v); |
|
|
cudaMemcpy(d_knots_u, h_knots_u, knotsBytes_u, cudaMemcpyHostToDevice); |
|
|
cudaMemcpy(d_knots_u, h_knots_u, knotsBytes_u, cudaMemcpyHostToDevice); |
|
@ -330,10 +331,10 @@ NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
|
|
|
|
|
|
// 结果数组 |
|
|
// 结果数组 |
|
|
size_t resBytes = sampleCnt_u * sampleCnt_v * 3 * sizeof(float); |
|
|
size_t resBytes = sampleCnt_u * sampleCnt_v * 3 * sizeof(float); |
|
|
|
|
|
safeCudaFree(d_evaluationRes); |
|
|
cudaMalloc((void **) &d_evaluationRes, resBytes); |
|
|
cudaMalloc((void **) &d_evaluationRes, resBytes); |
|
|
auto *h_res = (float *) malloc(resBytes); |
|
|
safeFree(h_evaluations); |
|
|
|
|
|
h_evaluations = (float *) malloc(resBytes); |
|
|
|
|
|
|
|
|
// 构造g_basisTexture线程层级 |
|
|
// 构造g_basisTexture线程层级 |
|
|
dim3 blockBasis(512); |
|
|
dim3 blockBasis(512); |
|
@ -354,8 +355,8 @@ NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
cudaDeviceSynchronize(); |
|
|
cudaDeviceSynchronize(); |
|
|
|
|
|
|
|
|
g_evaluate <<<grid, block>>>(d_evaluationRes, d_nTexture_u, d_nTexture_v, d_points, pointsCnt_u, pointsCnt_v, |
|
|
g_evaluate <<<grid, block>>>(d_evaluationRes, d_nTexture_u, d_nTexture_v, d_points, pointsCnt_u, pointsCnt_v, |
|
|
POINT_SIZE, |
|
|
POINT_SIZE, knots_u[knotsCnt_u - 1], knots_v[knotsCnt_v - 1], sampleCnt_u, |
|
|
knots_u[knotsCnt_u - 1], knots_v[knotsCnt_v - 1], sampleCnt_u, sampleCnt_v); |
|
|
sampleCnt_v); |
|
|
cudaDeviceSynchronize(); // 所用线程结束后再获取结束时间。cudaThreadSynchronize()在CUDA1.0后被弃用 |
|
|
cudaDeviceSynchronize(); // 所用线程结束后再获取结束时间。cudaThreadSynchronize()在CUDA1.0后被弃用 |
|
|
if (recordTime) { |
|
|
if (recordTime) { |
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
time_cost_device = get_time() - time_cost_device; |
|
@ -363,34 +364,58 @@ NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
time_cost_device); |
|
|
time_cost_device); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
cudaMemcpy(h_res, d_evaluationRes, resBytes, cudaMemcpyDeviceToHost); |
|
|
cudaMemcpy(h_evaluations, d_evaluationRes, resBytes, cudaMemcpyDeviceToHost); |
|
|
std::vector<std::vector<std::vector<float>>> res(sampleCnt_u, std::vector<std::vector<float>>(sampleCnt_v, |
|
|
|
|
|
std::vector<float>(3, |
|
|
|
|
|
0.))); |
|
|
// 释放内存 |
|
|
|
|
|
safeFree(h_points); |
|
|
|
|
|
safeFree(h_knots_u); |
|
|
|
|
|
safeFree(h_knots_v); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__host__ std::vector<std::vector<glm::vec3>> |
|
|
|
|
|
NurbsSurface::Surface::getEvaluateVec(int sampleCnt_u, int sampleCnt_v) const { |
|
|
|
|
|
std::vector<std::vector<glm::vec3>> res(sampleCnt_u, std::vector<glm::vec3>(sampleCnt_v, glm::vec3())); |
|
|
for (int i = 0; i < sampleCnt_u; i++) { |
|
|
for (int i = 0; i < sampleCnt_u; i++) { |
|
|
int baseIdx = i * sampleCnt_v * 3; |
|
|
int baseIdx = i * sampleCnt_v * 3; |
|
|
for (int j = 0; j < sampleCnt_v; j++) { |
|
|
for (int j = 0; j < sampleCnt_v; j++) { |
|
|
baseIdx += j * 3; |
|
|
baseIdx += j * 3; |
|
|
res[i][j][0] = h_res[baseIdx]; |
|
|
res[i][j].x = h_evaluations[baseIdx]; |
|
|
res[i][j][1] = h_res[baseIdx + 1]; |
|
|
res[i][j].y = h_evaluations[baseIdx + 1]; |
|
|
res[i][j][2] = h_res[baseIdx + 2]; |
|
|
res[i][j].z = h_evaluations[baseIdx + 2]; |
|
|
// printf("%d, %d: %f, %f, %f\n", i, j, res[i][j][0], res[i][j][1], res[i][j][2]); |
|
|
// printf("%d, %d: %f, %f, %f\n", i, j, res[i][j][0], res[i][j][1], res[i][j][2]); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 释放内存 |
|
|
|
|
|
safeFree(h_points); |
|
|
|
|
|
safeFree(h_knots_u); |
|
|
|
|
|
safeFree(h_knots_v); |
|
|
|
|
|
safeFree(h_res); |
|
|
|
|
|
|
|
|
|
|
|
return res; |
|
|
return res; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__host__ void NurbsSurface::Surface::derivative(int sampleCnt_u, int sampleCnt_v) { |
|
|
__host__ std::vector<MeshPoints3> NurbsSurface::Surface::getDerivativeVec(int sampleCnt_u, int sampleCnt_v) const { |
|
|
// 先完成evaluation |
|
|
MeshPoints3 der_u(sampleCnt_u, LinePoints3(sampleCnt_v)); |
|
|
evaluate(sampleCnt_u, sampleCnt_v); |
|
|
MeshPoints3 der_v(sampleCnt_u, LinePoints3(sampleCnt_v)); |
|
|
|
|
|
MeshPoints3 normal(sampleCnt_u, LinePoints3(sampleCnt_v)); |
|
|
|
|
|
for (int i = 0; i < sampleCnt_u; i++) { |
|
|
|
|
|
int baseIdx = i * sampleCnt_v * 6; |
|
|
|
|
|
for (int j = 0; j < sampleCnt_v; j++) { |
|
|
|
|
|
baseIdx += j * 6; |
|
|
|
|
|
der_u[i][j].x = h_derivatives[baseIdx]; |
|
|
|
|
|
der_u[i][j].y = h_derivatives[baseIdx + 1]; |
|
|
|
|
|
der_u[i][j].z = h_derivatives[baseIdx + 2]; |
|
|
|
|
|
der_v[i][j].x = h_derivatives[baseIdx + 3]; |
|
|
|
|
|
der_v[i][j].y = h_derivatives[baseIdx + 4]; |
|
|
|
|
|
der_v[i][j].z = h_derivatives[baseIdx + 5]; |
|
|
|
|
|
auto baseIdxNorm = baseIdx / 2; |
|
|
|
|
|
normal[i][j].x = h_normals[baseIdxNorm]; |
|
|
|
|
|
normal[i][j].y = h_normals[baseIdxNorm + 1]; |
|
|
|
|
|
normal[i][j].z = h_normals[baseIdxNorm + 2]; |
|
|
|
|
|
// TODO normalize 归一化在gpu中实现! |
|
|
|
|
|
normal[i][j] = glm::normalize(normal[i][j]); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return {der_u, der_v, normal}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
__host__ void NurbsSurface::Surface::derivative(int sampleCnt_u, int sampleCnt_v) { |
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
return; |
|
|
return; |
|
@ -405,13 +430,13 @@ __host__ void NurbsSurface::Surface::derivative(int sampleCnt_u, int sampleCnt_v |
|
|
|
|
|
|
|
|
// 构造切向量计算结果 |
|
|
// 构造切向量计算结果 |
|
|
safeCudaFree(d_derivatives); |
|
|
safeCudaFree(d_derivatives); |
|
|
cudaMalloc((void **) &d_derivatives, |
|
|
size_t derBytes = sampleCnt_u * sampleCnt_v * 6 * sizeof(float); |
|
|
sampleCnt_v * sampleCnt_u * 6 * sizeof(float)); // 每个采样所求的切向量是一个六元向量,前三位是对u的偏导、后三位是对v的偏导 |
|
|
cudaMalloc((void **) &d_derivatives, derBytes); // 每个采样所求的切向量是一个六元向量,前三位是对u的偏导、后三位是对v的偏导 |
|
|
|
|
|
|
|
|
// 构造法向量计算结果 |
|
|
// 构造法向量计算结果 |
|
|
safeCudaFree(d_normals); |
|
|
safeCudaFree(d_normals); |
|
|
cudaMalloc((void **) &d_normals, |
|
|
size_t normalBytes = sampleCnt_u * sampleCnt_v * 3 * sizeof(float); |
|
|
sampleCnt_v * sampleCnt_u * 3 * sizeof(float)); |
|
|
cudaMalloc((void **) &d_normals, normalBytes); |
|
|
|
|
|
|
|
|
// 构造线程层级 |
|
|
// 构造线程层级 |
|
|
dim3 block(32, 32); |
|
|
dim3 block(32, 32); |
|
@ -437,13 +462,22 @@ __host__ void NurbsSurface::Surface::derivative(int sampleCnt_u, int sampleCnt_v |
|
|
printf("GPU time cost of surface first derivative calculating for %d samples: %lf\n", sampleCnt_u * sampleCnt_v, |
|
|
printf("GPU time cost of surface first derivative calculating for %d samples: %lf\n", sampleCnt_u * sampleCnt_v, |
|
|
time_cost_device); |
|
|
time_cost_device); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 结果数组 |
|
|
|
|
|
safeFree(h_normals); |
|
|
|
|
|
h_normals = (float *) malloc(normalBytes); |
|
|
|
|
|
cudaMemcpy(h_normals, d_normals, normalBytes, cudaMemcpyDeviceToHost); |
|
|
|
|
|
|
|
|
|
|
|
safeFree(h_derivatives); |
|
|
|
|
|
h_derivatives = (float *) malloc(derBytes); |
|
|
|
|
|
cudaMemcpy(h_derivatives, d_derivatives, derBytes, cudaMemcpyDeviceToHost); |
|
|
|
|
|
|
|
|
cudaFree(d_derTexture_u); |
|
|
cudaFree(d_derTexture_u); |
|
|
cudaFree(d_derTexture_v); |
|
|
cudaFree(d_derTexture_v); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__host__ void NurbsSurface::Surface::curvature(int sampleCnt_u, int sampleCnt_v) { |
|
|
__host__ void NurbsSurface::Surface::curvature(int sampleCnt_u, int sampleCnt_v) { |
|
|
// 先计算切向量 |
|
|
|
|
|
derivative(sampleCnt_u, sampleCnt_v); |
|
|
|
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
return; |
|
|
return; |
|
@ -491,17 +525,18 @@ NurbsSurface::Surface::~Surface() { |
|
|
safeCudaFree(d_normals); |
|
|
safeCudaFree(d_normals); |
|
|
safeCudaFree(d_derivatives); |
|
|
safeCudaFree(d_derivatives); |
|
|
safeFree(bvh.nodes); |
|
|
safeFree(bvh.nodes); |
|
|
|
|
|
safeFree(h_evaluations); |
|
|
|
|
|
safeFree(h_normals); |
|
|
|
|
|
safeFree(h_derivatives); |
|
|
cudaDeviceReset(); |
|
|
cudaDeviceReset(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__host__ void NurbsSurface::Surface::buildBHV(int layerCnt, bool useK) { |
|
|
__host__ void NurbsSurface::Surface::buildBVH(int layerCnt, bool useK) { |
|
|
|
|
|
// TODO 构造BVH的函数不应该出现在NURBS Surface中,应该是BVH类的事情! |
|
|
|
|
|
// TODO NURBS Surface只需要一个函数去调用BVH对象的方法即可 |
|
|
int sampleCnt_u = pow(2, layerCnt - 1) + 1, sampleCnt_v = sampleCnt_u; |
|
|
int sampleCnt_u = pow(2, layerCnt - 1) + 1, sampleCnt_v = sampleCnt_u; |
|
|
if (useK) { |
|
|
if (!useK) { |
|
|
// 先计算曲率,过程中也会计算曲面值 |
|
|
// 必须safeFree一下,这样global函数中才能通过d_k = nullptr知道不需要再free |
|
|
curvature(sampleCnt_u, sampleCnt_v); |
|
|
|
|
|
} else { |
|
|
|
|
|
// 只做evaluation |
|
|
|
|
|
evaluate(sampleCnt_u, sampleCnt_v); |
|
|
|
|
|
safeCudaFree(d_k); |
|
|
safeCudaFree(d_k); |
|
|
} |
|
|
} |
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
@ -521,14 +556,15 @@ __host__ void NurbsSurface::Surface::buildBHV(int layerCnt, bool useK) { |
|
|
// 记录用时 |
|
|
// 记录用时 |
|
|
double time_cost_device; |
|
|
double time_cost_device; |
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
buildBvh<<<grid, block>>>(d_k, bvh.maxLevel, d_evaluationRes, knots_u[knots_u.size() - 1], |
|
|
g_buildBvh<<<grid, block>>>(d_k, bvh.maxLevel, d_evaluationRes, knots_u[knots_u.size() - 1], |
|
|
knots_v[knots_v.size() - 1], sampleCnt_u, sampleCnt_v, d_bvh); |
|
|
knots_v[knots_v.size() - 1], sampleCnt_u, sampleCnt_v, d_bvh); |
|
|
cudaDeviceSynchronize(); |
|
|
cudaDeviceSynchronize(); |
|
|
if (recordTime) { |
|
|
if (recordTime) { |
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
printf("GPU time cost of a %d-layer BVH building: %lf\n", |
|
|
printf("GPU time cost of a %d-layer BVH building: %lf\n", |
|
|
bvh.maxLevel, time_cost_device); |
|
|
bvh.maxLevel, time_cost_device); |
|
|
} |
|
|
} |
|
|
|
|
|
// 将bvh拷贝到cpu中 |
|
|
safeFree(bvh.nodes); |
|
|
safeFree(bvh.nodes); |
|
|
bvh.nodes = (BVHNode *) malloc(bvhBytes); |
|
|
bvh.nodes = (BVHNode *) malloc(bvhBytes); |
|
|
cudaMemcpy(bvh.nodes, d_bvh, bvhBytes, cudaMemcpyDeviceToHost); |
|
|
cudaMemcpy(bvh.nodes, d_bvh, bvhBytes, cudaMemcpyDeviceToHost); |
|
@ -537,9 +573,9 @@ __host__ void NurbsSurface::Surface::buildBHV(int layerCnt, bool useK) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__host__ void NurbsSurface::Surface::buildGaussMap(int layerCnt) { |
|
|
__host__ void NurbsSurface::Surface::buildGaussMap(int layerCnt) { |
|
|
|
|
|
// TODO,构造GAUSS Map的函数不应该出现在NURBS Surface中,应该是GAUSS Map类的事情! |
|
|
int sampleCnt_u = pow(2, layerCnt - 1) + 1, sampleCnt_v = sampleCnt_u; |
|
|
int sampleCnt_u = pow(2, layerCnt - 1) + 1, sampleCnt_v = sampleCnt_u; |
|
|
// 先计算法向量 |
|
|
|
|
|
derivative(sampleCnt_u, sampleCnt_v); |
|
|
|
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
return; |
|
|
return; |
|
@ -556,8 +592,8 @@ __host__ void NurbsSurface::Surface::buildGaussMap(int layerCnt) { |
|
|
// 记录用时 |
|
|
// 记录用时 |
|
|
double time_cost_device; |
|
|
double time_cost_device; |
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
buildBvh<<<grid, block>>>(nullptr, layerCnt, d_normals, knots_u[knots_u.size() - 1], |
|
|
g_buildBvh<<<grid, block>>>(nullptr, layerCnt, d_normals, knots_u[knots_u.size() - 1], |
|
|
knots_v[knots_v.size() - 1], sampleCnt_u, sampleCnt_v, d_gaussMapTree); |
|
|
knots_v[knots_v.size() - 1], sampleCnt_u, sampleCnt_v, d_gaussMapTree); |
|
|
cudaDeviceSynchronize(); |
|
|
cudaDeviceSynchronize(); |
|
|
if (recordTime) { |
|
|
if (recordTime) { |
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
time_cost_device = get_time() - time_cost_device; |
|
@ -603,16 +639,24 @@ __host__ void NurbsSurface::recursiveGetOverlapLeafNodes(const BVH &bvh1, const |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__host__ std::vector<std::pair<int, int>> |
|
|
|
|
|
|
|
|
__host__ std::vector<boxPair> |
|
|
NurbsSurface::getOverlappedLeafNodes(const BVH &bvh1, const BVH &bvh2) { |
|
|
NurbsSurface::getOverlappedLeafNodes(const BVH &bvh1, const BVH &bvh2) { |
|
|
std::vector<std::pair<int, int>> resPairs; |
|
|
std::vector<idx2> resPairs; |
|
|
// 记录用时 |
|
|
// 记录用时 |
|
|
double time_cost_device = get_time(); |
|
|
double time_cost_device = get_time(); |
|
|
|
|
|
|
|
|
recursiveGetOverlapLeafNodes(bvh1, bvh2, 0, 0, resPairs); |
|
|
recursiveGetOverlapLeafNodes(bvh1, bvh2, 0, 0, resPairs); |
|
|
|
|
|
std::vector<boxPair> boxPairsIdx2(resPairs.size()); |
|
|
|
|
|
for (int i = 0; i < resPairs.size(); i++) { |
|
|
|
|
|
boxPairsIdx2[i] = {{bvh1.nodes[resPairs[i].first].idx_u, bvh1.nodes[resPairs[i].first].idx_v}, |
|
|
|
|
|
{bvh2.nodes[resPairs[i].second].idx_u, bvh2.nodes[resPairs[i].second].idx_v}}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
printf("CPU time cost for recursively calculating the overlapped leaf nodes: %lf\n", time_cost_device); |
|
|
printf("CPU time cost for recursively calculating the overlapped leaf nodes: %lf\n", time_cost_device); |
|
|
|
|
|
|
|
|
return resPairs; |
|
|
return boxPairsIdx2; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__host__ bool |
|
|
__host__ bool |
|
@ -631,8 +675,10 @@ NurbsSurface::isGaussMapsOverlapped(const BVH &gm1, const BVH &gm2, std::pair<in |
|
|
printf("Error when detecting overlapping: idx range invalid!\n"); |
|
|
printf("Error when detecting overlapping: idx range invalid!\n"); |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
auto getRangedBox = [&commonMaxLayer](const BVH &bvh, const std::pair<int, int> &idxRange_u, |
|
|
auto getRangedBox = [&commonMaxLayer](const BVH &bvh, const std::pair<int, int> &idxRange_u, |
|
|
const std::pair<int, int> idxRange_v) { |
|
|
const std::pair<int, int> idxRange_v) { |
|
|
|
|
|
// 获取某个范围的gauss map的aabb |
|
|
AABB bounding; |
|
|
AABB bounding; |
|
|
for (int i = idxRange_u.first; i <= idxRange_u.second; ++i) { |
|
|
for (int i = idxRange_u.first; i <= idxRange_u.second; ++i) { |
|
|
for (int j = idxRange_v.first; j <= idxRange_v.second; ++j) { |
|
|
for (int j = idxRange_v.first; j <= idxRange_v.second; ++j) { |
|
@ -670,3 +716,69 @@ __host__ bool NurbsSurface::isGaussMapsOverlapped(const BVH &gm1, const BVH &gm2 |
|
|
auto idxRange_v2 = getIdxRange(range_v2, paramRange_v2, edgeCellCnt); |
|
|
auto idxRange_v2 = getIdxRange(range_v2, paramRange_v2, edgeCellCnt); |
|
|
return isGaussMapsOverlapped(gm1, gm2, idxRange_u1, idxRange_v1, idxRange_u2, idxRange_v2); |
|
|
return isGaussMapsOverlapped(gm1, gm2, idxRange_u1, idxRange_v1, idxRange_u2, idxRange_v2); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
__host__ void |
|
|
|
|
|
NurbsSurface::Surface::recursiveGetRayBVHIntersection(const glm::vec3 dir, const glm::vec3 startPoint, const int idx, |
|
|
|
|
|
std::vector<BVHNode> &intersectionLeafNodes) { |
|
|
|
|
|
auto bvhNode = bvh.nodes[idx]; |
|
|
|
|
|
// 射线与AABB判交 |
|
|
|
|
|
auto isRayBoxIntersect = [&]() { |
|
|
|
|
|
const auto &box = bvhNode.bounds; |
|
|
|
|
|
float t; // 射线的参数,当t<=0,表示线面交点不在视平面前方,视为没有交点 |
|
|
|
|
|
if (dir.x != 0.) { |
|
|
|
|
|
// 当x分量不为0,则射线会与AABB中垂直于x轴的平面可能有交 |
|
|
|
|
|
// 注意x的正负。x为正会先遇到较小点所在平面 |
|
|
|
|
|
if (dir.x > 0) t = (box.pMin.x - startPoint.x) / dir.x; |
|
|
|
|
|
else t = (box.pMax.x - startPoint.x) / dir.x; |
|
|
|
|
|
if (t > 0.) { |
|
|
|
|
|
// 射线与平面在前方有交点。但交点不一定在盒子上 |
|
|
|
|
|
auto tmpPt = startPoint + t * dir; // 交点 |
|
|
|
|
|
if (box.pMin.y <= tmpPt.y && box.pMin.z <= tmpPt.z && box.pMax.y >= tmpPt.y && box.pMax.z >= tmpPt.z) |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (dir.y != 0.) { |
|
|
|
|
|
// 同上测试y方向 |
|
|
|
|
|
if (dir.y > 0) t = (box.pMin.y - startPoint.y) / dir.y; |
|
|
|
|
|
else t = (box.pMax.y - startPoint.y) / dir.y; |
|
|
|
|
|
if (t > 0.) { |
|
|
|
|
|
auto tmpPt = startPoint + t * dir; |
|
|
|
|
|
if (box.pMin.x <= tmpPt.x && box.pMin.z <= tmpPt.z && box.pMax.x >= tmpPt.x && box.pMax.z >= tmpPt.z) |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (dir.z != 0.) { |
|
|
|
|
|
// 同上测试z方向 |
|
|
|
|
|
if (dir.z > 0) t = (box.pMin.z - startPoint.z) / dir.z; |
|
|
|
|
|
else t = (box.pMax.z - startPoint.z) / dir.z; |
|
|
|
|
|
if (t > 0.) { |
|
|
|
|
|
auto tmpPt = startPoint + t * dir; |
|
|
|
|
|
if (box.pMin.x <= tmpPt.x && box.pMin.y <= tmpPt.y && box.pMax.x >= tmpPt.x && box.pMax.y >= tmpPt.y) |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return false; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 不相交 |
|
|
|
|
|
if (!isRayBoxIntersect()) return; |
|
|
|
|
|
// 相交 |
|
|
|
|
|
if (bvhNode.firstChild == -1) { |
|
|
|
|
|
// 与叶节点相交 |
|
|
|
|
|
intersectionLeafNodes.emplace_back(bvhNode); |
|
|
|
|
|
} else { |
|
|
|
|
|
// 与父节点相交 |
|
|
|
|
|
for (int i = 0; i < 4; i++) |
|
|
|
|
|
recursiveGetRayBVHIntersection(dir, startPoint, bvhNode.firstChild + i, intersectionLeafNodes); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
__host__ std::vector<BVHNode> NurbsSurface::Surface::rayBVHIntersection(glm::vec3 dir, glm::vec3 startPoint) { |
|
|
|
|
|
std::vector<BVHNode> res; |
|
|
|
|
|
recursiveGetRayBVHIntersection(dir, startPoint, 0, res); |
|
|
|
|
|
//TODO sort res by t |
|
|
|
|
|
|
|
|
|
|
|
// res.emplace_back(BVHNode()); |
|
|
|
|
|
// printf("res size: %lld\n", res.size()); |
|
|
|
|
|
return res; |
|
|
|
|
|
} |