mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-04-23 06:09:57 +08:00
295 lines
8.6 KiB
Markdown
295 lines
8.6 KiB
Markdown
|
|
## Attributes Decoder
|
|
|
|
### ParseAttributeDecodersData()
|
|
|
|
~~~~~
|
|
void ParseAttributeDecodersData() {
|
|
num_attributes_decoders UI8
|
|
if (encoder_method == MESH_EDGEBREAKER_ENCODING) {
|
|
for (i = 0; i < num_attributes_decoders; ++i) {
|
|
att_dec_data_id[i] UI8
|
|
att_dec_decoder_type[i] UI8
|
|
att_dec_traversal_method[i] UI8
|
|
}
|
|
}
|
|
for (i = 0; i < num_attributes_decoders; ++i) {
|
|
att_dec_num_attributes[i] varUI32
|
|
for (j = 0; j < att_dec_num_attributes[i]; ++j) {
|
|
att_dec_att_type[i][j] UI8
|
|
att_dec_data_type[i][j] UI8
|
|
att_dec_num_components[i][j] UI8
|
|
att_dec_normalized[i][j] UI8
|
|
att_dec_unique_id[i][j] varUI32
|
|
}
|
|
for (j = 0; j < att_dec_num_attributes[i]; ++j) {
|
|
seq_att_dec_decoder_type[i][j] UI8
|
|
}
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### DecodeAttributeData()
|
|
|
|
~~~~~
|
|
void DecodeAttributeData() {
|
|
ParseAttributeDecodersData();
|
|
vertex_visited_point_ids.assign(num_attributes_decoders, 0);
|
|
curr_att_dec = 0;
|
|
if (encoder_method == MESH_EDGEBREAKER_ENCODING) {
|
|
DecodeAttributeSeams();
|
|
for (i = 0; i < num_encoded_vertices + eb_num_split_symbols; ++i) {
|
|
if (is_vert_hole_[i]) {
|
|
UpdateVertexToCornerMap(i);
|
|
}
|
|
}
|
|
for (i = 1; i < num_attributes_decoders; ++i) {
|
|
curr_att_dec = i;
|
|
RecomputeVerticesInternal();
|
|
}
|
|
Attribute_AssignPointsToCorners();
|
|
}
|
|
for (i = 0; i < num_attributes_decoders; ++i) {
|
|
curr_att_dec = i;
|
|
is_face_visited_.assign(num_faces, false);
|
|
is_vertex_visited_.assign(num_faces * 3, false);
|
|
GenerateSequence();
|
|
if (encoder_method == MESH_EDGEBREAKER_ENCODING) {
|
|
UpdatePointToAttributeIndexMapping();
|
|
}
|
|
}
|
|
for (i = 0; i < num_attributes_decoders; ++i) {
|
|
for (j = 0; j < att_dec_num_attributes[i]; ++j) {
|
|
att_dec_num_values_to_decode[i][j] =
|
|
encoded_attribute_value_index_to_corner_map[i].size();
|
|
}
|
|
}
|
|
for (i = 0; i < num_attributes_decoders; ++i) {
|
|
curr_att_dec = i;
|
|
DecodePortableAttributes();
|
|
DecodeDataNeededByPortableTransforms();
|
|
TransformAttributesToOriginalFormat();
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### RecomputeVerticesInternal()
|
|
|
|
~~~~~
|
|
void RecomputeVerticesInternal() {
|
|
attr = curr_att_dec - 1;
|
|
num_new_vertices = 0;
|
|
attr_face_to_vertex.push_back(face_to_vertex);
|
|
corner_to_vertex_map_[curr_att_dec].assign(
|
|
attr_face_to_vertex[attr][0].size() * 3, -1);
|
|
for (v = 0; v < num_encoded_vertices + eb_num_split_symbols; ++v) {
|
|
c = vertex_corners_[v];
|
|
if (c < 0)
|
|
continue;
|
|
first_vert_id(num_new_vertices++);
|
|
first_c = c;
|
|
if (IsVertexOnAttributeSeam(attr, v)) {
|
|
act_c = SwingLeft(curr_att_dec, first_c);
|
|
while (act_c >= 0) {
|
|
first_c = act_c;
|
|
act_c = SwingLeft(curr_att_dec, act_c);
|
|
}
|
|
}
|
|
corner_to_vertex_map_[curr_att_dec][first_c] = first_vert_id;
|
|
vertex_to_left_most_corner_map_[attr].push_back(first_c);
|
|
act_c = SwingRight(0, first_c);
|
|
while (act_c >= 0 && act_c != first_c) {
|
|
next_act_c = Next(act_c);
|
|
if (IsCornerOppositeToSeamEdge(next_act_c)) {
|
|
first_vert_id = num_new_vertices++;
|
|
vertex_to_left_most_corner_map_[attr].push_back(act_c);
|
|
}
|
|
corner_to_vertex_map_[curr_att_dec][act_c] = first_vert_id;
|
|
act_c = SwingRight(0, act_c);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < corner_to_vertex_map_[curr_att_dec].size(); i += 3) {
|
|
face = i / 3;
|
|
attr_face_to_vertex[attr][0][face] = corner_to_vertex_map_[curr_att_dec][i];
|
|
attr_face_to_vertex[attr][1][face] = corner_to_vertex_map_[curr_att_dec][i + 1];
|
|
attr_face_to_vertex[attr][2][face] = corner_to_vertex_map_[curr_att_dec][i + 2];
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### Attribute_AssignPointsToCorners()
|
|
|
|
~~~~~
|
|
void Attribute_AssignPointsToCorners() {
|
|
num_corners = face_to_vertex[0].size() * 3;
|
|
for (v = 0; v < num_encoded_vertices + eb_num_split_symbols; ++v) {
|
|
c = vertex_corners_[v];
|
|
if (c < 0)
|
|
continue;
|
|
deduplication_first_corner = c;
|
|
if (is_vert_hole_[v]) {
|
|
deduplication_first_corner = c;
|
|
} else {
|
|
for (i = 1; i < num_attributes_decoders; ++i) {
|
|
attr_id = i - 1;
|
|
if (!IsCornerOnAttributeSeam(0, attr_id, c))
|
|
continue;
|
|
vert_id = corner_to_vertex_map_[i][c];
|
|
act_c = SwingRight(0, c);
|
|
seam_found = false;
|
|
while (act_c != c) {
|
|
act_vert_id = corner_to_vertex_map_[i][act_c];
|
|
if (act_vert_id != vert_id) {
|
|
deduplication_first_corner = act_c;
|
|
seam_found = true;
|
|
break;
|
|
}
|
|
act_c = SwingRight(0, act_c);
|
|
}
|
|
if (seam_found)
|
|
break;
|
|
}
|
|
}
|
|
|
|
c = deduplication_first_corner;
|
|
corner_to_point_map[c] = point_to_corner_map.size();
|
|
point_to_corner_map.push_back(c);
|
|
prev_c = c;
|
|
c = SwingRight(0, c);
|
|
while (c >= 0 && c != deduplication_first_corner) {
|
|
attribute_seam = false;
|
|
for (i = 1; i < num_attributes_decoders; ++i) {
|
|
vert_id = corner_to_vertex_map_[i][c];
|
|
prev_vert_id = corner_to_vertex_map_[i][prev_c];
|
|
if (vert_id != prev_vert_id) {
|
|
attribute_seam = true;
|
|
break;
|
|
}
|
|
}
|
|
if (attribute_seam) {
|
|
corner_to_point_map[c] = point_to_corner_map.size();
|
|
point_to_corner_map.push_back(c);
|
|
} else {
|
|
corner_to_point_map[c] = corner_to_point_map[prev_c];
|
|
}
|
|
prev_c = c;
|
|
c = SwingRight(0, c);
|
|
}
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### SequentialGenerateSequence()
|
|
|
|
~~~~~
|
|
void SequentialGenerateSequence() {
|
|
for (i = 0; i < num_points; ++i) {
|
|
encoded_attribute_value_index_to_corner_map[curr_att_dec][i] = i;
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### EdgebreakerGenerateSequence()
|
|
|
|
~~~~~
|
|
void EdgebreakerGenerateSequence() {
|
|
if (att_dec_traversal_method[curr_att_dec] == MESH_TRAVERSAL_PREDICTION_DEGREE) {
|
|
prediction_degree_.assign(num_encoded_vertices + eb_num_split_symbols, 0);
|
|
}
|
|
for (i = 0; i < num_faces; ++i) {
|
|
if (att_dec_traversal_method[curr_att_dec] == MESH_TRAVERSAL_DEPTH_FIRST) {
|
|
if (curr_att_dec == 0) {
|
|
EdgeBreakerTraverser_ProcessCorner(3 * i);
|
|
} else {
|
|
EdgeBreakerAttributeTraverser_ProcessCorner(3 * i);
|
|
}
|
|
} else {
|
|
PredictionDegree_TraverseFromCorner(3 * i);
|
|
}
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### GenerateSequence()
|
|
|
|
~~~~~
|
|
void GenerateSequence() {
|
|
if (encoder_method == MESH_EDGEBREAKER_ENCODING)
|
|
EdgebreakerGenerateSequence();
|
|
else
|
|
SequentialGenerateSequence();
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### UpdatePointToAttributeIndexMapping()
|
|
|
|
~~~~~
|
|
void UpdatePointToAttributeIndexMapping() {
|
|
indices_map_.assign(num_faces * 3, -1);
|
|
for (f = 0; f < num_faces; ++f) {
|
|
for (p = 0; p < 3; ++p) {
|
|
corner = (f * 3) + p;
|
|
point_id = corner_to_point_map[corner];
|
|
CornerToVerts(curr_att_dec, corner, &vert, &next, &prev);
|
|
att_entry_id =
|
|
vertex_to_encoded_attribute_value_index_map[curr_att_dec][vert];
|
|
indices_map_[point_id] = att_entry_id;
|
|
}
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### TransformAttributesToOriginalFormat_StoreValues()
|
|
|
|
~~~~~
|
|
void TransformAttributesToOriginalFormat_StoreValues() {
|
|
num_components = GetNumComponents();
|
|
num_values = att_dec_num_values_to_decode[curr_att_dec][curr_att];
|
|
portable_attribute_data = seq_int_att_dec_original_values[curr_att_dec][curr_att];
|
|
for (i = 0; i < num_values; ++i) {
|
|
for (c = 0; c < num_components; ++c) {
|
|
out_values.push_back(portable_attribute_data[(i * num_components) + c]);
|
|
}
|
|
}
|
|
seq_int_att_dec_dequantized_values[curr_att_dec][curr_att] = out_values;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### TransformAttributesToOriginalFormat()
|
|
|
|
~~~~~
|
|
void TransformAttributesToOriginalFormat() {
|
|
for (i = 0; i < att_dec_num_attributes.back(); ++i) {
|
|
curr_att = i;
|
|
dec_type = seq_att_dec_decoder_type[curr_att_dec][curr_att];
|
|
if (dec_type == SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS) {
|
|
TransformAttributesToOriginalFormat_Normal();
|
|
} else if (dec_type == SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER) {
|
|
TransformAttributesToOriginalFormat_StoreValues();
|
|
} else {
|
|
SequentialQuantizationAttributeDecoder_DequantizeValues();
|
|
}
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|