[Bf-blender-cvs] [12cb22d5f6b] sculpt-dev: Sculpt IPMask: Multithreaded compute step

Pablo Dobarro noreply at git.blender.org
Fri Feb 26 14:59:01 CET 2021


Commit: 12cb22d5f6bb708076e457a401c16581be3732a5
Author: Pablo Dobarro
Date:   Fri Feb 26 00:25:06 2021 +0100
Branches: sculpt-dev
https://developer.blender.org/rB12cb22d5f6bb708076e457a401c16581be3732a5

Sculpt IPMask: Multithreaded compute step

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

M	source/blender/editors/sculpt_paint/sculpt_filter_mask.c

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

diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
index ce2619279a5..bf84a4919e9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
@@ -322,6 +322,9 @@ void SCULPT_OT_mask_filter(struct wmOperatorType *ot)
 /* Interactive Preview Mask Filter */
 
 
+#define SCULPT_IPMASK_FILTER_MIN_MULTITHREAD 1000
+#define SCULPT_IPMASK_FILTER_GRANULARITY 1000
+
 typedef enum eSculptIPMaskFilterType {
   MASK_FILTER_SMOOTH_SHARPEN,
   MASK_FILTER_GROW_SHRINK,
@@ -341,34 +344,6 @@ typedef struct MaskFilterDeltaStep {
     float *delta;
 } MaskFilterDeltaStep;
 
-
-static MaskFilterDeltaStep *sculpt_ipmask_filter_delta_create(const float *current_mask, const float *next_mask, const int totvert) {
-    int tot_modified_values = 0;
-    for (int i = 0; i < totvert; i++) {
-        if (current_mask[i] == next_mask[i]) {
-            continue;
-        }
-        tot_modified_values++;
-    }
-
-    MaskFilterDeltaStep *delta_step = MEM_callocN(sizeof (MaskFilterDeltaStep), "mask filter delta step");
-    delta_step->totelem = tot_modified_values;
-    delta_step->index = MEM_malloc_arrayN(sizeof (int), tot_modified_values, "delta indices");
-    delta_step->delta = MEM_malloc_arrayN(sizeof (float), tot_modified_values, "delta values");
-
-    int delta_step_index = 0;
-    for (int i = 0; i < totvert; i++) {
-        if (current_mask[i] == next_mask[i]) {
-            continue;
-        }
-        delta_step->index[delta_step_index] = i;
-        delta_step->delta[delta_step_index] = next_mask[i] - current_mask[i];
-        delta_step_index++;
-    }
-    return delta_step;
-}
-
-
 /* Grown/Shrink vertex callbacks. */
 static float sculpt_ipmask_vertex_grow_cb(SculptSession *ss, const int vertex, const float *current_mask) {
         float max = 0.0f;
@@ -435,18 +410,67 @@ static float sculpt_ipmask_vertex_sharpen_cb(SculptSession *ss, const int vertex
 }
 
 
-static float *sculpt_ipmask_step_compute(SculptSession *ss, const float *current_mask, MaskFilterStepDirectionType direction) {
-    const int totvert = SCULPT_vertex_count_get(ss);
-    float *next_mask = MEM_malloc_arrayN(sizeof (float), totvert, "delta values");
+static MaskFilterDeltaStep *sculpt_ipmask_filter_delta_create(const float *current_mask, const float *next_mask, const int totvert) {
+    int tot_modified_values = 0;
     for (int i = 0; i < totvert; i++) {
-        //next_mask[i] = sculpt_ipmask_vertex_shrink_cb(ss, i, current_mask);
-        if (direction == MASK_FILTER_STEP_DIRECTION_FORWARD) {
-            next_mask[i] = sculpt_ipmask_vertex_smooth_cb(ss, i, current_mask);
+        if (current_mask[i] == next_mask[i]) {
+            continue;
         }
-        else {
-            next_mask[i] = sculpt_ipmask_vertex_sharpen_cb(ss, i, current_mask);
+        tot_modified_values++;
+    }
+
+    MaskFilterDeltaStep *delta_step = MEM_callocN(sizeof (MaskFilterDeltaStep), "mask filter delta step");
+    delta_step->totelem = tot_modified_values;
+    delta_step->index = MEM_malloc_arrayN(sizeof (int), tot_modified_values, "delta indices");
+    delta_step->delta = MEM_malloc_arrayN(sizeof (float), tot_modified_values, "delta values");
+
+    int delta_step_index = 0;
+    for (int i = 0; i < totvert; i++) {
+        if (current_mask[i] == next_mask[i]) {
+            continue;
         }
+        delta_step->index[delta_step_index] = i;
+        delta_step->delta[delta_step_index] = next_mask[i] - current_mask[i];
+        delta_step_index++;
     }
+    return delta_step;
+}
+
+typedef struct SculptIPMaskFilterTaskData {
+    SculptSession *ss;
+    float *next_mask;
+    float *current_mask;
+    MaskFilterStepDirectionType direction;
+} SculptIPMaskFilterTaskData;
+
+static void ipmask_filter_compute_step_task_cb(void *__restrict userdata,
+                                const int i,
+                                const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  SculptIPMaskFilterTaskData *data = userdata;
+        if (data->direction == MASK_FILTER_STEP_DIRECTION_FORWARD) {
+            data->next_mask[i] = sculpt_ipmask_vertex_grow_cb(data->ss, i, data->current_mask);
+        }
+        else {
+            data->next_mask[i] = sculpt_ipmask_vertex_shrink_cb(data->ss, i, data->current_mask);
+        }
+}
+
+static float *sculpt_ipmask_step_compute(SculptSession *ss, float *current_mask, MaskFilterStepDirectionType direction) {
+    const int totvert = SCULPT_vertex_count_get(ss);
+    float *next_mask = MEM_malloc_arrayN(sizeof (float), totvert, "delta values");
+
+    SculptIPMaskFilterTaskData data = {
+        .ss = ss,
+        .next_mask = next_mask,
+        .current_mask = current_mask,
+        .direction = direction,
+    };
+    TaskParallelSettings settings;
+    memset(&settings, 0, sizeof(TaskParallelSettings));
+    settings.use_threading = totvert > SCULPT_IPMASK_FILTER_MIN_MULTITHREAD;
+    BLI_task_parallel_range(0, totvert, &data, ipmask_filter_compute_step_task_cb, &settings);
+
     return next_mask;
 }



More information about the Bf-blender-cvs mailing list