diff options
Diffstat (limited to 'extern/draco/dracoenc/src/draco/attributes/point_attribute.h')
-rw-r--r-- | extern/draco/dracoenc/src/draco/attributes/point_attribute.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/extern/draco/dracoenc/src/draco/attributes/point_attribute.h b/extern/draco/dracoenc/src/draco/attributes/point_attribute.h new file mode 100644 index 00000000000..dffde50356d --- /dev/null +++ b/extern/draco/dracoenc/src/draco/attributes/point_attribute.h @@ -0,0 +1,186 @@ +// 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_ATTRIBUTES_POINT_ATTRIBUTE_H_ +#define DRACO_ATTRIBUTES_POINT_ATTRIBUTE_H_ + +#include <memory> + +#include "draco/draco_features.h" + +#include "draco/attributes/attribute_transform_data.h" +#include "draco/attributes/geometry_attribute.h" +#include "draco/core/draco_index_type_vector.h" +#include "draco/core/hash_utils.h" +#include "draco/core/macros.h" + +namespace draco { + +// Class for storing point specific data about each attribute. In general, +// multiple points stored in a point cloud can share the same attribute value +// and this class provides the necessary mapping between point ids and attribute +// value ids. +class PointAttribute : public GeometryAttribute { + public: + PointAttribute(); + explicit PointAttribute(const GeometryAttribute &att); + + // Make sure the move constructor is defined (needed for better performance + // when new attributes are added to PointCloud). + PointAttribute(PointAttribute &&attribute) = default; + PointAttribute &operator=(PointAttribute &&attribute) = default; + + // Copies attribute data from the provided |src_att| attribute. + void CopyFrom(const PointAttribute &src_att); + + // Prepares the attribute storage for the specified number of entries. + bool Reset(size_t num_attribute_values); + + size_t size() const { return num_unique_entries_; } + AttributeValueIndex mapped_index(PointIndex point_index) const { + if (identity_mapping_) + return AttributeValueIndex(point_index.value()); + return indices_map_[point_index]; + } + DataBuffer *buffer() const { return attribute_buffer_.get(); } + bool is_mapping_identity() const { return identity_mapping_; } + size_t indices_map_size() const { + if (is_mapping_identity()) + return 0; + return indices_map_.size(); + } + + const uint8_t *GetAddressOfMappedIndex(PointIndex point_index) const { + return GetAddress(mapped_index(point_index)); + } + + // Sets the new number of unique attribute entries for the attribute. + void Resize(size_t new_num_unique_entries) { + num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries); + } + + // Functions for setting the type of mapping between point indices and + // attribute entry ids. + // This function sets the mapping to implicit, where point indices are equal + // to attribute entry indices. + void SetIdentityMapping() { + identity_mapping_ = true; + indices_map_.clear(); + } + // This function sets the mapping to be explicitly using the indices_map_ + // array that needs to be initialized by the caller. + void SetExplicitMapping(size_t num_points) { + identity_mapping_ = false; + indices_map_.resize(num_points, kInvalidAttributeValueIndex); + } + + // Set an explicit map entry for a specific point index. + void SetPointMapEntry(PointIndex point_index, + AttributeValueIndex entry_index) { + DRACO_DCHECK(!identity_mapping_); + indices_map_[point_index] = entry_index; + } + + // Sets a value of an attribute entry. The input value must be allocated to + // cover all components of a single attribute entry. + void SetAttributeValue(AttributeValueIndex entry_index, const void *value) { + const int64_t byte_pos = entry_index.value() * byte_stride(); + buffer()->Write(byte_pos, value, byte_stride()); + } + + // Same as GeometryAttribute::GetValue(), but using point id as the input. + // Mapping to attribute value index is performed automatically. + void GetMappedValue(PointIndex point_index, void *out_data) const { + return GetValue(mapped_index(point_index), out_data); + } + +#ifdef DRACO_ATTRIBUTE_DEDUPLICATION_SUPPORTED + // Deduplicate |in_att| values into |this| attribute. |in_att| can be equal + // to |this|. + // Returns -1 if the deduplication failed. + AttributeValueIndex::ValueType DeduplicateValues( + const GeometryAttribute &in_att); + + // Same as above but the values read from |in_att| are sampled with the + // provided offset |in_att_offset|. + AttributeValueIndex::ValueType DeduplicateValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset); +#endif + + // Set attribute transform data for the attribute. The data is used to store + // the type and parameters of the transform that is applied on the attribute + // data (optional). + void SetAttributeTransformData( + std::unique_ptr<AttributeTransformData> transform_data) { + attribute_transform_data_ = std::move(transform_data); + } + const AttributeTransformData *GetAttributeTransformData() const { + return attribute_transform_data_.get(); + } + + private: +#ifdef DRACO_ATTRIBUTE_DEDUPLICATION_SUPPORTED + template <typename T> + AttributeValueIndex::ValueType DeduplicateTypedValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset); + template <typename T, int COMPONENTS_COUNT> + AttributeValueIndex::ValueType DeduplicateFormattedValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset); +#endif + + // Data storage for attribute values. GeometryAttribute itself doesn't own its + // buffer so we need to allocate it here. + std::unique_ptr<DataBuffer> attribute_buffer_; + + // Mapping between point ids and attribute value ids. + IndexTypeVector<PointIndex, AttributeValueIndex> indices_map_; + AttributeValueIndex::ValueType num_unique_entries_; + // Flag when the mapping between point ids and attribute values is identity. + bool identity_mapping_; + + // If an attribute contains transformed data (e.g. quantized), we can specify + // the attribute transform here and use it to transform the attribute back to + // its original format. + std::unique_ptr<AttributeTransformData> attribute_transform_data_; + + friend struct PointAttributeHasher; +}; + +// Hash functor for the PointAttribute class. +struct PointAttributeHasher { + size_t operator()(const PointAttribute &attribute) const { + GeometryAttributeHasher base_hasher; + size_t hash = base_hasher(attribute); + hash = HashCombine(attribute.identity_mapping_, hash); + hash = HashCombine(attribute.num_unique_entries_, hash); + hash = HashCombine(attribute.indices_map_.size(), hash); + if (attribute.indices_map_.size() > 0) { + const uint64_t indices_hash = FingerprintString( + reinterpret_cast<const char *>(attribute.indices_map_.data()), + attribute.indices_map_.size()); + hash = HashCombine(indices_hash, hash); + } + if (attribute.attribute_buffer_ != nullptr) { + const uint64_t buffer_hash = FingerprintString( + reinterpret_cast<const char *>(attribute.attribute_buffer_->data()), + attribute.attribute_buffer_->data_size()); + hash = HashCombine(buffer_hash, hash); + } + return hash; + } +}; + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_POINT_ATTRIBUTE_H_ |