-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
executable file
·136 lines (125 loc) · 4.92 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <chrono>
#include <set>
#include <cmath>
//#include <armadillo>
//In Vast AI you need the docker image: nvidia/cuda:11.7.1-devel-ubuntu22.04
#include "EGT_GKNN.cuh"
#include "GPU_Normal.cuh"
#include "CGALHeaders.h"
#include "MeshPLY.h"
#include "GridKNNCuda.cuh"
#include "KNNInterface.cuh"
#include "GridMeshCuda1.cuh"
#include "EGT_CUDA.cuh"
#include "Normal_CUDA.cuh"
#include "getOutputPoints.cuh"
#define NUM_CARDS 2
void cudaWarmup(float* points_x, float* points_y, float* points_z, int pointsCount, int k, int* kNN, int num_cards);
void GRIDCUDAKNN(float* pnts_x, float* pnts_y, float* points_z, int pointsCount, int k,
float**& dpnts_x, float**& dpnts_y, float**& dpnts_z, int**& dknn, int num_cards,
int*& reverseIndexes, int*& pointsCard, int& partitionSize, float& minOriginal, float& maxOriginal,
float* x, float* y, float* z, int* knn);
void readPointCloud(const std::string& fileName, std::vector<float>& points_x,
std::vector<float>& points_y, std::vector<float>& points_z, std::vector<float>& normals_x,
std::vector<float>& normals_y, std::vector<float>& normals_z, bool hasNormals)
{
int number_of_lines = 0;
std::string line;
std::ifstream myfile(fileName, std::ios::in);
while (std::getline(myfile, line))
++number_of_lines;
std::cout << "reading " << number_of_lines << " points." << std::endl;
myfile.clear();
myfile.seekg(0);
float x, y, z, nx, ny, nz;
if (hasNormals)
while (myfile >> x >> y >> z >> nx >> ny >> nz) {
points_x.emplace_back(x);
points_y.emplace_back(y);
points_z.emplace_back(z);
normals_x.emplace_back(nx);
normals_y.emplace_back(ny);
normals_z.emplace_back(nz);
}
else
while (myfile >> x >> y >> z) {
points_x.emplace_back(x);
points_y.emplace_back(y);
points_z.emplace_back(z);
}
}
void savePointCloud(const char* fileName, float* pnts_x, float* pnts_y, float* pnts_z, int point_count,
float* nx, float* ny, float* nz, bool hasNormals)
{
FILE* file = fopen(fileName, "w");
for (int i = 0; i < point_count; i++)
{
if (hasNormals)
fprintf(file, "%lf %lf %lf %lf %lf %lf\n",
pnts_x[i], pnts_y[i], pnts_z[i], nx[i], ny[i], nz[i]);
else
fprintf(file, "%lf %lf %lf\n",
pnts_x[i], pnts_y[i], pnts_z[i]);
}
fclose(file);
}
int main(int argc, char** argv)
{
std::string meshPathOrigin = argv[1];
std::vector<float> normals_x;
std::vector<float> normals_y;
std::vector<float> normals_z;
//The total number of neighbors
int k = atoi(argv[2]);
//The total number of Elliptic Gabriel Taubin iterations
int iterations = atoi(argv[3]);
//The Gabriel graph alpha shout be set in the range (0,1] a good value is 0.65 for point-clouds
//and 1e-8 for meshes.
float alpha = atof(argv[4]);
//If it is a Mesh then set to one if point-cloud set to zero
float isMesh = atoi(argv[5]);
//The number of cards
int numcards = atoi(argv[6]);
Mesh mesh;
ReadPLY(meshPathOrigin, &mesh);
normals_x.resize(mesh.mV.size());
normals_y.resize(mesh.mV.size());
normals_z.resize(mesh.mV.size());
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::vector<float> out_x(mesh.mV.size());
std::vector<float> out_y(mesh.mV.size());
std::vector<float> out_z(mesh.mV.size());
std::shared_ptr<KNNInterface> knnInterface;
if (!isMesh) {
knnInterface = std::make_shared<GridStructure>(mesh, numcards, 1e-6, 1024, 4);
std::static_pointer_cast<GridStructure>(knnInterface)->GRIDCUDAKNNSELF_COMPACT(k, 1e8);
}
else {
knnInterface = std::make_shared<GridMeshCuda>(mesh, numcards, 1e-6, 1024);
std::static_pointer_cast<GridMeshCuda>(knnInterface)->GetNeighborsFromTriangles(k);
}
EGT_CUDA smoother(*knnInterface);
smoother.PerformSmoothing(iterations, 0.63, -0.64, alpha);
if (!isMesh) {
Normal_CUDA normalCuda(*knnInterface);
normalCuda.GetNormals(normals_x.data(), normals_y.data(), normals_z.data());
}
getOutputPoints(out_x.data(), out_y.data(), out_z.data(), knnInterface.get());
if (!isMesh) mesh.mN.resize(knnInterface->pointsRefCount());
for (int i = 0; i < mesh.mV.size(); i++) {
mesh.mV[i].x = out_x[i];
mesh.mV[i].y = out_y[i];
mesh.mV[i].z = out_z[i];
if (!isMesh) {
mesh.mN[i].x = normals_x[i];
mesh.mN[i].y = normals_y[i];
mesh.mN[i].z = normals_z[i];
}
}
WritePLY("output.ply", &mesh);
printf("Succeeded!\n");
}