Coverage Report

Created: 2024-09-08 06:46

/src/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2016 The Draco Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
#ifndef DRACO_COMPRESSION_MESH_TRAVERSER_MESH_TRAVERSAL_SEQUENCER_H_
16
#define DRACO_COMPRESSION_MESH_TRAVERSER_MESH_TRAVERSAL_SEQUENCER_H_
17
18
#include "draco/attributes/geometry_indices.h"
19
#include "draco/compression/attributes/mesh_attribute_indices_encoding_data.h"
20
#include "draco/compression/attributes/points_sequencer.h"
21
#include "draco/mesh/mesh.h"
22
23
namespace draco {
24
25
// Sequencer that generates point sequence in an order given by a deterministic
26
// traversal on the mesh surface. Note that all attributes encoded with this
27
// sequence must share the same connectivity.
28
// TODO(b/199760123): Consider refactoring such that this is an observer.
29
template <class TraverserT>
30
class MeshTraversalSequencer : public PointsSequencer {
31
 public:
32
  MeshTraversalSequencer(const Mesh *mesh,
33
                         const MeshAttributeIndicesEncodingData *encoding_data)
34
3.76k
      : mesh_(mesh), encoding_data_(encoding_data), corner_order_(nullptr) {}
draco::MeshTraversalSequencer<draco::MaxPredictionDegreeTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::MeshTraversalSequencer(draco::Mesh const*, draco::MeshAttributeIndicesEncodingData const*)
Line
Count
Source
34
600
      : mesh_(mesh), encoding_data_(encoding_data), corner_order_(nullptr) {}
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::MeshTraversalSequencer(draco::Mesh const*, draco::MeshAttributeIndicesEncodingData const*)
Line
Count
Source
34
1.41k
      : mesh_(mesh), encoding_data_(encoding_data), corner_order_(nullptr) {}
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::MeshAttributeCornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::MeshAttributeCornerTable> > >::MeshTraversalSequencer(draco::Mesh const*, draco::MeshAttributeIndicesEncodingData const*)
Line
Count
Source
34
1.75k
      : mesh_(mesh), encoding_data_(encoding_data), corner_order_(nullptr) {}
35
3.76k
  void SetTraverser(const TraverserT &t) { traverser_ = t; }
draco::MeshTraversalSequencer<draco::MaxPredictionDegreeTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::SetTraverser(draco::MaxPredictionDegreeTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > const&)
Line
Count
Source
35
600
  void SetTraverser(const TraverserT &t) { traverser_ = t; }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::SetTraverser(draco::DepthFirstTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > const&)
Line
Count
Source
35
1.41k
  void SetTraverser(const TraverserT &t) { traverser_ = t; }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::MeshAttributeCornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::MeshAttributeCornerTable> > >::SetTraverser(draco::DepthFirstTraverser<draco::MeshAttributeCornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::MeshAttributeCornerTable> > const&)
Line
Count
Source
35
1.75k
  void SetTraverser(const TraverserT &t) { traverser_ = t; }
36
37
  // Function that can be used to set an order in which the mesh corners should
38
  // be processed. This is an optional flag used usually only by the encoder
39
  // to match the same corner order that is going to be used by the decoder.
40
  // Note that |corner_order| should contain only one corner per face (it can
41
  // have all corners but only the first encountered corner for each face is
42
  // going to be used to start a traversal). If the corner order is not set, the
43
  // corners are processed sequentially based on their ids.
44
  void SetCornerOrder(const std::vector<CornerIndex> &corner_order) {
45
    corner_order_ = &corner_order;
46
  }
47
48
19.0k
  bool UpdatePointToAttributeIndexMapping(PointAttribute *attribute) override {
49
19.0k
    const auto *corner_table = traverser_.corner_table();
50
19.0k
    attribute->SetExplicitMapping(mesh_->num_points());
51
19.0k
    const size_t num_faces = mesh_->num_faces();
52
19.0k
    const size_t num_points = mesh_->num_points();
53
18.2M
    for (FaceIndex f(0); f < static_cast<uint32_t>(num_faces); ++f) {
54
18.1M
      const auto &face = mesh_->face(f);
55
72.7M
      for (int p = 0; p < 3; ++p) {
56
54.5M
        const PointIndex point_id = face[p];
57
54.5M
        const VertexIndex vert_id =
58
54.5M
            corner_table->Vertex(CornerIndex(3 * f.value() + p));
59
54.5M
        if (vert_id == kInvalidVertexIndex) {
60
0
          return false;
61
0
        }
62
54.5M
        const AttributeValueIndex att_entry_id(
63
54.5M
            encoding_data_
64
54.5M
                ->vertex_to_encoded_attribute_value_index_map[vert_id.value()]);
65
54.5M
        if (point_id >= num_points || att_entry_id.value() >= num_points) {
66
          // There cannot be more attribute values than the number of points.
67
0
          return false;
68
0
        }
69
54.5M
        attribute->SetPointMapEntry(point_id, att_entry_id);
70
54.5M
      }
71
18.1M
    }
72
19.0k
    return true;
73
19.0k
  }
draco::MeshTraversalSequencer<draco::MaxPredictionDegreeTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::UpdatePointToAttributeIndexMapping(draco::PointAttribute*)
Line
Count
Source
48
1.36k
  bool UpdatePointToAttributeIndexMapping(PointAttribute *attribute) override {
49
1.36k
    const auto *corner_table = traverser_.corner_table();
50
1.36k
    attribute->SetExplicitMapping(mesh_->num_points());
51
1.36k
    const size_t num_faces = mesh_->num_faces();
52
1.36k
    const size_t num_points = mesh_->num_points();
53
3.75M
    for (FaceIndex f(0); f < static_cast<uint32_t>(num_faces); ++f) {
54
3.75M
      const auto &face = mesh_->face(f);
55
15.0M
      for (int p = 0; p < 3; ++p) {
56
11.2M
        const PointIndex point_id = face[p];
57
11.2M
        const VertexIndex vert_id =
58
11.2M
            corner_table->Vertex(CornerIndex(3 * f.value() + p));
59
11.2M
        if (vert_id == kInvalidVertexIndex) {
60
0
          return false;
61
0
        }
62
11.2M
        const AttributeValueIndex att_entry_id(
63
11.2M
            encoding_data_
64
11.2M
                ->vertex_to_encoded_attribute_value_index_map[vert_id.value()]);
65
11.2M
        if (point_id >= num_points || att_entry_id.value() >= num_points) {
66
          // There cannot be more attribute values than the number of points.
67
0
          return false;
68
0
        }
69
11.2M
        attribute->SetPointMapEntry(point_id, att_entry_id);
70
11.2M
      }
71
3.75M
    }
72
1.36k
    return true;
73
1.36k
  }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::UpdatePointToAttributeIndexMapping(draco::PointAttribute*)
Line
Count
Source
48
8.85k
  bool UpdatePointToAttributeIndexMapping(PointAttribute *attribute) override {
49
8.85k
    const auto *corner_table = traverser_.corner_table();
50
8.85k
    attribute->SetExplicitMapping(mesh_->num_points());
51
8.85k
    const size_t num_faces = mesh_->num_faces();
52
8.85k
    const size_t num_points = mesh_->num_points();
53
7.25M
    for (FaceIndex f(0); f < static_cast<uint32_t>(num_faces); ++f) {
54
7.24M
      const auto &face = mesh_->face(f);
55
28.9M
      for (int p = 0; p < 3; ++p) {
56
21.7M
        const PointIndex point_id = face[p];
57
21.7M
        const VertexIndex vert_id =
58
21.7M
            corner_table->Vertex(CornerIndex(3 * f.value() + p));
59
21.7M
        if (vert_id == kInvalidVertexIndex) {
60
0
          return false;
61
0
        }
62
21.7M
        const AttributeValueIndex att_entry_id(
63
21.7M
            encoding_data_
64
21.7M
                ->vertex_to_encoded_attribute_value_index_map[vert_id.value()]);
65
21.7M
        if (point_id >= num_points || att_entry_id.value() >= num_points) {
66
          // There cannot be more attribute values than the number of points.
67
0
          return false;
68
0
        }
69
21.7M
        attribute->SetPointMapEntry(point_id, att_entry_id);
70
21.7M
      }
71
7.24M
    }
72
8.85k
    return true;
73
8.85k
  }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::MeshAttributeCornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::MeshAttributeCornerTable> > >::UpdatePointToAttributeIndexMapping(draco::PointAttribute*)
Line
Count
Source
48
8.82k
  bool UpdatePointToAttributeIndexMapping(PointAttribute *attribute) override {
49
8.82k
    const auto *corner_table = traverser_.corner_table();
50
8.82k
    attribute->SetExplicitMapping(mesh_->num_points());
51
8.82k
    const size_t num_faces = mesh_->num_faces();
52
8.82k
    const size_t num_points = mesh_->num_points();
53
7.18M
    for (FaceIndex f(0); f < static_cast<uint32_t>(num_faces); ++f) {
54
7.18M
      const auto &face = mesh_->face(f);
55
28.7M
      for (int p = 0; p < 3; ++p) {
56
21.5M
        const PointIndex point_id = face[p];
57
21.5M
        const VertexIndex vert_id =
58
21.5M
            corner_table->Vertex(CornerIndex(3 * f.value() + p));
59
21.5M
        if (vert_id == kInvalidVertexIndex) {
60
0
          return false;
61
0
        }
62
21.5M
        const AttributeValueIndex att_entry_id(
63
21.5M
            encoding_data_
64
21.5M
                ->vertex_to_encoded_attribute_value_index_map[vert_id.value()]);
65
21.5M
        if (point_id >= num_points || att_entry_id.value() >= num_points) {
66
          // There cannot be more attribute values than the number of points.
67
0
          return false;
68
0
        }
69
21.5M
        attribute->SetPointMapEntry(point_id, att_entry_id);
70
21.5M
      }
71
7.18M
    }
72
8.82k
    return true;
73
8.82k
  }
74
75
 protected:
76
3.69k
  bool GenerateSequenceInternal() override {
77
    // Preallocate memory for storing point indices. We expect the number of
78
    // points to be the same as the number of corner table vertices.
79
3.69k
    out_point_ids()->reserve(traverser_.corner_table()->num_vertices());
80
81
3.69k
    traverser_.OnTraversalStart();
82
3.69k
    if (corner_order_) {
83
0
      for (uint32_t i = 0; i < corner_order_->size(); ++i) {
84
0
        if (!ProcessCorner(corner_order_->at(i))) {
85
0
          return false;
86
0
        }
87
0
      }
88
3.69k
    } else {
89
3.69k
      const int32_t num_faces = traverser_.corner_table()->num_faces();
90
8.62M
      for (int i = 0; i < num_faces; ++i) {
91
8.61M
        if (!ProcessCorner(CornerIndex(3 * i))) {
92
0
          return false;
93
0
        }
94
8.61M
      }
95
3.69k
    }
96
3.69k
    traverser_.OnTraversalEnd();
97
3.69k
    return true;
98
3.69k
  }
draco::MeshTraversalSequencer<draco::MaxPredictionDegreeTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::GenerateSequenceInternal()
Line
Count
Source
76
581
  bool GenerateSequenceInternal() override {
77
    // Preallocate memory for storing point indices. We expect the number of
78
    // points to be the same as the number of corner table vertices.
79
581
    out_point_ids()->reserve(traverser_.corner_table()->num_vertices());
80
81
581
    traverser_.OnTraversalStart();
82
581
    if (corner_order_) {
83
0
      for (uint32_t i = 0; i < corner_order_->size(); ++i) {
84
0
        if (!ProcessCorner(corner_order_->at(i))) {
85
0
          return false;
86
0
        }
87
0
      }
88
581
    } else {
89
581
      const int32_t num_faces = traverser_.corner_table()->num_faces();
90
1.95M
      for (int i = 0; i < num_faces; ++i) {
91
1.95M
        if (!ProcessCorner(CornerIndex(3 * i))) {
92
0
          return false;
93
0
        }
94
1.95M
      }
95
581
    }
96
581
    traverser_.OnTraversalEnd();
97
581
    return true;
98
581
  }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::GenerateSequenceInternal()
Line
Count
Source
76
1.37k
  bool GenerateSequenceInternal() override {
77
    // Preallocate memory for storing point indices. We expect the number of
78
    // points to be the same as the number of corner table vertices.
79
1.37k
    out_point_ids()->reserve(traverser_.corner_table()->num_vertices());
80
81
1.37k
    traverser_.OnTraversalStart();
82
1.37k
    if (corner_order_) {
83
0
      for (uint32_t i = 0; i < corner_order_->size(); ++i) {
84
0
        if (!ProcessCorner(corner_order_->at(i))) {
85
0
          return false;
86
0
        }
87
0
      }
88
1.37k
    } else {
89
1.37k
      const int32_t num_faces = traverser_.corner_table()->num_faces();
90
3.07M
      for (int i = 0; i < num_faces; ++i) {
91
3.07M
        if (!ProcessCorner(CornerIndex(3 * i))) {
92
0
          return false;
93
0
        }
94
3.07M
      }
95
1.37k
    }
96
1.37k
    traverser_.OnTraversalEnd();
97
1.37k
    return true;
98
1.37k
  }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::MeshAttributeCornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::MeshAttributeCornerTable> > >::GenerateSequenceInternal()
Line
Count
Source
76
1.73k
  bool GenerateSequenceInternal() override {
77
    // Preallocate memory for storing point indices. We expect the number of
78
    // points to be the same as the number of corner table vertices.
79
1.73k
    out_point_ids()->reserve(traverser_.corner_table()->num_vertices());
80
81
1.73k
    traverser_.OnTraversalStart();
82
1.73k
    if (corner_order_) {
83
0
      for (uint32_t i = 0; i < corner_order_->size(); ++i) {
84
0
        if (!ProcessCorner(corner_order_->at(i))) {
85
0
          return false;
86
0
        }
87
0
      }
88
1.73k
    } else {
89
1.73k
      const int32_t num_faces = traverser_.corner_table()->num_faces();
90
3.58M
      for (int i = 0; i < num_faces; ++i) {
91
3.58M
        if (!ProcessCorner(CornerIndex(3 * i))) {
92
0
          return false;
93
0
        }
94
3.58M
      }
95
1.73k
    }
96
1.73k
    traverser_.OnTraversalEnd();
97
1.73k
    return true;
98
1.73k
  }
99
100
 private:
101
8.61M
  bool ProcessCorner(CornerIndex corner_id) {
102
8.61M
    return traverser_.TraverseFromCorner(corner_id);
103
8.61M
  }
draco::MeshTraversalSequencer<draco::MaxPredictionDegreeTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::ProcessCorner(draco::IndexType<unsigned int, draco::CornerIndex_tag_type_>)
Line
Count
Source
101
1.95M
  bool ProcessCorner(CornerIndex corner_id) {
102
1.95M
    return traverser_.TraverseFromCorner(corner_id);
103
1.95M
  }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::CornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::CornerTable> > >::ProcessCorner(draco::IndexType<unsigned int, draco::CornerIndex_tag_type_>)
Line
Count
Source
101
3.07M
  bool ProcessCorner(CornerIndex corner_id) {
102
3.07M
    return traverser_.TraverseFromCorner(corner_id);
103
3.07M
  }
draco::MeshTraversalSequencer<draco::DepthFirstTraverser<draco::MeshAttributeCornerTable, draco::MeshAttributeIndicesEncodingObserver<draco::MeshAttributeCornerTable> > >::ProcessCorner(draco::IndexType<unsigned int, draco::CornerIndex_tag_type_>)
Line
Count
Source
101
3.58M
  bool ProcessCorner(CornerIndex corner_id) {
102
3.58M
    return traverser_.TraverseFromCorner(corner_id);
103
3.58M
  }
104
105
  TraverserT traverser_;
106
  const Mesh *mesh_;
107
  const MeshAttributeIndicesEncodingData *encoding_data_;
108
  const std::vector<CornerIndex> *corner_order_;
109
};
110
111
}  // namespace draco
112
113
#endif  // DRACO_COMPRESSION_MESH_TRAVERSER_MESH_TRAVERSAL_SEQUENCER_H_