[Bf-blender-cvs] [5e9196ed11e] soc-2020-io-performance: Parse UV coordinates and normals.

Ankit Meel noreply at git.blender.org
Wed Jul 15 00:33:02 CEST 2020


Commit: 5e9196ed11eb483ac2171047c410731681da376a
Author: Ankit Meel
Date:   Wed Jul 15 03:12:35 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB5e9196ed11eb483ac2171047c410731681da376a

Parse UV coordinates and normals.

Adding UV to the mesh is not done yet.
Using `std:stoi` seems to add some benefits, so UVs will be added
to mesh after parser is complete.

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

M	source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_im_mesh.cc
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 c2d9245626d..82a3831844d 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
@@ -26,11 +26,11 @@
 
 #include "BKE_context.h"
 
-#include "BLI_vector.hh"
 #include "BLI_string_ref.hh"
+#include "BLI_vector.hh"
 
-#include "wavefront_obj_im_file_reader.hh"
 #include "wavefront_obj_ex_file_writer.hh"
+#include "wavefront_obj_im_file_reader.hh"
 
 namespace blender::io::obj {
 
@@ -39,6 +39,15 @@ OBJImporter::OBJImporter(const OBJImportParams &import_params) : import_params_(
   infile_.open(import_params_.filepath);
 }
 
+static void split_by_char(std::string in_string, char delimiter, Vector<std::string> &r_out_list)
+{
+  std::stringstream stream(in_string);
+  std::string word{};
+  while (std::getline(stream, word, delimiter)) {
+    r_out_list.append(word);
+  }
+}
+
 void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_objects)
 {
   std::string line;
@@ -76,24 +85,41 @@ void OBJImporter::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of
       (*curr_ob)->texture_vertices.append(curr_tex_vert);
     }
     else if (line_key == "f") {
-      Vector<OBJFaceCorner> curr_face;
-      while (s_line) {
+      OBJFaceElem curr_face;
+      std::string str_corners_line = s_line.str();
+      Vector<std::string> str_corners_split;
+      split_by_char(str_corners_line, ' ', str_corners_split);
+      for (auto str_corner : str_corners_split) {
+        if (str_corner == "f") {
+          /* Hack, since that's how streams change to strings. Ideally the line_key should be a
+           * string and then a stream is made from the rest of the line. */
+          continue;
+        }
         OBJFaceCorner corner;
-        if (!(s_line >> corner.vert_index)) {
-          break;
+        size_t n_slash = std::count(str_corner.begin(), str_corner.end(), '/');
+        if (n_slash == 0) {
+          corner.vert_index = std::stoi(str_corner);
         }
-        /* Base 1 in OBJ to base 0 in C++. */
-        corner.vert_index--;
-        /* Adjust for index offset of previous objects. */
-        corner.vert_index -= index_offsets[VERTEX_OFF];
+        else if (n_slash == 1) {
+          Vector<std::string> vert_texture;
+          split_by_char(str_corner, '/', vert_texture);
+          corner.vert_index = std::stoi(vert_texture[0]);
+          corner.tex_vert_index = vert_texture[1].empty() ? -1 : std::stoi(vert_texture[1]);
+        }
+        else if (n_slash == 2) {
+          Vector<std::string> vert_normal;
+          split_by_char(str_corner, '/', vert_normal);
+          corner.vert_index = std::stoi(vert_normal[0]);
+          /* 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;
 
-        // TODO texture coords handling. It's mostly string manipulation. Normal indices will be
-        // ignored and calculated depending on the smooth flag.
-        // s_line >> corner.tex_vert_index;
-        curr_face.append(corner);
+        curr_face.face_corners.append(corner);
       }
+
       (*curr_ob)->face_elements.append(curr_face);
-      (*curr_ob)->tot_loop += curr_face.size();
+      (*curr_ob)->tot_loop += curr_face.face_corners.size();
     }
     else if (line_key == "usemtl") {
       (*curr_ob)->material_name.append(s_line.str());
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 1221fc2d0a4..ecc870ef51a 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
@@ -41,14 +41,14 @@ OBJMeshFromRaw::OBJMeshFromRaw(const class OBJRawObject &curr_object)
 
   int curr_loop_idx = 0;
   for (int i = 0; i < curr_object.face_elements.size(); ++i) {
-    const Vector<OBJFaceCorner> &curr_face = curr_object.face_elements[i];
+    const OBJFaceElem &curr_face = curr_object.face_elements[i];
     MPoly &mpoly = mesh_from_bm_->mpoly[i];
-    mpoly.totloop = curr_face.size();
+    mpoly.totloop = curr_face.face_corners.size();
     mpoly.loopstart = curr_loop_idx;
 
-    for (int j = 0; j < curr_face.size(); ++j) {
+    for (int j = 0; j < mpoly.totloop; ++j) {
       MLoop *mloop = &mesh_from_bm_->mloop[curr_loop_idx];
-      mloop->v = curr_face[j].vert_index;
+      mloop->v = curr_face.face_corners[j].vert_index;
       curr_loop_idx++;
     }
   }
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
index 6cd4702909c..d432aca2f51 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
@@ -35,9 +35,16 @@
 namespace blender::io::obj {
 typedef struct OBJFaceCorner {
   int vert_index;
+  /* -1 is to indicate abscense of UV vertices. Only < 0 condition should be checked since
+   * it can be less than -1 too. */
   int tex_vert_index = -1;
 } OBJFaceCorner;
 
+typedef struct OBJFaceElem {
+  bool shaded_smooth = false;
+  Vector<OBJFaceCorner> face_corners;
+} OBJFaceElem;
+
 class OBJRawObject {
  public:
   OBJRawObject(StringRef ob_name) : object_name(ob_name.data()){};
@@ -45,10 +52,9 @@ class OBJRawObject {
   std::string object_name;
   Vector<MVert> vertices;
   Vector<MLoopUV> texture_vertices;
-  Vector<Vector<OBJFaceCorner>> face_elements;
+  Vector<OBJFaceElem> face_elements;
   uint tot_normals = 0;
   uint tot_loop = 0;
-  bool is_shaded_smooth;
   Vector<std::string> material_name;
 };
 
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
index 51d3ef88a57..c563d3bb21f 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
@@ -50,9 +50,9 @@ void OBJImporter::print_obj_data(Vector<std::unique_ptr<OBJRawObject>> &list_of_
       print_v2("tex vert", curr_tex_vert.uv);
     }
     printf("\n");
-    for (const Vector<OBJFaceCorner> &curr_face : curr_ob->face_elements) {
-      for (OBJFaceCorner a : curr_face) {
-        printf("%d ", a.vert_index);
+    for (const OBJFaceElem &curr_face : curr_ob->face_elements) {
+      for (OBJFaceCorner a : curr_face.face_corners) {
+        printf("%d %d ", a.vert_index, a.tex_vert_index);
       }
       printf("\n");
     }



More information about the Bf-blender-cvs mailing list