[Bf-blender-cvs] [5ac7068c5fa] blender2.8: Hair editing: Multi-thread various parts

Sergey Sharybin noreply at git.blender.org
Fri Jun 15 17:25:07 CEST 2018


Commit: 5ac7068c5fa888fe8502eab42b3639dc35b62785
Author: Sergey Sharybin
Date:   Fri Jun 15 10:22:44 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB5ac7068c5fa888fe8502eab42b3639dc35b62785

Hair editing: Multi-thread various parts

Currently focused on making parts which are a bottleneck for Spring,
to make things fast as possible. There are surely lots of places
where threading is not currently done, but we can keep doing this,
maybe even with help from the community :)

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

M	source/blender/blenkernel/intern/particle.c
M	source/blender/editors/physics/particle_edit.c

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

diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 127ef840027..0ae6d2a3f2d 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -2598,204 +2598,236 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
 	if (vg_length)
 		MEM_freeN(vg_length);
 }
-void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params)
-{
-	ParticleCacheKey *ca, **cache = edit->pathcache;
-	ParticleEditSettings *pset = &scene->toolsettings->particle;
-	
-	PTCacheEditPoint *point = NULL;
-	PTCacheEditKey *ekey = NULL;
-
-	ParticleSystem *psys = edit->psys;
-	ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
-
-	ParticleData *pa = psys ? psys->particles : NULL;
 
-	ParticleInterpolationData pind;
-	ParticleKey result;
-	
-	float birthtime = 0.0f, dietime = 0.0f;
-	float t, time = 0.0f, keytime = 0.0f /*, frs_sec */;
-	float hairmat[4][4], rotmat[3][3], prev_tangent[3] = {0.0f, 0.0f, 0.0f};
-	int k, i;
-	int segments = 1 << pset->draw_step;
-	int totpart = edit->totpoint, recalc_set = 0;
+typedef struct CacheEditrPathsIterData {
+	Object *object;
+	PTCacheEdit *edit;
+	ParticleSystemModifierData *psmd;
+	ParticleData *pa;
+	int segments;
+	bool use_weight;
 	float sel_col[3];
 	float nosel_col[3];
+} CacheEditrPathsIterData;
 
-	segments = MAX2(segments, 4);
-
-	if (!cache || edit->totpoint != edit->totcached) {
-		/* clear out old and create new empty path cache */
-		psys_free_path_cache(edit->psys, edit);
-		cache = edit->pathcache = psys_alloc_path_cache_buffers(&edit->pathcachebufs, totpart, segments + 1);
-
-		/* set flag for update (child particles check this too) */
-		for (i = 0, point = edit->points; i < totpart; i++, point++)
-			point->flag |= PEP_EDIT_RECALC;
-		recalc_set = 1;
+static void psys_cache_edit_paths_iter(
+        void *__restrict iter_data_v,
+        const int iter,
+        const ParallelRangeTLS *__restrict UNUSED(tls))
+{
+	CacheEditrPathsIterData *iter_data = (CacheEditrPathsIterData *)iter_data_v;
+	PTCacheEdit *edit = iter_data->edit;
+	PTCacheEditPoint *point = &edit->points[iter];
+	if (edit->totcached && !(point->flag & PEP_EDIT_RECALC)) {
+		return;
+	}
+	if (point->totkey == 0) {
+		return;
 	}
+	Object *ob = iter_data->object;
+	ParticleSystem *psys = edit->psys;
+	ParticleCacheKey **cache = edit->pathcache;
+	ParticleSystemModifierData *psmd = iter_data->psmd;
+	ParticleData *pa = iter_data->pa ? iter_data->pa + iter : NULL;
+	PTCacheEditKey *ekey = point->keys;
+	const int segments = iter_data->segments;
+	const bool use_weight = iter_data->use_weight;
 
-	/* frs_sec = (psys || edit->pid.flag & PTCACHE_VEL_PER_SEC) ? 25.0f : 1.0f; */ /* UNUSED */
+	float birthtime = 0.0f, dietime = 0.0f;
+	float hairmat[4][4], rotmat[3][3], prev_tangent[3] = {0.0f, 0.0f, 0.0f};
 
-	const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys != NULL) && (psys->particles != NULL);
+	ParticleInterpolationData pind;
+	pind.keyed = 0;
+	pind.cache = NULL;
+	pind.epoint = point;
+	pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0;
+	pind.mesh = NULL;
 
+	/* should init_particle_interpolation set this ? */
 	if (use_weight) {
-		; /* use weight painting colors now... */
-	}
-	else {
-		sel_col[0] = (float)edit->sel_col[0] / 255.0f;
-		sel_col[1] = (float)edit->sel_col[1] / 255.0f;
-		sel_col[2] = (float)edit->sel_col[2] / 255.0f;
-		nosel_col[0] = (float)edit->nosel_col[0] / 255.0f;
-		nosel_col[1] = (float)edit->nosel_col[1] / 255.0f;
-		nosel_col[2] = (float)edit->nosel_col[2] / 255.0f;
+		pind.hkey[0] = NULL;
+		/* pa != NULL since the weight brush is only available for hair */
+		pind.hkey[0] = pa->hair;
+		pind.hkey[1] = pa->hair + 1;
 	}
 
-	/*---first main loop: create all actual particles' paths---*/
-	for (i = 0, point = edit->points; i < totpart; i++, pa += pa ? 1 : 0, point++) {
-		if (edit->totcached && !(point->flag & PEP_EDIT_RECALC))
-			continue;
+	memset(cache[iter], 0, sizeof(*cache[iter]) * (segments + 1));
 
-		if (point->totkey == 0)
-			continue;
+	cache[iter]->segments = segments;
 
-		ekey = point->keys;
+	/*--get the first data points--*/
+	init_particle_interpolation(ob, psys, pa, &pind);
 
-		pind.keyed = 0;
-		pind.cache = NULL;
-		pind.epoint = point;
-		pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0;
-		pind.mesh = NULL;
+	if (psys) {
+		psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
+		copy_v3_v3(rotmat[0], hairmat[2]);
+		copy_v3_v3(rotmat[1], hairmat[1]);
+		copy_v3_v3(rotmat[2], hairmat[0]);
+	}
 
+	birthtime = pind.birthtime;
+	dietime = pind.dietime;
 
-		/* should init_particle_interpolation set this ? */
-		if (use_weight) {
-			pind.hkey[0] = NULL;
-			/* pa != NULL since the weight brush is only available for hair */
-			pind.hkey[0] = pa->hair;
-			pind.hkey[1] = pa->hair + 1;
-		}
+	if (birthtime >= dietime) {
+		cache[iter]->segments = -1;
+		return;
+	}
 
+	/*--interpolate actual path from data points--*/
+	ParticleCacheKey *ca;
+	int k;
+	float t, time = 0.0f, keytime = 0.0f;
+	for (k = 0, ca = cache[iter]; k <= segments; k++, ca++) {
+		time = (float)k / (float)segments;
+		t = birthtime + time * (dietime - birthtime);
+		ParticleKey result;
+		result.time = -t;
+		do_particle_interpolation(psys, iter, pa, t, &pind, &result);
+		copy_v3_v3(ca->co, result.co);
+
+		/* non-hair points are already in global space */
+		if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
+			mul_m4_v3(hairmat, ca->co);
 
-		memset(cache[i], 0, sizeof(*cache[i]) * (segments + 1));
+			if (k) {
+				cache_key_incremental_rotation(ca, ca - 1, ca - 2, prev_tangent, k);
 
-		cache[i]->segments = segments;
+				if (k == segments)
+					copy_qt_qt(ca->rot, (ca - 1)->rot);
 
-		/*--get the first data points--*/
-		init_particle_interpolation(ob, psys, pa, &pind);
+				/* set velocity */
+				sub_v3_v3v3(ca->vel, ca->co, (ca - 1)->co);
 
-		if (psys) {
-			psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
-			copy_v3_v3(rotmat[0], hairmat[2]);
-			copy_v3_v3(rotmat[1], hairmat[1]);
-			copy_v3_v3(rotmat[2], hairmat[0]);
+				if (k == 1)
+					copy_v3_v3((ca - 1)->vel, ca->vel);
+			}
 		}
-
-		birthtime = pind.birthtime;
-		dietime = pind.dietime;
-
-		if (birthtime >= dietime) {
-			cache[i]->segments = -1;
-			continue;
+		else {
+			ca->vel[0] = ca->vel[1] = 0.0f;
+			ca->vel[2] = 1.0f;
 		}
 
-		/*--interpolate actual path from data points--*/
-		for (k = 0, ca = cache[i]; k <= segments; k++, ca++) {
-			time = (float)k / (float)segments;
-			t = birthtime + time * (dietime - birthtime);
-			result.time = -t;
-			do_particle_interpolation(psys, i, pa, t, &pind, &result);
-			copy_v3_v3(ca->co, result.co);
-
-			/* non-hair points are already in global space */
-			if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
-				mul_m4_v3(hairmat, ca->co);
-
-				if (k) {
-					cache_key_incremental_rotation(ca, ca - 1, ca - 2, prev_tangent, k);
-
-					if (k == segments)
-						copy_qt_qt(ca->rot, (ca - 1)->rot);
-
-					/* set velocity */
-					sub_v3_v3v3(ca->vel, ca->co, (ca - 1)->co);
-
-					if (k == 1)
-						copy_v3_v3((ca - 1)->vel, ca->vel);
-				}
+		/* selection coloring in edit mode */
+		if (use_weight) {
+			if (k == 0) {
+				weight_to_rgb(ca->col, pind.hkey[1]->weight);
 			}
 			else {
-				ca->vel[0] = ca->vel[1] = 0.0f;
-				ca->vel[2] = 1.0f;
-			}
-
-			/* selection coloring in edit mode */
-			if (use_weight) {
-				if (k == 0) {
-					weight_to_rgb(ca->col, pind.hkey[1]->weight);
+				/* warning: copied from 'do_particle_interpolation' (without 'mvert' array stepping) */
+				float real_t;
+				if (result.time < 0.0f) {
+					real_t = -result.time;
 				}
 				else {
-					/* warning: copied from 'do_particle_interpolation' (without 'mvert' array stepping) */
-					float real_t;
-					if (result.time < 0.0f) {
-						real_t = -result.time;
-					}
-					else {
-						real_t = pind.hkey[0]->time + t * (pind.hkey[0][pa->totkey - 1].time - pind.hkey[0]->time);
-					}
+					real_t = pind.hkey[0]->time + t * (pind.hkey[0][pa->totkey - 1].time - pind.hkey[0]->time);
+				}
 
-					while (pind.hkey[1]->time < real_t) {
-						pind.hkey[1]++;
-					}
-					pind.hkey[0] = pind.hkey[1] - 1;
-					/* end copy */
+				while (pind.hkey[1]->time < real_t) {
+					pind.hkey[1]++;
+				}
+				pind.hkey[0] = pind.hkey[1] - 1;
+				/* end copy */
 
 
-					float w1[3], w2[3];
-					keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
+				float w1[3], w2[3];
+				keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
 
-					weight_to_rgb(w1, pind.hkey[0]->weight);
-					weight_to_rgb(w2, pind.hkey[1]->weight);
+				weight_to_rgb(w1, pind.hkey[0]->weight);
+				weight_to_rgb(w2, pind.hkey[1]->weight);
 
-					interp_v3_v3v3(ca->col, w1, w2, keytime);
+				interp_v3_v3v3(ca->col, w1, w2, keytime);
+			}
+		}
+		else {
+			if ((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT) {
+				if ((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT) {
+					copy_v3_v3(ca->col, iter_data->sel_col);
+				}
+				else {
+					keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
+					interp_v3_v3v3(ca->col, iter_data->sel_col, iter_data->nosel_col, keytime);
 				}
 			}
 			else {
-				if ((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT) {
-					if ((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT) {
-						copy_v3_v3(ca->col, sel_col);
-					}
-					else {
-						keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
-						interp_v3_v3v3(ca->col, sel_col, nosel_col, keytime);
-					}
+				if ((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT) {
+					keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
+					interp_v3_v3v3(ca->col, iter_data->nosel_col, iter_data->sel_col, keytime);
 				}
 				else {
-					if ((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT) {
-						keytime = (t - (*pind.ekey[0]->time)) / ((*pin

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list