1
0

feature: coordinate storage index

This commit is contained in:
2025-11-14 01:04:50 +02:00
parent 9d3452bea4
commit 7ae430ff4a
2 changed files with 122 additions and 58 deletions

View File

@@ -16,16 +16,126 @@ namespace wavefront {
ContainerType<std::array<IndexType, 3>, Args...> ContainerType<std::array<IndexType, 3>, Args...>
>; >;
template<typename IndexType, std::size_t NumDims> namespace {
void append_coordinate_map_to_storage( template<typename IndexType, std::size_t NumDims>
coordinate_index_storage_t<IndexType, std::set> &target, void append_coordinate_map_to_storage(
const std::map< coordinate_index_storage_t<IndexType, std::set> &target,
file_line_t, const std::map<
typename std::tuple_element_t<NumDims, std::decay_t<decltype(target)>>::value_type file_line_t,
> &source typename std::tuple_element_t<NumDims, std::decay_t<decltype(target)>>::value_type
) { > &source
for (const auto &[line_number, coordinates] : source) { ) {
std::get<NumDims>(target).emplace(coordinates); for (const auto &[line_number, coordinates] : source) {
std::get<NumDims>(target).emplace(coordinates);
}
}
template<typename TargetType, typename SourceType, typename Function, std::size_t... Index>
inline void foreach_tuple_element(TargetType &target_tuple, const SourceType &source_tuple, Function function, std::index_sequence<Index...>) {
static_assert(std::tuple_size_v<TargetType> == std::tuple_size_v<SourceType>);
((
function(
std::get<Index>(target_tuple),
std::get<Index>(source_tuple)
)
), ...);
} }
} }
template<typename IndexType>
coordinate_index_storage_t<IndexType, std::vector> compile_coordinate_storage(const coordinate_data_t<IndexType> &coordinate_index_data) {
coordinate_index_storage_t<IndexType, std::set> ndim_coordinate_storage_set;
append_coordinate_map_to_storage<IndexType, 3>(ndim_coordinate_storage_set, coordinate_index_data.position_coordinates);
append_coordinate_map_to_storage<IndexType, 3>(ndim_coordinate_storage_set, coordinate_index_data.normal_coordinates);
std::visit([&](const auto &texture_coordinates) {
if constexpr (std::ranges::range<std::decay_t<decltype(texture_coordinates)>>) {
if constexpr (std::ranges::range<typename std::decay_t<decltype(texture_coordinates)>::mapped_type>) {
append_coordinate_map_to_storage<
IndexType,
std::tuple_size_v<typename std::decay_t<decltype(texture_coordinates)>::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<IndexType, std::vector> 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<typename IndexType>
struct coordinate_storage_line_mapping_t {
std::map<file_line_t, IndexType> position_coordinate_index;
std::map<file_line_t, IndexType> normal_coordinate_index;
std::map<file_line_t, IndexType> texcoord_coordinate_index;
};
template<typename IndexType>
coordinate_storage_line_mapping_t<IndexType> compile_coordinate_storage_line_mapping(
const coordinate_data_t<IndexType> &coordinate_index_data,
const coordinate_index_storage_t<IndexType, std::vector> &coordinate_storage
) {
coordinate_storage_line_mapping_t<IndexType> 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<std::decay_t<decltype(texture_coordinates)>>) {
if constexpr (std::ranges::range<typename std::decay_t<decltype(texture_coordinates)>::mapped_type>) {
auto &data_storage = std::get<std::tuple_size_v<typename std::decay_t<decltype(texture_coordinates)>::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;
}
} }

View File

@@ -38,17 +38,6 @@ static void usage(const char* prog) {
return return_value; \ return return_value; \
} }
template<typename TargetType, typename SourceType, typename Function, std::size_t... Index>
inline void foreach_tuple_element(TargetType &target_tuple, const SourceType &source_tuple, Function function, std::index_sequence<Index...>) {
static_assert(std::tuple_size_v<TargetType> == std::tuple_size_v<SourceType>);
((
function(
std::get<Index>(target_tuple),
std::get<Index>(source_tuple)
)
), ...);
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
using namespace wavefront; using namespace wavefront;
@@ -160,44 +149,9 @@ int main(int argc, char** argv) {
auto coordinate_index_data = create_coordinate_index<FloatType, IndexType>(coordinate_data, number_list); auto coordinate_index_data = create_coordinate_index<FloatType, IndexType>(coordinate_data, number_list);
coordinate_index_storage_t<IndexType, std::set> ndim_coordinate_storage_set; auto coordinate_storage = compile_coordinate_storage(coordinate_index_data);
append_coordinate_map_to_storage<IndexType, 3>(ndim_coordinate_storage_set, coordinate_index_data.position_coordinates);
append_coordinate_map_to_storage<IndexType, 3>(ndim_coordinate_storage_set, coordinate_index_data.normal_coordinates);
std::visit([&](const auto &texture_coordinates) { auto coordinate_storage_index = compile_coordinate_storage_line_mapping(coordinate_index_data, coordinate_storage);
if constexpr (std::ranges::range<std::decay_t<decltype(texture_coordinates)>>) {
if constexpr (std::ranges::range<typename std::decay_t<decltype(texture_coordinates)>::mapped_type>) {
append_coordinate_map_to_storage<
IndexType,
std::tuple_size_v<typename std::decay_t<decltype(texture_coordinates)>::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<IndexType, std::vector> 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. // 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<file_line_t, std::size_t> pointing for each entry to entry in coordinate_list_data. // Then we can form coordinate_line_mapping : std::map<file_line_t, std::size_t> pointing for each entry to entry in coordinate_list_data.