mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-04-22 22:00:15 +08:00
6.8 KiB
6.8 KiB
EdgeBreaker Traversal
ParseEdgebreakerTraversalStandardSymbolData()
void ParseEdgebreakerTraversalStandardSymbolData() {
sz = eb_symbol_buffer_size varUI64
eb_symbol_buffer UI8[sz]
}
{:.draco-syntax }
ParseEdgebreakerTraversalStandardFaceData()
void ParseEdgebreakerTraversalStandardFaceData() {
eb_start_face_buffer_prob_zero UI8
sz = eb_start_face_buffer_size varUI32
eb_start_face_buffer UI8[sz]
}
{:.draco-syntax }
ParseEdgebreakerTraversalStandardAttributeConnectivityData()
void ParseEdgebreakerTraversalStandardAttributeConnectivityData() {
for (i = 0; i < num_attribute_data; ++i) {
attribute_connectivity_decoders_prob_zero[i] UI8
sz = attribute_connectivity_decoders_size[i] varUI32
attribute_connectivity_decoders_buffer[i] UI8[sz]
}
}
{:.draco-syntax }
DecodeEdgebreakerTraversalStandardData()
void DecodeEdgebreakerTraversalStandardData() {
ParseEdgebreakerTraversalStandardSymbolData()
ParseEdgebreakerTraversalStandardFaceData()
ParseEdgebreakerTraversalStandardAttributeConnectivityData()
}
{:.draco-syntax }
EdgebreakerTraversalStart()
void EdgebreakerTraversalStart() {
last_symbol_ = -1;
active_context_ = -1;
if (edgebreaker_traversal_type == STANDARD_EDGEBREAKER) {
DecodeEdgebreakerTraversalStandardData();
} else if (edgebreaker_traversal_type == VALENCE_EDGEBREAKER) {
EdgeBreakerTraversalValenceStart();
}
}
{:.draco-syntax }
IsFaceVisited()
bool IsFaceVisited(face_id) {
if (face_id < 0)
return true; // Invalid faces are always considered as visited.
return is_face_visited_[face_id];
}
{:.draco-syntax }
OnNewVertexVisited()
void OnNewVertexVisited(vertex, corner) {
encoded_attribute_value_index_to_corner_map[curr_att_dec].push_back(corner);
vertex_to_encoded_attribute_value_index_map[curr_att_dec][vertex] =
vertex_visited_point_ids[curr_att_dec];
vertex_visited_point_ids[curr_att_dec]++;
}
{:.draco-syntax }
EdgeBreakerTraverser_ProcessCorner()
void EdgeBreakerTraverser_ProcessCorner(corner_id) {
face = corner_id / 3;
if (IsFaceVisited(face))
return; // Already traversed.
corner_traversal_stack_.push_back(corner_id);
next_vert = face_to_vertex[1][face];
prev_vert = face_to_vertex[2][face];
if (!is_vertex_visited_[next_vert]) {
is_vertex_visited_[next_vert] = true;
next_c = Next(corner_id);
OnNewVertexVisited(next_vert, next_c);
}
if (!is_vertex_visited_[prev_vert]) {
is_vertex_visited_[prev_vert] = true;
prev_c = Previous(corner_id);
OnNewVertexVisited(prev_vert, prev_c);
}
while (!corner_traversal_stack_.empty()) {
corner_id = corner_traversal_stack_.back();
face_id = corner_id / 3;
if (corner_id < 0 || IsFaceVisited(face_id)) {
// This face has been already traversed.
corner_traversal_stack_.pop_back();
continue;
}
while (true) {
face_id = corner_id / 3;
is_face_visited_[face_id] = true;
vert_id = CornerToVert(0, corner_id);
if (!is_vertex_visited_[vert_id]) {
on_boundary = IsOnPositionBoundary(vert_id);
is_vertex_visited_[vert_id] = true;
OnNewVertexVisited(vert_id, corner_id);
if (!on_boundary) {
corner_id = GetRightCorner(corner_id);
continue;
}
}
right_corner_id = GetRightCorner(corner_id);
left_corner_id = GetLeftCorner(corner_id);
right_face_id = right_corner_id < 0 ? -1 : right_corner_id / 3;
left_face_id = left_corner_id < 0 ? -1 : left_corner_id / 3;
if (IsFaceVisited(right_face_id)) {
if (IsFaceVisited(left_face_id)) {
corner_traversal_stack_.pop_back();
break;
} else {
corner_id = left_corner_id;
}
} else {
if (IsFaceVisited(left_face_id)) {
corner_id = right_corner_id;
} else {
corner_traversal_stack_.back() = left_corner_id;
corner_traversal_stack_.push_back(right_corner_id);
break;
}
}
}
}
}
{:.draco-syntax }
EdgeBreakerAttributeTraverser_ProcessCorner()
void EdgeBreakerAttributeTraverser_ProcessCorner(corner_id) {
face = corner_id / 3;
if (IsFaceVisited(face))
return; // Already traversed.
corner_traversal_stack_.push_back(corner_id);
CornerToVerts(curr_att_dec, corner_id, &vert_id, &next_vert, &prev_vert);
if (!is_vertex_visited_[next_vert]) {
is_vertex_visited_[next_vert] = true;
next_c = Next(corner_id);
OnNewVertexVisited(next_vert, next_c);
}
if (!is_vertex_visited_[prev_vert]) {
is_vertex_visited_[prev_vert] = true;
prev_c = Previous(corner_id);
OnNewVertexVisited(prev_vert, prev_c);
}
while (!corner_traversal_stack_.empty()) {
corner_id = corner_traversal_stack_.back();
face_id = corner_id / 3;
if (corner_id < 0 || IsFaceVisited(face_id)) {
corner_traversal_stack_.pop_back();
continue;
}
while (true) {
face_id = corner_id / 3;
is_face_visited_[face_id] = true;
vert_id = CornerToVert(curr_att_dec, corner_id);
if (!is_vertex_visited_[vert_id]) {
on_seam = IsOnBoundary(curr_att_dec, vert_id);
pos_vert_id = CornerToVert(0, corner_id);
on_boundary = (on_seam) ? on_seam : IsOnPositionBoundary(pos_vert_id);
is_vertex_visited_[vert_id] = true;
OnNewVertexVisited(vert_id, corner_id);
if (!on_boundary) {
corner_id = GetRightCorner(corner_id);
continue;
}
}
next_c = Next(corner_id);
right_seam = IsCornerOppositeToSeamEdge(next_c);
right_corner_id = (right_seam) ? -1 : GetRightCorner(corner_id);
prev_c = Previous(corner_id);
left_seam = IsCornerOppositeToSeamEdge(prev_c);
left_corner_id = (left_seam) ? -1 : GetLeftCorner(corner_id);
right_face_id = right_corner_id < 0 ? -1 : right_corner_id / 3;
left_face_id = left_corner_id < 0 ? -1 : left_corner_id / 3;
if (IsFaceVisited(left_face_id)) {
corner_traversal_stack_.pop_back();
break;
} else {
corner_id = left_corner_id;
}
} else {
if (IsFaceVisited(left_face_id)) {
corner_id = right_corner_id;
} else {
corner_traversal_stack_.back() = left_corner_id;
corner_traversal_stack_.push_back(right_corner_id);
break;
}
}
}
}
}
{:.draco-syntax }