#ifndef UNTITLED1_NURBSEVALUATOR_CUH #define UNTITLED1_NURBSEVALUATOR_CUH #include <cuda_runtime.h> #include <thrust/device_vector.h> #include <vector> #include <map> const int POINT_SIZE = 4; /** * 保证释放后的指针指向空。这样一来保证指针不乱指,free的时候不会出错、二来可以判断指针是否已经free * 注意指针是引用传参,因为要把指针本身置空 */ __host__ void myCudaFree(float *&p); namespace NurbsSurface { /** * 曲线计算的核函数 * @param d_pointSize 点的大小(3: [x, y, z] | 4:[x, y, z, w]) */ __global__ static void g_evaluate(const float *d_nTexture_u, const float *d_nTexture_v, const float *d_points, int d_pointsCnt_u, int d_pointsCnt_v, int d_pointSize, float d_lastKnot_u, float d_lastKnot_v, int d_sampleCnt_u, int d_sampleCnt_v); __global__ static void g_derivative(float *derivatives, const float *derTexture_u, const float *derTexture_v, const float *nTexture_u, const float *nTexture_v, const float *d_points, int d_pointsCnt_u, int d_pointsCnt_v, int d_pointSize, float d_lastKnot_u, float d_lastKnot_v, int d_sampleCnt_u, int d_sampleCnt_v); __global__ static void g_curvature(const float *derivatives, int sampleCnt_u, int sampleCnt_v, float lastKnot_u, float lastKnot_v); class Evaluator { private: std::vector<std::vector<std::vector<float>>> controlPoints; float *d_points; std::vector<float> knots_u; std::vector<float> knots_v; float *d_knots_u; float *d_knots_v; bool recordTime; float *d_nTexture_u; // u方向指向度为p时的device中的nurbs基函数矩阵 float *d_nTexture_v; // v方向指向度为p时的device中的nurbs基函数矩阵 float *d_nTexture1_u; // u方向指向度为p-1时的device中的nurbs基函数矩阵 float *d_nTexture1_v; // v方向指向度为p-1时的device中的nurbs基函数矩阵 float *d_derivatives; // 一阶导计算结果 // int sampleCnt_u; // int sampleCnt_v; public: /** * 构造函数 * @param controlPoints 控制点矩阵[pointsCnt_u][pointsCnt_v][3] * @param knots_u u方向knots * @param knots_v v方向knots */ __host__ explicit Evaluator(std::vector<std::vector<std::vector<float>>> controlPoints, std::vector<float> knots_u, std::vector<float> knots_v); /** * 供外部CPU程序使用的、负责调用gpu并行计算的方法 * @param sampleCnt_u u方向采样数目 * @param sampleCnt_v v方向采样数目 * @return 由 map 组成的vector{<<u, v>, {x, y, z}>} */ __host__ std::vector<std::map<std::pair<float, float>, std::vector<float>>> evaluate(int sampleCnt_u_, int sampleCnt_v_); /** * 供外部CPU程序使用的、负责调用gpu并行计算切向量的方法 */ __host__ void derivative(int sampleCnt_u, int sampleCnt_v); /** * 供外部CPU程序使用的、负责调用gpu并行计算二阶导的方法 */ __host__ void curvature(int sampleCnt_u, int sampleCnt_v); void setRecordTime(bool r); ~Evaluator(); }; } /** * 曲线部分 */ namespace NurbsCurve { __global__ void g_test(float *nTexture); /** * 曲线计算的核函数 * @param d_pointSize 点的大小(3: [x, y, z] | 4:[x, y, z, w]) */ __global__ static void g_evaluate(const float *NTexture, const float *d_points, int d_pointsCnt, int d_pointSize, float d_lastKnot, int d_sampleCnt); __global__ static void g_derivative(float *derivatives, const float *derTexture, const float *nTexture, const float *d_points, int d_pointsCnt, int d_pointSize, float d_lastKnot, int d_sampleCnt); __global__ static void g_curvature(const float *derivatives, int sampleCnt, float lastKnot); class Evaluator { private: std::vector<std::vector<float>> controlPoints; std::vector<float> knots; float *d_knots; float *d_points; bool recordTime; float *d_nTexture; // 指向度为p时的device中的nurbs基函数矩阵 float *d_nTexture1; // 指向度为p-1时的device中的nurbs基函数矩阵 float *d_derivatives{}; // 一阶导计算结果 public: /** * 构造函数 * @param controlPoints 控制点矩阵[pointsCnt][3] */ __host__ explicit Evaluator(std::vector<std::vector<float>> controlPoints, std::vector<float> knots); /** * 供外部CPU程序使用的、负责调用gpu并行进行evaluation的方法 * @param sampleCnt_ 在参数域内均匀采样的采样数,它会更新成员变量中的sampleCnt * @return 由 map 组成的vector{<u, {x, y, z}>} */ __host__ std::vector<std::map<float, std::vector<float>>> evaluate(int sampleCnt_); /** * 供外部CPU程序使用的、负责调用gpu并行计算切向量的方法 */ __host__ void derivative(int sampleCnt); /** * 供外部CPU程序使用的、负责调用gpu并行计算二阶导的方法 */ __host__ void curvature(int sampleCnt); __host__ ~Evaluator(); void setRecordTime(bool r); }; } /** * 计算并保存基函数值 * @param nTexture 记录度数为p的基函数值,规模为【sampleCnt,pointsCnt】 * @param nTexture1 记录度数为p-1的基函数值,规模为【sampleCnt+1,pointsCnt】 */ __global__ static void g_basisTexture(float *nTexture, float *nTexture1, const float *d_knots, int d_pointsCnt, int d_knotsCnt, int d_sampleCnt); /** * 计算并保存基函数对采样点切向量的分量值 * @param derTexture 记录度数为p的Nurbs基函数对采样点切向量的分量值,大小为【sampleCnt,pointsCnt】 * @param nTexture1 度数为p-1的基函数值,规模为【sampleCnt+1,pointsCnt】 */ __global__ static void g_derTexture(float *derTexture, const float *nTexture1, const float *d_knots, int d_pointsCnt, int d_knotsCnt, int d_sampleCnt); /** * 当u值已知时,根据基函数N的递推表达式,采用动态规划的方式求解N值 * @param N_Texture 结果返回在N_Texture中 */ __device__ void d_basisFunction(float *nTexture, const float *knots, float u, int degree, int d_knotsCnt); /** * device中判断两个浮点数是否相等。与CPU中一样,GPU中的浮点数也存在很小的误差,直接使用==判断往往容易将相等误判为不等 * @return true:相等 */ __device__ bool d_floatEqual(float a, float b); #endif