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     }
49     return is_face_visited_[face_id.value()];
50   }
51 
52   // Returns true if the face containing the given corner was visited.
IsFaceVisited(CornerIndex corner_id)53   inline bool IsFaceVisited(CornerIndex corner_id) const {
54     if (corner_id == kInvalidCornerIndex) {
55       return true;  // Invalid faces are always considered as visited.
56     }
57     return is_face_visited_[corner_id.value() / 3];
58   }
59 
MarkFaceVisited(FaceIndex face_id)60   inline void MarkFaceVisited(FaceIndex face_id) {
61     is_face_visited_[face_id.value()] = true;
62   }
IsVertexVisited(VertexIndex vert_id)63   inline bool IsVertexVisited(VertexIndex vert_id) const {
64     return is_vertex_visited_[vert_id.value()];
65   }
MarkVertexVisited(VertexIndex vert_id)66   inline void MarkVertexVisited(VertexIndex vert_id) {
67     is_vertex_visited_[vert_id.value()] = true;
68   }
69 
corner_table()70   inline const CornerTable *corner_table() const { return corner_table_; }
traversal_observer()71   inline const TraversalObserverT &traversal_observer() const {
72     return traversal_observer_;
73   }
traversal_observer()74   inline TraversalObserverT &traversal_observer() {
75     return traversal_observer_;
76   }
77 
78  private:
79   const CornerTable *corner_table_;
80   TraversalObserverT traversal_observer_;
81   std::vector<bool> is_face_visited_;
82   std::vector<bool> is_vertex_visited_;
83 };
84 
85 }  // namespace draco
86 
87 #endif  // DRACO_COMPRESSION_MESH_TRAVERSER_TRAVERSER_BASE_H_
88