From 7ae430ff4a890840ab349f049511855a9561f034 Mon Sep 17 00:00:00 2001 From: Plamen Dragiyski Date: Fri, 14 Nov 2025 01:04:50 +0200 Subject: [PATCH] feature: coordinate storage index --- src/compile.hpp | 130 ++++++++++++++++++++++++++++++++++++++++++++---- src/main.cpp | 50 +------------------ 2 files changed, 122 insertions(+), 58 deletions(-) diff --git a/src/compile.hpp b/src/compile.hpp index 1682311..6407e3d 100644 --- a/src/compile.hpp +++ b/src/compile.hpp @@ -16,16 +16,126 @@ namespace wavefront { ContainerType, Args...> >; - template - void append_coordinate_map_to_storage( - coordinate_index_storage_t &target, - const std::map< - file_line_t, - typename std::tuple_element_t>::value_type - > &source - ) { - for (const auto &[line_number, coordinates] : source) { - std::get(target).emplace(coordinates); + namespace { + template + void append_coordinate_map_to_storage( + coordinate_index_storage_t &target, + const std::map< + file_line_t, + typename std::tuple_element_t>::value_type + > &source + ) { + for (const auto &[line_number, coordinates] : source) { + std::get(target).emplace(coordinates); + } + } + + template + inline void foreach_tuple_element(TargetType &target_tuple, const SourceType &source_tuple, Function function, std::index_sequence) { + static_assert(std::tuple_size_v == std::tuple_size_v); + (( + function( + std::get(target_tuple), + std::get(source_tuple) + ) + ), ...); } } + + template + coordinate_index_storage_t compile_coordinate_storage(const coordinate_data_t &coordinate_index_data) { + coordinate_index_storage_t ndim_coordinate_storage_set; + append_coordinate_map_to_storage(ndim_coordinate_storage_set, coordinate_index_data.position_coordinates); + append_coordinate_map_to_storage(ndim_coordinate_storage_set, coordinate_index_data.normal_coordinates); + + std::visit([&](const auto &texture_coordinates) { + if constexpr (std::ranges::range>) { + if constexpr (std::ranges::range::mapped_type>) { + append_coordinate_map_to_storage< + IndexType, + std::tuple_size_v::mapped_type> + >(ndim_coordinate_storage_set, texture_coordinates); + } else { + append_coordinate_map_to_storage< + IndexType, + 1 + >(ndim_coordinate_storage_set, texture_coordinates); + } + } + }, coordinate_index_data.texture_coordinates); + + coordinate_index_storage_t ndim_coordinate_storage; + + foreach_tuple_element( + ndim_coordinate_storage, + ndim_coordinate_storage_set, + [&]( + auto &target, + const auto &source + ) { + target.reserve(source.size()); + std::copy( + source.begin(), + source.end(), + std::back_inserter(target) + ); + }, + std::index_sequence<1, 2, 3>{} + ); + + return ndim_coordinate_storage; + } + + template + struct coordinate_storage_line_mapping_t { + std::map position_coordinate_index; + std::map normal_coordinate_index; + std::map texcoord_coordinate_index; + }; + + template + coordinate_storage_line_mapping_t compile_coordinate_storage_line_mapping( + const coordinate_data_t &coordinate_index_data, + const coordinate_index_storage_t &coordinate_storage + ) { + coordinate_storage_line_mapping_t result; + + { + auto &data_storage = std::get<3>(coordinate_storage); + for (const auto &[line_number, data_vector] : coordinate_index_data.position_coordinates) { + auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector); + assert(data_vector_iterator != data_storage.end()); + auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator); + result.position_coordinate_index[line_number] = data_vector_index; + } + } + { + auto &data_storage = std::get<3>(coordinate_storage); + for (const auto &[line_number, data_vector] : coordinate_index_data.normal_coordinates) { + auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector); + assert(data_vector_iterator != data_storage.end()); + auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator); + result.normal_coordinate_index[line_number] = data_vector_index; + } + } + std::visit([&](const auto &texture_coordinates){ + if constexpr (std::ranges::range>) { + if constexpr (std::ranges::range::mapped_type>) { + auto &data_storage = std::get::mapped_type>>(coordinate_storage); + for (const auto &[line_number, data_vector] : texture_coordinates) { + auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector); + assert(data_vector_iterator != data_storage.end()); + auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator); + result.texcoord_coordinate_index[line_number] = data_vector_index; + } + } else { + for (const auto &[line_number, data_index] : texture_coordinates) { + result.texcoord_coordinate_index[line_number] = data_index; + } + } + } + }, coordinate_index_data.texture_coordinates); + + return result; + } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e89bc8d..4db7e6c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,17 +38,6 @@ static void usage(const char* prog) { return return_value; \ } -template -inline void foreach_tuple_element(TargetType &target_tuple, const SourceType &source_tuple, Function function, std::index_sequence) { - static_assert(std::tuple_size_v == std::tuple_size_v); - (( - function( - std::get(target_tuple), - std::get(source_tuple) - ) - ), ...); -} - int main(int argc, char** argv) { using namespace wavefront; @@ -160,44 +149,9 @@ int main(int argc, char** argv) { auto coordinate_index_data = create_coordinate_index(coordinate_data, number_list); - coordinate_index_storage_t ndim_coordinate_storage_set; - append_coordinate_map_to_storage(ndim_coordinate_storage_set, coordinate_index_data.position_coordinates); - append_coordinate_map_to_storage(ndim_coordinate_storage_set, coordinate_index_data.normal_coordinates); + auto coordinate_storage = compile_coordinate_storage(coordinate_index_data); - std::visit([&](const auto &texture_coordinates) { - if constexpr (std::ranges::range>) { - if constexpr (std::ranges::range::mapped_type>) { - append_coordinate_map_to_storage< - IndexType, - std::tuple_size_v::mapped_type> - >(ndim_coordinate_storage_set, texture_coordinates); - } else { - append_coordinate_map_to_storage< - IndexType, - 1 - >(ndim_coordinate_storage_set, texture_coordinates); - } - } - }, coordinate_index_data.texture_coordinates); - - coordinate_index_storage_t ndim_coordinate_storage; - - foreach_tuple_element( - ndim_coordinate_storage, - ndim_coordinate_storage_set, - [&]( - auto &target, - const auto &source - ) { - target.reserve(source.size()); - std::copy( - source.begin(), - source.end(), - std::back_inserter(target) - ); - }, - std::index_sequence<1, 2, 3>{} - ); + auto coordinate_storage_index = compile_coordinate_storage_line_mapping(coordinate_index_data, coordinate_storage); // Form coordinate_list_data : std::vector variant of coordinate_index_data. Internally, it creates std::set initially, stores everything in the set and then convert to vector. // Then we can form coordinate_line_mapping : std::map pointing for each entry to entry in coordinate_list_data.