|
Blender
V2.59
|
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 };