20 changed files with 451 additions and 75 deletions
@ -1,4 +1,5 @@ |
|||
#pragma once |
|||
|
|||
#include <post_topo/patch_propagation.hpp> |
|||
#include <post_topo/filter_polygon_faces.hpp> |
|||
#include <post_topo/filter_polygon_faces.hpp> |
|||
#include <post_topo/chain_post_processing.hpp> |
@ -0,0 +1,29 @@ |
|||
#pragma once |
|||
|
|||
#include <fwd_types.hpp> |
|||
|
|||
struct baked_blobtree_t; |
|||
struct parameteric_plane_t; |
|||
|
|||
// return: active chain label
|
|||
dynamic_bitset_mp<> filter_chains(const stl_vector_mp<polygon_face_t>& faces, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches, |
|||
const dynamic_bitset_mp<>& active_patch_label, |
|||
size_t chain_size, |
|||
flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>>& chain_of_patch); |
|||
// return: is chain end vertices signular
|
|||
dynamic_bitset_mp<> identify_chain_signular(const stl_vector_mp<polygon_face_t>& faces, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& chains, |
|||
const flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>>& chain_of_patch, |
|||
size_t chain_size); |
|||
void identify_chain_near_parallel(flat_hash_map_mp<uint32_t, parameteric_plane_t>& parameteric_planes); |
|||
void map_chain_to_parameteric_plane(const baked_blobtree_t& tree, |
|||
const stl_vector_mp<Eigen::Vector3d>& vertices, |
|||
const stl_vector_mp<polygon_face_t>& faces, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& chains, |
|||
const flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>>& chain_of_patch, |
|||
const flat_hash_map_mp<uint32_t, uint32_t>& vertex_old_index_to_unique_index, |
|||
const dynamic_bitset_mp<>& chain_end_vertex_signular_flag, |
|||
flat_hash_map_mp<uint32_t, parameteric_plane_t>& parameteric_planes); |
@ -0,0 +1,43 @@ |
|||
#include <post_topo.hpp> |
|||
|
|||
dynamic_bitset_mp<> filter_chains(const stl_vector_mp<polygon_face_t>& faces, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches, |
|||
const dynamic_bitset_mp<>& active_patch_label, |
|||
size_t chain_size, |
|||
flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>>& chain_of_patch) |
|||
{ |
|||
flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>> filtered_chain_of_patch{}; |
|||
flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>> active_prim_of_chain{}; |
|||
for (uint32_t i = 0; i < chain_of_patch.size(); ++i) { |
|||
if (active_patch_label[i]) { |
|||
auto& cIds_of_patch = filtered_chain_of_patch[i]; |
|||
cIds_of_patch = std::move(chain_of_patch.at(i)); |
|||
for (auto chain_index : cIds_of_patch) { active_prim_of_chain[chain_index].emplace_back(i); } |
|||
} |
|||
} |
|||
|
|||
dynamic_bitset_mp<> active_chain_label(chain_size); |
|||
for (auto& [chain_index, patch_indices] : active_prim_of_chain) { |
|||
auto label = active_chain_label[chain_index]; |
|||
if (patch_indices.size() > 2) label = true; |
|||
// transform patch index to subface index
|
|||
for (auto& patch_index : patch_indices) patch_index = faces[patches[patch_index][0]].subface_index; |
|||
std::sort(patch_indices.begin(), patch_indices.end()); |
|||
auto iter = std::unique(patch_indices.begin(), patch_indices.end()); |
|||
// turn it off iff only one subface is incident
|
|||
if (std::distance(patch_indices.begin(), iter) <= 1) label = false; |
|||
} |
|||
|
|||
stl_vector_mp<uint32_t> temp_filtered_chain_indices{}; |
|||
chain_of_patch.clear(); |
|||
for (auto& [patch_index, chain_indices] : filtered_chain_of_patch) { |
|||
temp_filtered_chain_indices.clear(); |
|||
for (auto chain_index : chain_indices) { |
|||
if (active_chain_label[chain_index]) temp_filtered_chain_indices.emplace_back(chain_index); |
|||
} |
|||
temp_filtered_chain_indices.shrink_to_fit(); |
|||
if (!temp_filtered_chain_indices.empty()) chain_of_patch[patch_index] = std::move(temp_filtered_chain_indices); |
|||
} |
|||
|
|||
return active_chain_label; |
|||
} |
@ -0,0 +1,77 @@ |
|||
#include <process.hpp> |
|||
#include <post_topo.hpp> |
|||
|
|||
dynamic_bitset_mp<> identify_chain_signular(const stl_vector_mp<polygon_face_t>& faces, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& chains, |
|||
const flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>>& chain_of_patch, |
|||
size_t chain_size) |
|||
{ |
|||
dynamic_bitset_mp<> chain_end_vertex_signular_flag(chain_size * 2); |
|||
|
|||
flat_hash_map_mp<uint32_t, flat_hash_set_mp<uint32_t>> vertex_subface_indices{}; |
|||
flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>> start_vertex_to_chain_indices{}; |
|||
flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>> end_vertex_to_chain_indices{}; |
|||
for (const auto& [patch_index, chain_indices] : chain_of_patch) { |
|||
const auto subface_index = faces[patches[patch_index][0]].subface_index; |
|||
for (const auto& face_index : patches[patch_index]) { |
|||
const auto& face = faces[face_index]; |
|||
for (const auto& vertex_index : face.vertex_indices) { |
|||
for (const auto& chain_index : chain_indices) { |
|||
const auto start_vertex = chains[chain_index].front(); |
|||
const auto end_vertex = chains[chain_index].back(); |
|||
if (vertex_index == start_vertex) { |
|||
vertex_subface_indices[vertex_index].emplace(subface_index); |
|||
start_vertex_to_chain_indices[vertex_index].emplace_back(chain_index); |
|||
break; |
|||
} else if (vertex_index == end_vertex) { |
|||
vertex_subface_indices[vertex_index].emplace(subface_index); |
|||
end_vertex_to_chain_indices[vertex_index].emplace_back(chain_index); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
for (const auto& [vertex_index, subface_set] : vertex_subface_indices) { |
|||
if (subface_set.size() >= 3) { |
|||
if (auto iter = start_vertex_to_chain_indices.find(vertex_index); iter != start_vertex_to_chain_indices.end()) { |
|||
for (const auto& chain_index : iter->second) chain_end_vertex_signular_flag[chain_index * 2] = true; |
|||
} |
|||
if (auto iter = end_vertex_to_chain_indices.find(vertex_index); iter != end_vertex_to_chain_indices.end()) { |
|||
for (const auto& chain_index : iter->second) chain_end_vertex_signular_flag[chain_index * 2 + 1] = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return chain_end_vertex_signular_flag; |
|||
} |
|||
|
|||
void identify_chain_near_parallel(flat_hash_map_mp<uint32_t, parameteric_plane_t>& parameteric_planes) |
|||
{ |
|||
for (auto& [_, parameteric_plane] : parameteric_planes) { |
|||
parameteric_plane.edge_near_parallel_flags.reserve(parameteric_plane.chain_vertices.size()); |
|||
for (size_t i = 0; i < parameteric_plane.chain_vertices.size(); ++i) { |
|||
const auto& vertices = parameteric_plane.chain_vertices[i]; |
|||
auto& vertex_flags = parameteric_plane.vertex_special_flags[i]; |
|||
auto& edge_flags = parameteric_plane.edge_near_parallel_flags.emplace_back(); |
|||
edge_flags.resize(vertices.size() - 1); |
|||
|
|||
// identify edge near parallel first
|
|||
for (auto iter = vertices.begin(); iter != vertices.end() - 1; ++iter) { |
|||
if (std::abs(iter->x() - (iter + 1)->x()) <= epsilon || //
|
|||
std::abs(iter->y() - (iter + 1)->y()) <= epsilon) |
|||
edge_flags[std::distance(vertices.begin(), iter)] = true; |
|||
} |
|||
|
|||
// then identify polar vertex
|
|||
if (vertices.size() >= 3) { |
|||
for (auto iter = vertices.begin() + 1; iter != vertices.end() - 1; ++iter) { |
|||
auto vec1 = *iter - *(iter - 1); |
|||
auto vec2 = *(iter + 1) - *iter; |
|||
if (vec1.dot(vec2) < 0) vertex_flags[std::distance(vertices.begin(), iter)] = true; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,53 @@ |
|||
#include <process.hpp> |
|||
#include <post_topo.hpp> |
|||
|
|||
void map_chain_to_parameteric_plane(const baked_blobtree_t& tree, |
|||
const stl_vector_mp<Eigen::Vector3d>& vertices, |
|||
const stl_vector_mp<polygon_face_t>& faces, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches, |
|||
const stl_vector_mp<stl_vector_mp<uint32_t>>& chains, |
|||
const flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>>& chain_of_patch, |
|||
const flat_hash_map_mp<uint32_t, uint32_t>& vertex_old_index_to_unique_index, |
|||
const dynamic_bitset_mp<>& chain_end_vertex_signular_flag, |
|||
flat_hash_map_mp<uint32_t, parameteric_plane_t>& parameteric_planes) |
|||
{ |
|||
flat_hash_map_mp<uint32_t, stl_vector_mp<uint32_t>> patch_of_subface{}; |
|||
for (const auto& [patch_index, _] : chain_of_patch) { |
|||
const auto& subface_index = faces[patches[patch_index][0]].subface_index; |
|||
patch_of_subface[subface_index].emplace_back(patch_index); |
|||
} |
|||
|
|||
const auto& subfaces = tree.subfaces; |
|||
for (const auto& [subface_index, patch_indices] : patch_of_subface) { |
|||
const auto& subface = *subfaces[subface_index].object_ptr; |
|||
auto mapping_func = subface.fetch_param_mapping_evaluator(); |
|||
auto& parameteric_plane = parameteric_planes[subface_index]; |
|||
auto& chain_vertices = parameteric_plane.chain_vertices; |
|||
auto& chain_group_start_indices = parameteric_plane.chain_group_start_indices; |
|||
auto& chain_vertex_flags = parameteric_plane.vertex_special_flags; |
|||
chain_group_start_indices.reserve(patch_indices.size()); |
|||
chain_group_start_indices.emplace_back(0); |
|||
|
|||
for (const auto& patch_index : patch_indices) { |
|||
const auto& chain_indices = chain_of_patch.at(patch_index); |
|||
chain_group_start_indices.emplace_back(chain_indices.size() + chain_group_start_indices.back()); |
|||
chain_vertices.reserve(chain_vertices.size() + chain_indices.size()); |
|||
chain_vertex_flags.reserve(chain_vertex_flags.size() + chain_indices.size()); |
|||
for (const auto& chain_index : chain_indices) { |
|||
const auto& chain = chains[chain_index]; |
|||
|
|||
auto& chain_vertices_ = chain_vertices.emplace_back(); |
|||
chain_vertices_.resize(chain.size()); |
|||
std::transform(chain.begin(), chain.end(), chain_vertices_.begin(), [&](uint32_t vertex_index) { |
|||
auto mapped_vertex_index = vertex_old_index_to_unique_index.at(vertex_index); |
|||
return mapping_func(vertices[mapped_vertex_index]); |
|||
}); |
|||
|
|||
auto& chain_vertex_flags_ = chain_vertex_flags.emplace_back(); |
|||
chain_vertex_flags_.resize(chain.size()); |
|||
chain_vertex_flags_[0] = chain_end_vertex_signular_flag[2 * chain_index]; |
|||
chain_vertex_flags_[chain.size() - 1] = chain_end_vertex_signular_flag[2 * chain_index + 1]; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,39 @@ |
|||
#pragma once |
|||
|
|||
#include "../stl_alias.hpp" |
|||
|
|||
struct flat_index_group { |
|||
stl_vector_mp<uint32_t> index_group{}; /// a list of indices in the group
|
|||
stl_vector_mp<uint32_t> start_indices{}; /// a list of start indices for each group in the flat index group
|
|||
|
|||
inline size_t size() const { return start_indices.size() - 1; } |
|||
|
|||
// f(group_index, element_index_in_group, elemenet)
|
|||
template <typename F> |
|||
inline void foreach (F&& f) const |
|||
{ |
|||
for (uint32_t group_idx = 0; group_idx < size(); ++group_idx) { |
|||
for (uint32_t elem_idx = 0; elem_idx < start_indices[group_idx + 1] - start_indices[group_idx]; ++elem_idx) { |
|||
f(group_idx, elem_idx, index_group[start_indices[group_idx] + elem_idx]); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// f(group_index, group_start_index, group_end_index)
|
|||
template <typename F> |
|||
inline void group_foreach(F&& f) const |
|||
{ |
|||
for (uint32_t group_idx = 0; group_idx < size(); ++group_idx) { |
|||
f(group_idx, start_indices[group_idx], start_indices[group_idx + 1]); |
|||
} |
|||
} |
|||
|
|||
// f(element_index_in_group, element)
|
|||
template <typename F> |
|||
inline void loop_on_group(uint32_t group_idx, F&& f) const |
|||
{ |
|||
for (uint32_t elem_idx = 0; elem_idx < start_indices[group_idx + 1] - start_indices[group_idx]; ++elem_idx) { |
|||
f(elem_idx, index_group[start_indices[group_idx] + elem_idx]); |
|||
} |
|||
} |
|||
}; |
Loading…
Reference in new issue