diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/modifiers/intern/MOD_weightvgmix.c | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/modifiers/intern/MOD_weightvgmix.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_weightvgmix.c | 631 |
1 files changed, 328 insertions, 303 deletions
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 0894d30cfc1..ed2c2e5e940 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -35,7 +35,7 @@ #include "BKE_deform.h" #include "BKE_library_query.h" #include "BKE_modifier.h" -#include "BKE_texture.h" /* Texture masking. */ +#include "BKE_texture.h" /* Texture masking. */ #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_query.h" @@ -51,55 +51,56 @@ static float mix_weight(float weight, float weight2, char mix_mode) { #if 0 - /* - * XXX Don't know why, but the switch version takes many CPU time, - * and produces lag in realtime playback... - */ - switch (mix_mode) - { - case MOD_WVG_MIX_ADD: - return (weight + weight2); - case MOD_WVG_MIX_SUB: - return (weight - weight2); - case MOD_WVG_MIX_MUL: - return (weight * weight2); - case MOD_WVG_MIX_DIV: - /* Avoid dividing by zero (or really small values). */ - if (0.0 <= weight2 < MOD_WVG_ZEROFLOOR) - weight2 = MOD_WVG_ZEROFLOOR; - else if (-MOD_WVG_ZEROFLOOR < weight2) - weight2 = -MOD_WVG_ZEROFLOOR; - return (weight / weight2); - case MOD_WVG_MIX_DIF: - return (weight < weight2 ? weight2 - weight : weight - weight2); - case MOD_WVG_MIX_AVG: - return (weight + weight2) / 2.0; - case MOD_WVG_MIX_SET: - default: - return weight2; - } + /* + * XXX Don't know why, but the switch version takes many CPU time, + * and produces lag in realtime playback... + */ + switch (mix_mode) + { + case MOD_WVG_MIX_ADD: + return (weight + weight2); + case MOD_WVG_MIX_SUB: + return (weight - weight2); + case MOD_WVG_MIX_MUL: + return (weight * weight2); + case MOD_WVG_MIX_DIV: + /* Avoid dividing by zero (or really small values). */ + if (0.0 <= weight2 < MOD_WVG_ZEROFLOOR) + weight2 = MOD_WVG_ZEROFLOOR; + else if (-MOD_WVG_ZEROFLOOR < weight2) + weight2 = -MOD_WVG_ZEROFLOOR; + return (weight / weight2); + case MOD_WVG_MIX_DIF: + return (weight < weight2 ? weight2 - weight : weight - weight2); + case MOD_WVG_MIX_AVG: + return (weight + weight2) / 2.0; + case MOD_WVG_MIX_SET: + default: + return weight2; + } #endif - if (mix_mode == MOD_WVG_MIX_SET) - return weight2; - else if (mix_mode == MOD_WVG_MIX_ADD) - return (weight + weight2); - else if (mix_mode == MOD_WVG_MIX_SUB) - return (weight - weight2); - else if (mix_mode == MOD_WVG_MIX_MUL) - return (weight * weight2); - else if (mix_mode == MOD_WVG_MIX_DIV) { - /* Avoid dividing by zero (or really small values). */ - if (weight2 < 0.0f && weight2 > -MOD_WVG_ZEROFLOOR) - weight2 = -MOD_WVG_ZEROFLOOR; - else if (weight2 >= 0.0f && weight2 < MOD_WVG_ZEROFLOOR) - weight2 = MOD_WVG_ZEROFLOOR; - return (weight / weight2); - } - else if (mix_mode == MOD_WVG_MIX_DIF) - return (weight < weight2 ? weight2 - weight : weight - weight2); - else if (mix_mode == MOD_WVG_MIX_AVG) - return (weight + weight2) * 0.5f; - else return weight2; + if (mix_mode == MOD_WVG_MIX_SET) + return weight2; + else if (mix_mode == MOD_WVG_MIX_ADD) + return (weight + weight2); + else if (mix_mode == MOD_WVG_MIX_SUB) + return (weight - weight2); + else if (mix_mode == MOD_WVG_MIX_MUL) + return (weight * weight2); + else if (mix_mode == MOD_WVG_MIX_DIV) { + /* Avoid dividing by zero (or really small values). */ + if (weight2 < 0.0f && weight2 > -MOD_WVG_ZEROFLOOR) + weight2 = -MOD_WVG_ZEROFLOOR; + else if (weight2 >= 0.0f && weight2 < MOD_WVG_ZEROFLOOR) + weight2 = MOD_WVG_ZEROFLOOR; + return (weight / weight2); + } + else if (mix_mode == MOD_WVG_MIX_DIF) + return (weight < weight2 ? weight2 - weight : weight - weight2); + else if (mix_mode == MOD_WVG_MIX_AVG) + return (weight + weight2) * 0.5f; + else + return weight2; } /************************************** @@ -107,306 +108,330 @@ static float mix_weight(float weight, float weight2, char mix_mode) **************************************/ static void initData(ModifierData *md) { - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; - wmd->default_weight_a = 0.0f; - wmd->default_weight_b = 0.0f; - wmd->mix_mode = MOD_WVG_MIX_SET; - wmd->mix_set = MOD_WVG_SET_AND; + wmd->default_weight_a = 0.0f; + wmd->default_weight_b = 0.0f; + wmd->mix_mode = MOD_WVG_MIX_SET; + wmd->mix_set = MOD_WVG_SET_AND; - wmd->mask_constant = 1.0f; - wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */ - wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL; + wmd->mask_constant = 1.0f; + wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */ + wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL; } -static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks) +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *md, + CustomData_MeshMasks *r_cddata_masks) { - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; - /* We need vertex groups! */ - r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; + /* We need vertex groups! */ + r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; - /* Ask for UV coordinates if we need them. */ - if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) { - r_cddata_masks->fmask |= CD_MASK_MTFACE; - } + /* Ask for UV coordinates if we need them. */ + if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) { + r_cddata_masks->fmask |= CD_MASK_MTFACE; + } - /* No need to ask for CD_PREVIEW_MLOOPCOL... */ + /* No need to ask for CD_PREVIEW_MLOOPCOL... */ } static bool dependsOnTime(ModifierData *md) { - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; - if (wmd->mask_texture) - return BKE_texture_dependsOnTime(wmd->mask_texture); - return false; + if (wmd->mask_texture) + return BKE_texture_dependsOnTime(wmd->mask_texture); + return false; } static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) { - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; - walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP); + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; + walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP); } static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) { - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; - walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER); + walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER); - foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); + foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); } static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData) { - walk(userData, ob, md, "mask_texture"); + walk(userData, ob, md, "mask_texture"); } static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; - if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { - DEG_add_object_relation(ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGMix Modifier"); - DEG_add_object_relation(ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGMix Modifier"); - - DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier"); - } - else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) { - DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier"); - } - if (wmd->mask_texture != NULL) { - DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGMix Modifier"); - } + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; + if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { + DEG_add_object_relation( + ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGMix Modifier"); + DEG_add_object_relation( + ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGMix Modifier"); + + DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier"); + } + else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) { + DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier"); + } + if (wmd->mask_texture != NULL) { + DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGMix Modifier"); + } } -static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams)) +static bool isDisabled(const struct Scene *UNUSED(scene), + ModifierData *md, + bool UNUSED(useRenderParams)) { - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; - /* If no vertex group, bypass. */ - return (wmd->defgrp_name_a[0] == '\0'); + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; + /* If no vertex group, bypass. */ + return (wmd->defgrp_name_a[0] == '\0'); } static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { - BLI_assert(mesh != NULL); - - WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; - - MDeformVert *dvert = NULL; - MDeformWeight **dw1, **tdw1, **dw2, **tdw2; - float *org_w; - float *new_w; - int *tidx, *indices = NULL; - int numIdx = 0; - int i; - /* Flags. */ + BLI_assert(mesh != NULL); + + WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; + + MDeformVert *dvert = NULL; + MDeformWeight **dw1, **tdw1, **dw2, **tdw2; + float *org_w; + float *new_w; + int *tidx, *indices = NULL; + int numIdx = 0; + int i; + /* Flags. */ #if 0 - const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0; + const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0; #endif - /* Get number of verts. */ - const int numVerts = mesh->totvert; - - /* Check if we can just return the original mesh. - * Must have verts and therefore verts assigned to vgroups to do anything useful! - */ - if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) { - return mesh; - } - - /* Get vgroup idx from its name. */ - const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a); - if (defgrp_index == -1) { - return mesh; - } - /* Get second vgroup idx from its name, if given. */ - int defgrp_index_other = -1; - if (wmd->defgrp_name_b[0] != '\0') { - defgrp_index_other = defgroup_name_index(ctx->object, wmd->defgrp_name_b); - if (defgrp_index_other == -1) { - return mesh; - } - } - - const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT); - /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ - if (!has_mdef) { - /* If not affecting all vertices, just return. */ - if (wmd->mix_set != MOD_WVG_SET_ALL) { - return mesh; - } - } - - if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); - } - else { - /* Add a valid data layer! */ - dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); - } - /* Ultimate security check. */ - if (!dvert) { - return mesh; - } - mesh->dvert = dvert; - - /* Find out which vertices to work on. */ - tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx"); - tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1"); - tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2"); - switch (wmd->mix_set) { - case MOD_WVG_SET_A: - /* All vertices in first vgroup. */ - for (i = 0; i < numVerts; i++) { - MDeformWeight *dw = defvert_find_index(&dvert[i], defgrp_index); - if (dw) { - tdw1[numIdx] = dw; - tdw2[numIdx] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL; - tidx[numIdx++] = i; - } - } - break; - case MOD_WVG_SET_B: - /* All vertices in second vgroup. */ - for (i = 0; i < numVerts; i++) { - MDeformWeight *dw = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL; - if (dw) { - tdw1[numIdx] = defvert_find_index(&dvert[i], defgrp_index); - tdw2[numIdx] = dw; - tidx[numIdx++] = i; - } - } - break; - case MOD_WVG_SET_OR: - /* All vertices in one vgroup or the other. */ - for (i = 0; i < numVerts; i++) { - MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index); - MDeformWeight *bdw = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL; - if (adw || bdw) { - tdw1[numIdx] = adw; - tdw2[numIdx] = bdw; - tidx[numIdx++] = i; - } - } - break; - case MOD_WVG_SET_AND: - /* All vertices in both vgroups. */ - for (i = 0; i < numVerts; i++) { - MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index); - MDeformWeight *bdw = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL; - if (adw && bdw) { - tdw1[numIdx] = adw; - tdw2[numIdx] = bdw; - tidx[numIdx++] = i; - } - } - break; - case MOD_WVG_SET_ALL: - default: - /* Use all vertices. */ - for (i = 0; i < numVerts; i++) { - tdw1[i] = defvert_find_index(&dvert[i], defgrp_index); - tdw2[i] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL; - } - numIdx = -1; - break; - } - if (numIdx == 0) { - /* Use no vertices! Hence, return org data. */ - MEM_freeN(tdw1); - MEM_freeN(tdw2); - MEM_freeN(tidx); - return mesh; - } - if (numIdx != -1) { - indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices"); - memcpy(indices, tidx, sizeof(int) * numIdx); - dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1"); - memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx); - MEM_freeN(tdw1); - dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2"); - memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx); - MEM_freeN(tdw2); - } - else { - /* Use all vertices. */ - numIdx = numVerts; - /* Just copy MDeformWeight pointers arrays, they will be freed at the end. */ - dw1 = tdw1; - dw2 = tdw2; - } - MEM_freeN(tidx); - - org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w"); - new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w"); - - /* Mix weights. */ - for (i = 0; i < numIdx; i++) { - float weight2; - org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a; - weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b; - - new_w[i] = mix_weight(org_w[i], weight2, wmd->mix_mode); - } - - /* Do masking. */ - struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); - weightvg_do_mask(ctx, numIdx, indices, org_w, new_w, ctx->object, mesh, wmd->mask_constant, - wmd->mask_defgrp_name, scene, wmd->mask_texture, - wmd->mask_tex_use_channel, wmd->mask_tex_mapping, - wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); - - /* Update (add to) vgroup. - * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup. - */ - weightvg_update_vg(dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f); - - /* If weight preview enabled... */ + /* Get number of verts. */ + const int numVerts = mesh->totvert; + + /* Check if we can just return the original mesh. + * Must have verts and therefore verts assigned to vgroups to do anything useful! + */ + if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) { + return mesh; + } + + /* Get vgroup idx from its name. */ + const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a); + if (defgrp_index == -1) { + return mesh; + } + /* Get second vgroup idx from its name, if given. */ + int defgrp_index_other = -1; + if (wmd->defgrp_name_b[0] != '\0') { + defgrp_index_other = defgroup_name_index(ctx->object, wmd->defgrp_name_b); + if (defgrp_index_other == -1) { + return mesh; + } + } + + const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if (!has_mdef) { + /* If not affecting all vertices, just return. */ + if (wmd->mix_set != MOD_WVG_SET_ALL) { + return mesh; + } + } + + if (has_mdef) { + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); + } + else { + /* Add a valid data layer! */ + dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + } + /* Ultimate security check. */ + if (!dvert) { + return mesh; + } + mesh->dvert = dvert; + + /* Find out which vertices to work on. */ + tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx"); + tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1"); + tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2"); + switch (wmd->mix_set) { + case MOD_WVG_SET_A: + /* All vertices in first vgroup. */ + for (i = 0; i < numVerts; i++) { + MDeformWeight *dw = defvert_find_index(&dvert[i], defgrp_index); + if (dw) { + tdw1[numIdx] = dw; + tdw2[numIdx] = (defgrp_index_other >= 0) ? + defvert_find_index(&dvert[i], defgrp_index_other) : + NULL; + tidx[numIdx++] = i; + } + } + break; + case MOD_WVG_SET_B: + /* All vertices in second vgroup. */ + for (i = 0; i < numVerts; i++) { + MDeformWeight *dw = (defgrp_index_other >= 0) ? + defvert_find_index(&dvert[i], defgrp_index_other) : + NULL; + if (dw) { + tdw1[numIdx] = defvert_find_index(&dvert[i], defgrp_index); + tdw2[numIdx] = dw; + tidx[numIdx++] = i; + } + } + break; + case MOD_WVG_SET_OR: + /* All vertices in one vgroup or the other. */ + for (i = 0; i < numVerts; i++) { + MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index); + MDeformWeight *bdw = (defgrp_index_other >= 0) ? + defvert_find_index(&dvert[i], defgrp_index_other) : + NULL; + if (adw || bdw) { + tdw1[numIdx] = adw; + tdw2[numIdx] = bdw; + tidx[numIdx++] = i; + } + } + break; + case MOD_WVG_SET_AND: + /* All vertices in both vgroups. */ + for (i = 0; i < numVerts; i++) { + MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index); + MDeformWeight *bdw = (defgrp_index_other >= 0) ? + defvert_find_index(&dvert[i], defgrp_index_other) : + NULL; + if (adw && bdw) { + tdw1[numIdx] = adw; + tdw2[numIdx] = bdw; + tidx[numIdx++] = i; + } + } + break; + case MOD_WVG_SET_ALL: + default: + /* Use all vertices. */ + for (i = 0; i < numVerts; i++) { + tdw1[i] = defvert_find_index(&dvert[i], defgrp_index); + tdw2[i] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : + NULL; + } + numIdx = -1; + break; + } + if (numIdx == 0) { + /* Use no vertices! Hence, return org data. */ + MEM_freeN(tdw1); + MEM_freeN(tdw2); + MEM_freeN(tidx); + return mesh; + } + if (numIdx != -1) { + indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices"); + memcpy(indices, tidx, sizeof(int) * numIdx); + dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1"); + memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx); + MEM_freeN(tdw1); + dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2"); + memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx); + MEM_freeN(tdw2); + } + else { + /* Use all vertices. */ + numIdx = numVerts; + /* Just copy MDeformWeight pointers arrays, they will be freed at the end. */ + dw1 = tdw1; + dw2 = tdw2; + } + MEM_freeN(tidx); + + org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w"); + new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w"); + + /* Mix weights. */ + for (i = 0; i < numIdx; i++) { + float weight2; + org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a; + weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b; + + new_w[i] = mix_weight(org_w[i], weight2, wmd->mix_mode); + } + + /* Do masking. */ + struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); + weightvg_do_mask(ctx, + numIdx, + indices, + org_w, + new_w, + ctx->object, + mesh, + wmd->mask_constant, + wmd->mask_defgrp_name, + scene, + wmd->mask_texture, + wmd->mask_tex_use_channel, + wmd->mask_tex_mapping, + wmd->mask_tex_map_obj, + wmd->mask_tex_uvlayer_name); + + /* Update (add to) vgroup. + * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup. + */ + weightvg_update_vg( + dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f); + + /* If weight preview enabled... */ #if 0 /* XXX Currently done in mod stack :/ */ - if (do_prev) - DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices); + if (do_prev) + DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices); #endif - /* Freeing stuff. */ - MEM_freeN(org_w); - MEM_freeN(new_w); - MEM_freeN(dw1); - MEM_freeN(dw2); - MEM_SAFE_FREE(indices); + /* Freeing stuff. */ + MEM_freeN(org_w); + MEM_freeN(new_w); + MEM_freeN(dw1); + MEM_freeN(dw2); + MEM_SAFE_FREE(indices); - /* Return the vgroup-modified mesh. */ - return mesh; + /* Return the vgroup-modified mesh. */ + return mesh; } - ModifierTypeInfo modifierType_WeightVGMix = { - /* name */ "VertexWeightMix", - /* structName */ "WeightVGMixModifierData", - /* structSize */ sizeof(WeightVGMixModifierData), - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ eModifierTypeFlag_AcceptsMesh | - eModifierTypeFlag_SupportsMapping | - eModifierTypeFlag_SupportsEditmode | - eModifierTypeFlag_UsesPreview, - - /* copyData */ modifier_copyData_generic, - - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, - - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachObjectLink */ foreachObjectLink, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ NULL, + /* name */ "VertexWeightMix", + /* structName */ "WeightVGMixModifierData", + /* structSize */ sizeof(WeightVGMixModifierData), + /* type */ eModifierTypeType_NonGeometrical, + /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, + + /* copyData */ modifier_copyData_generic, + + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ NULL, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ dependsOnTime, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ foreachTexLink, + /* freeRuntimeData */ NULL, }; |