[Bf-blender-cvs] [85be72c1cc7] blender-v2.93-release: Fix T86278: vertex color baking not working with modifiers

Brecht Van Lommel noreply at git.blender.org
Mon May 17 19:41:58 CEST 2021


Commit: 85be72c1cc7317796dcce3ddc6ec2dedd627ff81
Author: Brecht Van Lommel
Date:   Wed May 12 23:14:58 2021 +0200
Branches: blender-v2.93-release
https://developer.blender.org/rB85be72c1cc7317796dcce3ddc6ec2dedd627ff81

Fix T86278: vertex color baking not working with modifiers

As in the old Blender Internal baking code, this still relies on there being a
good mapping to the original vertices.

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/mesh_convert.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/editors/object/object_bake_api.c
M	source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
M	source/blender/io/alembic/exporter/abc_writer_mball.cc
M	source/blender/io/usd/intern/usd_writer_metaball.cc
M	source/blender/python/bmesh/bmesh_py_types.c

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index e39caac7c36..22ce197088a 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -215,7 +215,8 @@ void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
  * ignored otherwise. */
 struct Mesh *BKE_mesh_new_from_object(struct Depsgraph *depsgraph,
                                       struct Object *object,
-                                      bool preserve_all_data_layers);
+                                      const bool preserve_all_data_layers,
+                                      const bool preserve_origindex);
 
 /* This is a version of BKE_mesh_new_from_object() which stores mesh in the given main database.
  * However, that function enforces object type to be a geometry one, and ensures a mesh is always
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index c8416ac897e..5bf87f53f75 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -712,11 +712,13 @@ static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free)
     if (!em) {
       ClothModifierData *clmd = (ClothModifierData *)BKE_modifiers_findby_type(
           ob, eModifierType_Cloth);
-      KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob),
-                                           clmd->sim_parms->shapekey_rest);
+      if (clmd) {
+        KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob),
+                                             clmd->sim_parms->shapekey_rest);
 
-      if (kb && kb->data) {
-        return (float(*)[3])kb->data;
+        if (kb && kb->data) {
+          return (float(*)[3])kb->data;
+        }
       }
     }
 
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 729c38ae7cf..d013becb372 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -1199,7 +1199,9 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
   return mesh_result;
 }
 
-static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object *object)
+static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
+                                                   Object *object,
+                                                   const bool preserve_origindex)
 {
   if (DEG_is_original_id(&object->id)) {
     return mesh_new_from_mesh(object, (Mesh *)object->data);
@@ -1216,16 +1218,23 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object
 
   Scene *scene = DEG_get_evaluated_scene(depsgraph);
   CustomData_MeshMasks mask = CD_MASK_MESH;
+  if (preserve_origindex) {
+    mask.vmask |= CD_MASK_ORIGINDEX;
+    mask.emask |= CD_MASK_ORIGINDEX;
+    mask.lmask |= CD_MASK_ORIGINDEX;
+    mask.pmask |= CD_MASK_ORIGINDEX;
+  }
   Mesh *result = mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask);
   return result;
 }
 
 static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
                                        Object *object,
-                                       bool preserve_all_data_layers)
+                                       const bool preserve_all_data_layers,
+                                       const bool preserve_origindex)
 {
-  if (preserve_all_data_layers) {
-    return mesh_new_from_mesh_object_with_layers(depsgraph, object);
+  if (preserve_all_data_layers || preserve_origindex) {
+    return mesh_new_from_mesh_object_with_layers(depsgraph, object, preserve_origindex);
   }
   Mesh *mesh_input = object->data;
   /* If we are in edit mode, use evaluated mesh from edit structure, matching to what
@@ -1236,7 +1245,10 @@ static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
   return mesh_new_from_mesh(object, mesh_input);
 }
 
-Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers)
+Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
+                               Object *object,
+                               const bool preserve_all_data_layers,
+                               const bool preserve_origindex)
 {
   Mesh *new_mesh = NULL;
   switch (object->type) {
@@ -1249,7 +1261,8 @@ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph, Object *object, bool preser
       new_mesh = mesh_new_from_mball_object(object);
       break;
     case OB_MESH:
-      new_mesh = mesh_new_from_mesh_object(depsgraph, object, preserve_all_data_layers);
+      new_mesh = mesh_new_from_mesh_object(
+          depsgraph, object, preserve_all_data_layers, preserve_origindex);
       break;
     default:
       /* Object does not have geometry data. */
@@ -1314,7 +1327,7 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
 {
   BLI_assert(ELEM(object->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_MESH));
 
-  Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers);
+  Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false);
   if (mesh == NULL) {
     /* Unable to convert the object to a mesh, return an empty one. */
     Mesh *mesh_in_bmain = BKE_mesh_add(bmain, ((ID *)object->data)->name + 2);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 160fb93b835..ef553e60eb8 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -5657,7 +5657,7 @@ Mesh *BKE_object_to_mesh(Depsgraph *depsgraph, Object *object, bool preserve_all
 {
   BKE_object_to_mesh_clear(object);
 
-  Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers);
+  Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false);
   object->runtime.object_as_temp_mesh = mesh;
   return mesh;
 }
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index f651f5bc3fd..3370476d466 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -669,9 +669,11 @@ static void bake_targets_clear(Main *bmain, const bool is_tangent)
 }
 
 /* create new mesh with edit mode changes and modifiers applied */
-static Mesh *bake_mesh_new_from_object(Object *object)
+static Mesh *bake_mesh_new_from_object(Depsgraph *depsgraph,
+                                       Object *object,
+                                       const bool preserve_origindex)
 {
-  Mesh *me = BKE_mesh_new_from_object(NULL, object, false);
+  Mesh *me = BKE_mesh_new_from_object(depsgraph, object, false, preserve_origindex);
 
   if (me->flag & ME_AUTOSMOOTH) {
     BKE_mesh_split_faces(me, true);
@@ -961,10 +963,39 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re
   return true;
 }
 
+static int find_original_loop(const Mesh *me_orig,
+                              const int *vert_origindex,
+                              const int *poly_origindex,
+                              const int poly_eval,
+                              const int vert_eval)
+{
+  /* Get original vertex and polygon index. There is currently no loop mapping
+   * in modifier stack evaluation. */
+  const int vert_orig = vert_origindex[vert_eval];
+  const int poly_orig = poly_origindex[poly_eval];
+
+  if (vert_orig == ORIGINDEX_NONE || poly_orig == ORIGINDEX_NONE) {
+    return ORIGINDEX_NONE;
+  }
+
+  /* Find matching loop with original vertex in original polygon. */
+  MPoly *mpoly_orig = me_orig->mpoly + poly_orig;
+  MLoop *mloop_orig = me_orig->mloop + mpoly_orig->loopstart;
+  for (int j = 0; j < mpoly_orig->totloop; ++j, ++mloop_orig) {
+    if (mloop_orig->v == vert_orig) {
+      return mpoly_orig->loopstart + j;
+    }
+  }
+
+  return ORIGINDEX_NONE;
+}
+
 static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
-                                                       Mesh *me,
+                                                       Object *ob,
+                                                       Mesh *me_eval,
                                                        BakePixel *pixel_array)
 {
+  Mesh *me = ob->data;
   const int num_pixels = targets->num_pixels;
 
   /* Initialize blank pixels. */
@@ -983,16 +1014,31 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
   }
 
   /* Populate through adjacent triangles, first triangle wins. */
-  const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
+  const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop);
   MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
 
-  BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+  BKE_mesh_recalc_looptri(
+      me_eval->mloop, me_eval->mpoly, me_eval->mvert, me_eval->totloop, me_eval->totpoly, looptri);
+
+  /* For mapping back to original mesh in case there are modifiers. */
+  const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
+  const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
 
   for (int i = 0; i < tottri; i++) {
     const MLoopTri *lt = &looptri[i];
 
     for (int j = 0; j < 3; j++) {
-      const unsigned int l = lt->tri[j];
+      unsigned int l = lt->tri[j];
+      unsigned int v = me_eval->mloop[l].v;
+
+      /* Map back to original loop if there are modifiers. */
+      if (vert_origindex != NULL && poly_origindex != NULL) {
+        l = find_original_loop(me, vert_origindex, poly_origindex, lt->poly, v);
+        if (l == ORIGINDEX_NONE || l >= me->totloop) {
+          continue;
+        }
+      }
+
       BakePixel *pixel = &pixel_array[l];
 
       if (pixel->primitive_id != -1) {
@@ -1004,7 +1050,7 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
       /* Seed is the vertex, so that sampling noise is coherent for the same
        * vertex, but different corners can still have different normals,
        * material

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list