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