draco/docs/_site/spec/edgebreaker.decoder.html
Lou Quillio c2fb47ac5d Split syntax table sections into files.
Also add .gitignore
2017-07-10 14:36:26 -07:00

351 lines
12 KiB
HTML

<h2 id="edgebreaker-decoder">EdgeBreaker Decoder</h2>
<h3 id="initializedecoder">InitializeDecoder()</h3>
<div class="syntax">
InitializeDecoder() { <b>Type</b>
<b>edgebreaker_decoder_type</b> UI8
}
</div>
<h3 id="decodeconnectivity">DecodeConnectivity()</h3>
<div class="syntax">
DecodeConnectivity() { <b>Type</b>
<b>num_new_verts</b> UI32
<b>num_encoded_vertices</b> UI32
<b>num_faces</b> UI32
<b>num_attribute_data</b> I8
<b>num_encoded_symbols</b> UI32
<b>num_encoded_split_symbols</b> UI32
<b>encoded_connectivity_size</b> UI32
// file pointer must be set to current position + encoded_connectivity_size
hole_and_split_bytes = DecodeHoleAndTopologySplitEvents()
// file pointer must be set to old current position
EdgeBreakerTraversalValence_Start()
DecodeConnectivity(num_symbols)
if (attribute_data_.size() &gt; 0) {
for (ci = 0; ci &lt; corner_table_-&gt;num_corners(); ci += 3) {
DecodeAttributeConnectivitiesOnFace(ci)
}
}
for (i = 0; i &lt; corner_table_-&gt;num_vertices(); ++i) {
if (is_vert_hole_[i]) {
corner_table_-&gt;UpdateVertexToCornerMap(i);
}
}
// Decode attribute connectivity.
for (uint32_t i = 0; i &lt; attribute_data_.size(); ++i) {
attribute_data_[i].connectivity_data.InitEmpty(corner_table_.get());
for (int32_t c : attribute_data_[i].attribute_seam_corners) {
attribute_data_[i].connectivity_data.AddSeamEdge(c);
}
attribute_data_[i].connectivity_data.RecomputeVertices(nullptr, nullptr);
}
// Preallocate vertex to value mapping
AssignPointsToCorners()
}
</div>
<h3 id="assignpointstocorners">AssignPointsToCorners()</h3>
<div class="syntax">
AssignPointsToCorners() { <b>Type</b>
decoder_-&gt;mesh()-&gt;SetNumFaces(corner_table_-&gt;num_faces());
if (attribute_data_.size() == 0) {
for (f = 0; f &lt; decoder_-&gt;mesh()-&gt;num_faces(); ++f) {
for (c = 0; c &lt; 3; ++c) {
vert_id = corner_table_-&gt;Vertex(3 * f + c);
if (point_id == -1)
point_id = num_points++;
face[c] = point_id;
}
decoder_-&gt;mesh()-&gt;SetFace(f, face);
}
decoder_-&gt;point_cloud()-&gt;set_num_points(num_points);
Return true;
}
for (v = 0; v &lt; corner_table_-&gt;num_vertices(); ++v) {
c = corner_table_-&gt;LeftMostCorner(v);
if (c &lt; 0)
continue;
deduplication_first_corner = c;
if (!is_vert_hole_[v]) {
for (uint32_t i = 0; i &lt; attribute_data_.size(); ++i) {
if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c))
continue;
vert_id = attribute_data_[i].connectivity_data.Vertex(c);
act_c = corner_table_-&gt;SwingRight(c);
seam_found = false;
while (act_c != c) {
if (attribute_data_[i].connectivity_data.Vertex(act_c) != vert_id) {
deduplication_first_corner = act_c;
seam_found = true;
break;
}
act_c = corner_table_-&gt;SwingRight(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 = corner_table_-&gt;SwingRight(c);
while (c &gt;= 0 &amp;&amp; c != deduplication_first_corner) {
attribute_seam = false;
for (uint32_t i = 0; i &lt; attribute_data_.size(); ++i) {
if (attribute_data_[i].connectivity_data.Vertex(c) !=
attribute_data_[i].connectivity_data.Vertex(prev_c)) {
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 = corner_table_-&gt;SwingRight(c);
}
}
for (f = 0; f &lt; decoder_-&gt;mesh()-&gt;num_faces(); ++f) {
for (c = 0; c &lt; 3; ++c) {
face[c] = corner_to_point_map[3 * f + c];
}
decoder_-&gt;mesh()-&gt;SetFace(f, face);
}
decoder_-&gt;point_cloud()-&gt;set_num_points(point_to_corner_map.size());
}
</div>
<h3 id="decodeconnectivity-1">DecodeConnectivity()</h3>
<div class="syntax">
DecodeConnectivity(num_symbols) { <b>Type</b>
for (i = 0; i &lt; num_symbols; ++i) {
symbol = TraversalValence_DecodeSymbol()
corner = 3 * num_faces++
if (symbol == TOPOLOGY_C) {
vertex_x = UpdateCornerTableForSymbolC()
is_vert_hole_[vertex_x] = false;
} else if (symbol == TOPOLOGY_R || symbol == TOPOLOGY_L) {
UpdateCornerTableForSymbolLR()
check_topology_split = true;
} else if (symbol == TOPOLOGY_S) {
HandleSymbolS()
} else if (symbol == TOPOLOGY_E) {
UpdateCornerTableForSymbolE()
check_topology_split = true;
}
active_corner_stack.back() = corner;
traversal_decoder_.NewActiveCornerReached(corner);
if (check_topology_split) {
encoder_symbol_id = num_symbols - symbol_id - 1;
while (true) {
split = IsTopologySplit(encoder_symbol_id, &amp;split_edge,
&amp;encoder_split_symbol_id);
if (!split) {
break;
}
act_top_corner = corner;
if (split_edge == RIGHT_FACE_EDGE) {
new_active_corner = corner_table_-&gt;Next(act_top_corner);
} else {
new_active_corner = corner_table_-&gt;Previous(act_top_corner);
}
decoder_split_symbol_id = num_symbols - encoder_split_symbol_id - 1;
topology_split_active_corners[decoder_split_symbol_id] =
new_active_corner;
}
}
}
while (active_corner_stack.size() &gt; 0) {
corner = active_corner_stack.pop_back();
interior_face = traversal_decoder_.DecodeStartFaceConfiguration();
if (interior_face == true) {
UpdateCornerTableForInteriorFace()
for (ci = 0; ci &lt; 3; ++ci) {
is_vert_hole_[corner_table_-&gt;Vertex(new_corner + ci)] = false;
}
init_face_configurations_.push_back(true);
init_corners_.push_back(new_corner);
} else {
init_face_configurations_.push_back(false);
init_corners_.push_back(corner);
}
}
Return num_vertices;
}
</div>
<h3 id="updatecornertableforsymbolc">UpdateCornerTableForSymbolC()</h3>
<div class="syntax">
UpdateCornerTableForSymbolC(corner) { <b>Type</b>
corner_a = active_corner_stack.back();
corner_b = corner_table_-&gt;Previous(corner_a);
while (corner_table_-&gt;Opposite(corner_b) &gt;= 0) {
corner_b = corner_table_-&gt;Previous(corner_table_-&gt;Opposite(corner_b));
}
SetOppositeCorners(corner_a, corner + 1);
SetOppositeCorners(corner_b, corner + 2);
vertex_x = corner_table_-&gt;Vertex(corner_table_-&gt;Next(corner_a));
corner_table_-&gt;MapCornerToVertex(corner, vertex_x);
corner_table_-&gt;MapCornerToVertex(
corner + 1, corner_table_-&gt;Vertex(corner_table_-&gt;Next(corner_b)));
corner_table_-&gt;MapCornerToVertex(
corner + 2, corner_table_-&gt;Vertex(corner_table_-&gt;Previous(corner_a)));
return vertex_x;
}
</div>
<h3 id="updatecornertableforsymbollr">UpdateCornerTableForSymbolLR()</h3>
<div class="syntax">
UpdateCornerTableForSymbolLR(corner, symbol) { <b>Type</b>
if (symbol == TOPOLOGY_R) {
opp_corner = corner + 2;
} else {
opp_corner = corner + 1;
}
SetOppositeCorners(opp_corner, corner_a);
corner_table_-&gt;MapCornerToVertex(opp_corner,num_vertices++);
corner_table_-&gt;MapCornerToVertex(
corner_table_-&gt;Next(opp_corner),
corner_table_-&gt;Vertex(corner_table_-&gt;Previous(corner_a)));
corner_table_-&gt;MapCornerToVertex(
corner_table_-&gt;Previous(opp_corner),
corner_table_-&gt;Vertex(corner_table_-&gt;Next(corner_a)));
}
</div>
<h3 id="handlesymbols">HandleSymbolS()</h3>
<div class="syntax">
HandleSymbolS(corner) { <b>Type</b>
corner_b = active_corner_stack.pop_back();
it = topology_split_active_corners.find(symbol_id);
if (it != topology_split_active_corners.end()) {
active_corner_stack.push_back(it-&gt;second);
}
corner_a = active_corner_stack.back();
SetOppositeCorners(corner_a, corner + 2);
SetOppositeCorners(corner_b, corner + 1);
vertex_p = corner_table_-&gt;Vertex(corner_table_-&gt;Previous(corner_a));
corner_table_-&gt;MapCornerToVertex(corner, vertex_p);
corner_table_-&gt;MapCornerToVertex(
corner + 1, corner_table_-&gt;Vertex(corner_table_-&gt;Next(corner_a)));
corner_table_-&gt;MapCornerToVertex(corner + 2,
corner_table_-&gt;Vertex(corner_table_-&gt;Previous(corner_b)));
corner_n = corner_table_-&gt;Next(corner_b);
vertex_n = corner_table_-&gt;Vertex(corner_n);
traversal_decoder_.MergeVertices(vertex_p, vertex_n);
// TraversalValence_MergeVertices
while (corner_n &gt;= 0) {
corner_table_-&gt;MapCornerToVertex(corner_n, vertex_p);
corner_n = corner_table_-&gt;SwingLeft(corner_n);
}
corner_table_-&gt;MakeVertexIsolated(vertex_n);
}
</div>
<h3 id="updatecornertableforsymbole">UpdateCornerTableForSymbolE()</h3>
<div class="syntax">
UpdateCornerTableForSymbolE() { <b>Type</b>
corner_table_-&gt;MapCornerToVertex(corner, num_vertices++);
corner_table_-&gt;MapCornerToVertex(corner + 1, num_vertices++);
corner_table_-&gt;MapCornerToVertex(corner + 2, num_vertices++);
}
</div>
<h3 id="updatecornertableforinteriorface">UpdateCornerTableForInteriorFace()</h3>
<div class="syntax">
UpdateCornerTableForInteriorFace() { <b>Type</b>
corner_b = corner_table_-&gt;Previous(corner);
while (corner_table_-&gt;Opposite(corner_b) &gt;= 0) {
corner_b = corner_table_-&gt;Previous(corner_table_-&gt;Opposite(corner_b));
}
corner_c = corner_table_-&gt;Next(corner);
while (corner_table_-&gt;Opposite(corner_c) &gt;= 0) {
corner_c = corner_table_-&gt;Next(corner_table_-&gt;Opposite(corner_c));
}
face(num_faces++);
corner_table_-&gt;MapCornerToVertex(
new_corner, corner_table_-&gt;Vertex(corner_table_-&gt;Next(corner_b)));
corner_table_-&gt;MapCornerToVertex(
new_corner + 1, corner_table_-&gt;Vertex(corner_table_-&gt;Next(corner_c)));
corner_table_-&gt;MapCornerToVertex(
new_corner + 2, corner_table_-&gt;Vertex(corner_table_-&gt;Next(corner)));
}
</div>
<h3 id="istopologysplit">IsTopologySplit()</h3>
<div class="syntax">
IsTopologySplit(encoder_symbol_id, *out_face_edge, <b>Type</b>
*out_encoder_split_symbol_id) {
if (topology_split_data_.size() == 0)
return false;
if (topology_split_data_.back().source_symbol_id != encoder_symbol_id)
return false;
*out_face_edge = topology_split_data_.back().source_edge;
*out_encoder_split_symbol_id =
topology_split_data_.back().split_symbol_id;
topology_split_data_.pop_back();
return true;
}
</div>
<h3 id="decodeattributeconnectivitiesonface">DecodeAttributeConnectivitiesOnFace()</h3>
<div class="syntax">
DecodeAttributeConnectivitiesOnFace(corner) { <b>Type</b>
corners[3] = {corner, corner_table_-&gt;Next(corner),
corner_table_-&gt;Previous(corner)}
for (c = 0; c &lt; 3; ++c) {
opp_corner = corner_table_-&gt;Opposite(corners[c]);
if (opp_corner &lt; 0) {
for (uint32_t i = 0; i &lt; attribute_data_.size(); ++i) {
attribute_data_[i].attribute_seam_corners.push_back(corners[c]);
}
continue
}
for (uint32_t i = 0; i &lt; attribute_data_.size(); ++i) {
bool is_seam = traversal_decoder_.DecodeAttributeSeam(i);
if (is_seam) {
attribute_data_[i].attribute_seam_corners.push_back(corners[c]);
}
}
}
}
</div>
<h3 id="setoppositecorners">SetOppositeCorners()</h3>
<div class="syntax">
SetOppositeCorners(corner_0, corner_1) { <b>Type</b>
corner_table_-&gt;SetOppositeCorner(corner_0, corner_1);
corner_table_-&gt;SetOppositeCorner(corner_1, corner_0);
}
</div>