[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16841] trunk/blender/source/blender: Fix for bug #17302: subsurf + particle size vertex groups did not

Brecht Van Lommel brecht at blender.org
Tue Sep 30 08:12:47 CEST 2008


Revision: 16841
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16841
Author:   blendix
Date:     2008-09-30 08:12:47 +0200 (Tue, 30 Sep 2008)

Log Message:
-----------
Fix for bug #17302: subsurf + particle size vertex groups did not
work correct, also refactored some code here to make it more clear.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_particle.h
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/src/editparticle.c

Modified: trunk/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_particle.h	2008-09-30 05:51:51 UTC (rev 16840)
+++ trunk/blender/source/blender/blenkernel/BKE_particle.h	2008-09-30 06:12:47 UTC (rev 16841)
@@ -226,7 +226,7 @@
 
 void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);
 
-void psys_particle_on_emitter(struct Object *ob, struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
+void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
 struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
 
 struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
@@ -284,11 +284,12 @@
 float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
 void psys_get_texture(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
 void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
+float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
 float psys_interpolate_value_from_verts(struct DerivedMesh *dm, short from, int index, float *fw, float *values);
 void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time);
 
 int psys_intersect_dm(struct Object *ob, struct DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, float *face_minmax, float *pa_minmax, float radius, float *ipoint);
-void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
+void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
 
 /* particle_system.c */
 void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2008-09-30 05:51:51 UTC (rev 16840)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2008-09-30 06:12:47 UTC (rev 16841)
@@ -6543,7 +6543,7 @@
 	/* make tree of emitter locations */
 	tree=BLI_kdtree_new(totpart);
 	for(p=0,pa=psys->particles; p<totpart; p++,pa++){
-		psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
+		psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
 		BLI_kdtree_insert(tree, p, co, NULL);
 	}
 	BLI_kdtree_balance(tree);
@@ -7146,7 +7146,7 @@
 			pa= pars+i;
 
 			/* get particle state */
-			psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
+			psys_particle_on_emitter(psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
 			Mat4MulVecfl(ob->obmat,loc0);
 
 			state.time=cfra;

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2008-09-30 05:51:51 UTC (rev 16840)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2008-09-30 06:12:47 UTC (rev 16841)
@@ -1117,8 +1117,8 @@
 	}
 }
 
-/* find the derived mesh face for a particle, set the mf passed.
-This is slow, can be optimized but only for many lookups, return the face lookup index*/
+/* find the derived mesh face for a particle, set the mf passed. this is slow
+ * and can be optimized but only for many lookups. returns the face index. */
 int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *fw, struct LinkNode *node)
 {
 	Mesh *me= (Mesh*)ob->data;
@@ -1186,169 +1186,143 @@
 	return DMCACHE_NOTFOUND;
 }
 
-/* interprets particle data to get a point on a mesh in object space */
-#define PARTICLE_ON_DM_ERROR \
-	{ if(vec) { vec[0]=vec[1]=vec[2]=0.0; } \
-	  if(nor) { nor[0]=nor[1]=0.0; nor[2]=1.0; } \
-	  if(orco) { orco[0]=orco[1]=orco[2]=0.0; } \
-	  if(ornor) { ornor[0]=ornor[1]=0.0; ornor[2]=1.0; } \
-	  if(utan) { utan[0]=utan[1]=utan[2]=0.0; } \
-	  if(vtan) { vtan[0]=vtan[1]=vtan[2]=0.0; } }
-
-void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
+static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, int *mapindex, float *mapfw)
 {
-	float temp1[3];
-	float (*orcodata)[3];
+	if(index < 0)
+		return 0;
 
-	if(index < 0) { /* 'no dm' error has happened! */
-		PARTICLE_ON_DM_ERROR;
-		return;
-	}
-	orcodata= dm->getVertDataArray(dm, CD_ORCO);
-
 	if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) {
-		/* this works for meshes with deform verts only - constructive modifiers wont work properly*/
+		/* for meshes that are either only defined or for child particles, the
+		 * index and fw do not require any mapping, so we can directly use it */
 		if(from == PART_FROM_VERT) {
-			if(index >= dm->getNumVerts(dm)) {
-				PARTICLE_ON_DM_ERROR;
-				return;
-			}
-	
-			dm->getVertCo(dm,index,vec);
-			if(nor){
-				dm->getVertNo(dm,index,nor);
-				Normalize(nor);
-			}
-			if(orco)
-				VECCOPY(orco, orcodata[index])
-			if(ornor) {
-				dm->getVertNo(dm,index,nor);
-				Normalize(nor);
-			}
+			if(index >= dm->getNumVerts(dm))
+				return 0;
+
+			*mapindex = index;
 		}
-		else { /* PART_FROM_FACE / PART_FROM_VOLUME */
-			MFace *mface;
-			MTFace *mtface=0;
-			MVert *mvert;
-			int uv_index;
+		else  { /* FROM_FACE/FROM_VOLUME */
+			if(index >= dm->getNumFaces(dm))
+				return 0;
 
-			if(index >= dm->getNumFaces(dm)) {
-				PARTICLE_ON_DM_ERROR;
-				return;
-			}
-			
-			mface=dm->getFaceData(dm,index,CD_MFACE);
-			mvert=dm->getVertDataArray(dm,CD_MVERT);
-			uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
-
-			if(uv_index>=0){
-				CustomDataLayer *layer=&dm->faceData.layers[uv_index];
-				mtface= &((MTFace*)layer->data)[index];
-			}
-
-			if(from==PART_FROM_VOLUME){
-				psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,temp1,utan,vtan,orco,ornor);
-				if(nor)
-					VECCOPY(nor,temp1);
-				Normalize(temp1);
-				VecMulf(temp1,-foffset);
-				VECADD(vec,vec,temp1);
-			}
-			else
-				psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,nor,utan,vtan,orco,ornor);
+			*mapindex = index;
+			QUATCOPY(mapfw, fw);
 		}
 	} else {
-		/* Need to support constructive modifiers, this is a bit more tricky
-			we need a customdata layer like UV's so we can position the particle */
-		
-		/* Only face supported at the moment */
-		if(ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+		/* for other meshes that have been modified, we try to map the particle
+		 * to their new location, which means a different index, and for faces
+		 * also a new face interpolation weights */
+		if(from == PART_FROM_VERT) {
+			if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > dm->getNumVerts(dm))
+				return 0;
+
+			*mapindex = index_dmcache;
+		}
+		else  { /* FROM_FACE/FROM_VOLUME */
 			/* find a face on the derived mesh that uses this face */
-			Mesh *me= (Mesh*)ob->data;
-			MVert *mvert;
 			MFace *mface;
-			MTFace *mtface;
 			OrigSpaceFace *osface;
-			int *origindex;
-			float fw_mod[4];
-			int i, totface;
-			
-			mvert= dm->getVertDataArray(dm,CD_MVERT);
+			int i;
 
+			i = index_dmcache;
+
+			if(i== DMCACHE_NOTFOUND || i >= dm->getNumFaces(dm))
+				return 0;
+
+			*mapindex = i;
+
+			/* modify the original weights to become
+			 * weights for the derived mesh face */
 			osface= dm->getFaceDataArray(dm, CD_ORIGSPACE);
-			origindex= dm->getFaceDataArray(dm, CD_ORIGINDEX);
+			mface= dm->getFaceData(dm, i, CD_MFACE);
 
-			/* For this to work we need origindex and OrigSpace coords */
-			if(origindex==NULL || osface==NULL || index>=me->totface) {
-				PARTICLE_ON_DM_ERROR;
-				return;
-			}
-			
-			if (index_dmcache == DMCACHE_NOTFOUND)
-				i = psys_particle_dm_face_lookup(ob, dm, index, fw, (LinkNode*)NULL);
+			if(osface == NULL)
+				mapfw[0]= mapfw[1]= mapfw[2]= mapfw[3]= 0.0f;
 			else
-				i = index_dmcache;
+				psys_origspace_to_w(&osface[i], mface->v4, fw, mapfw);
+		}
+	}
 
-			totface = dm->getNumFaces(dm);
+	return 1;
+}
 
-			/* Any time this happens, and the face has not been removed,
-			* its a BUG watch out for this error! */
-			if (i==-1) {
-				printf("Cannot find original face %i\n", index);
-				PARTICLE_ON_DM_ERROR;
-				return;
-			}
-			else if(i >= totface)
-				return;
+/* interprets particle data to get a point on a mesh in object space */
+void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
+{
+	float tmpnor[3], mapfw[4];
+	float (*orcodata)[3];
+	int mapindex;
 
-			mface= dm->getFaceData(dm, i, CD_MFACE);
-			mtface= dm->getFaceData(dm, i, CD_MTFACE); 
-			osface += i;
+	if(!psys_map_index_on_dm(dm, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) {
+		if(vec) { vec[0]=vec[1]=vec[2]=0.0; }
+		if(nor) { nor[0]=nor[1]=0.0; nor[2]=1.0; }
+		if(orco) { orco[0]=orco[1]=orco[2]=0.0; }
+		if(ornor) { ornor[0]=ornor[1]=0.0; ornor[2]=1.0; }
+		if(utan) { utan[0]=utan[1]=utan[2]=0.0; }
+		if(vtan) { vtan[0]=vtan[1]=vtan[2]=0.0; }
 
-			/* we need to modify the original weights to become weights for
-			 * the derived mesh face */

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list