| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								#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 stl_vector_mp<boundary_edge_header_t>&               chain_edge_headers,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								                                    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;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								    stl_vector_mp<uint32_t>              unique_chain_indices{};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								    flat_hash_map_mp<uint32_t, uint32_t> old_chain_index_to_unique_index{};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								    auto                                 unique_end_iter = unique_chain_indices.begin();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								    for (const auto& [subface_index, patch_indices] : patch_of_subface) {
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								        const auto& subface                     = subfaces[subface_index].object_ptr.get();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        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_indices         = parameteric_plane.chain_group_indices;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        auto&       chain_vertex_flags          = parameteric_plane.vertex_special_flags;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        auto&       chain_other_subface_indices = parameteric_plane.chain_other_subface_indices;
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								        chain_group_indices.reserve(patch_indices.size());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								        unique_chain_indices.clear();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        old_chain_index_to_unique_index.clear();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        for (const auto& patch_index : patch_indices) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            const auto& chain_indices = chain_of_patch.at(patch_index);
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								            unique_chain_indices.insert(unique_chain_indices.end(), chain_indices.begin(), chain_indices.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        std::sort(unique_chain_indices.begin(), unique_chain_indices.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        unique_end_iter = std::unique(unique_chain_indices.begin(), unique_chain_indices.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        for (auto iter = unique_chain_indices.begin(); iter != unique_end_iter; ++iter)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            old_chain_index_to_unique_index[*iter] = std::distance(unique_chain_indices.begin(), iter);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								        const auto unique_chain_count = std::distance(unique_chain_indices.begin(), unique_end_iter);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        chain_vertices.reserve(unique_chain_count);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        chain_vertex_flags.reserve(unique_chain_count);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        chain_other_subface_indices.reserve(unique_chain_count);
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								        for (const auto& chain_index : unique_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];
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            chain_other_subface_indices.emplace_back(chain_edge_headers[chain_index].subface_indices);
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								        for (const auto& patch_index : patch_indices) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            const auto& chain_indices = chain_of_patch.at(patch_index);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            auto&       chain_group   = chain_group_indices.emplace_back();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            std::transform(chain_indices.begin(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								                           chain_indices.end(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								                           std::back_inserter(chain_group),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								                           [&](uint32_t chain_index) { return old_chain_index_to_unique_index[chain_index]; });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								void remap_parameteric_plane_vertices(flat_hash_map_mp<uint32_t, parametric_plane_t>& parameteric_planes)
							 | 
						
					
						
							| 
								
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								    for (auto& [_, parameteric_plane] : parameteric_planes) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        auto& uv_bounds = parameteric_plane.uv_bounds;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        for (auto& chain_vertices : parameteric_plane.chain_vertices) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            for (auto& vertex : chain_vertices) uv_bounds = uv_bounds.extend(vertex);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        assert(uv_bounds.sizes().minCoeff() > epsilon);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        const auto uv_bounds_rpc = uv_bounds.sizes().cwiseInverse().array();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        for (auto& chain_vertices : parameteric_plane.chain_vertices) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								            std::transform(chain_vertices.begin(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								                           chain_vertices.end(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								                           chain_vertices.begin(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								                           [&](const Eigen::Vector2d& uv) { return (uv - uv_bounds.min()).array() * uv_bounds_rpc; });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
								}
							 |