[Bf-blender-cvs] [71eadb4b628] soc-2020-io-performance: Move vertex (and UV vertex) list outside OBJRawObject

Ankit Meel noreply at git.blender.org
Mon Jul 20 13:26:24 CEST 2020


Commit: 71eadb4b6287286c7b2d6a302dcbdcc5aef75491
Author: Ankit Meel
Date:   Mon Jul 20 16:56:10 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB71eadb4b6287286c7b2d6a302dcbdcc5aef75491

Move vertex (and UV vertex) list outside OBJRawObject

Since an OBJ file may contain data like [1], the vertex coordinates
list should be detached from any `OBJRawObject`. So every raw object
keeps track of its vertices by indexing into the global list of coordinates.

[1]
```
o plane
v 0 0 2
v 0 2 0
v 2 0 0
f 1 2 3
# note missing o <name>
v 1 1 0
v 1 0 0
v 0 1 0
v 0 0 0
g curve
cstype bspline
curv 0 1 -1 -2 -3 -4
...
```

===================================================================

M	source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
M	source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.hh
M	source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
M	source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc

===================================================================

diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
index 74cb71fa86f..4ef2c4ab236 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
@@ -124,31 +124,36 @@ void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of
 
     if (line_key == "o") {
       /* Update index offsets if an object has been processed already. */
-      if (list_of_objects.size() > 0) {
-        index_offsets[VERTEX_OFF] += (*curr_ob)->vertices.size();
-        index_offsets[UV_VERTEX_OFF] += (*curr_ob)->texture_vertices.size();
+      if (curr_ob) {
+        index_offsets[VERTEX_OFF] += (*curr_ob)->vertex_indices.size();
+        index_offsets[UV_VERTEX_OFF] += (*curr_ob)->uv_vertex_indices.size();
       }
       list_of_objects.append(std::make_unique<OBJRawObject>(s_line.str()));
       curr_ob = &list_of_objects.last();
     }
     /* TODO ankitm Check that an object exists. */
     else if (line_key == "v") {
-      MVert curr_vert;
+      float3 curr_vert;
       Vector<string> str_vert_split;
       split_by_char(s_line.str(), ' ', str_vert_split);
-      copy_string_to_float(str_vert_split, {curr_vert.co, 3});
-      (*curr_ob)->vertices.append(curr_vert);
+      copy_string_to_float(str_vert_split, {curr_vert, 3});
+      global_vertices.vertices.append(curr_vert);
+      if (curr_ob) {
+        (*curr_ob)->vertex_indices.append(global_vertices.vertices.size() - 1);
+      }
     }
     else if (line_key == "vn") {
       (*curr_ob)->tot_normals++;
     }
     else if (line_key == "vt") {
-      MLoopUV curr_tex_vert;
-      Vector<string> str_vert_split;
-      split_by_char(s_line.str(), ' ', str_vert_split);
-      copy_string_to_float(str_vert_split, {curr_tex_vert.uv, 2});
-      curr_tex_vert.flag = false;
-      (*curr_ob)->texture_vertices.append(curr_tex_vert);
+      float2 curr_uv_vert;
+      Vector<string> str_uv_vert_split;
+      split_by_char(s_line.str(), ' ', str_uv_vert_split);
+      copy_string_to_float(str_uv_vert_split, {curr_uv_vert, 2});
+      global_vertices.uv_vertices.append(curr_uv_vert);
+      if (curr_ob) {
+        (*curr_ob)->uv_vertex_indices.append(global_vertices.uv_vertices.size() - 1);
+      }
     }
     else if (line_key == "l") {
       int edge_v1, edge_v2;
@@ -156,9 +161,11 @@ void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of
       split_by_char(s_line.str(), ' ', str_edge_split);
       copy_string_to_int(str_edge_split[0], edge_v1);
       copy_string_to_int(str_edge_split[1], edge_v2);
-      edge_v1 -= (index_offsets[VERTEX_OFF] + 1);
-      edge_v2 -= (index_offsets[VERTEX_OFF] + 1);
-      BLI_assert(edge_v1 >= 0 && edge_v2 >= 0);
+      edge_v1 += edge_v1 < 0 ? (global_vertices.vertices.size() + 1) :
+                               -(index_offsets[VERTEX_OFF] + 1);
+      edge_v2 += edge_v2 < 0 ? (global_vertices.vertices.size() + 1) :
+                               -(index_offsets[VERTEX_OFF] + 1);
+      BLI_assert(edge_v1 > 0 && edge_v2 > 0);
       (*curr_ob)->edges.append({static_cast<uint>(edge_v1), static_cast<uint>(edge_v2)});
     }
     else if (line_key == "s") {
@@ -198,29 +205,31 @@ void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of
         }
         else if (n_slash == 1) {
           /* Case: f v1/vt1 v2/vt2 v3/vt3 . */
-          Vector<string> vert_texture_split;
-          split_by_char(str_corner, '/', vert_texture_split);
-          copy_string_to_int(vert_texture_split[0], corner.vert_index);
-          if (vert_texture_split.size() == 2) {
-            copy_string_to_int(vert_texture_split[1], corner.tex_vert_index);
+          Vector<string> vert_uv_split;
+          split_by_char(str_corner, '/', vert_uv_split);
+          copy_string_to_int(vert_uv_split[0], corner.vert_index);
+          if (vert_uv_split.size() == 2) {
+            copy_string_to_int(vert_uv_split[1], corner.uv_vert_index);
             (*curr_ob)->tot_uv_verts++;
           }
         }
         else if (n_slash == 2) {
           /* Case: f v1//vn1 v2//vn2 v3//vn3 . */
           /* Case: f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 . */
-          Vector<string> vert_tex_normal_split;
-          split_by_char(str_corner, '/', vert_tex_normal_split);
-          copy_string_to_int(vert_tex_normal_split[0], corner.vert_index);
-          if (vert_tex_normal_split.size() == 3) {
-            copy_string_to_int(vert_tex_normal_split[1], corner.tex_vert_index);
+          Vector<string> vert_uv_normal_split;
+          split_by_char(str_corner, '/', vert_uv_normal_split);
+          copy_string_to_int(vert_uv_normal_split[0], corner.vert_index);
+          if (vert_uv_normal_split.size() == 3) {
+            copy_string_to_int(vert_uv_normal_split[1], corner.uv_vert_index);
             (*curr_ob)->tot_uv_verts++;
           }
           /* Discard normals. They'll be calculated on the basis of smooth
            * shading flag. */
         }
-        corner.vert_index -= index_offsets[VERTEX_OFF] + 1;
-        corner.tex_vert_index -= index_offsets[UV_VERTEX_OFF] + 1;
+        corner.vert_index += corner.vert_index < 0 ? index_offsets[VERTEX_OFF] + 1 :
+                                                     -(index_offsets[VERTEX_OFF] + 1);
+        corner.uv_vert_index += corner.uv_vert_index < 0 ? index_offsets[UV_VERTEX_OFF] + 1 :
+                                                           -(index_offsets[UV_VERTEX_OFF] + 1);
 
         curr_face.face_corners.append(corner);
       }
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
index 7fb7f7d6006..f3fe3a9e092 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
@@ -37,11 +37,14 @@ class OBJImporter {
  public:
   OBJImporter(const OBJImportParams &import_params);
 
-  void parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_objects);
-  void print_obj_data(Vector<std::unique_ptr<OBJRawObject>> &list_of_objects);
+  void parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_objects,
+                       GlobalVertices &global_vertices);
+  void print_obj_data(Vector<std::unique_ptr<OBJRawObject>> &list_of_objects,
+                      const GlobalVertices &global_vertices);
   void raw_to_blender_objects(Main *bmain,
                               Scene *scene,
-                              Vector<std::unique_ptr<OBJRawObject>> &list_of_objects);
+                              Vector<std::unique_ptr<OBJRawObject>> &list_of_objects,
+                              const GlobalVertices global_vertices);
 };
 
 }  // namespace blender::io::obj
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.cc
index b88b8a52d0c..6150efdf149 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.cc
@@ -35,16 +35,19 @@
 #include "wavefront_obj_im_objects.hh"
 
 namespace blender::io::obj {
-OBJMeshFromRaw::OBJMeshFromRaw(const OBJRawObject &curr_object)
+OBJMeshFromRaw::OBJMeshFromRaw(const OBJRawObject &curr_object,
+                               const GlobalVertices global_vertices)
 {
-  uint tot_verts_object{curr_object.vertices.size()};
+  uint tot_verts_object{curr_object.vertex_indices.size()};
   uint tot_edges{curr_object.edges.size()};
   uint tot_face_elems{curr_object.face_elements.size()};
   mesh_from_ob_.reset(
       BKE_mesh_new_nomain(tot_verts_object, tot_edges, 0, curr_object.tot_loop, tot_face_elems));
 
   for (int i = 0; i < tot_verts_object; ++i) {
-    copy_v3_v3(mesh_from_ob_->mvert[i].co, curr_object.vertices[i].co);
+    /* Current object's vertex indices index into global list of vertex coordinates. */
+    copy_v3_v3(mesh_from_ob_->mvert[i].co,
+               global_vertices.vertices[curr_object.vertex_indices[i]]);
   }
 
   int tot_loop_idx = 0;
@@ -76,7 +79,7 @@ OBJMeshFromRaw::OBJMeshFromRaw(const OBJRawObject &curr_object)
   BKE_mesh_calc_edges_loose(mesh_from_ob_.get());
 
   /* TODO ankitm merge the face iteration loops. Kept separate for ease of debugging. */
-  if (curr_object.tot_uv_verts > 0 && curr_object.texture_vertices.size() > 0) {
+  if (curr_object.tot_uv_verts > 0 && curr_object.uv_vertex_indices.size() > 0) {
     MLoopUV *mluv_dst = (MLoopUV *)CustomData_add_layer(&mesh_from_ob_->ldata,
                                                         CD_MLOOPUV,
                                                         CD_DUPLICATE,
@@ -85,12 +88,15 @@ OBJMeshFromRaw::OBJMeshFromRaw(const OBJRawObject &curr_object)
     int tot_loop_idx = 0;
     for (const OBJFaceElem &curr_face : curr_object.face_elements) {
       for (const OBJFaceCorner &curr_corner : curr_face.face_corners) {
-        if (curr_corner.tex_vert_index < 0 ||
-            curr_corner.tex_vert_index >= curr_object.tot_uv_verts) {
+        if (curr_corner.uv_vert_index < 0 ||
+            curr_corner.uv_vert_index >= curr_object.tot_uv_verts) {
           continue;
         }
-        const MLoopUV *mluv_src = &curr_object.texture_vertices[curr_corner.tex_vert_index];
-        copy_v2_v2(mluv_dst[tot_loop_idx].uv, mluv_src->uv);
+        /* Current corner's UV vertex index indices into current object's UV vertex indices, which
+         * index into global list of UV vertex coordinates. */
+        const float2 &mluv_src =
+            global_vertices.uv_vertices[curr_object.uv_vertex_indices[curr_corner.uv_vert_index]];
+        copy_v2_v2(mluv_dst[tot_loop_idx].uv, mluv_src);
         tot_loop_idx++;
       }
     }
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.hh
index f7c956fa914..52db31d9d36 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.hh
+++ b/source/

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list