diff --git a/network_process/include/connect_by_topo/patch_connectivity.hpp b/network_process/include/connect_by_topo/patch_connectivity.hpp index 6c9e19d..9e29b2c 100644 --- a/network_process/include/connect_by_topo/patch_connectivity.hpp +++ b/network_process/include/connect_by_topo/patch_connectivity.hpp @@ -24,7 +24,7 @@ void compute_patch_edges(const stl_vector_mp &patch_faces, void compute_patches(const stl_vector_mp> &edges_of_face, const stl_vector_mp &patch_edges, const stl_vector_mp &patch_faces, - flat_index_group_t &patches, + flat_index_group &patches, stl_vector_mp &patch_of_face_mapping); /** @@ -41,9 +41,9 @@ void compute_chains(size_t iso_vert_count, size_t patch_count, stl_vector_mp &patch_of_face, stl_vector_mp &patch_edges, - flat_index_group_t &chains, + flat_index_group &chains, stl_vector_mp &chain_representative_headers, - flat_index_group_t &chain_of_patch); + flat_index_group &chain_of_patch); /** * @brief compute shells and connected components of isosurfaces, and build maps: half-patch --> shell, patch --> component @@ -55,9 +55,9 @@ void compute_chains(size_t iso_vert_count, * @note each shell is a list of half-patches, each component is a list of patches */ void compute_shells_and_components(const stl_vector_mp> &half_patch_adj_list, - flat_index_group_t &shells, + flat_index_group &shells, stl_vector_mp &shell_of_half_patch, - flat_index_group_t &components, + flat_index_group &components, stl_vector_mp &component_of_patch); /** @@ -68,4 +68,4 @@ void compute_shells_and_components(const stl_vector_mp> */ void compute_arrangement_cells(uint32_t num_shell, const stl_vector_mp> &shell_links, - flat_index_group_t &arrangement_cells); \ No newline at end of file + flat_index_group &arrangement_cells); \ No newline at end of file diff --git a/network_process/include/connect_by_topo/topology_ray_shooting.hpp b/network_process/include/connect_by_topo/topology_ray_shooting.hpp index 846858a..0f8c997 100644 --- a/network_process/include/connect_by_topo/topology_ray_shooting.hpp +++ b/network_process/include/connect_by_topo/topology_ray_shooting.hpp @@ -15,10 +15,10 @@ void topo_ray_shooting(const scene_bg_mesh_info_t const stl_vector_mp &tetrahedron_arrangements, const stl_vector_mp &iso_verts, const stl_vector_mp &iso_faces, - const flat_index_group_t &patches, + const flat_index_group &patches, const stl_vector_mp &patch_of_face, - const flat_index_group_t &shells, + const flat_index_group &shells, const stl_vector_mp &shell_of_half_patch, - const flat_index_group_t &components, + const flat_index_group &components, const stl_vector_mp &component_of_patch, stl_vector_mp> &shell_links); \ No newline at end of file diff --git a/network_process/include/post_topo/filter_polygon_faces.hpp b/network_process/include/post_topo/filter_polygon_faces.hpp index 2c0c241..91e656f 100644 --- a/network_process/include/post_topo/filter_polygon_faces.hpp +++ b/network_process/include/post_topo/filter_polygon_faces.hpp @@ -4,10 +4,10 @@ // return: active face label dynamic_bitset_mp<> filter_polygon_faces(const stl_vector_mp& faces, - const flat_index_group_t& patches, - const flat_index_group_t& arrangement_cells, + const flat_index_group& patches, + const flat_index_group& arrangement_cells, const stl_vector_mp& shell_of_half_patch, - const flat_index_group_t& shells, + const flat_index_group& shells, const stl_vector_mp& shell_to_cell, const dynamic_bitset_mp<>& active_cell_label, stl_vector_mp& output_polygon_faces, diff --git a/network_process/include/post_topo/patch_propagation.hpp b/network_process/include/post_topo/patch_propagation.hpp index 80bef52..3c91a2c 100644 --- a/network_process/include/post_topo/patch_propagation.hpp +++ b/network_process/include/post_topo/patch_propagation.hpp @@ -6,10 +6,10 @@ void propagate_subface_labels(const baked_blobtree_t& tree, const stl_vector_mp& faces, - const flat_index_group_t& patches, - const flat_index_group_t& arrangement_cells, + const flat_index_group& patches, + const flat_index_group& arrangement_cells, const stl_vector_mp& shell_of_half_patch, - const flat_index_group_t& shells, + const flat_index_group& shells, const stl_vector_mp& shell_to_cell, // in turn: [subface_index][cell_index] = sign stl_vector_mp>& cell_subface_signs); diff --git a/network_process/interface/fwd_types.hpp b/network_process/interface/fwd_types.hpp index c9c3f81..9639bca 100644 --- a/network_process/interface/fwd_types.hpp +++ b/network_process/interface/fwd_types.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -264,39 +265,4 @@ struct equal_to> { return static_cast>(k1) == static_cast>(k2); } }; -} // namespace std - -// ============================================================================== - -struct flat_index_group_t { - stl_vector_mp index_group{}; /// a list of indices in the group - stl_vector_mp 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; } - - template - 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]); - } - } - } - - template - 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]); - } - } - - template - 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]); - } - } -}; \ No newline at end of file +} // namespace std \ No newline at end of file diff --git a/network_process/interface/process.hpp b/network_process/interface/process.hpp index 5efbbd3..cd54347 100644 --- a/network_process/interface/process.hpp +++ b/network_process/interface/process.hpp @@ -4,6 +4,15 @@ #include "settings.h" +// each active subface should have one structure as below +struct parametric_plane { + stl_vector_mp chain_vertices{}; + flat_index_group chains{}; + stl_vector_mp singularity_vertices{}; // i.e. intersection of chains + stl_vector_mp polar_vertices{}; // i.e. min/max x/y around 2 connecting vertices + stl_vector_mp parallel_start_vertices{}; // i.e. edge {v, v + 1} is parallel to x/y axis +}; + ISNP_API void build_implicit_network_by_blobtree(const s_settings& settings, const baked_blobtree_t& tree, stl_vector_mp& output_vertices, diff --git a/network_process/src/connect_by_topo/patch_connectivity.cpp b/network_process/src/connect_by_topo/patch_connectivity.cpp index bbf1d52..8b5bb2c 100644 --- a/network_process/src/connect_by_topo/patch_connectivity.cpp +++ b/network_process/src/connect_by_topo/patch_connectivity.cpp @@ -44,7 +44,7 @@ void compute_patch_edges(const stl_vector_mp& patch_faces, void compute_patches(const stl_vector_mp>& edges_of_face, const stl_vector_mp& patch_edges, const stl_vector_mp& patch_faces, - flat_index_group_t& patches, + flat_index_group& patches, stl_vector_mp& patch_of_face_mapping) { stl_vector_mp visited_face(edges_of_face.size(), false); @@ -84,9 +84,9 @@ void compute_chains(size_t iso_vert_count, size_t patch_count, stl_vector_mp& patch_of_face, stl_vector_mp& patch_edges, - flat_index_group_t& chains, + flat_index_group& chains, stl_vector_mp& chain_representative_headers, - flat_index_group_t& chain_of_patch) + flat_index_group& chain_of_patch) { stl_vector_mp> non_manifold_edges_of_vert{}; stl_vector_mp non_manifold_edges{}; @@ -209,9 +209,9 @@ void compute_chains(size_t iso_vert_count, } void compute_shells_and_components(const stl_vector_mp>& half_patch_adj_list, - flat_index_group_t& shells, + flat_index_group& shells, stl_vector_mp& shell_of_half_patch, - flat_index_group_t& components, + flat_index_group& components, stl_vector_mp& component_of_patch) { const auto num_patch = half_patch_adj_list.size() / 2; @@ -298,7 +298,7 @@ void compute_shells_and_components(const stl_vector_mp>& void compute_arrangement_cells(uint32_t num_shell, const stl_vector_mp>& shell_links, - flat_index_group_t& arrangement_cells) + flat_index_group& arrangement_cells) { // build shell adjacency list uint32_t sink_shell = num_shell; @@ -343,7 +343,7 @@ void compute_arrangement_cells(uint32_t } // remove sink shell from arrangement cells - flat_index_group_t sink_free_cells{}; + flat_index_group sink_free_cells{}; sink_free_cells.index_group.reserve(arrangement_cells.index_group.size()); sink_free_cells.start_indices.reserve(arrangement_cells.size() + 1); sink_free_cells.start_indices.emplace_back(0); diff --git a/network_process/src/connect_by_topo/topo_ray_shooting/find_extermal_edges.hpp b/network_process/src/connect_by_topo/topo_ray_shooting/find_extermal_edges.hpp index f8e4aa3..8541c70 100644 --- a/network_process/src/connect_by_topo/topo_ray_shooting/find_extermal_edges.hpp +++ b/network_process/src/connect_by_topo/topo_ray_shooting/find_extermal_edges.hpp @@ -7,8 +7,8 @@ static inline void find_extremal_edges( const scene_bg_mesh_info_t &scene_bg_mesh_info, const stl_vector_mp &iso_verts, const stl_vector_mp &iso_faces, - const flat_index_group_t &patches, - const flat_index_group_t &components, + const flat_index_group &patches, + const flat_index_group &components, const stl_vector_mp &component_of_patch, const flat_hash_map_mp &next_vert, // extremal edge of component i is stored at position [2*i], [2*i+1] diff --git a/network_process/src/connect_by_topo/topology_ray_shooting.cpp b/network_process/src/connect_by_topo/topology_ray_shooting.cpp index f402995..d9eb0ee 100644 --- a/network_process/src/connect_by_topo/topology_ray_shooting.cpp +++ b/network_process/src/connect_by_topo/topology_ray_shooting.cpp @@ -10,11 +10,11 @@ void topo_ray_shooting(const scene_bg_mesh_info_t const stl_vector_mp &tetrahedron_arrangements, const stl_vector_mp &iso_verts, const stl_vector_mp &iso_faces, - const flat_index_group_t &patches, + const flat_index_group &patches, const stl_vector_mp &patch_of_face, - const flat_index_group_t &shells, + const flat_index_group &shells, const stl_vector_mp &shell_of_half_patch, - const flat_index_group_t &components, + const flat_index_group &components, const stl_vector_mp &component_of_patch, stl_vector_mp> &shell_links) { diff --git a/network_process/src/post_topo/filter_polygon_faces.cpp b/network_process/src/post_topo/filter_polygon_faces.cpp index ca28a30..af9ec15 100644 --- a/network_process/src/post_topo/filter_polygon_faces.cpp +++ b/network_process/src/post_topo/filter_polygon_faces.cpp @@ -4,15 +4,58 @@ // =========================================================================================================== +void collect_active_prims(const flat_index_group& patches, + const flat_index_group& chain_of_patch, + const flat_index_group& arrangement_cells, + const stl_vector_mp& shell_of_half_patch, + const flat_index_group& shells, + const stl_vector_mp& shell_to_cell, + const dynamic_bitset_mp<>& active_cell_label, + dynamic_bitset_mp<>& active_patch_label, + dynamic_bitset_mp<>& patch_sign_label, + dynamic_bitset_mp<>& active_chain_label) +{ + stl_vector_mp visited_cells(arrangement_cells.size(), false); + std::queue Q{}; + for (uint32_t i = 0; i < arrangement_cells.size(); ++i) { + if (active_cell_label[i]) { + Q.emplace(i); + break; + } + } + while (!Q.empty()) { + const auto cell_index = Q.front(); + Q.pop(); + if (!visited_cells[cell_index] && active_cell_label[cell_index]) { + visited_cells[cell_index] = true; + arrangement_cells.loop_on_group(cell_index, [&](uint32_t _, uint32_t shell_index) { + // it is secured that one shell cell cannot have a pair of half patches with same patch index + shells.loop_on_group(shell_index, [&](uint32_t _, uint32_t half_patch_index) { + const auto patch_index = half_patch_index >> 1; + active_patch_label[patch_index].flip(); + patch_sign_label[patch_index] = ((half_patch_index & 1) == 0); + + chain_of_patch.loop_on_group(patch_index, [&](uint32_t _, uint32_t chain_index) { + active_chain_label[chain_index].set(); + }); + + auto oppose_cell = shell_to_cell[shell_of_half_patch[(half_patch_index & 1) == 1 ? (half_patch_index + 1) + : (half_patch_index - 1)]]; + if (active_cell_label[oppose_cell] && !visited_cells[oppose_cell]) Q.emplace(oppose_cell); + }); + }); + } + } +} // =========================================================================================================== dynamic_bitset_mp<> filter_polygon_faces(const stl_vector_mp& faces, - const flat_index_group_t& patches, - const flat_index_group_t& arrangement_cells, + const flat_index_group& patches, + const flat_index_group& arrangement_cells, const stl_vector_mp& shell_of_half_patch, - const flat_index_group_t& shells, + const flat_index_group& shells, const stl_vector_mp& shell_to_cell, const dynamic_bitset_mp<>& active_cell_label, stl_vector_mp& output_polygon_faces, diff --git a/network_process/src/post_topo/patch_propagation.cpp b/network_process/src/post_topo/patch_propagation.cpp index 8cd21c0..4698a07 100644 --- a/network_process/src/post_topo/patch_propagation.cpp +++ b/network_process/src/post_topo/patch_propagation.cpp @@ -5,10 +5,10 @@ void propagate_subface_labels(const baked_blobtree_t& tree, const stl_vector_mp& faces, - const flat_index_group_t& patches, - const flat_index_group_t& arrangement_cells, + const flat_index_group& patches, + const flat_index_group& arrangement_cells, const stl_vector_mp& shell_of_half_patch, - const flat_index_group_t& shells, + const flat_index_group& shells, const stl_vector_mp& shell_to_cell, stl_vector_mp>& cell_subface_signs) { diff --git a/network_process/src/process.cpp b/network_process/src/process.cpp index 03190ae..69420b3 100644 --- a/network_process/src/process.cpp +++ b/network_process/src/process.cpp @@ -71,13 +71,13 @@ ISNP_API void build_implicit_network_by_blobtree(const s_settings& stl_vector_mp patch_of_face(iso_faces.size()); stl_vector_mp shell_of_half_patch{}; stl_vector_mp component_of_patch{}; - flat_index_group_t patches{}; - flat_index_group_t chains{}; - flat_index_group_t shells{}; - flat_index_group_t components{}; - flat_index_group_t arrangement_cells{}; + flat_index_group patches{}; + flat_index_group chains{}; + flat_index_group shells{}; + flat_index_group components{}; + flat_index_group arrangement_cells{}; stl_vector_mp shell_to_cell{}; - flat_index_group_t chain_of_patch{}; + flat_index_group chain_of_patch{}; { stl_vector_mp chain_representative_headers{}; { @@ -160,6 +160,9 @@ ISNP_API void build_implicit_network_by_blobtree(const s_settings& } active_cell_label = filter_cells_by_boolean(tree, cell_primitive_signs); } + dynamic_bitset_mp<> active_patch_label(patches.size(), false); + dynamic_bitset_mp<> patch_sign_label(patches.size(), false); + filter_polygon_faces(iso_faces, patches, arrangement_cells, diff --git a/primitive_process/interface/base/primitive.hpp b/primitive_process/interface/base/primitive.hpp index b0cf6e1..0df5a56 100644 --- a/primitive_process/interface/base/primitive.hpp +++ b/primitive_process/interface/base/primitive.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff --git a/shared_module/container/wrapper/flat_index_group.hpp b/shared_module/container/wrapper/flat_index_group.hpp new file mode 100644 index 0000000..f9494d2 --- /dev/null +++ b/shared_module/container/wrapper/flat_index_group.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "../stl_alias.hpp" + +struct flat_index_group { + stl_vector_mp index_group{}; /// a list of indices in the group + stl_vector_mp 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 + 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 + 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 + 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]); + } + } +}; \ No newline at end of file