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/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h')
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h228
1 files changed, 228 insertions, 0 deletions
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
new file mode 100644
index 00000000000..78053f91dbe
--- /dev/null
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
@@ -0,0 +1,228 @@
+// 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_MESH_MESH_EDGEBREAKER_DECODER_IMPL_H_
+#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_DECODER_IMPL_H_
+
+#include <unordered_map>
+#include <unordered_set>
+
+#include "draco/compression/attributes/mesh_attribute_indices_encoding_data.h"
+#include "draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h"
+#include "draco/compression/mesh/mesh_edgebreaker_shared.h"
+#include "draco/compression/mesh/traverser/mesh_traversal_sequencer.h"
+#include "draco/core/decoder_buffer.h"
+#include "draco/draco_features.h"
+#include "draco/mesh/corner_table.h"
+#include "draco/mesh/mesh_attribute_corner_table.h"
+
+namespace draco {
+
+// Implementation of the edgebreaker decoder that decodes data encoded with the
+// MeshEdgebreakerEncoderImpl class. The implementation of the decoder is based
+// on the algorithm presented in Isenburg et al'02 "Spirale Reversi: Reverse
+// decoding of the Edgebreaker encoding". Note that the encoding is still based
+// on the standard edgebreaker method as presented in "3D Compression
+// Made Simple: Edgebreaker on a Corner-Table" by Rossignac at al.'01.
+// http://www.cc.gatech.edu/~jarek/papers/CornerTableSMI.pdf. One difference is
+// caused by the properties of the spirale reversi algorithm that decodes the
+// symbols from the last one to the first one. To make the decoding more
+// efficient, we encode all symbols in the reverse order, therefore the decoder
+// can process them one by one.
+// The main advantage of the spirale reversi method is that the partially
+// decoded mesh has valid connectivity data at any time during the decoding
+// process (valid with respect to the decoded portion of the mesh). The standard
+// Edgebreaker decoder used two passes (forward decoding + zipping) which not
+// only prevented us from having a valid connectivity but it was also slower.
+// The main benefit of having the valid connectivity is that we can use the
+// known connectivity to predict encoded symbols that can improve the
+// compression rate.
+template <class TraversalDecoderT>
+class MeshEdgebreakerDecoderImpl : public MeshEdgebreakerDecoderImplInterface {
+ public:
+ MeshEdgebreakerDecoderImpl();
+ bool Init(MeshEdgebreakerDecoder *decoder) override;
+
+ const MeshAttributeCornerTable *GetAttributeCornerTable(
+ int att_id) const override;
+ const MeshAttributeIndicesEncodingData *GetAttributeEncodingData(
+ int att_id) const override;
+
+ bool CreateAttributesDecoder(int32_t att_decoder_id) override;
+ bool DecodeConnectivity() override;
+ bool OnAttributesDecoded() override;
+ MeshEdgebreakerDecoder *GetDecoder() const override { return decoder_; }
+ const CornerTable *GetCornerTable() const override {
+ return corner_table_.get();
+ }
+
+ private:
+ // Creates a vertex traversal sequencer for the specified |TraverserT| type.
+ template <class TraverserT>
+ std::unique_ptr<PointsSequencer> CreateVertexTraversalSequencer(
+ MeshAttributeIndicesEncodingData *encoding_data);
+
+ // Decodes connectivity between vertices (vertex indices).
+ // Returns the number of vertices created by the decoder or -1 on error.
+ int DecodeConnectivity(int num_symbols);
+
+ // Returns true if the current symbol was part of a topology split event. This
+ // means that the current face was connected to the left edge of a face
+ // encoded with the TOPOLOGY_S symbol. |out_symbol_edge| can be used to
+ // identify which edge of the source symbol was connected to the TOPOLOGY_S
+ // symbol.
+ bool IsTopologySplit(int encoder_symbol_id, EdgeFaceName *out_face_edge,
+ int *out_encoder_split_symbol_id) {
+ if (topology_split_data_.size() == 0) {
+ return false;
+ }
+ if (topology_split_data_.back().source_symbol_id >
+ static_cast<uint32_t>(encoder_symbol_id)) {
+ // Something is wrong; if the desired source symbol is greater than the
+ // current encoder_symbol_id, we missed it, or the input was tampered
+ // (|encoder_symbol_id| keeps decreasing).
+ // Return invalid symbol id to notify the decoder that there was an
+ // error.
+ *out_encoder_split_symbol_id = -1;
+ return true;
+ }
+ if (topology_split_data_.back().source_symbol_id != encoder_symbol_id) {
+ return false;
+ }
+ *out_face_edge =
+ static_cast<EdgeFaceName>(topology_split_data_.back().source_edge);
+ *out_encoder_split_symbol_id = topology_split_data_.back().split_symbol_id;
+ // Remove the latest split event.
+ topology_split_data_.pop_back();
+ return true;
+ }
+
+ // Decodes event data for hole and topology split events and stores them for
+ // future use.
+ // Returns the number of parsed bytes, or -1 on error.
+ int32_t DecodeHoleAndTopologySplitEvents(DecoderBuffer *decoder_buffer);
+
+ // Decodes all non-position attribute connectivity on the currently
+ // processed face.
+#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
+ bool DecodeAttributeConnectivitiesOnFaceLegacy(CornerIndex corner);
+#endif
+ bool DecodeAttributeConnectivitiesOnFace(CornerIndex corner);
+
+ // Initializes mapping between corners and point ids.
+ bool AssignPointsToCorners(int num_connectivity_verts);
+
+ bool IsFaceVisited(CornerIndex corner_id) const {
+ if (corner_id < 0) {
+ return true; // Invalid corner signalizes that the face does not exist.
+ }
+ return visited_faces_[corner_table_->Face(corner_id).value()];
+ }
+
+ void SetOppositeCorners(CornerIndex corner_0, CornerIndex corner_1) {
+ corner_table_->SetOppositeCorner(corner_0, corner_1);
+ corner_table_->SetOppositeCorner(corner_1, corner_0);
+ }
+
+ MeshEdgebreakerDecoder *decoder_;
+
+ std::unique_ptr<CornerTable> corner_table_;
+
+ // Stack used for storing corners that need to be traversed when decoding
+ // mesh vertices. New corner is added for each initial face and a split
+ // symbol, and one corner is removed when the end symbol is reached.
+ // Stored as member variable to prevent frequent memory reallocations when
+ // handling meshes with lots of disjoint components. Originally, we used
+ // recursive functions to handle this behavior, but that can cause stack
+ // memory overflow when compressing huge meshes.
+ std::vector<CornerIndex> corner_traversal_stack_;
+
+ // Array stores the number of visited visited for each mesh traversal.
+ std::vector<int> vertex_traversal_length_;
+
+ // List of decoded topology split events.
+ std::vector<TopologySplitEventData> topology_split_data_;
+
+ // List of decoded hole events.
+ std::vector<HoleEventData> hole_event_data_;
+
+ // Configuration of the initial face for each mesh component.
+ std::vector<bool> init_face_configurations_;
+
+ // Initial corner for each traversal.
+ std::vector<CornerIndex> init_corners_;
+
+ // Id of the last processed input symbol.
+ int last_symbol_id_;
+
+ // Id of the last decoded vertex.
+ int last_vert_id_;
+
+ // Id of the last decoded face.
+ int last_face_id_;
+
+ // Array for marking visited faces.
+ std::vector<bool> visited_faces_;
+ // Array for marking visited vertices.
+ std::vector<bool> visited_verts_;
+ // Array for marking vertices on open boundaries.
+ std::vector<bool> is_vert_hole_;
+
+ // The number of new vertices added by the encoder (because of non-manifold
+ // vertices on the input mesh).
+ // If there are no non-manifold edges/vertices on the input mesh, this should
+ // be 0.
+ int num_new_vertices_;
+ // For every newly added vertex, this array stores it's mapping to the
+ // parent vertex id of the encoded mesh.
+ std::unordered_map<int, int> new_to_parent_vertex_map_;
+ // The number of vertices that were encoded (can be different from the number
+ // of vertices of the input mesh).
+ int num_encoded_vertices_;
+
+ // Array for storing the encoded corner ids in the order their associated
+ // vertices were decoded.
+ std::vector<int32_t> processed_corner_ids_;
+
+ // Array storing corners in the order they were visited during the
+ // connectivity decoding (always storing the tip corner of each newly visited
+ // face).
+ std::vector<int> processed_connectivity_corners_;
+
+ MeshAttributeIndicesEncodingData pos_encoding_data_;
+
+ // Id of an attributes decoder that uses |pos_encoding_data_|.
+ int pos_data_decoder_id_;
+
+ // Data for non-position attributes used by the decoder.
+ struct AttributeData {
+ AttributeData() : decoder_id(-1), is_connectivity_used(true) {}
+ // Id of the attribute decoder that was used to decode this attribute data.
+ int decoder_id;
+ MeshAttributeCornerTable connectivity_data;
+ // Flag that can mark the connectivity_data invalid. In such case the base
+ // corner table of the mesh should be used instead.
+ bool is_connectivity_used;
+ MeshAttributeIndicesEncodingData encoding_data;
+ // Opposite corners to attribute seam edges.
+ std::vector<int32_t> attribute_seam_corners;
+ };
+ std::vector<AttributeData> attribute_data_;
+
+ TraversalDecoderT traversal_decoder_;
+};
+
+} // namespace draco
+
+#endif // DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_DECODER_IMPL_H_