Welcome to mirror list, hosted at ThFree Co, Russian Federation.

valence_cache.h « mesh « draco « src « draco « draco « extern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3540377db81f23ed92619ab28d74a7895da88e10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// 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_MESH_VALENCE_CACHE_H_
#define DRACO_MESH_VALENCE_CACHE_H_

#include "draco/attributes/geometry_indices.h"
#include "draco/core/draco_index_type_vector.h"
#include "draco/core/macros.h"

namespace draco {

// ValenceCache provides support for the caching of valences off of some kind of
// CornerTable 'type' of class.
// No valences should be queried before Caching is
// performed and values should be removed/recached when changes to the
// underlying mesh are taking place.

template <class CornerTableT>
class ValenceCache {
  const CornerTableT &table_;

 public:
  explicit ValenceCache(const CornerTableT &table) : table_(table) {}

  // Do not call before CacheValences() / CacheValencesInaccurate().
  inline int8_t ValenceFromCacheInaccurate(CornerIndex c) const {
    if (c == kInvalidCornerIndex) {
      return -1;
    }
    return ValenceFromCacheInaccurate(table_.Vertex(c));
  }
  inline int32_t ValenceFromCache(CornerIndex c) const {
    if (c == kInvalidCornerIndex) {
      return -1;
    }
    return ValenceFromCache(table_.Vertex(c));
  }

  inline int32_t ConfidentValenceFromCache(VertexIndex v) const {
    DRACO_DCHECK_LT(v.value(), table_.num_vertices());
    DRACO_DCHECK_EQ(vertex_valence_cache_32_bit_.size(), table_.num_vertices());
    return vertex_valence_cache_32_bit_[v];
  }

  // Collect the valence for all vertices so they can be reused later.  The
  // 'inaccurate' versions of this family of functions clips the true valence
  // of the vertices to 8 signed bits as a space optimization.  This clipping
  // will lead to occasionally wrong results.  If accurate results are required
  // under all circumstances, do not use the 'inaccurate' version or else
  // use it and fetch the correct result in the event the value appears clipped.
  // The topology of the mesh should be a constant when Valence Cache functions
  // are being used.  Modification of the mesh while cache(s) are filled will
  // not guarantee proper results on subsequent calls unless they are rebuilt.
  void CacheValencesInaccurate() const {
    if (vertex_valence_cache_8_bit_.size() == 0) {
      const VertexIndex vertex_count = VertexIndex(table_.num_vertices());
      vertex_valence_cache_8_bit_.resize(vertex_count.value());
      for (VertexIndex v = VertexIndex(0); v < vertex_count; v += 1) {
        vertex_valence_cache_8_bit_[v] = static_cast<int8_t>(
            (std::min)(static_cast<int32_t>(std::numeric_limits<int8_t>::max()),
                       table_.Valence(v)));
      }
    }
  }
  void CacheValences() const {
    if (vertex_valence_cache_32_bit_.size() == 0) {
      const VertexIndex vertex_count = VertexIndex(table_.num_vertices());
      vertex_valence_cache_32_bit_.resize(vertex_count.value());
      for (VertexIndex v = VertexIndex(0); v < vertex_count; v += 1) {
        vertex_valence_cache_32_bit_[v] = table_.Valence(v);
      }
    }
  }

  inline int8_t ConfidentValenceFromCacheInaccurate(CornerIndex c) const {
    DRACO_DCHECK_GE(c.value(), 0);
    return ConfidentValenceFromCacheInaccurate(table_.ConfidentVertex(c));
  }
  inline int32_t ConfidentValenceFromCache(CornerIndex c) const {
    DRACO_DCHECK_GE(c.value(), 0);
    return ConfidentValenceFromCache(table_.ConfidentVertex(c));
  }
  inline int8_t ValenceFromCacheInaccurate(VertexIndex v) const {
    DRACO_DCHECK_EQ(vertex_valence_cache_8_bit_.size(), table_.num_vertices());
    if (v == kInvalidVertexIndex || v.value() >= table_.num_vertices()) {
      return -1;
    }
    return ConfidentValenceFromCacheInaccurate(v);
  }
  inline int8_t ConfidentValenceFromCacheInaccurate(VertexIndex v) const {
    DRACO_DCHECK_LT(v.value(), table_.num_vertices());
    DRACO_DCHECK_EQ(vertex_valence_cache_8_bit_.size(), table_.num_vertices());
    return vertex_valence_cache_8_bit_[v];
  }

  // TODO(draco-eng) Add unit tests for ValenceCache functions.
  inline int32_t ValenceFromCache(VertexIndex v) const {
    DRACO_DCHECK_EQ(vertex_valence_cache_32_bit_.size(), table_.num_vertices());
    if (v == kInvalidVertexIndex || v.value() >= table_.num_vertices()) {
      return -1;
    }
    return ConfidentValenceFromCache(v);
  }

  // Clear the cache of valences and deallocate the memory.
  void ClearValenceCacheInaccurate() const {
    vertex_valence_cache_8_bit_.clear();
    // Force erasure.
    IndexTypeVector<VertexIndex, int8_t>().swap(vertex_valence_cache_8_bit_);
  }
  void ClearValenceCache() const {
    vertex_valence_cache_32_bit_.clear();
    // Force erasure.
    IndexTypeVector<VertexIndex, int32_t>().swap(vertex_valence_cache_32_bit_);
  }

  bool IsCacheEmpty() const {
    return vertex_valence_cache_8_bit_.size() == 0 &&
           vertex_valence_cache_32_bit_.size() == 0;
  }

 private:
  // Retain valences and clip them to char size.
  mutable IndexTypeVector<VertexIndex, int8_t> vertex_valence_cache_8_bit_;
  mutable IndexTypeVector<VertexIndex, int32_t> vertex_valence_cache_32_bit_;
};

}  // namespace draco

#endif  // DRACO_MESH_VALENCE_CACHE_H_