Commit: 3c90304b4e1443e9285a0b4ba80690e8f66c031f
Author: Bastien Montagne
Date:   Mon May 30 17:30:06 2016 +0200
Branches: compositor-2016
https://developer.blender.org/rB3c90304b4e1443e9285a0b4ba80690e8f66c031f

Shrinkwrap: OMP->BLI_task.

Gives little to no speedup (a few percents at best).

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

M       source/blender/blenkernel/intern/shrinkwrap.c

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

diff --git a/source/blender/blenkernel/intern/shrinkwrap.c 
b/source/blender/blenkernel/intern/shrinkwrap.c
index e855f6f..b9f7afb 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -44,6 +44,7 @@
 
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
+#include "BLI_task.h"
 
 #include "BKE_shrinkwrap.h"
 #include "BKE_DerivedMesh.h"
@@ -58,7 +59,7 @@
 
 /* for timing... */
 #if 0
-#  include "PIL_time.h"
+#  include "PIL_time_utildefines.h"
 #else
 #  define TIMEIT_BENCH(expr, id) (expr)
 #endif
@@ -66,16 +67,88 @@
 /* Util macros */
 #define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n"))
 
+typedef struct ShrinkwrapCalcCBData {
+       ShrinkwrapCalcData *calc;
+
+       void *treeData;
+       void *auxData;
+       BVHTree *targ_tree;
+       BVHTree *aux_tree;
+       void *targ_callback;
+       void *aux_callback;
+
+       float *proj_axis;
+       SpaceTransform *local2aux;
+} ShrinkwrapCalcCBData;
+
 /*
  * Shrinkwrap to the nearest vertex
  *
  * it builds a kdtree of vertexs we can attach to and then
  * for each vertex performs a nearest vertex search on the tree
  */
-static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
+static void shrinkwrap_calc_nearest_vertex_cb_ex(
+        void *userdata, void *userdata_chunk, const int i, const int 
UNUSED(threadid))
 {
-       int i;
+       ShrinkwrapCalcCBData *data = userdata;
+
+       ShrinkwrapCalcData *calc = data->calc;
+       BVHTreeFromMesh *treeData = data->treeData;
+       BVHTreeNearest *nearest = userdata_chunk;
+
+       float *co = calc->vertexCos[i];
+       float tmp_co[3];
+       float weight = defvert_array_find_weight_safe(calc->dvert, i, 
calc->vgroup);
+
+       if (calc->invert_vgroup) {
+               weight = 1.0f - weight;
+       }
+
+       if (weight == 0.0f) {
+               return;
+       }
+
+       /* Convert the vertex to tree coordinates */
+       if (calc->vert) {
+               copy_v3_v3(tmp_co, calc->vert[i].co);
+       }
+       else {
+               copy_v3_v3(tmp_co, co);
+       }
+       BLI_space_transform_apply(&calc->local2target, tmp_co);
+
+       /* Use local proximity heuristics (to reduce the nearest search)
+        *
+        * If we already had an hit before.. we assume this vertex is going to 
have a close hit to that other vertex
+        * so we can initiate the "nearest.dist" with the expected value to 
that last hit.
+        * This will lead in pruning of the search tree. */
+       if (nearest->index != -1)
+               nearest->dist_sq = len_squared_v3v3(tmp_co, nearest->co);
+       else
+               nearest->dist_sq = FLT_MAX;
+
+       BLI_bvhtree_find_nearest(treeData->tree, tmp_co, nearest, 
treeData->nearest_callback, treeData);
+
+
+       /* Found the nearest vertex */
+       if (nearest->index != -1) {
+               /* Adjusting the vertex weight,
+                * so that after interpolating it keeps a certain distance from 
the nearest position */
+               if (nearest->dist_sq > FLT_EPSILON) {
+                       const float dist = sqrtf(nearest->dist_sq);
+                       weight *= (dist - calc->keepDist) / dist;
+               }
+
+               /* Convert the coordinates back to mesh coordinates */
+               copy_v3_v3(tmp_co, nearest->co);
+               BLI_space_transform_invert(&calc->local2target, tmp_co);
+
+               interp_v3_v3v3(co, co, tmp_co, weight);  /* linear 
interpolation */
+       }
+}
 
+static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
+{
        BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
        BVHTreeNearest nearest  = NULL_BVHTreeNearest;
 
@@ -89,61 +162,11 @@ static void 
shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
        /* Setup nearest */
        nearest.index = -1;
        nearest.dist_sq = FLT_MAX;
-#ifndef __APPLE__
-#pragma omp parallel for default(none) private(i) firstprivate(nearest) 
shared(treeData, calc) schedule(static) if (calc->numVerts > BKE_MESH_OMP_LIMIT)
-#endif
-       for (i = 0; i < calc->numVerts; ++i) {
-               float *co = calc->vertexCos[i];
-               float tmp_co[3];
-               float weight = defvert_array_find_weight_safe(calc->dvert, i, 
calc->vgroup);
-
-               if (calc->invert_vgroup) {
-                       weight = 1.0f - weight;
-               }
-
-               if (weight == 0.0f) {
-                       continue;
-               }
-
-
-               /* Convert the vertex to tree coordinates */
-               if (calc->vert) {
-                       copy_v3_v3(tmp_co, calc->vert[i].co);
-               }
-               else {
-                       copy_v3_v3(tmp_co, co);
-               }
-               BLI_space_transform_apply(&calc->local2target, tmp_co);
-
-               /* Use local proximity heuristics (to reduce the nearest search)
-                *
-                * If we already had an hit before.. we assume this vertex is 
going to have a close hit to that other vertex
-                * so we can initiate the "nearest.dist" with the expected 
value to that last hit.
-                * This will lead in pruning of the search tree. */
-               if (nearest.index != -1)
-                       nearest.dist_sq = len_squared_v3v3(tmp_co, nearest.co);
-               else
-                       nearest.dist_sq = FLT_MAX;
-
-               BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, 
treeData.nearest_callback, &treeData);
-
-
-               /* Found the nearest vertex */
-               if (nearest.index != -1) {
-                       /* Adjusting the vertex weight,
-                        * so that after interpolating it keeps a certain 
distance from the nearest position */
-                       if (nearest.dist_sq > FLT_EPSILON) {
-                               const float dist = sqrtf(nearest.dist_sq);
-                               weight *= (dist - calc->keepDist) / dist;
-                       }
 
-                       /* Convert the coordinates back to mesh coordinates */
-                       copy_v3_v3(tmp_co, nearest.co);
-                       BLI_space_transform_invert(&calc->local2target, tmp_co);
-
-                       interp_v3_v3v3(co, co, tmp_co, weight);  /* linear 
interpolation */
-               }
-       }
+       ShrinkwrapCalcCBData data = {.calc = calc, .treeData = &treeData};
+       BLI_task_parallel_range_ex(
+                   0, calc->numVerts, &data, &nearest, sizeof(nearest), 
shrinkwrap_calc_nearest_vertex_cb_ex,
+                   calc->numVerts > BKE_MESH_OMP_LIMIT, false);
 
        free_bvhtree_from_mesh(&treeData);
 }
@@ -230,13 +253,109 @@ bool BKE_shrinkwrap_project_normal(
        return false;
 }
 
+static void shrinkwrap_calc_normal_projection_cb_ex(
+        void *userdata, void *userdata_chunk, const int i, const int 
UNUSED(threadid))
+{
+       ShrinkwrapCalcCBData *data = userdata;
+
+       ShrinkwrapCalcData *calc = data->calc;
+       void *treeData = data->treeData;
+       void *auxData = data->auxData;
+       BVHTree *targ_tree = data->targ_tree;
+       BVHTree *aux_tree = data->aux_tree;
+       void *targ_callback = data->targ_callback;
+       void *aux_callback = data->aux_callback;
+
+       float *proj_axis = data->proj_axis;
+       SpaceTransform *local2aux = data->local2aux;
+
+       BVHTreeRayHit *hit = userdata_chunk;
+
+       const float proj_limit_squared = calc->smd->projLimit * 
calc->smd->projLimit;
+       float *co = calc->vertexCos[i];
+       float tmp_co[3], tmp_no[3];
+       float weight = defvert_array_find_weight_safe(calc->dvert, i, 
calc->vgroup);
+
+       if (calc->invert_vgroup) {
+               weight = 1.0f - weight;
+       }
+
+       if (weight == 0.0f) {
+               return;
+       }
+
+       if (calc->vert) {
+               /* calc->vert contains verts from derivedMesh  */
+               /* this coordinated are deformed by vertexCos only for normal 
projection (to get correct normals) */
+               /* for other cases calc->varts contains undeformed coordinates 
and vertexCos should be used */
+               if (calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
+                       copy_v3_v3(tmp_co, calc->vert[i].co);
+                       normal_short_to_float_v3(tmp_no, calc->vert[i].no);
+               }
+               else {
+                       copy_v3_v3(tmp_co, co);
+                       copy_v3_v3(tmp_no, proj_axis);
+               }
+       }
+       else {
+               copy_v3_v3(tmp_co, co);
+               copy_v3_v3(tmp_no, proj_axis);
+       }
+
+
+       hit->index = -1;
+       hit->dist = BVH_RAYCAST_DIST_MAX; /* TODO: we should use FLT_MAX here, 
but sweepsphere code isn't prepared for that */
+
+       /* Project over positive direction of axis */
+       if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) {
+               if (aux_tree) {
+                       BKE_shrinkwrap_project_normal(
+                               0, tmp_co, tmp_no,
+                               local2aux, aux_tree, hit,
+                               aux_callback, auxData);
+               }
+
+               BKE_shrinkwrap_project_normal(
+                       calc->smd->shrinkOpts, tmp_co, tmp_no,
+                       &calc->local2target, targ_tree, hit,
+                       targ_callback, treeData);
+       }
+
+       /* Project over negative direction of axis */
+       if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR) {
+               float inv_no[3];
+               negate_v3_v3(inv_no, tmp_no);
+
+               if (aux_tree) {
+                       BKE_shrinkwrap_project_normal(
+                               0, tmp_co, inv_no,
+                               local2aux, aux_tree, hit,
+                               aux_callback, auxData);
+               }
+
+               BKE_shrinkwrap_project_normal(
+                       calc->smd->shrinkOpts, tmp_co, inv_no,
+                       &calc->local2target, targ_tree, hit,
+                       targ_callback, treeData);
+       }
+
+       /* don't set the initial dist (which is more efficient),
+        * because its calculated in the targets space, we want the dist in our 
own space */
+       if (proj_limit_squared != 0.0f) {
+               if (len_squared_v3v3(hit->co, co) > proj_limit_squared) {
+                       hit->index = -1;
+               }
+       }
+
+       if (hit->index != -1) {
+               madd_v3_v3v3fl(hit->co, hit->co, tmp_no, calc->keepDist);
+               interp_v3_v3v3(co, co, hit->co, weight);
+       }
+}
 
 static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool 
for_render)
 {
-       int i;
-
        /* Options about projection direction */
-       const float proj_limit_squared = calc->smd->projLimit * 
calc->smd->projLimit;
        float proj_axis[3]      = {0.0f, 0.0f, 0.0f};
 
        /* Raycast and tree stuff */
@@ -305,7 +424,7 @@ static void 
shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for
        }
        if (targ_tree) {
                BVHTree *aux_tree = NULL;
-               void *aux_callback;
+               void *aux_callback = NULL;
                if (auxMesh != NULL) {
                        /* use editmesh to avoid array allocation */
                        if (calc->smd->auxTarget && auxMesh->type == 
DM_TYPE_EDITBMESH) {
@@ -323,92 +442,15 @@ static void 
shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for
                        }
                }
                /* After sucessufuly build the trees, start projection vertexs 
*/
-
-#ifndef __APPLE__
-#pragma omp parallel for private(i, hit) schedule(static) if (calc->numVerts > 
BKE_MESH_OMP_LIMIT)
-#endif
-               for (i = 0; i < calc->numVerts; ++i) {
-                       float *co = calc->vertexCos[i];
-                       float tmp_co[3], tmp_no[3];
-                       float weight = 
defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
-
-                       if (calc->invert_vgroup) {
-                               weight = 1.0f - weight;
-                       }
-
-                       if (weight == 0.0f) {
-                               continue;
-                       }
-
-                       if (calc->vert) {
-                               /* calc->vert contains verts from derivedMesh  
*/
-                               /* this coordinated are deformed by vertexCos 
only for normal projection (to get correct normals) */
-                               /* for other cases calc->varts contains 
undeformed coordinates and vertexCos

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to