[Bf-blender-cvs] [f01a7d508d0] soc-2020-io-performance: Export UV vertex coordinates & their indices.

Ankit Meel noreply at git.blender.org
Thu Jun 11 17:46:38 CEST 2020


Commit: f01a7d508d0d5ba9e3949c18d6c713506efbabd7
Author: Ankit Meel
Date:   Thu Jun 11 21:12:40 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rBf01a7d508d0d5ba9e3949c18d6c713506efbabd7

Export UV vertex coordinates & their indices.

This commit adds support for UV vertex coordinates in the form:
`vt u v` for all vertices in the texture map.

Also, their indices are exported as per file format specification [1,2]
`f */vt1/* */vt2/*` for all polygons.

The text written by this and the python exporter has different order
of coordinates and thus their indices too. So direct diff of the two
files will not work.

Minor comments about 0-based/ 1-based indices are also added.

[1]: https://en.wikipedia.org/wiki/Wavefront_.obj_file#File_format
[2]: http://www.martinreddy.net/gfx/3d/OBJ.spec

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

M	source/blender/io/wavefront_obj/intern/wavefront_obj.hh
M	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc

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

diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
index 0ad0279b6c4..1d7b3cb12be 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
@@ -47,6 +47,10 @@ struct Polygon {
    * The index corresponds to the pre-defined vertex list.
    */
   std::vector<uint> vertex_index;
+  /**
+   * UV vertex indices of this polygon. vt1, vt2 .. above.
+   */
+  std::vector<uint> uv_vertex_index;
 };
 
 /**
@@ -68,6 +72,11 @@ struct OBJ_data_to_export {
   std::vector<Polygon> polygon_list;
   /** Number of polygons in a mesh to export. */
   uint tot_poly;
+
+  /** UV vertex coordinates of a mesh in texture map. */
+  std::vector<std::array<float, 2>> uv_coords;
+  /** Number of UV vertices of a mesh in texture map. */
+  uint tot_uv_vertices;
 };
 }  // namespace obj
 }  // namespace io
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
index a764f369740..06847604e92 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
@@ -27,6 +27,7 @@
 #include <vector>
 
 #include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_scene.h"
 
@@ -100,10 +101,65 @@ static void get_polygon_vert_indices(Mesh *me_eval, OBJ_data_to_export *data_to_
     data_to_export->polygon_list[i].vertex_index.resize(mpoly->totloop);
 
     for (int j = 0; j < mpoly->totloop; j++) {
+      /* mloop->v is 0-based index. Indices in OBJ start from 1. */
       data_to_export->polygon_list[i].vertex_index[j] = (mloop + j)->v + 1;
     }
   }
 }
+/**
+ * Store UV vertex coordinates in data_to_export->uv_coords as well as their indices, in
+ * a polygon[i].uv_vertex_index.
+ */
+static void get_uv_coordinates(Mesh *me_eval, OBJ_data_to_export *data_to_export)
+{
+  const CustomData *ldata = &me_eval->ldata;
+
+  for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) {
+    const CustomDataLayer *layer = &ldata->layers[layer_idx];
+    if (layer->type != CD_MLOOPUV) {
+      continue;
+    }
+
+    const MPoly *mpoly = me_eval->mpoly;
+    const MLoop *mloop = me_eval->mloop;
+    const MLoopUV *mloopuv = static_cast<MLoopUV *>(layer->data);
+    const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
+
+    UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
+        mpoly, mloop, mloopuv, me_eval->totpoly, me_eval->totvert, limit, false, false);
+
+    data_to_export->tot_uv_vertices = 0;
+    for (int vertex_index = 0; vertex_index < me_eval->totvert; vertex_index++) {
+      const UvMapVert *uv_vert = BKE_mesh_uv_vert_map_get_vert(uv_vert_map, vertex_index);
+      while (uv_vert != NULL) {
+        if (uv_vert->separate) {
+          data_to_export->tot_uv_vertices++;
+        }
+        Polygon &polygon_of_uv_vert = data_to_export->polygon_list[uv_vert->poly_index];
+        const uint vertices_in_poly = polygon_of_uv_vert.total_vertices_per_poly;
+        /* Resize UV vertices index list. */
+        polygon_of_uv_vert.uv_vertex_index.resize(vertices_in_poly);
+
+        /* Fill up UV vertex index for current polygon's one vertex. */
+        polygon_of_uv_vert.uv_vertex_index[uv_vert->loop_of_poly_index] =
+            data_to_export->tot_uv_vertices;
+
+        /* Fill up UV vertices' coordinates. We don't know how many unique vertices are there, so
+         * need to push back everytime. */
+        data_to_export->uv_coords.push_back(std::array<float, 2>());
+        data_to_export->uv_coords[data_to_export->tot_uv_vertices][0] =
+            mloopuv[mpoly[uv_vert->poly_index].loopstart + uv_vert->loop_of_poly_index].uv[0];
+        data_to_export->uv_coords[data_to_export->tot_uv_vertices][1] =
+            mloopuv[mpoly[uv_vert->poly_index].loopstart + uv_vert->loop_of_poly_index].uv[1];
+
+        uv_vert = uv_vert->next;
+      }
+    }
+    BKE_mesh_uv_vert_map_free(uv_vert_map);
+    /* No need to go over other layers. */
+    break;
+  }
+}
 
 static void get_geometry_per_object(const OBJExportParams *export_params,
                                     OBJ_data_to_export *data_to_export)
@@ -116,6 +172,7 @@ static void get_geometry_per_object(const OBJExportParams *export_params,
   get_transformed_mesh_vertices(me_eval, ob_eval, data_to_export);
   get_transformed_vertex_normals(me_eval, ob_eval, data_to_export);
   get_polygon_vert_indices(me_eval, data_to_export);
+  get_uv_coordinates(me_eval, data_to_export);
 }
 
 /**
@@ -131,8 +188,8 @@ void exporter_main(bContext *C, const OBJExportParams *export_params)
   get_geometry_per_object(export_params, &data_to_export);
 
   /* Comment out either one of the following. */
-  write_obj_data(filepath, &data_to_export);
-  //  write_obj_data_in_fprintf(filepath, &data_to_export);
+  //  write_obj_data(filepath, &data_to_export);
+  write_obj_data_fprintf(filepath, &data_to_export);
   MEM_freeN(data_to_export.mvert);
 }
 }  // namespace obj
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
index 291b14a6bd6..359c4df0c4c 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
@@ -72,6 +72,14 @@ void write_obj_data(const char *filepath, OBJ_data_to_export *data_to_export)
     outfile << vertex->co[0] << " " << vertex->co[1] << " " << vertex->co[2] << "\n";
   }
 
+  /**
+   * Write texture coordinates, vt u v for all vertices in a object's texture space.
+   */
+  for (uint i = 0; i < data_to_export->tot_uv_vertices; i++) {
+    std::array<float, 2> &uv_vertex = data_to_export->uv_coords[i];
+    outfile << "vt " << uv_vertex[0] << " " << uv_vertex[1] << "\n";
+  }
+
   /** Write vn nx ny nz for all face normals. */
   for (uint i = 0; i < data_to_export->tot_poly; i++) {
     MVert *vertex_list = data_to_export->mvert;
@@ -90,7 +98,9 @@ void write_obj_data(const char *filepath, OBJ_data_to_export *data_to_export)
     const Polygon &polygon = data_to_export->polygon_list[i];
     outfile << "f ";
     for (int j = 0; j < polygon.total_vertices_per_poly; j++) {
-      outfile << polygon.vertex_index[j] << "//" << i + 1 << " ";
+      /* This loop index is 0-based. Indices in OBJ start from 1. */
+      outfile << polygon.vertex_index[j] << "/" << polygon.uv_vertex_index[j] + 1 << "/" << i + 1
+              << " ";
     }
     outfile << "\n";
   }
@@ -119,6 +129,13 @@ void write_obj_data_fprintf(const char *filepath, OBJ_data_to_export *data_to_ex
     fprintf(outfile, "%f\n", vertex->co[2]);
   }
 
+  for (uint i = 0; i < data_to_export->tot_uv_vertices; i++) {
+    std::array<float, 2> &uv_vertex = data_to_export->uv_coords[i];
+    fprintf(outfile, "vt ");
+    fprintf(outfile, "%f ", uv_vertex[0]);
+    fprintf(outfile, "%f\n", uv_vertex[1]);
+  }
+
   for (uint i = 0; i < data_to_export->tot_poly; i++) {
     MVert *vertex_list = data_to_export->mvert;
     const Polygon &polygon = data_to_export->polygon_list[i];
@@ -132,7 +149,9 @@ void write_obj_data_fprintf(const char *filepath, OBJ_data_to_export *data_to_ex
     const Polygon &polygon = data_to_export->polygon_list[i];
     fprintf(outfile, "f ");
     for (int j = 0; j < polygon.total_vertices_per_poly; j++) {
-      fprintf(outfile, "%d//%d ", polygon.vertex_index[j], i + 1);
+      /* This loop index is 0-based. Indices in OBJ start from 1. */
+      fprintf(
+          outfile, "%d/%d/%d ", polygon.vertex_index[j], polygon.uv_vertex_index[j] + 1, i + 1);
     }
     fprintf(outfile, "\n");
   }



More information about the Bf-blender-cvs mailing list