Commit: a055395487a338ab5e4fe2b749df80cc87da97c5
Author: Bastien Montagne
Date:   Fri May 20 23:16:52 2016 +0200
Branches: master
https://developer.blender.org/rBa055395487a338ab5e4fe2b749df80cc87da97c5

Dynapaint: Serious cleanup and optimization of dynamicPaint_createUVSurface 
(mostly).

Gives 3-4% speedup in pre-bake step (from 112 to 108 seconds with own heavy 
test file).

Note that here we have a huge potential performance boost if we replace the flat
`Bounds2D *faceBB` array of UV tris bounding boxes by a real 2D AABB tree 
(right now,
we can loop over all UV triangles times the number of pixels of the surface 
times 5...).

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

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

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

diff --git a/source/blender/blenkernel/intern/dynamicpaint.c 
b/source/blender/blenkernel/intern/dynamicpaint.c
index 9e384eb..daf1e86 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -529,7 +529,7 @@ static int surface_getBrushFlags(DynamicPaintSurface 
*surface, const Scene *scen
        return flags;
 }
 
-static int brush_usesMaterial(DynamicPaintBrushSettings *brush, Scene *scene)
+static int brush_usesMaterial(const DynamicPaintBrushSettings *brush, const 
Scene *scene)
 {
        return ((brush->flags & MOD_DPAINT_USE_MATERIAL) && 
(!BKE_scene_use_new_shading_nodes(scene)));
 }
@@ -2174,11 +2174,9 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
                    0.4f, -0.2f,
                    -0.4f, 0.3f,
        };
-       int ty;
-       int w, h;
-       int tottri;
+       const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
        char uvname[MAX_CUSTOMDATA_LAYER_NAME];
-       int active_points = 0;
+       uint32_t active_points = 0;
        bool error = false;
 
        PaintSurfaceData *sData;
@@ -2193,7 +2191,6 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
 
        Bounds2D *faceBB = NULL;
        int *final_index;
-       int aa_samples;
 
        if (!dm)
                return setError(canvas, N_("Canvas mesh not updated"));
@@ -2202,7 +2199,7 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
 
        mloop = dm->getLoopArray(dm);
        mlooptri = dm->getLoopTriArray(dm);
-       tottri = dm->getNumLoopTri(dm);
+       const int tottri = dm->getNumLoopTri(dm);
 
        /* get uv map */
        if (CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
@@ -2216,7 +2213,8 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
        if (surface->image_resolution < 16 || surface->image_resolution > 8192)
                return setError(canvas, N_("Invalid resolution"));
 
-       w = h = surface->image_resolution;
+       const int w = surface->image_resolution;
+       const int h = w;
 
        /*
         *      Start generating the surface
@@ -2230,16 +2228,15 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
        if (!surface->data)
                return setError(canvas, N_("Not enough free memory"));
 
-       aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
-       tempPoints = (struct PaintUVPoint *) MEM_callocN(w * h * sizeof(struct 
PaintUVPoint), "Temp PaintUVPoint");
+       tempPoints = MEM_callocN(w * h * sizeof(*tempPoints), "Temp 
PaintUVPoint");
        if (!tempPoints)
                error = true;
 
-       final_index = (int *) MEM_callocN(w * h * sizeof(int), "Temp UV Final 
Indexes");
+       final_index = MEM_callocN(w * h * sizeof(*final_index), "Temp UV Final 
Indexes");
        if (!final_index)
                error = true;
 
-       tempWeights = (struct Vec3f *) MEM_mallocN(w * h * aa_samples * 
sizeof(struct Vec3f), "Temp bWeights");
+       tempWeights = MEM_mallocN(w * h * aa_samples * sizeof(*tempWeights), 
"Temp bWeights");
        if (!tempWeights)
                error = true;
 
@@ -2248,31 +2245,27 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
         *      the pixel-inside-a-face search.
         */
        if (!error) {
-               faceBB = (struct Bounds2D *) MEM_mallocN(tottri * sizeof(struct 
Bounds2D), "MPCanvasFaceBB");
+               faceBB = MEM_mallocN(tottri * sizeof(*faceBB), 
"MPCanvasFaceBB");
                if (!faceBB)
                        error = true;
        }
 
        if (!error) {
-               for (ty = 0; ty < tottri; ty++) {
-                       int i;
-
-                       copy_v2_v2(faceBB[ty].min, 
mloopuv[mlooptri[ty].tri[0]].uv);
-                       copy_v2_v2(faceBB[ty].max, 
mloopuv[mlooptri[ty].tri[0]].uv);
+               for (int i = 0; i < tottri; i++) {
+                       copy_v2_v2(faceBB[i].min, 
mloopuv[mlooptri[i].tri[0]].uv);
+                       copy_v2_v2(faceBB[i].max, 
mloopuv[mlooptri[i].tri[0]].uv);
 
-                       for (i = 1; i < 3; i++) {
-                               minmax_v2v2_v2(faceBB[ty].min, faceBB[ty].max, 
mloopuv[mlooptri[ty].tri[i]].uv);
+                       for (int j = 1; j < 3; j++) {
+                               minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, 
mloopuv[mlooptri[i].tri[j]].uv);
                        }
                }
 
                /* Loop through every pixel and check if pixel is uv-mapped on 
a canvas face. */
 #pragma omp parallel for schedule(static)
-               for (ty = 0; ty < h; ty++) {
-                       int tx;
-                       for (tx = 0; tx < w; tx++) {
-                               int i, sample;
-                               int index = tx + w * ty;
-                               PaintUVPoint *tPoint = (&tempPoints[index]);
+               for (int ty = 0; ty < h; ty++) {
+                       for (int tx = 0; tx < w; tx++) {
+                               const int index = tx + w * ty;
+                               PaintUVPoint *tPoint = &tempPoints[index];
                                float point[5][2];
 
                                /* Init per pixel settings */
@@ -2302,14 +2295,15 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
 
 
                                /* Loop through samples, starting from middle 
point     */
-                               for (sample = 0; sample < 5; sample++) {
+                               for (int sample = 0; sample < 5; sample++) {
                                        /* Loop through every face in the mesh  
*/
-                                       for (i = 0; i < tottri; i++) {
+                                       /* XXX TODO This is *horrible* with big 
meshes, should use a 2D BVHTree over UV tris here! */
+                                       for (int i = 0; i < tottri; i++) {
                                                /* Check uv bb  */
-                                               if ((faceBB[i].min[0] > 
(point[sample][0])) ||
-                                                   (faceBB[i].min[1] > 
(point[sample][1])) ||
-                                                   (faceBB[i].max[0] < 
(point[sample][0])) ||
-                                                   (faceBB[i].max[1] < 
(point[sample][1])))
+                                               if ((faceBB[i].min[0] > 
point[sample][0]) ||
+                                                   (faceBB[i].min[1] > 
point[sample][1]) ||
+                                                   (faceBB[i].max[0] < 
point[sample][0]) ||
+                                                   (faceBB[i].max[1] < 
point[sample][1]))
                                                {
                                                        continue;
                                                }
@@ -2353,42 +2347,51 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
                 *      (To avoid seams on uv island edges)
                 */
 #pragma omp parallel for schedule(static)
-               for (ty = 0; ty < h; ty++) {
-                       int tx;
-                       for (tx = 0; tx < w; tx++) {
-                               int index = tx + w * ty;
-                               PaintUVPoint *tPoint = (&tempPoints[index]);
+               for (int ty = 0; ty < h; ty++) {
+                       for (int tx = 0; tx < w; tx++) {
+                               const int index = tx + w * ty;
+                               PaintUVPoint *tPoint = &tempPoints[index];
 
-                               /* If point isn't't on canvas mesh      */
+                               /* If point isn't on canvas mesh        */
                                if (tPoint->tri_index == -1) {
-                                       int u_min, u_max, v_min, v_max;
-                                       int u, v, ind;
                                        float point[2];
 
                                        /* get loop area        */
-                                       u_min = (tx > 0) ? -1 : 0;
-                                       u_max = (tx < (w - 1)) ? 1 : 0;
-                                       v_min = (ty > 0) ? -1 : 0;
-                                       v_max = (ty < (h - 1)) ? 1 : 0;
+                                       const int u_min = (tx > 0) ? -1 : 0;
+                                       const int u_max = (tx < (w - 1)) ? 1 : 
0;
+                                       const int v_min = (ty > 0) ? -1 : 0;
+                                       const int v_max = (ty < (h - 1)) ? 1 : 
0;
 
                                        point[0] = ((float)tx + 0.5f) / w;
                                        point[1] = ((float)ty + 0.5f) / h;
 
                                        /* search through defined area for 
neighbor     */
-                                       for (u = u_min; u <= u_max; u++)
-                                               for (v = v_min; v <= v_max; 
v++) {
+                                       for (int u = u_min; u <= u_max; u++) {
+                                               for (int v = v_min; v <= v_max; 
v++) {
                                                        /* if not this pixel 
itself     */
                                                        if (u != 0 || v != 0) {
-                                                               ind = (tx + u) 
+ w * (ty + v);
+                                                               const int ind = 
(tx + u) + w * (ty + v);
 
-                                                               /* if neighbor 
has index        */
-                                                               if 
(tempPoints[ind].tri_index != -1) {
+                                                               /* if neighbor 
has index */
+                                                               if 
(tempPoints[ind].neighbour_pixel == -1 && tempPoints[ind].tri_index != -1) {
                                                                        float 
uv[2];
                                                                        const 
int i = tempPoints[ind].tri_index;
                                                                        const 
float *uv1 = mloopuv[mlooptri[i].tri[0]].uv;
                                                                        const 
float *uv2 = mloopuv[mlooptri[i].tri[1]].uv;
                                                                        const 
float *uv3 = mloopuv[mlooptri[i].tri[2]].uv;
 
+                                                                       /* tri 
index */
+                                                                       /* 
There is a low possibility of actually having a neighbor point which tri is
+                                                                        * 
already set from another neighbor in a separate thread here.
+                                                                        * 
Cheking for both tri_index and neighbour_pixel above reduces that probability
+                                                                        * but 
it remains possible.
+                                                                        * That 
atomic op (and its memory fence) ensures tPoint->neighbour_pixel is set
+                                                                        * to 
non--1 *before* its tri_index is set (i.e. that it cannot be used a neighbour).
+                                                                        */
+                                                                       
tPoint->neighbour_pixel = ind - 1;
+                                                                       
atomic_add_uint32(&tPoint->neighbour_pixel, 1);
+                                                                       
tPoint->tri_index = i;
+
                                                                        /* Now 
calculate pixel data for this pixel as it was on polygon surface */
                                                                        /* Add 
b-weights per anti-aliasing sample       */
                                                                        for 
(int j = 0; j < aa_samples; j++) {
@@ -2397,9 +2400,6 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
                                                                                
barycentric_weights_v2(uv1, uv2, uv3, uv, tempWeights[index * aa_samples + 
j].v);
                                                                        }
 
-                                                                       /* Set 
values   */
-                                                                       
tPoint->neighbour_pixel = ind;  /* tri index */
-
                                                                        /* save 
vertex indexes  */
                                                                        
tPoint->v1 = mloop[mlooptri[i].tri[0]].v;
                                                                        
tPoint->v2 = mloop[mlooptri[i].tri[1]].v;
@@ -2410,24 +2410,12 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
                                                                }
                                                        }
                                                }
+                                       }
                                }
-                       }
-               }
 
-               /*
-                *      When base loop is over convert found neighbor indexes 
to real ones
-                *      Also count the final number of active surface points
-                */
-               for (ty = 0; ty < h; ty++) {
-                       int tx;
-                       for (tx = 0; tx < w; tx++) {
-                               int index = tx + w * ty;
-                               PaintUVPoint *tPoint = &tempPoints[index];
-
-                               if (tPoint->tri_index == -1 && 
tPoint->neighbour_pixel != -1)
-                                       tPoint->tri_index = 
tempPoints[tPoint->neighbour_pixel].tri_index;
+                               /* Increase the final number of active surface 
points if relevant. */
                                if (tPoint->tri_index != -1)
-                                       active_points++;
+                                       atomic_add_uint32(&active_points, 1);
                        }
                }
 
@@ -2450,20 +2438,17 @@ int dynamicPaint_createUVSurface(Scene *scene, 
DynamicPaintSurface *surface)
                        if (sData->adj_data) {
                                PaintAdjData *ed = sData->adj_data;
                                unsigned int n_pos = 0;
-                               for (ty = 0; ty < h; ty++) {
-                                       int tx;
-                                       for (tx = 0; tx < w; tx++) {
-                                               int index = tx + w * ty;
+                               for (int ty = 0; ty < h; ty++) {
+                                       for (int tx = 0; tx < w; tx++) {
+                                               const int index = tx + w * ty;
 
                                                if (tempPoints[index].tri_index 
!= -1) {
                                                        
ed->n_index[final_index[index]] = n_pos;
                                                        
ed->n_num[final_index[index]] = 0;
 
                                                        for (int i = 0; i < 8; 
i++) {
-
-                                                               /* Try to find 
a neighboring pixel in defined direction
-                                                                *  If not 
found, -1 is returned */
-                                                               int n_target = 
dynamicPaint_findNeighbourPixel(tempPoints, dm, uvname, w, h,

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to