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 ++-- .../io/wavefront_obj/tests/obj_importer_tests.cc | 86 +++++++++++----------- 3 files changed, 63 insertions(+), 61 deletions(-) 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; diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc index f97546fe4f5..01a73ae42a0 100644 --- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc @@ -153,7 +153,7 @@ TEST_F(obj_importer_test, import_cube) 12, 6, 24, - float3(1, -1, 1), + float3(-1, -1, 1), float3(1, -1, -1), float3(-0.57735f, 0.57735f, -0.57735f)}, }; @@ -171,7 +171,7 @@ TEST_F(obj_importer_test, import_cube_o_after_verts) 12, 6, 24, - float3(1, -1, 1), + float3(-1, -1, 1), float3(1, -1, -1), float3(0, 0, 1), }, @@ -182,8 +182,8 @@ TEST_F(obj_importer_test, import_cube_o_after_verts) 3, 1, 3, + float3(1, -1, 1), float3(-2, -2, 2), - float3(-1, -1, -1), float3(-0.2357f, 0.9428f, 0.2357f), }, }; @@ -200,8 +200,8 @@ TEST_F(obj_importer_test, import_suzanne_all_data) 1005, 500, 1968, - float3(-0.5f, 0.09375f, 0.6875f), - float3(0.546875f, 0.054688f, 0.578125f), + float3(-0.4375f, 0.164062f, 0.765625f), + float3(0.4375f, 0.164062f, 0.765625f), float3(-0.6040f, -0.5102f, 0.6122f), float2(0.692094f, 0.40191f)}, }; @@ -306,7 +306,7 @@ TEST_F(obj_importer_test, import_materials) { Expectation expect[] = { {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, - {"OBmaterials", OB_MESH, 8, 12, 6, 24, float3(1, -1, 1), float3(1, -1, -1)}, + {"OBmaterials", OB_MESH, 8, 12, 6, 24, float3(-1, -1, 1), float3(1, -1, -1)}, }; import_and_check("materials.obj", expect, std::size(expect), 4, 8); } @@ -322,7 +322,7 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel) 6, 24, float3(1, 1, -1), - float3(1, -1, -1), + float3(-1, -1, 1), float3(0, 1, 0), float2(0.9935f, 0.0020f)}, {"OBCubeTexMul", @@ -332,7 +332,7 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel) 6, 24, float3(4, -2, -1), - float3(4, -4, -1), + float3(2, -4, 1), float3(0, 1, 0), float2(0.9935f, 0.0020f)}, {"OBCubeTiledTex", @@ -342,7 +342,7 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel) 6, 24, float3(4, 1, -1), - float3(4, -1, -1), + float3(2, -1, 1), float3(0, 1, 0), float2(0.9935f, 0.0020f)}, {"OBCubeTiledTexFromAnotherFolder", @@ -352,7 +352,7 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel) 6, 24, float3(7, 1, -1), - float3(7, -1, -1), + float3(5, -1, 1), float3(0, 1, 0), float2(0.9935f, 0.0020f)}, }; @@ -443,15 +443,15 @@ TEST_F(obj_importer_test, import_all_objects) {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, /* .obj file has empty EmptyText and EmptyMesh objects; these are ignored and skipped */ {"OBBezierCurve", OB_MESH, 13, 12, 0, 0, float3(-1, -2, 0), float3(1, -2, 0)}, - {"OBBlankCube", OB_MESH, 8, 13, 7, 26, float3(1, 1, 1), float3(-1, 1, -1), float3(0, 0, 1)}, + {"OBBlankCube", OB_MESH, 8, 13, 7, 26, float3(1, 1, -1), float3(-1, 1, 1), float3(0, 0, 1)}, {"OBMaterialCube", OB_MESH, 8, 13, 7, 26, - float3(26, -1, -1), - float3(28, -1, -1), + float3(28, 1, -1), + float3(26, 1, 1), float3(-1, 0, 0)}, {"OBNurbsCircle", OB_MESH, @@ -461,15 +461,15 @@ TEST_F(obj_importer_test, import_all_objects) 0, float3(3.292893f, -2.707107f, 0), float3(3.369084f, -2.77607f, 0)}, - {"OBNurbsCircle.001", OB_MESH, 4, 4, 0, 0, float3(3, -2, 0), float3(2, -1, 0)}, + {"OBNurbsCircle.001", OB_MESH, 4, 4, 0, 0, float3(2, -3, 0), float3(3, -2, 0)}, {"OBParticleCube", OB_MESH, 8, 13, 7, 26, - float3(22, 1, 1), - float3(20, 1, -1), + float3(22, 1, -1), + float3(20, 1, 1), float3(0, 0, 1)}, {"OBShapeKeyCube", OB_MESH, @@ -477,8 +477,8 @@ TEST_F(obj_importer_test, import_all_objects) 13, 7, 26, - float3(19, 1, 2), - float3(17, 1, -1), + float3(19, 1, -1), + float3(17, 1, 1), float3(-0.4082f, -0.4082f, 0.8165f)}, {"OBSmoothCube", OB_MESH, @@ -486,8 +486,8 @@ TEST_F(obj_importer_test, import_all_objects) 13, 7, 26, - float3(4, 1, 1), - float3(2, 1, -1), + float3(4, 1, -1), + float3(2, 1, 1), float3(0.5774f, 0.5773f, 0.5774f)}, {"OBSurface", OB_MESH, @@ -495,7 +495,7 @@ TEST_F(obj_importer_test, import_all_objects) 480, 224, 896, - float3(7.292893f, -2.707107f, -0.714285f), + float3(7.292893f, -2.707107f, -1), float3(7.525872f, -2.883338f, 1), float3(-0.7071f, -0.7071f, 0), float2(0, 0.142857f)}, @@ -505,7 +505,7 @@ TEST_F(obj_importer_test, import_all_objects) 480, 225, 900, - float3(12.56667f, -2.5f, 0.72037f), + float3(12.5f, -2.5f, 0.694444f), float3(13.5f, -1.5f, 0.694444f), float3(-0.3246f, -0.3531f, 0.8775f), float2(0, 0.066667f)}, @@ -526,7 +526,7 @@ TEST_F(obj_importer_test, import_all_objects) 1024, 4096, float3(5.34467f, -2.65533f, -0.176777f), - float3(5.158205f, -2.234695f, -0.220835f), + float3(5.232792f, -2.411795f, -0.220835f), float3(-0.5042f, -0.5042f, -0.7011f), float2(0, 1)}, {"OBTaperCube", @@ -535,8 +535,8 @@ TEST_F(obj_importer_test, import_all_objects) 208, 104, 416, - float3(24.316156f, 0.345556f, 0.796778f), - float3(23.551804f, 0.389113f, -0.639607f), + float3(24.444445f, 0.502543f, -0.753814f), + float3(23.790743f, 0.460522f, -0.766546f), float3(-0.0546f, 0.1716f, 0.9837f)}, {"OBText", OB_MESH, @@ -544,8 +544,8 @@ TEST_F(obj_importer_test, import_all_objects) 345, 171, 513, - float3(1.583f, -9.621f, 0), - float3(0.351f, -10.0f, 0), + float3(1.75f, -9.458f, 0), + float3(0.587f, -9.406f, 0), float3(0, 0, 1), float2(0.017544f, 0)}, {"OBUVCube", @@ -554,8 +554,8 @@ TEST_F(obj_importer_test, import_all_objects) 13, 7, 26, - float3(7, 1, 1), - float3(5, 1, -1), + float3(7, 1, -1), + float3(5, 1, 1), float3(0, 0, 1), float2(0.654526f, 0.579873f)}, {"OBUVImageCube", @@ -564,8 +564,8 @@ TEST_F(obj_importer_test, import_all_objects) 13, 7, 26, - float3(10, 1, 1), - float3(8, 1, -1), + float3(10, 1, -1), + float3(8, 1, 1), float3(0, 0, 1), float2(0.654526f, 0.579873f)}, {"OBVColCube", @@ -574,8 +574,8 @@ TEST_F(obj_importer_test, import_all_objects) 13, 7, 26, - float3(13, 1, 1), - float3(11, 1, -1), + float3(13, 1, -1), + float3(11, 1, 1), float3(0, 0, 1), float2(0, 0), float4(0.0f, 0.002125f, 1.0f, 1.0f)}, @@ -585,8 +585,8 @@ TEST_F(obj_importer_test, import_all_objects) 13, 7, 26, - float3(16, 1, 1), - float3(14, 1, -1), + float3(16, 1, -1), + float3(14, 1, 1), float3(0, 0, 1)}, }; import_and_check("all_objects.obj", expect, std::size(expect), 7); @@ -603,7 +603,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) 6, 24, float3(1.0f, 1.0f, -3.812445f), - float3(1.0f, -1.0f, -3.812445f), + float3(-1.0f, -1.0f, -1.812445f), float3(0, 0, 0), float2(0, 0), float4(0.89627f, 0.036889f, 0.47932f, 1.0f)}, @@ -614,7 +614,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) 6, 24, float3(3.481967f, 1.0f, -3.812445f), - float3(3.481967f, -1.0f, -3.812445f), + float3(1.481967f, -1.0f, -1.812445f), float3(0, 0, 0), float2(0, 0), float4(1.564582f, 0.039217f, 0.664309f, 1.0f)}, @@ -625,7 +625,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) 6, 24, float3(-4.725068f, -1.0f, 1.0f), - float3(-2.725068f, -1.0f, 1.0f), + float3(-2.725068f, 1.0f, -1.0f), float3(0, 0, 0), float2(0, 0), float4(0.270498f, 0.47932f, 0.262251f, 1.0f)}, @@ -636,7 +636,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) 6, 24, float3(-4.550208f, -1.0f, -1.918042f), - float3(-2.550208f, -1.0f, -1.918042f)}, + float3(-2.550208f, 1.0f, -3.918042f)}, {"OBCubeVertexByte", OB_MESH, 8, @@ -644,7 +644,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) 6, 24, float3(1.0f, 1.0f, -1.0f), - float3(1.0f, -1.0f, -1.0f), + float3(-1.0f, -1.0f, 1.0f), float3(0, 0, 0), float2(0, 0), float4(0.846873f, 0.027321f, 0.982123f, 1.0f)}, @@ -655,7 +655,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) 6, 24, float3(3.392028f, 1.0f, -1.0f), - float3(3.392028f, -1.0f, -1.0f), + float3(1.392028f, -1.0f, 1.0f), float3(0, 0, 0), float2(0, 0), float4(49.99467f, 0.027321f, 0.982123f, 1.0f)}, @@ -674,7 +674,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors_mrgb) 6, 24, float3(4, 1, -1), - float3(4, -1, -1), + float3(2, -1, 1), float3(0, 0, 0), float2(0, 0), float4(0.8714f, 0.6308f, 0.5271f, 1.0f)}, @@ -685,7 +685,7 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors_mrgb) 6, 24, float3(1, 1, -1), - float3(1, -1, -1), + float3(-1, -1, 1), float3(0, 0, 0), float2(0, 0), float4(0.6038f, 0.3185f, 0.1329f, 1.0f)}, -- cgit v1.2.3