From 9d3452bea402af5964a26658b2a20d73479f50eb Mon Sep 17 00:00:00 2001 From: Plamen Dragiyski Date: Wed, 12 Nov 2025 02:11:15 +0200 Subject: [PATCH] feature: compile index-based coordinate storage The storage contains coordinates based on their ndims: 1D, 2D or 3D. --- src/compile.hpp | 31 +++++++++++++++++++++++++ src/main.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 src/compile.hpp diff --git a/src/compile.hpp b/src/compile.hpp new file mode 100644 index 0000000..1682311 --- /dev/null +++ b/src/compile.hpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +#include "parse.hpp" + +namespace wavefront { + template typename ContainerType, typename ... Args> + using coordinate_index_storage_t = std::tuple< + std::monostate, + ContainerType, + ContainerType, Args...>, + 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); + } + } +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f3531a9..e89bc8d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,8 +12,9 @@ #include #include -#include "parse.hpp" #include "scan.hpp" +#include "parse.hpp" +#include "compile.hpp" #include "settings.hpp" static void usage(const char* prog) { @@ -37,6 +38,17 @@ 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; @@ -118,6 +130,9 @@ int main(int argc, char** argv) { Settings settings = settings_builder.build(); + using FloatType = float; + using IndexType = std::size_t; + CATCH_AND_RETURN(scan_data, wavefront::scan_error, 1, wavefront::scan( settings.input(), settings.selected_objects(), @@ -137,13 +152,52 @@ int main(int argc, char** argv) { std::cerr << "Selected " << face_data.index_normal_set.size() << " vertex normals" << std::endl; std::cerr << "Selected " << face_data.index_texcoord_set.size() << " vertex texture coordinates" << std::endl; - CATCH_AND_RETURN(coordinate_data, wavefront::parse_error, 1, wavefront::parse_coordinate_data(scan_data, face_data)); + CATCH_AND_RETURN(coordinate_data, wavefront::parse_error, 1, wavefront::parse_coordinate_data(scan_data, face_data)); - auto number_list = create_number_list(coordinate_data); + auto number_list = create_number_list(coordinate_data); std::cerr << "Generated number list with " << number_list.size() << " values" << std::endl; - auto coordinate_index_data = create_coordinate_index(coordinate_data, number_list); + 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); + + 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>{} + ); // 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.