diff options
Diffstat (limited to 'extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h')
-rw-r--r-- | extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h b/extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h new file mode 100644 index 00000000000..0ea057dcf54 --- /dev/null +++ b/extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h @@ -0,0 +1,232 @@ +// 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/draco_features.h" + +#include "draco/attributes/point_attribute.h" +#include "draco/core/bounding_box.h" +#include "draco/core/vector_d.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; + + // 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. + int AddAttribute(const GeometryAttribute &att, bool identity_mapping, + AttributeValueIndex::ValueType num_attribute_values); + + // 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_DEDUPLICATION_SUPPORTED + // Deduplicates all attribute values (all attribute entries with the same + // value are merged into a single entry). + virtual bool DeduplicateAttributeValues(); + + // 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_.get()) { + 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_ATTRIBUTE_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_.get()) { + hash = HashCombine(metadata_hasher(*pc.metadata_.get()), hash); + } + return hash; + } +}; + +} // namespace draco + +#endif // DRACO_POINT_CLOUD_POINT_CLOUD_H_ |