Fix multires modifier using too much memory outside of sculpt mode
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 27 Aug 2019 16:17:27 +0000 (18:17 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 27 Aug 2019 16:22:29 +0000 (18:22 +0200)
This reduce memory usage by about 25% in object mode for multires meshes.

source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/subdiv_mesh.c
source/blender/makesdna/DNA_customdata_types.h

index 15df0cff6fcc2ec99e065b75e4aa1d8bafd94295..12978e463275658871fe9aca8e79136c520437e6 100644 (file)
@@ -121,6 +121,13 @@ struct Mesh *BKE_mesh_new_nomain_from_template(const struct Mesh *me_src,
                                                int tessface_len,
                                                int loops_len,
                                                int polys_len);
+struct Mesh *BKE_mesh_new_nomain_from_template_ex(const struct Mesh *me_src,
+                                                  int verts_len,
+                                                  int edges_len,
+                                                  int tessface_len,
+                                                  int loops_len,
+                                                  int polys_len,
+                                                  CustomData_MeshMasks mask);
 
 void BKE_mesh_eval_delete(struct Mesh *me_eval);
 
index 71fd65d1f23b801a49c7608eb2fbef849035e875..61b841591a455e891dc2a43930cae51ee9e7624b 100644 (file)
@@ -661,13 +661,13 @@ Mesh *BKE_mesh_new_nomain(
   return mesh;
 }
 
-static Mesh *mesh_new_nomain_from_template_ex(const Mesh *me_src,
-                                              int verts_len,
-                                              int edges_len,
-                                              int tessface_len,
-                                              int loops_len,
-                                              int polys_len,
-                                              CustomData_MeshMasks mask)
+Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
+                                           int verts_len,
+                                           int edges_len,
+                                           int tessface_len,
+                                           int loops_len,
+                                           int polys_len,
+                                           CustomData_MeshMasks mask)
 {
   /* Only do tessface if we are creating tessfaces or copying from mesh with only tessfaces. */
   const bool do_tessface = (tessface_len || ((me_src->totface != 0) && (me_src->totpoly == 0)));
@@ -713,7 +713,7 @@ Mesh *BKE_mesh_new_nomain_from_template(const Mesh *me_src,
                                         int loops_len,
                                         int polys_len)
 {
-  return mesh_new_nomain_from_template_ex(
+  return BKE_mesh_new_nomain_from_template_ex(
       me_src, verts_len, edges_len, tessface_len, loops_len, polys_len, CD_MASK_EVERYTHING);
 }
 
index 1ff9140681fb4663f040f0678bf0e5354ab8936c..9d713d1937d8ec6dbe31f21f24cb5fd52c57d133 100644 (file)
@@ -498,9 +498,14 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
                                       const int num_loops,
                                       const int num_polygons)
 {
+  /* Multires grid data will be applied or become invalid after subdivision,
+   * so don't try to preserve it and use memory. */
+  CustomData_MeshMasks mask = CD_MASK_EVERYTHING;
+  mask.lmask &= ~CD_MASK_MULTIRES_GRIDS;
+
   SubdivMeshContext *subdiv_context = foreach_context->user_data;
-  subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template(
-      subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons);
+  subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template_ex(
+      subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
   subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
   subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
   return true;
index 14a078d8386ddc48d751984ed522375d9680e181..9799489982dd85fbdba41fd910ea0cdb22ee3229 100644 (file)
@@ -197,6 +197,9 @@ typedef enum CustomDataType {
 /** Data types that may be defined for all mesh elements types. */
 #define CD_MASK_GENERIC_DATA (CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR)
 
+/** Multires loop data. */
+#define CD_MASK_MULTIRES_GRIDS (CD_MASK_MDISPS | CD_GRID_PAINT_MASK)
+
 typedef struct CustomData_MeshMasks {
   uint64_t vmask;
   uint64_t emask;