This repository has been archived by the owner on Oct 25, 2024. It is now read-only.
forked from atteneder/draco
-
Notifications
You must be signed in to change notification settings - Fork 3
/
point_cloud.h
254 lines (214 loc) · 9.8 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
// Copyright 2016 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef DRACO_POINT_CLOUD_POINT_CLOUD_H_
#define DRACO_POINT_CLOUD_POINT_CLOUD_H_
#include "draco/attributes/point_attribute.h"
#include "draco/core/bounding_box.h"
#include "draco/core/vector_d.h"
#include "draco/draco_features.h"
#include "draco/metadata/geometry_metadata.h"
namespace draco {
// PointCloud is a collection of n-dimensional points that are described by a
// set of PointAttributes that can represent data such as positions or colors
// of individual points (see point_attribute.h).
class PointCloud {
public:
PointCloud();
virtual ~PointCloud() = default;
#ifdef DRACO_TRANSCODER_SUPPORTED
// Copies all data from the |src| point cloud.
void Copy(const PointCloud &src);
#endif
// Returns the number of named attributes of a given type.
int32_t NumNamedAttributes(GeometryAttribute::Type type) const;
// Returns attribute id of the first named attribute with a given type or -1
// when the attribute is not used by the point cloud.
int32_t GetNamedAttributeId(GeometryAttribute::Type type) const;
// Returns the id of the i-th named attribute of a given type.
int32_t GetNamedAttributeId(GeometryAttribute::Type type, int i) const;
// Returns the first named attribute of a given type or nullptr if the
// attribute is not used by the point cloud.
const PointAttribute *GetNamedAttribute(GeometryAttribute::Type type) const;
// Returns the i-th named attribute of a given type.
const PointAttribute *GetNamedAttribute(GeometryAttribute::Type type,
int i) const;
// Returns the named attribute of a given unique id.
const PointAttribute *GetNamedAttributeByUniqueId(
GeometryAttribute::Type type, uint32_t id) const;
// Returns the attribute of a given unique id.
const PointAttribute *GetAttributeByUniqueId(uint32_t id) const;
int32_t GetAttributeIdByUniqueId(uint32_t unique_id) const;
int32_t num_attributes() const {
return static_cast<int32_t>(attributes_.size());
}
const PointAttribute *attribute(int32_t att_id) const {
DRACO_DCHECK_LE(0, att_id);
DRACO_DCHECK_LT(att_id, static_cast<int32_t>(attributes_.size()));
return attributes_[att_id].get();
}
// Returned attribute can be modified, but it's caller's responsibility to
// maintain the attribute's consistency with draco::PointCloud.
PointAttribute *attribute(int32_t att_id) {
DRACO_DCHECK_LE(0, att_id);
DRACO_DCHECK_LT(att_id, static_cast<int32_t>(attributes_.size()));
return attributes_[att_id].get();
}
// Adds a new attribute to the point cloud.
// Returns the attribute id.
int AddAttribute(std::unique_ptr<PointAttribute> pa);
// Creates and adds a new attribute to the point cloud. The attribute has
// properties derived from the provided GeometryAttribute |att|.
// If |identity_mapping| is set to true, the attribute will use identity
// mapping between point indices and attribute value indices (i.e., each
// point has a unique attribute value). If |identity_mapping| is false, the
// mapping between point indices and attribute value indices is set to
// explicit, and it needs to be initialized manually using the
// PointAttribute::SetPointMapEntry() method. |num_attribute_values| can be
// used to specify the number of attribute values that are going to be
// stored in the newly created attribute. Returns attribute id of the newly
// created attribute or -1 in case of failure.
int AddAttribute(const GeometryAttribute &att, bool identity_mapping,
AttributeValueIndex::ValueType num_attribute_values);
// Creates and returns a new attribute or nullptr in case of failure. This
// method is similar to AddAttribute(), except that it returns the new
// attribute instead of adding it to the point cloud.
std::unique_ptr<PointAttribute> CreateAttribute(
const GeometryAttribute &att, bool identity_mapping,
AttributeValueIndex::ValueType num_attribute_values) const;
// Assigns an attribute id to a given PointAttribute. If an attribute with
// the same attribute id already exists, it is deleted.
virtual void SetAttribute(int att_id, std::unique_ptr<PointAttribute> pa);
// Deletes an attribute with specified attribute id. Note that this changes
// attribute ids of all subsequent attributes.
virtual void DeleteAttribute(int att_id);
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
// Deduplicates all attribute values (all attribute entries with the same
// value are merged into a single entry).
virtual bool DeduplicateAttributeValues();
#endif
#ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
// Removes duplicate point ids (two point ids are duplicate when all of their
// attributes are mapped to the same entry ids).
virtual void DeduplicatePointIds();
#endif
// Get bounding box.
BoundingBox ComputeBoundingBox() const;
// Add metadata.
void AddMetadata(std::unique_ptr<GeometryMetadata> metadata) {
metadata_ = std::move(metadata);
}
// Add metadata for an attribute.
void AddAttributeMetadata(int32_t att_id,
std::unique_ptr<AttributeMetadata> metadata) {
if (!metadata_) {
metadata_ = std::unique_ptr<GeometryMetadata>(new GeometryMetadata());
}
const int32_t att_unique_id = attribute(att_id)->unique_id();
metadata->set_att_unique_id(att_unique_id);
metadata_->AddAttributeMetadata(std::move(metadata));
}
const AttributeMetadata *GetAttributeMetadataByAttributeId(
int32_t att_id) const {
if (metadata_ == nullptr) {
return nullptr;
}
const uint32_t unique_id = attribute(att_id)->unique_id();
return metadata_->GetAttributeMetadataByUniqueId(unique_id);
}
// Returns the attribute metadata that has the requested metadata entry.
const AttributeMetadata *GetAttributeMetadataByStringEntry(
const std::string &name, const std::string &value) const {
if (metadata_ == nullptr) {
return nullptr;
}
return metadata_->GetAttributeMetadataByStringEntry(name, value);
}
// Returns the first attribute that has the requested metadata entry.
int GetAttributeIdByMetadataEntry(const std::string &name,
const std::string &value) const {
if (metadata_ == nullptr) {
return -1;
}
const AttributeMetadata *att_metadata =
metadata_->GetAttributeMetadataByStringEntry(name, value);
if (!att_metadata) {
return -1;
}
return GetAttributeIdByUniqueId(att_metadata->att_unique_id());
}
// Get a const pointer of the metadata of the point cloud.
const GeometryMetadata *GetMetadata() const { return metadata_.get(); }
// Get a pointer to the metadata of the point cloud.
GeometryMetadata *metadata() { return metadata_.get(); }
// Returns the number of n-dimensional points stored within the point cloud.
PointIndex::ValueType num_points() const { return num_points_; }
// Sets the number of points. It's the caller's responsibility to ensure the
// new number is valid with respect to the PointAttributes stored in the point
// cloud.
void set_num_points(PointIndex::ValueType num) { num_points_ = num; }
protected:
#ifdef DRACO_TRANSCODER_SUPPORTED
// Copies metadata from the |src| point cloud.
void CopyMetadata(const PointCloud &src);
#endif
#ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
// Applies id mapping of deduplicated points (called by DeduplicatePointIds).
virtual void ApplyPointIdDeduplication(
const IndexTypeVector<PointIndex, PointIndex> &id_map,
const std::vector<PointIndex> &unique_point_ids);
#endif
private:
// Metadata for the point cloud.
std::unique_ptr<GeometryMetadata> metadata_;
// Attributes describing the point cloud.
std::vector<std::unique_ptr<PointAttribute>> attributes_;
// Ids of named attributes of the given type.
std::vector<int32_t>
named_attribute_index_[GeometryAttribute::NAMED_ATTRIBUTES_COUNT];
// The number of n-dimensional points. All point attribute values are stored
// in corresponding PointAttribute instances in the |attributes_| array.
PointIndex::ValueType num_points_;
friend struct PointCloudHasher;
};
// Functor for computing a hash from data stored within a point cloud.
// Note that this can be quite slow. Two point clouds will have the same hash
// only when all points have the same order and when all attribute values are
// exactly the same.
struct PointCloudHasher {
size_t operator()(const PointCloud &pc) const {
size_t hash = pc.num_points_;
hash = HashCombine(pc.attributes_.size(), hash);
for (int i = 0; i < GeometryAttribute::NAMED_ATTRIBUTES_COUNT; ++i) {
hash = HashCombine(pc.named_attribute_index_[i].size(), hash);
for (int j = 0; j < static_cast<int>(pc.named_attribute_index_[i].size());
++j) {
hash = HashCombine(pc.named_attribute_index_[i][j], hash);
}
}
// Hash attributes.
for (int i = 0; i < static_cast<int>(pc.attributes_.size()); ++i) {
PointAttributeHasher att_hasher;
hash = HashCombine(att_hasher(*pc.attributes_[i]), hash);
}
// Hash metadata.
GeometryMetadataHasher metadata_hasher;
if (pc.metadata_) {
hash = HashCombine(metadata_hasher(*pc.metadata_), hash);
}
return hash;
}
};
} // namespace draco
#endif // DRACO_POINT_CLOUD_POINT_CLOUD_H_