1 2## Attributes Decoder 3 4### ParseAttributeDecodersData() 5 6~~~~~ 7void ParseAttributeDecodersData() { 8 num_attributes_decoders UI8 9 if (encoder_method == MESH_EDGEBREAKER_ENCODING) { 10 for (i = 0; i < num_attributes_decoders; ++i) { 11 att_dec_data_id[i] UI8 12 att_dec_decoder_type[i] UI8 13 att_dec_traversal_method[i] UI8 14 } 15 } 16 for (i = 0; i < num_attributes_decoders; ++i) { 17 att_dec_num_attributes[i] varUI32 18 for (j = 0; j < att_dec_num_attributes[i]; ++j) { 19 att_dec_att_type[i][j] UI8 20 att_dec_data_type[i][j] UI8 21 att_dec_num_components[i][j] UI8 22 att_dec_normalized[i][j] UI8 23 att_dec_unique_id[i][j] varUI32 24 } 25 for (j = 0; j < att_dec_num_attributes[i]; ++j) { 26 seq_att_dec_decoder_type[i][j] UI8 27 } 28 } 29} 30~~~~~ 31{:.draco-syntax } 32 33 34### DecodeAttributeData() 35 36~~~~~ 37void DecodeAttributeData() { 38 ParseAttributeDecodersData(); 39 vertex_visited_point_ids.assign(num_attributes_decoders, 0); 40 curr_att_dec = 0; 41 if (encoder_method == MESH_EDGEBREAKER_ENCODING) { 42 DecodeAttributeSeams(); 43 for (i = 0; i < num_encoded_vertices + num_encoded_split_symbols; ++i) { 44 if (is_vert_hole_[i]) { 45 UpdateVertexToCornerMap(i); 46 } 47 } 48 for (i = 1; i < num_attributes_decoders; ++i) { 49 curr_att_dec = i; 50 RecomputeVerticesInternal(); 51 } 52 Attribute_AssignPointsToCorners(); 53 } 54 for (i = 0; i < num_attributes_decoders; ++i) { 55 curr_att_dec = i; 56 is_face_visited_.assign(num_faces, false); 57 is_vertex_visited_.assign(num_faces * 3, false); 58 GenerateSequence(); 59 if (encoder_method == MESH_EDGEBREAKER_ENCODING) { 60 UpdatePointToAttributeIndexMapping(); 61 } 62 } 63 for (i = 0; i < num_attributes_decoders; ++i) { 64 for (j = 0; j < att_dec_num_attributes[i]; ++j) { 65 att_dec_num_values_to_decode[i][j] = 66 encoded_attribute_value_index_to_corner_map[i].size(); 67 } 68 } 69 for (i = 0; i < num_attributes_decoders; ++i) { 70 curr_att_dec = i; 71 DecodePortableAttributes(); 72 DecodeDataNeededByPortableTransforms(); 73 TransformAttributesToOriginalFormat(); 74 } 75} 76~~~~~ 77{:.draco-syntax } 78 79 80### RecomputeVerticesInternal() 81 82~~~~~ 83void RecomputeVerticesInternal() { 84 attr = curr_att_dec - 1; 85 num_new_vertices = 0; 86 attr_face_to_vertex.push_back(face_to_vertex); 87 corner_to_vertex_map_[curr_att_dec].assign( 88 attr_face_to_vertex[attr][0].size() * 3, -1); 89 for (v = 0; v < num_encoded_vertices + num_encoded_split_symbols; ++v) { 90 c = vertex_corners_[v]; 91 if (c < 0) 92 continue; 93 first_vert_id = num_new_vertices++; 94 first_c = c; 95 if (IsVertexOnAttributeSeam(attr, v)) { 96 act_c = SwingLeft(curr_att_dec, first_c); 97 while (act_c >= 0) { 98 first_c = act_c; 99 act_c = SwingLeft(curr_att_dec, act_c); 100 } 101 } 102 corner_to_vertex_map_[curr_att_dec][first_c] = first_vert_id; 103 vertex_to_left_most_corner_map_[attr].push_back(first_c); 104 act_c = SwingRight(0, first_c); 105 while (act_c >= 0 && act_c != first_c) { 106 next_act_c = Next(act_c); 107 if (IsCornerOppositeToSeamEdge(next_act_c)) { 108 first_vert_id = num_new_vertices++; 109 vertex_to_left_most_corner_map_[attr].push_back(act_c); 110 } 111 corner_to_vertex_map_[curr_att_dec][act_c] = first_vert_id; 112 act_c = SwingRight(0, act_c); 113 } 114 } 115 116 for (i = 0; i < corner_to_vertex_map_[curr_att_dec].size(); i += 3) { 117 face = i / 3; 118 attr_face_to_vertex[attr][0][face] = corner_to_vertex_map_[curr_att_dec][i]; 119 attr_face_to_vertex[attr][1][face] = corner_to_vertex_map_[curr_att_dec][i + 1]; 120 attr_face_to_vertex[attr][2][face] = corner_to_vertex_map_[curr_att_dec][i + 2]; 121 } 122} 123~~~~~ 124{:.draco-syntax } 125 126 127### Attribute_AssignPointsToCorners() 128 129~~~~~ 130void Attribute_AssignPointsToCorners() { 131 point_to_corner_map_count = 0; 132 for (v = 0; v < num_encoded_vertices + num_encoded_split_symbols; ++v) { 133 c = vertex_corners_[v]; 134 if (c < 0) 135 continue; 136 deduplication_first_corner = c; 137 if (is_vert_hole_[v]) { 138 deduplication_first_corner = c; 139 } else { 140 for (i = 1; i < num_attributes_decoders; ++i) { 141 attr_id = i - 1; 142 if (!IsCornerOnAttributeSeam(0, attr_id, c)) 143 continue; 144 vert_id = corner_to_vertex_map_[i][c]; 145 act_c = SwingRight(0, c); 146 seam_found = false; 147 while (act_c != c) { 148 act_vert_id = corner_to_vertex_map_[i][act_c]; 149 if (act_vert_id != vert_id) { 150 deduplication_first_corner = act_c; 151 seam_found = true; 152 break; 153 } 154 act_c = SwingRight(0, act_c); 155 } 156 if (seam_found) 157 break; 158 } 159 } 160 161 c = deduplication_first_corner; 162 corner_to_point_map[c] = point_to_corner_map_count++; 163 prev_c = c; 164 c = SwingRight(0, c); 165 while (c >= 0 && c != deduplication_first_corner) { 166 attribute_seam = false; 167 for (i = 1; i < num_attributes_decoders; ++i) { 168 vert_id = corner_to_vertex_map_[i][c]; 169 prev_vert_id = corner_to_vertex_map_[i][prev_c]; 170 if (vert_id != prev_vert_id) { 171 attribute_seam = true; 172 break; 173 } 174 } 175 if (attribute_seam) { 176 corner_to_point_map[c] = point_to_corner_map_count++; 177 } else { 178 corner_to_point_map[c] = corner_to_point_map[prev_c]; 179 } 180 prev_c = c; 181 c = SwingRight(0, c); 182 } 183 } 184} 185~~~~~ 186{:.draco-syntax } 187 188 189### SequentialGenerateSequence() 190 191~~~~~ 192void SequentialGenerateSequence() { 193 for (i = 0; i < num_points; ++i) { 194 encoded_attribute_value_index_to_corner_map[curr_att_dec][i] = i; 195 } 196} 197~~~~~ 198{:.draco-syntax } 199 200 201### EdgebreakerGenerateSequence() 202 203~~~~~ 204void EdgebreakerGenerateSequence() { 205 if (att_dec_traversal_method[curr_att_dec] == MESH_TRAVERSAL_PREDICTION_DEGREE) { 206 prediction_degree_.assign(num_encoded_vertices + num_encoded_split_symbols, 0); 207 } 208 for (i = 0; i < num_faces; ++i) { 209 if (att_dec_traversal_method[curr_att_dec] == MESH_TRAVERSAL_DEPTH_FIRST) { 210 if (curr_att_dec == 0) { 211 EdgeBreakerTraverser_ProcessCorner(3 * i); 212 } else { 213 EdgeBreakerAttributeTraverser_ProcessCorner(3 * i); 214 } 215 } else { 216 PredictionDegree_TraverseFromCorner(3 * i); 217 } 218 } 219} 220~~~~~ 221{:.draco-syntax } 222 223 224### GenerateSequence() 225 226~~~~~ 227void GenerateSequence() { 228 if (encoder_method == MESH_EDGEBREAKER_ENCODING) 229 EdgebreakerGenerateSequence(); 230 else 231 SequentialGenerateSequence(); 232} 233~~~~~ 234{:.draco-syntax } 235 236 237### UpdatePointToAttributeIndexMapping() 238 239~~~~~ 240void UpdatePointToAttributeIndexMapping() { 241 indices_map_.assign(num_faces * 3, -1); 242 for (f = 0; f < num_faces; ++f) { 243 for (p = 0; p < 3; ++p) { 244 corner = (f * 3) + p; 245 point_id = corner_to_point_map[corner]; 246 CornerToVerts(curr_att_dec, corner, &vert, &next, &prev); 247 att_entry_id = 248 vertex_to_encoded_attribute_value_index_map[curr_att_dec][vert]; 249 indices_map_[point_id] = att_entry_id; 250 } 251 } 252} 253~~~~~ 254{:.draco-syntax } 255 256 257### TransformAttributesToOriginalFormat_StoreValues() 258 259~~~~~ 260void TransformAttributesToOriginalFormat_StoreValues() { 261 num_components = GetNumComponents(); 262 num_values = att_dec_num_values_to_decode[curr_att_dec][curr_att]; 263 portable_attribute_data = seq_int_att_dec_original_values[curr_att_dec][curr_att]; 264 for (i = 0; i < num_values; ++i) { 265 for (c = 0; c < num_components; ++c) { 266 out_values.push_back(portable_attribute_data[(i * num_components) + c]); 267 } 268 } 269 seq_int_att_dec_dequantized_values[curr_att_dec][curr_att] = out_values; 270} 271~~~~~ 272{:.draco-syntax } 273 274 275### TransformAttributesToOriginalFormat() 276 277~~~~~ 278void TransformAttributesToOriginalFormat() { 279 for (i = 0; i < att_dec_num_attributes.back(); ++i) { 280 curr_att = i; 281 dec_type = seq_att_dec_decoder_type[curr_att_dec][curr_att]; 282 if (dec_type == SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS) { 283 TransformAttributesToOriginalFormat_Normal(); 284 } else if (dec_type == SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER) { 285 TransformAttributesToOriginalFormat_StoreValues(); 286 } else { 287 SequentialQuantizationAttributeDecoder_DequantizeValues(); 288 } 289 } 290} 291~~~~~ 292{:.draco-syntax } 293