GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
mesh_edgebreaker_traversal_valence_encoder.h
Go to the documentation of this file.
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_MESH_EDGEBREAKER_TRAVERSAL_VALENCE_ENCODER_H_
16#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_VALENCE_ENCODER_H_
17
21
22namespace draco {
23
24// Predictive encoder for the Edgebreaker symbols based on valences of the
25// previously encoded vertices, following the method described in: Szymczak'02,
26// "Optimized Edgebreaker Encoding for Large and Regular Triangle Meshes". Each
27// valence is used to specify a different entropy context for encoding of the
28// symbols.
29// Encoder can operate in various predefined modes that can be used to select
30// the way in which the entropy contexts are computed (e.g. using different
31// clamping for valences, or even using different inputs to compute the
32// contexts), see EdgebreakerValenceCodingMode in mesh_edgebreaker_shared.h for
33// a list of supported modes.
36 public:
38 : corner_table_(nullptr),
39 prev_symbol_(-1),
40 last_corner_(kInvalidCornerIndex),
41 num_symbols_(0),
42 min_valence_(2),
43 max_valence_(7) {}
44
47 return false;
48 }
49 min_valence_ = 2;
50 max_valence_ = 7;
51 corner_table_ = encoder->GetCornerTable();
52
53 // Initialize valences of all vertices.
54 vertex_valences_.resize(corner_table_->num_vertices());
55 for (VertexIndex i(0); i < static_cast<uint32_t>(vertex_valences_.size());
56 ++i) {
57 vertex_valences_[i] = corner_table_->Valence(VertexIndex(i));
58 }
59
60 // Replicate the corner to vertex map from the corner table. We need to do
61 // this because the map may get updated during encoding because we add new
62 // vertices when we encounter split symbols.
63 corner_to_vertex_map_.resize(corner_table_->num_corners());
64 for (CornerIndex i(0); i < corner_table_->num_corners(); ++i) {
65 corner_to_vertex_map_[i] = corner_table_->Vertex(i);
66 }
67 const int32_t num_unique_valences = max_valence_ - min_valence_ + 1;
68
69 context_symbols_.resize(num_unique_valences);
70 return true;
71 }
72
73 inline void NewCornerReached(CornerIndex corner) { last_corner_ = corner; }
74
76 ++num_symbols_;
77 // Update valences on the mesh and compute the context that is going to be
78 // used to encode the processed symbol.
79 // Note that the valences are computed for the so far unencoded part of the
80 // mesh (i.e. the decoding is reverse). Adding a new symbol either reduces
81 // valences on the vertices or leaves the valence unchanged.
82
83 const CornerIndex next = corner_table_->Next(last_corner_);
84 const CornerIndex prev = corner_table_->Previous(last_corner_);
85
86 // Get valence on the tip corner of the active edge (outgoing edge that is
87 // going to be used in reverse decoding of the connectivity to predict the
88 // next symbol).
89 const int active_valence = vertex_valences_[corner_to_vertex_map_[next]];
90 switch (symbol) {
91 case TOPOLOGY_C:
92 // Compute prediction.
94 case TOPOLOGY_S:
95 // Update valences.
96 vertex_valences_[corner_to_vertex_map_[next]] -= 1;
97 vertex_valences_[corner_to_vertex_map_[prev]] -= 1;
98 if (symbol == TOPOLOGY_S) {
99 // Whenever we reach a split symbol, we need to split the vertex into
100 // two and attach all corners on the left and right sides of the split
101 // vertex to the respective vertices (see image below). This is
102 // necessary since the decoder works in the reverse order and it
103 // merges the two vertices only after the split symbol is processed.
104 //
105 // * -----
106 // / \--------
107 // / \--------
108 // / \-------
109 // *-------v-------*
110 // \ /c\ /
111 // \ / \ /
112 // \ /n S p\ /
113 // *.......*
114 //
115
116 // Count the number of faces on the left side of the split vertex and
117 // update the valence on the "left vertex".
118 int num_left_faces = 0;
119 CornerIndex act_c = corner_table_->Opposite(prev);
120 while (act_c != kInvalidCornerIndex) {
121 if (encoder_impl()->IsFaceEncoded(corner_table_->Face(act_c))) {
122 break; // Stop when we reach the first visited face.
123 }
124 ++num_left_faces;
125 act_c = corner_table_->Opposite(corner_table_->Next(act_c));
126 }
127 vertex_valences_[corner_to_vertex_map_[last_corner_]] =
128 num_left_faces + 1;
129
130 // Create a new vertex for the right side and count the number of
131 // faces that should be attached to this vertex.
132 const int new_vert_id = static_cast<int>(vertex_valences_.size());
133 int num_right_faces = 0;
134
135 act_c = corner_table_->Opposite(next);
136 while (act_c != kInvalidCornerIndex) {
137 if (encoder_impl()->IsFaceEncoded(corner_table_->Face(act_c))) {
138 break; // Stop when we reach the first visited face.
139 }
140 ++num_right_faces;
141 // Map corners on the right side to the newly created vertex.
142 corner_to_vertex_map_[corner_table_->Next(act_c)] = new_vert_id;
143 act_c = corner_table_->Opposite(corner_table_->Previous(act_c));
144 }
145 vertex_valences_.push_back(num_right_faces + 1);
146 }
147 break;
148 case TOPOLOGY_R:
149 // Update valences.
150 vertex_valences_[corner_to_vertex_map_[last_corner_]] -= 1;
151 vertex_valences_[corner_to_vertex_map_[next]] -= 1;
152 vertex_valences_[corner_to_vertex_map_[prev]] -= 2;
153 break;
154 case TOPOLOGY_L:
155
156 vertex_valences_[corner_to_vertex_map_[last_corner_]] -= 1;
157 vertex_valences_[corner_to_vertex_map_[next]] -= 2;
158 vertex_valences_[corner_to_vertex_map_[prev]] -= 1;
159 break;
160 case TOPOLOGY_E:
161 vertex_valences_[corner_to_vertex_map_[last_corner_]] -= 2;
162 vertex_valences_[corner_to_vertex_map_[next]] -= 2;
163 vertex_valences_[corner_to_vertex_map_[prev]] -= 2;
164 break;
165 default:
166 break;
167 }
168
169 if (prev_symbol_ != -1) {
170 int clamped_valence;
171 if (active_valence < min_valence_) {
172 clamped_valence = min_valence_;
173 } else if (active_valence > max_valence_) {
174 clamped_valence = max_valence_;
175 } else {
176 clamped_valence = active_valence;
177 }
178
179 const int context = clamped_valence - min_valence_;
180 context_symbols_[context].push_back(
182 }
183
184 prev_symbol_ = symbol;
185 }
186
187 void Done() {
188 // Store the init face configurations and attribute seam data
191
192 // Store the contexts.
193 for (int i = 0; i < context_symbols_.size(); ++i) {
194 EncodeVarint<uint32_t>(static_cast<uint32_t>(context_symbols_[i].size()),
196 if (context_symbols_[i].size() > 0) {
197 EncodeSymbols(context_symbols_[i].data(),
198 static_cast<int>(context_symbols_[i].size()), 1, nullptr,
200 }
201 }
202 }
203
204 int NumEncodedSymbols() const { return num_symbols_; }
205
206 private:
207 const CornerTable *corner_table_;
208 // Explicit map between corners and vertices. We cannot use the one stored
209 // in the |corner_table_| because we may need to add additional vertices to
210 // handle split symbols.
211 IndexTypeVector<CornerIndex, VertexIndex> corner_to_vertex_map_;
212 IndexTypeVector<VertexIndex, int> vertex_valences_;
213 // Previously encoded symbol.
214 int32_t prev_symbol_;
215 CornerIndex last_corner_;
216 // Explicitly count the number of encoded symbols.
217 int num_symbols_;
218
219 int min_valence_;
220 int max_valence_;
221 std::vector<std::vector<uint32_t>> context_symbols_;
222};
223
224} // namespace draco
225
226#endif // DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_VALENCE_ENCODER_H_
Definition corner_table.h:53
Definition draco_index_type_vector.h:32
Definition mesh_edgebreaker_encoder_impl_interface.h:33
virtual const CornerTable * GetCornerTable() const =0
EncoderBuffer * GetOutputBuffer()
Definition mesh_edgebreaker_traversal_encoder.h:120
const MeshEdgebreakerEncoderImplInterface * encoder_impl() const
Definition mesh_edgebreaker_traversal_encoder.h:121
MeshEdgebreakerTraversalEncoder()
Definition mesh_edgebreaker_traversal_encoder.h:33
void EncodeStartFaces()
Definition mesh_edgebreaker_traversal_encoder.h:108
bool Init(MeshEdgebreakerEncoderImplInterface *encoder)
Definition mesh_edgebreaker_traversal_encoder.h:37
void EncodeAttributeSeams()
Definition mesh_edgebreaker_traversal_encoder.h:112
void NewCornerReached(CornerIndex corner)
Definition mesh_edgebreaker_traversal_valence_encoder.h:73
bool Init(MeshEdgebreakerEncoderImplInterface *encoder)
Definition mesh_edgebreaker_traversal_valence_encoder.h:45
int NumEncodedSymbols() const
Definition mesh_edgebreaker_traversal_valence_encoder.h:204
void EncodeSymbol(EdgebreakerTopologyBitPattern symbol)
Definition mesh_edgebreaker_traversal_valence_encoder.h:75
MeshEdgebreakerTraversalValenceEncoder()
Definition mesh_edgebreaker_traversal_valence_encoder.h:37
void Done()
Definition mesh_edgebreaker_traversal_valence_encoder.h:187
#define FALLTHROUGH_INTENDED
Definition macros.h:54
lazy data
Definition meshpage.php:1583
n< br > font size
Definition meshpage.php:3536
Definition attribute_octahedron_transform.cc:21
VertexIndex VertexIndex
Definition mesh_edgebreaker_encoder_impl.cc:37
bool EncodeSymbols(const uint32_t *symbols, int num_values, int num_components, const Options *options, EncoderBuffer *target_buffer)
Definition symbol_encoding.cc:118
CornerIndex CornerIndex
Definition mesh_edgebreaker_encoder_impl.cc:35
bool EncodeVarint(IntTypeT val, EncoderBuffer *out_buffer)
Definition varint_encoding.h:28
EdgebreakerTopologyBitPattern
Definition mesh_edgebreaker_shared.h:53
@ TOPOLOGY_R
Definition mesh_edgebreaker_shared.h:57
@ TOPOLOGY_S
Definition mesh_edgebreaker_shared.h:55
@ TOPOLOGY_L
Definition mesh_edgebreaker_shared.h:56
@ TOPOLOGY_E
Definition mesh_edgebreaker_shared.h:58
@ TOPOLOGY_C
Definition mesh_edgebreaker_shared.h:54
constexpr EdgebreakerSymbol edge_breaker_topology_to_symbol_id[]
Definition mesh_edgebreaker_shared.h:82