-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpoint_cloud.h
132 lines (107 loc) · 3.77 KB
/
point_cloud.h
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
/*
* Copyright (C) 2015-2018, Nils Moehrle
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD 3-Clause license. See the LICENSE.txt file for details.
*/
#ifndef CACC_POINTCLOUD_HEADER
#define CACC_POINTCLOUD_HEADER
#include <memory>
#include "defines.h"
#include "vector.h"
CACC_NAMESPACE_BEGIN
template <Location L>
class PointCloud {
public:
typedef typename std::shared_ptr<PointCloud> Ptr;
typedef typename std::shared_ptr<const PointCloud> ConstPtr;
struct Data {
uint num_vertices;
Vec3f * vertices_ptr;
Vec3f * normals_ptr;
float * values_ptr;
float * qualities_ptr;
};
private:
Data data;
void init(uint num_vertices) {
data.num_vertices = num_vertices;
if (L == HOST) {
data.vertices_ptr = new Vec3f[num_vertices];
data.normals_ptr = new Vec3f[num_vertices];
data.values_ptr = new float[num_vertices];
data.qualities_ptr = new float[num_vertices];
} else {
CHECK(cudaMalloc(&data.vertices_ptr, num_vertices * sizeof(Vec3f)));
CHECK(cudaMalloc(&data.normals_ptr, num_vertices * sizeof(Vec3f)));
CHECK(cudaMalloc(&data.values_ptr, num_vertices * sizeof(float)));
CHECK(cudaMalloc(&data.qualities_ptr, num_vertices * sizeof(float)));
}
}
template <typename T>
void cleanup(T * ptr) {
if (ptr == nullptr) return;
if (L == HOST) delete[] ptr;
if (L == DEVICE) CHECK(cudaFree(ptr));
ptr = nullptr;
}
void cleanup(void) {
cleanup(data.vertices_ptr);
cleanup(data.normals_ptr);
cleanup(data.values_ptr);
cleanup(data.qualities_ptr);
}
template <Location O>
bool meta_equal(Data data, typename PointCloud<O>::Data odata) {
return data.num_vertices == odata.num_vertices;
}
template <Location O>
void copy(typename PointCloud<O>::Data const & odata, cudaMemcpyKind src_to_dst) {
CHECK(cudaMemcpy(data.vertices_ptr, odata.vertices_ptr,
data.num_vertices * sizeof(Vec3f), src_to_dst));
CHECK(cudaMemcpy(data.normals_ptr, odata.normals_ptr,
data.num_vertices * sizeof(Vec3f), src_to_dst));
CHECK(cudaMemcpy(data.values_ptr, odata.values_ptr,
data.num_vertices * sizeof(float), src_to_dst));
CHECK(cudaMemcpy(data.qualities_ptr, odata.qualities_ptr,
data.num_vertices * sizeof(float), src_to_dst));
}
public:
PointCloud() : data({0, nullptr, nullptr, nullptr, nullptr}) {};
PointCloud(uint num_vertices) : PointCloud() {
init(num_vertices);
}
static Ptr create(uint num_vertices) {
return Ptr(new PointCloud(num_vertices));
}
template <Location O>
static Ptr create(typename PointCloud<O>::Ptr point_cloud) {
return Ptr(new PointCloud(*point_cloud));
}
template <Location O>
PointCloud& operator=(PointCloud<O> const & other) {
typename PointCloud<O>::Data const & odata = other.cdata();
if (!meta_equal<O>(data, odata)) {
cleanup();
init(odata.num_vertices);
}
if (L == HOST && O == HOST) copy<O>(odata, cudaMemcpyHostToHost);
if (L == HOST && O == DEVICE) copy<O>(odata, cudaMemcpyDeviceToHost);
if (L == DEVICE && O == HOST) copy<O>(odata, cudaMemcpyHostToDevice);
if (L == DEVICE && O == DEVICE) copy<O>(odata, cudaMemcpyDeviceToDevice);
return *this;
}
template<Location O>
PointCloud(PointCloud<O> const & other) : PointCloud() {
*this = other;
}
~PointCloud() {
cleanup();
}
Data const & cdata(void) const {
return data;
}
};
CACC_NAMESPACE_END
#endif /* CACC_POINTCLOUD_HEADER */