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
This commit is contained in:
Himanshi Kalra 2021-08-06 00:03:16 +05:30 committed by Himanshi Kalra
parent 89014b51f1
commit 92edf37997
1 changed files with 86 additions and 9 deletions

View File

@ -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);
}