Differential D4501 Diff 14521 extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
Changeset View
Changeset View
Standalone View
Standalone View
extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.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_COMPRESSION_POINT_CLOUD_ALGORITHMS_FLOAT_POINTS_TREE_ENCODER_H_ | |||||
| #define DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_FLOAT_POINTS_TREE_ENCODER_H_ | |||||
| #include <memory> | |||||
| #include <vector> | |||||
| #include "draco/compression/point_cloud/algorithms/point_cloud_compression_method.h" | |||||
| #include "draco/compression/point_cloud/algorithms/point_cloud_types.h" | |||||
| #include "draco/compression/point_cloud/algorithms/quantize_points_3.h" | |||||
| #include "draco/core/encoder_buffer.h" | |||||
| namespace draco { | |||||
| // This class encodes a given point cloud based on the point cloud compression | |||||
| // algorithm in: | |||||
| // Olivier Devillers and Pierre-Marie Gandoin | |||||
| // "Geometric compression for interactive transmission" | |||||
| // | |||||
| // In principle the algorithm keeps on splitting the point cloud in the middle | |||||
| // while alternating the axes. For 3D this results in an Octree like structure. | |||||
| // In each step we encode the number of points in the first half. | |||||
| // The algorithm uses quantization and does not preserve the order of points. | |||||
| // | |||||
| // However, the algorithm here differs from the original as follows: | |||||
| // The algorithm keeps on splitting the point cloud in the middle of the axis | |||||
| // that keeps the point cloud as clustered as possible, which gives a better | |||||
| // compression rate. | |||||
| // The number of points is encode by the deviation from the half of the points | |||||
| // in the smaller half of the two. This results in a better compression rate as | |||||
| // there are more leading zeros, which is then compressed better by the | |||||
| // arithmetic encoding. | |||||
| // TODO(hemmer): Remove class because it duplicates quantization code. | |||||
| class FloatPointsTreeEncoder { | |||||
| public: | |||||
| explicit FloatPointsTreeEncoder(PointCloudCompressionMethod method); | |||||
| explicit FloatPointsTreeEncoder(PointCloudCompressionMethod method, | |||||
| uint32_t quantization_bits, | |||||
| uint32_t compression_level); | |||||
| template <class InputIteratorT> | |||||
| bool EncodePointCloud(InputIteratorT points_begin, InputIteratorT points_end); | |||||
| EncoderBuffer *buffer() { return &buffer_; } | |||||
| uint32_t version() const { return version_; } | |||||
| uint32_t quantization_bits() const { return qinfo_.quantization_bits; } | |||||
| uint32_t &quantization_bits() { return qinfo_.quantization_bits; } | |||||
| uint32_t compression_level() const { return compression_level_; } | |||||
| uint32_t &compression_level() { return compression_level_; } | |||||
| float range() const { return qinfo_.range; } | |||||
| uint32_t num_points() const { return num_points_; } | |||||
| std::string identification_string() const { | |||||
| if (method_ == KDTREE) { | |||||
| return "FloatPointsTreeEncoder: IntegerPointsKDTreeEncoder"; | |||||
| } else { | |||||
| return "FloatPointsTreeEncoder: Unsupported Method"; | |||||
| } | |||||
| } | |||||
| private: | |||||
| void Clear() { buffer_.Clear(); } | |||||
| bool EncodePointCloudKdTreeInternal(std::vector<Point3ui> *qpoints); | |||||
| static const uint32_t version_; | |||||
| QuantizationInfo qinfo_; | |||||
| PointCloudCompressionMethod method_; | |||||
| uint32_t num_points_; | |||||
| EncoderBuffer buffer_; | |||||
| uint32_t compression_level_; | |||||
| }; | |||||
| template <class InputIteratorT> | |||||
| bool FloatPointsTreeEncoder::EncodePointCloud(InputIteratorT points_begin, | |||||
| InputIteratorT points_end) { | |||||
| Clear(); | |||||
| // Collect necessary data for encoding. | |||||
| num_points_ = std::distance(points_begin, points_end); | |||||
| // TODO(hemmer): Extend quantization tools to make this more automatic. | |||||
| // Compute range of points for quantization | |||||
| std::vector<Point3ui> qpoints; | |||||
| qpoints.reserve(num_points_); | |||||
| QuantizePoints3(points_begin, points_end, &qinfo_, | |||||
| std::back_inserter(qpoints)); | |||||
| // Encode header. | |||||
| buffer()->Encode(version_); | |||||
| buffer()->Encode(static_cast<int8_t>(method_)); | |||||
| buffer()->Encode(qinfo_.quantization_bits); | |||||
| buffer()->Encode(qinfo_.range); | |||||
| buffer()->Encode(num_points_); | |||||
| if (method_ == KDTREE) | |||||
| buffer()->Encode(compression_level_); | |||||
| if (num_points_ == 0) | |||||
| return true; | |||||
| if (method_ == KDTREE) { | |||||
| return EncodePointCloudKdTreeInternal(&qpoints); | |||||
| } else { // Unsupported method. | |||||
| fprintf(stderr, "Method not supported. \n"); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| } // namespace draco | |||||
| #endif // DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_FLOAT_POINTS_TREE_ENCODER_H_ | |||||