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_TRAVERSER_BASE_H_
16 #define DRACO_COMPRESSION_MESH_TRAVERSER_TRAVERSER_BASE_H_
17 
18 #include "draco/mesh/corner_table.h"
19 
20 namespace draco {
21 
22 // Class providing the basic traversal functionality needed by traversers (such
23 // as the DepthFirstTraverser, see depth_first_traverser.h). It keeps a pointer
24 // to the corner table that is used for the traversal, plus it provides a basic
25 // bookkeeping of visited faces and vertices during the traversal.
26 template <class CornerTableT, class TraversalObserverT>
27 class TraverserBase {
28  public:
29   typedef CornerTableT CornerTable;
30   typedef TraversalObserverT TraversalObserver;
31 
TraverserBase()32   TraverserBase() : corner_table_(nullptr) {}
33   virtual ~TraverserBase() = default;
34 
Init(const CornerTable * corner_table,TraversalObserver traversal_observer)35   virtual void Init(const CornerTable *corner_table,
36                     TraversalObserver traversal_observer) {
37     corner_table_ = corner_table;
38     is_face_visited_.assign(corner_table->num_faces(), false);
39     is_vertex_visited_.assign(corner_table_->num_vertices(), false);
40     traversal_observer_ = traversal_observer;
41   }
42 
GetCornerTable()43   const CornerTable &GetCornerTable() const { return *corner_table_; }
44 
IsFaceVisited(FaceIndex face_id)45   inline bool IsFaceVisited(FaceIndex face_id) const {
46     if (face_id == kInvalidFaceIndex)
47       return true;  // Invalid faces are always considered as visited.
48     return is_face_visited_[face_id.value()];
49   }
50 
51   // Returns true if the face containing the given corner was visited.
IsFaceVisited(CornerIndex corner_id)52   inline bool IsFaceVisited(CornerIndex corner_id) const {
53     if (corner_id == kInvalidCornerIndex)
54       return true;  // Invalid faces are always considered as visited.
55     return is_face_visited_[corner_id.value() / 3];
56   }
57 
MarkFaceVisited(FaceIndex face_id)58   inline void MarkFaceVisited(FaceIndex face_id) {
59     is_face_visited_[face_id.value()] = true;
60   }
IsVertexVisited(VertexIndex vert_id)61   inline bool IsVertexVisited(VertexIndex vert_id) const {
62     return is_vertex_visited_[vert_id.value()];
63   }
MarkVertexVisited(VertexIndex vert_id)64   inline void MarkVertexVisited(VertexIndex vert_id) {
65     is_vertex_visited_[vert_id.value()] = true;
66   }
67 
corner_table()68   inline const CornerTable *corner_table() const { return corner_table_; }
traversal_observer()69   inline const TraversalObserverT &traversal_observer() const {
70     return traversal_observer_;
71   }
traversal_observer()72   inline TraversalObserverT &traversal_observer() {
73     return traversal_observer_;
74   }
75 
76  private:
77   const CornerTable *corner_table_;
78   TraversalObserverT traversal_observer_;
79   std::vector<bool> is_face_visited_;
80   std::vector<bool> is_vertex_visited_;
81 };
82 
83 }  // namespace draco
84 
85 #endif  // DRACO_COMPRESSION_MESH_TRAVERSER_TRAVERSER_BASE_H_
86