diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-01-11 22:19:18 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-01-11 22:19:18 +0300 |
commit | 8bff6f319a1f562e6d3595468a9ddba7bfec931c (patch) | |
tree | a04606dd2bab058b539eeae3727673b527b1584e /source/blender/blenkernel/intern/multires.c | |
parent | da97b6930b47555fbc526b7165d5b73abe06252d (diff) | |
parent | 610459658777e73e50671ddbcebd70294a6ad76e (diff) |
Merge branch 'master' into blender2.8
Conflicts:
source/blender/blenkernel/intern/multires.c
Diffstat (limited to 'source/blender/blenkernel/intern/multires.c')
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 330 |
1 files changed, 207 insertions, 123 deletions
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 7ef4b588dcd..b6e3d048f0b 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -44,6 +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" @@ -1002,6 +1003,117 @@ static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, 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 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm 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 */ @@ -1050,98 +1162,34 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm 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 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) 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,6 +2221,56 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) } } +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; @@ -2226,38 +2323,25 @@ static void multires_apply_smat(const struct EvaluationContext *eval_ctx, Scene 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); |