Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/draco/dracoenc/src/draco/attributes/point_attribute.cc')
-rw-r--r--extern/draco/dracoenc/src/draco/attributes/point_attribute.cc205
1 files changed, 205 insertions, 0 deletions
diff --git a/extern/draco/dracoenc/src/draco/attributes/point_attribute.cc b/extern/draco/dracoenc/src/draco/attributes/point_attribute.cc
new file mode 100644
index 00000000000..4428f332b93
--- /dev/null
+++ b/extern/draco/dracoenc/src/draco/attributes/point_attribute.cc
@@ -0,0 +1,205 @@
+// 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.
+//
+#include "draco/attributes/point_attribute.h"
+
+#include <unordered_map>
+
+using std::unordered_map;
+
+// Shortcut for typed conditionals.
+template <bool B, class T, class F>
+using conditional_t = typename std::conditional<B, T, F>::type;
+
+namespace draco {
+
+PointAttribute::PointAttribute()
+ : num_unique_entries_(0), identity_mapping_(false) {}
+
+PointAttribute::PointAttribute(const GeometryAttribute &att)
+ : GeometryAttribute(att),
+ num_unique_entries_(0),
+ identity_mapping_(false) {}
+
+void PointAttribute::CopyFrom(const PointAttribute &src_att) {
+ if (buffer() == nullptr) {
+ // If the destination attribute doesn't have a valid buffer, create it.
+ attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
+ ResetBuffer(attribute_buffer_.get(), 0, 0);
+ }
+ if (!GeometryAttribute::CopyFrom(src_att))
+ return;
+ identity_mapping_ = src_att.identity_mapping_;
+ num_unique_entries_ = src_att.num_unique_entries_;
+ indices_map_ = src_att.indices_map_;
+ if (src_att.attribute_transform_data_) {
+ attribute_transform_data_ = std::unique_ptr<AttributeTransformData>(
+ new AttributeTransformData(*src_att.attribute_transform_data_.get()));
+ } else {
+ attribute_transform_data_ = nullptr;
+ }
+}
+
+bool PointAttribute::Reset(size_t num_attribute_values) {
+ if (attribute_buffer_ == nullptr) {
+ attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
+ }
+ const int64_t entry_size = DataTypeLength(data_type()) * num_components();
+ if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size))
+ return false;
+ // Assign the new buffer to the parent attribute.
+ ResetBuffer(attribute_buffer_.get(), entry_size, 0);
+ num_unique_entries_ = static_cast<uint32_t>(num_attribute_values);
+ return true;
+}
+
+#ifdef DRACO_ATTRIBUTE_DEDUPLICATION_SUPPORTED
+AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
+ const GeometryAttribute &in_att) {
+ return DeduplicateValues(in_att, AttributeValueIndex(0));
+}
+
+AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
+ const GeometryAttribute &in_att, AttributeValueIndex in_att_offset) {
+ AttributeValueIndex::ValueType unique_vals = 0;
+ switch (in_att.data_type()) {
+ // Currently we support only float, uint8, and uint16 arguments.
+ case DT_FLOAT32:
+ unique_vals = DeduplicateTypedValues<float>(in_att, in_att_offset);
+ break;
+ case DT_INT8:
+ unique_vals = DeduplicateTypedValues<int8_t>(in_att, in_att_offset);
+ break;
+ case DT_UINT8:
+ case DT_BOOL:
+ unique_vals = DeduplicateTypedValues<uint8_t>(in_att, in_att_offset);
+ break;
+ case DT_UINT16:
+ unique_vals = DeduplicateTypedValues<uint16_t>(in_att, in_att_offset);
+ break;
+ case DT_INT16:
+ unique_vals = DeduplicateTypedValues<int16_t>(in_att, in_att_offset);
+ break;
+ case DT_UINT32:
+ unique_vals = DeduplicateTypedValues<uint32_t>(in_att, in_att_offset);
+ break;
+ case DT_INT32:
+ unique_vals = DeduplicateTypedValues<int32_t>(in_att, in_att_offset);
+ break;
+ default:
+ return -1; // Unsupported data type.
+ }
+ if (unique_vals == 0)
+ return -1; // Unexpected error.
+ return unique_vals;
+}
+
+// Helper function for calling UnifyDuplicateAttributes<T,num_components_t>
+// with the correct template arguments.
+// Returns the number of unique attribute values.
+template <typename T>
+AttributeValueIndex::ValueType PointAttribute::DeduplicateTypedValues(
+ const GeometryAttribute &in_att, AttributeValueIndex in_att_offset) {
+ // Select the correct method to call based on the number of attribute
+ // components.
+ switch (in_att.num_components()) {
+ case 1:
+ return DeduplicateFormattedValues<T, 1>(in_att, in_att_offset);
+ case 2:
+ return DeduplicateFormattedValues<T, 2>(in_att, in_att_offset);
+ case 3:
+ return DeduplicateFormattedValues<T, 3>(in_att, in_att_offset);
+ case 4:
+ return DeduplicateFormattedValues<T, 4>(in_att, in_att_offset);
+ default:
+ return 0;
+ }
+}
+
+template <typename T, int num_components_t>
+AttributeValueIndex::ValueType PointAttribute::DeduplicateFormattedValues(
+ const GeometryAttribute &in_att, AttributeValueIndex in_att_offset) {
+ // We want to detect duplicates using a hash map but we cannot hash floating
+ // point numbers directly so bit-copy floats to the same sized integers and
+ // hash them.
+
+ // First we need to determine which int type to use (1, 2, 4 or 8 bytes).
+ // Note, this is done at compile time using std::conditional struct.
+ // Conditional is in form <bool-expression, true, false>. If bool-expression
+ // is true the "true" branch is used and vice versa. All at compile time.
+ typedef conditional_t<sizeof(T) == 1, uint8_t,
+ conditional_t<sizeof(T) == 2, uint16_t,
+ conditional_t<sizeof(T) == 4, uint32_t,
+ /*else*/ uint64_t>>>
+ HashType;
+
+ AttributeValueIndex unique_vals(0);
+ typedef std::array<T, num_components_t> AttributeValue;
+ typedef std::array<HashType, num_components_t> AttributeHashableValue;
+ // Hash map storing index of the first attribute with a given value.
+ unordered_map<AttributeHashableValue, AttributeValueIndex,
+ HashArray<AttributeHashableValue>>
+ value_to_index_map;
+ AttributeValue att_value;
+ AttributeHashableValue hashable_value;
+ IndexTypeVector<AttributeValueIndex, AttributeValueIndex> value_map(
+ num_unique_entries_);
+ for (AttributeValueIndex i(0); i < num_unique_entries_; ++i) {
+ const AttributeValueIndex att_pos = i + in_att_offset;
+ att_value = in_att.GetValue<T, num_components_t>(att_pos);
+ // Convert the value to hashable type. Bit-copy real attributes to integers.
+ memcpy(&(hashable_value[0]), &(att_value[0]), sizeof(att_value));
+
+ // Check if the given attribute value has been used before already.
+ auto it = value_to_index_map.find(hashable_value);
+ if (it != value_to_index_map.end()) {
+ // Duplicated value found. Update index mapping.
+ value_map[i] = it->second;
+ } else {
+ // New unique value.
+ // Update the hash map with a new entry pointing to the latest unique
+ // vertex index.
+ value_to_index_map.insert(
+ std::pair<AttributeHashableValue, AttributeValueIndex>(hashable_value,
+ unique_vals));
+ // Add the unique value to the mesh builder.
+ SetAttributeValue(unique_vals, &att_value);
+ // Update index mapping.
+ value_map[i] = unique_vals;
+
+ ++unique_vals;
+ }
+ }
+ if (unique_vals == num_unique_entries_)
+ return unique_vals.value(); // Nothing has changed.
+ if (is_mapping_identity()) {
+ // Change identity mapping to the explicit one.
+ // The number of points is equal to the number of old unique values.
+ SetExplicitMapping(num_unique_entries_);
+ // Update the explicit map.
+ for (uint32_t i = 0; i < num_unique_entries_; ++i) {
+ SetPointMapEntry(PointIndex(i), value_map[AttributeValueIndex(i)]);
+ }
+ } else {
+ // Update point to value map using the mapping between old and new values.
+ for (PointIndex i(0); i < static_cast<uint32_t>(indices_map_.size()); ++i) {
+ SetPointMapEntry(i, value_map[indices_map_[i]]);
+ }
+ }
+ num_unique_entries_ = unique_vals.value();
+ return num_unique_entries_;
+}
+#endif
+
+} // namespace draco