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): Reevan McKay 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <string.h> 00034 #include <math.h> 00035 #include "ctype.h" 00036 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "DNA_meshdata_types.h" 00040 #include "DNA_object_types.h" 00041 00042 #include "BKE_deform.h" 00043 00044 #include "BLI_blenlib.h" 00045 #include "BLI_utildefines.h" 00046 00047 00048 void defgroup_copy_list(ListBase *outbase, ListBase *inbase) 00049 { 00050 bDeformGroup *defgroup, *defgroupn; 00051 00052 outbase->first= outbase->last= NULL; 00053 00054 for (defgroup = inbase->first; defgroup; defgroup=defgroup->next){ 00055 defgroupn= defgroup_duplicate(defgroup); 00056 BLI_addtail(outbase, defgroupn); 00057 } 00058 } 00059 00060 bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup) 00061 { 00062 bDeformGroup *outgroup; 00063 00064 if (!ingroup) 00065 return NULL; 00066 00067 outgroup=MEM_callocN(sizeof(bDeformGroup), "copy deformGroup"); 00068 00069 /* For now, just copy everything over. */ 00070 memcpy (outgroup, ingroup, sizeof(bDeformGroup)); 00071 00072 outgroup->next=outgroup->prev=NULL; 00073 00074 return outgroup; 00075 } 00076 00077 /* copy & overwrite weights */ 00078 void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src) 00079 { 00080 if (dvert_dst->totweight == dvert_src->totweight) { 00081 if (dvert_src->totweight) 00082 memcpy(dvert_dst->dw, dvert_src->dw, dvert_src->totweight * sizeof(MDeformWeight)); 00083 } 00084 else { 00085 if (dvert_dst->dw) 00086 MEM_freeN(dvert_dst->dw); 00087 00088 if (dvert_src->totweight) 00089 dvert_dst->dw= MEM_dupallocN(dvert_src->dw); 00090 else 00091 dvert_dst->dw= NULL; 00092 00093 dvert_dst->totweight = dvert_src->totweight; 00094 } 00095 } 00096 00097 /* copy an index from one dvert to another 00098 * - do nothing if neither are set. 00099 * - add destination weight if needed. 00100 */ 00101 void defvert_copy_index(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const int defgroup) 00102 { 00103 MDeformWeight *dw_src, *dw_dst; 00104 00105 dw_src= defvert_find_index(dvert_src, defgroup); 00106 00107 if (dw_src) { 00108 /* source is valid, verify destination */ 00109 dw_dst= defvert_verify_index(dvert_dst, defgroup); 00110 dw_dst->weight= dw_src->weight; 00111 } 00112 else { 00113 /* source was NULL, assign zero, could also remove */ 00114 dw_dst= defvert_find_index(dvert_dst, defgroup); 00115 00116 if (dw_dst) { 00117 dw_dst->weight= 0.0f; 00118 } 00119 } 00120 } 00121 00122 /* only sync over matching weights, don't add or remove groups 00123 * warning, loop within loop. 00124 */ 00125 void defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, int use_verify) 00126 { 00127 if (dvert_src->totweight && dvert_dst->totweight) { 00128 int i; 00129 MDeformWeight *dw_src; 00130 for (i=0, dw_src=dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) { 00131 MDeformWeight *dw_dst; 00132 if (use_verify) dw_dst= defvert_verify_index(dvert_dst, dw_src->def_nr); 00133 else dw_dst= defvert_find_index(dvert_dst, dw_src->def_nr); 00134 00135 if (dw_dst) { 00136 dw_dst->weight= dw_src->weight; 00137 } 00138 } 00139 } 00140 } 00141 00142 /* be sure all flip_map values are valid */ 00143 void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src, 00144 const int *flip_map, const int flip_map_len, const int use_verify) 00145 { 00146 if (dvert_src->totweight && dvert_dst->totweight) { 00147 int i; 00148 MDeformWeight *dw_src; 00149 for (i=0, dw_src=dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) { 00150 if (dw_src->def_nr < flip_map_len) { 00151 MDeformWeight *dw_dst; 00152 if (use_verify) dw_dst= defvert_verify_index(dvert_dst, flip_map[dw_src->def_nr]); 00153 else dw_dst= defvert_find_index(dvert_dst, flip_map[dw_src->def_nr]); 00154 00155 if (dw_dst) { 00156 dw_dst->weight= dw_src->weight; 00157 } 00158 } 00159 } 00160 } 00161 } 00162 00163 /* be sure all flip_map values are valid */ 00164 void defvert_remap(MDeformVert *dvert, int *map, const int map_len) 00165 { 00166 MDeformWeight *dw= dvert->dw; 00167 unsigned int i; 00168 for (i= dvert->totweight; i != 0; i--, dw++) { 00169 if (dw->def_nr < map_len) { 00170 dw->def_nr= map[dw->def_nr]; 00171 00172 /* just incase */ 00173 BLI_assert(dw->def_nr >= 0); 00174 } 00175 } 00176 } 00177 00178 void defvert_normalize(MDeformVert *dvert) 00179 { 00180 if (dvert->totweight <= 0) { 00181 /* nothing */ 00182 } 00183 else if (dvert->totweight==1) { 00184 dvert->dw[0].weight= 1.0f; 00185 } 00186 else { 00187 MDeformWeight *dw; 00188 unsigned int i; 00189 float tot_weight= 0.0f; 00190 00191 for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { 00192 tot_weight += dw->weight; 00193 } 00194 00195 if (tot_weight > 0.0f) { 00196 float scalar= 1.0f / tot_weight; 00197 for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { 00198 dw->weight *= scalar; 00199 00200 /* incase of division errors with very low weights */ 00201 CLAMP(dw->weight, 0.0f, 1.0f); 00202 } 00203 } 00204 } 00205 } 00206 00207 void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock) 00208 { 00209 if (dvert->totweight <= 0) { 00210 /* nothing */ 00211 } 00212 else if (dvert->totweight==1) { 00213 dvert->dw[0].weight= 1.0f; 00214 } 00215 else { 00216 MDeformWeight *dw_lock = NULL; 00217 MDeformWeight *dw; 00218 unsigned int i; 00219 float tot_weight= 0.0f; 00220 float lock_iweight= 1.0f; 00221 00222 for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { 00223 if(dw->def_nr != def_nr_lock) { 00224 tot_weight += dw->weight; 00225 } 00226 else { 00227 dw_lock= dw; 00228 lock_iweight = (1.0f - dw_lock->weight); 00229 CLAMP(lock_iweight, 0.0f, 1.0f); 00230 } 00231 } 00232 00233 if (tot_weight > 0.0f) { 00234 /* paranoid, should be 1.0 but incase of float error clamp anyway */ 00235 00236 float scalar= (1.0f / tot_weight) * lock_iweight; 00237 for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { 00238 if(dw != dw_lock) { 00239 dw->weight *= scalar; 00240 00241 /* incase of division errors with very low weights */ 00242 CLAMP(dw->weight, 0.0f, 1.0f); 00243 } 00244 } 00245 } 00246 } 00247 } 00248 00249 void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len) 00250 { 00251 MDeformWeight *dw; 00252 int i; 00253 00254 for (dw= dvert->dw, i=0; i<dvert->totweight; dw++, i++) { 00255 if (dw->def_nr < flip_map_len) { 00256 if (flip_map[dw->def_nr] >= 0) { 00257 dw->def_nr= flip_map[dw->def_nr]; 00258 } 00259 } 00260 } 00261 } 00262 00263 00264 bDeformGroup *defgroup_find_name(Object *ob, const char *name) 00265 { 00266 /* return a pointer to the deform group with this name 00267 * or return NULL otherwise. 00268 */ 00269 bDeformGroup *curdef; 00270 00271 for (curdef = ob->defbase.first; curdef; curdef=curdef->next) { 00272 if (!strcmp(curdef->name, name)) { 00273 return curdef; 00274 } 00275 } 00276 return NULL; 00277 } 00278 00279 int defgroup_name_index(Object *ob, const char *name) 00280 { 00281 /* Return the location of the named deform group within the list of 00282 * deform groups. This function is a combination of BLI_findlink and 00283 * defgroup_find_name. The other two could be called instead, but that 00284 * require looping over the vertexgroups twice. 00285 */ 00286 bDeformGroup *curdef; 00287 int def_nr; 00288 00289 if (name && name[0] != '\0') { 00290 for (curdef=ob->defbase.first, def_nr=0; curdef; curdef=curdef->next, def_nr++) { 00291 if (!strcmp(curdef->name, name)) 00292 return def_nr; 00293 } 00294 } 00295 00296 return -1; 00297 } 00298 00299 /* note, must be freed */ 00300 int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) 00301 { 00302 int defbase_tot= *flip_map_len= BLI_countlist(&ob->defbase); 00303 00304 if (defbase_tot==0) { 00305 return NULL; 00306 } 00307 else { 00308 bDeformGroup *dg; 00309 char name[sizeof(dg->name)]; 00310 int i, flip_num, *map= MEM_mallocN(defbase_tot * sizeof(int), __func__); 00311 00312 for (i=0; i < defbase_tot; i++) { 00313 map[i]= -1; 00314 } 00315 00316 for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) { 00317 if (map[i] == -1) { /* may be calculated previously */ 00318 00319 /* incase no valid value is found, use this */ 00320 if (use_default) 00321 map[i]= i; 00322 00323 flip_side_name(name, dg->name, FALSE); 00324 if (strcmp(name, dg->name)) { 00325 flip_num= defgroup_name_index(ob, name); 00326 if (flip_num >= 0) { 00327 map[i]= flip_num; 00328 map[flip_num]= i; /* save an extra lookup */ 00329 } 00330 } 00331 } 00332 } 00333 return map; 00334 } 00335 } 00336 00337 /* note, must be freed */ 00338 int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, int defgroup) 00339 { 00340 int defbase_tot= *flip_map_len= BLI_countlist(&ob->defbase); 00341 00342 if (defbase_tot==0) { 00343 return NULL; 00344 } 00345 else { 00346 bDeformGroup *dg; 00347 char name[sizeof(dg->name)]; 00348 int i, flip_num, *map= MEM_mallocN(defbase_tot * sizeof(int), __func__); 00349 00350 for (i=0; i < defbase_tot; i++) { 00351 if (use_default) map[i]= i; 00352 else map[i]= -1; 00353 } 00354 00355 dg= BLI_findlink(&ob->defbase, defgroup); 00356 00357 flip_side_name(name, dg->name, FALSE); 00358 if (strcmp(name, dg->name)) { 00359 flip_num= defgroup_name_index(ob, name); 00360 00361 if (flip_num >= 0) { 00362 map[defgroup]= flip_num; 00363 map[flip_num]= defgroup; 00364 } 00365 } 00366 00367 return map; 00368 } 00369 } 00370 00371 int defgroup_flip_index(Object *ob, int index, int use_default) 00372 { 00373 bDeformGroup *dg= BLI_findlink(&ob->defbase, index); 00374 int flip_index = -1; 00375 00376 if (dg) { 00377 char name[sizeof(dg->name)]; 00378 flip_side_name(name, dg->name, 0); 00379 00380 if (strcmp(name, dg->name)) 00381 flip_index= defgroup_name_index(ob, name); 00382 } 00383 00384 return (flip_index==-1 && use_default) ? index : flip_index; 00385 } 00386 00387 static int defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob) 00388 { 00389 bDeformGroup *curdef; 00390 00391 for (curdef = ob->defbase.first; curdef; curdef=curdef->next) { 00392 if (dg!=curdef) { 00393 if (!strcmp(curdef->name, name)) { 00394 return 1; 00395 } 00396 } 00397 } 00398 00399 return 0; 00400 } 00401 00402 static int defgroup_unique_check(void *arg, const char *name) 00403 { 00404 struct {Object *ob; void *dg;} *data= arg; 00405 return defgroup_find_name_dupe(name, data->dg, data->ob); 00406 } 00407 00408 void defgroup_unique_name(bDeformGroup *dg, Object *ob) 00409 { 00410 struct {Object *ob; void *dg;} data; 00411 data.ob= ob; 00412 data.dg= dg; 00413 00414 BLI_uniquename_cb(defgroup_unique_check, &data, "Group", '.', dg->name, sizeof(dg->name)); 00415 } 00416 00417 /* finds the best possible flipped name. For renaming; check for unique names afterwards */ 00418 /* if strip_number: removes number extensions 00419 * note: dont use sizeof() for 'name' or 'from_name' */ 00420 void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], int strip_number) 00421 { 00422 int len; 00423 char prefix[MAX_VGROUP_NAME]= ""; /* The part before the facing */ 00424 char suffix[MAX_VGROUP_NAME]= ""; /* The part after the facing */ 00425 char replace[MAX_VGROUP_NAME]= ""; /* The replacement string */ 00426 char number[MAX_VGROUP_NAME]= ""; /* The number extension string */ 00427 char *index=NULL; 00428 00429 /* always copy the name, since this can be called with an uninitialized string */ 00430 BLI_strncpy(name, from_name, MAX_VGROUP_NAME); 00431 00432 len= BLI_strnlen(from_name, MAX_VGROUP_NAME); 00433 if (len < 3) { 00434 /* we don't do names like .R or .L */ 00435 return; 00436 } 00437 00438 /* We first check the case with a .### extension, let's find the last period */ 00439 if (isdigit(name[len-1])) { 00440 index= strrchr(name, '.'); // last occurrence 00441 if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! 00442 if (strip_number==0) 00443 BLI_strncpy(number, index, sizeof(number)); 00444 *index= 0; 00445 len= BLI_strnlen(name, MAX_VGROUP_NAME); 00446 } 00447 } 00448 00449 BLI_strncpy(prefix, name, sizeof(prefix)); 00450 00451 #define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') 00452 00453 /* first case; separator . - _ with extensions r R l L */ 00454 if (IS_SEPARATOR(name[len-2]) ) { 00455 switch(name[len-1]) { 00456 case 'l': 00457 prefix[len-1]= 0; 00458 strcpy(replace, "r"); 00459 break; 00460 case 'r': 00461 prefix[len-1]= 0; 00462 strcpy(replace, "l"); 00463 break; 00464 case 'L': 00465 prefix[len-1]= 0; 00466 strcpy(replace, "R"); 00467 break; 00468 case 'R': 00469 prefix[len-1]= 0; 00470 strcpy(replace, "L"); 00471 break; 00472 } 00473 } 00474 /* case; beginning with r R l L , with separator after it */ 00475 else if (IS_SEPARATOR(name[1]) ) { 00476 switch(name[0]) { 00477 case 'l': 00478 strcpy(replace, "r"); 00479 BLI_strncpy(suffix, name+1, sizeof(suffix)); 00480 prefix[0]= 0; 00481 break; 00482 case 'r': 00483 strcpy(replace, "l"); 00484 BLI_strncpy(suffix, name+1, sizeof(suffix)); 00485 prefix[0]= 0; 00486 break; 00487 case 'L': 00488 strcpy(replace, "R"); 00489 BLI_strncpy(suffix, name+1, sizeof(suffix)); 00490 prefix[0]= 0; 00491 break; 00492 case 'R': 00493 strcpy(replace, "L"); 00494 BLI_strncpy(suffix, name+1, sizeof(suffix)); 00495 prefix[0]= 0; 00496 break; 00497 } 00498 } 00499 else if (len > 5) { 00500 /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ 00501 index = BLI_strcasestr(prefix, "right"); 00502 if (index==prefix || index==prefix+len-5) { 00503 if (index[0]=='r') 00504 strcpy(replace, "left"); 00505 else { 00506 if (index[1]=='I') 00507 strcpy(replace, "LEFT"); 00508 else 00509 strcpy(replace, "Left"); 00510 } 00511 *index= 0; 00512 BLI_strncpy(suffix, index+5, sizeof(suffix)); 00513 } 00514 else { 00515 index = BLI_strcasestr(prefix, "left"); 00516 if (index==prefix || index==prefix+len-4) { 00517 if (index[0]=='l') 00518 strcpy(replace, "right"); 00519 else { 00520 if (index[1]=='E') 00521 strcpy(replace, "RIGHT"); 00522 else 00523 strcpy(replace, "Right"); 00524 } 00525 *index= 0; 00526 BLI_strncpy(suffix, index + 4, sizeof(suffix)); 00527 } 00528 } 00529 } 00530 00531 #undef IS_SEPARATOR 00532 00533 BLI_snprintf (name, MAX_VGROUP_NAME, "%s%s%s%s", prefix, replace, suffix, number); 00534 } 00535 00536 float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup) 00537 { 00538 MDeformWeight *dw= defvert_find_index(dvert, defgroup); 00539 return dw ? dw->weight : 0.0f; 00540 } 00541 00542 /* take care with this the rationale is: 00543 * - if the object has no vertex group. act like vertex group isnt set and return 1.0, 00544 * - if the vertex group exists but the 'defgroup' isnt found on this vertex, _still_ return 0.0 00545 * 00546 * This is a bit confusing, just saves some checks from the caller. 00547 */ 00548 float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup) 00549 { 00550 if (defgroup == -1 || dvert == NULL) 00551 return 1.0f; 00552 00553 return defvert_find_weight(dvert+index, defgroup); 00554 } 00555 00556 00557 MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup) 00558 { 00559 if (dvert && defgroup >= 0) { 00560 MDeformWeight *dw = dvert->dw; 00561 unsigned int i; 00562 00563 for (i= dvert->totweight; i != 0; i--, dw++) { 00564 if (dw->def_nr == defgroup) { 00565 return dw; 00566 } 00567 } 00568 } 00569 00570 return NULL; 00571 } 00572 00573 /* Ensures that mv has a deform weight entry for the specified defweight group */ 00574 /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */ 00575 MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup) 00576 { 00577 MDeformWeight *dw_new; 00578 00579 /* do this check always, this function is used to check for it */ 00580 if (!dvert || defgroup < 0) 00581 return NULL; 00582 00583 dw_new= defvert_find_index(dvert, defgroup); 00584 if (dw_new) 00585 return dw_new; 00586 00587 dw_new= MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); 00588 if (dvert->dw) { 00589 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); 00590 MEM_freeN(dvert->dw); 00591 } 00592 dvert->dw= dw_new; 00593 dw_new += dvert->totweight; 00594 dw_new->weight= 0.0f; 00595 dw_new->def_nr= defgroup; 00596 /* Group index */ 00597 00598 dvert->totweight++; 00599 00600 return dw_new; 00601 } 00602 00603 /* TODO. merge with code above! */ 00604 00605 /* Adds the given vertex to the specified vertex group, with given weight. 00606 * warning, this does NOT check for existign, assume caller already knows its not there */ 00607 void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight) 00608 { 00609 MDeformWeight *dw_new; 00610 00611 /* do this check always, this function is used to check for it */ 00612 if (!dvert || defgroup < 0) 00613 return; 00614 00615 dw_new = MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "defvert_add_to group, new deformWeight"); 00616 if(dvert->dw) { 00617 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); 00618 MEM_freeN(dvert->dw); 00619 } 00620 dvert->dw = dw_new; 00621 dw_new += dvert->totweight; 00622 dw_new->weight = weight; 00623 dw_new->def_nr = defgroup; 00624 dvert->totweight++; 00625 } 00626 00627 00628 /* Removes the given vertex from the vertex group. 00629 * WARNING: This function frees the given MDeformWeight, do not use it afterward! */ 00630 void defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw) 00631 { 00632 if (dvert && dw) { 00633 MDeformWeight *dw_new; 00634 int i = dw - dvert->dw; 00635 00636 /* Security check! */ 00637 if(i < 0 || i >= dvert->totweight) { 00638 return; 00639 } 00640 00641 dvert->totweight--; 00642 /* If there are still other deform weights attached to this vert then remove 00643 * this deform weight, and reshuffle the others. 00644 */ 00645 if (dvert->totweight) { 00646 dw_new = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), __func__); 00647 if (dvert->dw) { 00648 #if 1 /* since we dont care about order, swap this with the last, save a memcpy */ 00649 if (i != dvert->totweight) { 00650 dvert->dw[i]= dvert->dw[dvert->totweight]; 00651 } 00652 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight); 00653 MEM_freeN(dvert->dw); 00654 #else 00655 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*i); 00656 memcpy(dw_new+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); 00657 #endif 00658 } 00659 dvert->dw = dw_new; 00660 } 00661 else { 00662 /* If there are no other deform weights left then just remove this one. */ 00663 MEM_freeN(dvert->dw); 00664 dvert->dw = NULL; 00665 } 00666 } 00667 }