Blender V2.61 - r43446

MOD_explode.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software  Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): Daniel Dunbar
00022  *                 Ton Roosendaal,
00023  *                 Ben Batt,
00024  *                 Brecht Van Lommel,
00025  *                 Campbell Barton
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  *
00029  */
00030 
00036 #include "DNA_meshdata_types.h"
00037 #include "DNA_scene_types.h"
00038 
00039 #include "BLI_kdtree.h"
00040 #include "BLI_rand.h"
00041 #include "BLI_math.h"
00042 #include "BLI_edgehash.h"
00043 #include "BLI_utildefines.h"
00044 
00045 #include "BKE_cdderivedmesh.h"
00046 #include "BKE_deform.h"
00047 #include "BKE_lattice.h"
00048 #include "BKE_mesh.h"
00049 #include "BKE_modifier.h"
00050 #include "BKE_object.h"
00051 #include "BKE_particle.h"
00052 #include "BKE_scene.h"
00053 
00054 
00055 #include "MEM_guardedalloc.h"
00056 
00057 #include "MOD_util.h"
00058 
00059 static void initData(ModifierData *md)
00060 {
00061     ExplodeModifierData *emd= (ExplodeModifierData*) md;
00062 
00063     emd->facepa= NULL;
00064     emd->flag |= eExplodeFlag_Unborn+eExplodeFlag_Alive+eExplodeFlag_Dead;
00065 }
00066 static void freeData(ModifierData *md)
00067 {
00068     ExplodeModifierData *emd= (ExplodeModifierData*) md;
00069     
00070     if(emd->facepa) MEM_freeN(emd->facepa);
00071 }
00072 static void copyData(ModifierData *md, ModifierData *target)
00073 {
00074     ExplodeModifierData *emd= (ExplodeModifierData*) md;
00075     ExplodeModifierData *temd= (ExplodeModifierData*) target;
00076 
00077     temd->facepa = NULL;
00078     temd->flag = emd->flag;
00079     temd->protect = emd->protect;
00080     temd->vgroup = emd->vgroup;
00081 }
00082 static int dependsOnTime(ModifierData *UNUSED(md)) 
00083 {
00084     return 1;
00085 }
00086 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
00087 {
00088     ExplodeModifierData *emd= (ExplodeModifierData*) md;
00089     CustomDataMask dataMask = 0;
00090 
00091     if(emd->vgroup)
00092         dataMask |= CD_MASK_MDEFORMVERT;
00093 
00094     return dataMask;
00095 }
00096 
00097 static void createFacepa(ExplodeModifierData *emd,
00098                         ParticleSystemModifierData *psmd,
00099                         DerivedMesh *dm)
00100 {
00101     ParticleSystem *psys=psmd->psys;
00102     MFace *fa=NULL, *mface=NULL;
00103     MVert *mvert = NULL;
00104     ParticleData *pa;
00105     KDTree *tree;
00106     float center[3], co[3];
00107     int *facepa=NULL,*vertpa=NULL,totvert=0,totface=0,totpart=0;
00108     int i,p,v1,v2,v3,v4=0;
00109 
00110     mvert = dm->getVertArray(dm);
00111     mface = dm->getFaceArray(dm);
00112     totface= dm->getNumFaces(dm);
00113     totvert= dm->getNumVerts(dm);
00114     totpart= psmd->psys->totpart;
00115 
00116     BLI_srandom(psys->seed);
00117 
00118     if(emd->facepa)
00119         MEM_freeN(emd->facepa);
00120 
00121     facepa = emd->facepa = MEM_callocN(sizeof(int)*totface, "explode_facepa");
00122 
00123     vertpa = MEM_callocN(sizeof(int)*totvert, "explode_vertpa");
00124 
00125     /* initialize all faces & verts to no particle */
00126     for(i=0; i<totface; i++)
00127         facepa[i]=totpart;
00128 
00129     for (i=0; i<totvert; i++)
00130         vertpa[i]=totpart;
00131 
00132     /* set protected verts */
00133     if(emd->vgroup){
00134         MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
00135         if(dvert){
00136             const int defgrp_index= emd->vgroup-1;
00137             for(i=0; i<totvert; i++, dvert++){
00138                 float val = BLI_frand();
00139                 val = (1.0f-emd->protect)*val + emd->protect*0.5f;
00140                 if(val < defvert_find_weight(dvert, defgrp_index))
00141                     vertpa[i] = -1;
00142             }
00143         }
00144     }
00145 
00146     /* make tree of emitter locations */
00147     tree=BLI_kdtree_new(totpart);
00148     for(p=0,pa=psys->particles; p<totpart; p++,pa++){
00149         psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,NULL,NULL,NULL,NULL,NULL);
00150         BLI_kdtree_insert(tree, p, co, NULL);
00151     }
00152     BLI_kdtree_balance(tree);
00153 
00154     /* set face-particle-indexes to nearest particle to face center */
00155     for(i=0,fa=mface; i<totface; i++,fa++){
00156         add_v3_v3v3(center,mvert[fa->v1].co,mvert[fa->v2].co);
00157         add_v3_v3(center, mvert[fa->v3].co);
00158         if(fa->v4){
00159             add_v3_v3(center, mvert[fa->v4].co);
00160             mul_v3_fl(center,0.25);
00161         }
00162         else
00163             mul_v3_fl(center,0.3333f);
00164 
00165         p= BLI_kdtree_find_nearest(tree,center,NULL,NULL);
00166 
00167         v1=vertpa[fa->v1];
00168         v2=vertpa[fa->v2];
00169         v3=vertpa[fa->v3];
00170         if(fa->v4)
00171             v4=vertpa[fa->v4];
00172 
00173         if(v1>=0 && v2>=0 && v3>=0 && (fa->v4==0 || v4>=0))
00174             facepa[i]=p;
00175 
00176         if(v1>=0) vertpa[fa->v1]=p;
00177         if(v2>=0) vertpa[fa->v2]=p;
00178         if(v3>=0) vertpa[fa->v3]=p;
00179         if(fa->v4 && v4>=0) vertpa[fa->v4]=p;
00180     }
00181 
00182     if(vertpa) MEM_freeN(vertpa);
00183     BLI_kdtree_free(tree);
00184 }
00185 
00186 static int edgecut_get(EdgeHash *edgehash, int v1, int v2)
00187 {
00188     return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
00189 }
00190 
00191  
00192 static const short add_faces[24] = {
00193     0,
00194     0, 0, 2, 0, 1, 2, 2, 0, 2, 1,
00195     2, 2, 2, 2, 3, 0, 0, 0, 1, 0,
00196     1, 1, 2
00197  };
00198 
00199 static MFace *get_dface(DerivedMesh *dm, DerivedMesh *split, int cur, int i, MFace *mf)
00200 {
00201     MFace *df = CDDM_get_face(split, cur);
00202     DM_copy_face_data(dm, split, i, cur, 1);
00203     *df = *mf;
00204     return df;
00205 }
00206 
00207 #define SET_VERTS(a, b, c, d) \
00208             v[0]=mf->v##a; uv[0]=a-1; \
00209             v[1]=mf->v##b; uv[1]=b-1; \
00210             v[2]=mf->v##c; uv[2]=c-1; \
00211             v[3]=mf->v##d; uv[3]=d-1;
00212 
00213 #define GET_ES(v1, v2) edgecut_get(eh, v1, v2);
00214 #define INT_UV(uvf, c0, c1) interp_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1], 0.5f);
00215 
00216 static void remap_faces_3_6_9_12(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
00217 {
00218     MFace *df1 = get_dface(dm, split, cur, i, mf);
00219     MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00220     MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00221 
00222     facepa[cur] = vertpa[v1];
00223     df1->v1 = v1;
00224     df1->v2 = GET_ES(v1, v2)
00225     df1->v3 = GET_ES(v2, v3)
00226     df1->v4 = v3;
00227     df1->flag |= ME_FACE_SEL;
00228 
00229     facepa[cur+1] = vertpa[v2];
00230     df2->v1 = GET_ES(v1, v2)
00231     df2->v2 = v2;
00232     df2->v3 = GET_ES(v2, v3)
00233     df2->v4 = 0;
00234     df2->flag &= ~ME_FACE_SEL;
00235 
00236     facepa[cur+2] = vertpa[v1];
00237     df3->v1 = v1;
00238     df3->v2 = v3;
00239     df3->v3 = v4;
00240     df3->v4 = 0;
00241     df3->flag &= ~ME_FACE_SEL;
00242 }
00243 
00244 static void remap_uvs_3_6_9_12(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
00245 {
00246     MTFace *mf, *df1, *df2, *df3;
00247     int l;
00248 
00249     for(l=0; l<numlayer; l++) {
00250         mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00251         df1 = mf+cur;
00252         df2 = df1 + 1;
00253         df3 = df1 + 2;
00254         mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00255         mf += i;
00256 
00257         copy_v2_v2(df1->uv[0], mf->uv[c0]);
00258         INT_UV(df1->uv[1], c0, c1)
00259         INT_UV(df1->uv[2], c1, c2)
00260         copy_v2_v2(df1->uv[3], mf->uv[c2]);
00261 
00262         INT_UV(df2->uv[0], c0, c1)
00263         copy_v2_v2(df2->uv[1], mf->uv[c1]);
00264         INT_UV(df2->uv[2], c1, c2)
00265 
00266         copy_v2_v2(df3->uv[0], mf->uv[c0]);
00267         copy_v2_v2(df3->uv[1], mf->uv[c2]);
00268         copy_v2_v2(df3->uv[2], mf->uv[c3]);
00269     }
00270 }
00271 
00272 static void remap_faces_5_10(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
00273 {
00274     MFace *df1 = get_dface(dm, split, cur, i, mf);
00275     MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00276 
00277     facepa[cur] = vertpa[v1];
00278     df1->v1 = v1;
00279     df1->v2 = v2;
00280     df1->v3 = GET_ES(v2, v3)
00281     df1->v4 = GET_ES(v1, v4)
00282     df1->flag |= ME_FACE_SEL;
00283 
00284     facepa[cur+1] = vertpa[v3];
00285     df2->v1 = GET_ES(v1, v4)
00286     df2->v2 = GET_ES(v2, v3)
00287     df2->v3 = v3;
00288     df2->v4 = v4;
00289     df2->flag |= ME_FACE_SEL;
00290 }
00291 
00292 static void remap_uvs_5_10(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
00293 {
00294     MTFace *mf, *df1, *df2;
00295     int l;
00296 
00297     for(l=0; l<numlayer; l++) {
00298         mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00299         df1 = mf+cur;
00300         df2 = df1 + 1;
00301         mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00302         mf += i;
00303 
00304         copy_v2_v2(df1->uv[0], mf->uv[c0]);
00305         copy_v2_v2(df1->uv[1], mf->uv[c1]);
00306         INT_UV(df1->uv[2], c1, c2)
00307         INT_UV(df1->uv[3], c0, c3)
00308 
00309         INT_UV(df2->uv[0], c0, c3)
00310         INT_UV(df2->uv[1], c1, c2)
00311         copy_v2_v2(df2->uv[2], mf->uv[c2]);
00312         copy_v2_v2(df2->uv[3], mf->uv[c3]);
00313 
00314     }
00315 }
00316 
00317 static void remap_faces_15(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
00318 {
00319     MFace *df1 = get_dface(dm, split, cur, i, mf);
00320     MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00321     MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00322     MFace *df4 = get_dface(dm, split, cur+3, i, mf);
00323 
00324     facepa[cur] = vertpa[v1];
00325     df1->v1 = v1;
00326     df1->v2 = GET_ES(v1, v2)
00327     df1->v3 = GET_ES(v1, v3)
00328     df1->v4 = GET_ES(v1, v4)
00329     df1->flag |= ME_FACE_SEL;
00330 
00331     facepa[cur+1] = vertpa[v2];
00332     df2->v1 = GET_ES(v1, v2)
00333     df2->v2 = v2;
00334     df2->v3 = GET_ES(v2, v3)
00335     df2->v4 = GET_ES(v1, v3)
00336     df2->flag |= ME_FACE_SEL;
00337 
00338     facepa[cur+2] = vertpa[v3];
00339     df3->v1 = GET_ES(v1, v3)
00340     df3->v2 = GET_ES(v2, v3)
00341     df3->v3 = v3;
00342     df3->v4 = GET_ES(v3, v4)
00343     df3->flag |= ME_FACE_SEL;
00344 
00345     facepa[cur+3] = vertpa[v4];
00346     df4->v1 = GET_ES(v1, v4)
00347     df4->v2 = GET_ES(v1, v3)
00348     df4->v3 = GET_ES(v3, v4)
00349     df4->v4 = v4;
00350     df4->flag |= ME_FACE_SEL;
00351 }
00352 
00353 static void remap_uvs_15(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
00354 {
00355     MTFace *mf, *df1, *df2, *df3, *df4;
00356     int l;
00357 
00358     for(l=0; l<numlayer; l++) {
00359         mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00360         df1 = mf+cur;
00361         df2 = df1 + 1;
00362         df3 = df1 + 2;
00363         df4 = df1 + 3;
00364         mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00365         mf += i;
00366 
00367         copy_v2_v2(df1->uv[0], mf->uv[c0]);
00368         INT_UV(df1->uv[1], c0, c1)
00369         INT_UV(df1->uv[2], c0, c2)
00370         INT_UV(df1->uv[3], c0, c3)
00371 
00372         INT_UV(df2->uv[0], c0, c1)
00373         copy_v2_v2(df2->uv[1], mf->uv[c1]);
00374         INT_UV(df2->uv[2], c1, c2)
00375         INT_UV(df2->uv[3], c0, c2)
00376 
00377         INT_UV(df3->uv[0], c0, c2)
00378         INT_UV(df3->uv[1], c1, c2)
00379         copy_v2_v2(df3->uv[2], mf->uv[c2]);
00380         INT_UV(df3->uv[3], c2, c3)
00381 
00382         INT_UV(df4->uv[0], c0, c3)
00383         INT_UV(df4->uv[1], c0, c2)
00384         INT_UV(df4->uv[2], c2, c3)
00385         copy_v2_v2(df4->uv[3], mf->uv[c3]);
00386     }
00387 }
00388 
00389 static void remap_faces_7_11_13_14(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
00390 {
00391     MFace *df1 = get_dface(dm, split, cur, i, mf);
00392     MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00393     MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00394 
00395     facepa[cur] = vertpa[v1];
00396     df1->v1 = v1;
00397     df1->v2 = GET_ES(v1, v2)
00398     df1->v3 = GET_ES(v2, v3)
00399     df1->v4 = GET_ES(v1, v4)
00400     df1->flag |= ME_FACE_SEL;
00401 
00402     facepa[cur+1] = vertpa[v2];
00403     df2->v1 = GET_ES(v1, v2)
00404     df2->v2 = v2;
00405     df2->v3 = GET_ES(v2, v3)
00406     df2->v4 = 0;
00407     df2->flag &= ~ME_FACE_SEL;
00408 
00409     facepa[cur+2] = vertpa[v4];
00410     df3->v1 = GET_ES(v1, v4)
00411     df3->v2 = GET_ES(v2, v3)
00412     df3->v3 = v3;
00413     df3->v4 = v4;
00414     df3->flag |= ME_FACE_SEL;
00415 }
00416 
00417 static void remap_uvs_7_11_13_14(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
00418 {
00419     MTFace *mf, *df1, *df2, *df3;
00420     int l;
00421 
00422     for(l=0; l<numlayer; l++) {
00423         mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00424         df1 = mf+cur;
00425         df2 = df1 + 1;
00426         df3 = df1 + 2;
00427         mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00428         mf += i;
00429 
00430         copy_v2_v2(df1->uv[0], mf->uv[c0]);
00431         INT_UV(df1->uv[1], c0, c1)
00432         INT_UV(df1->uv[2], c1, c2)
00433         INT_UV(df1->uv[3], c0, c3)
00434 
00435         INT_UV(df2->uv[0], c0, c1)
00436         copy_v2_v2(df2->uv[1], mf->uv[c1]);
00437         INT_UV(df2->uv[2], c1, c2)
00438 
00439         INT_UV(df3->uv[0], c0, c3)
00440         INT_UV(df3->uv[1], c1, c2)
00441         copy_v2_v2(df3->uv[2], mf->uv[c2]);
00442         copy_v2_v2(df3->uv[3], mf->uv[c3]);
00443     }
00444 }
00445 
00446 static void remap_faces_19_21_22(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3)
00447 {
00448     MFace *df1 = get_dface(dm, split, cur, i, mf);
00449     MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00450 
00451     facepa[cur] = vertpa[v1];
00452     df1->v1 = v1;
00453     df1->v2 = GET_ES(v1, v2)
00454     df1->v3 = GET_ES(v1, v3)
00455     df1->v4 = 0;
00456     df1->flag &= ~ME_FACE_SEL;
00457 
00458     facepa[cur+1] = vertpa[v2];
00459     df2->v1 = GET_ES(v1, v2)
00460     df2->v2 = v2;
00461     df2->v3 = v3;
00462     df2->v4 = GET_ES(v1, v3)
00463     df2->flag |= ME_FACE_SEL;
00464 }
00465 
00466 static void remap_uvs_19_21_22(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
00467 {
00468     MTFace *mf, *df1, *df2;
00469     int l;
00470 
00471     for(l=0; l<numlayer; l++) {
00472         mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00473         df1 = mf+cur;
00474         df2 = df1 + 1;
00475         mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00476         mf += i;
00477 
00478         copy_v2_v2(df1->uv[0], mf->uv[c0]);
00479         INT_UV(df1->uv[1], c0, c1)
00480         INT_UV(df1->uv[2], c0, c2)
00481 
00482         INT_UV(df2->uv[0], c0, c1)
00483         copy_v2_v2(df2->uv[1], mf->uv[c1]);
00484         copy_v2_v2(df2->uv[2], mf->uv[c2]);
00485         INT_UV(df2->uv[3], c0, c2)
00486     }
00487 }
00488 
00489 static void remap_faces_23(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3)
00490 {
00491     MFace *df1 = get_dface(dm, split, cur, i, mf);
00492     MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00493     MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00494 
00495     facepa[cur] = vertpa[v1];
00496     df1->v1 = v1;
00497     df1->v2 = GET_ES(v1, v2)
00498     df1->v3 = GET_ES(v2, v3)
00499     df1->v4 = GET_ES(v1, v3)
00500     df1->flag |= ME_FACE_SEL;
00501 
00502     facepa[cur+1] = vertpa[v2];
00503     df2->v1 = GET_ES(v1, v2)
00504     df2->v2 = v2;
00505     df2->v3 = GET_ES(v2, v3)
00506     df2->v4 = 0;
00507     df2->flag &= ~ME_FACE_SEL;
00508 
00509     facepa[cur+2] = vertpa[v3];
00510     df3->v1 = GET_ES(v1, v3)
00511     df3->v2 = GET_ES(v2, v3)
00512     df3->v3 = v3;
00513     df3->v4 = 0;
00514     df3->flag &= ~ME_FACE_SEL;
00515 }
00516 
00517 static void remap_uvs_23(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
00518 {
00519     MTFace *mf, *df1, *df2;
00520     int l;
00521 
00522     for(l=0; l<numlayer; l++) {
00523         mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00524         df1 = mf+cur;
00525         df2 = df1 + 1;
00526         mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00527         mf += i;
00528 
00529         copy_v2_v2(df1->uv[0], mf->uv[c0]);
00530         INT_UV(df1->uv[1], c0, c1)
00531         INT_UV(df1->uv[2], c1, c2)
00532         INT_UV(df1->uv[3], c0, c2)
00533 
00534         INT_UV(df2->uv[0], c0, c1)
00535         copy_v2_v2(df2->uv[1], mf->uv[c1]);
00536         INT_UV(df2->uv[2], c1, c2)
00537 
00538         INT_UV(df2->uv[0], c0, c2)
00539         INT_UV(df2->uv[1], c1, c2)
00540         copy_v2_v2(df2->uv[2], mf->uv[c2]);
00541     }
00542 }
00543 
00544 static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm)
00545 {
00546     DerivedMesh *splitdm;
00547     MFace *mf=NULL,*df1=NULL;
00548     MFace *mface=dm->getFaceArray(dm);
00549     MVert *dupve, *mv;
00550     EdgeHash *edgehash;
00551     EdgeHashIterator *ehi;
00552     int totvert=dm->getNumVerts(dm);
00553     int totface=dm->getNumFaces(dm);
00554 
00555     int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_facesplit");
00556     int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
00557     int *facepa = emd->facepa;
00558     int *fs, totesplit=0,totfsplit=0,curdupface=0;
00559     int i, v1, v2, v3, v4, esplit,
00560         v[4]  = {0, 0, 0, 0}, /* To quite gcc barking... */
00561         uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */
00562     int numlayer;
00563     unsigned int ed_v1, ed_v2;
00564 
00565     edgehash= BLI_edgehash_new();
00566 
00567     /* recreate vertpa from facepa calculation */
00568     for (i=0,mf=mface; i<totface; i++,mf++) {
00569         vertpa[mf->v1]=facepa[i];
00570         vertpa[mf->v2]=facepa[i];
00571         vertpa[mf->v3]=facepa[i];
00572         if(mf->v4)
00573             vertpa[mf->v4]=facepa[i];
00574     }
00575 
00576     /* mark edges for splitting and how to split faces */
00577     for (i=0,mf=mface,fs=facesplit; i<totface; i++,mf++,fs++) {
00578         v1=vertpa[mf->v1];
00579         v2=vertpa[mf->v2];
00580         v3=vertpa[mf->v3];
00581 
00582         if(v1!=v2){
00583             BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
00584             (*fs) |= 1;
00585         }
00586 
00587         if(v2!=v3){
00588             BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
00589             (*fs) |= 2;
00590         }
00591 
00592         if(mf->v4){
00593             v4=vertpa[mf->v4];
00594 
00595             if(v3!=v4){
00596                 BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
00597                 (*fs) |= 4;
00598             }
00599 
00600             if(v1!=v4){
00601                 BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
00602                 (*fs) |= 8;
00603             }
00604 
00605             /* mark center vertex as a fake edge split */
00606             if(*fs == 15)
00607                 BLI_edgehash_insert(edgehash, mf->v1, mf->v3, NULL);
00608         }
00609         else {
00610             (*fs) |= 16; /* mark face as tri */
00611 
00612             if(v1!=v3){
00613                 BLI_edgehash_insert(edgehash, mf->v1, mf->v3, NULL);
00614                 (*fs) |= 4;
00615             }
00616         }
00617     }
00618 
00619     /* count splits & create indexes for new verts */
00620     ehi= BLI_edgehashIterator_new(edgehash);
00621     totesplit=totvert;
00622     for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
00623         BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit));
00624         totesplit++;
00625     }
00626     BLI_edgehashIterator_free(ehi);
00627 
00628     /* count new faces due to splitting */
00629     for(i=0,fs=facesplit; i<totface; i++,fs++)
00630         totfsplit += add_faces[*fs];
00631     
00632     splitdm= CDDM_from_template(dm, totesplit, 0, totface+totfsplit);
00633     numlayer = CustomData_number_of_layers(&splitdm->faceData, CD_MTFACE);
00634 
00635     /* copy new faces & verts (is it really this painful with custom data??) */
00636     for(i=0; i<totvert; i++){
00637         MVert source;
00638         MVert *dest;
00639         dm->getVert(dm, i, &source);
00640         dest = CDDM_get_vert(splitdm, i);
00641 
00642         DM_copy_vert_data(dm, splitdm, i, i, 1);
00643         *dest = source;
00644     }
00645 
00646     /* override original facepa (original pointer is saved in caller function) */
00647     facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"explode_facepa");
00648     //memcpy(facepa,emd->facepa,totface*sizeof(int));
00649     emd->facepa=facepa;
00650 
00651     /* create new verts */
00652     ehi= BLI_edgehashIterator_new(edgehash);
00653     for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
00654         BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
00655         esplit= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
00656         mv=CDDM_get_vert(splitdm, ed_v2);
00657         dupve=CDDM_get_vert(splitdm,esplit);
00658 
00659         DM_copy_vert_data(splitdm,splitdm, ed_v2, esplit,1);
00660 
00661         *dupve=*mv;
00662 
00663         mv=CDDM_get_vert(splitdm, ed_v1);
00664 
00665         add_v3_v3(dupve->co, mv->co);
00666         mul_v3_fl(dupve->co, 0.5f);
00667     }
00668     BLI_edgehashIterator_free(ehi);
00669 
00670     /* create new faces */
00671     curdupface=0;//=totface;
00672     //curdupin=totesplit;
00673     for(i=0,fs=facesplit; i<totface; i++,fs++){
00674         mf = dm->getFaceData(dm, i, CD_MFACE);
00675 
00676         switch(*fs) {
00677         case 3:
00678         case 10:
00679         case 11:
00680         case 15:
00681             SET_VERTS(1, 2, 3, 4)
00682             break;
00683         case 5:
00684         case 6:
00685         case 7:
00686             SET_VERTS(2, 3, 4, 1)
00687             break;
00688         case 9:
00689         case 13:
00690             SET_VERTS(4, 1, 2, 3)
00691             break;
00692         case 12:
00693         case 14:
00694             SET_VERTS(3, 4, 1, 2)
00695             break;
00696         case 21:
00697         case 23:
00698             SET_VERTS(1, 2, 3, 4)
00699             break;
00700         case 19:
00701             SET_VERTS(2, 3, 1, 4)
00702             break;
00703         case 22:
00704             SET_VERTS(3, 1, 2, 4)
00705             break;
00706         }
00707 
00708         switch(*fs) {
00709         case 3:
00710         case 6:
00711         case 9:
00712         case 12:
00713             remap_faces_3_6_9_12(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00714             if(numlayer)
00715                 remap_uvs_3_6_9_12(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00716             break;
00717         case 5:
00718         case 10:
00719             remap_faces_5_10(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00720             if(numlayer)
00721                 remap_uvs_5_10(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00722             break;
00723         case 15:
00724             remap_faces_15(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00725             if(numlayer)
00726                 remap_uvs_15(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00727             break;
00728         case 7:
00729         case 11:
00730         case 13:
00731         case 14:
00732             remap_faces_7_11_13_14(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00733             if(numlayer)
00734                 remap_uvs_7_11_13_14(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00735             break;
00736         case 19:
00737         case 21:
00738         case 22:
00739             remap_faces_19_21_22(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
00740             if(numlayer)
00741                 remap_uvs_19_21_22(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
00742             break;
00743         case 23:
00744             remap_faces_23(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
00745             if(numlayer)
00746                 remap_uvs_23(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
00747             break;
00748         case 0:
00749         case 16:
00750             df1 = get_dface(dm, splitdm, curdupface, i, mf);
00751             facepa[curdupface] = vertpa[mf->v1];
00752 
00753             if(df1->v4)
00754                 df1->flag |= ME_FACE_SEL;
00755             else
00756                 df1->flag &= ~ME_FACE_SEL;
00757             break;
00758         }
00759 
00760         curdupface += add_faces[*fs]+1;
00761     }
00762 
00763     for(i=0; i<curdupface; i++) {
00764         mf = CDDM_get_face(splitdm, i);
00765         test_index_face(mf, &splitdm->faceData, i, (mf->flag & ME_FACE_SEL ? 4 : 3));
00766     }
00767 
00768     BLI_edgehash_free(edgehash, NULL);
00769     MEM_freeN(facesplit);
00770     MEM_freeN(vertpa);
00771 
00772     return splitdm;
00773 
00774 }
00775 static DerivedMesh * explodeMesh(ExplodeModifierData *emd, 
00776         ParticleSystemModifierData *psmd, Scene *scene, Object *ob, 
00777   DerivedMesh *to_explode)
00778 {
00779     DerivedMesh *explode, *dm=to_explode;
00780     MFace *mf= NULL, *mface;
00781     /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */
00782     ParticleSimulationData sim= {NULL};
00783     ParticleData *pa=NULL, *pars=psmd->psys->particles;
00784     ParticleKey state, birth;
00785     EdgeHash *vertpahash;
00786     EdgeHashIterator *ehi;
00787     float *vertco= NULL, imat[4][4];
00788     float rot[4];
00789     float cfra;
00790     /* float timestep; */
00791     int *facepa=emd->facepa;
00792     int totdup=0,totvert=0,totface=0,totpart=0;
00793     int i, v;
00794     unsigned int ed_v1, ed_v2, mindex=0;
00795     MTFace *mtface = NULL, *mtf;
00796 
00797     totface= dm->getNumFaces(dm);
00798     totvert= dm->getNumVerts(dm);
00799     mface= dm->getFaceArray(dm);
00800     totpart= psmd->psys->totpart;
00801 
00802     sim.scene= scene;
00803     sim.ob= ob;
00804     sim.psys= psmd->psys;
00805     sim.psmd= psmd;
00806 
00807     /* timestep= psys_get_timestep(&sim); */
00808 
00809     cfra= BKE_curframe(scene);
00810 
00811     /* hash table for vertice <-> particle relations */
00812     vertpahash= BLI_edgehash_new();
00813 
00814     for (i=0; i<totface; i++) {
00815         /* do mindex + totvert to ensure the vertex index to be the first
00816          * with BLI_edgehashIterator_getKey */
00817         if(facepa[i]==totpart || cfra < (pars+facepa[i])->time)
00818             mindex = totvert+totpart;
00819         else 
00820             mindex = totvert+facepa[i];
00821 
00822         mf= &mface[i];
00823 
00824         /* set face vertices to exist in particle group */
00825         BLI_edgehash_insert(vertpahash, mf->v1, mindex, NULL);
00826         BLI_edgehash_insert(vertpahash, mf->v2, mindex, NULL);
00827         BLI_edgehash_insert(vertpahash, mf->v3, mindex, NULL);
00828         if(mf->v4)
00829             BLI_edgehash_insert(vertpahash, mf->v4, mindex, NULL);
00830     }
00831 
00832     /* make new vertice indexes & count total vertices after duplication */
00833     ehi= BLI_edgehashIterator_new(vertpahash);
00834     for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
00835         BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup));
00836         totdup++;
00837     }
00838     BLI_edgehashIterator_free(ehi);
00839 
00840     /* the final duplicated vertices */
00841     explode= CDDM_from_template(dm, totdup, 0,totface);
00842     mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname);
00843     /*dupvert= CDDM_get_verts(explode);*/
00844 
00845     /* getting back to object space */
00846     invert_m4_m4(imat,ob->obmat);
00847 
00848     psmd->psys->lattice = psys_get_lattice(&sim);
00849 
00850     /* duplicate & displace vertices */
00851     ehi= BLI_edgehashIterator_new(vertpahash);
00852     for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
00853         MVert source;
00854         MVert *dest;
00855 
00856         /* get particle + vertex from hash */
00857         BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
00858         ed_v2 -= totvert;
00859         v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
00860 
00861         dm->getVert(dm, ed_v1, &source);
00862         dest = CDDM_get_vert(explode,v);
00863 
00864         DM_copy_vert_data(dm, explode, ed_v1, v, 1);
00865         *dest = source;
00866 
00867         if(ed_v2 != totpart) {
00868             /* get particle */
00869             pa= pars + ed_v2;
00870 
00871             psys_get_birth_coordinates(&sim, pa, &birth, 0, 0);
00872 
00873             state.time=cfra;
00874             psys_get_particle_state(&sim, ed_v2, &state, 1);
00875 
00876             vertco=CDDM_get_vert(explode,v)->co;
00877             mul_m4_v3(ob->obmat,vertco);
00878 
00879             sub_v3_v3(vertco, birth.co);
00880 
00881             /* apply rotation, size & location */
00882             sub_qt_qtqt(rot, state.rot, birth.rot);
00883             mul_qt_v3(rot, vertco);
00884 
00885             if(emd->flag & eExplodeFlag_PaSize)
00886                 mul_v3_fl(vertco,pa->size);
00887 
00888             add_v3_v3(vertco, state.co);
00889 
00890             mul_m4_v3(imat, vertco);
00891         }
00892     }
00893     BLI_edgehashIterator_free(ehi);
00894 
00895     /*map new vertices to faces*/
00896     for (i=0; i<totface; i++) {
00897         MFace source;
00898         int orig_v4;
00899 
00900         if(facepa[i]!=totpart)
00901         {
00902             pa=pars+facepa[i];
00903 
00904             if(pa->alive==PARS_UNBORN && (emd->flag&eExplodeFlag_Unborn)==0) continue;
00905             if(pa->alive==PARS_ALIVE && (emd->flag&eExplodeFlag_Alive)==0) continue;
00906             if(pa->alive==PARS_DEAD && (emd->flag&eExplodeFlag_Dead)==0) continue;
00907         }
00908 
00909         dm->getFace(dm,i,&source);
00910         mf=CDDM_get_face(explode,i);
00911         
00912         orig_v4 = source.v4;
00913 
00914         if(facepa[i]!=totpart && cfra < pa->time)
00915             mindex = totvert+totpart;
00916         else 
00917             mindex = totvert+facepa[i];
00918 
00919         source.v1 = edgecut_get(vertpahash, source.v1, mindex);
00920         source.v2 = edgecut_get(vertpahash, source.v2, mindex);
00921         source.v3 = edgecut_get(vertpahash, source.v3, mindex);
00922         if(source.v4)
00923             source.v4 = edgecut_get(vertpahash, source.v4, mindex);
00924 
00925         DM_copy_face_data(dm,explode,i,i,1);
00926 
00927         *mf = source;
00928 
00929         /* override uv channel for particle age */
00930         if(mtface) {
00931             float age = (cfra - pa->time)/pa->lifetime;
00932             /* Clamp to this range to avoid flipping to the other side of the coordinates. */
00933             CLAMP(age, 0.001f, 0.999f);
00934 
00935             mtf = mtface + i;
00936 
00937             mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age;
00938             mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f;
00939         }
00940 
00941         test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
00942     }
00943 
00944     /* cleanup */
00945     BLI_edgehash_free(vertpahash, NULL);
00946 
00947     /* finalization */
00948     CDDM_calc_edges(explode);
00949     CDDM_calc_normals(explode);
00950 
00951     if(psmd->psys->lattice){
00952         end_latt_deform(psmd->psys->lattice);
00953         psmd->psys->lattice= NULL;
00954     }
00955 
00956     return explode;
00957 }
00958 
00959 static ParticleSystemModifierData * findPrecedingParticlesystem(Object *ob, ModifierData *emd)
00960 {
00961     ModifierData *md;
00962     ParticleSystemModifierData *psmd= NULL;
00963 
00964     for (md=ob->modifiers.first; emd!=md; md=md->next){
00965         if(md->type==eModifierType_ParticleSystem)
00966             psmd= (ParticleSystemModifierData*) md;
00967     }
00968     return psmd;
00969 }
00970 static DerivedMesh * applyModifier(ModifierData *md, Object *ob,
00971                         DerivedMesh *derivedData,
00972                         int UNUSED(useRenderParams),
00973                         int UNUSED(isFinalCalc))
00974 {
00975     DerivedMesh *dm = derivedData;
00976     ExplodeModifierData *emd= (ExplodeModifierData*) md;
00977     ParticleSystemModifierData *psmd=findPrecedingParticlesystem(ob,md);
00978 
00979     if(psmd){
00980         ParticleSystem * psys=psmd->psys;
00981 
00982         if(psys==NULL || psys->totpart==0) return derivedData;
00983         if(psys->part==NULL || psys->particles==NULL) return derivedData;
00984         if(psmd->dm==NULL) return derivedData;
00985 
00986         /* 1. find faces to be exploded if needed */
00987         if(emd->facepa == NULL
00988                  || psmd->flag&eParticleSystemFlag_Pars
00989                  || emd->flag&eExplodeFlag_CalcFaces
00990                  || MEM_allocN_len(emd->facepa)/sizeof(int) != dm->getNumFaces(dm))
00991         {
00992             if(psmd->flag & eParticleSystemFlag_Pars)
00993                 psmd->flag &= ~eParticleSystemFlag_Pars;
00994             
00995             if(emd->flag & eExplodeFlag_CalcFaces)
00996                 emd->flag &= ~eExplodeFlag_CalcFaces;
00997 
00998             createFacepa(emd,psmd,derivedData);
00999         }
01000         /* 2. create new mesh */
01001         if(emd->flag & eExplodeFlag_EdgeCut){
01002             int *facepa = emd->facepa;
01003             DerivedMesh *splitdm=cutEdges(emd,dm);
01004             DerivedMesh *explode=explodeMesh(emd, psmd, md->scene, ob, splitdm);
01005 
01006             MEM_freeN(emd->facepa);
01007             emd->facepa=facepa;
01008             splitdm->release(splitdm);
01009             return explode;
01010         }
01011         else
01012             return explodeMesh(emd, psmd, md->scene, ob, derivedData);
01013     }
01014     return derivedData;
01015 }
01016 
01017 
01018 ModifierTypeInfo modifierType_Explode = {
01019     /* name */              "Explode",
01020     /* structName */        "ExplodeModifierData",
01021     /* structSize */        sizeof(ExplodeModifierData),
01022     /* type */              eModifierTypeType_Constructive,
01023     /* flags */             eModifierTypeFlag_AcceptsMesh,
01024     /* copyData */          copyData,
01025     /* deformVerts */       NULL,
01026     /* deformMatrices */    NULL,
01027     /* deformVertsEM */     NULL,
01028     /* deformMatricesEM */  NULL,
01029     /* applyModifier */     applyModifier,
01030     /* applyModifierEM */   NULL,
01031     /* initData */          initData,
01032     /* requiredDataMask */  requiredDataMask,
01033     /* freeData */          freeData,
01034     /* isDisabled */        NULL,
01035     /* updateDepgraph */    NULL,
01036     /* dependsOnTime */     dependsOnTime,
01037     /* dependsOnNormals */  NULL,
01038     /* foreachObjectLink */ NULL,
01039     /* foreachIDLink */     NULL,
01040     /* foreachTexLink */    NULL,
01041 };