diff options
author | Ankit Meel <ankitjmeel@gmail.com> | 2022-04-04 13:36:10 +0300 |
---|---|---|
committer | Aras Pranckevicius <aras@nesnausk.org> | 2022-04-04 13:36:10 +0300 |
commit | e6a9b223844346a34ce195652449fec3229a2ec1 (patch) | |
tree | 38b9621299a83515670af0189b8cddc51813f838 /source/blender/io/wavefront_obj/importer/obj_import_file_reader.hh | |
parent | ee3f71d747e3ffd5091335437d52b3ec518d7b67 (diff) |
OBJ: New C++ based wavefront OBJ importer
This takes state of soc-2020-io-performance branch as it was at
e9bbfd0c8c7 (2021 Oct 31), merges latest master (2022 Apr 4),
adds a bunch of tests, and fixes a bunch of stuff found by said
tests. The fixes are detailed in the differential.
Timings on my machine (Windows, VS2022 release build, AMD Ryzen
5950X 32 threads):
- Rungholt minecraft level (269MB file, 1 mesh): 54.2s -> 14.2s
(memory usage: 7.0GB -> 1.9GB).
- Blender 3.0 splash scene: "I waited for 90 minutes and gave up"
-> 109s. Now, this time is not great, but at least 20% of the
time is spent assigning unique names for the imported objects
(the scene has 24 thousand objects). This is not specific to obj
importer, but rather a general issue across blender overall.
Test suite file updates done in Subversion tests repository.
Reviewed By: @howardt, @sybren
Differential Revision: https://developer.blender.org/D13958
Diffstat (limited to 'source/blender/io/wavefront_obj/importer/obj_import_file_reader.hh')
-rw-r--r-- | source/blender/io/wavefront_obj/importer/obj_import_file_reader.hh | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.hh b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.hh new file mode 100644 index 00000000000..c8d8b78fc0e --- /dev/null +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.hh @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup obj + */ + +#pragma once + +#include "BLI_fileops.hh" +#include "IO_wavefront_obj.h" +#include "obj_import_mtl.hh" +#include "obj_import_objects.hh" + +namespace blender::io::obj { + +/* Note: the OBJ parser implementation is planned to get fairly large changes "soon", + * so don't read too much into current implementation... */ +class OBJParser { + private: + const OBJImportParams &import_params_; + blender::fstream obj_file_; + Vector<std::string> mtl_libraries_; + + public: + OBJParser(const OBJImportParams &import_params); + + void parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries, + GlobalVertices &r_global_vertices); + Span<std::string> mtl_libraries() const; +}; + +enum class eOBJLineKey { + V, + VN, + VT, + F, + L, + CSTYPE, + DEG, + CURV, + PARM, + O, + G, + S, + USEMTL, + MTLLIB, + COMMENT +}; + +constexpr eOBJLineKey line_key_str_to_enum(const std::string_view key_str) +{ + if (key_str == "v" || key_str == "V") { + return eOBJLineKey::V; + } + if (key_str == "vn" || key_str == "VN") { + return eOBJLineKey::VN; + } + if (key_str == "vt" || key_str == "VT") { + return eOBJLineKey::VT; + } + if (key_str == "f" || key_str == "F") { + return eOBJLineKey::F; + } + if (key_str == "l" || key_str == "L") { + return eOBJLineKey::L; + } + if (key_str == "cstype" || key_str == "CSTYPE") { + return eOBJLineKey::CSTYPE; + } + if (key_str == "deg" || key_str == "DEG") { + return eOBJLineKey::DEG; + } + if (key_str == "curv" || key_str == "CURV") { + return eOBJLineKey::CURV; + } + if (key_str == "parm" || key_str == "PARM") { + return eOBJLineKey::PARM; + } + if (key_str == "o" || key_str == "O") { + return eOBJLineKey::O; + } + if (key_str == "g" || key_str == "G") { + return eOBJLineKey::G; + } + if (key_str == "s" || key_str == "S") { + return eOBJLineKey::S; + } + if (key_str == "usemtl" || key_str == "USEMTL") { + return eOBJLineKey::USEMTL; + } + if (key_str == "mtllib" || key_str == "MTLLIB") { + return eOBJLineKey::MTLLIB; + } + if (key_str == "#") { + return eOBJLineKey::COMMENT; + } + return eOBJLineKey::COMMENT; +} + +/** + * All texture map options with number of arguments they accept. + */ +class TextureMapOptions { + private: + Map<const std::string, int> tex_map_options; + + public: + TextureMapOptions() + { + tex_map_options.add_new("-blendu", 1); + tex_map_options.add_new("-blendv", 1); + tex_map_options.add_new("-boost", 1); + tex_map_options.add_new("-mm", 2); + tex_map_options.add_new("-o", 3); + tex_map_options.add_new("-s", 3); + tex_map_options.add_new("-t", 3); + tex_map_options.add_new("-texres", 1); + tex_map_options.add_new("-clamp", 1); + tex_map_options.add_new("-bm", 1); + tex_map_options.add_new("-imfchan", 1); + } + + /** + * All valid option strings. + */ + Map<const std::string, int>::KeyIterator all_options() const + { + return tex_map_options.keys(); + } + + int number_of_args(StringRef option) const + { + return tex_map_options.lookup_as(std::string(option)); + } +}; + +class MTLParser { + private: + char mtl_file_path_[FILE_MAX]; + /** + * Directory in which the MTL file is found. + */ + char mtl_dir_path_[FILE_MAX]; + blender::fstream mtl_file_; + + public: + MTLParser(StringRef mtl_library_, StringRefNull obj_filepath); + + void parse_and_store(Map<std::string, std::unique_ptr<MTLMaterial>> &r_mtl_materials); +}; +} // namespace blender::io::obj |