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