feature: compile index-based coordinate storage
The storage contains coordinates based on their ndims: 1D, 2D or 3D.
This commit is contained in:
31
src/compile.hpp
Normal file
31
src/compile.hpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include <array>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "parse.hpp"
|
||||||
|
|
||||||
|
namespace wavefront {
|
||||||
|
template<typename IndexType, template<typename, typename...> typename ContainerType, typename ... Args>
|
||||||
|
using coordinate_index_storage_t = std::tuple<
|
||||||
|
std::monostate,
|
||||||
|
ContainerType<IndexType, Args...>,
|
||||||
|
ContainerType<std::array<IndexType, 2>, Args...>,
|
||||||
|
ContainerType<std::array<IndexType, 3>, Args...>
|
||||||
|
>;
|
||||||
|
|
||||||
|
template<typename IndexType, std::size_t NumDims>
|
||||||
|
void append_coordinate_map_to_storage(
|
||||||
|
coordinate_index_storage_t<IndexType, std::set> &target,
|
||||||
|
const std::map<
|
||||||
|
file_line_t,
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/main.cpp
62
src/main.cpp
@@ -12,8 +12,9 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "parse.hpp"
|
|
||||||
#include "scan.hpp"
|
#include "scan.hpp"
|
||||||
|
#include "parse.hpp"
|
||||||
|
#include "compile.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
static void usage(const char* prog) {
|
static void usage(const char* prog) {
|
||||||
@@ -37,6 +38,17 @@ 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;
|
||||||
|
|
||||||
@@ -118,6 +130,9 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
Settings settings = settings_builder.build();
|
Settings settings = settings_builder.build();
|
||||||
|
|
||||||
|
using FloatType = float;
|
||||||
|
using IndexType = std::size_t;
|
||||||
|
|
||||||
CATCH_AND_RETURN(scan_data, wavefront::scan_error, 1, wavefront::scan(
|
CATCH_AND_RETURN(scan_data, wavefront::scan_error, 1, wavefront::scan(
|
||||||
settings.input(),
|
settings.input(),
|
||||||
settings.selected_objects(),
|
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_normal_set.size() << " vertex normals" << std::endl;
|
||||||
std::cerr << "Selected " << face_data.index_texcoord_set.size() << " vertex texture coordinates" << 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<float>(scan_data, face_data));
|
CATCH_AND_RETURN(coordinate_data, wavefront::parse_error, 1, wavefront::parse_coordinate_data<FloatType>(scan_data, face_data));
|
||||||
|
|
||||||
auto number_list = create_number_list<float>(coordinate_data);
|
auto number_list = create_number_list<FloatType>(coordinate_data);
|
||||||
|
|
||||||
std::cerr << "Generated number list with " << number_list.size() << " values" << std::endl;
|
std::cerr << "Generated number list with " << number_list.size() << " values" << std::endl;
|
||||||
|
|
||||||
auto coordinate_index_data = create_coordinate_index<float, std::size_t>(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;
|
||||||
|
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>{}
|
||||||
|
);
|
||||||
|
|
||||||
// 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.
|
||||||
|
|||||||
Reference in New Issue
Block a user