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:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-10-22 13:56:52 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-10-22 14:20:41 +0400
commitdfc4de036e39f74aa0a3b1e1734a02f4a9530a78 (patch)
tree2df085daa2c61acada91e542bb86deaed395cb98 /source/blender/modifiers
parent74f40a5217c9c72447a80881c192de72577e869c (diff)
Meshdeform modifier: Use threaded evaluation
This commit switches meshdeform modifier to use threads to evaluate the vertices positions using the central task scheduler. SO now we've got an utility function to help splitting the for loop into tasks using BLI_task module which is pretty straightforward to use: it gets range (which is an integer lower and higher bounds) and the function and userdata to be invoked for each of the iterations. The only weak point for now is the passing the data to the callback, this isn't so trivial to improve in pure C. Reviewers: campbellbarton Differential Revision: https://developer.blender.org/D838
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c139
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);