Merging revisions 14946-15020 of https://svn.blender.org/svnroot/bf-blender/trunk...
[blender-staging.git] / source / blender / blenkernel / intern / modifier.c
index fa54b0458d5b42dbb357035f84f6d08b6d53cfbe..067108ac8cb06adebdc93b75677876067f8c4f4e 100644 (file)
@@ -6568,12 +6568,14 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        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;
 
@@ -6588,34 +6590,36 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        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);
 
@@ -6624,45 +6628,49 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
 
        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;
-
-                               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){
-                                       vertco=CDDM_get_vert(explode,v)->co;
-                                       
-                                       Mat4MulVecfl(ob->obmat,vertco);
+                       vertco=CDDM_get_vert(explode,v)->co;
+                       
+                       Mat4MulVecfl(ob->obmat,vertco);
 
-                                       VECSUB(vertco,vertco,loc0);
+                       VECSUB(vertco,vertco,loc0);
 
-                                       /* apply rotation, size & location */
-                                       QuatMulVecf(state.rot,vertco);
-                                       VecMulf(vertco,pa->size);
-                                       VECADD(vertco,vertco,state.co);
+                       /* 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++) {
@@ -6684,15 +6692,15 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
                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);
 
@@ -6701,9 +6709,10 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
                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);