[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14810] trunk/blender/source/blender:

Brecht Van Lommel brechtvanlommel at pandora.be
Mon May 12 13:48:55 CEST 2008


Revision: 14810
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14810
Author:   blendix
Date:     2008-05-12 13:48:55 +0200 (Mon, 12 May 2008)

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

Fix for bug #11140: explode modifier could run out of memory quite
quickly because it allocated a totvert*totvert size array, now uses
edgehash instead.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/blenlib/BLI_edgehash.h
    trunk/blender/source/blender/blenlib/intern/edgehash.c

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2008-05-12 09:01:15 UTC (rev 14809)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2008-05-12 11:48:55 UTC (rev 14810)
@@ -5997,21 +5997,30 @@
 	if(vertpa) MEM_freeN(vertpa);
 	BLI_kdtree_free(tree);
 }
+
+static int edgesplit_get(EdgeHash *edgehash, int v1, int v2)
+{
+	return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
+}
+
 static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
 	DerivedMesh *splitdm;
 	MFace *mf=0,*df1=0,*df2=0,*df3=0;
 	MFace *mface=CDDM_get_faces(dm);
 	MVert *dupve, *mv;
+	EdgeHash *edgehash;
+	EdgeHashIterator *ehi;
 	int totvert=dm->getNumVerts(dm);
 	int totface=dm->getNumFaces(dm);
 
-	int *edgesplit = MEM_callocN(sizeof(int)*totvert*totvert,"explode_edgesplit");
-	int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_edgesplit");
+	int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_facesplit");
 	int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
 	int *facepa = emd->facepa;
 	int *fs, totesplit=0,totfsplit=0,totin=0,curdupvert=0,curdupface=0,curdupin=0;
-	int i,j,v1,v2,v3,v4;
+	int i,j,v1,v2,v3,v4,esplit;
 
+	edgehash= BLI_edgehash_new();
+
 	/* recreate vertpa from facepa calculation */
 	for (i=0,mf=mface; i<totface; i++,mf++) {
 		vertpa[mf->v1]=facepa[i];
@@ -6030,22 +6039,22 @@
 			v4=vertpa[mf->v4];
 
 			if(v1!=v2){
-				edgesplit[mf->v1*totvert+mf->v2]=edgesplit[mf->v2*totvert+mf->v1]=1;
+				BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
 				(*fs)++;
 			}
 
 			if(v2!=v3){
-				edgesplit[mf->v2*totvert+mf->v3]=edgesplit[mf->v3*totvert+mf->v2]=1;
+				BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
 				(*fs)++;
 			}
 
 			if(v3!=v4){
-				edgesplit[mf->v3*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v3]=1;
+				BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
 				(*fs)++;
 			}
 
 			if(v1!=v4){
-				edgesplit[mf->v1*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v1]=1;
+				BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
 				(*fs)++;
 			}
 
@@ -6054,28 +6063,29 @@
 					*fs=1;
 				else if(v1!=v2){
 					if(v1!=v4)
-						edgesplit[mf->v2*totvert+mf->v3]=edgesplit[mf->v3*totvert+mf->v2]=1;
+						BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
 					else
-						edgesplit[mf->v3*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v3]=1;
+						BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
 				}
 				else{ 
 					if(v1!=v4)
-						edgesplit[mf->v1*totvert+mf->v2]=edgesplit[mf->v2*totvert+mf->v1]=1;
+						BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
 					else
-						edgesplit[mf->v1*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v1]=1;
+						BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
 				}
 			}
 		}
 	}
 
 	/* count splits & reindex */
+	ehi= BLI_edgehashIterator_new(edgehash);
 	totesplit=totvert;
-	for(j=0; j<totvert; j++){
-		for(i=j+1; i<totvert; i++){
-			if(edgesplit[j*totvert+i])
-				edgesplit[j*totvert+i]=edgesplit[i*totvert+j]=totesplit++;
-		}
+	for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+		BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit));
+		totesplit++;
 	}
+	BLI_edgehashIterator_free(ehi);
+
 	/* count new faces due to splitting */
 	for(i=0,fs=facesplit; i<totface; i++,fs++){
 		if(*fs==1)
@@ -6123,23 +6133,23 @@
 
 	/* create new verts */
 	curdupvert=totvert;
-	for(j=0; j<totvert; j++){
-		for(i=j+1; i<totvert; i++){
-			if(edgesplit[j*totvert+i]){
-				mv=CDDM_get_vert(splitdm,j);
-				dupve=CDDM_get_vert(splitdm,edgesplit[j*totvert+i]);
+	ehi= BLI_edgehashIterator_new(edgehash);
+	for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+		BLI_edgehashIterator_getKey(ehi, &i, &j);
+		esplit= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
+		mv=CDDM_get_vert(splitdm,j);
+		dupve=CDDM_get_vert(splitdm,esplit);
 
-				DM_copy_vert_data(splitdm,splitdm,j,edgesplit[j*totvert+i],1);
+		DM_copy_vert_data(splitdm,splitdm,j,esplit,1);
 
-				*dupve=*mv;
+		*dupve=*mv;
 
-				mv=CDDM_get_vert(splitdm,i);
+		mv=CDDM_get_vert(splitdm,i);
 
-				VECADD(dupve->co,dupve->co,mv->co);
-				VecMulf(dupve->co,0.5);
-			}
-		}
+		VECADD(dupve->co,dupve->co,mv->co);
+		VecMulf(dupve->co,0.5);
 	}
+	BLI_edgehashIterator_free(ehi);
 
 	/* create new faces */
 	curdupface=totface;
@@ -6160,14 +6170,14 @@
 				curdupface++;
 				
 				if(v1==v2){
-					df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-					df1->v2=edgesplit[mf->v2*totvert+mf->v3];
+					df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+					df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
 					mf->v3=df1->v2;
 					mf->v4=df1->v1;
 				}
 				else{
-					df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-					df1->v4=edgesplit[mf->v3*totvert+mf->v4];
+					df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+					df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
 					mf->v2=df1->v1;
 					mf->v3=df1->v4;
 				}
@@ -6190,8 +6200,8 @@
 
 				if(v1!=v2){
 					if(v1!=v4){
-						df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-						df1->v2=edgesplit[mf->v1*totvert+mf->v2];
+						df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+						df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
 						df2->v1=df1->v3=mf->v2;
 						df2->v3=df1->v4=mf->v4;
 						df2->v2=mf->v3;
@@ -6204,8 +6214,8 @@
 						facepa[i]=v1;
 					}
 					else{
-						df1->v2=edgesplit[mf->v1*totvert+mf->v2];
-						df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+						df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
+						df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
 						df1->v4=mf->v3;
 						df2->v2=mf->v3;
 						df2->v3=mf->v4;
@@ -6221,8 +6231,8 @@
 				}
 				else{
 					if(v1!=v4){
-						df1->v3=edgesplit[mf->v3*totvert+mf->v4];
-						df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+						df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
+						df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
 						df1->v2=mf->v3;
 
 						mf->v1=df1->v4;
@@ -6234,8 +6244,8 @@
 						facepa[i]=v4;
 					}
 					else{
-						df1->v3=edgesplit[mf->v2*totvert+mf->v3];
-						df1->v4=edgesplit[mf->v3*totvert+mf->v4];
+						df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
+						df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
 						df1->v1=mf->v4;
 						df1->v2=mf->v2;
 						df2->v3=mf->v4;
@@ -6271,9 +6281,9 @@
 				curdupface++;
 
 				if(v1==v2){
-					df2->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-					df3->v1=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
-					df3->v3=df2->v2=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+					df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+					df3->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
+					df3->v3=df2->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 					df3->v2=mf->v3;
 					df2->v3=mf->v4;
 					df1->v4=df2->v4=df3->v4=0;
@@ -6286,9 +6296,9 @@
 					facepa[curdupface-2]=v4;
 				}
 				else if(v2==v3){
-					df3->v1=df2->v3=df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-					df2->v2=df1->v2=edgesplit[mf->v1*totvert+mf->v2];
-					df3->v2=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+					df3->v1=df2->v3=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+					df2->v2=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
+					df3->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
 					df3->v3=mf->v4;
 					df2->v1=mf->v1;
@@ -6302,9 +6312,9 @@
 					facepa[curdupface-2]=v1;
 				}
 				else if(v3==v4){
-					df3->v2=df2->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-					df2->v3=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
-					df3->v3=df1->v3=edgesplit[mf->v1*totvert+mf->v4];
+					df3->v2=df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+					df2->v3=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
+					df3->v3=df1->v3=edgesplit_get(edgehash, mf->v1, mf->v4);
 
 					df3->v1=mf->v1;
 					df2->v2=mf->v2;
@@ -6318,9 +6328,9 @@
 					facepa[curdupface-2]=v2;
 				}
 				else{
-					df3->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-					df3->v3=df2->v1=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
-					df2->v3=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+					df3->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+					df3->v3=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
+					df2->v3=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
 					df3->v2=mf->v2;
 					df2->v2=mf->v3;
@@ -6371,11 +6381,11 @@
 					*df3=*mf;
 					curdupface++;
 
-					df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-					df3->v2=df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+					df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+					df3->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
 
-					df2->v1=edgesplit[mf->v1*totvert+mf->v4];
-					df3->v4=df2->v3=edgesplit[mf->v3*totvert+mf->v4];
+					df2->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+					df3->v4=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
 					df3->v1=df2->v2=df1->v4=curdupin;
 
@@ -6412,11 +6422,11 @@
 					curdupface++;
 
 					if(v2==v3){
-						df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-						df3->v1=df1->v2=df1->v3=edgesplit[mf->v2*totvert+mf->v3];
-						df2->v1=df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+						df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+						df3->v1=df1->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
+						df2->v1=df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
 
-						df3->v3=df2->v3=edgesplit[mf->v3*totvert+mf->v4];
+						df3->v3=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
 						df3->v2=mf->v3;
 						df3->v4=0;
@@ -6430,11 +6440,11 @@
 						facepa[curdupface-1]=v3;
 					}
 					else{
-						df3->v1=df2->v1=df1->v2=edgesplit[mf->v1*totvert+mf->v2];
-						df2->v4=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
-						df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+						df3->v1=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
+						df2->v4=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
+						df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
 
-						df3->v3=df2->v2=edgesplit[mf->v2*totvert+mf->v3];
+						df3->v3=df2->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
 
 						df3->v4=0;
 
@@ -6458,7 +6468,7 @@
 		}
 	}
 
-	MEM_freeN(edgesplit);
+	BLI_edgehash_free(edgehash, NULL);
 	MEM_freeN(facesplit);
 	MEM_freeN(vertpa);
 

Modified: trunk/blender/source/blender/blenlib/BLI_edgehash.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_edgehash.h	2008-05-12 09:01:15 UTC (rev 14809)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list