[Bf-blender-cvs] [c34c6d3e25f] master: Mesh: Move runtime data out of DNA

Hans Goudey noreply at git.blender.org
Thu Oct 13 03:56:13 CEST 2022


Commit: c34c6d3e25f2f4d96d124cb5ec43c4392e7de4dc
Author: Hans Goudey
Date:   Wed Oct 12 20:55:26 2022 -0500
Branches: master
https://developer.blender.org/rBc34c6d3e25f2f4d96d124cb5ec43c4392e7de4dc

Mesh: Move runtime data out of DNA

This commit replaces the `Mesh_Runtime` struct embedded in `Mesh`
with `blender::bke::MeshRuntime`. This has quite a few benefits:
- It's possible to use C++ types like `std::mutex`, `Array`,
  `BitVector`, etc. more easily
- Meshes saved in files are slightly smaller
- Copying and writing meshes is a bit more obvious without
  clearing of runtime data, etc.

The first is by far the most important. It will allows us to avoid a
bunch of manual memory management boilerplate that is error-prone and
annoying. It should also simplify future CoW improvements for runtime
data.

This patch doesn't change anything besides changing `mesh.runtime.data`
to `mesh.runtime->data`. The cleanups above will happen separately.

Differential Revision: https://developer.blender.org/D16180

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

M	source/blender/blenkernel/BKE_editmesh_cache.h
M	source/blender/blenkernel/BKE_mesh_runtime.h
M	source/blender/blenkernel/BKE_mesh_types.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/bvhutils.cc
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/blenkernel/intern/editmesh.cc
M	source/blender/blenkernel/intern/mball_tessellate.cc
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/mesh_convert.cc
M	source/blender/blenkernel/intern/mesh_debug.cc
M	source/blender/blenkernel/intern/mesh_iterators.cc
M	source/blender/blenkernel/intern/mesh_normals.cc
M	source/blender/blenkernel/intern/mesh_remap.c
M	source/blender/blenkernel/intern/mesh_runtime.cc
M	source/blender/blenkernel/intern/mesh_tangent.cc
M	source/blender/blenkernel/intern/mesh_wrapper.cc
M	source/blender/blenkernel/intern/modifier.cc
M	source/blender/blenkernel/intern/multires.cc
M	source/blender/blenkernel/intern/object.cc
M	source/blender/blenkernel/intern/object_dupli.cc
M	source/blender/blenkernel/intern/object_update.cc
M	source/blender/blenkernel/intern/paint.cc
M	source/blender/blenkernel/intern/particle.c
M	source/blender/blenkernel/intern/particle_distribute.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/blenkernel/intern/shrinkwrap.cc
M	source/blender/blenkernel/intern/subdiv_ccg.cc
M	source/blender/blenkernel/intern/subdiv_mesh.cc
M	source/blender/blenkernel/intern/subdiv_modifier.cc
M	source/blender/bmesh/intern/bmesh_mesh_convert.cc
M	source/blender/draw/engines/workbench/workbench_engine.c
M	source/blender/draw/intern/draw_cache_extract_mesh.cc
M	source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
M	source/blender/draw/intern/draw_cache_impl_mesh.cc
M	source/blender/draw/intern/draw_cache_impl_subdivision.cc
M	source/blender/draw/intern/draw_manager_data.cc
M	source/blender/draw/intern/draw_manager_text.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh.hh
M	source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
M	source/blender/editors/mesh/editmesh_select.cc
M	source/blender/editors/mesh/editmesh_undo.cc
M	source/blender/editors/physics/particle_edit.c
M	source/blender/editors/physics/particle_object.c
M	source/blender/editors/sculpt_paint/paint_image_proj.c
M	source/blender/editors/sculpt_paint/paint_utils.c
M	source/blender/editors/space_info/info_stats.cc
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc
M	source/blender/editors/space_view3d/view3d_iterators.cc
M	source/blender/editors/transform/transform_snap_object.cc
M	source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
M	source/blender/makesdna/DNA_mesh_types.h
M	source/blender/makesrna/intern/rna_mesh.c
M	source/blender/modifiers/intern/MOD_cast.c
M	source/blender/modifiers/intern/MOD_datatransfer.cc
M	source/blender/modifiers/intern/MOD_multires.cc
M	source/blender/modifiers/intern/MOD_normal_edit.cc
M	source/blender/modifiers/intern/MOD_particlesystem.cc
M	source/blender/modifiers/intern/MOD_remesh.c
M	source/blender/modifiers/intern/MOD_subsurf.cc
M	source/blender/modifiers/intern/MOD_util.cc
M	source/blender/modifiers/intern/MOD_uvproject.cc
M	source/blender/modifiers/intern/MOD_uvwarp.cc
M	source/blender/modifiers/intern/MOD_wave.cc
M	source/blender/modifiers/intern/MOD_weighted_normal.cc
M	source/blender/modifiers/intern/MOD_weightvgedit.cc
M	source/blender/modifiers/intern/MOD_weightvgmix.cc
M	source/blender/modifiers/intern/MOD_weightvgproximity.cc
M	source/blender/render/intern/bake.c

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

diff --git a/source/blender/blenkernel/BKE_editmesh_cache.h b/source/blender/blenkernel/BKE_editmesh_cache.h
index 2640356ccf6..454a07be4e3 100644
--- a/source/blender/blenkernel/BKE_editmesh_cache.h
+++ b/source/blender/blenkernel/BKE_editmesh_cache.h
@@ -11,15 +11,25 @@ extern "C" {
 #endif
 
 struct BMEditMesh;
-struct EditMeshData;
 
-void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, struct EditMeshData *emd);
-void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd);
+typedef struct EditMeshData {
+  /** when set, \a vertexNos, polyNos are lazy initialized */
+  const float (*vertexCos)[3];
 
-void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, struct EditMeshData *emd);
+  /** lazy initialize (when \a vertexCos is set) */
+  float const (*vertexNos)[3];
+  float const (*polyNos)[3];
+  /** also lazy init but don't depend on \a vertexCos */
+  const float (*polyCos)[3];
+} EditMeshData;
+
+void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, EditMeshData *emd);
+void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, EditMeshData *emd);
+
+void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, EditMeshData *emd);
 
 bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
-                                    struct EditMeshData *emd,
+                                    EditMeshData *emd,
                                     float min[3],
                                     float max[3]);
 
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index dfefe125a51..27e04c1a4de 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -9,6 +9,7 @@
  */
 
 //#include "BKE_customdata.h"  /* for eCustomDataMask */
+#include "BKE_mesh_types.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -25,22 +26,11 @@ struct Mesh;
 struct Object;
 struct Scene;
 
-/**
- * \brief Initialize the runtime of the given mesh.
- *
- * Function expects that the runtime is already cleared.
- */
-void BKE_mesh_runtime_init_data(struct Mesh *mesh);
 /**
  * \brief Free all data (and mutexes) inside the runtime of the given mesh.
  */
 void BKE_mesh_runtime_free_data(struct Mesh *mesh);
-/**
- * Clear all pointers which we don't want to be shared on copying the datablock.
- * However, keep all the flags which defines what the mesh is (for example, that
- * it's deformed only, or that its custom data layers are out of date.)
- */
-void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, int flag);
+
 int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
 void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
 /**
@@ -66,6 +56,11 @@ void BKE_mesh_runtime_verttri_from_looptri(struct MVertTri *r_verttri,
                                            const struct MLoopTri *looptri,
                                            int looptri_num);
 
+/** \note Only used for access in C. */
+bool BKE_mesh_is_deformed_only(const struct Mesh *mesh);
+/** \note Only used for access in C. */
+eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh);
+
 /* NOTE: the functions below are defined in DerivedMesh.cc, and are intended to be moved
  * to a more suitable location when that file is removed.
  * They should also be renamed to use conventions from BKE, not old DerivedMesh.cc.
diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h
index 0b879c1dfe9..8f3fee70c7f 100644
--- a/source/blender/blenkernel/BKE_mesh_types.h
+++ b/source/blender/blenkernel/BKE_mesh_types.h
@@ -1,11 +1,33 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later
  * Copyright 2020 Blender Foundation. All rights reserved. */
+
 #pragma once
 
 /** \file
  * \ingroup bke
  */
 
+#ifdef __cplusplus
+
+#  include "BLI_span.hh"
+
+#  include "DNA_customdata_types.h"
+
+#  include "MEM_guardedalloc.h"
+
+struct BVHCache;
+struct EditMeshData;
+struct MLoopTri;
+struct ShrinkwrapBoundaryData;
+struct SubdivCCG;
+struct SubsurfRuntimeData;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef enum eMeshBatchDirtyMode {
   BKE_MESH_BATCH_DIRTY_ALL = 0,
   BKE_MESH_BATCH_DIRTY_SELECT,
@@ -14,3 +36,125 @@ typedef enum eMeshBatchDirtyMode {
   BKE_MESH_BATCH_DIRTY_UVEDIT_ALL,
   BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT,
 } eMeshBatchDirtyMode;
+
+/** #MeshRuntime.wrapper_type */
+typedef enum eMeshWrapperType {
+  /** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
+  ME_WRAPPER_TYPE_MDATA = 0,
+  /** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */
+  ME_WRAPPER_TYPE_BMESH = 1,
+  /** Use subdivision mesh data (#MeshRuntime.mesh_eval). */
+  ME_WRAPPER_TYPE_SUBD = 2,
+} eMeshWrapperType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+
+namespace blender::bke {
+
+/**
+ * \warning Typical access is done via #Mesh::looptris().
+ */
+struct MLoopTri_Store {
+  /* WARNING! swapping between array (ready-to-be-used data) and array_wip
+   * (where data is actually computed)
+   * shall always be protected by same lock as one used for looptris computing. */
+  MLoopTri *array = nullptr;
+  MLoopTri *array_wip = nullptr;
+  int len = 0;
+  int len_alloc = 0;
+};
+
+struct MeshRuntime {
+  /* Evaluated mesh for objects which do not have effective modifiers.
+   * This mesh is used as a result of modifier stack evaluation.
+   * Since modifier stack evaluation is threaded on object level we need some synchronization. */
+  Mesh *mesh_eval = nullptr;
+  void *eval_mutex = nullptr;
+
+  /* A separate mutex is needed for normal calculation, because sometimes
+   * the normals are needed while #eval_mutex is already locked. */
+  void *normals_mutex = nullptr;
+
+  /** Needed to ensure some thread-safety during render data pre-processing. */
+  void *render_mutex = nullptr;
+
+  /** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */
+  EditMeshData *edit_data = nullptr;
+
+  /**
+   * Data used to efficiently draw the mesh in the viewport, especially useful when
+   * the same mesh is used in many objects or instances. See `draw_cache_impl_mesh.cc`.
+   */
+  void *batch_cache = nullptr;
+
+  /** Cache for derived triangulation of the mesh. */
+  MLoopTri_Store looptris;
+
+  /** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
+  BVHCache *bvh_cache = nullptr;
+
+  /** Cache of non-manifold boundary data for Shrinkwrap Target Project. */
+  ShrinkwrapBoundaryData *shrinkwrap_data = nullptr;
+
+  /** Needed in case we need to lazily initialize the mesh. */
+  CustomData_MeshMasks cd_mask_extra = {};
+
+  SubdivCCG *subdiv_ccg = nullptr;
+  int subdiv_ccg_tot_level = 0;
+
+  /** Set by modifier stack if only deformed from original. */
+  bool deformed_only = false;
+  /**
+   * Copied from edit-mesh (hint, draw with edit-mesh data when true).
+   *
+   * Modifiers that edit the mesh data in-place must set this to false
+   * (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
+   * data will be used for drawing, missing changes from modifiers. See T79517.
+   */
+  bool is_original_bmesh = false;
+
+  /** #eMeshWrapperType and others. */
+  eMeshWrapperType wrapper_type = ME_WRAPPER_TYPE_MDATA;
+  /**
+   * A type mask from wrapper_type,
+   * in case there are differences in finalizing logic between types.
+   */
+  eMeshWrapperType wrapper_type_finalize = ME_WRAPPER_TYPE_MDATA;
+
+  /**
+   * Settings for lazily evaluating the subdivision on the CPU if needed. These are
+   * set in the modifier when GPU subdivision can be performed, and owned by the by
+   * the modifier in the object.
+   */
+  SubsurfRuntimeData *subsurf_runtime_data = nullptr;
+
+  /**
+   * Caches for lazily computed vertex and polygon normals. These are stored here rather than in
+   * #CustomData because they can be calculated on a const mesh, and adding custom data layers on a
+   * const mesh is not thread-safe.
+   */
+  bool vert_normals_dirty = false;
+  bool poly_normals_dirty = false;
+  float (*vert_normals)[3] = nullptr;
+  float (*poly_normals)[3] = nullptr;
+
+  /**
+   * A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the
+   * subdivision surface modifier and used by drawing code instead of polygon center face dots.
+   */
+  uint32_t *subsurf_face_dot_tags = nullptr;
+
+  MeshRuntime();
+  /** \warning This does not free all data currently. See #BKE_mesh_runtime_free_data. */
+  ~MeshRuntime();
+
+  MEM_CXX_CLASS_ALLOC_FUNCS("MeshRuntime")
+};
+
+}  // namespace blender::bke
+
+#endif
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 742f20fa65f..9930e5f23fa 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -35,6 +35,7 @@
 #include "BKE_colorband.h"
 #include "BKE_deform.h"
 #include "BKE_editmesh.h"
+#include "BKE_editmesh_cache.h"
 #include "BKE_geometry_set.hh"
 #include "BKE_geometry_set_instances.hh"
 #include "BKE_key.h"
@@ -537,7 +538,7 @@ static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
                                   (final_datamask->lmask & CD_MASK_NORMAL) != 0);
 
   /* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */
-  SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data;
+  SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
   if (subsurf_runtime_data) {
     subsurf_runtime_data->calc_loop_normals = calc_loop_normals;
   }
@@ -585,11 +586,12 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
 void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval,
                                               const CustomData_MeshMasks *cd_mask_finalize)
 {
-  if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
+  if (me_eval->runtime->wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
     editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize);
-    me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH);
+   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list