From efdcef7855e378bc3183ceab16e17f3dfd8e3c76 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Tue, 16 Aug 2022 13:49:27 +0300 Subject: Fix T100421: OBJ importer in 3.3 does not keep the vertex order While fixing T100302 (rBd76583cb4a1) I did not realize that the change in imported vertex order would actually matter. Turns out, it does for morph targets / mesh shape keys. So redo the fix in a way that does not change the vertex order. Fixes T100421. --- .../io/wavefront_obj/importer/obj_import_mesh.cc | 24 +++++++++++++--------- .../wavefront_obj/importer/obj_import_objects.hh | 14 ++++++------- 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'source/blender/io/wavefront_obj/importer') diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index e62470588ec..a570b374231 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -157,17 +157,21 @@ void MeshFromGeometry::fixup_invalid_faces() void MeshFromGeometry::create_vertices(Mesh *mesh) { - int mi = 0; - for (int vi : mesh_geometry_.vertices_) { - if (vi < global_vertices_.vertices.size()) { - copy_v3_v3(mesh->mvert[mi].co, global_vertices_.vertices[vi]); - } - else { - std::cerr << "Vertex index:" << vi - << " larger than total vertices:" << global_vertices_.vertices.size() << " ." - << std::endl; + /* Go through all the global vertex indices from min to max, + * checking which ones are actually and building a global->local + * index mapping. Write out the used vertex positions into the Mesh + * data. */ + mesh_geometry_.global_to_local_vertices_.clear(); + mesh_geometry_.global_to_local_vertices_.reserve(mesh_geometry_.vertices_.size()); + for (int vi = mesh_geometry_.vertex_index_min_; vi <= mesh_geometry_.vertex_index_max_; ++vi) { + BLI_assert(vi >= 0 && vi < global_vertices_.vertices.size()); + if (!mesh_geometry_.vertices_.contains(vi)) { + continue; } - ++mi; + int local_vi = (int)mesh_geometry_.global_to_local_vertices_.size(); + BLI_assert(local_vi >= 0 && local_vi < mesh->totvert); + copy_v3_v3(mesh->mvert[local_vi].co, global_vertices_.vertices[vi]); + mesh_geometry_.global_to_local_vertices_.add_new(vi, local_vi); } } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh index f48b6dd55e8..04d9a665588 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh @@ -11,8 +11,8 @@ #include "BLI_map.hh" #include "BLI_math_base.hh" #include "BLI_math_vec_types.hh" +#include "BLI_set.hh" #include "BLI_vector.hh" -#include "BLI_vector_set.hh" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -93,9 +93,11 @@ struct Geometry { int vertex_index_min_ = INT_MAX; int vertex_index_max_ = -1; - VectorSet vertices_; + /* Global vertex indices used by this geometry. */ + Set vertices_; + /* Mapping from global vertex index to geometry-local vertex index. */ Map global_to_local_vertices_; - /** Edges written in the file in addition to (or even without polygon) elements. */ + /* Loose edges in the file. */ Vector edges_; Vector face_corners_; @@ -112,19 +114,15 @@ struct Geometry { } void track_vertex_index(int index) { - if (vertices_.add(index)) { - global_to_local_vertices_.add_new(index, (int)vertices_.size() - 1); - } + vertices_.add(index); math::min_inplace(vertex_index_min_, index); math::max_inplace(vertex_index_max_, index); } void track_all_vertices(int count) { vertices_.reserve(count); - global_to_local_vertices_.reserve(count); for (int i = 0; i < count; ++i) { vertices_.add(i); - global_to_local_vertices_.add(i, i); } vertex_index_min_ = 0; vertex_index_max_ = count - 1; -- cgit v1.2.3