diff options
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/intern/MOD_meshdeform.c | 139 |
1 files changed, 88 insertions, 51 deletions
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 959bbdcbca9..bd6ce26103c 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -37,6 +37,7 @@ #include "DNA_scene_types.h" #include "BLI_math.h" +#include "BLI_task.h" #include "BLI_utildefines.h" #include "BLF_translation.h" @@ -181,6 +182,75 @@ static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3 return totweight; } +typedef struct MeshdeformUserdata { + /*const*/ MeshDeformModifierData *mmd; + const MDeformVert *dvert; + /*const*/ float (*dco)[3]; + int defgrp_index; + float (*vertexCos)[3]; + float (*cagemat)[4]; + float (*icagemat)[3]; + SpinLock lock; +} MeshdeformUserdata; + +static void meshdeform_vert_task(void *userdata, int iter) +{ + MeshdeformUserdata *data = userdata; + /*const*/ MeshDeformModifierData *mmd = data->mmd; + const MDeformVert *dvert = data->dvert; + const int defgrp_index = data->defgrp_index; + const int *offsets = mmd->bindoffsets; + const MDefInfluence *influences = influences = mmd->bindinfluences; + /*const*/ float (*dco)[3] = data->dco; + float (*vertexCos)[3] = data->vertexCos; + float co[3]; + float weight, totweight, fac = 1.0f; + + if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) + if (!mmd->dynverts[iter]) + return; + + if (dvert) { + fac = defvert_find_weight(&dvert[iter], defgrp_index); + + if (mmd->flag & MOD_MDEF_INVERT_VGROUP) { + fac = 1.0f - fac; + } + + if (fac <= 0.0f) { + return; + } + } + + if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) { + /* transform coordinate into cage's local space */ + mul_v3_m4v3(co, data->cagemat, vertexCos[iter]); + totweight = meshdeform_dynamic_bind(mmd, dco, co); + } + else { + int a; + totweight = 0.0f; + zero_v3(co); + + for (a = offsets[iter]; a < offsets[iter + 1]; a++) { + weight = influences[a].weight; + madd_v3_v3fl(co, dco[influences[a].vertex], weight); + totweight += weight; + } + } + + if (totweight > 0.0f) { + mul_v3_fl(co, fac / totweight); + mul_m3_v3(data->icagemat, co); + BLI_spin_lock(&data->lock); + if (G.debug_value != 527) + add_v3_v3(vertexCos[iter], co); + else + copy_v3_v3(vertexCos[iter], co); + BLI_spin_unlock(&data->lock); + } +} + static void meshdeformModifier_do( ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) @@ -188,12 +258,11 @@ static void meshdeformModifier_do( MeshDeformModifierData *mmd = (MeshDeformModifierData *) md; DerivedMesh *tmpdm, *cagedm; MDeformVert *dvert = NULL; - MDefInfluence *influences; - const int *offsets; float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; - float weight, totweight, fac, co[3], (*dco)[3], (*bindcagecos)[3]; - int a, b, totvert, totcagevert, defgrp_index; + float co[3], (*dco)[3], (*bindcagecos)[3]; + int a, totvert, totcagevert, defgrp_index; float (*cagecos)[3]; + MeshdeformUserdata data; if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc)) return; @@ -273,8 +342,6 @@ static void meshdeformModifier_do( /* setup deformation data */ cagedm->getVertCos(cagedm, cagecos); - influences = mmd->bindinfluences; - offsets = mmd->bindoffsets; bindcagecos = (float(*)[3])mmd->bindcagecos; dco = MEM_callocN(sizeof(*dco) * totcagevert, "MDefDco"); @@ -293,51 +360,21 @@ static void meshdeformModifier_do( modifier_get_vgroup(ob, dm, mmd->defgrp_name, &dvert, &defgrp_index); - /* do deformation */ - fac = 1.0f; - - for (b = 0; b < totvert; b++) { - if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) - if (!mmd->dynverts[b]) - continue; - - if (dvert) { - fac = defvert_find_weight(&dvert[b], defgrp_index); - - if (mmd->flag & MOD_MDEF_INVERT_VGROUP) { - fac = 1.0f - fac; - } - - if (fac <= 0.0f) { - continue; - } - } - - if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) { - /* transform coordinate into cage's local space */ - mul_v3_m4v3(co, cagemat, vertexCos[b]); - totweight = meshdeform_dynamic_bind(mmd, dco, co); - } - else { - totweight = 0.0f; - zero_v3(co); - - for (a = offsets[b]; a < offsets[b + 1]; a++) { - weight = influences[a].weight; - madd_v3_v3fl(co, dco[influences[a].vertex], weight); - totweight += weight; - } - } - - if (totweight > 0.0f) { - mul_v3_fl(co, fac / totweight); - mul_m3_v3(icagemat, co); - if (G.debug_value != 527) - add_v3_v3(vertexCos[b], co); - else - copy_v3_v3(vertexCos[b], co); - } - } + /* Initialize data to be pass to the for body function. */ + data.mmd = mmd; + data.dvert = dvert; + data.dco = dco; + data.defgrp_index = defgrp_index; + data.vertexCos = vertexCos; + data.cagemat = cagemat; + data.icagemat = icagemat; + BLI_spin_init(&data.lock); + + /* Do deformation. */ + BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task); + + /* Uninitialize user dtaa used by the task system. */ + BLI_spin_end(&data.lock); /* release cage derivedmesh */ MEM_freeN(dco); |