-
Notifications
You must be signed in to change notification settings - Fork 21
/
point_io.hpp
121 lines (93 loc) · 3.25 KB
/
point_io.hpp
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
#ifndef POINTIO_H
#define POINTIO_H
#include <iostream>
#include <fstream>
#ifdef WITH_PDAL
#include <pdal/Options.hpp>
#include <pdal/PointTable.hpp>
#include <pdal/StageFactory.hpp>
#include <pdal/io/BufferReader.hpp>
#endif
#include "vendor/json/json.hpp"
#include "vendor/nanoflann/nanoflann.hpp"
using json = nlohmann::json;
struct XYZ {
float x;
float y;
float z;
};
#define KDTREE_MAX_LEAF 10
#define RELEASE_POINTSET(__POINTER) { if (__POINTER != nullptr) { __POINTER->freeIndex<KdTree>(); delete __POINTER; __POINTER = nullptr; } }
struct PointSet {
std::vector<std::array<float, 3> > points;
std::vector<std::array<uint8_t, 3> > colors;
std::vector<std::array<float, 3> > normals;
std::vector<uint8_t> labels;
std::vector<uint8_t> views;
std::vector<size_t> pointMap;
PointSet *base = nullptr;
void *kdTree = nullptr;
#ifdef WITH_PDAL
pdal::PointViewPtr pointView = nullptr;
#endif
template <typename T>
inline T *getIndex() {
return kdTree != nullptr ? reinterpret_cast<T *>(kdTree) : buildIndex<T>();
}
template <typename T>
inline T *buildIndex() {
if (kdTree == nullptr) kdTree = static_cast<void *>(new T(3, *this, { KDTREE_MAX_LEAF }));
return reinterpret_cast<T *>(kdTree);
}
inline size_t count() const { return points.size(); }
inline size_t kdtree_get_point_count() const { return points.size(); }
inline float kdtree_get_pt(const size_t idx, const size_t dim) const {
return points[idx][dim];
};
template <class BBOX>
bool kdtree_get_bbox(BBOX & /* bb */) const
{
return false;
}
void appendPoint(PointSet &src, size_t idx) {
points.push_back(src.points[idx]);
colors.push_back(src.colors[idx]);
}
void trackPoint(PointSet &src, size_t idx) {
src.pointMap[idx] = points.size() - 1;
}
bool hasNormals() const { return normals.size() > 0; }
bool hasColors() const { return colors.size() > 0; }
bool hasViews() const { return views.size() > 0; }
bool hasLabels() const { return labels.size() > 0; }
double spacing(int kNeighbors = 3);
template <typename T>
void freeIndex() {
if (kdTree != nullptr) {
T *tree = getIndex<T>();
delete tree;
kdTree = nullptr;
}
}
~PointSet() {
}
private:
double m_spacing = -1.0;
};
using KdTree = nanoflann::KDTreeSingleIndexAdaptor<
nanoflann::L2_Simple_Adaptor<float, PointSet>,
PointSet, 3, size_t
>;
std::string getVertexLine(std::ifstream &reader);
size_t getVertexCount(const std::string &line);
inline void checkHeader(std::ifstream &reader, const std::string &prop);
inline bool hasHeader(const std::string &line, const std::string &prop);
PointSet *fastPlyReadPointSet(const std::string &filename);
PointSet *pdalReadPointSet(const std::string &filename);
PointSet *readPointSet(const std::string &filename);
void fastPlySavePointSet(PointSet &pSet, const std::string &filename);
void pdalSavePointSet(PointSet &pSet, const std::string &filename);
void savePointSet(PointSet &pSet, const std::string &filename);
bool fileExists(const std::string &path);
std::unordered_map<int, std::string> getClassMappings(const std::string &filename);
#endif