Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-01-26 12:15:08 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-01-26 16:01:32 +0300
commitd9ccc0c95787b7f74d8f52f74a06e183ed56648a (patch)
tree1d554a7d35dc3625f20498f4592eb62e7447c1f9 /source/blender/blenkernel
parente4c83bc3459847c33269557499cc891ed4f747af (diff)
mesh_evaluate.c: OMP -> BLI_task, and some more parallelization.
Only concerns poly normals computing, have usual 10% speedup of affected code for OMP -> BLI_task switching. Also parallelized the 'weighted accum' part (used when computing both polys and vertices normals, when using modifiers e.g.), which gives nice 325% speedup (from 66ms to 20ms for a 500k poly monkey with simple deform modifier e.g.). ;)
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c71
1 files changed, 43 insertions, 28 deletions
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 7aad5ad1890..b2c1e5df583 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -167,11 +167,33 @@ void BKE_mesh_calc_normals_mapping_ex(
}
-static void mesh_calc_normals_poly_accum(
- const MPoly *mp, const MLoop *ml,
- const MVert *mvert,
- float r_polyno[3], float (*r_tnorms)[3])
+typedef struct MeshCalcNormalsData {
+ const MPoly *mpolys;
+ const MLoop *mloop;
+ MVert *mverts;
+ float (*pnors)[3];
+ float (*vnors)[3];
+} MeshCalcNormalsData;
+
+static void mesh_calc_normals_poly_task_cb(void *userdata, const int pidx)
{
+ MeshCalcNormalsData *data = userdata;
+ const MPoly *mp = &data->mpolys[pidx];
+
+ BKE_mesh_calc_poly_normal(mp, data->mloop + mp->loopstart, data->mverts, data->pnors[pidx]);
+}
+
+static void mesh_calc_normals_poly_accum_task_cb(void *userdata, const int pidx)
+{
+ MeshCalcNormalsData *data = userdata;
+ const MPoly *mp = &data->mpolys[pidx];
+ const MLoop *ml = &data->mloop[mp->loopstart];
+ const MVert *mverts = data->mverts;
+
+ float pnor_temp[3];
+ float *pnor = data->pnors ? data->pnors[pidx] : pnor_temp;
+ float (*vnors)[3] = data->vnors;
+
const int nverts = mp->totloop;
float (*edgevecbuf)[3] = BLI_array_alloca(edgevecbuf, (size_t)nverts);
int i;
@@ -180,14 +202,14 @@ static void mesh_calc_normals_poly_accum(
/* inline version of #BKE_mesh_calc_poly_normal, also does edge-vectors */
{
int i_prev = nverts - 1;
- const float *v_prev = mvert[ml[i_prev].v].co;
+ const float *v_prev = mverts[ml[i_prev].v].co;
const float *v_curr;
- zero_v3(r_polyno);
+ zero_v3(pnor);
/* Newell's Method */
for (i = 0; i < nverts; i++) {
- v_curr = mvert[ml[i].v].co;
- add_newell_cross_v3_v3v3(r_polyno, v_prev, v_curr);
+ v_curr = mverts[ml[i].v].co;
+ add_newell_cross_v3_v3v3(pnor, v_prev, v_curr);
/* Unrelated to normalize, calculate edge-vector */
sub_v3_v3v3(edgevecbuf[i_prev], v_prev, v_curr);
@@ -196,8 +218,8 @@ static void mesh_calc_normals_poly_accum(
v_prev = v_curr;
}
- if (UNLIKELY(normalize_v3(r_polyno) == 0.0f)) {
- r_polyno[2] = 1.0f; /* other axis set to 0.0 */
+ if (UNLIKELY(normalize_v3(pnor) == 0.0f)) {
+ pnor[2] = 1.0f; /* other axis set to 0.0 */
}
}
@@ -214,7 +236,7 @@ static void mesh_calc_normals_poly_accum(
const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
/* accumulate */
- madd_v3_v3fl(r_tnorms[ml[i].v], r_polyno, fac);
+ madd_v3_v3fl(vnors[ml[i].v], pnor, fac);
prev_edge = cur_edge;
}
}
@@ -231,16 +253,16 @@ void BKE_mesh_calc_normals_poly(
float (*vnors)[3] = r_vertnors;
bool free_vnors = false;
int i;
- const MPoly *mp;
if (only_face_normals) {
BLI_assert((pnors != NULL) || (numPolys == 0));
BLI_assert(r_vertnors == NULL);
-#pragma omp parallel for if (numPolys > BKE_MESH_OMP_LIMIT)
- for (i = 0; i < numPolys; i++) {
- BKE_mesh_calc_poly_normal(&mpolys[i], mloop + mpolys[i].loopstart, mverts, pnors[i]);
- }
+ MeshCalcNormalsData data = {
+ .mpolys = mpolys, .mloop = mloop, .mverts = mverts, .pnors = pnors,
+ };
+
+ BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_task_cb, (numPolys > BKE_MESH_OMP_LIMIT));
return;
}
@@ -253,18 +275,11 @@ void BKE_mesh_calc_normals_poly(
memset(vnors, 0, sizeof(*vnors) * (size_t)numVerts);
}
- mp = mpolys;
- if (pnors) {
- for (i = 0; i < numPolys; i++, mp++) {
- mesh_calc_normals_poly_accum(mp, mloop + mp->loopstart, mverts, pnors[i], vnors);
- }
- }
- else {
- float tpnor[3]; /* temp poly normal */
- for (i = 0; i < numPolys; i++, mp++) {
- mesh_calc_normals_poly_accum(mp, mloop + mp->loopstart, mverts, tpnor, vnors);
- }
- }
+ MeshCalcNormalsData data = {
+ .mpolys = mpolys, .mloop = mloop, .mverts = mverts, .pnors = pnors, .vnors = vnors,
+ };
+
+ BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_accum_task_cb, (numPolys > BKE_MESH_OMP_LIMIT));
for (i = 0; i < numVerts; i++) {
MVert *mv = &mverts[i];