Changeset View
Changeset View
Standalone View
Standalone View
extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h
- This file was added.
| // 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_ | |||||