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/traverser/mesh_traversal_sequencer.h')
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
new file mode 100644
index 00000000000..ebe1d5f7a9e
--- /dev/null
+++ b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
@@ -0,0 +1,113 @@
+// 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_TRAVERSER_MESH_TRAVERSAL_SEQUENCER_H_
+#define DRACO_COMPRESSION_MESH_TRAVERSER_MESH_TRAVERSAL_SEQUENCER_H_
+
+#include "draco/attributes/geometry_indices.h"
+#include "draco/compression/attributes/mesh_attribute_indices_encoding_data.h"
+#include "draco/compression/attributes/points_sequencer.h"
+#include "draco/mesh/mesh.h"
+
+namespace draco {
+
+// Sequencer that generates point sequence in an order given by a deterministic
+// traversal on the mesh surface. Note that all attributes encoded with this
+// sequence must share the same connectivity.
+// TODO(hemmer): Consider refactoring such that this is an observer.
+template <class TraverserT>
+class MeshTraversalSequencer : public PointsSequencer {
+ public:
+ MeshTraversalSequencer(const Mesh *mesh,
+ const MeshAttributeIndicesEncodingData *encoding_data)
+ : mesh_(mesh), encoding_data_(encoding_data), corner_order_(nullptr) {}
+ void SetTraverser(const TraverserT &t) { traverser_ = t; }
+
+ // Function that can be used to set an order in which the mesh corners should
+ // be processed. This is an optional flag used usually only by the encoder
+ // to match the same corner order that is going to be used by the decoder.
+ // Note that |corner_order| should contain only one corner per face (it can
+ // have all corners but only the first encountered corner for each face is
+ // going to be used to start a traversal). If the corner order is not set, the
+ // corners are processed sequentially based on their ids.
+ void SetCornerOrder(const std::vector<CornerIndex> &corner_order) {
+ corner_order_ = &corner_order;
+ }
+
+ bool UpdatePointToAttributeIndexMapping(PointAttribute *attribute) override {
+ const auto *corner_table = traverser_.corner_table();
+ attribute->SetExplicitMapping(mesh_->num_points());
+ const size_t num_faces = mesh_->num_faces();
+ const size_t num_points = mesh_->num_points();
+ for (FaceIndex f(0); f < static_cast<uint32_t>(num_faces); ++f) {
+ const auto &face = mesh_->face(f);
+ for (int p = 0; p < 3; ++p) {
+ const PointIndex point_id = face[p];
+ const VertexIndex vert_id =
+ corner_table->Vertex(CornerIndex(3 * f.value() + p));
+ if (vert_id == kInvalidVertexIndex) {
+ return false;
+ }
+ const AttributeValueIndex att_entry_id(
+ encoding_data_
+ ->vertex_to_encoded_attribute_value_index_map[vert_id.value()]);
+ if (point_id >= num_points || att_entry_id.value() >= num_points) {
+ // There cannot be more attribute values than the number of points.
+ return false;
+ }
+ attribute->SetPointMapEntry(point_id, att_entry_id);
+ }
+ }
+ return true;
+ }
+
+ protected:
+ bool GenerateSequenceInternal() override {
+ // Preallocate memory for storing point indices. We expect the number of
+ // points to be the same as the number of corner table vertices.
+ out_point_ids()->reserve(traverser_.corner_table()->num_vertices());
+
+ traverser_.OnTraversalStart();
+ if (corner_order_) {
+ for (uint32_t i = 0; i < corner_order_->size(); ++i) {
+ if (!ProcessCorner(corner_order_->at(i))) {
+ return false;
+ }
+ }
+ } else {
+ const int32_t num_faces = traverser_.corner_table()->num_faces();
+ for (int i = 0; i < num_faces; ++i) {
+ if (!ProcessCorner(CornerIndex(3 * i))) {
+ return false;
+ }
+ }
+ }
+ traverser_.OnTraversalEnd();
+ return true;
+ }
+
+ private:
+ bool ProcessCorner(CornerIndex corner_id) {
+ return traverser_.TraverseFromCorner(corner_id);
+ }
+
+ TraverserT traverser_;
+ const Mesh *mesh_;
+ const MeshAttributeIndicesEncodingData *encoding_data_;
+ const std::vector<CornerIndex> *corner_order_;
+};
+
+} // namespace draco
+
+#endif // DRACO_COMPRESSION_MESH_TRAVERSER_MESH_TRAVERSAL_SEQUENCER_H_