[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15013] trunk/blender/source/blender/ blenkernel/intern/modifier.c:

Brecht Van Lommel brechtvanlommel at pandora.be
Tue May 27 17:36:36 CEST 2008


Revision: 15013
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15013
Author:   blendix
Date:     2008-05-27 17:36:36 +0200 (Tue, 27 May 2008)

Log Message:
-----------

Another fix for bug #11140: explode modifier was still using more
memory than needed.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/modifier.c

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2008-05-27 15:15:50 UTC (rev 15012)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2008-05-27 15:36:36 UTC (rev 15013)
@@ -6485,12 +6485,14 @@
 	MFace *mf=0;
 	MVert *dupvert=0;
 	ParticleSettings *part=psmd->psys->part;
-	ParticleData *pa, *pars=psmd->psys->particles;
+	ParticleData *pa=NULL, *pars=psmd->psys->particles;
 	ParticleKey state;
+	EdgeHash *vertpahash;
+	EdgeHashIterator *ehi;
 	float *vertco=0, imat[4][4];
 	float loc0[3], nor[3];
 	float timestep, cfra;
-	int *facepa=emd->facepa, *vertpa=0;
+	int *facepa=emd->facepa;
 	int totdup=0,totvert=0,totface=0,totpart=0;
 	int i, j, v, mindex=0;
 
@@ -6505,34 +6507,36 @@
 	else
 		cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0);
 
-	/* table for vertice <-> particle relations (row totpart+1 is for yet unexploded verts) */
-	vertpa = MEM_callocN(sizeof(int)*(totpart+1)*totvert, "explode_vertpatab");
-	for(i=0; i<(totpart+1)*totvert; i++)
-		vertpa[i] = -1;
+	/* hash table for vertice <-> particle relations */
+	vertpahash= BLI_edgehash_new();
 
 	for (i=0; i<totface; i++) {
+		/* do mindex + totvert to ensure the vertex index to be the first
+		 * with BLI_edgehashIterator_getKey */
 		if(facepa[i]==totpart || cfra <= (pars+facepa[i])->time)
-			mindex = totpart*totvert;
+			mindex = totvert+totpart;
 		else 
-			mindex = facepa[i]*totvert;
+			mindex = totvert+facepa[i];
 
 		mf=CDDM_get_face(dm,i);
 
-		/*set face vertices to exist in particle group*/
-		vertpa[mindex+mf->v1] = 1;
-		vertpa[mindex+mf->v2] = 1;
-		vertpa[mindex+mf->v3] = 1;
+		/* set face vertices to exist in particle group */
+		BLI_edgehash_insert(vertpahash, mf->v1, mindex, NULL);
+		BLI_edgehash_insert(vertpahash, mf->v2, mindex, NULL);
+		BLI_edgehash_insert(vertpahash, mf->v3, mindex, NULL);
 		if(mf->v4)
-			vertpa[mindex+mf->v4] = 1;
+			BLI_edgehash_insert(vertpahash, mf->v4, mindex, NULL);
 	}
 
-	/*make new vertice indexes & count total vertices after duplication*/
-	for(i=0; i<(totpart+1)*totvert; i++){
-		if(vertpa[i] != -1)
-			vertpa[i] = totdup++;
+	/* make new vertice indexes & count total vertices after duplication */
+	ehi= BLI_edgehashIterator_new(vertpahash);
+	for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+		BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup));
+		totdup++;
 	}
+	BLI_edgehashIterator_free(ehi);
 
-	/*the final duplicated vertices*/
+	/* the final duplicated vertices */
 	explode= CDDM_from_template(dm, totdup, 0,totface);
 	dupvert= CDDM_get_verts(explode);
 
@@ -6541,45 +6545,49 @@
 
 	psmd->psys->lattice = psys_get_lattice(ob, psmd->psys);
 
-	/*duplicate & displace vertices*/
-	for(i=0, pa=pars; i<=totpart; i++, pa++){
-		if(i!=totpart){
+	/* duplicate & displace vertices */
+	ehi= BLI_edgehashIterator_new(vertpahash);
+	for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+		MVert source;
+		MVert *dest;
+
+		/* get particle + vertex from hash */
+		BLI_edgehashIterator_getKey(ehi, &j, &i);
+		i -= totvert;
+		v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
+
+		dm->getVert(dm, j, &source);
+		dest = CDDM_get_vert(explode,v);
+
+		DM_copy_vert_data(dm,explode,j,v,1);
+		*dest = source;
+
+		if(i!=totpart) {
+			/* get particle */
+			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);
 			Mat4MulVecfl(ob->obmat,loc0);
 
 			state.time=cfra;
 			psys_get_particle_state(ob,psmd->psys,i,&state,1);
-		}
 
-		for(j=0; j<totvert; j++){
-			v=vertpa[i*totvert+j];
-			if(v != -1) {
-				MVert source;
-				MVert *dest;
+			vertco=CDDM_get_vert(explode,v)->co;
+			
+			Mat4MulVecfl(ob->obmat,vertco);
 
-				dm->getVert(dm, j, &source);
-				dest = CDDM_get_vert(explode,v);
+			VECSUB(vertco,vertco,loc0);
 
-				DM_copy_vert_data(dm,explode,j,v,1);
-				*dest = source;
+			/* apply rotation, size & location */
+			QuatMulVecf(state.rot,vertco);
+			VecMulf(vertco,pa->size);
+			VECADD(vertco,vertco,state.co);
 
-				if(i!=totpart){
-					vertco=CDDM_get_vert(explode,v)->co;
-					
-					Mat4MulVecfl(ob->obmat,vertco);
-
-					VECSUB(vertco,vertco,loc0);
-
-					/* apply rotation, size & location */
-					QuatMulVecf(state.rot,vertco);
-					VecMulf(vertco,pa->size);
-					VECADD(vertco,vertco,state.co);
-
-					Mat4MulVecfl(imat,vertco);
-				}
-			}
+			Mat4MulVecfl(imat,vertco);
 		}
 	}
+	BLI_edgehashIterator_free(ehi);
 
 	/*map new vertices to faces*/
 	for (i=0; i<totface; i++) {
@@ -6601,15 +6609,15 @@
 		orig_v4 = source.v4;
 
 		if(facepa[i]!=totpart && cfra <= pa->time)
-			mindex = totpart*totvert;
+			mindex = totvert+totpart;
 		else 
-			mindex = facepa[i]*totvert;
+			mindex = totvert+facepa[i];
 
-		source.v1 = vertpa[mindex+source.v1];
-		source.v2 = vertpa[mindex+source.v2];
-		source.v3 = vertpa[mindex+source.v3];
+		source.v1 = edgesplit_get(vertpahash, source.v1, mindex);
+		source.v2 = edgesplit_get(vertpahash, source.v2, mindex);
+		source.v3 = edgesplit_get(vertpahash, source.v3, mindex);
 		if(source.v4)
-			source.v4 = vertpa[mindex+source.v4];
+			source.v4 = edgesplit_get(vertpahash, source.v4, mindex);
 
 		DM_copy_face_data(dm,explode,i,i,1);
 
@@ -6618,9 +6626,10 @@
 		test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3));
 	}
 
+	MEM_printmemlist_stats();
 
 	/* cleanup */
-	if(vertpa) MEM_freeN(vertpa);
+	BLI_edgehash_free(vertpahash, NULL);
 
 	/* finalization */
 	CDDM_calc_edges(explode);





More information about the Bf-blender-cvs mailing list