[Bf-blender-cvs] [425e19bc1fc] master: Modifiers: Performance Simple Deformation

Jagannadhan Ravi noreply at git.blender.org
Fri Apr 23 10:08:37 CEST 2021


Commit: 425e19bc1fca91116d5fceb7e994bdbf7656acc2
Author: Jagannadhan Ravi
Date:   Fri Apr 23 10:06:46 2021 +0200
Branches: master
https://developer.blender.org/rB425e19bc1fca91116d5fceb7e994bdbf7656acc2

Modifiers: Performance Simple Deformation

Use multiprocessing with simple deform modifiers.

Master 2.92 fps this patch 3.13 fps on Ryzen 1700X With Vega 64 GPU.

3970X: 2.85 fps -> 2.95 fps
3990X: 3.15 fps -> 3.41 fps
3995WX: 3.21 fps -> 3.38 fps

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D10609

===================================================================

M	release/scripts/addons
M	source/blender/blenlib/BLI_compiler_attrs.h
M	source/blender/modifiers/intern/MOD_simpledeform.c

===================================================================

diff --git a/release/scripts/addons b/release/scripts/addons
index 81815ea92c2..4cb833e84ac 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 81815ea92c2071a08566dc66d4a871b6e2f5c868
+Subproject commit 4cb833e84acfd2be5fa08ce75118ce9cb60643b8
diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h
index 680c4bc78da..4b5a7d671f2 100644
--- a/source/blender/blenlib/BLI_compiler_attrs.h
+++ b/source/blender/blenlib/BLI_compiler_attrs.h
@@ -98,3 +98,10 @@
 #else
 #  define ATTR_ALIGN(x) __attribute__((aligned(x)))
 #endif
+
+/* Alignment directive */
+#ifdef _WIN64
+#  define ALIGN_STRUCT __declspec(align(64))
+#else
+#  define ALIGN_STRUCT
+#endif
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index ea31bdc6e31..f9d1d5ae566 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -22,9 +22,8 @@
  */
 
 #include "BLI_utildefines.h"
-
 #include "BLI_math.h"
-
+#include "BLI_task.h"
 #include "BLT_translation.h"
 
 #include "DNA_defaults.h"
@@ -57,6 +56,21 @@
 
 #define BEND_EPS 0.000001f
 
+ALIGN_STRUCT struct DeformUserData {
+  bool invert_vgroup;
+  char mode;
+  char deform_axis;
+  int lock_axis;
+  int vgroup;
+  int limit_axis;
+  float weight;
+  float smd_factor;
+  float smd_limit[2];
+  float (*vertexCos)[3];
+  SpaceTransform *transf;
+  MDeformVert *dvert;
+};
+
 /* Re-maps the indices for X Y Z by shifting them up and wrapping, such that
  * X = Y, Y = Z, Z = X (for X axis), and X = Z, Y = X, Z = Y (for Y axis). This
  * exists because the deformations (excluding bend) are based on the Z axis.
@@ -203,6 +217,86 @@ static void simpleDeform_bend(const float factor,
   }
 }
 
+static void simple_helper(void *__restrict userdata,
+                          const int iter,
+                          const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  struct DeformUserData *curr_deform_data = userdata;
+  float weight = BKE_defvert_array_find_weight_safe(curr_deform_data->dvert, iter, curr_deform_data->vgroup);
+  const uint *axis_map = axis_map_table[(curr_deform_data->mode != MOD_SIMPLEDEFORM_MODE_BEND) ?
+                                            curr_deform_data->deform_axis :
+                                            2];
+  const float base_limit[2] = {0.0f, 0.0f};
+
+  if (curr_deform_data->invert_vgroup) {
+    weight = 1.0f - weight;
+  }
+
+  if (weight != 0.0f) {
+    float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
+
+    if (curr_deform_data->transf) {
+      BLI_space_transform_apply(curr_deform_data->transf, curr_deform_data->vertexCos[iter]);
+    }
+
+    copy_v3_v3(co, curr_deform_data->vertexCos[iter]);
+
+    /* Apply axis limits, and axis mappings */
+    if (curr_deform_data->lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) {
+      axis_limit(0, base_limit, co, dcut);
+    }
+    if (curr_deform_data->lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) {
+      axis_limit(1, base_limit, co, dcut);
+    }
+    if (curr_deform_data->lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Z) {
+      axis_limit(2, base_limit, co, dcut);
+    }
+    axis_limit(curr_deform_data->limit_axis, curr_deform_data->smd_limit, co, dcut);
+
+    /* apply the deform to a mapped copy of the vertex, and then re-map it back. */
+    float co_remap[3];
+    float dcut_remap[3];
+    copy_v3_v3_map(co_remap, co, axis_map);
+    copy_v3_v3_map(dcut_remap, dcut, axis_map);
+    switch (curr_deform_data->mode) {
+      case MOD_SIMPLEDEFORM_MODE_TWIST:
+        simpleDeform_twist(curr_deform_data->smd_factor,
+                           curr_deform_data->deform_axis,
+                           dcut_remap,
+                           co_remap); /* apply deform */
+        break;
+      case MOD_SIMPLEDEFORM_MODE_BEND:
+        simpleDeform_bend(curr_deform_data->smd_factor,
+                          curr_deform_data->deform_axis,
+                          dcut_remap,
+                          co_remap); /* apply deform */
+        break;
+      case MOD_SIMPLEDEFORM_MODE_TAPER:
+        simpleDeform_taper(curr_deform_data->smd_factor,
+                           curr_deform_data->deform_axis,
+                           dcut_remap,
+                           co_remap); /* apply deform */
+        break;
+      case MOD_SIMPLEDEFORM_MODE_STRETCH:
+        simpleDeform_stretch(curr_deform_data->smd_factor,
+                             curr_deform_data->deform_axis,
+                             dcut_remap,
+                             co_remap); /* apply deform */
+        break;
+      default:
+        return; /* No simple-deform mode? */
+    }
+    copy_v3_v3_unmap(co, co_remap, axis_map);
+
+    /* Use vertex weight has coef of linear interpolation */
+    interp_v3_v3v3(curr_deform_data->vertexCos[iter], curr_deform_data->vertexCos[iter], co, weight);
+
+    if (curr_deform_data->transf) {
+      BLI_space_transform_invert(curr_deform_data->transf, curr_deform_data->vertexCos[iter]);
+    }
+  }
+}
+
 /* simple deform modifier */
 static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
                                     const ModifierEvalContext *UNUSED(ctx),
@@ -211,14 +305,9 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
                                     float (*vertexCos)[3],
                                     int numVerts)
 {
-  const float base_limit[2] = {0.0f, 0.0f};
   int i;
   float smd_limit[2], smd_factor;
   SpaceTransform *transf = NULL, tmp_transf;
-  void (*simpleDeform_callback)(const float factor,
-                                const int axis,
-                                const float dcut[3],
-                                float co[3]) = NULL; /* Mode callback */
   int vgroup;
   MDeformVert *dvert;
 
@@ -300,23 +389,6 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
     smd_factor = smd->factor / max_ff(FLT_EPSILON, smd_limit[1] - smd_limit[0]);
   }
 
-  switch (smd->mode) {
-    case MOD_SIMPLEDEFORM_MODE_TWIST:
-      simpleDeform_callback = simpleDeform_twist;
-      break;
-    case MOD_SIMPLEDEFORM_MODE_BEND:
-      simpleDeform_callback = simpleDeform_bend;
-      break;
-    case MOD_SIMPLEDEFORM_MODE_TAPER:
-      simpleDeform_callback = simpleDeform_taper;
-      break;
-    case MOD_SIMPLEDEFORM_MODE_STRETCH:
-      simpleDeform_callback = simpleDeform_stretch;
-      break;
-    default:
-      return; /* No simple-deform mode? */
-  }
-
   if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) {
     if (fabsf(smd_factor) < BEND_EPS) {
       return;
@@ -325,53 +397,24 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
 
   MOD_get_vgroup(ob, mesh, smd->vgroup_name, &dvert, &vgroup);
   const bool invert_vgroup = (smd->flag & MOD_SIMPLEDEFORM_FLAG_INVERT_VGROUP) != 0;
-  const uint *axis_map =
-      axis_map_table[(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? deform_axis : 2];
-
-  for (i = 0; i < numVerts; i++) {
-    float weight = BKE_defvert_array_find_weight_safe(dvert, i, vgroup);
-
-    if (invert_vgroup) {
-      weight = 1.0f - weight;
-    }
-
-    if (weight != 0.0f) {
-      float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
 
-      if (transf) {
-        BLI_space_transform_apply(transf, vertexCos[i]);
-      }
-
-      copy_v3_v3(co, vertexCos[i]);
-
-      /* Apply axis limits, and axis mappings */
-      if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) {
-        axis_limit(0, base_limit, co, dcut);
-      }
-      if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) {
-        axis_limit(1, base_limit, co, dcut);
-      }
-      if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Z) {
-        axis_limit(2, base_limit, co, dcut);
-      }
-      axis_limit(limit_axis, smd_limit, co, dcut);
-
-      /* apply the deform to a mapped copy of the vertex, and then re-map it back. */
-      float co_remap[3];
-      float dcut_remap[3];
-      copy_v3_v3_map(co_remap, co, axis_map);
-      copy_v3_v3_map(dcut_remap, dcut, axis_map);
-      simpleDeform_callback(smd_factor, deform_axis, dcut_remap, co_remap); /* apply deform */
-      copy_v3_v3_unmap(co, co_remap, axis_map);
-
-      /* Use vertex weight has coef of linear interpolation */
-      interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight);
-
-      if (transf) {
-        BLI_space_transform_invert(transf, vertexCos[i]);
-      }
-    }
-  }
+  // build our data
+  struct DeformUserData deform_pool_data = {.mode = smd->mode,
+                                            .smd_factor = smd_factor,
+                                            .deform_axis = deform_axis,
+                                            .transf = transf,
+                                            .vertexCos = vertexCos,
+                                            .invert_vgroup = invert_vgroup,
+                                            .lock_axis = lock_axis,
+                                            .vgroup = vgroup,
+                                            .smd_limit[0] = smd_limit[0],
+                                            .smd_limit[1] = smd_limit[1],
+                                            .dvert = dvert,
+                                            .limit_axis = limit_axis};
+  /* Do deformation. */
+  TaskParallelSettings settings;
+  BLI_parallel_range_settings_defaults(&settings);
+  BLI_task_parallel_range(0, numVerts, &deform_pool_data, simple_helper, &settings);
 }
 
 /* SimpleDeform */



More information about the Bf-blender-cvs mailing list