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_objects.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_objects.hh')
-rw-r--r-- | source/blender/io/wavefront_obj/importer/obj_import_objects.hh | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh new file mode 100644 index 00000000000..c6ce7d3c434 --- /dev/null +++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup obj + */ + +#pragma once + +#include "BKE_lib_id.h" + +#include "BLI_math_vec_types.hh" +#include "BLI_vector.hh" +#include "BLI_vector_set.hh" + +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" + +namespace blender::io::obj { + +/** + * List of all vertex and UV vertex coordinates in an OBJ file accessible to any + * Geometry instance at any time. + */ +struct GlobalVertices { + Vector<float3> vertices; + Vector<float2> uv_vertices; + Vector<float3> vertex_normals; +}; + +/** + * Keeps track of the vertices that belong to other Geometries. + * Needed only for MLoop.v and MEdge.v1 which needs vertex indices ranging from (0 to total + * vertices in the mesh) as opposed to the other OBJ indices ranging from (0 to total vertices + * in the global list). + */ +struct VertexIndexOffset { + private: + int offset_ = 0; + + public: + void set_index_offset(const int64_t total_vertices) + { + offset_ = total_vertices; + } + int64_t get_index_offset() const + { + return offset_; + } +}; + +/** + * A face's corner in an OBJ file. In Blender, it translates to a mloop vertex. + */ +struct PolyCorner { + /* These indices range from zero to total vertices in the OBJ file. */ + int vert_index; + /* -1 is to indicate absence of UV vertices. Only < 0 condition should be checked since + * it can be less than -1 too. */ + int uv_vert_index = -1; + int vertex_normal_index = -1; +}; + +struct PolyElem { + std::string vertex_group; + std::string material_name; + bool shaded_smooth = false; + Vector<PolyCorner> face_corners; +}; + +/** + * Contains data for one single NURBS curve in the OBJ file. + */ +struct NurbsElement { + /** + * For curves, groups may be used to specify multiple splines in the same curve object. + * It may also serve as the name of the curve if not specified explicitly. + */ + std::string group_; + int degree = 0; + /** + * Indices into the global list of vertex coordinates. Must be non-negative. + */ + Vector<int> curv_indices; + /* Values in the parm u/v line in a curve definition. */ + Vector<float> parm; +}; + +enum eGeometryType { + GEOM_MESH = OB_MESH, + GEOM_CURVE = OB_CURVES_LEGACY, +}; + +struct Geometry { + eGeometryType geom_type_ = GEOM_MESH; + std::string geometry_name_; + VectorSet<std::string> material_names_; + /** + * Indices in the vector range from zero to total vertices in a geometry. + * Values range from zero to total coordinates in the global list. + */ + Vector<int> vertex_indices_; + /** Edges written in the file in addition to (or even without polygon) elements. */ + Vector<MEdge> edges_; + Vector<PolyElem> face_elements_; + bool has_vertex_normals_ = false; + bool use_vertex_groups_ = false; + NurbsElement nurbs_element_; + int total_loops_ = 0; +}; + +} // namespace blender::io::obj |