|
|
@ -81,9 +81,12 @@ void compute_patches(const stl_vector_mp<stl_vector_mp<uint32_t>>& edges_of_face |
|
|
|
} |
|
|
|
|
|
|
|
void compute_chains(size_t iso_vert_count, |
|
|
|
size_t patch_count, |
|
|
|
stl_vector_mp<uint32_t>& patch_of_face, |
|
|
|
stl_vector_mp<iso_edge_t>& patch_edges, |
|
|
|
flat_index_group_t& chains, |
|
|
|
stl_vector_mp<iso_edge_t>& chain_representative_headers) |
|
|
|
stl_vector_mp<iso_edge_t>& chain_representative_headers, |
|
|
|
flat_index_group_t& chain_of_patch) |
|
|
|
{ |
|
|
|
stl_vector_mp<stl_vector_mp<uint32_t>> non_manifold_edges_of_vert{}; |
|
|
|
stl_vector_mp<uint32_t> non_manifold_edges{}; |
|
|
@ -108,8 +111,9 @@ void compute_chains(size_t iso_vert_count, |
|
|
|
// 1. each chain can start from arbitary vertex of a non-manifold edge, and end at visited edge (i.e. a ring is built) or
|
|
|
|
// singular vertex;
|
|
|
|
// 2. along each chain, the neighboring patch does not change, otherwise a new chain is raised.
|
|
|
|
stl_vector_mp<bool> visited_edge(patch_edges.size(), false); |
|
|
|
std::list<uint32_t> chain_edges{}; |
|
|
|
stl_vector_mp<bool> visited_edge(patch_edges.size(), false); |
|
|
|
std::list<uint32_t> chain_edges{}; |
|
|
|
stl_vector_mp<stl_vector_mp<uint32_t>> split_chain_of_patch(patch_count); |
|
|
|
chains.index_group.reserve(non_manifold_edges.size() * 2); |
|
|
|
chains.start_indices.reserve(8); |
|
|
|
chain_representative_headers.reserve(8); |
|
|
@ -118,17 +122,21 @@ void compute_chains(size_t iso_vert_count, |
|
|
|
// unvisited non-manifold iso-edge (not a boundary edge)
|
|
|
|
// new chain
|
|
|
|
chains.start_indices.emplace_back(static_cast<uint32_t>(chains.index_group.size())); |
|
|
|
auto& edge = patch_edges[i]; |
|
|
|
auto chain_index = static_cast<uint32_t>(chains.size()); |
|
|
|
auto& edge = patch_edges[i]; |
|
|
|
chain_edges.clear(); |
|
|
|
std::queue<uint32_t> Q{}; |
|
|
|
Q.emplace(i); |
|
|
|
chain_edges.emplace_back(edge.v1); |
|
|
|
chain_edges.emplace_back(edge.v2); |
|
|
|
chain_representative_headers.emplace_back(edge); |
|
|
|
visited_edge[i] = true; |
|
|
|
chain_edges.clear(); |
|
|
|
while (!Q.empty()) { |
|
|
|
const auto eId = Q.front(); |
|
|
|
Q.pop(); |
|
|
|
for (const auto& header : patch_edges[eId].headers) { |
|
|
|
split_chain_of_patch[patch_of_face[header.face_index]].emplace_back(chain_index); |
|
|
|
} |
|
|
|
// v1
|
|
|
|
auto v = patch_edges[eId].v1; |
|
|
|
if (non_manifold_edges_of_vert[v].size() == 2) { |
|
|
@ -185,6 +193,19 @@ void compute_chains(size_t iso_vert_count, |
|
|
|
chains.start_indices.emplace_back(static_cast<uint32_t>(chains.index_group.size())); |
|
|
|
chains.start_indices.shrink_to_fit(); |
|
|
|
chains.index_group.shrink_to_fit(); |
|
|
|
|
|
|
|
{ |
|
|
|
size_t chain_patch_count{}; |
|
|
|
for (const auto& chain_patches : split_chain_of_patch) { chain_patch_count += chain_patches.size(); } |
|
|
|
chain_of_patch.index_group.reserve(chain_patch_count); |
|
|
|
chain_of_patch.start_indices.reserve(split_chain_of_patch.size() + 1); |
|
|
|
for (const auto& chain_patches : split_chain_of_patch) { |
|
|
|
chain_of_patch.start_indices.emplace_back(static_cast<uint32_t>(chain_of_patch.index_group.size())); |
|
|
|
chain_of_patch.index_group.insert(chain_of_patch.index_group.end(), |
|
|
|
std::make_move_iterator(chain_patches.begin()), |
|
|
|
std::make_move_iterator(chain_patches.end())); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void compute_shells_and_components(const stl_vector_mp<stl_vector_mp<uint32_t>>& half_patch_adj_list, |
|
|
|