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) Blender Foundation 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Daniel Genrich 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include "MEM_guardedalloc.h" 00032 00033 #include "DNA_cloth_types.h" 00034 #include "DNA_scene_types.h" 00035 #include "DNA_object_types.h" 00036 #include "DNA_meshdata_types.h" 00037 00038 #include "BLI_math.h" 00039 #include "BLI_edgehash.h" 00040 #include "BLI_utildefines.h" 00041 #include "BLI_linklist.h" 00042 00043 #include "BKE_cdderivedmesh.h" 00044 #include "BKE_cloth.h" 00045 #include "BKE_effect.h" 00046 #include "BKE_global.h" 00047 #include "BKE_modifier.h" 00048 #include "BKE_pointcache.h" 00049 00050 #ifdef _WIN32 00051 void tstart ( void ) 00052 {} 00053 void tend ( void ) 00054 { 00055 } 00056 double tval( void ) 00057 { 00058 return 0; 00059 } 00060 #else 00061 #include <sys/time.h> 00062 static struct timeval _tstart, _tend; 00063 static struct timezone tz; 00064 void tstart ( void ) 00065 { 00066 gettimeofday ( &_tstart, &tz ); 00067 } 00068 void tend ( void ) 00069 { 00070 gettimeofday ( &_tend,&tz ); 00071 } 00072 double tval(void) 00073 { 00074 double t1, t2; 00075 t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); 00076 t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); 00077 return t2-t1; 00078 } 00079 #endif 00080 00081 /* Our available solvers. */ 00082 // 255 is the magic reserved number, so NEVER try to put 255 solvers in here! 00083 // 254 = MAX! 00084 static CM_SOLVER_DEF solvers [] = 00085 { 00086 { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, 00087 // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, 00088 }; 00089 00090 /* ********** cloth engine ******* */ 00091 /* Prototypes for internal functions. 00092 */ 00093 static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); 00094 static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm ); 00095 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first); 00096 static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); 00097 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ); 00098 00099 00100 /****************************************************************************** 00101 * 00102 * External interface called by modifier.c clothModifier functions. 00103 * 00104 ******************************************************************************/ 00111 void cloth_init ( ClothModifierData *clmd ) 00112 { 00113 /* Initialize our new data structure to reasonable values. */ 00114 clmd->sim_parms->gravity [0] = 0.0; 00115 clmd->sim_parms->gravity [1] = 0.0; 00116 clmd->sim_parms->gravity [2] = -9.81; 00117 clmd->sim_parms->structural = 15.0; 00118 clmd->sim_parms->shear = 15.0; 00119 clmd->sim_parms->bending = 0.5; 00120 clmd->sim_parms->Cdis = 5.0; 00121 clmd->sim_parms->Cvi = 1.0; 00122 clmd->sim_parms->mass = 0.3f; 00123 clmd->sim_parms->stepsPerFrame = 5; 00124 clmd->sim_parms->flags = 0; 00125 clmd->sim_parms->solver_type = 0; 00126 clmd->sim_parms->preroll = 0; 00127 clmd->sim_parms->maxspringlen = 10; 00128 clmd->sim_parms->vgroup_mass = 0; 00129 clmd->sim_parms->avg_spring_len = 0.0; 00130 clmd->sim_parms->presets = 2; /* cotton as start setting */ 00131 clmd->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */ 00132 clmd->sim_parms->reset = 0; 00133 00134 clmd->coll_parms->self_friction = 5.0; 00135 clmd->coll_parms->friction = 5.0; 00136 clmd->coll_parms->loop_count = 2; 00137 clmd->coll_parms->epsilon = 0.015f; 00138 clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; 00139 clmd->coll_parms->collision_list = NULL; 00140 clmd->coll_parms->self_loop_count = 1.0; 00141 clmd->coll_parms->selfepsilon = 0.75; 00142 00143 /* These defaults are copied from softbody.c's 00144 * softbody_calc_forces() function. 00145 */ 00146 clmd->sim_parms->eff_force_scale = 1000.0; 00147 clmd->sim_parms->eff_wind_scale = 250.0; 00148 00149 // also from softbodies 00150 clmd->sim_parms->maxgoal = 1.0f; 00151 clmd->sim_parms->mingoal = 0.0f; 00152 clmd->sim_parms->defgoal = 0.0f; 00153 clmd->sim_parms->goalspring = 1.0f; 00154 clmd->sim_parms->goalfrict = 0.0f; 00155 clmd->sim_parms->velocity_smooth = 0.0f; 00156 00157 if(!clmd->sim_parms->effector_weights) 00158 clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL); 00159 00160 if(clmd->point_cache) 00161 clmd->point_cache->step = 1; 00162 } 00163 00164 static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) 00165 { 00166 unsigned int i; 00167 BVHTree *bvhtree; 00168 Cloth *cloth; 00169 ClothVertex *verts; 00170 float co[12]; 00171 00172 if(!clmd) 00173 return NULL; 00174 00175 cloth = clmd->clothObject; 00176 00177 if(!cloth) 00178 return NULL; 00179 00180 verts = cloth->verts; 00181 00182 // in the moment, return zero if no faces there 00183 if(!cloth->numverts) 00184 return NULL; 00185 00186 // create quadtree with k=26 00187 bvhtree = BLI_bvhtree_new(cloth->numverts, epsilon, 4, 6); 00188 00189 // fill tree 00190 for(i = 0; i < cloth->numverts; i++, verts++) 00191 { 00192 copy_v3_v3(&co[0*3], verts->xold); 00193 00194 BLI_bvhtree_insert(bvhtree, i, co, 1); 00195 } 00196 00197 // balance tree 00198 BLI_bvhtree_balance(bvhtree); 00199 00200 return bvhtree; 00201 } 00202 00203 static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) 00204 { 00205 unsigned int i; 00206 BVHTree *bvhtree; 00207 Cloth *cloth; 00208 ClothVertex *verts; 00209 MFace *mfaces; 00210 float co[12]; 00211 00212 if(!clmd) 00213 return NULL; 00214 00215 cloth = clmd->clothObject; 00216 00217 if(!cloth) 00218 return NULL; 00219 00220 verts = cloth->verts; 00221 mfaces = cloth->mfaces; 00222 00223 // in the moment, return zero if no faces there 00224 if(!cloth->numfaces) 00225 return NULL; 00226 00227 // create quadtree with k=26 00228 bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 26); 00229 00230 // fill tree 00231 for(i = 0; i < cloth->numfaces; i++, mfaces++) 00232 { 00233 copy_v3_v3(&co[0*3], verts[mfaces->v1].xold); 00234 copy_v3_v3(&co[1*3], verts[mfaces->v2].xold); 00235 copy_v3_v3(&co[2*3], verts[mfaces->v3].xold); 00236 00237 if(mfaces->v4) 00238 copy_v3_v3(&co[3*3], verts[mfaces->v4].xold); 00239 00240 BLI_bvhtree_insert(bvhtree, i, co, (mfaces->v4 ? 4 : 3)); 00241 } 00242 00243 // balance tree 00244 BLI_bvhtree_balance(bvhtree); 00245 00246 return bvhtree; 00247 } 00248 00249 void bvhtree_update_from_cloth(ClothModifierData *clmd, int moving) 00250 { 00251 unsigned int i = 0; 00252 Cloth *cloth = clmd->clothObject; 00253 BVHTree *bvhtree = cloth->bvhtree; 00254 ClothVertex *verts = cloth->verts; 00255 MFace *mfaces; 00256 float co[12], co_moving[12]; 00257 int ret = 0; 00258 00259 if(!bvhtree) 00260 return; 00261 00262 mfaces = cloth->mfaces; 00263 00264 // update vertex position in bvh tree 00265 if(verts && mfaces) 00266 { 00267 for(i = 0; i < cloth->numfaces; i++, mfaces++) 00268 { 00269 copy_v3_v3(&co[0*3], verts[mfaces->v1].txold); 00270 copy_v3_v3(&co[1*3], verts[mfaces->v2].txold); 00271 copy_v3_v3(&co[2*3], verts[mfaces->v3].txold); 00272 00273 if(mfaces->v4) 00274 copy_v3_v3(&co[3*3], verts[mfaces->v4].txold); 00275 00276 // copy new locations into array 00277 if(moving) 00278 { 00279 // update moving positions 00280 copy_v3_v3(&co_moving[0*3], verts[mfaces->v1].tx); 00281 copy_v3_v3(&co_moving[1*3], verts[mfaces->v2].tx); 00282 copy_v3_v3(&co_moving[2*3], verts[mfaces->v3].tx); 00283 00284 if(mfaces->v4) 00285 copy_v3_v3(&co_moving[3*3], verts[mfaces->v4].tx); 00286 00287 ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, (mfaces->v4 ? 4 : 3)); 00288 } 00289 else 00290 { 00291 ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, (mfaces->v4 ? 4 : 3)); 00292 } 00293 00294 // check if tree is already full 00295 if(!ret) 00296 break; 00297 } 00298 00299 BLI_bvhtree_update_tree(bvhtree); 00300 } 00301 } 00302 00303 void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving) 00304 { 00305 unsigned int i = 0; 00306 Cloth *cloth = clmd->clothObject; 00307 BVHTree *bvhtree = cloth->bvhselftree; 00308 ClothVertex *verts = cloth->verts; 00309 MFace *mfaces; 00310 float co[12], co_moving[12]; 00311 int ret = 0; 00312 00313 if(!bvhtree) 00314 return; 00315 00316 mfaces = cloth->mfaces; 00317 00318 // update vertex position in bvh tree 00319 if(verts && mfaces) 00320 { 00321 for(i = 0; i < cloth->numverts; i++, verts++) 00322 { 00323 copy_v3_v3(&co[0*3], verts->txold); 00324 00325 // copy new locations into array 00326 if(moving) 00327 { 00328 // update moving positions 00329 copy_v3_v3(&co_moving[0*3], verts->tx); 00330 00331 ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, 1); 00332 } 00333 else 00334 { 00335 ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, 1); 00336 } 00337 00338 // check if tree is already full 00339 if(!ret) 00340 break; 00341 } 00342 00343 BLI_bvhtree_update_tree(bvhtree); 00344 } 00345 } 00346 00347 void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) 00348 { 00349 PTCacheID pid; 00350 00351 BKE_ptcache_id_from_cloth(&pid, ob, clmd); 00352 00353 // don't do anything as long as we're in editmode! 00354 if(pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT) 00355 return; 00356 00357 BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr); 00358 } 00359 00360 static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr) 00361 { 00362 PointCache *cache; 00363 00364 cache= clmd->point_cache; 00365 00366 /* initialize simulation data if it didn't exist already */ 00367 if(clmd->clothObject == NULL) { 00368 if(!cloth_from_object(ob, clmd, result, framenr, 1)) { 00369 BKE_ptcache_invalidate(cache); 00370 return 0; 00371 } 00372 00373 if(clmd->clothObject == NULL) { 00374 BKE_ptcache_invalidate(cache); 00375 return 0; 00376 } 00377 00378 implicit_set_positions(clmd); 00379 00380 clmd->clothObject->last_frame= MINFRAME-1; 00381 } 00382 00383 return 1; 00384 } 00385 00386 static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr) 00387 { 00388 ClothVertex *verts = NULL; 00389 Cloth *cloth; 00390 ListBase *effectors = NULL; 00391 MVert *mvert; 00392 unsigned int i = 0; 00393 int ret = 0; 00394 00395 /* simulate 1 frame forward */ 00396 cloth = clmd->clothObject; 00397 verts = cloth->verts; 00398 mvert = result->getVertArray(result); 00399 00400 /* force any pinned verts to their constrained location. */ 00401 for(i = 0; i < clmd->clothObject->numverts; i++, verts++) { 00402 /* save the previous position. */ 00403 copy_v3_v3(verts->xold, verts->xconst); 00404 copy_v3_v3(verts->txold, verts->x); 00405 00406 /* Get the current position. */ 00407 copy_v3_v3(verts->xconst, mvert[i].co); 00408 mul_m4_v3(ob->obmat, verts->xconst); 00409 } 00410 00411 effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights); 00412 00413 tstart(); 00414 00415 /* call the solver. */ 00416 if(solvers [clmd->sim_parms->solver_type].solver) 00417 ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors); 00418 00419 tend(); 00420 00421 pdEndEffectors(&effectors); 00422 00423 // printf ( "%f\n", ( float ) tval() ); 00424 00425 return ret; 00426 } 00427 00428 /************************************************ 00429 * clothModifier_do - main simulation function 00430 ************************************************/ 00431 DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm) 00432 { 00433 DerivedMesh *result; 00434 PointCache *cache; 00435 PTCacheID pid; 00436 float timescale; 00437 int framenr, startframe, endframe; 00438 int cache_result; 00439 00440 clmd->scene= scene; /* nice to pass on later :) */ 00441 framenr= (int)scene->r.cfra; 00442 cache= clmd->point_cache; 00443 result = CDDM_copy(dm); 00444 00445 BKE_ptcache_id_from_cloth(&pid, ob, clmd); 00446 BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); 00447 clmd->sim_parms->timescale= timescale; 00448 00449 if(!result) { 00450 BKE_ptcache_invalidate(cache); 00451 return dm; 00452 } 00453 00454 if(clmd->sim_parms->reset 00455 || (framenr == (startframe - clmd->sim_parms->preroll) && clmd->sim_parms->preroll != 0) 00456 || (clmd->clothObject && result->getNumVerts(result) != clmd->clothObject->numverts)) 00457 { 00458 clmd->sim_parms->reset = 0; 00459 cache->flag |= PTCACHE_OUTDATED; 00460 BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); 00461 BKE_ptcache_validate(cache, 0); 00462 cache->last_exact= 0; 00463 cache->flag &= ~PTCACHE_REDO_NEEDED; 00464 return result; 00465 } 00466 00467 // unused in the moment, calculated separately in implicit.c 00468 clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame; 00469 00470 /* handle continuous simulation with the play button */ 00471 if(BKE_ptcache_get_continue_physics() || ((clmd->sim_parms->preroll > 0) && (framenr > startframe - clmd->sim_parms->preroll) && (framenr < startframe))) { 00472 BKE_ptcache_invalidate(cache); 00473 00474 /* do simulation */ 00475 if(!do_init_cloth(ob, clmd, dm, framenr)) 00476 return result; 00477 00478 do_step_cloth(ob, clmd, dm, framenr); 00479 cloth_to_object(ob, clmd, result); 00480 00481 clmd->clothObject->last_frame= framenr; 00482 00483 return result; 00484 } 00485 00486 /* simulation is only active during a specific period */ 00487 if(framenr < startframe) { 00488 BKE_ptcache_invalidate(cache); 00489 return result; 00490 } 00491 else if(framenr > endframe) { 00492 framenr= endframe; 00493 } 00494 00495 /* initialize simulation data if it didn't exist already */ 00496 if(!do_init_cloth(ob, clmd, dm, framenr)) 00497 return result; 00498 00499 if((framenr == startframe) && (clmd->sim_parms->preroll == 0)) { 00500 BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); 00501 do_init_cloth(ob, clmd, dm, framenr); 00502 BKE_ptcache_validate(cache, framenr); 00503 cache->flag &= ~PTCACHE_REDO_NEEDED; 00504 clmd->clothObject->last_frame= framenr; 00505 return result; 00506 } 00507 00508 /* try to read from cache */ 00509 cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe); 00510 00511 if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { 00512 implicit_set_positions(clmd); 00513 cloth_to_object (ob, clmd, result); 00514 00515 BKE_ptcache_validate(cache, framenr); 00516 00517 if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) 00518 BKE_ptcache_write(&pid, framenr); 00519 00520 clmd->clothObject->last_frame= framenr; 00521 00522 return result; 00523 } 00524 else if(cache_result==PTCACHE_READ_OLD) { 00525 implicit_set_positions(clmd); 00526 } 00527 else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */ 00528 /* if baked and nothing in cache, do nothing */ 00529 BKE_ptcache_invalidate(cache); 00530 return result; 00531 } 00532 00533 if(framenr!=clmd->clothObject->last_frame+1) 00534 return result; 00535 00536 /* if on second frame, write cache for first frame */ 00537 if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) 00538 BKE_ptcache_write(&pid, startframe); 00539 00540 clmd->sim_parms->timescale *= framenr - cache->simframe; 00541 00542 /* do simulation */ 00543 BKE_ptcache_validate(cache, framenr); 00544 00545 if(!do_step_cloth(ob, clmd, dm, framenr)) { 00546 BKE_ptcache_invalidate(cache); 00547 } 00548 else 00549 BKE_ptcache_write(&pid, framenr); 00550 00551 cloth_to_object (ob, clmd, result); 00552 clmd->clothObject->last_frame= framenr; 00553 00554 return result; 00555 } 00556 00557 /* frees all */ 00558 void cloth_free_modifier(ClothModifierData *clmd ) 00559 { 00560 Cloth *cloth = NULL; 00561 00562 if ( !clmd ) 00563 return; 00564 00565 cloth = clmd->clothObject; 00566 00567 00568 if ( cloth ) 00569 { 00570 // If our solver provides a free function, call it 00571 if ( solvers [clmd->sim_parms->solver_type].free ) 00572 { 00573 solvers [clmd->sim_parms->solver_type].free ( clmd ); 00574 } 00575 00576 // Free the verts. 00577 if ( cloth->verts != NULL ) 00578 MEM_freeN ( cloth->verts ); 00579 00580 cloth->verts = NULL; 00581 cloth->numverts = 0; 00582 00583 // Free the springs. 00584 if ( cloth->springs != NULL ) 00585 { 00586 LinkNode *search = cloth->springs; 00587 while(search) 00588 { 00589 ClothSpring *spring = search->link; 00590 00591 MEM_freeN ( spring ); 00592 search = search->next; 00593 } 00594 BLI_linklist_free(cloth->springs, NULL); 00595 00596 cloth->springs = NULL; 00597 } 00598 00599 cloth->springs = NULL; 00600 cloth->numsprings = 0; 00601 00602 // free BVH collision tree 00603 if ( cloth->bvhtree ) 00604 BLI_bvhtree_free ( cloth->bvhtree ); 00605 00606 if ( cloth->bvhselftree ) 00607 BLI_bvhtree_free ( cloth->bvhselftree ); 00608 00609 // we save our faces for collision objects 00610 if ( cloth->mfaces ) 00611 MEM_freeN ( cloth->mfaces ); 00612 00613 if(cloth->edgehash) 00614 BLI_edgehash_free ( cloth->edgehash, NULL ); 00615 00616 00617 /* 00618 if(clmd->clothObject->facemarks) 00619 MEM_freeN(clmd->clothObject->facemarks); 00620 */ 00621 MEM_freeN ( cloth ); 00622 clmd->clothObject = NULL; 00623 } 00624 } 00625 00626 /* frees all */ 00627 void cloth_free_modifier_extern ( ClothModifierData *clmd ) 00628 { 00629 Cloth *cloth = NULL; 00630 if(G.rt > 0) 00631 printf("cloth_free_modifier_extern\n"); 00632 00633 if ( !clmd ) 00634 return; 00635 00636 cloth = clmd->clothObject; 00637 00638 if ( cloth ) 00639 { 00640 if(G.rt > 0) 00641 printf("cloth_free_modifier_extern in\n"); 00642 00643 // If our solver provides a free function, call it 00644 if ( solvers [clmd->sim_parms->solver_type].free ) 00645 { 00646 solvers [clmd->sim_parms->solver_type].free ( clmd ); 00647 } 00648 00649 // Free the verts. 00650 if ( cloth->verts != NULL ) 00651 MEM_freeN ( cloth->verts ); 00652 00653 cloth->verts = NULL; 00654 cloth->numverts = 0; 00655 00656 // Free the springs. 00657 if ( cloth->springs != NULL ) 00658 { 00659 LinkNode *search = cloth->springs; 00660 while(search) 00661 { 00662 ClothSpring *spring = search->link; 00663 00664 MEM_freeN ( spring ); 00665 search = search->next; 00666 } 00667 BLI_linklist_free(cloth->springs, NULL); 00668 00669 cloth->springs = NULL; 00670 } 00671 00672 cloth->springs = NULL; 00673 cloth->numsprings = 0; 00674 00675 // free BVH collision tree 00676 if ( cloth->bvhtree ) 00677 BLI_bvhtree_free ( cloth->bvhtree ); 00678 00679 if ( cloth->bvhselftree ) 00680 BLI_bvhtree_free ( cloth->bvhselftree ); 00681 00682 // we save our faces for collision objects 00683 if ( cloth->mfaces ) 00684 MEM_freeN ( cloth->mfaces ); 00685 00686 if(cloth->edgehash) 00687 BLI_edgehash_free ( cloth->edgehash, NULL ); 00688 00689 00690 /* 00691 if(clmd->clothObject->facemarks) 00692 MEM_freeN(clmd->clothObject->facemarks); 00693 */ 00694 MEM_freeN ( cloth ); 00695 clmd->clothObject = NULL; 00696 } 00697 } 00698 00699 /****************************************************************************** 00700 * 00701 * Internal functions. 00702 * 00703 ******************************************************************************/ 00704 00709 static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm) 00710 { 00711 unsigned int i = 0; 00712 MVert *mvert = NULL; 00713 unsigned int numverts; 00714 Cloth *cloth = clmd->clothObject; 00715 00716 if (clmd->clothObject) { 00717 /* inverse matrix is not uptodate... */ 00718 invert_m4_m4(ob->imat, ob->obmat); 00719 00720 mvert = CDDM_get_verts(dm); 00721 numverts = dm->getNumVerts(dm); 00722 00723 for (i = 0; i < numverts; i++) 00724 { 00725 copy_v3_v3 (mvert[i].co, cloth->verts[i].x); 00726 mul_m4_v3(ob->imat, mvert[i].co); /* cloth is in global coords */ 00727 } 00728 } 00729 } 00730 00731 00732 int cloth_uses_vgroup(ClothModifierData *clmd) 00733 { 00734 return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || 00735 (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && 00736 ((clmd->sim_parms->vgroup_mass>0) || 00737 (clmd->sim_parms->vgroup_struct>0)|| 00738 (clmd->sim_parms->vgroup_bend>0))); 00739 } 00740 00745 /* can be optimized to do all groups in one loop */ 00746 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) 00747 { 00748 int i = 0; 00749 int j = 0; 00750 MDeformVert *dvert = NULL; 00751 Cloth *clothObj = NULL; 00752 int numverts; 00753 /* float goalfac = 0; */ /* UNUSED */ 00754 ClothVertex *verts = NULL; 00755 00756 if (!clmd || !dm) return; 00757 00758 clothObj = clmd->clothObject; 00759 00760 numverts = dm->getNumVerts ( dm ); 00761 00762 verts = clothObj->verts; 00763 00764 if (cloth_uses_vgroup(clmd)) 00765 { 00766 for ( i = 0; i < numverts; i++, verts++ ) 00767 { 00768 dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); 00769 if ( dvert ) 00770 { 00771 for ( j = 0; j < dvert->totweight; j++ ) 00772 { 00773 if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) 00774 { 00775 verts->goal = dvert->dw [j].weight; 00776 /* goalfac= 1.0f; */ /* UNUSED */ 00777 00778 /* 00779 // Kicking goal factor to simplify things...who uses that anyway? 00780 // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); 00781 */ 00782 00783 verts->goal = ( float ) pow ( verts->goal , 4.0f ); 00784 if ( verts->goal >=SOFTGOALSNAP ) 00785 { 00786 verts->flags |= CLOTH_VERT_FLAG_PINNED; 00787 } 00788 } 00789 00790 if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) 00791 { 00792 if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct-1)) 00793 { 00794 verts->struct_stiff = dvert->dw [j].weight; 00795 verts->shear_stiff = dvert->dw [j].weight; 00796 } 00797 00798 if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_bend-1)) 00799 { 00800 verts->bend_stiff = dvert->dw [j].weight; 00801 } 00802 } 00803 /* 00804 // for later 00805 if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_weight-1)) 00806 { 00807 verts->mass = dvert->dw [j].weight; 00808 } 00809 */ 00810 } 00811 } 00812 } 00813 } 00814 } 00815 00816 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float UNUSED(framenr), int first) 00817 { 00818 int i = 0; 00819 MVert *mvert = NULL; 00820 ClothVertex *verts = NULL; 00821 float (*shapekey_rest)[3]= NULL; 00822 float tnull[3] = {0,0,0}; 00823 Cloth *cloth = NULL; 00824 float maxdist = 0; 00825 00826 // If we have a clothObject, free it. 00827 if ( clmd->clothObject != NULL ) 00828 { 00829 cloth_free_modifier ( clmd ); 00830 if(G.rt > 0) 00831 printf("cloth_free_modifier cloth_from_object\n"); 00832 } 00833 00834 // Allocate a new cloth object. 00835 clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); 00836 if ( clmd->clothObject ) 00837 { 00838 clmd->clothObject->old_solver_type = 255; 00839 // clmd->clothObject->old_collision_type = 255; 00840 cloth = clmd->clothObject; 00841 clmd->clothObject->edgehash = NULL; 00842 } 00843 else if ( !clmd->clothObject ) 00844 { 00845 modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); 00846 return 0; 00847 } 00848 00849 // mesh input objects need DerivedMesh 00850 if ( !dm ) 00851 return 0; 00852 00853 cloth_from_mesh ( clmd, dm ); 00854 00855 // create springs 00856 clmd->clothObject->springs = NULL; 00857 clmd->clothObject->numsprings = -1; 00858 00859 if( clmd->sim_parms->shapekey_rest ) 00860 shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO ); 00861 00862 mvert = dm->getVertArray ( dm ); 00863 00864 verts = clmd->clothObject->verts; 00865 00866 // set initial values 00867 for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) 00868 { 00869 if(first) 00870 { 00871 copy_v3_v3( verts->x, mvert[i].co ); 00872 00873 mul_m4_v3( ob->obmat, verts->x ); 00874 00875 if( shapekey_rest ) { 00876 verts->xrest= shapekey_rest[i]; 00877 mul_m4_v3( ob->obmat, verts->xrest ); 00878 } 00879 else 00880 verts->xrest = verts->x; 00881 } 00882 00883 /* no GUI interface yet */ 00884 verts->mass = clmd->sim_parms->mass; 00885 verts->impulse_count = 0; 00886 00887 if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) 00888 verts->goal= clmd->sim_parms->defgoal; 00889 else 00890 verts->goal= 0.0f; 00891 00892 verts->flags = 0; 00893 copy_v3_v3 ( verts->xold, verts->x ); 00894 copy_v3_v3 ( verts->xconst, verts->x ); 00895 copy_v3_v3 ( verts->txold, verts->x ); 00896 copy_v3_v3 ( verts->tx, verts->x ); 00897 mul_v3_fl( verts->v, 0.0f ); 00898 00899 verts->impulse_count = 0; 00900 copy_v3_v3 ( verts->impulse, tnull ); 00901 } 00902 00903 // apply / set vertex groups 00904 // has to be happen before springs are build! 00905 cloth_apply_vgroup (clmd, dm); 00906 00907 if ( !cloth_build_springs ( clmd, dm ) ) 00908 { 00909 cloth_free_modifier ( clmd ); 00910 modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); 00911 printf("cloth_free_modifier cloth_build_springs\n"); 00912 return 0; 00913 } 00914 00915 for ( i = 0; i < dm->getNumVerts(dm); i++) 00916 { 00917 if((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO)) 00918 { 00919 cloth_add_spring (clmd, i, i, 0.0, CLOTH_SPRING_TYPE_GOAL); 00920 } 00921 } 00922 00923 // init our solver 00924 if ( solvers [clmd->sim_parms->solver_type].init ) { 00925 solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); 00926 } 00927 00928 if(!first) 00929 implicit_set_positions(clmd); 00930 00931 clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel) ); 00932 00933 for(i = 0; i < dm->getNumVerts(dm); i++) 00934 { 00935 maxdist = MAX2(maxdist, clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len*2.0f)); 00936 } 00937 00938 clmd->clothObject->bvhselftree = bvhselftree_build_from_cloth ( clmd, maxdist ); 00939 00940 return 1; 00941 } 00942 00943 static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm ) 00944 { 00945 unsigned int numverts = dm->getNumVerts ( dm ); 00946 unsigned int numfaces = dm->getNumFaces ( dm ); 00947 MFace *mface = dm->getFaceArray( dm ); 00948 unsigned int i = 0; 00949 00950 /* Allocate our vertices. */ 00951 clmd->clothObject->numverts = numverts; 00952 clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); 00953 if ( clmd->clothObject->verts == NULL ) 00954 { 00955 cloth_free_modifier ( clmd ); 00956 modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); 00957 printf("cloth_free_modifier clmd->clothObject->verts\n"); 00958 return; 00959 } 00960 00961 // save face information 00962 clmd->clothObject->numfaces = numfaces; 00963 clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" ); 00964 if ( clmd->clothObject->mfaces == NULL ) 00965 { 00966 cloth_free_modifier ( clmd ); 00967 modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." ); 00968 printf("cloth_free_modifier clmd->clothObject->mfaces\n"); 00969 return; 00970 } 00971 for ( i = 0; i < numfaces; i++ ) 00972 memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) ); 00973 00974 /* Free the springs since they can't be correct if the vertices 00975 * changed. 00976 */ 00977 if ( clmd->clothObject->springs != NULL ) 00978 MEM_freeN ( clmd->clothObject->springs ); 00979 00980 } 00981 00982 /*************************************************************************************** 00983 * SPRING NETWORK BUILDING IMPLEMENTATION BEGIN 00984 ***************************************************************************************/ 00985 00986 // be careful: implicit solver has to be resettet when using this one! 00987 // --> only for implicit handling of this spring! 00988 int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type) 00989 { 00990 Cloth *cloth = clmd->clothObject; 00991 ClothSpring *spring = NULL; 00992 00993 if(cloth) 00994 { 00995 // TODO: look if this spring is already there 00996 00997 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); 00998 00999 if(!spring) 01000 return 0; 01001 01002 spring->ij = indexA; 01003 spring->kl = indexB; 01004 spring->restlen = restlength; 01005 spring->type = spring_type; 01006 spring->flags = 0; 01007 spring->stiffness = 0; 01008 01009 cloth->numsprings++; 01010 01011 BLI_linklist_prepend ( &cloth->springs, spring ); 01012 01013 return 1; 01014 } 01015 return 0; 01016 } 01017 01018 static void cloth_free_errorsprings(Cloth *cloth, EdgeHash *UNUSED(edgehash), LinkNode **edgelist) 01019 { 01020 unsigned int i = 0; 01021 01022 if ( cloth->springs != NULL ) 01023 { 01024 LinkNode *search = cloth->springs; 01025 while(search) 01026 { 01027 ClothSpring *spring = search->link; 01028 01029 MEM_freeN ( spring ); 01030 search = search->next; 01031 } 01032 BLI_linklist_free(cloth->springs, NULL); 01033 01034 cloth->springs = NULL; 01035 } 01036 01037 if(edgelist) 01038 { 01039 for ( i = 0; i < cloth->numverts; i++ ) 01040 { 01041 BLI_linklist_free ( edgelist[i],NULL ); 01042 } 01043 01044 MEM_freeN ( edgelist ); 01045 } 01046 01047 if(cloth->edgehash) 01048 BLI_edgehash_free ( cloth->edgehash, NULL ); 01049 } 01050 01051 static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) 01052 { 01053 Cloth *cloth = clmd->clothObject; 01054 ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; 01055 unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; 01056 unsigned int i = 0; 01057 unsigned int numverts = (unsigned int)dm->getNumVerts ( dm ); 01058 unsigned int numedges = (unsigned int)dm->getNumEdges ( dm ); 01059 unsigned int numfaces = (unsigned int)dm->getNumFaces ( dm ); 01060 MEdge *medge = dm->getEdgeArray ( dm ); 01061 MFace *mface = dm->getFaceArray ( dm ); 01062 int index2 = 0; // our second vertex index 01063 LinkNode **edgelist = NULL; 01064 EdgeHash *edgehash = NULL; 01065 LinkNode *search = NULL, *search2 = NULL; 01066 01067 // error handling 01068 if ( numedges==0 ) 01069 return 0; 01070 01071 cloth->springs = NULL; 01072 01073 edgelist = MEM_callocN ( sizeof ( LinkNode * ) * numverts, "cloth_edgelist_alloc" ); 01074 01075 if(!edgelist) 01076 return 0; 01077 01078 for ( i = 0; i < numverts; i++ ) 01079 { 01080 edgelist[i] = NULL; 01081 } 01082 01083 if ( cloth->springs ) 01084 MEM_freeN ( cloth->springs ); 01085 01086 // create spring network hash 01087 edgehash = BLI_edgehash_new(); 01088 01089 // structural springs 01090 for ( i = 0; i < numedges; i++ ) 01091 { 01092 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); 01093 01094 if ( spring ) 01095 { 01096 spring->ij = MIN2(medge[i].v1, medge[i].v2); 01097 spring->kl = MAX2(medge[i].v2, medge[i].v1); 01098 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); 01099 clmd->sim_parms->avg_spring_len += spring->restlen; 01100 cloth->verts[spring->ij].avg_spring_len += spring->restlen; 01101 cloth->verts[spring->kl].avg_spring_len += spring->restlen; 01102 cloth->verts[spring->ij].spring_count++; 01103 cloth->verts[spring->kl].spring_count++; 01104 spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; 01105 spring->flags = 0; 01106 spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0f; 01107 struct_springs++; 01108 01109 BLI_linklist_prepend ( &cloth->springs, spring ); 01110 } 01111 else 01112 { 01113 cloth_free_errorsprings(cloth, edgehash, edgelist); 01114 return 0; 01115 } 01116 } 01117 01118 if(struct_springs > 0) 01119 clmd->sim_parms->avg_spring_len /= struct_springs; 01120 01121 for(i = 0; i < numverts; i++) 01122 { 01123 cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f / ((float)cloth->verts[i].spring_count); 01124 } 01125 01126 // shear springs 01127 for ( i = 0; i < numfaces; i++ ) 01128 { 01129 // triangle faces already have shear springs due to structural geometry 01130 if ( !mface[i].v4 ) 01131 continue; 01132 01133 spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); 01134 01135 if(!spring) 01136 { 01137 cloth_free_errorsprings(cloth, edgehash, edgelist); 01138 return 0; 01139 } 01140 01141 spring->ij = MIN2(mface[i].v1, mface[i].v3); 01142 spring->kl = MAX2(mface[i].v3, mface[i].v1); 01143 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); 01144 spring->type = CLOTH_SPRING_TYPE_SHEAR; 01145 spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0f; 01146 01147 BLI_linklist_append ( &edgelist[spring->ij], spring ); 01148 BLI_linklist_append ( &edgelist[spring->kl], spring ); 01149 shear_springs++; 01150 01151 BLI_linklist_prepend ( &cloth->springs, spring ); 01152 01153 01154 // if ( mface[i].v4 ) --> Quad face 01155 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); 01156 01157 if(!spring) 01158 { 01159 cloth_free_errorsprings(cloth, edgehash, edgelist); 01160 return 0; 01161 } 01162 01163 spring->ij = MIN2(mface[i].v2, mface[i].v4); 01164 spring->kl = MAX2(mface[i].v4, mface[i].v2); 01165 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); 01166 spring->type = CLOTH_SPRING_TYPE_SHEAR; 01167 spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; 01168 01169 BLI_linklist_append ( &edgelist[spring->ij], spring ); 01170 BLI_linklist_append ( &edgelist[spring->kl], spring ); 01171 shear_springs++; 01172 01173 BLI_linklist_prepend ( &cloth->springs, spring ); 01174 } 01175 01176 if(numfaces) { 01177 // bending springs 01178 search2 = cloth->springs; 01179 for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) 01180 { 01181 if ( !search2 ) 01182 break; 01183 01184 tspring2 = search2->link; 01185 search = edgelist[tspring2->kl]; 01186 while ( search ) 01187 { 01188 tspring = search->link; 01189 index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) ); 01190 01191 // check for existing spring 01192 // check also if startpoint is equal to endpoint 01193 if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) ) 01194 && ( index2!=tspring2->ij ) ) 01195 { 01196 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); 01197 01198 if(!spring) 01199 { 01200 cloth_free_errorsprings(cloth, edgehash, edgelist); 01201 return 0; 01202 } 01203 01204 spring->ij = MIN2(tspring2->ij, index2); 01205 spring->kl = MAX2(tspring2->ij, index2); 01206 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); 01207 spring->type = CLOTH_SPRING_TYPE_BENDING; 01208 spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f; 01209 BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL ); 01210 bend_springs++; 01211 01212 BLI_linklist_prepend ( &cloth->springs, spring ); 01213 } 01214 search = search->next; 01215 } 01216 search2 = search2->next; 01217 } 01218 } 01219 else if(struct_springs > 2) { 01220 /* bending springs for hair strands */ 01221 /* The current algorightm only goes through the edges in order of the mesh edges list */ 01222 /* and makes springs between the outer vert of edges sharing a vertice. This works just */ 01223 /* fine for hair, but not for user generated string meshes. This could/should be later */ 01224 /* extended to work with non-ordered edges so that it can be used for general "rope */ 01225 /* dynamics" without the need for the vertices or edges to be ordered through the length*/ 01226 /* of the strands. -jahka */ 01227 search = cloth->springs; 01228 search2 = search->next; 01229 while(search && search2) 01230 { 01231 tspring = search->link; 01232 tspring2 = search2->link; 01233 01234 if(tspring->ij == tspring2->kl) { 01235 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); 01236 01237 if(!spring) 01238 { 01239 cloth_free_errorsprings(cloth, edgehash, edgelist); 01240 return 0; 01241 } 01242 01243 spring->ij = tspring2->ij; 01244 spring->kl = tspring->kl; 01245 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); 01246 spring->type = CLOTH_SPRING_TYPE_BENDING; 01247 spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f; 01248 bend_springs++; 01249 01250 BLI_linklist_prepend ( &cloth->springs, spring ); 01251 } 01252 01253 search = search->next; 01254 search2 = search2->next; 01255 } 01256 } 01257 01258 /* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */ 01259 for ( i = 0; i < numedges; i++ ) // struct springs 01260 BLI_edgehash_insert ( edgehash, MIN2(medge[i].v1, medge[i].v2), MAX2(medge[i].v2, medge[i].v1), NULL ); 01261 01262 for ( i = 0; i < numfaces; i++ ) // edge springs 01263 { 01264 if(mface[i].v4) 01265 { 01266 BLI_edgehash_insert ( edgehash, MIN2(mface[i].v1, mface[i].v3), MAX2(mface[i].v3, mface[i].v1), NULL ); 01267 01268 BLI_edgehash_insert ( edgehash, MIN2(mface[i].v2, mface[i].v4), MAX2(mface[i].v2, mface[i].v4), NULL ); 01269 } 01270 } 01271 01272 01273 cloth->numsprings = struct_springs + shear_springs + bend_springs; 01274 01275 if ( edgelist ) 01276 { 01277 for ( i = 0; i < numverts; i++ ) 01278 { 01279 BLI_linklist_free ( edgelist[i],NULL ); 01280 } 01281 01282 MEM_freeN ( edgelist ); 01283 } 01284 01285 cloth->edgehash = edgehash; 01286 01287 if(G.rt>0) 01288 printf("avg_len: %f\n",clmd->sim_parms->avg_spring_len); 01289 01290 return 1; 01291 01292 } /* cloth_build_springs */ 01293 /*************************************************************************************** 01294 * SPRING NETWORK BUILDING IMPLEMENTATION END 01295 ***************************************************************************************/ 01296