Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 11 Jan 2018 19:19:18 +0000 (20:19 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 11 Jan 2018 19:19:18 +0000 (20:19 +0100)
Conflicts:
source/blender/blenkernel/intern/multires.c

1  2 
source/blender/blenkernel/intern/multires.c

index 7ef4b588dcd74f9b4c1a20ae2a4800f2b8a3f4de,3fc052414eb75869e89b53a76aaa495b821771ad..b6e3d048f0b456d29abfa5236cad51178f4c8be7
@@@ -44,6 -44,7 +44,7 @@@
  #include "BLI_blenlib.h"
  #include "BLI_math.h"
  #include "BLI_utildefines.h"
+ #include "BLI_task.h"
  
  #include "BKE_pbvh.h"
  #include "BKE_ccg.h"
@@@ -276,14 -277,14 +277,14 @@@ static MDisps *multires_mdisps_initiali
        return mdisps;
  }
  
 -DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob)
 +DerivedMesh *get_multires_dm(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob)
  {
        ModifierData *md = (ModifierData *)mmd;
        const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 -      DerivedMesh *tdm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
 +      DerivedMesh *tdm = mesh_get_derived_deform(eval_ctx, scene, ob, CD_MASK_BAREMESH);
        DerivedMesh *dm;
  
 -      dm = mti->applyModifier(md, ob, tdm, MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY);
 +      dm = mti->applyModifier(md, eval_ctx, ob, tdm, MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY);
        if (dm == tdm) {
                dm = CDDM_copy(tdm);
        }
@@@ -397,10 -398,10 +398,10 @@@ void multires_force_render_update(Objec
                multires_force_update(ob);
  }
  
 -int multiresModifier_reshapeFromDM(Scene *scene, MultiresModifierData *mmd,
 +int multiresModifier_reshapeFromDM(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
                                     Object *ob, DerivedMesh *srcdm)
  {
 -      DerivedMesh *mrdm = get_multires_dm(scene, mmd, ob);
 +      DerivedMesh *mrdm = get_multires_dm(eval_ctx, scene, mmd, ob);
  
        if (mrdm && srcdm && mrdm->getNumVerts(mrdm) == srcdm->getNumVerts(srcdm)) {
                multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm));
  }
  
  /* Returns 1 on success, 0 if the src's totvert doesn't match */
 -int multiresModifier_reshape(Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
 +int multiresModifier_reshape(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
  {
 -      DerivedMesh *srcdm = mesh_get_derived_final(scene, src, CD_MASK_BAREMESH);
 -      return multiresModifier_reshapeFromDM(scene, mmd, dst, srcdm);
 +      DerivedMesh *srcdm = mesh_get_derived_final(eval_ctx, scene, src, CD_MASK_BAREMESH);
 +      return multiresModifier_reshapeFromDM(eval_ctx, scene, mmd, dst, srcdm);
  }
  
 -int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mmd,
 +int multiresModifier_reshapeFromDeformMod(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
                                            Object *ob, ModifierData *md)
  {
        const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
                return 0;
  
        /* Create DerivedMesh for deformation modifier */
 -      dm = get_multires_dm(scene, mmd, ob);
 +      dm = get_multires_dm(eval_ctx, scene, mmd, ob);
        numVerts = dm->getNumVerts(dm);
        deformedVerts = MEM_mallocN(sizeof(float[3]) * numVerts, "multiresReshape_deformVerts");
  
        dm->getVertCos(dm, deformedVerts);
 -      mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0);
 +      mti->deformVerts(md, eval_ctx, ob, dm, deformedVerts, numVerts, 0);
  
        ndm = CDDM_copy(dm);
        CDDM_apply_vert_coords(ndm, deformedVerts);
        dm->release(dm);
  
        /* Reshaping */
 -      result = multiresModifier_reshapeFromDM(scene, mmd, ob, ndm);
 +      result = multiresModifier_reshapeFromDM(eval_ctx, scene, mmd, ob, ndm);
  
        /* Cleanup */
        ndm->release(ndm);
@@@ -1002,6 -1003,117 +1003,117 @@@ static void grid_tangent_matrix(float m
        copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y));
  }
  
+ typedef struct MultiresThreadedData {
+       DispOp op;
+       CCGElem **gridData, **subGridData;
+       CCGKey *key;
+       CCGKey *sub_key;
+       MPoly *mpoly;
+       MDisps *mdisps;
+       GridPaintMask *grid_paint_mask;
+       int *gridOffset;
+       int gridSize, dGridSize, dSkip;
+       float (*smat)[3];
+ } MultiresThreadedData;
+ static void multires_disp_run_cb(
+         void *__restrict userdata,
+         const int pidx,
+         const ParallelRangeTLS *__restrict UNUSED(tls))
+ {
+       MultiresThreadedData *tdata = userdata;
+       DispOp op = tdata->op;
+       CCGElem **gridData = tdata->gridData;
+       CCGElem **subGridData = tdata->subGridData;
+       CCGKey *key = tdata->key;
+       MPoly *mpoly = tdata->mpoly;
+       MDisps *mdisps = tdata->mdisps;
+       GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
+       int *gridOffset = tdata->gridOffset;
+       int gridSize = tdata->gridSize;
+       int dGridSize = tdata->dGridSize;
+       int dSkip = tdata->dSkip;
+       const int numVerts = mpoly[pidx].totloop;
+       int S, x, y, gIndex = gridOffset[pidx];
+       for (S = 0; S < numVerts; ++S, ++gIndex) {
+               GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : NULL;
+               MDisps *mdisp = &mdisps[mpoly[pidx].loopstart + S];
+               CCGElem *grid = gridData[gIndex];
+               CCGElem *subgrid = subGridData[gIndex];
+               float (*dispgrid)[3] = NULL;
+               dispgrid = mdisp->disps;
+               /* if needed, reallocate multires paint mask */
+               if (gpm && gpm->level < key->level) {
+                       gpm->level = key->level;
+                       if (gpm->data) {
+                               MEM_freeN(gpm->data);
+                       }
+                       gpm->data = MEM_callocN(sizeof(float) * key->grid_area, "gpm.data");
+               }
+               for (y = 0; y < gridSize; y++) {
+                       for (x = 0; x < gridSize; x++) {
+                               float *co = CCG_grid_elem_co(key, grid, x, y);
+                               float *sco = CCG_grid_elem_co(key, subgrid, x, y);
+                               float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
+                               float mat[3][3], disp[3], d[3], mask;
+                               /* construct tangent space matrix */
+                               grid_tangent_matrix(mat, key, x, y, subgrid);
+                               switch (op) {
+                                       case APPLY_DISPLACEMENTS:
+                                               /* Convert displacement to object space
+                                                * and add to grid points */
+                                               mul_v3_m3v3(disp, mat, data);
+                                               add_v3_v3v3(co, sco, disp);
+                                               break;
+                                       case CALC_DISPLACEMENTS:
+                                               /* Calculate displacement between new and old
+                                                * grid points and convert to tangent space */
+                                               sub_v3_v3v3(disp, co, sco);
+                                               invert_m3(mat);
+                                               mul_v3_m3v3(data, mat, disp);
+                                               break;
+                                       case ADD_DISPLACEMENTS:
+                                               /* Convert subdivided displacements to tangent
+                                                * space and add to the original displacements */
+                                               invert_m3(mat);
+                                               mul_v3_m3v3(d, mat, co);
+                                               add_v3_v3(data, d);
+                                               break;
+                               }
+                               if (gpm) {
+                                       switch (op) {
+                                               case APPLY_DISPLACEMENTS:
+                                                       /* Copy mask from gpm to DM */
+                                                       *CCG_grid_elem_mask(key, grid, x, y) =
+                                                           paint_grid_paint_mask(gpm, key->level, x, y);
+                                                       break;
+                                               case CALC_DISPLACEMENTS:
+                                                       /* Copy mask from DM to gpm */
+                                                       mask = *CCG_grid_elem_mask(key, grid, x, y);
+                                                       gpm->data[y * gridSize + x] = CLAMPIS(mask, 0, 1);
+                                                       break;
+                                               case ADD_DISPLACEMENTS:
+                                                       /* Add mask displacement to gpm */
+                                                       gpm->data[y * gridSize + x] +=
+                                                           *CCG_grid_elem_mask(key, grid, x, y);
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+       }
+ }
  /* XXX WARNING: subsurf elements from dm and oldGridData *must* be of the same format (size),
   *              because this code uses CCGKey's info from dm to access oldGridData's normals
   *              (through the call to grid_tangent_matrix())! */
@@@ -1014,7 -1126,7 +1126,7 @@@ static void multiresModifier_disp_run(D
        MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
        GridPaintMask *grid_paint_mask = NULL;
        int *gridOffset;
-       int i, k, /*numGrids, */ gridSize, dGridSize, dSkip;
+       int i, gridSize, dGridSize, dSkip;
        int totloop, totpoly;
        
        /* this happens in the dm made by bmesh_mdisps_space_set */
        if (key.has_mask)
                grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
  
-       k = 0; /*current loop/mdisp index within the mloop array*/
- #pragma omp parallel for private(i) if (totloop * gridSize * gridSize >= CCG_OMP_LIMIT)
-       for (i = 0; i < totpoly; ++i) {
-               const int numVerts = mpoly[i].totloop;
-               int S, x, y, gIndex = gridOffset[i];
-               for (S = 0; S < numVerts; ++S, ++gIndex, ++k) {
-                       GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : NULL;
-                       MDisps *mdisp = &mdisps[mpoly[i].loopstart + S];
-                       CCGElem *grid = gridData[gIndex];
-                       CCGElem *subgrid = subGridData[gIndex];
-                       float (*dispgrid)[3] = NULL;
-                       /* when adding new faces in edit mode, need to allocate disps */
-                       if (!mdisp->disps)
- #pragma omp critical
-                       {
-                               multires_reallocate_mdisps(totloop, mdisps, totlvl);
-                       }
-                       dispgrid = mdisp->disps;
-                       /* if needed, reallocate multires paint mask */
-                       if (gpm && gpm->level < key.level) {
-                               gpm->level = key.level;
- #pragma omp critical
-                               {
-                                       if (gpm->data)
-                                               MEM_freeN(gpm->data);
-                                       gpm->data = MEM_callocN(sizeof(float) * key.grid_area, "gpm.data");
-                               }
-                       }
+       /* when adding new faces in edit mode, need to allocate disps */
+       for (i = 0; i < totloop; ++i) {
+               if (mdisps[i].disps == NULL) {
+                       multires_reallocate_mdisps(totloop, mdisps, totlvl);
+                       break;
+               }
+       }
  
-                       for (y = 0; y < gridSize; y++) {
-                               for (x = 0; x < gridSize; x++) {
-                                       float *co = CCG_grid_elem_co(&key, grid, x, y);
-                                       float *sco = CCG_grid_elem_co(&key, subgrid, x, y);
-                                       float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
-                                       float mat[3][3], disp[3], d[3], mask;
+       ParallelRangeSettings settings;
+       BLI_parallel_range_settings_defaults(&settings);
+       settings.min_iter_per_thread = CCG_TASK_LIMIT;
  
-                                       /* construct tangent space matrix */
-                                       grid_tangent_matrix(mat, &key, x, y, subgrid);
+       MultiresThreadedData data = {
+           .op = op,
+           .gridData = gridData,
+           .subGridData = subGridData,
+           .key = &key,
+           .mpoly = mpoly,
+           .mdisps = mdisps,
+           .grid_paint_mask = grid_paint_mask,
+           .gridOffset = gridOffset,
+           .gridSize = gridSize,
+           .dGridSize = dGridSize,
+           .dSkip = dSkip
+       };
  
-                                       switch (op) {
-                                               case APPLY_DISPLACEMENTS:
-                                                       /* Convert displacement to object space
-                                                        * and add to grid points */
-                                                       mul_v3_m3v3(disp, mat, data);
-                                                       add_v3_v3v3(co, sco, disp);
-                                                       break;
-                                               case CALC_DISPLACEMENTS:
-                                                       /* Calculate displacement between new and old
-                                                        * grid points and convert to tangent space */
-                                                       sub_v3_v3v3(disp, co, sco);
-                                                       invert_m3(mat);
-                                                       mul_v3_m3v3(data, mat, disp);
-                                                       break;
-                                               case ADD_DISPLACEMENTS:
-                                                       /* Convert subdivided displacements to tangent
-                                                        * space and add to the original displacements */
-                                                       invert_m3(mat);
-                                                       mul_v3_m3v3(d, mat, co);
-                                                       add_v3_v3(data, d);
-                                                       break;
-                                       }
+       BLI_task_parallel_range(0, totpoly, &data, multires_disp_run_cb, &settings);
  
-                                       if (gpm) {
-                                               switch (op) {
-                                                       case APPLY_DISPLACEMENTS:
-                                                               /* Copy mask from gpm to DM */
-                                                               *CCG_grid_elem_mask(&key, grid, x, y) =
-                                                                   paint_grid_paint_mask(gpm, key.level, x, y);
-                                                               break;
-                                                       case CALC_DISPLACEMENTS:
-                                                               /* Copy mask from DM to gpm */
-                                                               mask = *CCG_grid_elem_mask(&key, grid, x, y);
-                                                               gpm->data[y * gridSize + x] = CLAMPIS(mask, 0, 1);
-                                                               break;
-                                                       case ADD_DISPLACEMENTS:
-                                                               /* Add mask displacement to gpm */
-                                                               gpm->data[y * gridSize + x] +=
-                                                                   *CCG_grid_elem_mask(&key, grid, x, y);
-                                                               break;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-       
        if (op == APPLY_DISPLACEMENTS) {
                ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
                ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
@@@ -1332,8 -1380,7 +1380,7 @@@ void multires_set_space(DerivedMesh *dm
  
        k = 0; /*current loop/mdisp index within the mloop array*/
  
-       //#pragma omp parallel for private(i) if (dm->numLoopData * gridSize * gridSize >= CCG_OMP_LIMIT)
+       /* TODO: Use BLI_task parallel range for that one too? */
        for (i = 0; i < dm->numPolyData; ++i) {
                const int numVerts = mpoly[i].totloop;
                int S, x, y, gIndex = gridOffset[i];
@@@ -2174,7 -2221,57 +2221,57 @@@ static void multires_sync_levels(Scene 
        }
  }
  
 -static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
+ static void multires_apply_smat_cb(
+         void *__restrict userdata,
+         const int pidx,
+         const ParallelRangeTLS *__restrict UNUSED(tls))
+ {
+       MultiresThreadedData *tdata = userdata;
+       CCGElem **gridData = tdata->gridData;
+       CCGElem **subGridData = tdata->subGridData;
+       CCGKey *dm_key = tdata->key;
+       CCGKey *subdm_key = tdata->sub_key;
+       MPoly *mpoly = tdata->mpoly;
+       MDisps *mdisps = tdata->mdisps;
+       int *gridOffset = tdata->gridOffset;
+       int gridSize = tdata->gridSize;
+       int dGridSize = tdata->dGridSize;
+       int dSkip = tdata->dSkip;
+       float (*smat)[3] = tdata->smat;
+       const int numVerts = mpoly[pidx].totloop;
+       MDisps *mdisp = &mdisps[mpoly[pidx].loopstart];
+       int S, x, y, gIndex = gridOffset[pidx];
+       for (S = 0; S < numVerts; ++S, ++gIndex, mdisp++) {
+               CCGElem *grid = gridData[gIndex];
+               CCGElem *subgrid = subGridData[gIndex];
+               float (*dispgrid)[3] = mdisp->disps;
+               for (y = 0; y < gridSize; y++) {
+                       for (x = 0; x < gridSize; x++) {
+                               float *co = CCG_grid_elem_co(dm_key, grid, x, y);
+                               float *sco = CCG_grid_elem_co(subdm_key, subgrid, x, y);
+                               float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
+                               float mat[3][3], disp[3];
+                               /* construct tangent space matrix */
+                               grid_tangent_matrix(mat, dm_key, x, y, grid);
+                               /* scale subgrid coord and calculate displacement */
+                               mul_m3_v3(smat, sco);
+                               sub_v3_v3v3(disp, sco, co);
+                               /* convert difference to tangent space */
+                               invert_m3(mat);
+                               mul_v3_m3v3(data, mat, disp);
+                       }
+               }
+       }
+ }
 +static void multires_apply_smat(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float smat[3][3])
  {
        DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL;
        CCGElem **gridData, **subGridData;
        high_mmd.lvl = high_mmd.totlvl;
  
        /* unscaled multires with applied displacement */
 -      subdm = get_multires_dm(scene, &high_mmd, ob);
 +      subdm = get_multires_dm(eval_ctx, scene, &high_mmd, ob);
  
        /* prepare scaled CDDM to create ccgDN */
 -      cddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
 +      cddm = mesh_get_derived_deform(eval_ctx, scene, ob, CD_MASK_BAREMESH);
  
        totvert = cddm->getNumVerts(cddm);
        vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "multiresScale vertCos");
        dGridSize = multires_side_tot[high_mmd.totlvl];
        dSkip = (dGridSize - 1) / (gridSize - 1);
  
- #pragma omp parallel for private(i) if (me->totloop * gridSize * gridSize >= CCG_OMP_LIMIT)
-       for (i = 0; i < me->totpoly; ++i) {
-               const int numVerts = mpoly[i].totloop;
-               MDisps *mdisp = &mdisps[mpoly[i].loopstart];
-               int S, x, y, gIndex = gridOffset[i];
-               for (S = 0; S < numVerts; ++S, ++gIndex, mdisp++) {
-                       CCGElem *grid = gridData[gIndex];
-                       CCGElem *subgrid = subGridData[gIndex];
-                       float (*dispgrid)[3] = mdisp->disps;
-                       for (y = 0; y < gridSize; y++) {
-                               for (x = 0; x < gridSize; x++) {
-                                       float *co = CCG_grid_elem_co(&dm_key, grid, x, y);
-                                       float *sco = CCG_grid_elem_co(&subdm_key, subgrid, x, y);
-                                       float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
-                                       float mat[3][3], disp[3];
-                                       /* construct tangent space matrix */
-                                       grid_tangent_matrix(mat, &dm_key, x, y, grid);
-                                       /* scale subgrid coord and calculate displacement */
-                                       mul_m3_v3(smat, sco);
-                                       sub_v3_v3v3(disp, sco, co);
-                                       /* convert difference to tangent space */
-                                       invert_m3(mat);
-                                       mul_v3_m3v3(data, mat, disp);
-                               }
-                       }
-               }
-       }
+       ParallelRangeSettings settings;
+       BLI_parallel_range_settings_defaults(&settings);
+       settings.min_iter_per_thread = CCG_TASK_LIMIT;
+       MultiresThreadedData data = {
+           .gridData = gridData,
+           .subGridData = subGridData,
+           .key = &dm_key,
+           .sub_key = &subdm_key,
+           .mpoly = mpoly,
+           .mdisps = mdisps,
+           .gridOffset = gridOffset,
+           .gridSize = gridSize,
+           .dGridSize = dGridSize,
+           .dSkip = dSkip,
+           .smat = smat
+       };
+       BLI_task_parallel_range(0, me->totpoly, &data, multires_apply_smat_cb, &settings);
  
        dm->release(dm);
        subdm->release(subdm);
@@@ -2276,17 -2360,17 +2360,17 @@@ int multires_mdisp_corners(MDisps *s
        return 0;
  }
  
 -void multiresModifier_scale_disp(Scene *scene, Object *ob)
 +void multiresModifier_scale_disp(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
  {
        float smat[3][3];
  
        /* object's scale matrix */
        BKE_object_scale_to_mat3(ob, smat);
  
 -      multires_apply_smat(scene, ob, smat);
 +      multires_apply_smat(eval_ctx, scene, ob, smat);
  }
  
 -void multiresModifier_prepare_join(Scene *scene, Object *ob, Object *to_ob)
 +void multiresModifier_prepare_join(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob)
  {
        float smat[3][3], tmat[3][3], mat[3][3];
        multires_sync_levels(scene, to_ob, ob);
        BKE_object_scale_to_mat3(ob, smat);
        mul_m3_m3m3(mat, smat, tmat);
  
 -      multires_apply_smat(scene, ob, mat);
 +      multires_apply_smat(eval_ctx, scene, ob, mat);
  }
  
  /* update multires data after topology changing */