Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/customdata.c')
-rw-r--r--source/blender/blenkernel/intern/customdata.c318
1 files changed, 156 insertions, 162 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 7c244ed8f58..fdb3e246382 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -137,7 +137,7 @@ typedef struct LayerTypeInfo {
* \note in some cases \a dest pointer is in \a sources
* so all functions have to take this into account and delay
* applying changes while reading from sources.
- * See bug [#32395] - Campbell.
+ * See bug T32395 - Campbell.
*/
cd_interp interp;
@@ -255,15 +255,11 @@ static void layerInterp_mdeformvert(const void **sources,
struct MDeformWeight_Link *node;
int i, j, totweight;
- if (count <= 0) {
- return;
- }
-
/* build a list of unique def_nrs for dest */
totweight = 0;
for (i = 0; i < count; i++) {
const MDeformVert *source = sources[i];
- float interp_weight = weights ? weights[i] : 1.0f;
+ float interp_weight = weights[i];
for (j = 0; j < source->totweight; j++) {
MDeformWeight *dw = &source->dw[j];
@@ -424,23 +420,19 @@ static void layerInterp_tface(
float uv[4][2] = {{0.0f}};
const float *sub_weight;
- if (count <= 0) {
- return;
- }
-
sub_weight = sub_weights;
for (i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1;
+ const float interp_weight = weights[i];
const MTFace *src = sources[i];
for (j = 0; j < 4; j++) {
if (sub_weights) {
for (k = 0; k < 4; k++, sub_weight++) {
- madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
+ madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight);
}
}
else {
- madd_v2_v2fl(uv[j], src->uv[j], weight);
+ madd_v2_v2fl(uv[j], src->uv[j], interp_weight);
}
}
}
@@ -529,23 +521,19 @@ static void layerInterp_origspace_face(
float uv[4][2] = {{0.0f}};
const float *sub_weight;
- if (count <= 0) {
- return;
- }
-
sub_weight = sub_weights;
for (i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1;
+ const float interp_weight = weights[i];
const OrigSpaceFace *src = sources[i];
for (j = 0; j < 4; j++) {
if (sub_weights) {
for (k = 0; k < 4; k++, sub_weight++) {
- madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
+ madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight);
}
}
else {
- madd_v2_v2fl(uv[j], src->uv[j], weight);
+ madd_v2_v2fl(uv[j], src->uv[j], interp_weight);
}
}
}
@@ -690,21 +678,17 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int
return size;
}
-static void layerInterp_paint_mask(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_paint_mask(const void **sources,
+ const float *weights,
+ const float *UNUSED(sub_weights),
+ int count,
+ void *dest)
{
float mask = 0.0f;
- const float *sub_weight = sub_weights;
for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1.0f;
+ const float interp_weight = weights[i];
const float *src = sources[i];
- if (sub_weights) {
- mask += (*src) * (*sub_weight) * weight;
- sub_weight++;
- }
- else {
- mask += (*src) * weight;
- }
+ mask += (*src) * interp_weight;
}
*(float *)dest = mask;
}
@@ -767,6 +751,7 @@ static void layerCopyValue_mloopcol(const void *source,
m2->r = m1->r;
m2->g = m1->g;
m2->b = m1->b;
+ m2->a = m1->a;
}
else { /* Modes that support 'real' mix factor. */
unsigned char src[4] = {m1->r, m1->g, m1->b, m1->a};
@@ -787,13 +772,14 @@ static void layerCopyValue_mloopcol(const void *source,
else {
memcpy(tmp_col, src, sizeof(tmp_col));
}
+
blend_color_interpolate_byte(dst, dst, tmp_col, mixfactor);
m2->r = (char)dst[0];
m2->g = (char)dst[1];
m2->b = (char)dst[2];
+ m2->a = (char)dst[3];
}
- m2->a = m1->a;
}
static bool layerEqual_mloopcol(const void *data1, const void *data2)
@@ -885,8 +871,11 @@ static void layerDefault_mloopcol(void *data, int count)
}
}
-static void layerInterp_mloopcol(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_mloopcol(const void **sources,
+ const float *weights,
+ const float *UNUSED(sub_weights),
+ int count,
+ void *dest)
{
MLoopCol *mc = dest;
struct {
@@ -896,23 +885,13 @@ static void layerInterp_mloopcol(
float b;
} col = {0};
- const float *sub_weight = sub_weights;
for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1;
+ const float interp_weight = weights[i];
const MLoopCol *src = sources[i];
- if (sub_weights) {
- col.r += src->r * (*sub_weight) * weight;
- col.g += src->g * (*sub_weight) * weight;
- col.b += src->b * (*sub_weight) * weight;
- col.a += src->a * (*sub_weight) * weight;
- sub_weight++;
- }
- else {
- col.r += src->r * weight;
- col.g += src->g * weight;
- col.b += src->b * weight;
- col.a += src->a * weight;
- }
+ col.r += src->r * interp_weight;
+ col.g += src->g * interp_weight;
+ col.b += src->b * interp_weight;
+ col.a += src->a * interp_weight;
}
/* Subdivide smooth or fractal can cause problems without clamping
@@ -986,34 +965,23 @@ static void layerAdd_mloopuv(void *data1, const void *data2)
add_v2_v2(l1->uv, l2->uv);
}
-static void layerInterp_mloopuv(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_mloopuv(const void **sources,
+ const float *weights,
+ const float *UNUSED(sub_weights),
+ int count,
+ void *dest)
{
float uv[2];
int flag = 0;
zero_v2(uv);
- if (sub_weights) {
- const float *sub_weight = sub_weights;
- for (int i = 0; i < count; i++) {
- float weight = (weights ? weights[i] : 1.0f) * (*sub_weight);
- const MLoopUV *src = sources[i];
- madd_v2_v2fl(uv, src->uv, weight);
- if (weight > 0.0f) {
- flag |= src->flag;
- }
- sub_weight++;
- }
- }
- else {
- for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1;
- const MLoopUV *src = sources[i];
- madd_v2_v2fl(uv, src->uv, weight);
- if (weight > 0.0f) {
- flag |= src->flag;
- }
+ for (int i = 0; i < count; i++) {
+ const float interp_weight = weights[i];
+ const MLoopUV *src = sources[i];
+ madd_v2_v2fl(uv, src->uv, interp_weight);
+ if (interp_weight > 0.0f) {
+ flag |= src->flag;
}
}
@@ -1088,27 +1056,19 @@ static void layerAdd_mloop_origspace(void *data1, const void *data2)
add_v2_v2(l1->uv, l2->uv);
}
-static void layerInterp_mloop_origspace(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_mloop_origspace(const void **sources,
+ const float *weights,
+ const float *UNUSED(sub_weights),
+ int count,
+ void *dest)
{
float uv[2];
zero_v2(uv);
- if (sub_weights) {
- const float *sub_weight = sub_weights;
- for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1.0f;
- const OrigSpaceLoop *src = sources[i];
- madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
- sub_weight++;
- }
- }
- else {
- for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1.0f;
- const OrigSpaceLoop *src = sources[i];
- madd_v2_v2fl(uv, src->uv, weight);
- }
+ for (int i = 0; i < count; i++) {
+ const float interp_weight = weights[i];
+ const OrigSpaceLoop *src = sources[i];
+ madd_v2_v2fl(uv, src->uv, interp_weight);
}
/* Delay writing to the destination in case dest is in sources. */
@@ -1127,19 +1087,15 @@ static void layerInterp_mcol(
float b;
} col[4] = {{0.0f}};
- if (count <= 0) {
- return;
- }
-
const float *sub_weight = sub_weights;
for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1;
+ const float interp_weight = weights[i];
for (int j = 0; j < 4; j++) {
if (sub_weights) {
const MCol *src = sources[i];
for (int k = 0; k < 4; k++, sub_weight++, src++) {
- const float w = (*sub_weight) * weight;
+ const float w = (*sub_weight) * interp_weight;
col[j].a += src->a * w;
col[j].r += src->r * w;
col[j].g += src->g * w;
@@ -1148,10 +1104,10 @@ static void layerInterp_mcol(
}
else {
const MCol *src = sources[i];
- col[j].a += src[j].a * weight;
- col[j].r += src[j].r * weight;
- col[j].g += src[j].g * weight;
- col[j].b += src[j].b * weight;
+ col[j].a += src[j].a * interp_weight;
+ col[j].r += src[j].r * interp_weight;
+ col[j].g += src[j].g * interp_weight;
+ col[j].b += src[j].b * interp_weight;
}
}
}
@@ -1210,15 +1166,9 @@ static void layerInterp_bweight(const void **sources,
float f = 0.0f;
- if (weights) {
- for (int i = 0; i < count; i++) {
- f += *in[i] * weights[i];
- }
- }
- else {
- for (int i = 0; i < count; i++) {
- f += *in[i];
- }
+ for (int i = 0; i < count; i++) {
+ const float interp_weight = weights[i];
+ f += *in[i] * interp_weight;
}
/* Delay writing to the destination in case dest is in sources. */
@@ -1240,15 +1190,9 @@ static void layerInterp_shapekey(const void **sources,
float co[3];
zero_v3(co);
- if (weights) {
- for (int i = 0; i < count; i++) {
- madd_v3_v3fl(co, in[i], weights[i]);
- }
- }
- else {
- for (int i = 0; i < count; i++) {
- add_v3_v3(co, in[i]);
- }
+ for (int i = 0; i < count; i++) {
+ const float interp_weight = weights[i];
+ madd_v3_v3fl(co, in[i], interp_weight);
}
/* Delay writing to the destination in case dest is in sources. */
@@ -1282,10 +1226,10 @@ static void layerInterp_mvert_skin(const void **sources,
zero_v3(radius);
for (int i = 0; i < count; i++) {
+ const float interp_weight = weights[i];
const MVertSkin *vs_src = sources[i];
- float w = weights ? weights[i] : 1.0f;
- madd_v3_v3fl(radius, vs_src->radius, w);
+ madd_v3_v3fl(radius, vs_src->radius, interp_weight);
}
/* Delay writing to the destination in case dest is in sources. */
@@ -1339,7 +1283,7 @@ static void layerCopyValue_propcol(const void *source,
return; /* Do Nothing! */
}
}
- copy_v3_v3(m2->color, m1->color);
+ copy_v4_v4(m2->color, m1->color);
}
else { /* Modes that support 'real' mix factor. */
if (mixmode == CDT_MIX_MIX) {
@@ -1359,9 +1303,8 @@ static void layerCopyValue_propcol(const void *source,
}
blend_color_interpolate_float(m2->color, m2->color, tmp_col, mixfactor);
- copy_v3_v3(m2->color, m1->color);
+ copy_v4_v4(m2->color, m1->color);
}
- m2->color[3] = m1->color[3];
}
static bool layerEqual_propcol(const void *data1, const void *data2)
@@ -1415,22 +1358,18 @@ static void layerDefault_propcol(void *data, int count)
}
}
-static void layerInterp_propcol(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_propcol(const void **sources,
+ const float *weights,
+ const float *UNUSED(sub_weights),
+ int count,
+ void *dest)
{
MPropCol *mc = dest;
float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- const float *sub_weight = sub_weights;
for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1.0f;
+ const float interp_weight = weights[i];
const MPropCol *src = sources[i];
- if (sub_weights) {
- madd_v4_v4fl(col, src->color, (*sub_weight) * weight);
- sub_weight++;
- }
- else {
- madd_v4_v4fl(col, src->color, weight);
- }
+ madd_v4_v4fl(col, src->color, interp_weight);
}
copy_v4_v4(mc->color, col);
}
@@ -1440,19 +1379,17 @@ static int layerMaxNum_propcol(void)
return MAX_MCOL;
}
-static void layerInterp_propfloat3(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_propfloat3(const void **sources,
+ const float *weights,
+ const float *UNUSED(sub_weights),
+ int count,
+ void *dest)
{
vec3f result = {0.0f, 0.0f, 0.0f};
for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1.0f;
+ const float interp_weight = weights[i];
const vec3f *src = sources[i];
- if (sub_weights) {
- madd_v3_v3fl(&result.x, &src->x, sub_weights[i] * weight);
- }
- else {
- madd_v3_v3fl(&result.x, &src->x, weight);
- }
+ madd_v3_v3fl(&result.x, &src->x, interp_weight);
}
copy_v3_v3((float *)dest, &result.x);
}
@@ -1489,19 +1426,17 @@ static bool layerValidate_propfloat3(void *data, const uint totitems, const bool
return has_errors;
}
-static void layerInterp_propfloat2(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_propfloat2(const void **sources,
+ const float *weights,
+ const float *UNUSED(sub_weights),
+ int count,
+ void *dest)
{
vec2f result = {0.0f, 0.0f};
for (int i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1.0f;
+ const float interp_weight = weights[i];
const vec2f *src = sources[i];
- if (sub_weights) {
- madd_v2_v2fl(&result.x, &src->x, sub_weights[i] * weight);
- }
- else {
- madd_v2_v2fl(&result.x, &src->x, weight);
- }
+ madd_v2_v2fl(&result.x, &src->x, interp_weight);
}
copy_v2_v2((float *)dest, &result.x);
}
@@ -1980,8 +1915,8 @@ const CustomData_MeshMasks CD_MASK_MESH = {
.fmask = 0,
.lmask = (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL |
CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
- .pmask = (CD_MASK_MPOLY | CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE |
- CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS),
+ .pmask = (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL |
+ CD_MASK_SCULPT_FACE_SETS),
};
const CustomData_MeshMasks CD_MASK_EDITMESH = {
.vmask = (CD_MASK_MDEFORMVERT | CD_MASK_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY |
@@ -1990,18 +1925,19 @@ const CustomData_MeshMasks CD_MASK_EDITMESH = {
.fmask = 0,
.lmask = (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL |
CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
- .pmask = (CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS),
+ .pmask = (CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS),
};
const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
.vmask = (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN |
- CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR),
+ CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL |
+ CD_MASK_PROP_COLOR),
.emask = (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
.fmask = (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT),
.lmask = (CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL |
CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP |
CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */
- .pmask = (CD_MASK_ORIGINDEX | CD_MASK_RECAST | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP |
- CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS),
+ .pmask = (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL |
+ CD_MASK_SCULPT_FACE_SETS),
};
const CustomData_MeshMasks CD_MASK_BMESH = {
.vmask = (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY |
@@ -2010,7 +1946,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = {
.fmask = 0,
.lmask = (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL |
CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
- .pmask = (CD_MASK_RECAST | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL |
+ .pmask = (CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL |
CD_MASK_SCULPT_FACE_SETS),
};
/**
@@ -2040,7 +1976,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = {
CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP |
CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
.pmask = (CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_NORMAL |
- CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL |
+ CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL |
CD_MASK_SCULPT_FACE_SETS),
};
@@ -2350,6 +2286,7 @@ int CustomData_get_layer_index(const CustomData *data, int type)
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
{
+ BLI_assert(n >= 0);
int i = CustomData_get_layer_index(data, type);
if (i != -1) {
@@ -2572,7 +2509,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
return &data->layers[CustomData_get_layer_index(data, type)];
}
- if ((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
+ if (ELEM(alloctype, CD_ASSIGN, CD_REFERENCE)) {
newlayerdata = layerdata;
}
else if (totelem > 0 && typeInfo->size > 0) {
@@ -3057,6 +2994,18 @@ void CustomData_free_elem(CustomData *data, int index, int count)
#define SOURCE_BUF_SIZE 100
+/**
+ * Interpolate given custom data source items into a single destination one.
+ *
+ * \param src_indices: Indices of every source items to interpolate into the destination one.
+ * \param weights: The weight to apply to each source value individually. If NULL, they will be
+ * averaged.
+ * \param sub_weights: The weights of sub-items, only used to affect each corners of a
+ * tessellated face data (should always be and array of four values).
+ * \param count: The number of source items to interpolate.
+ * \param dest_index: Index of the destination item, in which to put the result of the
+ * interpolation.
+ */
void CustomData_interp(const CustomData *source,
CustomData *dest,
const int *src_indices,
@@ -3065,6 +3014,10 @@ void CustomData_interp(const CustomData *source,
int count,
int dest_index)
{
+ if (count <= 0) {
+ return;
+ }
+
const void *source_buf[SOURCE_BUF_SIZE];
const void **sources = source_buf;
@@ -3073,6 +3026,17 @@ void CustomData_interp(const CustomData *source,
sources = MEM_malloc_arrayN(count, sizeof(*sources), __func__);
}
+ /* If no weights are given, generate default ones to produce an average result. */
+ float default_weights_buf[SOURCE_BUF_SIZE];
+ float *default_weights = NULL;
+ if (weights == NULL) {
+ default_weights = (count > SOURCE_BUF_SIZE) ?
+ MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) :
+ default_weights_buf;
+ copy_vn_fl(default_weights, count, 1.0f / count);
+ weights = default_weights;
+ }
+
/* interpolates a layer at a time */
int dest_i = 0;
for (int src_i = 0; src_i < source->totlayer; src_i++) {
@@ -3119,6 +3083,9 @@ void CustomData_interp(const CustomData *source,
if (count > SOURCE_BUF_SIZE) {
MEM_freeN((void *)sources);
}
+ if (!ELEM(default_weights, NULL, default_weights_buf)) {
+ MEM_freeN(default_weights);
+ }
}
/**
@@ -3637,7 +3604,7 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
}
/**
- * Same as #CustomData_bmesh_free_block but zero the memory rather then freeing.
+ * Same as #CustomData_bmesh_free_block but zero the memory rather than freeing.
*/
void CustomData_bmesh_free_block_data(CustomData *data, void *block)
{
@@ -4047,6 +4014,9 @@ void CustomData_bmesh_interp_n(CustomData *data,
void *dst_block_ofs,
int n)
{
+ BLI_assert(weights != NULL);
+ BLI_assert(count > 0);
+
CustomDataLayer *layer = &data->layers[n];
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
@@ -4060,6 +4030,10 @@ void CustomData_bmesh_interp(CustomData *data,
int count,
void *dst_block)
{
+ if (count <= 0) {
+ return;
+ }
+
int i, j;
void *source_buf[SOURCE_BUF_SIZE];
const void **sources = (const void **)source_buf;
@@ -4069,6 +4043,17 @@ void CustomData_bmesh_interp(CustomData *data,
sources = MEM_malloc_arrayN(count, sizeof(*sources), __func__);
}
+ /* If no weights are given, generate default ones to produce an average result. */
+ float default_weights_buf[SOURCE_BUF_SIZE];
+ float *default_weights = NULL;
+ if (weights == NULL) {
+ default_weights = (count > SOURCE_BUF_SIZE) ?
+ MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) :
+ default_weights_buf;
+ copy_vn_fl(default_weights, count, 1.0f / count);
+ weights = default_weights;
+ }
+
/* interpolates a layer at a time */
for (i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = &data->layers[i];
@@ -4085,6 +4070,9 @@ void CustomData_bmesh_interp(CustomData *data,
if (count > SOURCE_BUF_SIZE) {
MEM_freeN((void *)sources);
}
+ if (!ELEM(default_weights, NULL, default_weights_buf)) {
+ MEM_freeN(default_weights);
+ }
}
/**
@@ -4801,6 +4789,9 @@ static void customdata_data_transfer_interp_generic(const CustomDataTransferLaye
const int count,
const float mix_factor)
{
+ BLI_assert(weights != NULL);
+ BLI_assert(count > 0);
+
/* Fake interpolation, we actually copy highest weighted source to dest.
* Note we also handle bitflags here,
* in which case we rather choose to transfer value of elements totaling
@@ -4916,6 +4907,9 @@ void customdata_data_transfer_interp_normal_normals(const CustomDataTransferLaye
const int count,
const float mix_factor)
{
+ BLI_assert(weights != NULL);
+ BLI_assert(count > 0);
+
const int data_type = laymap->data_type;
const int mix_mode = laymap->mix_mode;
@@ -5162,8 +5156,8 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
{
BLO_read_data_address(reader, &data->layers);
- /* annoying workaround for bug [#31079] loading legacy files with
- * no polygons _but_ have stale customdata */
+ /* Annoying workaround for bug T31079 loading legacy files with
+ * no polygons _but_ have stale custom-data. */
if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) {
CustomData_reset(data);
return;