[Bf-blender-cvs] [d8f9ec15473] blender2.8: Particles: Support changing modifiers during particle edit mode

Sergey Sharybin noreply at git.blender.org
Tue Jun 19 15:29:09 CEST 2018


Commit: d8f9ec1547387bf363e9c7100322a7d94f08f12a
Author: Sergey Sharybin
Date:   Tue Jun 19 15:25:48 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBd8f9ec1547387bf363e9c7100322a7d94f08f12a

Particles: Support changing modifiers during particle edit mode

The idea is to only use pointers to particles in original object when
creating an edit structure. The derived mesh we get from evaluated
object.

The rest of the commit is just keeping pointers in sync.

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

M	source/blender/blenkernel/BKE_pointcache.h
M	source/blender/blenkernel/intern/particle.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/draw/intern/draw_cache_impl_particles.c
M	source/blender/editors/physics/particle_edit.c

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

diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 8daef0348b9..21673213db1 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -246,13 +246,25 @@ typedef struct PTCacheUndo {
 	size_t undo_size;
 } PTCacheUndo;
 
+enum {
+	/* Modifier stack got evaluated during particle edit mode, need to copy
+	 * new evaluated particles to the edit struct.
+	 */
+	PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL = (1 << 0),
+};
+
 typedef struct PTCacheEdit {
+	int flags;
+
 	PTCacheEditPoint *points;
 
 	struct PTCacheID pid;
 
 	/* particles stuff */
 	struct ParticleSystem *psys;
+	struct ParticleSystem *psys_eval;
+	struct ParticleSystemModifierData *psmd;
+	struct ParticleSystemModifierData *psmd_eval;
 	struct KDTree *emitter_field;
 	float *emitter_cosnos; /* localspace face centers and normals (average of its verts), from the derived mesh */
 	int *mirror_cache;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 9461b0a21a5..693d6ac587e 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -2824,7 +2824,6 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
 	ParticleEditSettings *pset = &scene->toolsettings->particle;
 
 	ParticleSystem *psys = edit->psys;
-	ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
 
 	ParticleData *pa = psys ? psys->particles : NULL;
 
@@ -2851,7 +2850,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
 	CacheEditrPathsIterData iter_data;
 	iter_data.object = ob;
 	iter_data.edit = edit;
-	iter_data.psmd = psmd;
+	iter_data.psmd = edit->psmd_eval;
 	iter_data.pa = pa;
 	iter_data.segments = segments;
 	iter_data.use_weight = use_weight;
@@ -2881,7 +2880,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
 		sim.scene = scene;
 		sim.ob = ob;
 		sim.psys = psys;
-		sim.psmd = psys_get_modifier(ob, psys);
+		sim.psmd = edit->psmd_eval;
 
 		psys_cache_child_paths(&sim, cfra, true, use_render_params);
 	}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 9c6c30143cc..314a58647a9 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4211,7 +4211,9 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o
 {
 	ParticleSimulationData sim= {0};
 	ParticleSettings *part = psys->part;
+	ParticleSystem *psys_orig = psys_orig_get(psys);
 	float cfra;
+	ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
 
 	/* drawdata is outdated after ANY change */
 	if (psys->pdd) psys->pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
@@ -4219,13 +4221,23 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o
 	if (!psys_check_enabled(ob, psys, use_render_params))
 		return;
 
+	if (DEG_is_active(depsgraph)) {
+		if (psys->orig_psys != NULL &&
+		    psys->orig_psys->edit != NULL &&
+		    psys->orig_psys->edit->psys == psys_orig_get(psys))
+		{
+			psys->orig_psys->edit->psys_eval = psys;
+			psys->orig_psys->edit->psmd_eval = psmd;
+		}
+	}
+
 	cfra = DEG_get_ctime(depsgraph);
 
 	sim.depsgraph = depsgraph;
 	sim.scene = scene;
 	sim.ob = ob;
 	sim.psys = psys;
-	sim.psmd = psys_get_modifier(ob, psys);
+	sim.psmd = psmd;
 
 	/* system was already updated from modifier stack */
 	if (sim.psmd->flag & eParticleSystemFlag_psys_updated) {
@@ -4270,10 +4282,10 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o
 
 				free_hair(ob, psys, 0);
 
-				if (psys->edit && psys->free_edit) {
-					psys->free_edit(psys->edit);
-					psys->edit = NULL;
-					psys->free_edit = NULL;
+				if (psys_orig->edit && psys_orig->free_edit) {
+					psys_orig->free_edit(psys_orig->edit);
+					psys_orig->edit = NULL;
+					psys_orig->free_edit = NULL;
 				}
 
 				/* first step is negative so particles get killed and reset */
@@ -4369,6 +4381,10 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o
 		psys->flag &= ~PSYS_OB_ANIM_RESTORE;
 	}
 
+	if (psys_orig->edit) {
+		psys_orig->edit->flags |= PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL;
+	}
+
 	psys->cfra = cfra;
 	psys->recalc = 0;
 
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index b3006f1bd98..d1e05b525ef 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -1331,9 +1331,6 @@ static void drw_particle_get_hair_source(
 	if ((object->mode & OB_MODE_PARTICLE_EDIT) != 0) {
 		r_draw_source->object = DEG_get_original_object(object);
 		r_draw_source->psys = psys_orig_get(psys);
-		if (md != NULL) {
-			r_draw_source->md = modifiers_findByName(r_draw_source->object, md->name);
-		}
 	}
 }
 
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 66369d989be..e926540408e 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -217,6 +217,31 @@ PTCacheEdit *PE_get_current_from_psys(ParticleSystem *psys)
 	return NULL;
 }
 
+/* NOTE: Similar to creation of edit, but only updates pointers in the
+ * existing struct.
+ */
+static void pe_update_hair_particle_edit_pointers(PTCacheEdit *edit)
+{
+	ParticleSystem *psys = edit->psys;
+	ParticleData *pa = psys->particles;
+	for (int p = 0; p < edit->totpoint; p++) {
+		PTCacheEditPoint *point = &edit->points[p];
+		HairKey *hair_key = pa->hair;
+		for (int k = 0; k < point->totkey; k++) {
+			PTCacheEditKey *key = &point->keys[k];
+			key->co = hair_key->co;
+			key->time = &hair_key->time;
+			key->flag = hair_key->editflag;
+			if (!(psys->flag & PSYS_GLOBAL_HAIR)) {
+				key->flag |= PEK_USE_WCO;
+				hair_key->editflag |= PEK_USE_WCO;
+			}
+			hair_key++;
+		}
+		pa++;
+	}
+}
+
 /* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set
  *
  * note: this function runs on poll, therefor it can runs many times a second
@@ -302,8 +327,16 @@ static PTCacheEdit *pe_get_current(
 		}
 	}
 
-	if (edit)
+	if (edit) {
 		edit->pid = *pid;
+		if (edit->flags & PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL) {
+			if (edit->psys != NULL) {
+				psys_copy_particles(edit->psys, edit->psys_eval);
+				pe_update_hair_particle_edit_pointers(edit);
+			}
+			edit->flags &= ~PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL;
+		}
+	}
 
 	BLI_freelistN(&pidlist);
 
@@ -651,7 +684,6 @@ static void foreach_mouse_hit_point(PEData *data, ForPointFunc func, int selecte
 typedef struct KeyIterData {
 	PEData *data;
 	PTCacheEdit *edit;
-	ParticleSystemModifierData *psmd;
 	int selected;
 	ForKeyMatFunc func;
 } KeyIterData;
@@ -669,7 +701,7 @@ static void foreach_mouse_hit_key_iter(
 		return;
 	}
 	ParticleSystem *psys = edit->psys;
-	ParticleSystemModifierData *psmd = iter_data->psmd;
+	ParticleSystemModifierData *psmd_eval = iter_data->edit->psmd_eval;
 	ParticleEditSettings *pset = PE_settings(data->scene);
 	const int selected = iter_data->selected;
 	float mat[4][4], imat[4][4];
@@ -683,7 +715,7 @@ static void foreach_mouse_hit_key_iter(
 			if (selected==0 || key->flag & PEK_SELECT) {
 				if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
 					if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
-						psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + iter, mat);
+						psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat);
 						invert_m4_m4(imat, mat);
 					}
 					iter_data->func(data, mat, imat, iter, point->totkey-1, key);
@@ -699,7 +731,7 @@ static void foreach_mouse_hit_key_iter(
 			if (selected==0 || key->flag & PEK_SELECT) {
 				if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
 					if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
-						psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + iter, mat);
+						psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat);
 						invert_m4_m4(imat, mat);
 					}
 					iter_data->func(data, mat, imat, iter, k, key);
@@ -712,11 +744,7 @@ static void foreach_mouse_hit_key_iter(
 static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected)
 {
 	PTCacheEdit *edit = data->edit;
-	ParticleSystemModifierData *psmd = NULL;
 	ParticleEditSettings *pset = PE_settings(data->scene);
-	if (edit->psys != NULL) {
-		psmd= psys_get_modifier(data->ob, edit->psys);
-	}
 	/* all is selected in path mode */
 	if (pset->selectmode == SCE_SELECT_PATH) {
 		selected = 0;
@@ -725,7 +753,6 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
 	KeyIterData iter_data;
 	iter_data.data = data;
 	iter_data.edit = edit;
-	iter_data.psmd = psmd;
 	iter_data.selected = selected;
 	iter_data.func = func;
 
@@ -798,7 +825,7 @@ static int count_selected_keys(Scene *scene, PTCacheEdit *edit)
 static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
 {
 	PTCacheEdit *edit;
-	ParticleSystemModifierData *psmd;
+	ParticleSystemModifierData *psmd_eval;
 	KDTree *tree;
 	KDTreeNearest nearest;
 	HairKey *key;
@@ -807,10 +834,10 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
 	int index, totpart;
 
 	edit= psys->edit;
-	psmd= psys_get_modifier(ob, psys);
+	psmd_eval = edit->psmd_eval;
 	totpart= psys->totpart;
 
-	if (!psmd->mesh_final)
+	if (!psmd_eval->mesh_final)
 		return;
 
 	tree= BLI_kdtree_new(totpart);
@@ -818,7 +845,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
 	/* insert particles into kd tree */
 	LOOP_PARTICLES {
 		key = pa->hair;
-		psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat);
+		psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat);
 		copy_v3_v3(co, key->co);
 		mul_m4_v3(mat, co);
 		BLI_kdtree_insert(tree, p, co);
@@

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list