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