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 #include "draco/compression/mesh/mesh_edgebreaker_decoder_impl.h"
16 
17 #include <algorithm>
18 
19 #include "draco/compression/attributes/sequential_attribute_decoders_controller.h"
20 #include "draco/compression/mesh/mesh_edgebreaker_decoder.h"
21 #include "draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h"
22 #include "draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h"
23 #include "draco/compression/mesh/traverser/depth_first_traverser.h"
24 #include "draco/compression/mesh/traverser/max_prediction_degree_traverser.h"
25 #include "draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h"
26 #include "draco/compression/mesh/traverser/mesh_traversal_sequencer.h"
27 #include "draco/compression/mesh/traverser/traverser_base.h"
28 #include "draco/mesh/corner_table_iterators.h"
29 
30 namespace draco {
31 
32 // Types of "free" edges that are used during topology decoding.
33 // A free edge is an edge that is connected to one face only.
34 // All edge types are stored in the opposite_corner_id_ array, where each
35 // edge "e" is uniquely identified by the opposite corner "C" in its parent
36 // triangle:
37 //          *
38 //         /C\
39 //        /   \
40 //       /  e  \
41 //      *-------*
42 // For more description about how the edges are used, see comment inside
43 // ZipConnectivity() method.
44 
45 template <class TraversalDecoder>
MeshEdgebreakerDecoderImpl()46 MeshEdgebreakerDecoderImpl<TraversalDecoder>::MeshEdgebreakerDecoderImpl()
47     : decoder_(nullptr),
48       last_symbol_id_(-1),
49       last_vert_id_(-1),
50       last_face_id_(-1),
51       num_new_vertices_(0),
52       num_encoded_vertices_(0),
53       pos_data_decoder_id_(-1) {}
54 
55 template <class TraversalDecoder>
Init(MeshEdgebreakerDecoder * decoder)56 bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::Init(
57     MeshEdgebreakerDecoder *decoder) {
58   decoder_ = decoder;
59   return true;
60 }
61 
62 template <class TraversalDecoder>
63 const MeshAttributeCornerTable *
GetAttributeCornerTable(int att_id) const64 MeshEdgebreakerDecoderImpl<TraversalDecoder>::GetAttributeCornerTable(
65     int att_id) const {
66   for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
67     const int decoder_id = attribute_data_[i].decoder_id;
68     if (decoder_id < 0 || decoder_id >= decoder_->num_attributes_decoders())
69       continue;
70     const AttributesDecoderInterface *const dec =
71         decoder_->attributes_decoder(decoder_id);
72     for (int j = 0; j < dec->GetNumAttributes(); ++j) {
73       if (dec->GetAttributeId(j) == att_id) {
74         if (attribute_data_[i].is_connectivity_used)
75           return &attribute_data_[i].connectivity_data;
76         return nullptr;
77       }
78     }
79   }
80   return nullptr;
81 }
82 
83 template <class TraversalDecoder>
84 const MeshAttributeIndicesEncodingData *
GetAttributeEncodingData(int att_id) const85 MeshEdgebreakerDecoderImpl<TraversalDecoder>::GetAttributeEncodingData(
86     int att_id) const {
87   for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
88     const int decoder_id = attribute_data_[i].decoder_id;
89     if (decoder_id < 0 || decoder_id >= decoder_->num_attributes_decoders())
90       continue;
91     const AttributesDecoderInterface *const dec =
92         decoder_->attributes_decoder(decoder_id);
93     for (int j = 0; j < dec->GetNumAttributes(); ++j) {
94       if (dec->GetAttributeId(j) == att_id)
95         return &attribute_data_[i].encoding_data;
96     }
97   }
98   return &pos_encoding_data_;
99 }
100 
101 template <class TraversalDecoder>
102 template <class TraverserT>
103 std::unique_ptr<PointsSequencer>
CreateVertexTraversalSequencer(MeshAttributeIndicesEncodingData * encoding_data)104 MeshEdgebreakerDecoderImpl<TraversalDecoder>::CreateVertexTraversalSequencer(
105     MeshAttributeIndicesEncodingData *encoding_data) {
106   typedef typename TraverserT::TraversalObserver AttObserver;
107   typedef typename TraverserT::CornerTable CornerTable;
108 
109   const Mesh *mesh = decoder_->mesh();
110   std::unique_ptr<MeshTraversalSequencer<TraverserT>> traversal_sequencer(
111       new MeshTraversalSequencer<TraverserT>(mesh, encoding_data));
112 
113   AttObserver att_observer(corner_table_.get(), mesh, traversal_sequencer.get(),
114                            encoding_data);
115 
116   TraverserT att_traverser;
117   att_traverser.Init(corner_table_.get(), att_observer);
118 
119   traversal_sequencer->SetTraverser(att_traverser);
120   return std::move(traversal_sequencer);
121 }
122 
123 template <class TraversalDecoder>
CreateAttributesDecoder(int32_t att_decoder_id)124 bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::CreateAttributesDecoder(
125     int32_t att_decoder_id) {
126   int8_t att_data_id;
127   if (!decoder_->buffer()->Decode(&att_data_id))
128     return false;
129   uint8_t decoder_type;
130   if (!decoder_->buffer()->Decode(&decoder_type))
131     return false;
132 
133   if (att_data_id >= 0) {
134     if (att_data_id >= attribute_data_.size()) {
135       return false;  // Unexpected attribute data.
136     }
137 
138     // Ensure that the attribute data is not mapped to a different attributes
139     // decoder already.
140     if (attribute_data_[att_data_id].decoder_id >= 0)
141       return false;
142 
143     attribute_data_[att_data_id].decoder_id = att_decoder_id;
144   } else {
145     // Assign the attributes decoder to |pos_encoding_data_|.
146     if (pos_data_decoder_id_ >= 0)
147       return false;  // Some other decoder is already using the data. Error.
148     pos_data_decoder_id_ = att_decoder_id;
149   }
150 
151   MeshTraversalMethod traversal_method = MESH_TRAVERSAL_DEPTH_FIRST;
152   if (decoder_->bitstream_version() >= DRACO_BITSTREAM_VERSION(1, 2)) {
153     uint8_t traversal_method_encoded;
154     if (!decoder_->buffer()->Decode(&traversal_method_encoded))
155       return false;
156     traversal_method =
157         static_cast<MeshTraversalMethod>(traversal_method_encoded);
158   }
159 
160   const Mesh *mesh = decoder_->mesh();
161   std::unique_ptr<PointsSequencer> sequencer;
162 
163   if (decoder_type == MESH_VERTEX_ATTRIBUTE) {
164     // Per-vertex attribute decoder.
165 
166     MeshAttributeIndicesEncodingData *encoding_data = nullptr;
167     if (att_data_id < 0) {
168       encoding_data = &pos_encoding_data_;
169     } else {
170       encoding_data = &attribute_data_[att_data_id].encoding_data;
171       // Mark the attribute connectivity data invalid to ensure it's not used
172       // later on.
173       attribute_data_[att_data_id].is_connectivity_used = false;
174     }
175     // Defining sequencer via a traversal scheme.
176     if (traversal_method == MESH_TRAVERSAL_PREDICTION_DEGREE) {
177       typedef MeshAttributeIndicesEncodingObserver<CornerTable> AttObserver;
178       typedef MaxPredictionDegreeTraverser<CornerTable, AttObserver>
179           AttTraverser;
180       sequencer = CreateVertexTraversalSequencer<AttTraverser>(encoding_data);
181     } else if (traversal_method == MESH_TRAVERSAL_DEPTH_FIRST) {
182       typedef MeshAttributeIndicesEncodingObserver<CornerTable> AttObserver;
183       typedef DepthFirstTraverser<CornerTable, AttObserver> AttTraverser;
184       sequencer = CreateVertexTraversalSequencer<AttTraverser>(encoding_data);
185     } else {
186       return false;  // Unsupported method
187     }
188   } else {
189     if (traversal_method != MESH_TRAVERSAL_DEPTH_FIRST)
190       return false;  // Unsupported method.
191     if (att_data_id < 0)
192       return false;  // Attribute data must be specified.
193 
194     // Per-corner attribute decoder.
195 
196     typedef MeshAttributeIndicesEncodingObserver<MeshAttributeCornerTable>
197         AttObserver;
198     typedef DepthFirstTraverser<MeshAttributeCornerTable, AttObserver>
199         AttTraverser;
200 
201     MeshAttributeIndicesEncodingData *const encoding_data =
202         &attribute_data_[att_data_id].encoding_data;
203     const MeshAttributeCornerTable *const corner_table =
204         &attribute_data_[att_data_id].connectivity_data;
205 
206     std::unique_ptr<MeshTraversalSequencer<AttTraverser>> traversal_sequencer(
207         new MeshTraversalSequencer<AttTraverser>(mesh, encoding_data));
208 
209     AttObserver att_observer(corner_table, mesh, traversal_sequencer.get(),
210                              encoding_data);
211 
212     AttTraverser att_traverser;
213     att_traverser.Init(corner_table, att_observer);
214 
215     traversal_sequencer->SetTraverser(att_traverser);
216     sequencer = std::move(traversal_sequencer);
217   }
218 
219   if (!sequencer)
220     return false;
221 
222   std::unique_ptr<SequentialAttributeDecodersController> att_controller(
223       new SequentialAttributeDecodersController(std::move(sequencer)));
224 
225   return decoder_->SetAttributesDecoder(att_decoder_id,
226                                         std::move(att_controller));
227 }
228 
229 template <class TraversalDecoder>
DecodeConnectivity()230 bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
231   num_new_vertices_ = 0;
232   new_to_parent_vertex_map_.clear();
233 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
234   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
235     uint32_t num_new_verts;
236     if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
237       if (!decoder_->buffer()->Decode(&num_new_verts))
238         return false;
239     } else {
240       if (!DecodeVarint(&num_new_verts, decoder_->buffer()))
241         return false;
242     }
243     num_new_vertices_ = num_new_verts;
244   }
245 #endif
246 
247   uint32_t num_encoded_vertices;
248 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
249   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
250     if (!decoder_->buffer()->Decode(&num_encoded_vertices))
251       return false;
252 
253   } else
254 #endif
255   {
256     if (!DecodeVarint(&num_encoded_vertices, decoder_->buffer()))
257       return false;
258   }
259   num_encoded_vertices_ = num_encoded_vertices;
260 
261   uint32_t num_faces;
262 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
263   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
264     if (!decoder_->buffer()->Decode(&num_faces))
265       return false;
266 
267   } else
268 #endif
269   {
270     if (!DecodeVarint(&num_faces, decoder_->buffer()))
271       return false;
272   }
273   if (num_faces > std::numeric_limits<CornerIndex::ValueType>::max() / 3)
274     return false;  // Draco cannot handle this many faces.
275 
276   if (static_cast<uint32_t>(num_encoded_vertices_) > num_faces * 3) {
277     return false;  // There cannot be more vertices than 3 * num_faces.
278   }
279   uint8_t num_attribute_data;
280   if (!decoder_->buffer()->Decode(&num_attribute_data))
281     return false;
282 
283   uint32_t num_encoded_symbols;
284 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
285   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
286     if (!decoder_->buffer()->Decode(&num_encoded_symbols))
287       return false;
288 
289   } else
290 #endif
291   {
292     if (!DecodeVarint(&num_encoded_symbols, decoder_->buffer()))
293       return false;
294   }
295 
296   if (num_faces < num_encoded_symbols) {
297     // Number of faces needs to be the same or greater than the number of
298     // symbols (it can be greater because the initial face may not be encoded as
299     // a symbol).
300     return false;
301   }
302   const uint32_t max_encoded_faces =
303       num_encoded_symbols + (num_encoded_symbols / 3);
304   if (num_faces > max_encoded_faces) {
305     // Faces can only be 1 1/3 times bigger than number of encoded symbols. This
306     // could only happen if all new encoded components started with interior
307     // triangles. E.g. A mesh with multiple tetrahedrons.
308     return false;
309   }
310 
311   uint32_t num_encoded_split_symbols;
312 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
313   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
314     if (!decoder_->buffer()->Decode(&num_encoded_split_symbols))
315       return false;
316 
317   } else
318 #endif
319   {
320     if (!DecodeVarint(&num_encoded_split_symbols, decoder_->buffer()))
321       return false;
322   }
323 
324   if (num_encoded_split_symbols > num_encoded_symbols) {
325     return false;  // Split symbols are a sub-set of all symbols.
326   }
327 
328   // Decode topology (connectivity).
329   vertex_traversal_length_.clear();
330   corner_table_ = std::unique_ptr<CornerTable>(new CornerTable());
331   if (corner_table_ == nullptr)
332     return false;
333   processed_corner_ids_.clear();
334   processed_corner_ids_.reserve(num_faces);
335   processed_connectivity_corners_.clear();
336   processed_connectivity_corners_.reserve(num_faces);
337   topology_split_data_.clear();
338   hole_event_data_.clear();
339   init_face_configurations_.clear();
340   init_corners_.clear();
341 
342   last_symbol_id_ = -1;
343   last_face_id_ = -1;
344   last_vert_id_ = -1;
345 
346   attribute_data_.clear();
347   // Add one attribute data for each attribute decoder.
348   attribute_data_.resize(num_attribute_data);
349 
350   if (!corner_table_->Reset(num_faces,
351                             num_encoded_vertices_ + num_encoded_split_symbols))
352     return false;
353 
354   // Start with all vertices marked as holes (boundaries).
355   // Only vertices decoded with TOPOLOGY_C symbol (and the initial face) will
356   // be marked as non hole vertices. We need to allocate the array larger
357   // because split symbols can create extra vertices during the decoding
358   // process (these extra vertices are then eliminated during deduplication).
359   is_vert_hole_.assign(num_encoded_vertices_ + num_encoded_split_symbols, true);
360 
361 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
362   int32_t topology_split_decoded_bytes = -1;
363   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
364     uint32_t encoded_connectivity_size;
365     if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
366       if (!decoder_->buffer()->Decode(&encoded_connectivity_size))
367         return false;
368     } else {
369       if (!DecodeVarint(&encoded_connectivity_size, decoder_->buffer()))
370         return false;
371     }
372     if (encoded_connectivity_size == 0 ||
373         encoded_connectivity_size > decoder_->buffer()->remaining_size())
374       return false;
375     DecoderBuffer event_buffer;
376     event_buffer.Init(
377         decoder_->buffer()->data_head() + encoded_connectivity_size,
378         decoder_->buffer()->remaining_size() - encoded_connectivity_size,
379         decoder_->buffer()->bitstream_version());
380     // Decode hole and topology split events.
381     topology_split_decoded_bytes =
382         DecodeHoleAndTopologySplitEvents(&event_buffer);
383     if (topology_split_decoded_bytes == -1)
384       return false;
385 
386   } else
387 #endif
388   {
389     if (DecodeHoleAndTopologySplitEvents(decoder_->buffer()) == -1)
390       return false;
391   }
392 
393   traversal_decoder_.Init(this);
394   // Add one extra vertex for each split symbol.
395   traversal_decoder_.SetNumEncodedVertices(num_encoded_vertices_ +
396                                            num_encoded_split_symbols);
397   traversal_decoder_.SetNumAttributeData(num_attribute_data);
398 
399   DecoderBuffer traversal_end_buffer;
400   if (!traversal_decoder_.Start(&traversal_end_buffer))
401     return false;
402 
403   const int num_connectivity_verts = DecodeConnectivity(num_encoded_symbols);
404   if (num_connectivity_verts == -1)
405     return false;
406 
407   // Set the main buffer to the end of the traversal.
408   decoder_->buffer()->Init(traversal_end_buffer.data_head(),
409                            traversal_end_buffer.remaining_size(),
410                            decoder_->buffer()->bitstream_version());
411 
412 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
413   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
414     // Skip topology split data that was already decoded earlier.
415     decoder_->buffer()->Advance(topology_split_decoded_bytes);
416   }
417 #endif
418 
419   // Decode connectivity of non-position attributes.
420   if (attribute_data_.size() > 0) {
421 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
422     if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 1)) {
423       for (CornerIndex ci(0); ci < corner_table_->num_corners(); ci += 3) {
424         if (!DecodeAttributeConnectivitiesOnFaceLegacy(ci))
425           return false;
426       }
427 
428     } else
429 #endif
430     {
431       for (CornerIndex ci(0); ci < corner_table_->num_corners(); ci += 3) {
432         if (!DecodeAttributeConnectivitiesOnFace(ci))
433           return false;
434       }
435     }
436   }
437   traversal_decoder_.Done();
438 
439   // Decode attribute connectivity.
440   // Prepare data structure for decoding non-position attribute connectivity.
441   for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
442     attribute_data_[i].connectivity_data.InitEmpty(corner_table_.get());
443     // Add all seams.
444     for (int32_t c : attribute_data_[i].attribute_seam_corners) {
445       attribute_data_[i].connectivity_data.AddSeamEdge(CornerIndex(c));
446     }
447     // Recompute vertices from the newly added seam edges.
448     attribute_data_[i].connectivity_data.RecomputeVertices(nullptr, nullptr);
449   }
450 
451   pos_encoding_data_.Init(corner_table_->num_vertices());
452   for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
453     // For non-position attributes, preallocate the vertex to value mapping
454     // using the maximum number of vertices from the base corner table and the
455     // attribute corner table (since the attribute decoder may use either of
456     // it).
457     int32_t att_connectivity_verts =
458         attribute_data_[i].connectivity_data.num_vertices();
459     if (att_connectivity_verts < corner_table_->num_vertices())
460       att_connectivity_verts = corner_table_->num_vertices();
461     attribute_data_[i].encoding_data.Init(att_connectivity_verts);
462   }
463   if (!AssignPointsToCorners(num_connectivity_verts))
464     return false;
465   return true;
466 }
467 
468 template <class TraversalDecoder>
OnAttributesDecoded()469 bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::OnAttributesDecoded() {
470   return true;
471 }
472 
473 template <class TraversalDecoder>
DecodeConnectivity(int num_symbols)474 int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
475     int num_symbols) {
476   // Algorithm does the reverse decoding of the symbols encoded with the
477   // edgebreaker method. The reverse decoding always keeps track of the active
478   // edge identified by its opposite corner (active corner). New faces are
479   // always added to this active edge. There may be multiple active corners at
480   // one time that either correspond to separate mesh components or to
481   // sub-components of one mesh that are going to be merged together using the
482   // TOPOLOGY_S symbol. We can store these active edges on a stack, because the
483   // decoder always processes only the latest active edge. TOPOLOGY_S then
484   // removes the top edge from the stack and TOPOLOGY_E adds a new edge to the
485   // stack.
486   std::vector<CornerIndex> active_corner_stack;
487 
488   // Additional active edges may be added as a result of topology split events.
489   // They can be added in arbitrary order, but we always know the split symbol
490   // id they belong to, so we can address them using this symbol id.
491   std::unordered_map<int, CornerIndex> topology_split_active_corners;
492 
493   // Vector used for storing vertices that were marked as isolated during the
494   // decoding process. Currently used only when the mesh doesn't contain any
495   // non-position connectivity data.
496   std::vector<VertexIndex> invalid_vertices;
497   const bool remove_invalid_vertices = attribute_data_.empty();
498 
499   int max_num_vertices = static_cast<int>(is_vert_hole_.size());
500   int num_faces = 0;
501   for (int symbol_id = 0; symbol_id < num_symbols; ++symbol_id) {
502     const FaceIndex face(num_faces++);
503     // Used to flag cases where we need to look for topology split events.
504     bool check_topology_split = false;
505     const uint32_t symbol = traversal_decoder_.DecodeSymbol();
506     if (symbol == TOPOLOGY_C) {
507       // Create a new face between two edges on the open boundary.
508       // The first edge is opposite to the corner "a" from the image below.
509       // The other edge is opposite to the corner "b" that can be reached
510       // through a CCW traversal around the vertex "v".
511       // One new active boundary edge is created, opposite to the new corner
512       // "x".
513       //
514       //     *-------*
515       //    / \     / \
516       //   /   \   /   \
517       //  /     \ /     \
518       // *-------v-------*
519       //  \b    /x\    a/
520       //   \   /   \   /
521       //    \ /  C  \ /
522       //     *.......*
523 
524       // Find the corner "b" from the corner "a" which is the corner on the
525       // top of the active stack.
526       if (active_corner_stack.empty())
527         return -1;
528 
529       const CornerIndex corner_a = active_corner_stack.back();
530       const VertexIndex vertex_x =
531           corner_table_->Vertex(corner_table_->Next(corner_a));
532       const CornerIndex corner_b =
533           corner_table_->Next(corner_table_->LeftMostCorner(vertex_x));
534 
535       // New tip corner.
536       const CornerIndex corner(3 * face.value());
537       // Update opposite corner mappings.
538       SetOppositeCorners(corner_a, corner + 1);
539       SetOppositeCorners(corner_b, corner + 2);
540 
541       // Update vertex mapping.
542       corner_table_->MapCornerToVertex(corner, vertex_x);
543       corner_table_->MapCornerToVertex(
544           corner + 1, corner_table_->Vertex(corner_table_->Next(corner_b)));
545       const VertexIndex vert_a_prev =
546           corner_table_->Vertex(corner_table_->Previous(corner_a));
547       corner_table_->MapCornerToVertex(corner + 2, vert_a_prev);
548       corner_table_->SetLeftMostCorner(vert_a_prev, corner + 2);
549       // Mark the vertex |x| as interior.
550       is_vert_hole_[vertex_x.value()] = false;
551       // Update the corner on the active stack.
552       active_corner_stack.back() = corner;
553     } else if (symbol == TOPOLOGY_R || symbol == TOPOLOGY_L) {
554       // Create a new face extending from the open boundary edge opposite to the
555       // corner "a" from the image below. Two new boundary edges are created
556       // opposite to corners "r" and "l". New active corner is set to either "r"
557       // or "l" depending on the decoded symbol. One new vertex is created
558       // at the opposite corner to corner "a".
559       //     *-------*
560       //    /a\     / \
561       //   /   \   /   \
562       //  /     \ /     \
563       // *-------v-------*
564       //  .l   r.
565       //   .   .
566       //    . .
567       //     *
568       if (active_corner_stack.empty())
569         return -1;
570       const CornerIndex corner_a = active_corner_stack.back();
571 
572       // First corner on the new face is either corner "l" or "r".
573       const CornerIndex corner(3 * face.value());
574       CornerIndex opp_corner, corner_l, corner_r;
575       if (symbol == TOPOLOGY_R) {
576         // "r" is the new first corner.
577         opp_corner = corner + 2;
578         corner_l = corner + 1;
579         corner_r = corner;
580       } else {
581         // "l" is the new first corner.
582         opp_corner = corner + 1;
583         corner_l = corner;
584         corner_r = corner + 2;
585       }
586       SetOppositeCorners(opp_corner, corner_a);
587       // Update vertex mapping.
588       const VertexIndex new_vert_index = corner_table_->AddNewVertex();
589 
590       if (corner_table_->num_vertices() > max_num_vertices)
591         return -1;  // Unexpected number of decoded vertices.
592 
593       corner_table_->MapCornerToVertex(opp_corner, new_vert_index);
594       corner_table_->SetLeftMostCorner(new_vert_index, opp_corner);
595 
596       const VertexIndex vertex_r =
597           corner_table_->Vertex(corner_table_->Previous(corner_a));
598       corner_table_->MapCornerToVertex(corner_r, vertex_r);
599       // Update left-most corner on the vertex on the |corner_r|.
600       corner_table_->SetLeftMostCorner(vertex_r, corner_r);
601 
602       corner_table_->MapCornerToVertex(
603           corner_l, corner_table_->Vertex(corner_table_->Next(corner_a)));
604       active_corner_stack.back() = corner;
605       check_topology_split = true;
606     } else if (symbol == TOPOLOGY_S) {
607       // Create a new face that merges two last active edges from the active
608       // stack. No new vertex is created, but two vertices at corners "p" and
609       // "n" need to be merged into a single vertex.
610       //
611       // *-------v-------*
612       //  \a   p/x\n   b/
613       //   \   /   \   /
614       //    \ /  S  \ /
615       //     *.......*
616       //
617       if (active_corner_stack.empty())
618         return -1;
619       const CornerIndex corner_b = active_corner_stack.back();
620       active_corner_stack.pop_back();
621 
622       // Corner "a" can correspond either to a normal active edge, or to an edge
623       // created from the topology split event.
624       const auto it = topology_split_active_corners.find(symbol_id);
625       if (it != topology_split_active_corners.end()) {
626         // Topology split event. Move the retrieved edge to the stack.
627         active_corner_stack.push_back(it->second);
628       }
629       if (active_corner_stack.empty())
630         return -1;
631       const CornerIndex corner_a = active_corner_stack.back();
632 
633       if (corner_table_->Opposite(corner_a) != kInvalidCornerIndex ||
634           corner_table_->Opposite(corner_b) != kInvalidCornerIndex) {
635         // One of the corners is already opposite to an existing face, which
636         // should not happen unless the input was tempered with.
637         return -1;
638       }
639 
640       // First corner on the new face is corner "x" from the image above.
641       const CornerIndex corner(3 * face.value());
642       // Update the opposite corner mapping.
643       SetOppositeCorners(corner_a, corner + 2);
644       SetOppositeCorners(corner_b, corner + 1);
645       // Update vertices. For the vertex at corner "x", use the vertex id from
646       // the corner "p".
647       const VertexIndex vertex_p =
648           corner_table_->Vertex(corner_table_->Previous(corner_a));
649       corner_table_->MapCornerToVertex(corner, vertex_p);
650       corner_table_->MapCornerToVertex(
651           corner + 1, corner_table_->Vertex(corner_table_->Next(corner_a)));
652       const VertexIndex vert_b_prev =
653           corner_table_->Vertex(corner_table_->Previous(corner_b));
654       corner_table_->MapCornerToVertex(corner + 2, vert_b_prev);
655       corner_table_->SetLeftMostCorner(vert_b_prev, corner + 2);
656       CornerIndex corner_n = corner_table_->Next(corner_b);
657       const VertexIndex vertex_n = corner_table_->Vertex(corner_n);
658       traversal_decoder_.MergeVertices(vertex_p, vertex_n);
659       // Update the left most corner on the newly merged vertex.
660       corner_table_->SetLeftMostCorner(vertex_p,
661                                        corner_table_->LeftMostCorner(vertex_n));
662 
663       // Also update the vertex id at corner "n" and all corners that are
664       // connected to it in the CCW direction.
665       while (corner_n != kInvalidCornerIndex) {
666         corner_table_->MapCornerToVertex(corner_n, vertex_p);
667         corner_n = corner_table_->SwingLeft(corner_n);
668       }
669       // Make sure the old vertex n is now mapped to an invalid corner (make it
670       // isolated).
671       corner_table_->MakeVertexIsolated(vertex_n);
672       if (remove_invalid_vertices)
673         invalid_vertices.push_back(vertex_n);
674       active_corner_stack.back() = corner;
675     } else if (symbol == TOPOLOGY_E) {
676       const CornerIndex corner(3 * face.value());
677       const VertexIndex first_vert_index = corner_table_->AddNewVertex();
678       // Create three new vertices at the corners of the new face.
679       corner_table_->MapCornerToVertex(corner, first_vert_index);
680       corner_table_->MapCornerToVertex(corner + 1,
681                                        corner_table_->AddNewVertex());
682       corner_table_->MapCornerToVertex(corner + 2,
683                                        corner_table_->AddNewVertex());
684 
685       if (corner_table_->num_vertices() > max_num_vertices)
686         return -1;  // Unexpected number of decoded vertices.
687 
688       corner_table_->SetLeftMostCorner(first_vert_index, corner);
689       corner_table_->SetLeftMostCorner(first_vert_index + 1, corner + 1);
690       corner_table_->SetLeftMostCorner(first_vert_index + 2, corner + 2);
691       // Add the tip corner to the active stack.
692       active_corner_stack.push_back(corner);
693       check_topology_split = true;
694     } else {
695       // Error. Unknown symbol decoded.
696       return -1;
697     }
698     // Inform the traversal decoder that a new corner has been reached.
699     traversal_decoder_.NewActiveCornerReached(active_corner_stack.back());
700 
701     if (check_topology_split) {
702       // Check for topology splits happens only for TOPOLOGY_L, TOPOLOGY_R and
703       // TOPOLOGY_E symbols because those are the symbols that correspond to
704       // faces that can be directly connected a TOPOLOGY_S face through the
705       // topology split event.
706       // If a topology split is detected, we need to add a new active edge
707       // onto the active_corner_stack because it will be used later when the
708       // corresponding TOPOLOGY_S event is decoded.
709 
710       // Symbol id used by the encoder (reverse).
711       const int encoder_symbol_id = num_symbols - symbol_id - 1;
712       EdgeFaceName split_edge;
713       int encoder_split_symbol_id;
714       while (IsTopologySplit(encoder_symbol_id, &split_edge,
715                              &encoder_split_symbol_id)) {
716         if (encoder_split_symbol_id < 0)
717           return -1;  // Wrong split symbol id.
718         // Symbol was part of a topology split. Now we need to determine which
719         // edge should be added to the active edges stack.
720         const CornerIndex act_top_corner = active_corner_stack.back();
721         // The current symbol has one active edge (stored in act_top_corner) and
722         // two remaining inactive edges that are attached to it.
723         //              *
724         //             / \
725         //  left_edge /   \ right_edge
726         //           /     \
727         //          *.......*
728         //         active_edge
729 
730         CornerIndex new_active_corner;
731         if (split_edge == RIGHT_FACE_EDGE) {
732           new_active_corner = corner_table_->Next(act_top_corner);
733         } else {
734           new_active_corner = corner_table_->Previous(act_top_corner);
735         }
736         // Add the new active edge.
737         // Convert the encoder split symbol id to decoder symbol id.
738         const int decoder_split_symbol_id =
739             num_symbols - encoder_split_symbol_id - 1;
740         topology_split_active_corners[decoder_split_symbol_id] =
741             new_active_corner;
742       }
743     }
744   }
745   if (corner_table_->num_vertices() > max_num_vertices)
746     return -1;  // Unexpected number of decoded vertices.
747   // Decode start faces and connect them to the faces from the active stack.
748   while (active_corner_stack.size() > 0) {
749     const CornerIndex corner = active_corner_stack.back();
750     active_corner_stack.pop_back();
751     const bool interior_face =
752         traversal_decoder_.DecodeStartFaceConfiguration();
753     if (interior_face) {
754       // The start face is interior, we need to find three corners that are
755       // opposite to it. The first opposite corner "a" is the corner from the
756       // top of the active corner stack and the remaining two corners "b" and
757       // "c" are then the next corners from the left-most corners of vertices
758       // "n" and "x" respectively.
759       //
760       //           *-------*
761       //          / \     / \
762       //         /   \   /   \
763       //        /     \ /     \
764       //       *-------p-------*
765       //      / \a    . .    c/ \
766       //     /   \   .   .   /   \
767       //    /     \ .  I  . /     \
768       //   *-------n.......x------*
769       //    \     / \     / \     /
770       //     \   /   \   /   \   /
771       //      \ /     \b/     \ /
772       //       *-------*-------*
773       //
774 
775       if (num_faces >= corner_table_->num_faces()) {
776         return -1;  // More faces than expected added to the mesh.
777       }
778 
779       const CornerIndex corner_a = corner;
780       const VertexIndex vert_n =
781           corner_table_->Vertex(corner_table_->Next(corner_a));
782       const CornerIndex corner_b =
783           corner_table_->Next(corner_table_->LeftMostCorner(vert_n));
784 
785       const VertexIndex vert_x =
786           corner_table_->Vertex(corner_table_->Next(corner_b));
787       const CornerIndex corner_c =
788           corner_table_->Next(corner_table_->LeftMostCorner(vert_x));
789 
790       const VertexIndex vert_p =
791           corner_table_->Vertex(corner_table_->Next(corner_c));
792 
793       const FaceIndex face(num_faces++);
794       // The first corner of the initial face is the corner opposite to "a".
795       const CornerIndex new_corner(3 * face.value());
796       SetOppositeCorners(new_corner, corner);
797       SetOppositeCorners(new_corner + 1, corner_b);
798       SetOppositeCorners(new_corner + 2, corner_c);
799 
800       // Map new corners to existing vertices.
801       corner_table_->MapCornerToVertex(new_corner, vert_x);
802       corner_table_->MapCornerToVertex(new_corner + 1, vert_p);
803       corner_table_->MapCornerToVertex(new_corner + 2, vert_n);
804 
805       // Mark all three vertices as interior.
806       for (int ci = 0; ci < 3; ++ci) {
807         is_vert_hole_[corner_table_->Vertex(new_corner + ci).value()] = false;
808       }
809 
810       init_face_configurations_.push_back(true);
811       init_corners_.push_back(new_corner);
812     } else {
813       // The initial face wasn't interior and the traversal had to start from
814       // an open boundary. In this case no new face is added, but we need to
815       // keep record about the first opposite corner to this boundary.
816       init_face_configurations_.push_back(false);
817       init_corners_.push_back(corner);
818     }
819   }
820   if (num_faces != corner_table_->num_faces())
821     return -1;  // Unexpected number of decoded faces.
822 
823   int num_vertices = corner_table_->num_vertices();
824   // If any vertex was marked as isolated, we want to remove it from the corner
825   // table to ensure that all vertices in range <0, num_vertices> are valid.
826   for (const VertexIndex invalid_vert : invalid_vertices) {
827     // Find the last valid vertex and swap it with the isolated vertex.
828     VertexIndex src_vert(num_vertices - 1);
829     while (corner_table_->LeftMostCorner(src_vert) == kInvalidCornerIndex) {
830       // The last vertex is invalid, proceed to the previous one.
831       src_vert = VertexIndex(--num_vertices - 1);
832     }
833     if (src_vert < invalid_vert)
834       continue;  // No need to swap anything.
835 
836     // Remap all corners mapped to |src_vert| to |invalid_vert|.
837     VertexCornersIterator<CornerTable> vcit(corner_table_.get(), src_vert);
838     for (; !vcit.End(); ++vcit) {
839       const CornerIndex cid = vcit.Corner();
840       corner_table_->MapCornerToVertex(cid, invalid_vert);
841     }
842     corner_table_->SetLeftMostCorner(invalid_vert,
843                                      corner_table_->LeftMostCorner(src_vert));
844 
845     // Make the |src_vert| invalid.
846     corner_table_->MakeVertexIsolated(src_vert);
847     is_vert_hole_[invalid_vert.value()] = is_vert_hole_[src_vert.value()];
848     is_vert_hole_[src_vert.value()] = false;
849 
850     // The last vertex is now invalid.
851     num_vertices--;
852   }
853   return num_vertices;
854 }
855 
856 template <class TraversalDecoder>
857 int32_t
DecodeHoleAndTopologySplitEvents(DecoderBuffer * decoder_buffer)858 MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
859     DecoderBuffer *decoder_buffer) {
860   // Prepare a new decoder from the provided buffer offset.
861   uint32_t num_topology_splits;
862 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
863   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
864     if (!decoder_buffer->Decode(&num_topology_splits))
865       return -1;
866 
867   } else
868 #endif
869   {
870     if (!DecodeVarint(&num_topology_splits, decoder_buffer))
871       return -1;
872   }
873   if (num_topology_splits > 0) {
874     if (num_topology_splits > static_cast<uint32_t>(corner_table_->num_faces()))
875       return -1;
876 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
877     if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(1, 2)) {
878       for (uint32_t i = 0; i < num_topology_splits; ++i) {
879         TopologySplitEventData event_data;
880         if (!decoder_buffer->Decode(&event_data.split_symbol_id))
881           return -1;
882         if (!decoder_buffer->Decode(&event_data.source_symbol_id))
883           return -1;
884         uint8_t edge_data;
885         if (!decoder_buffer->Decode(&edge_data))
886           return -1;
887         event_data.source_edge = edge_data & 1;
888         topology_split_data_.push_back(event_data);
889       }
890 
891     } else
892 #endif
893     {
894       // Decode source and split symbol ids using delta and varint coding. See
895       // description in mesh_edgebreaker_encoder_impl.cc for more details.
896       int last_source_symbol_id = 0;
897       for (uint32_t i = 0; i < num_topology_splits; ++i) {
898         TopologySplitEventData event_data;
899         uint32_t delta;
900         DecodeVarint<uint32_t>(&delta, decoder_buffer);
901         event_data.source_symbol_id = delta + last_source_symbol_id;
902         DecodeVarint<uint32_t>(&delta, decoder_buffer);
903         if (delta > event_data.source_symbol_id)
904           return -1;
905         event_data.split_symbol_id =
906             event_data.source_symbol_id - static_cast<int32_t>(delta);
907         last_source_symbol_id = event_data.source_symbol_id;
908         topology_split_data_.push_back(event_data);
909       }
910       // Split edges are decoded from a direct bit decoder.
911       decoder_buffer->StartBitDecoding(false, nullptr);
912       for (uint32_t i = 0; i < num_topology_splits; ++i) {
913         uint32_t edge_data;
914         if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
915           decoder_buffer->DecodeLeastSignificantBits32(2, &edge_data);
916         } else {
917           decoder_buffer->DecodeLeastSignificantBits32(1, &edge_data);
918         }
919         TopologySplitEventData &event_data = topology_split_data_[i];
920         event_data.source_edge = edge_data & 1;
921       }
922       decoder_buffer->EndBitDecoding();
923     }
924   }
925   uint32_t num_hole_events = 0;
926 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
927   if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
928     if (!decoder_buffer->Decode(&num_hole_events))
929       return -1;
930   } else if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 1)) {
931     if (!DecodeVarint(&num_hole_events, decoder_buffer))
932       return -1;
933   }
934 #endif
935   if (num_hole_events > 0) {
936 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
937     if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(1, 2)) {
938       for (uint32_t i = 0; i < num_hole_events; ++i) {
939         HoleEventData event_data;
940         if (!decoder_buffer->Decode(&event_data))
941           return -1;
942         hole_event_data_.push_back(event_data);
943       }
944 
945     } else
946 #endif
947     {
948       // Decode hole symbol ids using delta and varint coding.
949       int last_symbol_id = 0;
950       for (uint32_t i = 0; i < num_hole_events; ++i) {
951         HoleEventData event_data;
952         uint32_t delta;
953         DecodeVarint<uint32_t>(&delta, decoder_buffer);
954         event_data.symbol_id = delta + last_symbol_id;
955         last_symbol_id = event_data.symbol_id;
956         hole_event_data_.push_back(event_data);
957       }
958     }
959   }
960   return static_cast<int32_t>(decoder_buffer->decoded_size());
961 }
962 
963 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
964 template <class TraversalDecoder>
965 bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::
DecodeAttributeConnectivitiesOnFaceLegacy(CornerIndex corner)966     DecodeAttributeConnectivitiesOnFaceLegacy(CornerIndex corner) {
967   // Three corners of the face.
968   const CornerIndex corners[3] = {corner, corner_table_->Next(corner),
969                                   corner_table_->Previous(corner)};
970 
971   for (int c = 0; c < 3; ++c) {
972     const CornerIndex opp_corner = corner_table_->Opposite(corners[c]);
973     if (opp_corner == kInvalidCornerIndex) {
974       // Don't decode attribute seams on boundary edges (every boundary edge
975       // is automatically an attribute seam).
976       for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
977         attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
978       }
979       continue;
980     }
981 
982     for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
983       const bool is_seam = traversal_decoder_.DecodeAttributeSeam(i);
984       if (is_seam)
985         attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
986     }
987   }
988   return true;
989 }
990 #endif
991 
992 template <class TraversalDecoder>
993 bool MeshEdgebreakerDecoderImpl<
DecodeAttributeConnectivitiesOnFace(CornerIndex corner)994     TraversalDecoder>::DecodeAttributeConnectivitiesOnFace(CornerIndex corner) {
995   // Three corners of the face.
996   const CornerIndex corners[3] = {corner, corner_table_->Next(corner),
997                                   corner_table_->Previous(corner)};
998 
999   const FaceIndex src_face_id = corner_table_->Face(corner);
1000   for (int c = 0; c < 3; ++c) {
1001     const CornerIndex opp_corner = corner_table_->Opposite(corners[c]);
1002     if (opp_corner == kInvalidCornerIndex) {
1003       // Don't decode attribute seams on boundary edges (every boundary edge
1004       // is automatically an attribute seam).
1005       for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
1006         attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
1007       }
1008       continue;
1009     }
1010     const FaceIndex opp_face_id = corner_table_->Face(opp_corner);
1011     // Don't decode edges when the opposite face has been already processed.
1012     if (opp_face_id < src_face_id)
1013       continue;
1014 
1015     for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
1016       const bool is_seam = traversal_decoder_.DecodeAttributeSeam(i);
1017       if (is_seam)
1018         attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
1019     }
1020   }
1021   return true;
1022 }
1023 
1024 template <class TraversalDecoder>
AssignPointsToCorners(int num_connectivity_verts)1025 bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::AssignPointsToCorners(
1026     int num_connectivity_verts) {
1027   // Map between the existing and deduplicated point ids.
1028   // Note that at this point we have one point id for each corner of the
1029   // mesh so there is corner_table_->num_corners() point ids.
1030   decoder_->mesh()->SetNumFaces(corner_table_->num_faces());
1031 
1032   if (attribute_data_.empty()) {
1033     // We have connectivity for position only. In this case all vertex indices
1034     // are equal to point indices.
1035     for (FaceIndex f(0); f < decoder_->mesh()->num_faces(); ++f) {
1036       Mesh::Face face;
1037       const CornerIndex start_corner(3 * f.value());
1038       for (int c = 0; c < 3; ++c) {
1039         // Get the vertex index on the corner and use it as a point index.
1040         const int32_t vert_id = corner_table_->Vertex(start_corner + c).value();
1041         face[c] = vert_id;
1042       }
1043       decoder_->mesh()->SetFace(f, face);
1044     }
1045     decoder_->point_cloud()->set_num_points(num_connectivity_verts);
1046     return true;
1047   }
1048   // Else we need to deduplicate multiple attributes.
1049 
1050   // Map between point id and an associated corner id. Only one corner for
1051   // each point is stored. The corners are used to sample the attribute values
1052   // in the last stage of the deduplication.
1053   std::vector<int32_t> point_to_corner_map;
1054   // Map between every corner and their new point ids.
1055   std::vector<int32_t> corner_to_point_map(corner_table_->num_corners());
1056   for (int v = 0; v < corner_table_->num_vertices(); ++v) {
1057     CornerIndex c = corner_table_->LeftMostCorner(VertexIndex(v));
1058     if (c == kInvalidCornerIndex)
1059       continue;  // Isolated vertex.
1060     CornerIndex deduplication_first_corner = c;
1061     if (is_vert_hole_[v]) {
1062       // If the vertex is on a boundary, start deduplication from the left most
1063       // corner that is guaranteed to lie on the boundary.
1064       deduplication_first_corner = c;
1065     } else {
1066       // If we are not on the boundary we need to find the first seam (of any
1067       // attribute).
1068       for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
1069         if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c))
1070           continue;  // No seam for this attribute, ignore it.
1071         // Else there needs to be at least one seam edge.
1072 
1073         // At this point, we use identity mapping between corners and point ids.
1074         const VertexIndex vert_id =
1075             attribute_data_[i].connectivity_data.Vertex(c);
1076         CornerIndex act_c = corner_table_->SwingRight(c);
1077         bool seam_found = false;
1078         while (act_c != c) {
1079           if (act_c == kInvalidCornerIndex)
1080             return false;
1081           if (attribute_data_[i].connectivity_data.Vertex(act_c) != vert_id) {
1082             // Attribute seam found. Stop.
1083             deduplication_first_corner = act_c;
1084             seam_found = true;
1085             break;
1086           }
1087           act_c = corner_table_->SwingRight(act_c);
1088         }
1089         if (seam_found)
1090           break;  // No reason to process other attributes if we found a seam.
1091       }
1092     }
1093 
1094     // Do a deduplication pass over the corners on the processed vertex.
1095     // At this point each corner corresponds to one point id and our goal is to
1096     // merge similar points into a single point id.
1097     // We do a single pass in a clockwise direction over the corners and we add
1098     // a new point id whenever one of the attributes change.
1099     c = deduplication_first_corner;
1100     // Create a new point.
1101     corner_to_point_map[c.value()] =
1102         static_cast<uint32_t>(point_to_corner_map.size());
1103     point_to_corner_map.push_back(c.value());
1104     // Traverse in CW direction.
1105     CornerIndex prev_c = c;
1106     c = corner_table_->SwingRight(c);
1107     while (c != kInvalidCornerIndex && c != deduplication_first_corner) {
1108       bool attribute_seam = false;
1109       for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
1110         if (attribute_data_[i].connectivity_data.Vertex(c) !=
1111             attribute_data_[i].connectivity_data.Vertex(prev_c)) {
1112           // Attribute index changed from the previous corner. We need to add a
1113           // new point here.
1114           attribute_seam = true;
1115           break;
1116         }
1117       }
1118       if (attribute_seam) {
1119         corner_to_point_map[c.value()] =
1120             static_cast<uint32_t>(point_to_corner_map.size());
1121         point_to_corner_map.push_back(c.value());
1122       } else {
1123         corner_to_point_map[c.value()] = corner_to_point_map[prev_c.value()];
1124       }
1125       prev_c = c;
1126       c = corner_table_->SwingRight(c);
1127     }
1128   }
1129   // Add faces.
1130   for (FaceIndex f(0); f < decoder_->mesh()->num_faces(); ++f) {
1131     Mesh::Face face;
1132     for (int c = 0; c < 3; ++c) {
1133       // Remap old points to the new ones.
1134       face[c] = corner_to_point_map[3 * f.value() + c];
1135     }
1136     decoder_->mesh()->SetFace(f, face);
1137   }
1138   decoder_->point_cloud()->set_num_points(
1139       static_cast<uint32_t>(point_to_corner_map.size()));
1140   return true;
1141 }
1142 
1143 template class MeshEdgebreakerDecoderImpl<MeshEdgebreakerTraversalDecoder>;
1144 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
1145 template class MeshEdgebreakerDecoderImpl<
1146     MeshEdgebreakerTraversalPredictiveDecoder>;
1147 #endif
1148 template class MeshEdgebreakerDecoderImpl<
1149     MeshEdgebreakerTraversalValenceDecoder>;
1150 }  // namespace draco
1151