[Bf-blender-cvs] [92edf37997c] master: Add custom data comparison for generic attributes

Himanshi Kalra noreply at git.blender.org
Thu Aug 5 20:39:33 CEST 2021


Commit: 92edf37997c25444fc2628c8057a87b7e87c5eff
Author: Himanshi Kalra
Date:   Fri Aug 6 00:03:16 2021 +0530
Branches: master
https://developer.blender.org/rB92edf37997c25444fc2628c8057a87b7e87c5eff

Add custom data comparison for generic attributes

Generic attributes CD_PROP_* comparison is added in customdata_compare
Checks for built-in as well as user created attributes.

Reviewed By: JacquesLucke

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

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

M	source/blender/blenkernel/intern/mesh.c

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

diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 8d74002ad79..b00670aad4c 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -389,6 +389,7 @@ enum {
   MESHCMP_EDGEUNKNOWN,
   MESHCMP_VERTCOMISMATCH,
   MESHCMP_CDLAYERS_MISMATCH,
+  MESHCMP_ATTRIBUTE_VALUE_MISMATCH,
 };
 
 static const char *cmpcode_to_str(int code)
@@ -416,6 +417,8 @@ static const char *cmpcode_to_str(int code)
       return "Vertex Coordinate Mismatch";
     case MESHCMP_CDLAYERS_MISMATCH:
       return "CustomData Layer Count Mismatch";
+    case MESHCMP_ATTRIBUTE_VALUE_MISMATCH:
+      return "Attribute Value Mismatch";
     default:
       return "Mesh Comparison Code Unknown";
   }
@@ -423,13 +426,13 @@ static const char *cmpcode_to_str(int code)
 
 /** Thresh is threshold for comparing vertices, UV's, vertex colors, weights, etc. */
 static int customdata_compare(
-    CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2, const float thresh)
+    CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, Mesh *m2, const float thresh)
 {
   const float thresh_sq = thresh * thresh;
   CustomDataLayer *l1, *l2;
-  int i, i1 = 0, i2 = 0, tot, j;
+  int i1 = 0, i2 = 0, tot, j;
 
-  for (i = 0; i < c1->totlayer; i++) {
+  for (int i = 0; i < c1->totlayer; i++) {
     if (ELEM(c1->layers[i].type,
              CD_MVERT,
              CD_MEDGE,
@@ -441,7 +444,7 @@ static int customdata_compare(
     }
   }
 
-  for (i = 0; i < c2->totlayer; i++) {
+  for (int i = 0; i < c2->totlayer; i++) {
     if (ELEM(c2->layers[i].type,
              CD_MVERT,
              CD_MEDGE,
@@ -457,12 +460,86 @@ static int customdata_compare(
     return MESHCMP_CDLAYERS_MISMATCH;
   }
 
+  l1 = c1->layers;
+  l2 = c2->layers;
+
+  for (i1 = 0; i1 < c1->totlayer; i1++) {
+    l1 = c1->layers + i1;
+    if ((CD_TYPE_AS_MASK(l1->type) & CD_MASK_PROP_ALL) == 0) {
+      /* Skip non generic attribute layers. */
+      continue;
+    }
+
+    bool found_corresponding_layer = false;
+    for (i2 = 0; i2 < c2->totlayer; i2++) {
+      l2 = c2->layers + i2;
+      if (l1->type != l2->type || !STREQ(l1->name, l2->name)) {
+        continue;
+      }
+      found_corresponding_layer = true;
+      /* At this point `l1` and `l2` have the same name and type, so they should be compared. */
+
+      switch (l1->type) {
+
+        case CD_PROP_FLOAT: {
+          const float *l1_data = l1->data;
+          const float *l2_data = l2->data;
+
+          for (int i = 0; i < total_length; i++) {
+            if (fabsf(l1_data[i] - l2_data[i]) > thresh) {
+              return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
+            }
+          }
+          break;
+        }
+        case CD_PROP_FLOAT2: {
+          const float(*l1_data)[2] = l1->data;
+          const float(*l2_data)[2] = l2->data;
+
+          for (int i = 0; i < total_length; i++) {
+            if (len_squared_v2v2(l1_data[i], l2_data[i]) > thresh_sq) {
+              return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
+            }
+          }
+          break;
+        }
+        case CD_PROP_FLOAT3: {
+          const float(*l1_data)[3] = l1->data;
+          const float(*l2_data)[3] = l2->data;
+
+          for (int i = 0; i < total_length; i++) {
+            if (len_squared_v3v3(l1_data[i], l2_data[i]) > thresh_sq) {
+              return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
+            }
+          }
+          break;
+        }
+        default: {
+          int element_size = CustomData_sizeof(l1->type);
+          for (int i = 0; i < total_length; i++) {
+            int offset = element_size * i;
+            if (!CustomData_data_equals(l1->type,
+                                        POINTER_OFFSET(l1->data, offset),
+                                        POINTER_OFFSET(l2->data, offset))) {
+              return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
+            }
+          }
+          break;
+        }
+      }
+    }
+
+    if (!found_corresponding_layer) {
+      return MESHCMP_CDLAYERS_MISMATCH;
+    }
+  }
+
   l1 = c1->layers;
   l2 = c2->layers;
   tot = i1;
   i1 = 0;
   i2 = 0;
-  for (i = 0; i < tot; i++) {
+  for (int i = 0; i < tot; i++) {
     while (
         i1 < c1->totlayer &&
         !ELEM(l1->type, CD_MVERT, CD_MEDGE, CD_MPOLY, CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT)) {
@@ -626,19 +703,19 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
     return "Number of loops don't match";
   }
 
-  if ((c = customdata_compare(&me1->vdata, &me2->vdata, me1, me2, thresh))) {
+  if ((c = customdata_compare(&me1->vdata, &me2->vdata, me1->totvert, me1, me2, thresh))) {
     return cmpcode_to_str(c);
   }
 
-  if ((c = customdata_compare(&me1->edata, &me2->edata, me1, me2, thresh))) {
+  if ((c = customdata_compare(&me1->edata, &me2->edata, me1->totedge, me1, me2, thresh))) {
     return cmpcode_to_str(c);
   }
 
-  if ((c = customdata_compare(&me1->ldata, &me2->ldata, me1, me2, thresh))) {
+  if ((c = customdata_compare(&me1->ldata, &me2->ldata, me1->totloop, me1, me2, thresh))) {
     return cmpcode_to_str(c);
   }
 
-  if ((c = customdata_compare(&me1->pdata, &me2->pdata, me1, me2, thresh))) {
+  if ((c = customdata_compare(&me1->pdata, &me2->pdata, me1->totpoly, me1, me2, thresh))) {
     return cmpcode_to_str(c);
   }



More information about the Bf-blender-cvs mailing list