mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-06-04 11:25:44 +08:00
6.3 KiB
6.3 KiB
EdgeBreaker Traversal
ParseEdgebreakerTraversalStandardData()
void ParseEdgebreakerTraversalStandardData() {
eb_symbol_buffer_size UI64
eb_symbol_buffer size * UI8
eb_start_face_buffer_size UI64
eb_start_face_buffer size * UI8
for (i = 0; i < num_attribute_data; ++i) {
attribute_connectivity_decoders_prob_zero[i] UI8
attribute_connectivity_decoders_size[i] UI32
attribute_connectivity_decoders_buffer[i] size * UI8
}
}
{:.draco-syntax }
DecodeEdgebreakerTraversalData()
void DecodeEdgebreakerTraversalData() {
ParseEdgebreakerTraversalStandardData();
if (edgebreaker_traversal_type == VALENCE_EDGEBREAKER) {
ParseEdgebreakerTraversalValenceData();
}
}
{:.draco-syntax }
EdgebreakerTraversalStart()
void EdgebreakerTraversalStart() {
last_symbol_ = -1;
active_context_ = -1;
DecodeEdgebreakerTraversalData();
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 }