Blender  V2.59
MOD_explode.c
Go to the documentation of this file.
00001 /*
00002 * $Id: MOD_explode.c 37629 2011-06-19 06:57:56Z campbellbarton $
00003 *
00004 * ***** BEGIN GPL LICENSE BLOCK *****
00005 *
00006 * This program is free software; you can redistribute it and/or
00007 * modify it under the terms of the GNU General Public License
00008 * as published by the Free Software Foundation; either version 2
00009 * of the License, or (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU General Public License
00017 * along with this program; if not, write to the Free Software  Foundation,
00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 *
00020 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
00021 * All rights reserved.
00022 *
00023 * Contributor(s): Daniel Dunbar
00024 *                 Ton Roosendaal,
00025 *                 Ben Batt,
00026 *                 Brecht Van Lommel,
00027 *                 Campbell Barton
00028 *
00029 * ***** END GPL LICENSE BLOCK *****
00030 *
00031 */
00032 
00038 #include "DNA_meshdata_types.h"
00039 #include "DNA_scene_types.h"
00040 
00041 #include "BLI_kdtree.h"
00042 #include "BLI_rand.h"
00043 #include "BLI_math.h"
00044 #include "BLI_edgehash.h"
00045 #include "BLI_utildefines.h"
00046 
00047 #include "BKE_cdderivedmesh.h"
00048 #include "BKE_deform.h"
00049 #include "BKE_lattice.h"
00050 #include "BKE_mesh.h"
00051 #include "BKE_modifier.h"
00052 #include "BKE_object.h"
00053 #include "BKE_particle.h"
00054 #include "BKE_scene.h"
00055 
00056 
00057 #include "MEM_guardedalloc.h"
00058 
00059 #include "MOD_util.h"
00060 
00061 static void initData(ModifierData *md)
00062 {
00063         ExplodeModifierData *emd= (ExplodeModifierData*) md;
00064 
00065         emd->facepa= NULL;
00066         emd->flag |= eExplodeFlag_Unborn+eExplodeFlag_Alive+eExplodeFlag_Dead;
00067 }
00068 static void freeData(ModifierData *md)
00069 {
00070         ExplodeModifierData *emd= (ExplodeModifierData*) md;
00071         
00072         if(emd->facepa) MEM_freeN(emd->facepa);
00073 }
00074 static void copyData(ModifierData *md, ModifierData *target)
00075 {
00076         ExplodeModifierData *emd= (ExplodeModifierData*) md;
00077         ExplodeModifierData *temd= (ExplodeModifierData*) target;
00078 
00079         temd->facepa = NULL;
00080         temd->flag = emd->flag;
00081         temd->protect = emd->protect;
00082         temd->vgroup = emd->vgroup;
00083 }
00084 static int dependsOnTime(ModifierData *UNUSED(md)) 
00085 {
00086         return 1;
00087 }
00088 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
00089 {
00090         ExplodeModifierData *emd= (ExplodeModifierData*) md;
00091         CustomDataMask dataMask = 0;
00092 
00093         if(emd->vgroup)
00094                 dataMask |= CD_MASK_MDEFORMVERT;
00095 
00096         return dataMask;
00097 }
00098 
00099 static void createFacepa(ExplodeModifierData *emd,
00100                                                 ParticleSystemModifierData *psmd,
00101                                                 DerivedMesh *dm)
00102 {
00103         ParticleSystem *psys=psmd->psys;
00104         MFace *fa=NULL, *mface=NULL;
00105         MVert *mvert = NULL;
00106         ParticleData *pa;
00107         KDTree *tree;
00108         float center[3], co[3];
00109         int *facepa=NULL,*vertpa=NULL,totvert=0,totface=0,totpart=0;
00110         int i,p,v1,v2,v3,v4=0;
00111 
00112         mvert = dm->getVertArray(dm);
00113         mface = dm->getFaceArray(dm);
00114         totface= dm->getNumFaces(dm);
00115         totvert= dm->getNumVerts(dm);
00116         totpart= psmd->psys->totpart;
00117 
00118         BLI_srandom(psys->seed);
00119 
00120         if(emd->facepa)
00121                 MEM_freeN(emd->facepa);
00122 
00123         facepa = emd->facepa = MEM_callocN(sizeof(int)*totface, "explode_facepa");
00124 
00125         vertpa = MEM_callocN(sizeof(int)*totvert, "explode_vertpa");
00126 
00127         /* initialize all faces & verts to no particle */
00128         for(i=0; i<totface; i++)
00129                 facepa[i]=totpart;
00130 
00131         for (i=0; i<totvert; i++)
00132                 vertpa[i]=totpart;
00133 
00134         /* set protected verts */
00135         if(emd->vgroup){
00136                 MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
00137                 if(dvert){
00138                         const int defgrp_index= emd->vgroup-1;
00139                         for(i=0; i<totvert; i++, dvert++){
00140                                 float val = BLI_frand();
00141                                 val = (1.0f-emd->protect)*val + emd->protect*0.5f;
00142                                 if(val < defvert_find_weight(dvert, defgrp_index))
00143                                         vertpa[i] = -1;
00144                         }
00145                 }
00146         }
00147 
00148         /* make tree of emitter locations */
00149         tree=BLI_kdtree_new(totpart);
00150         for(p=0,pa=psys->particles; p<totpart; p++,pa++){
00151                 psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,NULL,NULL,NULL,NULL,NULL);
00152                 BLI_kdtree_insert(tree, p, co, NULL);
00153         }
00154         BLI_kdtree_balance(tree);
00155 
00156         /* set face-particle-indexes to nearest particle to face center */
00157         for(i=0,fa=mface; i<totface; i++,fa++){
00158                 add_v3_v3v3(center,mvert[fa->v1].co,mvert[fa->v2].co);
00159                 add_v3_v3(center, mvert[fa->v3].co);
00160                 if(fa->v4){
00161                         add_v3_v3(center, mvert[fa->v4].co);
00162                         mul_v3_fl(center,0.25);
00163                 }
00164                 else
00165                         mul_v3_fl(center,0.3333f);
00166 
00167                 p= BLI_kdtree_find_nearest(tree,center,NULL,NULL);
00168 
00169                 v1=vertpa[fa->v1];
00170                 v2=vertpa[fa->v2];
00171                 v3=vertpa[fa->v3];
00172                 if(fa->v4)
00173                         v4=vertpa[fa->v4];
00174 
00175                 if(v1>=0 && v2>=0 && v3>=0 && (fa->v4==0 || v4>=0))
00176                         facepa[i]=p;
00177 
00178                 if(v1>=0) vertpa[fa->v1]=p;
00179                 if(v2>=0) vertpa[fa->v2]=p;
00180                 if(v3>=0) vertpa[fa->v3]=p;
00181                 if(fa->v4 && v4>=0) vertpa[fa->v4]=p;
00182         }
00183 
00184         if(vertpa) MEM_freeN(vertpa);
00185         BLI_kdtree_free(tree);
00186 }
00187 
00188 static int edgecut_get(EdgeHash *edgehash, int v1, int v2)
00189 {
00190         return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
00191 }
00192 
00193  
00194 static const short add_faces[24] = {
00195         0,
00196         0, 0, 2, 0, 1, 2, 2, 0, 2, 1,
00197         2, 2, 2, 2, 3, 0, 0, 0, 1, 0,
00198         1, 1, 2
00199  };
00200 
00201 static MFace *get_dface(DerivedMesh *dm, DerivedMesh *split, int cur, int i, MFace *mf)
00202 {
00203         MFace *df = CDDM_get_face(split, cur);
00204         DM_copy_face_data(dm, split, i, cur, 1);
00205         *df = *mf;
00206         return df;
00207 }
00208 
00209 #define SET_VERTS(a, b, c, d) \
00210                         v[0]=mf->v##a; uv[0]=a-1; \
00211                         v[1]=mf->v##b; uv[1]=b-1; \
00212                         v[2]=mf->v##c; uv[2]=c-1; \
00213                         v[3]=mf->v##d; uv[3]=d-1;
00214 
00215 #define GET_ES(v1, v2) edgecut_get(eh, v1, v2);
00216 #define INT_UV(uvf, c0, c1) interp_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1], 0.5f);
00217 
00218 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)
00219 {
00220         MFace *df1 = get_dface(dm, split, cur, i, mf);
00221         MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00222         MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00223 
00224         facepa[cur] = vertpa[v1];
00225         df1->v1 = v1;
00226         df1->v2 = GET_ES(v1, v2)
00227         df1->v3 = GET_ES(v2, v3)
00228         df1->v4 = v3;
00229         df1->flag |= ME_FACE_SEL;
00230 
00231         facepa[cur+1] = vertpa[v2];
00232         df2->v1 = GET_ES(v1, v2)
00233         df2->v2 = v2;
00234         df2->v3 = GET_ES(v2, v3)
00235         df2->v4 = 0;
00236         df2->flag &= ~ME_FACE_SEL;
00237 
00238         facepa[cur+2] = vertpa[v1];
00239         df3->v1 = v1;
00240         df3->v2 = v3;
00241         df3->v3 = v4;
00242         df3->v4 = 0;
00243         df3->flag &= ~ME_FACE_SEL;
00244 }
00245 
00246 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)
00247 {
00248         MTFace *mf, *df1, *df2, *df3;
00249         int l;
00250 
00251         for(l=0; l<numlayer; l++) {
00252                 mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00253                 df1 = mf+cur;
00254                 df2 = df1 + 1;
00255                 df3 = df1 + 2;
00256                 mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00257                 mf += i;
00258 
00259                 copy_v2_v2(df1->uv[0], mf->uv[c0]);
00260                 INT_UV(df1->uv[1], c0, c1)
00261                 INT_UV(df1->uv[2], c1, c2)
00262                 copy_v2_v2(df1->uv[3], mf->uv[c2]);
00263 
00264                 INT_UV(df2->uv[0], c0, c1)
00265                 copy_v2_v2(df2->uv[1], mf->uv[c1]);
00266                 INT_UV(df2->uv[2], c1, c2)
00267 
00268                 copy_v2_v2(df3->uv[0], mf->uv[c0]);
00269                 copy_v2_v2(df3->uv[1], mf->uv[c2]);
00270                 copy_v2_v2(df3->uv[2], mf->uv[c3]);
00271         }
00272 }
00273 
00274 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)
00275 {
00276         MFace *df1 = get_dface(dm, split, cur, i, mf);
00277         MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00278 
00279         facepa[cur] = vertpa[v1];
00280         df1->v1 = v1;
00281         df1->v2 = v2;
00282         df1->v3 = GET_ES(v2, v3)
00283         df1->v4 = GET_ES(v1, v4)
00284         df1->flag |= ME_FACE_SEL;
00285 
00286         facepa[cur+1] = vertpa[v3];
00287         df2->v1 = GET_ES(v1, v4)
00288         df2->v2 = GET_ES(v2, v3)
00289         df2->v3 = v3;
00290         df2->v4 = v4;
00291         df2->flag |= ME_FACE_SEL;
00292 }
00293 
00294 static void remap_uvs_5_10(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
00295 {
00296         MTFace *mf, *df1, *df2;
00297         int l;
00298 
00299         for(l=0; l<numlayer; l++) {
00300                 mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00301                 df1 = mf+cur;
00302                 df2 = df1 + 1;
00303                 mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00304                 mf += i;
00305 
00306                 copy_v2_v2(df1->uv[0], mf->uv[c0]);
00307                 copy_v2_v2(df1->uv[1], mf->uv[c1]);
00308                 INT_UV(df1->uv[2], c1, c2)
00309                 INT_UV(df1->uv[3], c0, c3)
00310 
00311                 INT_UV(df2->uv[0], c0, c3)
00312                 INT_UV(df2->uv[1], c1, c2)
00313                 copy_v2_v2(df2->uv[2], mf->uv[c2]);
00314                 copy_v2_v2(df2->uv[3], mf->uv[c3]);
00315 
00316         }
00317 }
00318 
00319 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)
00320 {
00321         MFace *df1 = get_dface(dm, split, cur, i, mf);
00322         MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00323         MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00324         MFace *df4 = get_dface(dm, split, cur+3, i, mf);
00325 
00326         facepa[cur] = vertpa[v1];
00327         df1->v1 = v1;
00328         df1->v2 = GET_ES(v1, v2)
00329         df1->v3 = GET_ES(v1, v3)
00330         df1->v4 = GET_ES(v1, v4)
00331         df1->flag |= ME_FACE_SEL;
00332 
00333         facepa[cur+1] = vertpa[v2];
00334         df2->v1 = GET_ES(v1, v2)
00335         df2->v2 = v2;
00336         df2->v3 = GET_ES(v2, v3)
00337         df2->v4 = GET_ES(v1, v3)
00338         df2->flag |= ME_FACE_SEL;
00339 
00340         facepa[cur+2] = vertpa[v3];
00341         df3->v1 = GET_ES(v1, v3)
00342         df3->v2 = GET_ES(v2, v3)
00343         df3->v3 = v3;
00344         df3->v4 = GET_ES(v3, v4)
00345         df3->flag |= ME_FACE_SEL;
00346 
00347         facepa[cur+3] = vertpa[v4];
00348         df4->v1 = GET_ES(v1, v4)
00349         df4->v2 = GET_ES(v1, v3)
00350         df4->v3 = GET_ES(v3, v4)
00351         df4->v4 = v4;
00352         df4->flag |= ME_FACE_SEL;
00353 }
00354 
00355 static void remap_uvs_15(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
00356 {
00357         MTFace *mf, *df1, *df2, *df3, *df4;
00358         int l;
00359 
00360         for(l=0; l<numlayer; l++) {
00361                 mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00362                 df1 = mf+cur;
00363                 df2 = df1 + 1;
00364                 df3 = df1 + 2;
00365                 df4 = df1 + 3;
00366                 mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00367                 mf += i;
00368 
00369                 copy_v2_v2(df1->uv[0], mf->uv[c0]);
00370                 INT_UV(df1->uv[1], c0, c1)
00371                 INT_UV(df1->uv[2], c0, c2)
00372                 INT_UV(df1->uv[3], c0, c3)
00373 
00374                 INT_UV(df2->uv[0], c0, c1)
00375                 copy_v2_v2(df2->uv[1], mf->uv[c1]);
00376                 INT_UV(df2->uv[2], c1, c2)
00377                 INT_UV(df2->uv[3], c0, c2)
00378 
00379                 INT_UV(df3->uv[0], c0, c2)
00380                 INT_UV(df3->uv[1], c1, c2)
00381                 copy_v2_v2(df3->uv[2], mf->uv[c2]);
00382                 INT_UV(df3->uv[3], c2, c3)
00383 
00384                 INT_UV(df4->uv[0], c0, c3)
00385                 INT_UV(df4->uv[1], c0, c2)
00386                 INT_UV(df4->uv[2], c2, c3)
00387                 copy_v2_v2(df4->uv[3], mf->uv[c3]);
00388         }
00389 }
00390 
00391 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)
00392 {
00393         MFace *df1 = get_dface(dm, split, cur, i, mf);
00394         MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00395         MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00396 
00397         facepa[cur] = vertpa[v1];
00398         df1->v1 = v1;
00399         df1->v2 = GET_ES(v1, v2)
00400         df1->v3 = GET_ES(v2, v3)
00401         df1->v4 = GET_ES(v1, v4)
00402         df1->flag |= ME_FACE_SEL;
00403 
00404         facepa[cur+1] = vertpa[v2];
00405         df2->v1 = GET_ES(v1, v2)
00406         df2->v2 = v2;
00407         df2->v3 = GET_ES(v2, v3)
00408         df2->v4 = 0;
00409         df2->flag &= ~ME_FACE_SEL;
00410 
00411         facepa[cur+2] = vertpa[v4];
00412         df3->v1 = GET_ES(v1, v4)
00413         df3->v2 = GET_ES(v2, v3)
00414         df3->v3 = v3;
00415         df3->v4 = v4;
00416         df3->flag |= ME_FACE_SEL;
00417 }
00418 
00419 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)
00420 {
00421         MTFace *mf, *df1, *df2, *df3;
00422         int l;
00423 
00424         for(l=0; l<numlayer; l++) {
00425                 mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00426                 df1 = mf+cur;
00427                 df2 = df1 + 1;
00428                 df3 = df1 + 2;
00429                 mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00430                 mf += i;
00431 
00432                 copy_v2_v2(df1->uv[0], mf->uv[c0]);
00433                 INT_UV(df1->uv[1], c0, c1)
00434                 INT_UV(df1->uv[2], c1, c2)
00435                 INT_UV(df1->uv[3], c0, c3)
00436 
00437                 INT_UV(df2->uv[0], c0, c1)
00438                 copy_v2_v2(df2->uv[1], mf->uv[c1]);
00439                 INT_UV(df2->uv[2], c1, c2)
00440 
00441                 INT_UV(df3->uv[0], c0, c3)
00442                 INT_UV(df3->uv[1], c1, c2)
00443                 copy_v2_v2(df3->uv[2], mf->uv[c2]);
00444                 copy_v2_v2(df3->uv[3], mf->uv[c3]);
00445         }
00446 }
00447 
00448 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)
00449 {
00450         MFace *df1 = get_dface(dm, split, cur, i, mf);
00451         MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00452 
00453         facepa[cur] = vertpa[v1];
00454         df1->v1 = v1;
00455         df1->v2 = GET_ES(v1, v2)
00456         df1->v3 = GET_ES(v1, v3)
00457         df1->v4 = 0;
00458         df1->flag &= ~ME_FACE_SEL;
00459 
00460         facepa[cur+1] = vertpa[v2];
00461         df2->v1 = GET_ES(v1, v2)
00462         df2->v2 = v2;
00463         df2->v3 = v3;
00464         df2->v4 = GET_ES(v1, v3)
00465         df2->flag |= ME_FACE_SEL;
00466 }
00467 
00468 static void remap_uvs_19_21_22(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
00469 {
00470         MTFace *mf, *df1, *df2;
00471         int l;
00472 
00473         for(l=0; l<numlayer; l++) {
00474                 mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00475                 df1 = mf+cur;
00476                 df2 = df1 + 1;
00477                 mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00478                 mf += i;
00479 
00480                 copy_v2_v2(df1->uv[0], mf->uv[c0]);
00481                 INT_UV(df1->uv[1], c0, c1)
00482                 INT_UV(df1->uv[2], c0, c2)
00483 
00484                 INT_UV(df2->uv[0], c0, c1)
00485                 copy_v2_v2(df2->uv[1], mf->uv[c1]);
00486                 copy_v2_v2(df2->uv[2], mf->uv[c2]);
00487                 INT_UV(df2->uv[3], c0, c2)
00488         }
00489 }
00490 
00491 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)
00492 {
00493         MFace *df1 = get_dface(dm, split, cur, i, mf);
00494         MFace *df2 = get_dface(dm, split, cur+1, i, mf);
00495         MFace *df3 = get_dface(dm, split, cur+2, i, mf);
00496 
00497         facepa[cur] = vertpa[v1];
00498         df1->v1 = v1;
00499         df1->v2 = GET_ES(v1, v2)
00500         df1->v3 = GET_ES(v2, v3)
00501         df1->v4 = GET_ES(v1, v3)
00502         df1->flag |= ME_FACE_SEL;
00503 
00504         facepa[cur+1] = vertpa[v2];
00505         df2->v1 = GET_ES(v1, v2)
00506         df2->v2 = v2;
00507         df2->v3 = GET_ES(v2, v3)
00508         df2->v4 = 0;
00509         df2->flag &= ~ME_FACE_SEL;
00510 
00511         facepa[cur+2] = vertpa[v3];
00512         df3->v1 = GET_ES(v1, v3)
00513         df3->v2 = GET_ES(v2, v3)
00514         df3->v3 = v3;
00515         df3->v4 = 0;
00516         df3->flag &= ~ME_FACE_SEL;
00517 }
00518 
00519 static void remap_uvs_23(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
00520 {
00521         MTFace *mf, *df1, *df2;
00522         int l;
00523 
00524         for(l=0; l<numlayer; l++) {
00525                 mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
00526                 df1 = mf+cur;
00527                 df2 = df1 + 1;
00528                 mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
00529                 mf += i;
00530 
00531                 copy_v2_v2(df1->uv[0], mf->uv[c0]);
00532                 INT_UV(df1->uv[1], c0, c1)
00533                 INT_UV(df1->uv[2], c1, c2)
00534                 INT_UV(df1->uv[3], c0, c2)
00535 
00536                 INT_UV(df2->uv[0], c0, c1)
00537                 copy_v2_v2(df2->uv[1], mf->uv[c1]);
00538                 INT_UV(df2->uv[2], c1, c2)
00539 
00540                 INT_UV(df2->uv[0], c0, c2)
00541                 INT_UV(df2->uv[1], c1, c2)
00542                 copy_v2_v2(df2->uv[2], mf->uv[c2]);
00543         }
00544 }
00545 
00546 static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm){
00547         DerivedMesh *splitdm;
00548         MFace *mf=NULL,*df1=NULL;
00549         MFace *mface=dm->getFaceArray(dm);
00550         MVert *dupve, *mv;
00551         EdgeHash *edgehash;
00552         EdgeHashIterator *ehi;
00553         int totvert=dm->getNumVerts(dm);
00554         int totface=dm->getNumFaces(dm);
00555 
00556         int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_facesplit");
00557         int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
00558         int *facepa = emd->facepa;
00559         int *fs, totesplit=0,totfsplit=0,curdupface=0;
00560         int i,j,v1,v2,v3,v4,esplit, v[4], uv[4];
00561         int numlayer;
00562 
00563         edgehash= BLI_edgehash_new();
00564 
00565         /* recreate vertpa from facepa calculation */
00566         for (i=0,mf=mface; i<totface; i++,mf++) {
00567                 vertpa[mf->v1]=facepa[i];
00568                 vertpa[mf->v2]=facepa[i];
00569                 vertpa[mf->v3]=facepa[i];
00570                 if(mf->v4)
00571                         vertpa[mf->v4]=facepa[i];
00572         }
00573 
00574         /* mark edges for splitting and how to split faces */
00575         for (i=0,mf=mface,fs=facesplit; i<totface; i++,mf++,fs++) {
00576                 v1=vertpa[mf->v1];
00577                 v2=vertpa[mf->v2];
00578                 v3=vertpa[mf->v3];
00579 
00580                 if(v1!=v2){
00581                         BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
00582                         (*fs) |= 1;
00583                 }
00584 
00585                 if(v2!=v3){
00586                         BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
00587                         (*fs) |= 2;
00588                 }
00589 
00590                 if(mf->v4){
00591                         v4=vertpa[mf->v4];
00592 
00593                         if(v3!=v4){
00594                                 BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
00595                                 (*fs) |= 4;
00596                         }
00597 
00598                         if(v1!=v4){
00599                                 BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
00600                                 (*fs) |= 8;
00601                         }
00602 
00603                         /* mark center vertex as a fake edge split */
00604                         if(*fs == 15)
00605                                 BLI_edgehash_insert(edgehash, mf->v1, mf->v3, NULL);
00606                 }
00607                 else {
00608                         (*fs) |= 16; /* mark face as tri */
00609 
00610                         if(v1!=v3){
00611                                 BLI_edgehash_insert(edgehash, mf->v1, mf->v3, NULL);
00612                                 (*fs) |= 4;
00613                         }
00614                 }
00615         }
00616 
00617         /* count splits & create indexes for new verts */
00618         ehi= BLI_edgehashIterator_new(edgehash);
00619         totesplit=totvert;
00620         for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
00621                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit));
00622                 totesplit++;
00623         }
00624         BLI_edgehashIterator_free(ehi);
00625 
00626         /* count new faces due to splitting */
00627         for(i=0,fs=facesplit; i<totface; i++,fs++)
00628                 totfsplit += add_faces[*fs];
00629         
00630         splitdm= CDDM_from_template(dm, totesplit, 0, totface+totfsplit);
00631         numlayer = CustomData_number_of_layers(&splitdm->faceData, CD_MTFACE);
00632 
00633         /* copy new faces & verts (is it really this painful with custom data??) */
00634         for(i=0; i<totvert; i++){
00635                 MVert source;
00636                 MVert *dest;
00637                 dm->getVert(dm, i, &source);
00638                 dest = CDDM_get_vert(splitdm, i);
00639 
00640                 DM_copy_vert_data(dm, splitdm, i, i, 1);
00641                 *dest = source;
00642         }
00643 
00644         /* override original facepa (original pointer is saved in caller function) */
00645         facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"explode_facepa");
00646         //memcpy(facepa,emd->facepa,totface*sizeof(int));
00647         emd->facepa=facepa;
00648 
00649         /* create new verts */
00650         ehi= BLI_edgehashIterator_new(edgehash);
00651         for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
00652                 BLI_edgehashIterator_getKey(ehi, &i, &j);
00653                 esplit= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
00654                 mv=CDDM_get_vert(splitdm,j);
00655                 dupve=CDDM_get_vert(splitdm,esplit);
00656 
00657                 DM_copy_vert_data(splitdm,splitdm,j,esplit,1);
00658 
00659                 *dupve=*mv;
00660 
00661                 mv=CDDM_get_vert(splitdm,i);
00662 
00663                 add_v3_v3(dupve->co, mv->co);
00664                 mul_v3_fl(dupve->co, 0.5f);
00665         }
00666         BLI_edgehashIterator_free(ehi);
00667 
00668         /* create new faces */
00669         curdupface=0;//=totface;
00670         //curdupin=totesplit;
00671         for(i=0,fs=facesplit; i<totface; i++,fs++){
00672                 mf = dm->getFaceData(dm, i, CD_MFACE);
00673 
00674                 switch(*fs) {
00675                 case 3:
00676                 case 10:
00677                 case 11:
00678                 case 15:
00679                         SET_VERTS(1, 2, 3, 4)
00680                         break;
00681                 case 5:
00682                 case 6:
00683                 case 7:
00684                         SET_VERTS(2, 3, 4, 1)
00685                         break;
00686                 case 9:
00687                 case 13:
00688                         SET_VERTS(4, 1, 2, 3)
00689                         break;
00690                 case 12:
00691                 case 14:
00692                         SET_VERTS(3, 4, 1, 2)
00693                         break;
00694                 case 21:
00695                 case 23:
00696                         SET_VERTS(1, 2, 3, 4)
00697                         break;
00698                 case 19:
00699                         SET_VERTS(2, 3, 1, 4)
00700                         break;
00701                 case 22:
00702                         SET_VERTS(3, 1, 2, 4)
00703                         break;
00704                 }
00705 
00706                 switch(*fs) {
00707                 case 3:
00708                 case 6:
00709                 case 9:
00710                 case 12:
00711                         remap_faces_3_6_9_12(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00712                         if(numlayer)
00713                                 remap_uvs_3_6_9_12(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00714                         break;
00715                 case 5:
00716                 case 10:
00717                         remap_faces_5_10(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00718                         if(numlayer)
00719                                 remap_uvs_5_10(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00720                         break;
00721                 case 15:
00722                         remap_faces_15(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00723                         if(numlayer)
00724                                 remap_uvs_15(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00725                         break;
00726                 case 7:
00727                 case 11:
00728                 case 13:
00729                 case 14:
00730                         remap_faces_7_11_13_14(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
00731                         if(numlayer)
00732                                 remap_uvs_7_11_13_14(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
00733                         break;
00734                 case 19:
00735                 case 21:
00736                 case 22:
00737                         remap_faces_19_21_22(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
00738                         if(numlayer)
00739                                 remap_uvs_19_21_22(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
00740                         break;
00741                 case 23:
00742                         remap_faces_23(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
00743                         if(numlayer)
00744                                 remap_uvs_23(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
00745                         break;
00746                 case 0:
00747                 case 16:
00748                         df1 = get_dface(dm, splitdm, curdupface, i, mf);
00749                         facepa[curdupface] = vertpa[mf->v1];
00750 
00751                         if(df1->v4)
00752                                 df1->flag |= ME_FACE_SEL;
00753                         else
00754                                 df1->flag &= ~ME_FACE_SEL;
00755                         break;
00756                 }
00757 
00758                 curdupface += add_faces[*fs]+1;
00759         }
00760 
00761         for(i=0; i<curdupface; i++) {
00762                 mf = CDDM_get_face(splitdm, i);
00763                 test_index_face(mf, &splitdm->faceData, i, (mf->flag & ME_FACE_SEL ? 4 : 3));
00764         }
00765 
00766         BLI_edgehash_free(edgehash, NULL);
00767         MEM_freeN(facesplit);
00768         MEM_freeN(vertpa);
00769 
00770         return splitdm;
00771 
00772 }
00773 static DerivedMesh * explodeMesh(ExplodeModifierData *emd, 
00774                 ParticleSystemModifierData *psmd, Scene *scene, Object *ob, 
00775   DerivedMesh *to_explode)
00776 {
00777         DerivedMesh *explode, *dm=to_explode;
00778         MFace *mf= NULL, *mface;
00779         /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */
00780         ParticleSimulationData sim= {NULL};
00781         ParticleData *pa=NULL, *pars=psmd->psys->particles;
00782         ParticleKey state, birth;
00783         EdgeHash *vertpahash;
00784         EdgeHashIterator *ehi;
00785         float *vertco= NULL, imat[4][4];
00786         float rot[4];
00787         float cfra;
00788         /* float timestep; */
00789         int *facepa=emd->facepa;
00790         int totdup=0,totvert=0,totface=0,totpart=0;
00791         int i, j, v, mindex=0;
00792         MTFace *mtface = NULL, *mtf;
00793 
00794         totface= dm->getNumFaces(dm);
00795         totvert= dm->getNumVerts(dm);
00796         mface= dm->getFaceArray(dm);
00797         totpart= psmd->psys->totpart;
00798 
00799         sim.scene= scene;
00800         sim.ob= ob;
00801         sim.psys= psmd->psys;
00802         sim.psmd= psmd;
00803 
00804         /* timestep= psys_get_timestep(&sim); */
00805 
00806         //if(part->flag & PART_GLOB_TIME)
00807                 cfra= BKE_curframe(scene);
00808         //else
00809         //      cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
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, &j, &i);
00858                 i -= totvert;
00859                 v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
00860 
00861                 dm->getVert(dm, j, &source);
00862                 dest = CDDM_get_vert(explode,v);
00863 
00864                 DM_copy_vert_data(dm,explode,j,v,1);
00865                 *dest = source;
00866 
00867                 if(i!=totpart) {
00868                         /* get particle */
00869                         pa= pars+i;
00870 
00871                         psys_get_birth_coordinates(&sim, pa, &birth, 0, 0);
00872 
00873                         state.time=cfra;
00874                         psys_get_particle_state(&sim, i, &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 };