[Bf-blender-cvs] [182d6f1] temp_hair_modifiers: List of particle modifiers in particle systems and read/write code.

Lukas Tönne noreply at git.blender.org
Tue Feb 3 11:34:26 CET 2015


Commit: 182d6f147c59fa8a5bbd35cacb72589955cab499
Author: Lukas Tönne
Date:   Tue Feb 3 11:31:23 2015 +0100
Branches: temp_hair_modifiers
https://developer.blender.org/rB182d6f147c59fa8a5bbd35cacb72589955cab499

List of particle modifiers in particle systems and read/write code.

Note: Ideally modifiers for particles should be part of the
`ParticleSettings` datablock instead of `ParticleSystem`. The problem
with this is that many modifiers, as they are implemented for meshes,
will store specific data that is associated to the object instance
in the scene. Storing modifiers in the settings would make this
impossible and require some complicated syncing between particle systems
and their settings.

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

M	source/blender/blenkernel/BKE_particle.h
M	source/blender/blenkernel/intern/particle_modifier.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_particle_types.h

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

diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index c9e5330..ed10f60 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -40,6 +40,7 @@
 #include "DNA_object_types.h"
 
 #include "BKE_customdata.h"
+#include "BKE_modifier.h"
 
 struct ParticleSystemModifierData;
 struct ParticleSystem;
@@ -273,6 +274,8 @@ typedef struct ParticleInterpolationData {
 	int bspline;
 } ParticleInterpolationData;
 
+typedef void (*IDWalkParticleFunc)(void *userData, struct Object *ob, struct ParticleSystem *psys, struct ID **idpoin);
+
 typedef struct ParticleModifierTypeInfo {
 	/* The user visible name for this modifier */
 	char name[32];
@@ -282,6 +285,40 @@ typedef struct ParticleModifierTypeInfo {
 
 	/* The size of the modifier data type, used by allocation. */
 	int structSize;
+
+	/********************* Non-optional functions *********************/
+
+	/* Copy instance data for this modifier type. Should copy all user
+	 * level settings to the target modifier.
+	 */
+	void (*copyData)(struct ParticleModifierData *md, struct ParticleModifierData *target);
+
+	/********************* Optional functions *********************/
+
+	/* Initialize new instance data for this modifier type, this function
+	 * should set modifier variables to their default values.
+	 * 
+	 * This function is optional.
+	 */
+	void (*initData)(struct ParticleModifierData *md);
+
+	/* Free internal modifier data variables, this function should
+	 * not free the md variable itself.
+	 *
+	 * This function is optional.
+	 */
+	void (*freeData)(struct ParticleModifierData *md);
+
+	/* Should call the given walk function with a pointer to each ID
+	 * pointer (i.e. each datablock pointer) that the modifier data
+	 * stores. This is used for linking on file load and for
+	 * unlinking datablocks or forwarding datablock references.
+	 *
+	 * This function is optional. If it is not present, foreachObjectLink
+	 * will be used.
+	 */
+	void (*foreachIDLink)(struct ParticleModifierData *md, struct Object *ob, struct ParticleSystem *psys,
+	                      IDWalkParticleFunc walk, void *userData);
 } ParticleModifierTypeInfo;
 
 #define PARTICLE_DRAW_DATA_UPDATED  1
@@ -318,6 +355,7 @@ BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float ve
 /* particle.c */
 void particle_modifier_types_init(void);
 struct ParticleModifierTypeInfo *particle_modifier_type_info_get(ParticleModifierType type);
+void particle_modifier_foreachIDLink(struct Object *ob, struct ParticleSystem *psys, IDWalkParticleFunc walk, void *userData);
 
 int count_particles(struct ParticleSystem *psys);
 int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);
diff --git a/source/blender/blenkernel/intern/particle_modifier.c b/source/blender/blenkernel/intern/particle_modifier.c
index e528e8c..d6ed199 100644
--- a/source/blender/blenkernel/intern/particle_modifier.c
+++ b/source/blender/blenkernel/intern/particle_modifier.c
@@ -68,3 +68,15 @@ ParticleModifierTypeInfo *particle_modifier_type_info_get(ParticleModifierType t
 		return NULL;
 	}
 }
+
+void particle_modifier_foreachIDLink(Object *ob, ParticleSystem *psys, IDWalkParticleFunc walk, void *userData)
+{
+	ParticleModifierData *md = psys->modifiers.first;
+
+	for (; md; md = md->next) {
+		ParticleModifierTypeInfo *mti = particle_modifier_type_info_get(md->type);
+
+		if (mti->foreachIDLink)
+			mti->foreachIDLink(md, ob, psys, walk, userData);
+	}
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 34e9e0a..cf5125f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3852,6 +3852,58 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 	}
 }
 
+static void lib_link_particle_modifiers__linkModifiers(void *userData, Object *ob, ParticleSystem *UNUSED(psys),
+                                                       ID **idpoin)
+{
+	FileData *fd = userData;
+
+	*idpoin = newlibadr(fd, ob->id.lib, *idpoin);
+	/* hardcoded bad exception; non-object modifier data gets user count (texture, displace) */
+	if (*idpoin && GS((*idpoin)->name) != ID_OB)
+		(*idpoin)->us++;
+}
+static void lib_link_particle_modifiers(FileData *fd, Object *ob, ParticleSystem *psys)
+{
+	particle_modifier_foreachIDLink(ob, psys, lib_link_particle_modifiers__linkModifiers, fd);
+}
+
+static void direct_link_particle_modifiers(FileData *fd, ListBase *lb)
+{
+	ParticleModifierData *md;
+	
+	link_list(fd, lb);
+	
+	for (md = lb->first; md; md = md->next) {
+		/* if modifiers disappear, or for upward compatibility */
+		if (NULL == particle_modifier_type_info_get(md->type))
+			md->type = eModifierType_None;
+		
+		if (md->type == eModifierType_MeshDeform) {
+			MeshDeformParticleModifierData *mmd = (MeshDeformParticleModifierData*) md;
+			
+#if 0 // TODO
+			mmd->bindinfluences = newdataadr(fd, mmd->bindinfluences);
+			mmd->bindoffsets = newdataadr(fd, mmd->bindoffsets);
+			mmd->bindcagecos = newdataadr(fd, mmd->bindcagecos);
+			mmd->dyngrid = newdataadr(fd, mmd->dyngrid);
+			mmd->dyninfluences = newdataadr(fd, mmd->dyninfluences);
+			mmd->dynverts = newdataadr(fd, mmd->dynverts);
+			
+			mmd->bindweights = newdataadr(fd, mmd->bindweights);
+			mmd->bindcos = newdataadr(fd, mmd->bindcos);
+			
+			if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+				if (mmd->bindoffsets)  BLI_endian_switch_int32_array(mmd->bindoffsets, mmd->totvert + 1);
+				if (mmd->bindcagecos)  BLI_endian_switch_float_array(mmd->bindcagecos, mmd->totcagevert * 3);
+				if (mmd->dynverts)     BLI_endian_switch_int32_array(mmd->dynverts, mmd->totvert);
+				if (mmd->bindweights)  BLI_endian_switch_float_array(mmd->bindweights, mmd->totvert);
+				if (mmd->bindcos)      BLI_endian_switch_float_array(mmd->bindcos, mmd->totcagevert * 3);
+			}
+#endif
+		}
+	}
+}
+
 static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
 {
 	ParticleSystem *psys, *psysnext;
@@ -3869,6 +3921,8 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase
 			psys->parent = newlibadr(fd, id->lib, psys->parent);
 			psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
 			
+			lib_link_particle_modifiers(fd, ob, psys);
+			
 			if (psys->clmd) {
 				/* XXX - from reading existing code this seems correct but intended usage of
 				 * pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -3946,6 +4000,8 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
 		
 		direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache, 0);
 		
+		direct_link_particle_modifiers(fd, &psys->modifiers);
+		
 		if (psys->clmd) {
 			psys->clmd = newdataadr(fd, psys->clmd);
 			psys->clmd->clothObject = NULL;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 85130ee..a619ca8 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -153,6 +153,7 @@
 #include "BKE_library.h" // for  set_listbasepointers
 #include "BKE_main.h"
 #include "BKE_node.h"
+#include "BKE_particle.h"
 #include "BKE_report.h"
 #include "BKE_sequencer.h"
 #include "BKE_subsurf.h"
@@ -1090,6 +1091,7 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches)
 		}
 	}
 }
+
 static void write_particlesettings(WriteData *wd, ListBase *idbase)
 {
 	ParticleSettings *part;
@@ -1146,6 +1148,35 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
 		part= part->id.next;
 	}
 }
+
+static void write_particle_modifiers(WriteData *wd, ListBase *modbase)
+{
+	ParticleModifierData *md;
+
+	if (modbase == NULL) return;
+	for (md=modbase->first; md; md= md->next) {
+		ParticleModifierTypeInfo *mti = particle_modifier_type_info_get(md->type);
+		if (mti == NULL) return;
+		
+		writestruct(wd, DATA, mti->structName, 1, md);
+			
+		if (md->type==eParticleModifierType_MeshDeform) {
+			MeshDeformParticleModifierData *mmd = (MeshDeformParticleModifierData*) md;
+#if 0 // TODO
+			int size = mmd->dyngridsize;
+
+			writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->bindinfluences);
+			writedata(wd, DATA, sizeof(int) * (mmd->totvert + 1), mmd->bindoffsets);
+			writedata(wd, DATA, sizeof(float) * 3 * mmd->totcagevert,
+				mmd->bindcagecos);
+			writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid);
+			writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
+			writedata(wd, DATA, sizeof(int)*mmd->totvert, mmd->dynverts);
+#endif
+		}
+	}
+}
+
 static void write_particlesystems(WriteData *wd, ListBase *particles)
 {
 	ParticleSystem *psys= particles->first;
@@ -1184,6 +1215,8 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
 		}
 
 		write_pointcaches(wd, &psys->ptcaches);
+
+		write_particle_modifiers(wd, &psys->modifiers);
 	}
 }
 
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index a890b49..76a2044 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -165,6 +165,8 @@ typedef enum ParticleModifierType {
 } ParticleModifierType;
 
 typedef struct ParticleModifierData {
+	struct ParticleModifierData *next, *prev;
+	
 	int type;
 	int flag;
 } ParticleModifierData;
@@ -269,7 +271,7 @@ typedef struct ParticleSettings {
 	struct MTex *mtex[18];		/* MAX_MTEX */
 
 	struct Group *dup_group;
-	struct ListBase dupliweights;
+	ListBase dupliweights;
 	struct Group *eff_group  DNA_DEPRECATED;		// deprecated
 	struct Object *dup_ob;
 	struct Object *bb_ob;
@@ -307,6 +309,8 @@ typedef struct ParticleSystem {
 	struct ClothModifierData *clmd;					/* cloth simulation for hair */
 	struct DerivedMesh *hair_in_dm, *hair_out_dm;	/* input/output for cloth simulation */
 
+	ListBase modifiers;
+
 	struct Object *target_ob;
 
 	struct LatticeDeformData *lattice_deform_data;		/* run-time only lattice deformation data */




More information about the Bf-blender-cvs mailing list