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