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

mesh_edgebreaker_traversal_encoder.h « mesh « compression « draco « src « draco « draco « extern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 08cb66e4cdc98a274d05ef71d5ed2d5098d9eb04 (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
// 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_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_ENCODER_H_
#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_ENCODER_H_

#include "draco/compression/bit_coders/rans_bit_encoder.h"
#include "draco/compression/mesh/mesh_edgebreaker_encoder.h"
#include "draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h"
#include "draco/core/macros.h"

namespace draco {

typedef RAnsBitEncoder BinaryEncoder;

// Default implementation of the edgebreaker traversal encoder. Face
// configurations are stored directly into the output buffer and the symbols
// are first collected and then encoded in the reverse order to make the
// decoding faster.
class MeshEdgebreakerTraversalEncoder {
 public:
  MeshEdgebreakerTraversalEncoder()
      : encoder_impl_(nullptr),
        attribute_connectivity_encoders_(nullptr),
        num_attribute_data_(0) {}
  bool Init(MeshEdgebreakerEncoderImplInterface *encoder) {
    encoder_impl_ = encoder;
    return true;
  }

  // Set the number of non-position attribute data for which we need to encode
  // the connectivity.
  void SetNumAttributeData(int num_data) { num_attribute_data_ = num_data; }

  // Called before the traversal encoding is started.
  void Start() {
    start_face_encoder_.StartEncoding();
    if (num_attribute_data_ > 0) {
      // Init and start arithmetic encoders for storing configuration types
      // of non-position attributes.
      attribute_connectivity_encoders_ = std::unique_ptr<BinaryEncoder[]>(
          new BinaryEncoder[num_attribute_data_]);
      for (int i = 0; i < num_attribute_data_; ++i) {
        attribute_connectivity_encoders_[i].StartEncoding();
      }
    }
  }

  // Called when a traversal starts from a new initial face.
  inline void EncodeStartFaceConfiguration(bool interior) {
    start_face_encoder_.EncodeBit(interior);
  }

  // Called when a new corner is reached during the traversal. No-op for the
  // default encoder.
  inline void NewCornerReached(CornerIndex /* corner */) {}

  // Called whenever a new symbol is reached during the edgebreaker traversal.
  inline void EncodeSymbol(EdgebreakerTopologyBitPattern symbol) {
    // Store the symbol. It will be encoded after all symbols are processed.
    symbols_.push_back(symbol);
  }

  // Called for every pair of connected and visited faces. |is_seam| specifies
  // whether there is an attribute seam between the two faces.

  inline void EncodeAttributeSeam(int attribute, bool is_seam) {
    attribute_connectivity_encoders_[attribute].EncodeBit(is_seam ? 1 : 0);
  }

  // Called when the traversal is finished.
  void Done() {
    EncodeTraversalSymbols();
    EncodeStartFaces();
    EncodeAttributeSeams();
  }

  // Returns the number of encoded symbols.
  int NumEncodedSymbols() const { return static_cast<int>(symbols_.size()); }

  const EncoderBuffer &buffer() const { return traversal_buffer_; }

 protected:
  void EncodeTraversalSymbols() {
    // Bit encode the collected symbols.
    // Allocate enough storage for the bit encoder.
    // It's guaranteed that each face will need only up to 3 bits.
    traversal_buffer_.StartBitEncoding(
        encoder_impl_->GetEncoder()->mesh()->num_faces() * 3, true);
    for (int i = static_cast<int>(symbols_.size() - 1); i >= 0; --i) {
      traversal_buffer_.EncodeLeastSignificantBits32(
          edge_breaker_topology_bit_pattern_length[symbols_[i]], symbols_[i]);
    }
    traversal_buffer_.EndBitEncoding();
  }

  void EncodeStartFaces() {
    start_face_encoder_.EndEncoding(&traversal_buffer_);
  }

  void EncodeAttributeSeams() {
    if (attribute_connectivity_encoders_ != nullptr) {
      for (int i = 0; i < num_attribute_data_; ++i) {
        attribute_connectivity_encoders_[i].EndEncoding(&traversal_buffer_);
      }
    }
  }

  EncoderBuffer *GetOutputBuffer() { return &traversal_buffer_; }
  const MeshEdgebreakerEncoderImplInterface *encoder_impl() const {
    return encoder_impl_;
  }

 private:
  BinaryEncoder start_face_encoder_;
  EncoderBuffer traversal_buffer_;
  const MeshEdgebreakerEncoderImplInterface *encoder_impl_;
  // Symbols collected during the traversal.
  std::vector<EdgebreakerTopologyBitPattern> symbols_;
  // Arithmetic encoder for encoding attribute seams.
  // One context for each non-position attribute.
  std::unique_ptr<BinaryEncoder[]> attribute_connectivity_encoders_;
  int num_attribute_data_;
};

}  // namespace draco

#endif  // DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_ENCODER_H_