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) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <math.h> 00034 #include <string.h> 00035 #include <stddef.h> 00036 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "BLI_blenlib.h" 00040 #include "BLI_editVert.h" 00041 #include "BLI_math_vector.h" 00042 #include "BLI_utildefines.h" 00043 00044 #include "DNA_anim_types.h" 00045 #include "DNA_key_types.h" 00046 #include "DNA_lattice_types.h" 00047 #include "DNA_meshdata_types.h" 00048 #include "DNA_object_types.h" 00049 #include "DNA_scene_types.h" 00050 00051 #include "BKE_animsys.h" 00052 #include "BKE_curve.h" 00053 #include "BKE_customdata.h" 00054 #include "BKE_deform.h" 00055 #include "BKE_global.h" 00056 #include "BKE_key.h" 00057 #include "BKE_lattice.h" 00058 #include "BKE_library.h" 00059 #include "BKE_main.h" 00060 #include "BKE_object.h" 00061 #include "BKE_deform.h" 00062 #include "BKE_scene.h" 00063 00064 00065 #include "RNA_access.h" 00066 00067 #define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */ 00068 #define KEY_MODE_BPOINT 1 00069 #define KEY_MODE_BEZTRIPLE 2 00070 00071 // old defines from DNA_ipo_types.h for data-type 00072 #define IPO_FLOAT 4 00073 #define IPO_BEZTRIPLE 100 00074 #define IPO_BPOINT 101 00075 00076 int slurph_opt= 1; 00077 00078 00079 void free_key(Key *key) 00080 { 00081 KeyBlock *kb; 00082 00083 BKE_free_animdata((ID *)key); 00084 00085 while( (kb= key->block.first) ) { 00086 00087 if(kb->data) MEM_freeN(kb->data); 00088 00089 BLI_remlink(&key->block, kb); 00090 MEM_freeN(kb); 00091 } 00092 00093 } 00094 00095 /* GS reads the memory pointed at in a specific ordering. There are, 00096 * however two definitions for it. I have jotted them down here, both, 00097 * but I think the first one is actually used. The thing is that 00098 * big-endian systems might read this the wrong way round. OTOH, we 00099 * constructed the IDs that are read out with this macro explicitly as 00100 * well. I expect we'll sort it out soon... */ 00101 00102 /* from blendef: */ 00103 #define GS(a) (*((short *)(a))) 00104 00105 /* from misc_util: flip the bytes from x */ 00106 /* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */ 00107 00108 Key *add_key(ID *id) /* common function */ 00109 { 00110 Key *key; 00111 char *el; 00112 00113 key= alloc_libblock(&G.main->key, ID_KE, "Key"); 00114 00115 key->type= KEY_NORMAL; 00116 key->from= id; 00117 00118 // XXX the code here uses some defines which will soon be depreceated... 00119 if( GS(id->name)==ID_ME) { 00120 el= key->elemstr; 00121 00122 el[0]= 3; 00123 el[1]= IPO_FLOAT; 00124 el[2]= 0; 00125 00126 key->elemsize= 12; 00127 } 00128 else if( GS(id->name)==ID_LT) { 00129 el= key->elemstr; 00130 00131 el[0]= 3; 00132 el[1]= IPO_FLOAT; 00133 el[2]= 0; 00134 00135 key->elemsize= 12; 00136 } 00137 else if( GS(id->name)==ID_CU) { 00138 el= key->elemstr; 00139 00140 el[0]= 4; 00141 el[1]= IPO_BPOINT; 00142 el[2]= 0; 00143 00144 key->elemsize= 16; 00145 } 00146 00147 return key; 00148 } 00149 00150 Key *copy_key(Key *key) 00151 { 00152 Key *keyn; 00153 KeyBlock *kbn, *kb; 00154 00155 if(key==NULL) return NULL; 00156 00157 keyn= copy_libblock(&key->id); 00158 00159 BLI_duplicatelist(&keyn->block, &key->block); 00160 00161 kb= key->block.first; 00162 kbn= keyn->block.first; 00163 while(kbn) { 00164 00165 if(kbn->data) kbn->data= MEM_dupallocN(kbn->data); 00166 if(kb==key->refkey) keyn->refkey= kbn; 00167 00168 kbn= kbn->next; 00169 kb= kb->next; 00170 } 00171 00172 return keyn; 00173 } 00174 00175 void make_local_key(Key *key) 00176 { 00177 00178 /* - only lib users: do nothing 00179 * - only local users: set flag 00180 * - mixed: make copy 00181 */ 00182 if(key==NULL) return; 00183 00184 key->id.lib= NULL; 00185 new_id(NULL, &key->id, NULL); 00186 } 00187 00188 /* Sort shape keys and Ipo curves after a change. This assumes that at most 00189 * one key was moved, which is a valid assumption for the places it's 00190 * currently being called. 00191 */ 00192 00193 void sort_keys(Key *key) 00194 { 00195 KeyBlock *kb; 00196 //short i, adrcode; 00197 //IpoCurve *icu = NULL; 00198 KeyBlock *kb2; 00199 00200 /* locate the key which is out of position */ 00201 for (kb= key->block.first; kb; kb= kb->next) 00202 if ((kb->next) && (kb->pos > kb->next->pos)) 00203 break; 00204 00205 /* if we find a key, move it */ 00206 if (kb) { 00207 kb = kb->next; /* next key is the out-of-order one */ 00208 BLI_remlink(&key->block, kb); 00209 00210 /* find the right location and insert before */ 00211 for (kb2=key->block.first; kb2; kb2= kb2->next) { 00212 if (kb2->pos > kb->pos) { 00213 BLI_insertlink(&key->block, kb2->prev, kb); 00214 break; 00215 } 00216 } 00217 00218 /* if more than one Ipo curve, see if this key had a curve */ 00219 #if 0 // XXX old animation system 00220 if(key->ipo && key->ipo->curve.first != key->ipo->curve.last ) { 00221 for(icu= key->ipo->curve.first; icu; icu= icu->next) { 00222 /* if we find the curve, remove it and reinsert in the 00223 right place */ 00224 if(icu->adrcode==kb->adrcode) { 00225 IpoCurve *icu2; 00226 BLI_remlink(&key->ipo->curve, icu); 00227 for(icu2= key->ipo->curve.first; icu2; icu2= icu2->next) { 00228 if(icu2->adrcode >= kb2->adrcode) { 00229 BLI_insertlink(&key->ipo->curve, icu2->prev, icu); 00230 break; 00231 } 00232 } 00233 break; 00234 } 00235 } 00236 } 00237 00238 /* kb points at the moved key, icu at the moved ipo (if it exists). 00239 * go back now and renumber adrcodes */ 00240 00241 /* first new code */ 00242 adrcode = kb2->adrcode; 00243 for (i = kb->adrcode - adrcode; i >= 0; i--, adrcode++) { 00244 /* if the next ipo curve matches the current key, renumber it */ 00245 if(icu && icu->adrcode == kb->adrcode ) { 00246 icu->adrcode = adrcode; 00247 icu = icu->next; 00248 } 00249 /* renumber the shape key */ 00250 kb->adrcode = adrcode; 00251 kb = kb->next; 00252 } 00253 #endif // XXX old animation system 00254 } 00255 00256 /* new rule; first key is refkey, this to match drawing channels... */ 00257 key->refkey= key->block.first; 00258 } 00259 00260 /**************** do the key ****************/ 00261 00262 void key_curve_position_weights(float t, float *data, int type) 00263 { 00264 float t2, t3, fc; 00265 00266 if(type==KEY_LINEAR) { 00267 data[0]= 0.0f; 00268 data[1]= -t + 1.0f; 00269 data[2]= t; 00270 data[3]= 0.0f; 00271 } 00272 else if(type==KEY_CARDINAL) { 00273 t2= t*t; 00274 t3= t2*t; 00275 fc= 0.71f; 00276 00277 data[0]= -fc*t3 + 2.0f*fc*t2 - fc*t; 00278 data[1]= (2.0f-fc)*t3 + (fc-3.0f)*t2 + 1.0f; 00279 data[2]= (fc-2.0f)*t3 + (3.0f-2.0f*fc)*t2 + fc*t; 00280 data[3]= fc*t3 - fc*t2; 00281 } 00282 else if(type==KEY_BSPLINE) { 00283 t2= t*t; 00284 t3= t2*t; 00285 00286 data[0]= -0.16666666f*t3 + 0.5f*t2 - 0.5f*t + 0.16666666f; 00287 data[1]= 0.5f*t3 - t2 + 0.6666666f; 00288 data[2]= -0.5f*t3 + 0.5f*t2 + 0.5f*t + 0.16666666f; 00289 data[3]= 0.16666666f*t3; 00290 } 00291 } 00292 00293 /* first derivative */ 00294 void key_curve_tangent_weights(float t, float *data, int type) 00295 { 00296 float t2, fc; 00297 00298 if(type==KEY_LINEAR) { 00299 data[0]= 0.0f; 00300 data[1]= -1.0f; 00301 data[2]= 1.0f; 00302 data[3]= 0.0f; 00303 } 00304 else if(type==KEY_CARDINAL) { 00305 t2= t*t; 00306 fc= 0.71f; 00307 00308 data[0]= -3.0f*fc*t2 +4.0f*fc*t - fc; 00309 data[1]= 3.0f*(2.0f-fc)*t2 +2.0f*(fc-3.0f)*t; 00310 data[2]= 3.0f*(fc-2.0f)*t2 +2.0f*(3.0f-2.0f*fc)*t + fc; 00311 data[3]= 3.0f*fc*t2 -2.0f*fc*t; 00312 } 00313 else if(type==KEY_BSPLINE) { 00314 t2= t*t; 00315 00316 data[0]= -0.5f*t2 + t - 0.5f; 00317 data[1]= 1.5f*t2 - 2.0f*t; 00318 data[2]= -1.5f*t2 + t + 0.5f; 00319 data[3]= 0.5f*t2; 00320 } 00321 } 00322 00323 /* second derivative */ 00324 void key_curve_normal_weights(float t, float *data, int type) 00325 { 00326 float fc; 00327 00328 if(type==KEY_LINEAR) { 00329 data[0]= 0.0f; 00330 data[1]= 0.0f; 00331 data[2]= 0.0f; 00332 data[3]= 0.0f; 00333 } 00334 else if(type==KEY_CARDINAL) { 00335 fc= 0.71f; 00336 00337 data[0]= -6.0f*fc*t + 4.0f*fc; 00338 data[1]= 6.0f*(2.0f-fc)*t + 2.0f*(fc-3.0f); 00339 data[2]= 6.0f*(fc-2.0f)*t + 2.0f*(3.0f-2.0f*fc); 00340 data[3]= 6.0f*fc*t - 2.0f*fc; 00341 } 00342 else if(type==KEY_BSPLINE) { 00343 data[0]= -1.0f*t + 1.0f; 00344 data[1]= 3.0f*t - 2.0f; 00345 data[2]= -3.0f*t + 1.0f; 00346 data[3]= 1.0f*t; 00347 } 00348 } 00349 00350 static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl) 00351 { 00352 /* return 1 means k[2] is the position, return 0 means interpolate */ 00353 KeyBlock *k1, *firstkey; 00354 float d, dpos, ofs=0, lastpos, temp, fval[4]; 00355 short bsplinetype; 00356 00357 firstkey= lb->first; 00358 k1= lb->last; 00359 lastpos= k1->pos; 00360 dpos= lastpos - firstkey->pos; 00361 00362 if(fac < firstkey->pos) fac= firstkey->pos; 00363 else if(fac > k1->pos) fac= k1->pos; 00364 00365 k1=k[0]=k[1]=k[2]=k[3]= firstkey; 00366 t[0]=t[1]=t[2]=t[3]= k1->pos; 00367 00368 /* if(fac<0.0 || fac>1.0) return 1; */ 00369 00370 if(k1->next==NULL) return 1; 00371 00372 if(cycl) { /* pre-sort */ 00373 k[2]= k1->next; 00374 k[3]= k[2]->next; 00375 if(k[3]==NULL) k[3]=k1; 00376 while(k1) { 00377 if(k1->next==NULL) k[0]=k1; 00378 k1=k1->next; 00379 } 00380 k1= k[1]; 00381 t[0]= k[0]->pos; 00382 t[1]+= dpos; 00383 t[2]= k[2]->pos + dpos; 00384 t[3]= k[3]->pos + dpos; 00385 fac+= dpos; 00386 ofs= dpos; 00387 if(k[3]==k[1]) { 00388 t[3]+= dpos; 00389 ofs= 2.0f*dpos; 00390 } 00391 if(fac<t[1]) fac+= dpos; 00392 k1= k[3]; 00393 } 00394 else { /* pre-sort */ 00395 k[2]= k1->next; 00396 t[2]= k[2]->pos; 00397 k[3]= k[2]->next; 00398 if(k[3]==NULL) k[3]= k[2]; 00399 t[3]= k[3]->pos; 00400 k1= k[3]; 00401 } 00402 00403 while( t[2]<fac ) { /* find correct location */ 00404 if(k1->next==NULL) { 00405 if(cycl) { 00406 k1= firstkey; 00407 ofs+= dpos; 00408 } 00409 else if(t[2]==t[3]) break; 00410 } 00411 else k1= k1->next; 00412 00413 t[0]= t[1]; 00414 k[0]= k[1]; 00415 t[1]= t[2]; 00416 k[1]= k[2]; 00417 t[2]= t[3]; 00418 k[2]= k[3]; 00419 t[3]= k1->pos+ofs; 00420 k[3]= k1; 00421 00422 if(ofs > 2.1f + lastpos) break; 00423 } 00424 00425 bsplinetype= 0; 00426 if(k[1]->type==KEY_BSPLINE || k[2]->type==KEY_BSPLINE) bsplinetype= 1; 00427 00428 00429 if(cycl==0) { 00430 if(bsplinetype==0) { /* B spline doesn't go through the control points */ 00431 if(fac<=t[1]) { /* fac for 1st key */ 00432 t[2]= t[1]; 00433 k[2]= k[1]; 00434 return 1; 00435 } 00436 if(fac>=t[2] ) { /* fac after 2nd key */ 00437 return 1; 00438 } 00439 } 00440 else if(fac>t[2]) { /* last key */ 00441 fac= t[2]; 00442 k[3]= k[2]; 00443 t[3]= t[2]; 00444 } 00445 } 00446 00447 d= t[2]-t[1]; 00448 if(d == 0.0f) { 00449 if(bsplinetype==0) { 00450 return 1; /* both keys equal */ 00451 } 00452 } 00453 else d= (fac-t[1])/d; 00454 00455 /* interpolation */ 00456 00457 key_curve_position_weights(d, t, k[1]->type); 00458 00459 if(k[1]->type != k[2]->type) { 00460 key_curve_position_weights(d, fval, k[2]->type); 00461 00462 temp= 1.0f-d; 00463 t[0]= temp*t[0]+ d*fval[0]; 00464 t[1]= temp*t[1]+ d*fval[1]; 00465 t[2]= temp*t[2]+ d*fval[2]; 00466 t[3]= temp*t[3]+ d*fval[3]; 00467 } 00468 00469 return 0; 00470 00471 } 00472 00473 static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3, float *t) 00474 { 00475 int a; 00476 00477 for(a=0; a<tot; a++) { 00478 in[a]= t[0]*f0[a]+t[1]*f1[a]+t[2]*f2[a]+t[3]*f3[a]; 00479 } 00480 } 00481 00482 static void rel_flerp(int tot, float *in, float *ref, float *out, float fac) 00483 { 00484 int a; 00485 00486 for(a=0; a<tot; a++) { 00487 in[a]-= fac*(ref[a]-out[a]); 00488 } 00489 } 00490 00491 static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata) 00492 { 00493 if(kb == actkb) { 00494 /* this hack makes it possible to edit shape keys in 00495 edit mode with shape keys blending applied */ 00496 if(GS(key->from->name) == ID_ME) { 00497 Mesh *me; 00498 EditVert *eve; 00499 float (*co)[3]; 00500 int a; 00501 00502 me= (Mesh*)key->from; 00503 00504 if(me->edit_mesh && me->edit_mesh->totvert == kb->totelem) { 00505 a= 0; 00506 co= MEM_callocN(sizeof(float)*3*me->edit_mesh->totvert, "key_block_get_data"); 00507 00508 for(eve=me->edit_mesh->verts.first; eve; eve=eve->next, a++) 00509 copy_v3_v3(co[a], eve->co); 00510 00511 *freedata= (char*)co; 00512 return (char*)co; 00513 } 00514 } 00515 } 00516 00517 *freedata= NULL; 00518 return kb->data; 00519 } 00520 00521 00522 /* currently only the first value of 'ofs' may be set. */ 00523 static short key_pointer_size(const Key *key, const int mode, int *poinsize, int *ofs) 00524 { 00525 if(key->from==NULL) { 00526 return FALSE; 00527 } 00528 00529 switch(GS(key->from->name)) { 00530 case ID_ME: 00531 *ofs= sizeof(float)*3; 00532 *poinsize= *ofs; 00533 break; 00534 case ID_LT: 00535 *ofs= sizeof(float)*3; 00536 *poinsize= *ofs; 00537 break; 00538 case ID_CU: 00539 if(mode == KEY_MODE_BPOINT) { 00540 *ofs= sizeof(float)*4; 00541 *poinsize= *ofs; 00542 } else { 00543 ofs[0]= sizeof(float)*12; 00544 *poinsize= (*ofs) / 3; 00545 } 00546 00547 break; 00548 default: 00549 BLI_assert(!"invalid 'key->from' ID type"); 00550 return FALSE; 00551 } 00552 00553 return TRUE; 00554 } 00555 00556 static void cp_key(const int start, int end, const int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, const int mode) 00557 { 00558 float ktot = 0.0, kd = 0.0; 00559 int elemsize, poinsize = 0, a, *ofsp, ofs[32], flagflo=0; 00560 char *k1, *kref, *freek1, *freekref; 00561 char *cp, elemstr[8]; 00562 00563 /* currently always 0, in future key_pointer_size may assign */ 00564 ofs[1]= 0; 00565 00566 if(!key_pointer_size(key, mode, &poinsize, &ofs[0])) 00567 return; 00568 00569 if(end>tot) end= tot; 00570 00571 if(tot != kb->totelem) { 00572 ktot= 0.0; 00573 flagflo= 1; 00574 if(kb->totelem) { 00575 kd= kb->totelem/(float)tot; 00576 } 00577 else return; 00578 } 00579 00580 k1= key_block_get_data(key, actkb, kb, &freek1); 00581 kref= key_block_get_data(key, actkb, key->refkey, &freekref); 00582 00583 /* this exception is needed for slurphing */ 00584 if(start!=0) { 00585 00586 poin+= poinsize*start; 00587 00588 if(flagflo) { 00589 ktot+= start*kd; 00590 a= (int)floor(ktot); 00591 if(a) { 00592 ktot-= a; 00593 k1+= a*key->elemsize; 00594 } 00595 } 00596 else k1+= start*key->elemsize; 00597 } 00598 00599 if(mode == KEY_MODE_BEZTRIPLE) { 00600 elemstr[0]= 1; 00601 elemstr[1]= IPO_BEZTRIPLE; 00602 elemstr[2]= 0; 00603 } 00604 00605 /* just do it here, not above! */ 00606 elemsize= key->elemsize; 00607 if(mode == KEY_MODE_BEZTRIPLE) elemsize*= 3; 00608 00609 for(a=start; a<end; a++) { 00610 cp= key->elemstr; 00611 if(mode == KEY_MODE_BEZTRIPLE) cp= elemstr; 00612 00613 ofsp= ofs; 00614 00615 while( cp[0] ) { 00616 00617 switch(cp[1]) { 00618 case IPO_FLOAT: 00619 if(weights) { 00620 memcpy(poin, kref, sizeof(float)*3); 00621 if(*weights!=0.0f) 00622 rel_flerp(cp[0], (float *)poin, (float *)kref, (float *)k1, *weights); 00623 weights++; 00624 } 00625 else 00626 memcpy(poin, k1, sizeof(float)*3); 00627 break; 00628 case IPO_BPOINT: 00629 memcpy(poin, k1, sizeof(float)*4); 00630 break; 00631 case IPO_BEZTRIPLE: 00632 memcpy(poin, k1, sizeof(float)*12); 00633 break; 00634 default: 00635 /* should never happen */ 00636 if(freek1) MEM_freeN(freek1); 00637 if(freekref) MEM_freeN(freekref); 00638 BLI_assert(!"invalid 'cp[1]'"); 00639 return; 00640 } 00641 00642 poin+= ofsp[0]; 00643 cp+= 2; ofsp++; 00644 } 00645 00646 /* are we going to be nasty? */ 00647 if(flagflo) { 00648 ktot+= kd; 00649 while(ktot >= 1.0f) { 00650 ktot -= 1.0f; 00651 k1+= elemsize; 00652 kref+= elemsize; 00653 } 00654 } 00655 else { 00656 k1+= elemsize; 00657 kref+= elemsize; 00658 } 00659 00660 if(mode == KEY_MODE_BEZTRIPLE) a+=2; 00661 } 00662 00663 if(freek1) MEM_freeN(freek1); 00664 if(freekref) MEM_freeN(freekref); 00665 } 00666 00667 static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const int start, int end, char *out, const int tot) 00668 { 00669 Nurb *nu; 00670 int a, step, a1, a2; 00671 00672 for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { 00673 if(nu->bp) { 00674 step= nu->pntsu*nu->pntsv; 00675 00676 a1= MAX2(a, start); 00677 a2= MIN2(a+step, end); 00678 00679 if(a1<a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BPOINT); 00680 } 00681 else if(nu->bezt) { 00682 step= 3*nu->pntsu; 00683 00684 /* exception because keys prefer to work with complete blocks */ 00685 a1= MAX2(a, start); 00686 a2= MIN2(a+step, end); 00687 00688 if(a1<a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BEZTRIPLE); 00689 } 00690 else 00691 step= 0; 00692 } 00693 } 00694 00695 void do_rel_key(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, const int mode) 00696 { 00697 KeyBlock *kb; 00698 int *ofsp, ofs[3], elemsize, b; 00699 char *cp, *poin, *reffrom, *from, elemstr[8]; 00700 char *freefrom, *freereffrom; 00701 int poinsize; 00702 00703 /* currently always 0, in future key_pointer_size may assign */ 00704 ofs[1]= 0; 00705 00706 if(!key_pointer_size(key, mode, &poinsize, &ofs[0])) 00707 return; 00708 00709 if(end>tot) end= tot; 00710 00711 /* in case of beztriple */ 00712 elemstr[0]= 1; /* nr of ipofloats */ 00713 elemstr[1]= IPO_BEZTRIPLE; 00714 elemstr[2]= 0; 00715 00716 /* just here, not above! */ 00717 elemsize= key->elemsize; 00718 if(mode == KEY_MODE_BEZTRIPLE) elemsize*= 3; 00719 00720 /* step 1 init */ 00721 cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode); 00722 00723 /* step 2: do it */ 00724 00725 for(kb=key->block.first; kb; kb=kb->next) { 00726 if(kb!=key->refkey) { 00727 float icuval= kb->curval; 00728 00729 /* only with value, and no difference allowed */ 00730 if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) { 00731 KeyBlock *refb; 00732 float weight, *weights= kb->weights; 00733 00734 /* reference now can be any block */ 00735 refb= BLI_findlink(&key->block, kb->relative); 00736 if(refb==NULL) continue; 00737 00738 poin= basispoin; 00739 from= key_block_get_data(key, actkb, kb, &freefrom); 00740 reffrom= key_block_get_data(key, actkb, refb, &freereffrom); 00741 00742 poin+= start*poinsize; 00743 reffrom+= key->elemsize*start; // key elemsize yes! 00744 from+= key->elemsize*start; 00745 00746 for(b=start; b<end; b++) { 00747 00748 if(weights) 00749 weight= *weights * icuval; 00750 else 00751 weight= icuval; 00752 00753 cp= key->elemstr; 00754 if(mode == KEY_MODE_BEZTRIPLE) cp= elemstr; 00755 00756 ofsp= ofs; 00757 00758 while( cp[0] ) { /* cp[0]==amount */ 00759 00760 switch(cp[1]) { 00761 case IPO_FLOAT: 00762 rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, weight); 00763 break; 00764 case IPO_BPOINT: 00765 rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight); 00766 break; 00767 case IPO_BEZTRIPLE: 00768 rel_flerp(12, (float *)poin, (float *)reffrom, (float *)from, weight); 00769 break; 00770 default: 00771 /* should never happen */ 00772 if(freefrom) MEM_freeN(freefrom); 00773 if(freereffrom) MEM_freeN(freereffrom); 00774 BLI_assert(!"invalid 'cp[1]'"); 00775 return; 00776 } 00777 00778 poin+= ofsp[0]; 00779 00780 cp+= 2; 00781 ofsp++; 00782 } 00783 00784 reffrom+= elemsize; 00785 from+= elemsize; 00786 00787 if(mode == KEY_MODE_BEZTRIPLE) b+= 2; 00788 if(weights) weights++; 00789 } 00790 00791 if(freefrom) MEM_freeN(freefrom); 00792 if(freereffrom) MEM_freeN(freereffrom); 00793 } 00794 } 00795 } 00796 } 00797 00798 00799 static void do_key(const int start, int end, const int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, const int mode) 00800 { 00801 float k1tot = 0.0, k2tot = 0.0, k3tot = 0.0, k4tot = 0.0; 00802 float k1d = 0.0, k2d = 0.0, k3d = 0.0, k4d = 0.0; 00803 int a, ofs[32], *ofsp; 00804 int flagdo= 15, flagflo=0, elemsize, poinsize=0; 00805 char *k1, *k2, *k3, *k4, *freek1, *freek2, *freek3, *freek4; 00806 char *cp, elemstr[8]; 00807 00808 /* currently always 0, in future key_pointer_size may assign */ 00809 ofs[1]= 0; 00810 00811 if(!key_pointer_size(key, mode, &poinsize, &ofs[0])) 00812 return; 00813 00814 if(end>tot) end= tot; 00815 00816 k1= key_block_get_data(key, actkb, k[0], &freek1); 00817 k2= key_block_get_data(key, actkb, k[1], &freek2); 00818 k3= key_block_get_data(key, actkb, k[2], &freek3); 00819 k4= key_block_get_data(key, actkb, k[3], &freek4); 00820 00821 /* test for more or less points (per key!) */ 00822 if(tot != k[0]->totelem) { 00823 k1tot= 0.0; 00824 flagflo |= 1; 00825 if(k[0]->totelem) { 00826 k1d= k[0]->totelem/(float)tot; 00827 } 00828 else flagdo -= 1; 00829 } 00830 if(tot != k[1]->totelem) { 00831 k2tot= 0.0; 00832 flagflo |= 2; 00833 if(k[0]->totelem) { 00834 k2d= k[1]->totelem/(float)tot; 00835 } 00836 else flagdo -= 2; 00837 } 00838 if(tot != k[2]->totelem) { 00839 k3tot= 0.0; 00840 flagflo |= 4; 00841 if(k[0]->totelem) { 00842 k3d= k[2]->totelem/(float)tot; 00843 } 00844 else flagdo -= 4; 00845 } 00846 if(tot != k[3]->totelem) { 00847 k4tot= 0.0; 00848 flagflo |= 8; 00849 if(k[0]->totelem) { 00850 k4d= k[3]->totelem/(float)tot; 00851 } 00852 else flagdo -= 8; 00853 } 00854 00855 /* this exception needed for slurphing */ 00856 if(start!=0) { 00857 00858 poin+= poinsize*start; 00859 00860 if(flagdo & 1) { 00861 if(flagflo & 1) { 00862 k1tot+= start*k1d; 00863 a= (int)floor(k1tot); 00864 if(a) { 00865 k1tot-= a; 00866 k1+= a*key->elemsize; 00867 } 00868 } 00869 else k1+= start*key->elemsize; 00870 } 00871 if(flagdo & 2) { 00872 if(flagflo & 2) { 00873 k2tot+= start*k2d; 00874 a= (int)floor(k2tot); 00875 if(a) { 00876 k2tot-= a; 00877 k2+= a*key->elemsize; 00878 } 00879 } 00880 else k2+= start*key->elemsize; 00881 } 00882 if(flagdo & 4) { 00883 if(flagflo & 4) { 00884 k3tot+= start*k3d; 00885 a= (int)floor(k3tot); 00886 if(a) { 00887 k3tot-= a; 00888 k3+= a*key->elemsize; 00889 } 00890 } 00891 else k3+= start*key->elemsize; 00892 } 00893 if(flagdo & 8) { 00894 if(flagflo & 8) { 00895 k4tot+= start*k4d; 00896 a= (int)floor(k4tot); 00897 if(a) { 00898 k4tot-= a; 00899 k4+= a*key->elemsize; 00900 } 00901 } 00902 else k4+= start*key->elemsize; 00903 } 00904 00905 } 00906 00907 /* in case of beztriple */ 00908 elemstr[0]= 1; /* nr of ipofloats */ 00909 elemstr[1]= IPO_BEZTRIPLE; 00910 elemstr[2]= 0; 00911 00912 /* only here, not above! */ 00913 elemsize= key->elemsize; 00914 if(mode == KEY_MODE_BEZTRIPLE) elemsize*= 3; 00915 00916 for(a=start; a<end; a++) { 00917 00918 cp= key->elemstr; 00919 if(mode == KEY_MODE_BEZTRIPLE) cp= elemstr; 00920 00921 ofsp= ofs; 00922 00923 while( cp[0] ) { /* cp[0]==amount */ 00924 00925 switch(cp[1]) { 00926 case IPO_FLOAT: 00927 flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t); 00928 break; 00929 case IPO_BPOINT: 00930 flerp(4, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t); 00931 break; 00932 case IPO_BEZTRIPLE: 00933 flerp(12, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t); 00934 break; 00935 default: 00936 /* should never happen */ 00937 if(freek1) MEM_freeN(freek1); 00938 if(freek2) MEM_freeN(freek2); 00939 if(freek3) MEM_freeN(freek3); 00940 if(freek4) MEM_freeN(freek4); 00941 BLI_assert(!"invalid 'cp[1]'"); 00942 return; 00943 } 00944 00945 poin+= ofsp[0]; 00946 cp+= 2; 00947 ofsp++; 00948 } 00949 /* lets do it the difficult way: when keys have a different size */ 00950 if(flagdo & 1) { 00951 if(flagflo & 1) { 00952 k1tot+= k1d; 00953 while(k1tot >= 1.0f) { 00954 k1tot -= 1.0f; 00955 k1+= elemsize; 00956 } 00957 } 00958 else k1+= elemsize; 00959 } 00960 if(flagdo & 2) { 00961 if(flagflo & 2) { 00962 k2tot+= k2d; 00963 while(k2tot >= 1.0f) { 00964 k2tot -= 1.0f; 00965 k2+= elemsize; 00966 } 00967 } 00968 else k2+= elemsize; 00969 } 00970 if(flagdo & 4) { 00971 if(flagflo & 4) { 00972 k3tot+= k3d; 00973 while(k3tot >= 1.0f) { 00974 k3tot -= 1.0f; 00975 k3+= elemsize; 00976 } 00977 } 00978 else k3+= elemsize; 00979 } 00980 if(flagdo & 8) { 00981 if(flagflo & 8) { 00982 k4tot+= k4d; 00983 while(k4tot >= 1.0f) { 00984 k4tot -= 1.0f; 00985 k4+= elemsize; 00986 } 00987 } 00988 else k4+= elemsize; 00989 } 00990 00991 if(mode == KEY_MODE_BEZTRIPLE) a+= 2; 00992 } 00993 00994 if(freek1) MEM_freeN(freek1); 00995 if(freek2) MEM_freeN(freek2); 00996 if(freek3) MEM_freeN(freek3); 00997 if(freek4) MEM_freeN(freek4); 00998 } 00999 01000 static float *get_weights_array(Object *ob, char *vgroup) 01001 { 01002 MDeformVert *dvert= NULL; 01003 EditMesh *em= NULL; 01004 EditVert *eve; 01005 int totvert= 0, defgrp_index= 0; 01006 01007 /* no vgroup string set? */ 01008 if(vgroup[0]==0) return NULL; 01009 01010 /* gather dvert and totvert */ 01011 if(ob->type==OB_MESH) { 01012 Mesh *me= ob->data; 01013 dvert= me->dvert; 01014 totvert= me->totvert; 01015 01016 if(me->edit_mesh && me->edit_mesh->totvert == totvert) 01017 em= me->edit_mesh; 01018 } 01019 else if(ob->type==OB_LATTICE) { 01020 Lattice *lt= ob->data; 01021 dvert= lt->dvert; 01022 totvert= lt->pntsu*lt->pntsv*lt->pntsw; 01023 } 01024 01025 if(dvert==NULL) return NULL; 01026 01027 /* find the group (weak loop-in-loop) */ 01028 defgrp_index= defgroup_name_index(ob, vgroup); 01029 if(defgrp_index >= 0) { 01030 float *weights; 01031 int i; 01032 01033 weights= MEM_callocN(totvert*sizeof(float), "weights"); 01034 01035 if(em) { 01036 for(i=0, eve=em->verts.first; eve; eve=eve->next, i++) { 01037 dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); 01038 01039 if(dvert) { 01040 weights[i]= defvert_find_weight(dvert, defgrp_index); 01041 } 01042 } 01043 } 01044 else { 01045 for(i=0; i < totvert; i++, dvert++) { 01046 weights[i]= defvert_find_weight(dvert, defgrp_index); 01047 } 01048 } 01049 01050 return weights; 01051 } 01052 return NULL; 01053 } 01054 01055 static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int tot) 01056 { 01057 KeyBlock *k[4], *actkb= ob_get_keyblock(ob); 01058 float cfra, ctime, t[4], delta; 01059 int a, flag = 0, step; 01060 01061 if(key->slurph && key->type!=KEY_RELATIVE ) { 01062 delta= key->slurph; 01063 delta/= tot; 01064 01065 step= 1; 01066 if(tot>100 && slurph_opt) { 01067 step= tot/50; 01068 delta*= step; 01069 /* in do_key and cp_key the case a>tot is handled */ 01070 } 01071 01072 cfra= (float)scene->r.cfra; 01073 01074 for(a=0; a<tot; a+=step, cfra+= delta) { 01075 01076 ctime= BKE_curframe(scene); 01077 #if 0 // XXX old animation system 01078 if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { 01079 ctime /= 100.0; 01080 CLAMP(ctime, 0.0, 1.0); 01081 } 01082 #endif // XXX old animation system 01083 // XXX for now... since speed curve cannot be directly ported yet 01084 ctime /= 100.0f; 01085 CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing 01086 01087 flag= setkeys(ctime, &key->block, k, t, 0); 01088 01089 if(flag==0) 01090 do_key(a, a+step, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY); 01091 else 01092 cp_key(a, a+step, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY); 01093 } 01094 } 01095 else { 01096 if(key->type==KEY_RELATIVE) { 01097 KeyBlock *kb; 01098 01099 for(kb= key->block.first; kb; kb= kb->next) 01100 kb->weights= get_weights_array(ob, kb->vgroup); 01101 01102 do_rel_key(0, tot, tot, (char *)out, key, actkb, KEY_MODE_DUMMY); 01103 01104 for(kb= key->block.first; kb; kb= kb->next) { 01105 if(kb->weights) MEM_freeN(kb->weights); 01106 kb->weights= NULL; 01107 } 01108 } 01109 else { 01110 ctime= BKE_curframe(scene); 01111 01112 #if 0 // XXX old animation system 01113 if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { 01114 ctime /= 100.0; 01115 CLAMP(ctime, 0.0, 1.0); 01116 } 01117 #endif // XXX old animation system 01118 // XXX for now... since speed curve cannot be directly ported yet 01119 ctime /= 100.0f; 01120 CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing 01121 01122 flag= setkeys(ctime, &key->block, k, t, 0); 01123 01124 if(flag==0) 01125 do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY); 01126 else 01127 cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY); 01128 } 01129 } 01130 } 01131 01132 static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, const int tot) 01133 { 01134 Nurb *nu; 01135 int a, step; 01136 01137 for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { 01138 if(nu->bp) { 01139 step= nu->pntsu*nu->pntsv; 01140 do_key(a, a+step, tot, out, key, actkb, k, t, KEY_MODE_BPOINT); 01141 } 01142 else if(nu->bezt) { 01143 step= 3*nu->pntsu; 01144 do_key(a, a+step, tot, out, key, actkb, k, t, KEY_MODE_BEZTRIPLE); 01145 } 01146 else 01147 step= 0; 01148 } 01149 } 01150 01151 static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, float UNUSED(ctime), char *out, const int tot) 01152 { 01153 Nurb *nu; 01154 int a, step; 01155 01156 for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { 01157 if(nu->bp) { 01158 step= nu->pntsu*nu->pntsv; 01159 do_rel_key(a, a+step, tot, out, key, actkb, KEY_MODE_BPOINT); 01160 } 01161 else if(nu->bezt) { 01162 step= 3*nu->pntsu; 01163 do_rel_key(a, a+step, tot, out, key, actkb, KEY_MODE_BEZTRIPLE); 01164 } 01165 else 01166 step= 0; 01167 } 01168 } 01169 01170 static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const int tot) 01171 { 01172 Curve *cu= ob->data; 01173 KeyBlock *k[4], *actkb= ob_get_keyblock(ob); 01174 float cfra, ctime, t[4], delta; 01175 int a, flag = 0, step = 0; 01176 01177 if(key->slurph && key->type!=KEY_RELATIVE) { 01178 Nurb *nu; 01179 int mode=0, i= 0, remain= 0, estep=0, count=0; 01180 01181 delta= (float)key->slurph / tot; 01182 01183 step= 1; 01184 if(tot>100 && slurph_opt) { 01185 step= tot/50; 01186 delta*= step; 01187 /* in do_key and cp_key the case a>tot has been handled */ 01188 } 01189 01190 cfra= (float)scene->r.cfra; 01191 01192 for(nu=cu->nurb.first; nu; nu=nu->next) { 01193 if(nu->bp) { 01194 mode= KEY_MODE_BPOINT; 01195 estep= nu->pntsu*nu->pntsv; 01196 } 01197 else if(nu->bezt) { 01198 mode= KEY_MODE_BEZTRIPLE; 01199 estep= 3*nu->pntsu; 01200 } 01201 else 01202 step= 0; 01203 01204 a= 0; 01205 while (a < estep) { 01206 if (remain <= 0) { 01207 cfra+= delta; 01208 ctime= BKE_curframe(scene); 01209 01210 ctime /= 100.0f; 01211 CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing 01212 flag= setkeys(ctime, &key->block, k, t, 0); 01213 01214 remain= step; 01215 } 01216 01217 count= MIN2(remain, estep); 01218 if (mode == KEY_MODE_BEZTRIPLE) { 01219 count += 3 - count % 3; 01220 } 01221 01222 if(flag==0) 01223 do_key(i, i+count, tot, (char *)out, key, actkb, k, t, mode); 01224 else 01225 cp_key(i, i+count, tot, (char *)out, key, actkb, k[2], NULL, mode); 01226 01227 a += count; 01228 i += count; 01229 remain -= count; 01230 } 01231 } 01232 } 01233 else { 01234 01235 ctime= BKE_curframe(scene); 01236 01237 if(key->type==KEY_RELATIVE) { 01238 do_rel_cu_key(cu, cu->key, actkb, ctime, out, tot); 01239 } 01240 else { 01241 #if 0 // XXX old animation system 01242 if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { 01243 ctime /= 100.0; 01244 CLAMP(ctime, 0.0, 1.0); 01245 } 01246 #endif // XXX old animation system 01247 01248 flag= setkeys(ctime, &key->block, k, t, 0); 01249 01250 if(flag==0) do_cu_key(cu, key, actkb, k, t, out, tot); 01251 else cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot); 01252 } 01253 } 01254 } 01255 01256 static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int tot) 01257 { 01258 Lattice *lt= ob->data; 01259 KeyBlock *k[4], *actkb= ob_get_keyblock(ob); 01260 float delta, cfra, ctime, t[4]; 01261 int a, flag; 01262 01263 if(key->slurph) { 01264 delta= key->slurph; 01265 delta/= (float)tot; 01266 01267 cfra= (float)scene->r.cfra; 01268 01269 for(a=0; a<tot; a++, cfra+= delta) { 01270 01271 ctime= BKE_curframe(scene); 01272 #if 0 // XXX old animation system 01273 if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { 01274 ctime /= 100.0; 01275 CLAMP(ctime, 0.0, 1.0); 01276 } 01277 #endif // XXX old animation system 01278 01279 flag= setkeys(ctime, &key->block, k, t, 0); 01280 01281 if(flag==0) 01282 do_key(a, a+1, tot, out, key, actkb, k, t, KEY_MODE_DUMMY); 01283 else 01284 cp_key(a, a+1, tot, out, key, actkb, k[2], NULL, KEY_MODE_DUMMY); 01285 } 01286 } 01287 else { 01288 if(key->type==KEY_RELATIVE) { 01289 KeyBlock *kb; 01290 01291 for(kb= key->block.first; kb; kb= kb->next) 01292 kb->weights= get_weights_array(ob, kb->vgroup); 01293 01294 do_rel_key(0, tot, tot, out, key, actkb, KEY_MODE_DUMMY); 01295 01296 for(kb= key->block.first; kb; kb= kb->next) { 01297 if(kb->weights) MEM_freeN(kb->weights); 01298 kb->weights= NULL; 01299 } 01300 } 01301 else { 01302 ctime= BKE_curframe(scene); 01303 01304 #if 0 // XXX old animation system 01305 if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { 01306 ctime /= 100.0; 01307 CLAMP(ctime, 0.0, 1.0); 01308 } 01309 #endif // XXX old animation system 01310 01311 flag= setkeys(ctime, &key->block, k, t, 0); 01312 01313 if(flag==0) 01314 do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY); 01315 else 01316 cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY); 01317 } 01318 } 01319 01320 if(lt->flag & LT_OUTSIDE) outside_lattice(lt); 01321 } 01322 01323 /* returns key coordinates (+ tilt) when key applied, NULL otherwise */ 01324 float *do_ob_key(Scene *scene, Object *ob) 01325 { 01326 Key *key= ob_get_key(ob); 01327 KeyBlock *actkb= ob_get_keyblock(ob); 01328 char *out; 01329 int tot= 0, size= 0; 01330 01331 if(key==NULL || key->block.first==NULL) 01332 return NULL; 01333 01334 /* compute size of output array */ 01335 if(ob->type == OB_MESH) { 01336 Mesh *me= ob->data; 01337 01338 tot= me->totvert; 01339 size= tot*3*sizeof(float); 01340 } 01341 else if(ob->type == OB_LATTICE) { 01342 Lattice *lt= ob->data; 01343 01344 tot= lt->pntsu*lt->pntsv*lt->pntsw; 01345 size= tot*3*sizeof(float); 01346 } 01347 else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { 01348 Curve *cu= ob->data; 01349 Nurb *nu; 01350 01351 for(nu=cu->nurb.first; nu; nu=nu->next) { 01352 if(nu->bezt) { 01353 tot += 3*nu->pntsu; 01354 size += nu->pntsu*12*sizeof(float); 01355 } 01356 else if(nu->bp) { 01357 tot += nu->pntsu*nu->pntsv; 01358 size += nu->pntsu*nu->pntsv*12*sizeof(float); 01359 } 01360 } 01361 } 01362 01363 /* if nothing to interpolate, cancel */ 01364 if(tot == 0 || size == 0) 01365 return NULL; 01366 01367 /* allocate array */ 01368 out= MEM_callocN(size, "do_ob_key out"); 01369 01370 /* prevent python from screwing this up? anyhoo, the from pointer could be dropped */ 01371 key->from= (ID *)ob->data; 01372 01373 if(ob->shapeflag & OB_SHAPE_LOCK) { 01374 /* shape locked, copy the locked shape instead of blending */ 01375 KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1); 01376 01377 if(kb && (kb->flag & KEYBLOCK_MUTE)) 01378 kb= key->refkey; 01379 01380 if(kb==NULL) { 01381 kb= key->block.first; 01382 ob->shapenr= 1; 01383 } 01384 01385 if (OB_TYPE_SUPPORT_VGROUP(ob->type)) { 01386 float *weights= get_weights_array(ob, kb->vgroup); 01387 01388 cp_key(0, tot, tot, out, key, actkb, kb, weights, 0); 01389 01390 if(weights) MEM_freeN(weights); 01391 } 01392 else if(ELEM(ob->type, OB_CURVE, OB_SURF)) 01393 cp_cu_key(ob->data, key, actkb, kb, 0, tot, out, tot); 01394 } 01395 else { 01396 /* do shapekey local drivers */ 01397 float ctime= (float)scene->r.cfra; // XXX this needs to be checked 01398 01399 BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS); 01400 01401 if(ob->type==OB_MESH) do_mesh_key(scene, ob, key, out, tot); 01402 else if(ob->type==OB_LATTICE) do_latt_key(scene, ob, key, out, tot); 01403 else if(ob->type==OB_CURVE) do_curve_key(scene, ob, key, out, tot); 01404 else if(ob->type==OB_SURF) do_curve_key(scene, ob, key, out, tot); 01405 } 01406 01407 return (float*)out; 01408 } 01409 01410 Key *ob_get_key(Object *ob) 01411 { 01412 if(ob==NULL) return NULL; 01413 01414 if(ob->type==OB_MESH) { 01415 Mesh *me= ob->data; 01416 return me->key; 01417 } 01418 else if ELEM(ob->type, OB_CURVE, OB_SURF) { 01419 Curve *cu= ob->data; 01420 return cu->key; 01421 } 01422 else if(ob->type==OB_LATTICE) { 01423 Lattice *lt= ob->data; 01424 return lt->key; 01425 } 01426 return NULL; 01427 } 01428 01429 KeyBlock *add_keyblock(Key *key, const char *name) 01430 { 01431 KeyBlock *kb; 01432 float curpos= -0.1; 01433 int tot; 01434 01435 kb= key->block.last; 01436 if(kb) curpos= kb->pos; 01437 01438 kb= MEM_callocN(sizeof(KeyBlock), "Keyblock"); 01439 BLI_addtail(&key->block, kb); 01440 kb->type= KEY_CARDINAL; 01441 01442 tot= BLI_countlist(&key->block); 01443 if(name) { 01444 BLI_strncpy(kb->name, name, sizeof(kb->name)); 01445 } else { 01446 if(tot==1) BLI_strncpy(kb->name, "Basis", sizeof(kb->name)); 01447 else BLI_snprintf(kb->name, sizeof(kb->name), "Key %d", tot-1); 01448 } 01449 01450 BLI_uniquename(&key->block, kb, "Key", '.', offsetof(KeyBlock, name), sizeof(kb->name)); 01451 01452 // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey) 01453 kb->adrcode= tot-1; 01454 01455 key->totkey++; 01456 if(key->totkey==1) key->refkey= kb; 01457 01458 kb->slidermin= 0.0f; 01459 kb->slidermax= 1.0f; 01460 01461 // XXX kb->pos is the confusing old horizontal-line RVK crap in old IPO Editor... 01462 if(key->type == KEY_RELATIVE) 01463 kb->pos= curpos + 0.1f; 01464 else { 01465 #if 0 // XXX old animation system 01466 curpos= BKE_curframe(scene); 01467 if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) { 01468 curpos /= 100.0; 01469 } 01470 kb->pos= curpos; 01471 01472 sort_keys(key); 01473 #endif // XXX old animation system 01474 } 01475 return kb; 01476 } 01477 01478 /* only the active keyblock */ 01479 KeyBlock *ob_get_keyblock(Object *ob) 01480 { 01481 Key *key= ob_get_key(ob); 01482 01483 if (key) { 01484 KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1); 01485 return kb; 01486 } 01487 01488 return NULL; 01489 } 01490 01491 KeyBlock *ob_get_reference_keyblock(Object *ob) 01492 { 01493 Key *key= ob_get_key(ob); 01494 01495 if (key) 01496 return key->refkey; 01497 01498 return NULL; 01499 } 01500 01501 /* get the appropriate KeyBlock given an index */ 01502 KeyBlock *key_get_keyblock(Key *key, int index) 01503 { 01504 KeyBlock *kb; 01505 int i; 01506 01507 if (key) { 01508 kb= key->block.first; 01509 01510 for (i= 1; i < key->totkey; i++) { 01511 kb= kb->next; 01512 01513 if (index==i) 01514 return kb; 01515 } 01516 } 01517 01518 return NULL; 01519 } 01520 01521 /* get the appropriate KeyBlock given a name to search for */ 01522 KeyBlock *key_get_named_keyblock(Key *key, const char name[]) 01523 { 01524 if (key && name) 01525 return BLI_findstring(&key->block, name, offsetof(KeyBlock, name)); 01526 01527 return NULL; 01528 } 01529 01530 /* Get RNA-Path for 'value' setting of the given ShapeKey 01531 * NOTE: the user needs to free the returned string once they're finishe with it 01532 */ 01533 char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb) 01534 { 01535 PointerRNA ptr; 01536 PropertyRNA *prop; 01537 01538 /* sanity checks */ 01539 if ELEM(NULL, key, kb) 01540 return NULL; 01541 01542 /* create the RNA pointer */ 01543 RNA_pointer_create(&key->id, &RNA_ShapeKey, kb, &ptr); 01544 /* get pointer to the property too */ 01545 prop= RNA_struct_find_property(&ptr, "value"); 01546 01547 /* return the path */ 01548 return RNA_path_from_ID_to_property(&ptr, prop); 01549 } 01550 01551 01552 /* conversion functions */ 01553 01554 /************************* Lattice ************************/ 01555 void latt_to_key(Lattice *lt, KeyBlock *kb) 01556 { 01557 BPoint *bp; 01558 float *fp; 01559 int a, tot; 01560 01561 tot= lt->pntsu*lt->pntsv*lt->pntsw; 01562 if(tot==0) return; 01563 01564 if(kb->data) MEM_freeN(kb->data); 01565 01566 kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data"); 01567 kb->totelem= tot; 01568 01569 bp= lt->def; 01570 fp= kb->data; 01571 for(a=0; a<kb->totelem; a++, fp+=3, bp++) { 01572 copy_v3_v3(fp, bp->vec); 01573 } 01574 } 01575 01576 void key_to_latt(KeyBlock *kb, Lattice *lt) 01577 { 01578 BPoint *bp; 01579 float *fp; 01580 int a, tot; 01581 01582 bp= lt->def; 01583 fp= kb->data; 01584 01585 tot= lt->pntsu*lt->pntsv*lt->pntsw; 01586 tot= MIN2(kb->totelem, tot); 01587 01588 for(a=0; a<tot; a++, fp+=3, bp++) { 01589 copy_v3_v3(bp->vec, fp); 01590 } 01591 } 01592 01593 /************************* Curve ************************/ 01594 void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) 01595 { 01596 Nurb *nu; 01597 BezTriple *bezt; 01598 BPoint *bp; 01599 float *fp; 01600 int a, tot; 01601 01602 /* count */ 01603 tot= count_curveverts(nurb); 01604 if(tot==0) return; 01605 01606 if(kb->data) MEM_freeN(kb->data); 01607 01608 kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data"); 01609 kb->totelem= tot; 01610 01611 nu= nurb->first; 01612 fp= kb->data; 01613 while(nu) { 01614 01615 if(nu->bezt) { 01616 bezt= nu->bezt; 01617 a= nu->pntsu; 01618 while(a--) { 01619 copy_v3_v3(fp, bezt->vec[0]); 01620 fp+= 3; 01621 copy_v3_v3(fp, bezt->vec[1]); 01622 fp+= 3; 01623 copy_v3_v3(fp, bezt->vec[2]); 01624 fp+= 3; 01625 fp[0]= bezt->alfa; 01626 fp+= 3; /* alphas */ 01627 bezt++; 01628 } 01629 } 01630 else { 01631 bp= nu->bp; 01632 a= nu->pntsu*nu->pntsv; 01633 while(a--) { 01634 copy_v3_v3(fp, bp->vec); 01635 fp[3]= bp->alfa; 01636 01637 fp+= 4; 01638 bp++; 01639 } 01640 } 01641 nu= nu->next; 01642 } 01643 } 01644 01645 void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) 01646 { 01647 Nurb *nu; 01648 BezTriple *bezt; 01649 BPoint *bp; 01650 float *fp; 01651 int a, tot; 01652 01653 nu= nurb->first; 01654 fp= kb->data; 01655 01656 tot= count_curveverts(nurb); 01657 01658 tot= MIN2(kb->totelem, tot); 01659 01660 while(nu && tot>0) { 01661 01662 if(nu->bezt) { 01663 bezt= nu->bezt; 01664 a= nu->pntsu; 01665 while(a-- && tot>0) { 01666 copy_v3_v3(bezt->vec[0], fp); 01667 fp+= 3; 01668 copy_v3_v3(bezt->vec[1], fp); 01669 fp+= 3; 01670 copy_v3_v3(bezt->vec[2], fp); 01671 fp+= 3; 01672 bezt->alfa= fp[0]; 01673 fp+= 3; /* alphas */ 01674 01675 tot-= 3; 01676 bezt++; 01677 } 01678 } 01679 else { 01680 bp= nu->bp; 01681 a= nu->pntsu*nu->pntsv; 01682 while(a-- && tot>0) { 01683 copy_v3_v3(bp->vec, fp); 01684 bp->alfa= fp[3]; 01685 01686 fp+= 4; 01687 tot--; 01688 bp++; 01689 } 01690 } 01691 nu= nu->next; 01692 } 01693 } 01694 01695 /************************* Mesh ************************/ 01696 void mesh_to_key(Mesh *me, KeyBlock *kb) 01697 { 01698 MVert *mvert; 01699 float *fp; 01700 int a; 01701 01702 if(me->totvert==0) return; 01703 01704 if(kb->data) MEM_freeN(kb->data); 01705 01706 kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); 01707 kb->totelem= me->totvert; 01708 01709 mvert= me->mvert; 01710 fp= kb->data; 01711 for(a=0; a<kb->totelem; a++, fp+=3, mvert++) { 01712 copy_v3_v3(fp, mvert->co); 01713 01714 } 01715 } 01716 01717 void key_to_mesh(KeyBlock *kb, Mesh *me) 01718 { 01719 MVert *mvert; 01720 float *fp; 01721 int a, tot; 01722 01723 mvert= me->mvert; 01724 fp= kb->data; 01725 01726 tot= MIN2(kb->totelem, me->totvert); 01727 01728 for(a=0; a<tot; a++, fp+=3, mvert++) { 01729 copy_v3_v3(mvert->co, fp); 01730 } 01731 } 01732 01733 /************************* vert coords ************************/ 01734 float (*key_to_vertcos(Object *ob, KeyBlock *kb))[3] 01735 { 01736 float (*vertCos)[3], *co; 01737 float *fp= kb->data; 01738 int tot= 0, a; 01739 01740 /* Count of vertex coords in array */ 01741 if(ob->type == OB_MESH) { 01742 Mesh *me= (Mesh*)ob->data; 01743 tot= me->totvert; 01744 } else if(ob->type == OB_LATTICE) { 01745 Lattice *lt= (Lattice*)ob->data; 01746 tot= lt->pntsu*lt->pntsv*lt->pntsw; 01747 } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { 01748 Curve *cu= (Curve*)ob->data; 01749 tot= count_curveverts(&cu->nurb); 01750 } 01751 01752 if (tot == 0) return NULL; 01753 01754 vertCos= MEM_callocN(tot*sizeof(*vertCos), "key_to_vertcos vertCos"); 01755 01756 /* Copy coords to array */ 01757 co= (float*)vertCos; 01758 01759 if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { 01760 for (a= 0; a<tot; a++, fp+=3, co+=3) { 01761 copy_v3_v3(co, fp); 01762 } 01763 } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { 01764 Curve *cu= (Curve*)ob->data; 01765 Nurb *nu= cu->nurb.first; 01766 BezTriple *bezt; 01767 BPoint *bp; 01768 01769 while (nu) { 01770 if(nu->bezt) { 01771 int i; 01772 bezt= nu->bezt; 01773 a= nu->pntsu; 01774 01775 while (a--) { 01776 for (i= 0; i<3; i++) { 01777 copy_v3_v3(co, fp); 01778 fp+= 3; co+= 3; 01779 } 01780 01781 fp+= 3; /* skip alphas */ 01782 01783 bezt++; 01784 } 01785 } 01786 else { 01787 bp= nu->bp; 01788 a= nu->pntsu*nu->pntsv; 01789 01790 while (a--) { 01791 copy_v3_v3(co, fp); 01792 01793 fp+= 4; 01794 co+= 3; 01795 01796 bp++; 01797 } 01798 } 01799 01800 nu= nu->next; 01801 } 01802 } 01803 01804 return vertCos; 01805 } 01806 01807 void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) 01808 { 01809 float *co= (float*)vertCos, *fp; 01810 int tot= 0, a, elemsize; 01811 01812 if (kb->data) MEM_freeN(kb->data); 01813 01814 /* Count of vertex coords in array */ 01815 if(ob->type == OB_MESH) { 01816 Mesh *me= (Mesh*)ob->data; 01817 tot= me->totvert; 01818 elemsize= me->key->elemsize; 01819 } else if(ob->type == OB_LATTICE) { 01820 Lattice *lt= (Lattice*)ob->data; 01821 tot= lt->pntsu*lt->pntsv*lt->pntsw; 01822 elemsize= lt->key->elemsize; 01823 } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { 01824 Curve *cu= (Curve*)ob->data; 01825 elemsize= cu->key->elemsize; 01826 tot= count_curveverts(&cu->nurb); 01827 } 01828 01829 if (tot == 0) { 01830 kb->data= NULL; 01831 return; 01832 } 01833 01834 fp= kb->data= MEM_callocN(tot*elemsize, "key_to_vertcos vertCos"); 01835 01836 /* Copy coords to keyblock */ 01837 01838 if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { 01839 for (a= 0; a<tot; a++, fp+=3, co+=3) { 01840 copy_v3_v3(fp, co); 01841 } 01842 } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { 01843 Curve *cu= (Curve*)ob->data; 01844 Nurb *nu= cu->nurb.first; 01845 BezTriple *bezt; 01846 BPoint *bp; 01847 01848 while (nu) { 01849 if(nu->bezt) { 01850 int i; 01851 bezt= nu->bezt; 01852 a= nu->pntsu; 01853 01854 while (a--) { 01855 for (i= 0; i<3; i++) { 01856 copy_v3_v3(fp, co); 01857 fp+= 3; co+= 3; 01858 } 01859 01860 fp+= 3; /* skip alphas */ 01861 01862 bezt++; 01863 } 01864 } 01865 else { 01866 bp= nu->bp; 01867 a= nu->pntsu*nu->pntsv; 01868 01869 while (a--) { 01870 copy_v3_v3(fp, co); 01871 01872 fp+= 4; 01873 co+= 3; 01874 01875 bp++; 01876 } 01877 } 01878 01879 nu= nu->next; 01880 } 01881 } 01882 } 01883 01884 void offset_to_key(Object *ob, KeyBlock *kb, float (*ofs)[3]) 01885 { 01886 int a; 01887 float *co= (float*)ofs, *fp= kb->data; 01888 01889 if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { 01890 for (a= 0; a<kb->totelem; a++, fp+=3, co+=3) { 01891 add_v3_v3(fp, co); 01892 } 01893 } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { 01894 Curve *cu= (Curve*)ob->data; 01895 Nurb *nu= cu->nurb.first; 01896 BezTriple *bezt; 01897 BPoint *bp; 01898 01899 while (nu) { 01900 if(nu->bezt) { 01901 int i; 01902 bezt= nu->bezt; 01903 a= nu->pntsu; 01904 01905 while (a--) { 01906 for (i= 0; i<3; i++) { 01907 add_v3_v3(fp, co); 01908 fp+= 3; co+= 3; 01909 } 01910 01911 fp+= 3; /* skip alphas */ 01912 01913 bezt++; 01914 } 01915 } 01916 else { 01917 bp= nu->bp; 01918 a= nu->pntsu*nu->pntsv; 01919 01920 while (a--) { 01921 add_v3_v3(fp, co); 01922 01923 fp+= 4; 01924 co+= 3; 01925 01926 bp++; 01927 } 01928 } 01929 01930 nu= nu->next; 01931 } 01932 } 01933 }