[Bf-blender-cvs] [f2a1a66b8c9] soc-2020-io-performance: Refactor: arrange the code in OOP style.

Ankit Meel noreply at git.blender.org
Mon Jun 22 21:03:37 CEST 2020


Commit: f2a1a66b8c900720acff21727809f4ec005c4146
Author: Ankit Meel
Date:   Mon Jun 22 13:22:14 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rBf2a1a66b8c900720acff21727809f4ec005c4146

Refactor: arrange the code in OOP style.

The OBJWriter class' one instance writes to one file.
All OBJWriter handles is writing to the file after calling functions
of OBJMesh which collect the required data.

OBJNurbs and OBJMaterial will be added soon too.

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

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
M	source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.hh

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

diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
index a9a2cfd6d86..eb1aa6d58dd 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
@@ -21,9 +21,8 @@
 #ifndef __WAVEFRONT_OBJ_HH__
 #define __WAVEFRONT_OBJ_HH__
 
-#include <stdio.h>
-
 #include "BKE_context.h"
+#include "BKE_mesh.h"
 #include "BKE_object.h"
 
 #include "BLI_array.hh"
@@ -33,6 +32,8 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 
+#include "IO_wavefront_obj.h"
+
 namespace io {
 namespace obj {
 
@@ -41,72 +42,71 @@ namespace obj {
 /* Z */
 #define DEFAULT_AXIS_UP 2
 
-/**
- * Polygon stores the data of one face of the mesh.
- * f v1/vt1/vn1 v2/vt2/vn2 .. (n)
- */
-struct Polygon {
-  /** Total vertices in one polgon face. n above. */
-  uint total_vertices_per_poly;
-  /**
-   * Vertex indices of this polygon. v1, v2 .. above.
-   */
-  std::vector<uint> vertex_index;
-  /**
-   * UV vertex indices of this polygon. vt1, vt2 .. above.
-   */
-  std::vector<uint> uv_vertex_index;
-};
-
-/**
- * Stores geometry of one mesh object to be exported.
- */
-typedef struct OBJ_obmesh_to_export {
+class OBJMesh {
+ public:
+  const OBJExportParams *export_params;
   bContext *C;
-  Depsgraph *depsgraph;
+
   Object *object;
+  Mesh *me_eval;
+  /** For curves and triangulated meshes, a new mesh is allocated which needs to be freed later. */
+  bool me_eval_needs_free = false;
 
-  /** Vertices in a mesh to export. */
-  MVert *mvert;
-  /** Number of vertices in a mesh to export. */
+  /** Total vertices in a mesh. */
   uint tot_vertices;
-
-  /** Polygons in a mesh to export. */
-  /* TODO (ankitm): Replace vector with BLI::Vector. See D7931 */
-  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. */
+  /** Total polygons (and thus normals) in a mesh. */
+  uint tot_poly_normals;
+  /** Total UV vertices in a mesh's texture map. */
   uint tot_uv_vertices;
+  /** Only for curve-like meshes: total edges in a mesh. */
+  uint tot_edges;
+  /** Final transform of an object obtained from export settings (up_axis, forward_axis) and world
+   * transform matrix.
+   */
+  float world_and_axes_transform[4][4];
 
-  int forward_axis;
-  int up_axis;
-  float scaling_factor;
-} OBJ_obmesh_to_export;
-
-typedef struct OBJ_obcurve_to_export {
-  bContext *C;
-  Depsgraph *depsgraph;
-  Object *object;
-
-  /** Vertices in a mesh made from a curve to export. */
-  MVert *mvert;
-  /** Number of vertices in a curve to export. */
-  uint tot_vertices;
+  /**
+   * Store evaluated object and mesh pointers depending on object type.
+   * New meshes are created for curves and triangulated meshes.
+   */
+  void get_mesh_eval();
+  /**
+   * Store the product of export axes settings and an object's world transform matrix in
+   * world_and_axes_transform[4][4].
+   */
+  void store_world_axes_transform();
+  /**
+   * Calculate coordinates of the vertex at given index.
+   */
+  void calc_vertex_coords(float coords[3], uint vert_index);
+  /**
+   * Calculate vertex indices of all vertices of a polygon.
+   */
+  void calc_poly_vertex_indices(std::vector<uint> &poly_vertex_indices, uint poly_index);
+  /**
+   * Store UV vertex coordinates as well as their indices.
+   */
+  void store_uv_coords_and_indices(std::vector<std::array<float, 2>> &uv_coords,
+                                   std::vector<std::vector<uint>> &uv_indices);
+  /**
+   * Calculate face normal of the polygon at given index.
+   */
+  void calc_poly_normal(float poly_normal[3], uint poly_index);
+  /**
+   * Calculate face normal indices of all polygons.
+   */
+  void calc_poly_normal_indices(std::vector<uint> &normal_indices, uint poly_indices);
+  /**
+   * Only for curve-like meshes: calculate vertex indices of one edge.
+   */
+  void calc_edge_vert_indices(std::array<uint, 2> &vert_indices, uint edge_index);
+};
 
-  /** Vertex indices of an edge of a mesh made from a curve. */
-  std::vector<std::array<uint, 2>> edge_vert_indices;
-  /** Number of edges in a curve to export. */
-  uint tot_edges;
+class OBJNurbs {
+  /*TODO ankitm to be done*/
+ public:
+};
 
-  int forward_axis;
-  int up_axis;
-  float scaling_factor;
-  bool export_curves_as_nurbs;
-} OBJ_obcurve_to_export;
 }  // 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 2e12f8a4ad4..892e460ffa1 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
@@ -60,78 +60,54 @@ namespace io {
 namespace obj {
 
 /**
- * Store the mesh vertex coordinates in obmesh, in world coordinates.
+ * Store the product of export axes settings and an object's world transform matrix in
+ * world_and_axes_transform[4][4].
  */
-static void store_transformed_mesh_vertices(const Mesh *me_eval,
-                                            const Object *ob_eval,
-                                            OBJ_obmesh_to_export &ob_mesh)
+void OBJMesh::store_world_axes_transform()
 {
-  uint num_verts = ob_mesh.tot_vertices = me_eval->totvert;
   float axes_transform[3][3];
   unit_m3(axes_transform);
   mat3_from_axis_conversion(DEFAULT_AXIS_FORWARD,
                             DEFAULT_AXIS_UP,
-                            ob_mesh.forward_axis,
-                            ob_mesh.up_axis,
+                            export_params->forward_axis,
+                            export_params->up_axis,
                             axes_transform);
-
-  float world_transform[4][4];
-  copy_m4_m4(world_transform, ob_eval->obmat);
-  mul_m4_m3m4(world_transform, axes_transform, world_transform);
-  for (uint i = 0; i < num_verts; i++) {
-    copy_v3_v3(ob_mesh.mvert[i].co, me_eval->mvert[i].co);
-    mul_m4_v3(world_transform, ob_mesh.mvert[i].co);
-    mul_v3_fl(ob_mesh.mvert[i].co, ob_mesh.scaling_factor);
-  }
+  mul_m4_m3m4(world_and_axes_transform, axes_transform, object->obmat);
+  /* mul_m4_m3m4 does not copy last row of obmat, i.e. location data. */
+  copy_v4_v4(world_and_axes_transform[3], object->obmat[3]);
 }
 
 /**
- * Store the mesh's per-face per-vertex normals in ob_mesh, in world coordinates.
+ * Calculate coordinates of the vertex at given index.
  */
-static void store_transformed_vertex_normals(Mesh *me_eval,
-                                             const Object *ob_eval,
-                                             OBJ_obmesh_to_export &ob_mesh)
+void OBJMesh::calc_vertex_coords(float coords[3], uint vert_index)
 {
-  BKE_mesh_ensure_normals(me_eval);
-  float transformed_normal[3];
-  for (uint i = 0; i < me_eval->totvert; i++) {
-    normal_short_to_float_v3(transformed_normal, me_eval->mvert[i].no);
-    mul_mat3_m4_v3(ob_eval->obmat, transformed_normal);
-    normal_float_to_short_v3(ob_mesh.mvert[i].no, transformed_normal);
-  }
+  copy_v3_v3(coords, me_eval->mvert[vert_index].co);
+  mul_m4_v3(world_and_axes_transform, coords);
+  mul_v3_fl(coords, export_params->scaling_factor);
 }
 
 /**
- * Store the vertex indices of all loops in all polygons of a mesh.
+ * Calculate vertex indices of all vertices of a polygon.
  */
-static void store_polygon_vert_indices(const Mesh *me_eval, OBJ_obmesh_to_export &ob_mesh)
+void OBJMesh::calc_poly_vertex_indices(std::vector<uint> &poly_vertex_indices, uint poly_index)
 {
-  const MLoop *mloop;
-  const MPoly *mpoly = me_eval->mpoly;
-
-  ob_mesh.tot_poly = me_eval->totpoly;
-  ob_mesh.polygon_list.resize(me_eval->totpoly);
-
-  for (uint poly_index = 0; poly_index < me_eval->totpoly; poly_index++, mpoly++) {
-    mloop = &me_eval->mloop[mpoly->loopstart];
-    Polygon &poly = ob_mesh.polygon_list[poly_index];
-
-    poly.total_vertices_per_poly = mpoly->totloop;
-    poly.vertex_index.resize(mpoly->totloop);
-
-    for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) {
-      /* mloop->v is 0-based index. Indices in OBJ start from 1. */
-      poly.vertex_index[loop_index] = (mloop + loop_index)->v + 1;
-    }
+  const MPoly &mpoly = me_eval->mpoly[poly_index];
+  const MLoop *mloop = &me_eval->mloop[mpoly.loopstart];
+  poly_vertex_indices.resize(mpoly.totloop);
+  for (uint loop_index = 0; loop_index < mpoly.totloop; loop_index++) {
+    poly_vertex_indices[loop_index] = (mloop + loop_index)->v + 1;
   }
 }
 
 /**
- * Store UV vertex coordinates in ob_mesh.uv_coords as well as their indices, in
- * a polygon[i].uv_vertex_index.
+ * Store UV vertex coordinates as well as their indices.
  */
-static void store_uv_coordinates(Mesh *me_eval, OBJ_obmesh_to_export &ob_mesh)
+void OBJMesh::store_uv_coords_and_indices(std::vector<std::array<float, 2>> &uv_coords,
+                                          std::vector<std::vector<uint>> &uv_indices)
 {
+  Mesh *me_eval = this->me_eval;
+  OBJMesh *ob_mesh = this;
   const CustomData *ldata = &me_eval->ldata;
 
   for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) {
@@ -144,100 +120,115 @@ static void store_uv_coordinates(Mesh *me_eval, OBJ_obmesh_to_export &ob_mesh)
     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);
 
-    ob_mesh.tot_uv_vertices = -1;
+    uv_indices.resize(me_eval->totpoly);
+    /* TODO ankitm check if pre-emptively reserving space for uv coords improves timing or not.
+     * It is guaranteed that there will be at least me_eval->totvert vertices.
+     */
+    ob_mesh->tot_uv_vertices = -1;
+
     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_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list