[Bf-blender-cvs] [21f2bacad97] master: Cleanup: Simplify BKE_mesh_nomain_to_mesh

Hans Goudey noreply at git.blender.org
Fri Sep 9 15:30:24 CEST 2022


Commit: 21f2bacad977d3fd83d9e4730f2a14dc9932f043
Author: Hans Goudey
Date:   Fri Sep 9 08:24:31 2022 -0500
Branches: master
https://developer.blender.org/rB21f2bacad977d3fd83d9e4730f2a14dc9932f043

Cleanup: Simplify BKE_mesh_nomain_to_mesh

- Remove "take ownership" argument which was confusing and always true
  - The argument made ownership very confusing
  - Better to avoid boolean arguments that switch a function's purpose
- Remove "mask" argument which was basically wrong and not used properly
  - "EVERYTHING" was used because developers are wary of removing data
  - Instead use `CD_MASK_MESH` for its purpose of original mesh data
- Remove use of shallow copied temporary mesh, which is unnecessary now
- Split shape key processing into separate functions and use C++ types
- Copy fields explicitly rather than using memcpy for the whole struct
- Use higher level functions and avoid redundant code
  - The whole idea is pretty simple and can be built from standard logic
- Adjust `CustomData` logic to be consistent with "assign" expectations
  - Clear the layer data from the source, and moves the anonymous ID

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

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

M	source/blender/blenkernel/BKE_key.h
M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/blenkernel/intern/key.c
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/mesh_convert.cc
M	source/blender/blenkernel/intern/multires_unsubdivide.c
M	source/blender/editors/mesh/editmesh_mask_extract.c
M	source/blender/editors/object/object_add.cc
M	source/blender/editors/object/object_modifier.cc
M	source/blender/editors/object/object_remesh.cc
M	source/blender/editors/sculpt_paint/paint_mask.c
M	source/blender/io/alembic/intern/abc_reader_mesh.cc
M	source/blender/io/alembic/intern/abc_reader_points.cc
M	source/blender/io/usd/intern/usd_reader_mesh.cc
M	source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
M	source/blender/makesrna/intern/rna_mesh_api.c

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

diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 9f506ded8e9..45a72e8d7a3 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -95,6 +95,9 @@ struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index);
  * Get the appropriate #KeyBlock given a name to search for.
  */
 struct KeyBlock *BKE_keyblock_find_name(struct Key *key, const char name[]);
+
+struct KeyBlock *BKE_keyblock_find_uid(struct Key *key, int uid);
+
 /**
  * \brief copy shape-key attributes, but not key data or name/UID.
  */
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 1048ca39958..ef57c9a2e0e 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -292,13 +292,10 @@ struct Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
                                                   bool build_shapekey_layers);
 
 /**
- * Copies a nomain-Mesh into an existing Mesh.
+ * Move data from a mesh outside of the main data-base into a mesh in the data-base.
+ * Takes ownership of the source mesh.
  */
-void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src,
-                             struct Mesh *mesh_dst,
-                             struct Object *ob,
-                             const struct CustomData_MeshMasks *mask,
-                             bool take_ownership);
+void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct Object *ob);
 void BKE_mesh_nomain_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct KeyBlock *kb);
 
 /* vertex level transformations & checks (no derived mesh) */
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index cfb8416b0b4..a3b9f012e45 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -2353,8 +2353,16 @@ bool CustomData_merge(const CustomData *source,
       changed = true;
 
       if (layer->anonymous_id != nullptr) {
-        BKE_anonymous_attribute_id_increment_weak(layer->anonymous_id);
         newlayer->anonymous_id = layer->anonymous_id;
+        if (alloctype == CD_ASSIGN) {
+          layer->anonymous_id = nullptr;
+        }
+        else {
+          BKE_anonymous_attribute_id_increment_weak(layer->anonymous_id);
+        }
+      }
+      if (alloctype == CD_ASSIGN) {
+        layer->data = nullptr;
       }
     }
   }
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index a4475869c2a..2ba81c54872 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1938,6 +1938,16 @@ KeyBlock *BKE_keyblock_find_name(Key *key, const char name[])
   return BLI_findstring(&key->block, name, offsetof(KeyBlock, name));
 }
 
+KeyBlock *BKE_keyblock_find_uid(Key *key, const int uid)
+{
+  LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
+    if (kb->uid == uid) {
+      return kb;
+    }
+  }
+  return NULL;
+}
+
 void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src)
 {
   kb_dst->pos = kb_src->pos;
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 8254bb953d2..c82d9be008d 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -881,11 +881,12 @@ static void mesh_clear_geometry(Mesh *mesh)
   mesh->totpoly = 0;
   mesh->act_face = -1;
   mesh->totselect = 0;
+
+  BLI_freelistN(&mesh->vertex_group_names);
 }
 
 void BKE_mesh_clear_geometry(Mesh *mesh)
 {
-  BKE_animdata_free(&mesh->id, false);
   BKE_mesh_runtime_clear_cache(mesh);
   mesh_clear_geometry(mesh);
 }
@@ -975,6 +976,7 @@ void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
   copy_v3_v3(me_dst->size, me_src->size);
 
   me_dst->vertex_group_active_index = me_src->vertex_group_active_index;
+  me_dst->attributes_active_index = me_src->attributes_active_index;
 }
 
 void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index a8ff90c128a..756529473f4 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -54,9 +54,11 @@
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
+using blender::float3;
 using blender::IndexRange;
 using blender::MutableSpan;
 using blender::Span;
+using blender::StringRefNull;
 
 /* Define for cases when you want extra validation of mesh
  * after certain modifications.
@@ -1081,7 +1083,7 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
   mesh_in_bmain->smoothresh = mesh->smoothresh;
   mesh->mat = nullptr;
 
-  BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, nullptr, &CD_MASK_MESH, true);
+  BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, nullptr);
 
   /* Anonymous attributes shouldn't exist on original data. */
   mesh_in_bmain->attributes_for_write().remove_anonymous();
@@ -1235,239 +1237,113 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
   return result;
 }
 
-/* This is a Mesh-based copy of the same function in DerivedMesh.cc */
-static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int actshape_uid)
+static KeyBlock *keyblock_ensure_from_uid(Key &key, const int uid, const StringRefNull name)
 {
-  KeyBlock *kb;
-  int i, j, tot;
-
-  if (!mesh_dst->key) {
-    return;
+  if (KeyBlock *kb = BKE_keyblock_find_uid(&key, uid)) {
+    return kb;
   }
+  KeyBlock *kb = BKE_keyblock_add(&key, name.c_str());
+  kb->uid = uid;
+  return kb;
+}
 
-  tot = CustomData_number_of_layers(&mesh_src->vdata, CD_SHAPEKEY);
-  for (i = 0; i < tot; i++) {
-    CustomDataLayer *layer =
-        &mesh_src->vdata.layers[CustomData_get_layer_index_n(&mesh_src->vdata, CD_SHAPEKEY, i)];
-    float(*kbcos)[3];
-
-    for (kb = (KeyBlock *)mesh_dst->key->block.first; kb; kb = kb->next) {
-      if (kb->uid == layer->uid) {
-        break;
-      }
-    }
+static int find_object_active_key_uid(const Key &key, const Object &object)
+{
+  const int active_kb_index = object.shapenr - 1;
+  const KeyBlock *kb = (const KeyBlock *)BLI_findlink(&key.block, active_kb_index);
+  if (!kb) {
+    CLOG_ERROR(&LOG, "Could not find object's active shapekey %d", active_kb_index);
+    return -1;
+  }
+  return kb->uid;
+}
 
-    if (!kb) {
-      kb = BKE_keyblock_add(mesh_dst->key, layer->name);
-      kb->uid = layer->uid;
-    }
+static void move_shapekey_layers_to_keyblocks(Mesh &mesh, Key &key_dst, const int actshape_uid)
+{
+  using namespace blender::bke;
+  for (const int i : IndexRange(CustomData_number_of_layers(&mesh.vdata, CD_SHAPEKEY))) {
+    const int layer_index = CustomData_get_layer_index_n(&mesh.vdata, CD_SHAPEKEY, i);
+    CustomDataLayer &layer = mesh.vdata.layers[layer_index];
 
-    if (kb->data) {
-      MEM_freeN(kb->data);
-    }
+    KeyBlock *kb = keyblock_ensure_from_uid(key_dst, layer.uid, layer.name);
+    MEM_SAFE_FREE(kb->data);
 
-    const float(*cos)[3] = (const float(*)[3])CustomData_get_layer_n(
-        &mesh_src->vdata, CD_SHAPEKEY, i);
-    kb->totelem = mesh_src->totvert;
+    kb->totelem = mesh.totvert;
 
-    kb->data = kbcos = (float(*)[3])MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
     if (kb->uid == actshape_uid) {
-      const Span<MVert> verts = mesh_src->verts();
-      for (j = 0; j < mesh_src->totvert; j++, kbcos++) {
-        copy_v3_v3(*kbcos, verts[j].co);
-      }
+      kb->data = MEM_malloc_arrayN(kb->totelem, sizeof(float3), __func__);
+      MutableSpan<float3> kb_coords(static_cast<float3 *>(kb->data), kb->totelem);
+      mesh.attributes().lookup<float3>("position").materialize(kb_coords);
     }
     else {
-      for (j = 0; j < kb->totelem; j++, cos++, kbcos++) {
-        copy_v3_v3(*kbcos, *cos);
-      }
+      kb->data = layer.data;
+      layer.data = nullptr;
     }
   }
 
-  for (kb = (KeyBlock *)mesh_dst->key->block.first; kb; kb = kb->next) {
-    if (kb->totelem != mesh_src->totvert) {
-      if (kb->data) {
-        MEM_freeN(kb->data);
-      }
-
-      kb->totelem = mesh_src->totvert;
-      kb->data = MEM_calloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
-      CLOG_ERROR(&LOG, "lost a shapekey layer: '%s'! (bmesh internal error)", kb->name);
+  LISTBASE_FOREACH (KeyBlock *, kb, &key_dst.block) {
+    if (kb->totelem != mesh.totvert) {
+      MEM_SAFE_FREE(kb->data);
     }
+    kb->totelem = mesh.totvert;
+    kb->data = MEM_cnew_array<float3>(kb->totelem, __func__);
+    CLOG_ERROR(&LOG, "Data for shape key '%s' on mesh missing from evaluated mesh ", kb->name);
   }
 }
 
-void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
-                             Mesh *mesh_dst,
-                             Object *ob,
-                             const CustomData_MeshMasks *mask,
-                             bool take_ownership)
+void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
 {
   using namespace blender::bke;
   BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN);
-
-  /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
-  /* TODO(Sybren): the above claim came from 2.7x derived-mesh code (DM_to_mesh);
-   * check whether it is still true with Mesh */
-  Mesh tmp = blender::dna::shallow_copy(*mesh_dst);
-  int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
-  bool did_shapekeys = false;
-  eCDAllocType alloctype = CD_DUPLICATE;
-
-  if (take_ownership /* && dm->type == DM_TYPE_CDDM && dm->needsFree */) {
-    bool has_any_referenced_layers = CustomData_has_referenced(&mesh_src->vdata) ||
-                                     CustomData_has_referenced(&mesh_src->edata) ||
-                                     CustomData_has_referenced(&mesh_src->ldata) ||
-                                     CustomData_has_referenced(&mesh_src->fdata) ||
-                                     CustomData_has_referenced(&mesh_src->pdata);
-    if (!has_any_referenced_layers) {
-      alloctype = CD_ASSIGN;
-    }
-  }
-  CustomData_reset(&tmp.vda

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list