[Bf-blender-cvs] [a5f9f7e2fc3] master: OBJ: Avoid retrieving mesh arrays, improve const correctness

Hans Goudey noreply at git.blender.org
Tue Dec 6 22:26:53 CET 2022


Commit: a5f9f7e2fc3084961285642f8bcb23ba9b9cc804
Author: Hans Goudey
Date:   Tue Dec 6 15:26:42 2022 -0600
Branches: master
https://developer.blender.org/rBa5f9f7e2fc3084961285642f8bcb23ba9b9cc804

OBJ: Avoid retrieving mesh arrays, improve const correctness

Store the potentially owned mesh separately from the original/evaluated
mesh which is now stored with a const pointer. Also store mesh spans
separately in the class so they don't have to be retrieved for every
index.

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

M	source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
M	source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
M	source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh

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

diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
index b8d03cfac65..599357ece37 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
@@ -250,7 +250,7 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
 {
   const int tot_count = obj_mesh_data.tot_vertices();
 
-  Mesh *mesh = obj_mesh_data.get_mesh();
+  const Mesh *mesh = obj_mesh_data.get_mesh();
   const CustomDataLayer *colors_layer = nullptr;
   if (write_colors) {
     colors_layer = BKE_id_attributes_active_color_get(&mesh->id);
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
index 8519fb97217..86518bd09f2 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
@@ -33,21 +33,23 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
   /* We need to copy the object because it may be in temporary space. */
   Object *obj_eval = DEG_get_evaluated_object(depsgraph, mesh_object);
   export_object_eval_ = dna::shallow_copy(*obj_eval);
-  export_mesh_eval_ = export_params.apply_modifiers ?
-                          BKE_object_get_evaluated_mesh(&export_object_eval_) :
-                          BKE_object_get_pre_modified_mesh(&export_object_eval_);
-  mesh_eval_needs_free_ = false;
-
-  if (!export_mesh_eval_) {
+  export_mesh_ = export_params.apply_modifiers ?
+                     BKE_object_get_evaluated_mesh(&export_object_eval_) :
+                     BKE_object_get_pre_modified_mesh(&export_object_eval_);
+  if (export_mesh_) {
+    mesh_verts_ = export_mesh_->verts();
+    mesh_edges_ = export_mesh_->edges();
+    mesh_polys_ = export_mesh_->polys();
+    mesh_loops_ = export_mesh_->loops();
+  }
+  else {
     /* Curves and NURBS surfaces need a new mesh when they're
      * exported in the form of vertices and edges.
      */
-    export_mesh_eval_ = BKE_mesh_new_from_object(depsgraph, &export_object_eval_, true, true);
-    /* Since a new mesh been allocated, it needs to be freed in the destructor. */
-    mesh_eval_needs_free_ = true;
+    this->set_mesh(BKE_mesh_new_from_object(depsgraph, &export_object_eval_, true, true));
   }
   if (export_params.export_triangulated_mesh && export_object_eval_.type == OB_MESH) {
-    std::tie(export_mesh_eval_, mesh_eval_needs_free_) = triangulate_mesh_eval();
+    this->triangulate_mesh_eval();
   }
   set_world_axes_transform(export_params.forward_axis, export_params.up_axis);
 }
@@ -60,18 +62,26 @@ OBJMesh::~OBJMesh()
   clear();
 }
 
-void OBJMesh::free_mesh_if_needed()
+void OBJMesh::set_mesh(Mesh *mesh)
 {
-  if (mesh_eval_needs_free_ && export_mesh_eval_) {
-    BKE_id_free(nullptr, export_mesh_eval_);
-    export_mesh_eval_ = nullptr;
-    mesh_eval_needs_free_ = false;
+  if (owned_export_mesh_) {
+    BKE_id_free(nullptr, owned_export_mesh_);
   }
+  owned_export_mesh_ = mesh;
+  export_mesh_ = owned_export_mesh_;
+  mesh_verts_ = mesh->verts();
+  mesh_edges_ = mesh->edges();
+  mesh_polys_ = mesh->polys();
+  mesh_loops_ = mesh->loops();
 }
 
 void OBJMesh::clear()
 {
-  free_mesh_if_needed();
+  if (owned_export_mesh_) {
+    BKE_id_free(nullptr, owned_export_mesh_);
+    owned_export_mesh_ = nullptr;
+  }
+  export_mesh_ = nullptr;
   uv_indices_.clear_and_make_inline();
   uv_coords_.clear_and_make_inline();
   loop_to_normal_index_.clear_and_make_inline();
@@ -83,10 +93,10 @@ void OBJMesh::clear()
   }
 }
 
-std::pair<Mesh *, bool> OBJMesh::triangulate_mesh_eval()
+void OBJMesh::triangulate_mesh_eval()
 {
-  if (export_mesh_eval_->totpoly <= 0) {
-    return {export_mesh_eval_, false};
+  if (export_mesh_->totpoly <= 0) {
+    return;
   }
   const BMeshCreateParams bm_create_params = {false};
   BMeshFromMeshParams bm_convert_params{};
@@ -99,7 +109,7 @@ std::pair<Mesh *, bool> OBJMesh::triangulate_mesh_eval()
    * triangulated here. */
   const int triangulate_min_verts = 4;
 
-  BMesh *bmesh = BKE_mesh_to_bmesh_ex(export_mesh_eval_, &bm_create_params, &bm_convert_params);
+  BMesh *bmesh = BKE_mesh_to_bmesh_ex(export_mesh_, &bm_create_params, &bm_convert_params);
   BM_mesh_triangulate(bmesh,
                       MOD_TRIANGULATE_NGON_BEAUTY,
                       MOD_TRIANGULATE_QUAD_SHORTEDGE,
@@ -108,11 +118,9 @@ std::pair<Mesh *, bool> OBJMesh::triangulate_mesh_eval()
                       nullptr,
                       nullptr,
                       nullptr);
-
-  Mesh *triangulated = BKE_mesh_from_bmesh_for_eval_nomain(bmesh, nullptr, export_mesh_eval_);
+  Mesh *triangulated = BKE_mesh_from_bmesh_for_eval_nomain(bmesh, nullptr, export_mesh_);
   BM_mesh_free(bmesh);
-  free_mesh_if_needed();
-  return {triangulated, true};
+  this->set_mesh(triangulated);
 }
 
 void OBJMesh::set_world_axes_transform(const eIOAxis forward, const eIOAxis up)
@@ -137,12 +145,12 @@ void OBJMesh::set_world_axes_transform(const eIOAxis forward, const eIOAxis up)
 
 int OBJMesh::tot_vertices() const
 {
-  return export_mesh_eval_->totvert;
+  return export_mesh_->totvert;
 }
 
 int OBJMesh::tot_polygons() const
 {
-  return export_mesh_eval_->totpoly;
+  return export_mesh_->totpoly;
 }
 
 int OBJMesh::tot_uv_vertices() const
@@ -152,12 +160,12 @@ int OBJMesh::tot_uv_vertices() const
 
 int OBJMesh::tot_edges() const
 {
-  return export_mesh_eval_->totedge;
+  return export_mesh_->totedge;
 }
 
 int16_t OBJMesh::tot_materials() const
 {
-  return export_mesh_eval_->totcol;
+  return export_mesh_->totcol;
 }
 
 int OBJMesh::tot_normal_indices() const
@@ -175,27 +183,25 @@ int OBJMesh::ith_smooth_group(const int poly_index) const
 
 void OBJMesh::ensure_mesh_normals() const
 {
-  BKE_mesh_calc_normals_split(export_mesh_eval_);
+  /* Const cast can be removed when calculating face corner normals lazily is possible. */
+  BKE_mesh_calc_normals_split(const_cast<Mesh *>(export_mesh_));
 }
 
 void OBJMesh::calc_smooth_groups(const bool use_bitflags)
 {
-  const Span<MEdge> edges = export_mesh_eval_->edges();
-  const Span<MPoly> polys = export_mesh_eval_->polys();
-  const Span<MLoop> loops = export_mesh_eval_->loops();
-  poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(edges.data(),
-                                                   edges.size(),
-                                                   polys.data(),
-                                                   polys.size(),
-                                                   loops.data(),
-                                                   loops.size(),
+  poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.data(),
+                                                   mesh_edges_.size(),
+                                                   mesh_polys_.data(),
+                                                   mesh_polys_.size(),
+                                                   mesh_loops_.data(),
+                                                   mesh_loops_.size(),
                                                    &tot_smooth_groups_,
                                                    use_bitflags);
 }
 
 void OBJMesh::calc_poly_order()
 {
-  const bke::AttributeAccessor attributes = export_mesh_eval_->attributes();
+  const bke::AttributeAccessor attributes = export_mesh_->attributes();
   const VArray<int> material_indices = attributes.lookup_or_default<int>(
       "material_index", ATTR_DOMAIN_FACE, 0);
   if (material_indices.is_single() && material_indices.get_internal_single() == 0) {
@@ -234,8 +240,7 @@ const Material *OBJMesh::get_object_material(const int16_t mat_nr) const
 
 bool OBJMesh::is_ith_poly_smooth(const int poly_index) const
 {
-  const Span<MPoly> polys = export_mesh_eval_->polys();
-  return polys[poly_index].flag & ME_SMOOTH;
+  return mesh_polys_[poly_index].flag & ME_SMOOTH;
 }
 
 const char *OBJMesh::get_object_name() const
@@ -245,7 +250,7 @@ const char *OBJMesh::get_object_name() const
 
 const char *OBJMesh::get_object_mesh_name() const
 {
-  return export_mesh_eval_->id.name + 2;
+  return export_mesh_->id.name + 2;
 }
 
 const char *OBJMesh::get_object_material_name(const int16_t mat_nr) const
@@ -260,8 +265,7 @@ const char *OBJMesh::get_object_material_name(const int16_t mat_nr) const
 float3 OBJMesh::calc_vertex_coords(const int vert_index, const float global_scale) const
 {
   float3 r_coords;
-  const Span<MVert> verts = export_mesh_eval_->verts();
-  copy_v3_v3(r_coords, verts[vert_index].co);
+  copy_v3_v3(r_coords, mesh_verts_[vert_index].co);
   mul_m4_v3(world_and_axes_transform_, r_coords);
   mul_v3_fl(r_coords, global_scale);
   return r_coords;
@@ -269,10 +273,8 @@ float3 OBJMesh::calc_vertex_coords(const int vert_index, const float global_scal
 
 Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const
 {
-  const Span<MPoly> polys = export_mesh_eval_->polys();
-  const Span<MLoop> loops = export_mesh_eval_->loops();
-  const MPoly &mpoly = polys[poly_index];
-  const MLoop *mloop = &loops[mpoly.loopstart];
+  const MPoly &mpoly = mesh_polys_[poly_index];
+  const MLoop *mloop = &mesh_loops_[mpoly.loopstart];
   const int totloop = mpoly.totloop;
   Vector<int> r_poly_vertex_indices(totloop);
   for (int loop_index = 0; loop_index < totloop; loop_index++) {
@@ -283,29 +285,27 @@ Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const
 
 void OBJMesh::store_uv_coords_and_indices()
 {
-  const Span<MPoly> polys = export_mesh_eval_->polys();
-  const Span<MLoop> loops = export_mesh_eval_->loops();
-  const int totvert = export_mesh_eval_->totvert;
+  const int totvert = export_mesh_->totvert;
   const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
-      CustomData_get_layer(&export_mesh_eval_->ldata, CD_MLOOPUV));
+      CustomData_get_layer(&export_mesh_->ldata, CD_MLOOPUV));
   if (!mloopuv) {
     tot_uv_vertices_ = 0;
     return;
   }
   const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
 
-  UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(polys.data(),
+  UvVertMap *

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list