mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-04-22 22:00:15 +08:00
8.6 KiB
8.6 KiB
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 + num_encoded_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 + num_encoded_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 + num_encoded_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 + num_encoded_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 }