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 * Contributor(s): Martin Poirier 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 * autoarmature.c: Interface for automagically manipulating armature (retarget, created, ...) 00022 */ 00023 00029 #include <ctype.h> 00030 #include <stdlib.h> 00031 #include <string.h> 00032 #include <math.h> 00033 #include <float.h> 00034 00035 #include "MEM_guardedalloc.h" 00036 00037 #include "PIL_time.h" 00038 00039 #include "DNA_armature_types.h" 00040 #include "DNA_constraint_types.h" 00041 #include "DNA_scene_types.h" 00042 #include "DNA_object_types.h" 00043 00044 #include "BLI_blenlib.h" 00045 #include "BLI_math.h" 00046 #include "BLI_editVert.h" 00047 #include "BLI_utildefines.h" 00048 #include "BLI_ghash.h" 00049 #include "BLI_graph.h" 00050 #include "BLI_rand.h" 00051 #include "BLI_threads.h" 00052 00053 //#include "BDR_editobject.h" 00054 00055 #include "BKE_constraint.h" 00056 #include "BKE_armature.h" 00057 #include "BKE_context.h" 00058 00059 #include "ED_armature.h" 00060 #include "ED_util.h" 00061 00062 #include "BIF_retarget.h" 00063 00064 00065 //#include "mydevice.h" 00066 #include "reeb.h" // FIX ME 00067 //#include "blendef.h" 00068 00069 #include "armature_intern.h" 00070 00071 /************ RIG RETARGET DATA STRUCTURES ***************/ 00072 00073 typedef struct MemoNode { 00074 float weight; 00075 int next; 00076 } MemoNode; 00077 00078 typedef struct RetargetParam { 00079 RigGraph *rigg; 00080 RigArc *iarc; 00081 RigNode *inode_start; 00082 bContext *context; 00083 } RetargetParam; 00084 00085 typedef enum 00086 { 00087 RETARGET_LENGTH, 00088 RETARGET_AGGRESSIVE 00089 } RetargetMode; 00090 00091 typedef enum 00092 { 00093 METHOD_BRUTE_FORCE = 0, 00094 METHOD_MEMOIZE = 1 00095 } RetargetMethod; 00096 00097 typedef enum 00098 { 00099 ARC_FREE = 0, 00100 ARC_TAKEN = 1, 00101 ARC_USED = 2 00102 } ArcUsageFlags; 00103 00104 static RigGraph *GLOBAL_RIGG = NULL; 00105 00106 /*******************************************************************************************************/ 00107 00108 void *exec_retargetArctoArc(void *param); 00109 00110 static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second); 00111 float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]); 00112 00113 /* two levels */ 00114 #define SHAPE_LEVELS (SHAPE_RADIX * SHAPE_RADIX) 00115 00116 /*********************************** EDITBONE UTILS ****************************************************/ 00117 00118 static int countEditBoneChildren(ListBase *list, EditBone *parent) 00119 { 00120 EditBone *ebone; 00121 int count = 0; 00122 00123 for (ebone = list->first; ebone; ebone = ebone->next) 00124 { 00125 if (ebone->parent == parent) 00126 { 00127 count++; 00128 } 00129 } 00130 00131 return count; 00132 } 00133 00134 static EditBone* nextEditBoneChild(ListBase *list, EditBone *parent, int n) 00135 { 00136 EditBone *ebone; 00137 00138 for (ebone = list->first; ebone; ebone = ebone->next) 00139 { 00140 if (ebone->parent == parent) 00141 { 00142 if (n == 0) 00143 { 00144 return ebone; 00145 } 00146 n--; 00147 } 00148 } 00149 00150 return NULL; 00151 } 00152 00153 static void getEditBoneRollUpAxis(EditBone *bone, float roll, float up_axis[3]) 00154 { 00155 float mat[3][3], nor[3]; 00156 00157 sub_v3_v3v3(nor, bone->tail, bone->head); 00158 00159 vec_roll_to_mat3(nor, roll, mat); 00160 copy_v3_v3(up_axis, mat[2]); 00161 } 00162 00163 static float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], float qroll[4], float aligned_axis[3]) 00164 { 00165 float nor[3], new_up_axis[3], x_axis[3], z_axis[3]; 00166 00167 copy_v3_v3(new_up_axis, old_up_axis); 00168 mul_qt_v3(qrot, new_up_axis); 00169 00170 sub_v3_v3v3(nor, bone->tail, bone->head); 00171 00172 cross_v3_v3v3(x_axis, nor, aligned_axis); 00173 cross_v3_v3v3(z_axis, x_axis, nor); 00174 00175 normalize_v3(new_up_axis); 00176 normalize_v3(x_axis); 00177 normalize_v3(z_axis); 00178 00179 if (dot_v3v3(new_up_axis, x_axis) < 0) 00180 { 00181 negate_v3(x_axis); 00182 } 00183 00184 if (dot_v3v3(new_up_axis, z_axis) < 0) 00185 { 00186 negate_v3(z_axis); 00187 } 00188 00189 if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis)) 00190 { 00191 rotation_between_vecs_to_quat(qroll, new_up_axis, x_axis); /* set roll rotation quat */ 00192 return ED_rollBoneToVector(bone, x_axis, FALSE); 00193 } 00194 else 00195 { 00196 rotation_between_vecs_to_quat(qroll, new_up_axis, z_axis); /* set roll rotation quat */ 00197 return ED_rollBoneToVector(bone, z_axis, FALSE); 00198 } 00199 } 00200 00201 static float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4], float up_axis[3]) 00202 { 00203 if (previous == NULL) 00204 { 00205 /* default to up_axis if no previous */ 00206 return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis); 00207 } 00208 else 00209 { 00210 float new_up_axis[3]; 00211 float vec_first[3], vec_second[3], normal[3]; 00212 00213 if (previous->bone) 00214 { 00215 sub_v3_v3v3(vec_first, previous->bone->tail, previous->bone->head); 00216 } 00217 else if (previous->prev->bone) 00218 { 00219 sub_v3_v3v3(vec_first, edge->bone->head, previous->prev->bone->tail); 00220 } 00221 else 00222 { 00223 /* default to up_axis if first bone in the chain is an offset */ 00224 return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis); 00225 } 00226 00227 sub_v3_v3v3(vec_second, edge->bone->tail, edge->bone->head); 00228 00229 normalize_v3(vec_first); 00230 normalize_v3(vec_second); 00231 00232 cross_v3_v3v3(normal, vec_first, vec_second); 00233 normalize_v3(normal); 00234 00235 axis_angle_to_quat(qroll, vec_second, edge->up_angle); 00236 00237 mul_qt_v3(qroll, normal); 00238 00239 copy_v3_v3(new_up_axis, edge->up_axis); 00240 mul_qt_v3(qrot, new_up_axis); 00241 00242 normalize_v3(new_up_axis); 00243 00244 /* real qroll between normal and up_axis */ 00245 rotation_between_vecs_to_quat(qroll, new_up_axis, normal); 00246 00247 return ED_rollBoneToVector(edge->bone, normal, FALSE); 00248 } 00249 } 00250 00251 float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]) 00252 { 00253 float new_up_axis[3]; 00254 00255 copy_v3_v3(new_up_axis, old_up_axis); 00256 mul_qt_v3(qrot, new_up_axis); 00257 00258 return ED_rollBoneToVector(bone, new_up_axis, FALSE); 00259 } 00260 00261 /************************************ DESTRUCTORS ******************************************************/ 00262 00263 static void RIG_freeRigArc(BArc *arc) 00264 { 00265 BLI_freelistN(&((RigArc*)arc)->edges); 00266 } 00267 00268 void RIG_freeRigGraph(BGraph *rg) 00269 { 00270 RigGraph *rigg = (RigGraph*)rg; 00271 BNode *node; 00272 BArc *arc; 00273 00274 #ifdef USE_THREADS 00275 BLI_destroy_worker(rigg->worker); 00276 #endif 00277 00278 if (rigg->link_mesh) 00279 { 00280 REEB_freeGraph(rigg->link_mesh); 00281 } 00282 00283 for (arc = rg->arcs.first; arc; arc = arc->next) 00284 { 00285 RIG_freeRigArc(arc); 00286 } 00287 BLI_freelistN(&rg->arcs); 00288 00289 for (node = rg->nodes.first; node; node = node->next) 00290 { 00291 BLI_freeNode(rg, (BNode*)node); 00292 } 00293 BLI_freelistN(&rg->nodes); 00294 00295 BLI_freelistN(&rigg->controls); 00296 00297 BLI_ghash_free(rigg->bones_map, NULL, NULL); 00298 BLI_ghash_free(rigg->controls_map, NULL, NULL); 00299 00300 if (rigg->flag & RIG_FREE_BONELIST) 00301 { 00302 BLI_freelistN(rigg->editbones); 00303 MEM_freeN(rigg->editbones); 00304 } 00305 00306 MEM_freeN(rg); 00307 } 00308 00309 /************************************* ALLOCATORS ******************************************************/ 00310 00311 static RigGraph *newRigGraph(void) 00312 { 00313 RigGraph *rg; 00314 int totthread; 00315 00316 rg = MEM_callocN(sizeof(RigGraph), "rig graph"); 00317 00318 rg->head = NULL; 00319 00320 rg->bones_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph bones gh"); 00321 rg->controls_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph cont gh"); 00322 00323 rg->free_arc = RIG_freeRigArc; 00324 rg->free_node = NULL; 00325 00326 #ifdef USE_THREADS 00327 // if(G.scene->r.mode & R_FIXED_THREADS) 00328 // { 00329 // totthread = G.scene->r.threads; 00330 // } 00331 // else 00332 // { 00333 totthread = BLI_system_thread_count(); 00334 // } 00335 00336 rg->worker = BLI_create_worker(exec_retargetArctoArc, totthread, 20); /* fix number of threads */ 00337 #endif 00338 00339 return rg; 00340 } 00341 00342 static RigArc *newRigArc(RigGraph *rg) 00343 { 00344 RigArc *arc; 00345 00346 arc = MEM_callocN(sizeof(RigArc), "rig arc"); 00347 arc->count = 0; 00348 BLI_addtail(&rg->arcs, arc); 00349 00350 return arc; 00351 } 00352 00353 static RigControl *newRigControl(RigGraph *rg) 00354 { 00355 RigControl *ctrl; 00356 00357 ctrl = MEM_callocN(sizeof(RigControl), "rig control"); 00358 00359 BLI_addtail(&rg->controls, ctrl); 00360 00361 return ctrl; 00362 } 00363 00364 static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3]) 00365 { 00366 RigNode *node; 00367 node = MEM_callocN(sizeof(RigNode), "rig node"); 00368 BLI_addtail(&rg->nodes, node); 00369 00370 copy_v3_v3(node->p, p); 00371 node->degree = 1; 00372 node->arcs = NULL; 00373 00374 arc->head = node; 00375 00376 return node; 00377 } 00378 00379 static void addRigNodeHead(RigGraph *UNUSED(rg), RigArc *arc, RigNode *node) 00380 { 00381 node->degree++; 00382 00383 arc->head = node; 00384 } 00385 00386 static RigNode *newRigNode(RigGraph *rg, float p[3]) 00387 { 00388 RigNode *node; 00389 node = MEM_callocN(sizeof(RigNode), "rig node"); 00390 BLI_addtail(&rg->nodes, node); 00391 00392 copy_v3_v3(node->p, p); 00393 node->degree = 0; 00394 node->arcs = NULL; 00395 00396 return node; 00397 } 00398 00399 static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3]) 00400 { 00401 RigNode *node = newRigNode(rg, p); 00402 00403 node->degree = 1; 00404 arc->tail = node; 00405 00406 return node; 00407 } 00408 00409 static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge) 00410 { 00411 BLI_addtail(&arc->edges, edge); 00412 00413 if (edge->prev == NULL) 00414 { 00415 copy_v3_v3(edge->head, arc->head->p); 00416 } 00417 else 00418 { 00419 RigEdge *last_edge = edge->prev; 00420 copy_v3_v3(edge->head, last_edge->tail); 00421 RIG_calculateEdgeAngles(last_edge, edge); 00422 } 00423 00424 edge->length = len_v3v3(edge->head, edge->tail); 00425 00426 arc->length += edge->length; 00427 00428 arc->count += 1; 00429 } 00430 00431 static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone) 00432 { 00433 RigEdge *edge; 00434 00435 edge = MEM_callocN(sizeof(RigEdge), "rig edge"); 00436 00437 copy_v3_v3(edge->tail, tail); 00438 edge->bone = bone; 00439 00440 if (bone) 00441 { 00442 getEditBoneRollUpAxis(bone, bone->roll, edge->up_axis); 00443 } 00444 00445 RIG_appendEdgeToArc(arc, edge); 00446 } 00447 /************************************** CLONING TEMPLATES **********************************************/ 00448 00449 static void renameTemplateBone(char *name, char *template_name, ListBase *editbones, char *side_string, char *num_string) 00450 { 00451 int i, j; 00452 00453 for (i = 0, j = 0; template_name[i] != '\0' && i < (MAXBONENAME-1) && j < (MAXBONENAME-1); i++) 00454 { 00455 if (template_name[i] == '&') 00456 { 00457 if (template_name[i+1] == 'S' || template_name[i+1] == 's') 00458 { 00459 j += sprintf(name + j, "%s", side_string); 00460 i++; 00461 } 00462 else if (template_name[i+1] == 'N' || template_name[i+1] == 'n') 00463 { 00464 j += sprintf(name + j, "%s", num_string); 00465 i++; 00466 } 00467 else 00468 { 00469 name[j] = template_name[i]; 00470 j++; 00471 } 00472 } 00473 else 00474 { 00475 name[j] = template_name[i]; 00476 j++; 00477 } 00478 } 00479 00480 name[j] = '\0'; 00481 00482 unique_editbone_name(editbones, name, NULL); 00483 } 00484 00485 static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash, char *side_string, char *num_string) 00486 { 00487 RigControl *ctrl; 00488 char name[MAXBONENAME]; 00489 00490 ctrl = newRigControl(rg); 00491 00492 copy_v3_v3(ctrl->head, src_ctrl->head); 00493 copy_v3_v3(ctrl->tail, src_ctrl->tail); 00494 copy_v3_v3(ctrl->up_axis, src_ctrl->up_axis); 00495 copy_v3_v3(ctrl->offset, src_ctrl->offset); 00496 00497 ctrl->tail_mode = src_ctrl->tail_mode; 00498 ctrl->flag = src_ctrl->flag; 00499 00500 renameTemplateBone(name, src_ctrl->bone->name, rg->editbones, side_string, num_string); 00501 ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob); 00502 ctrl->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL); 00503 BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone); 00504 00505 ctrl->link = src_ctrl->link; 00506 ctrl->link_tail = src_ctrl->link_tail; 00507 00508 return ctrl; 00509 } 00510 00511 static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *ptr_hash, char *side_string, char *num_string) 00512 { 00513 RigEdge *src_edge; 00514 RigArc *arc; 00515 00516 arc = newRigArc(rg); 00517 00518 arc->head = BLI_ghash_lookup(ptr_hash, src_arc->head); 00519 arc->tail = BLI_ghash_lookup(ptr_hash, src_arc->tail); 00520 00521 arc->head->degree++; 00522 arc->tail->degree++; 00523 00524 arc->length = src_arc->length; 00525 00526 arc->count = src_arc->count; 00527 00528 for (src_edge = src_arc->edges.first; src_edge; src_edge = src_edge->next) 00529 { 00530 RigEdge *edge; 00531 00532 edge = MEM_callocN(sizeof(RigEdge), "rig edge"); 00533 00534 copy_v3_v3(edge->head, src_edge->head); 00535 copy_v3_v3(edge->tail, src_edge->tail); 00536 copy_v3_v3(edge->up_axis, src_edge->up_axis); 00537 00538 edge->length = src_edge->length; 00539 edge->angle = src_edge->angle; 00540 edge->up_angle = src_edge->up_angle; 00541 00542 if (src_edge->bone != NULL) 00543 { 00544 char name[MAXBONENAME]; 00545 renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string); 00546 edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob); 00547 edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL); 00548 BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone); 00549 } 00550 00551 BLI_addtail(&arc->edges, edge); 00552 } 00553 00554 return arc; 00555 } 00556 00557 static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, char *side_string, char *num_string) 00558 { 00559 GHash *ptr_hash; 00560 RigNode *node; 00561 RigArc *arc; 00562 RigControl *ctrl; 00563 RigGraph *rg; 00564 00565 ptr_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "cloneRigGraph gh"); 00566 00567 rg = newRigGraph(); 00568 00569 rg->ob = ob; 00570 rg->editbones = editbones; 00571 00572 preEditBoneDuplicate(rg->editbones); /* prime bones for duplication */ 00573 preEditBoneDuplicate(src->editbones); /* prime bones for duplication */ 00574 00575 /* Clone nodes */ 00576 for (node = src->nodes.first; node; node = node->next) 00577 { 00578 RigNode *cloned_node = newRigNode(rg, node->p); 00579 BLI_ghash_insert(ptr_hash, node, cloned_node); 00580 } 00581 00582 rg->head = BLI_ghash_lookup(ptr_hash, src->head); 00583 00584 /* Clone arcs */ 00585 for (arc = src->arcs.first; arc; arc = arc->next) 00586 { 00587 cloneArc(rg, src, arc, ptr_hash, side_string, num_string); 00588 } 00589 00590 /* Clone controls */ 00591 for (ctrl = src->controls.first; ctrl; ctrl = ctrl->next) 00592 { 00593 cloneControl(rg, src, ctrl, ptr_hash, side_string, num_string); 00594 } 00595 00596 /* Relink bones properly */ 00597 for (arc = rg->arcs.first; arc; arc = arc->next) 00598 { 00599 RigEdge *edge; 00600 00601 for (edge = arc->edges.first; edge; edge = edge->next) 00602 { 00603 if (edge->bone != NULL) 00604 { 00605 EditBone *bone; 00606 00607 updateDuplicateSubtargetObjects(edge->bone, src->editbones, src->ob, rg->ob); 00608 00609 if (edge->bone->parent) 00610 { 00611 bone = BLI_ghash_lookup(ptr_hash, edge->bone->parent); 00612 00613 if (bone != NULL) 00614 { 00615 edge->bone->parent = bone; 00616 } 00617 else 00618 { 00619 /* disconnect since parent isn't cloned 00620 * this will only happen when cloning from selected bones 00621 * */ 00622 edge->bone->flag &= ~BONE_CONNECTED; 00623 } 00624 } 00625 } 00626 } 00627 } 00628 00629 for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) 00630 { 00631 EditBone *bone; 00632 00633 updateDuplicateSubtargetObjects(ctrl->bone, src->editbones, src->ob, rg->ob); 00634 00635 if (ctrl->bone->parent) 00636 { 00637 bone = BLI_ghash_lookup(ptr_hash, ctrl->bone->parent); 00638 00639 if (bone != NULL) 00640 { 00641 ctrl->bone->parent = bone; 00642 } 00643 else 00644 { 00645 /* disconnect since parent isn't cloned 00646 * this will only happen when cloning from selected bones 00647 * */ 00648 ctrl->bone->flag &= ~BONE_CONNECTED; 00649 } 00650 } 00651 00652 ctrl->link = BLI_ghash_lookup(ptr_hash, ctrl->link); 00653 ctrl->link_tail = BLI_ghash_lookup(ptr_hash, ctrl->link_tail); 00654 } 00655 00656 BLI_ghash_free(ptr_hash, NULL, NULL); 00657 00658 return rg; 00659 } 00660 00661 00662 /*******************************************************************************************************/ 00663 00664 static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second) 00665 { 00666 float vec_first[3], vec_second[3]; 00667 00668 sub_v3_v3v3(vec_first, edge_first->tail, edge_first->head); 00669 sub_v3_v3v3(vec_second, edge_second->tail, edge_second->head); 00670 00671 normalize_v3(vec_first); 00672 normalize_v3(vec_second); 00673 00674 edge_first->angle = angle_normalized_v3v3(vec_first, vec_second); 00675 00676 if (edge_second->bone != NULL) 00677 { 00678 float normal[3]; 00679 00680 cross_v3_v3v3(normal, vec_first, vec_second); 00681 normalize_v3(normal); 00682 00683 edge_second->up_angle = angle_normalized_v3v3(normal, edge_second->up_axis); 00684 } 00685 } 00686 00687 /************************************ CONTROL BONES ****************************************************/ 00688 00689 static void RIG_addControlBone(RigGraph *rg, EditBone *bone) 00690 { 00691 RigControl *ctrl = newRigControl(rg); 00692 ctrl->bone = bone; 00693 copy_v3_v3(ctrl->head, bone->head); 00694 copy_v3_v3(ctrl->tail, bone->tail); 00695 getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis); 00696 ctrl->tail_mode = TL_NONE; 00697 00698 BLI_ghash_insert(rg->controls_map, bone->name, ctrl); 00699 } 00700 00701 static int RIG_parentControl(RigControl *ctrl, EditBone *link) 00702 { 00703 if (link) 00704 { 00705 float offset[3]; 00706 int flag = 0; 00707 00708 sub_v3_v3v3(offset, ctrl->bone->head, link->head); 00709 00710 /* if root matches, check for direction too */ 00711 if (dot_v3v3(offset, offset) < 0.0001f) 00712 { 00713 float vbone[3], vparent[3]; 00714 00715 flag |= RIG_CTRL_FIT_ROOT; 00716 00717 sub_v3_v3v3(vbone, ctrl->bone->tail, ctrl->bone->head); 00718 sub_v3_v3v3(vparent, link->tail, link->head); 00719 00720 /* test for opposite direction */ 00721 if (dot_v3v3(vbone, vparent) > 0) 00722 { 00723 float nor[3]; 00724 float len; 00725 00726 cross_v3_v3v3(nor, vbone, vparent); 00727 00728 len = dot_v3v3(nor, nor); 00729 if (len < 0.0001f) 00730 { 00731 flag |= RIG_CTRL_FIT_BONE; 00732 } 00733 } 00734 } 00735 00736 /* Bail out if old one is automatically better */ 00737 if (flag < ctrl->flag) 00738 { 00739 return 0; 00740 } 00741 00742 /* if there's already a link 00743 * overwrite only if new link is higher in the chain */ 00744 if (ctrl->link && flag == ctrl->flag) 00745 { 00746 EditBone *bone = NULL; 00747 00748 for (bone = ctrl->link; bone; bone = bone->parent) 00749 { 00750 /* if link is in the chain, break and use that one */ 00751 if (bone == link) 00752 { 00753 break; 00754 } 00755 } 00756 00757 /* not in chain, don't update link */ 00758 if (bone == NULL) 00759 { 00760 return 0; 00761 } 00762 } 00763 00764 00765 ctrl->link = link; 00766 ctrl->flag = flag; 00767 00768 copy_v3_v3(ctrl->offset, offset); 00769 00770 return 1; 00771 } 00772 00773 return 0; 00774 } 00775 00776 static void RIG_reconnectControlBones(RigGraph *rg) 00777 { 00778 RigControl *ctrl; 00779 int change = 1; 00780 00781 /* first pass, link to deform bones */ 00782 for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) 00783 { 00784 bPoseChannel *pchan; 00785 bConstraint *con; 00786 int found = 0; 00787 00788 /* DO SOME MAGIC HERE */ 00789 for (pchan= rg->ob->pose->chanbase.first; pchan; pchan= pchan->next) 00790 { 00791 for (con= pchan->constraints.first; con; con= con->next) 00792 { 00793 bConstraintTypeInfo *cti= constraint_get_typeinfo(con); 00794 ListBase targets = {NULL, NULL}; 00795 bConstraintTarget *ct; 00796 00797 /* constraint targets */ 00798 if (cti && cti->get_constraint_targets) 00799 { 00800 int target_index; 00801 00802 cti->get_constraint_targets(con, &targets); 00803 00804 for (target_index = 0, ct= targets.first; ct; target_index++, ct= ct->next) 00805 { 00806 if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0) 00807 { 00808 /* SET bone link to bone corresponding to pchan */ 00809 EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name); 00810 00811 /* Making sure bone is in this armature */ 00812 if (link != NULL) 00813 { 00814 /* for pole targets, link to parent bone instead, if possible */ 00815 if (con->type == CONSTRAINT_TYPE_KINEMATIC && target_index == 1) 00816 { 00817 if (link->parent && BLI_ghash_haskey(rg->bones_map, link->parent->name)) 00818 { 00819 link = link->parent; 00820 } 00821 } 00822 00823 found = RIG_parentControl(ctrl, link); 00824 } 00825 } 00826 } 00827 00828 if (cti->flush_constraint_targets) 00829 cti->flush_constraint_targets(con, &targets, 0); 00830 } 00831 } 00832 } 00833 00834 /* if not found yet, check parent */ 00835 if (found == 0) 00836 { 00837 if (ctrl->bone->parent) 00838 { 00839 /* make sure parent is a deforming bone 00840 * NULL if not 00841 * */ 00842 EditBone *link = BLI_ghash_lookup(rg->bones_map, ctrl->bone->parent->name); 00843 00844 found = RIG_parentControl(ctrl, link); 00845 } 00846 00847 /* check if bone is not superposed on another one */ 00848 { 00849 RigArc *arc; 00850 RigArc *best_arc = NULL; 00851 EditBone *link = NULL; 00852 00853 for (arc = rg->arcs.first; arc; arc = arc->next) 00854 { 00855 RigEdge *edge; 00856 for (edge = arc->edges.first; edge; edge = edge->next) 00857 { 00858 if (edge->bone) 00859 { 00860 int fit = 0; 00861 00862 fit = len_v3v3(ctrl->bone->head, edge->bone->head) < 0.0001f; 00863 fit = fit || len_v3v3(ctrl->bone->tail, edge->bone->tail) < 0.0001f; 00864 00865 if (fit) 00866 { 00867 /* pick the bone on the arc with the lowest symmetry level 00868 * means you connect control to the trunk of the skeleton */ 00869 if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) 00870 { 00871 best_arc = arc; 00872 link = edge->bone; 00873 } 00874 } 00875 } 00876 } 00877 } 00878 00879 found = RIG_parentControl(ctrl, link); 00880 } 00881 } 00882 00883 /* if not found yet, check child */ 00884 if (found == 0) 00885 { 00886 RigArc *arc; 00887 RigArc *best_arc = NULL; 00888 EditBone *link = NULL; 00889 00890 for (arc = rg->arcs.first; arc; arc = arc->next) 00891 { 00892 RigEdge *edge; 00893 for (edge = arc->edges.first; edge; edge = edge->next) 00894 { 00895 if (edge->bone && edge->bone->parent == ctrl->bone) 00896 { 00897 /* pick the bone on the arc with the lowest symmetry level 00898 * means you connect control to the trunk of the skeleton */ 00899 if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) 00900 { 00901 best_arc = arc; 00902 link = edge->bone; 00903 } 00904 } 00905 } 00906 } 00907 00908 found = RIG_parentControl(ctrl, link); 00909 } 00910 00911 } 00912 00913 00914 /* second pass, make chains in control bones */ 00915 while (change) 00916 { 00917 change = 0; 00918 00919 for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) 00920 { 00921 /* if control is not linked yet */ 00922 if (ctrl->link == NULL) 00923 { 00924 bPoseChannel *pchan; 00925 bConstraint *con; 00926 RigControl *ctrl_parent = NULL; 00927 RigControl *ctrl_child; 00928 int found = 0; 00929 00930 if (ctrl->bone->parent) 00931 { 00932 ctrl_parent = BLI_ghash_lookup(rg->controls_map, ctrl->bone->parent->name); 00933 } 00934 00935 /* check constraints first */ 00936 00937 /* DO SOME MAGIC HERE */ 00938 for (pchan= rg->ob->pose->chanbase.first; pchan; pchan= pchan->next) 00939 { 00940 for (con= pchan->constraints.first; con; con= con->next) 00941 { 00942 bConstraintTypeInfo *cti= constraint_get_typeinfo(con); 00943 ListBase targets = {NULL, NULL}; 00944 bConstraintTarget *ct; 00945 00946 /* constraint targets */ 00947 if (cti && cti->get_constraint_targets) 00948 { 00949 cti->get_constraint_targets(con, &targets); 00950 00951 for (ct= targets.first; ct; ct= ct->next) 00952 { 00953 if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0) 00954 { 00955 /* SET bone link to ctrl corresponding to pchan */ 00956 RigControl *link = BLI_ghash_lookup(rg->controls_map, pchan->name); 00957 00958 /* if owner is a control bone, link with it */ 00959 if (link && link->link) 00960 { 00961 RIG_parentControl(ctrl, link->bone); 00962 found = 1; 00963 break; 00964 } 00965 } 00966 } 00967 00968 if (cti->flush_constraint_targets) 00969 cti->flush_constraint_targets(con, &targets, 0); 00970 } 00971 } 00972 } 00973 00974 if (found == 0) 00975 { 00976 /* check if parent is already linked */ 00977 if (ctrl_parent && ctrl_parent->link) 00978 { 00979 RIG_parentControl(ctrl, ctrl_parent->bone); 00980 change = 1; 00981 } 00982 else 00983 { 00984 /* check childs */ 00985 for (ctrl_child = rg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) 00986 { 00987 /* if a child is linked, link to that one */ 00988 if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone) 00989 { 00990 RIG_parentControl(ctrl, ctrl_child->bone); 00991 change = 1; 00992 break; 00993 } 00994 } 00995 } 00996 } 00997 } 00998 } 00999 } 01000 01001 /* third pass, link control tails */ 01002 for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) 01003 { 01004 /* fit bone already means full match, so skip those */ 01005 if ((ctrl->flag & RIG_CTRL_FIT_BONE) == 0) 01006 { 01007 GHashIterator ghi; 01008 01009 /* look on deform bones first */ 01010 BLI_ghashIterator_init(&ghi, rg->bones_map); 01011 01012 for( ; !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi)) 01013 { 01014 EditBone *bone = (EditBone*)BLI_ghashIterator_getValue(&ghi); 01015 01016 /* don't link with parent */ 01017 if (bone->parent != ctrl->bone) 01018 { 01019 if (len_v3v3(ctrl->bone->tail, bone->head) < 0.01f) 01020 { 01021 ctrl->tail_mode = TL_HEAD; 01022 ctrl->link_tail = bone; 01023 break; 01024 } 01025 else if (len_v3v3(ctrl->bone->tail, bone->tail) < 0.01f) 01026 { 01027 ctrl->tail_mode = TL_TAIL; 01028 ctrl->link_tail = bone; 01029 break; 01030 } 01031 } 01032 } 01033 01034 /* if we haven't found one yet, look in control bones */ 01035 if (ctrl->tail_mode == TL_NONE) 01036 { 01037 } 01038 } 01039 } 01040 01041 } 01042 01043 /*******************************************************************************************************/ 01044 01045 static void RIG_joinArcs(RigGraph *rg, RigNode *node, RigArc *joined_arc1, RigArc *joined_arc2) 01046 { 01047 RigEdge *edge, *next_edge; 01048 01049 /* ignore cases where joint is at start or end */ 01050 if (joined_arc1->head == joined_arc2->head || joined_arc1->tail == joined_arc2->tail) 01051 { 01052 return; 01053 } 01054 01055 /* swap arcs to make sure arc1 is before arc2 */ 01056 if (joined_arc1->head == joined_arc2->tail) 01057 { 01058 RigArc *tmp = joined_arc1; 01059 joined_arc1 = joined_arc2; 01060 joined_arc2 = tmp; 01061 } 01062 01063 for (edge = joined_arc2->edges.first; edge; edge = next_edge) 01064 { 01065 next_edge = edge->next; 01066 01067 RIG_appendEdgeToArc(joined_arc1, edge); 01068 } 01069 01070 joined_arc1->tail = joined_arc2->tail; 01071 01072 joined_arc2->edges.first = joined_arc2->edges.last = NULL; 01073 01074 BLI_removeArc((BGraph*)rg, (BArc*)joined_arc2); 01075 01076 BLI_removeNode((BGraph*)rg, (BNode*)node); 01077 } 01078 01079 static void RIG_removeNormalNodes(RigGraph *rg) 01080 { 01081 RigNode *node, *next_node; 01082 01083 for (node = rg->nodes.first; node; node = next_node) 01084 { 01085 next_node = node->next; 01086 01087 if (node->degree == 2) 01088 { 01089 RigArc *arc, *joined_arc1 = NULL, *joined_arc2 = NULL; 01090 01091 for (arc = rg->arcs.first; arc; arc = arc->next) 01092 { 01093 if (arc->head == node || arc->tail == node) 01094 { 01095 if (joined_arc1 == NULL) 01096 { 01097 joined_arc1 = arc; 01098 } 01099 else 01100 { 01101 joined_arc2 = arc; 01102 break; 01103 } 01104 } 01105 } 01106 01107 RIG_joinArcs(rg, node, joined_arc1, joined_arc2); 01108 } 01109 } 01110 } 01111 01112 static void RIG_removeUneededOffsets(RigGraph *rg) 01113 { 01114 RigArc *arc; 01115 01116 for (arc = rg->arcs.first; arc; arc = arc->next) 01117 { 01118 RigEdge *first_edge, *last_edge; 01119 01120 first_edge = arc->edges.first; 01121 last_edge = arc->edges.last; 01122 01123 if (first_edge->bone == NULL) 01124 { 01125 if (first_edge->bone == NULL && len_v3v3(first_edge->tail, arc->head->p) <= 0.001f) 01126 { 01127 BLI_remlink(&arc->edges, first_edge); 01128 MEM_freeN(first_edge); 01129 } 01130 else if (arc->head->degree == 1) 01131 { 01132 RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, first_edge->tail, 0.001f); 01133 01134 if (new_node) 01135 { 01136 BLI_remlink(&arc->edges, first_edge); 01137 MEM_freeN(first_edge); 01138 BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->head); 01139 } 01140 else 01141 { 01142 RigEdge *next_edge = first_edge->next; 01143 01144 if (next_edge) 01145 { 01146 BLI_remlink(&arc->edges, first_edge); 01147 MEM_freeN(first_edge); 01148 01149 copy_v3_v3(arc->head->p, next_edge->head); 01150 } 01151 } 01152 } 01153 else 01154 { 01155 /* check if all arc connected start with a null edge */ 01156 RigArc *other_arc; 01157 for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) 01158 { 01159 if (other_arc != arc) 01160 { 01161 RigEdge *test_edge; 01162 if (other_arc->head == arc->head) 01163 { 01164 test_edge = other_arc->edges.first; 01165 01166 if (test_edge->bone != NULL) 01167 { 01168 break; 01169 } 01170 } 01171 else if (other_arc->tail == arc->head) 01172 { 01173 test_edge = other_arc->edges.last; 01174 01175 if (test_edge->bone != NULL) 01176 { 01177 break; 01178 } 01179 } 01180 } 01181 } 01182 01183 if (other_arc == NULL) 01184 { 01185 RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, first_edge->tail, 0.001); 01186 01187 if (new_node) 01188 { 01189 /* remove null edge in other arcs too */ 01190 for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) 01191 { 01192 if (other_arc != arc) 01193 { 01194 RigEdge *test_edge; 01195 if (other_arc->head == arc->head) 01196 { 01197 BLI_replaceNodeInArc((BGraph*)rg, (BArc*)other_arc, (BNode*)new_node, (BNode*)other_arc->head); 01198 test_edge = other_arc->edges.first; 01199 BLI_remlink(&other_arc->edges, test_edge); 01200 MEM_freeN(test_edge); 01201 } 01202 else if (other_arc->tail == arc->head) 01203 { 01204 BLI_replaceNodeInArc((BGraph*)rg, (BArc*)other_arc, (BNode*)new_node, (BNode*)other_arc->tail); 01205 test_edge = other_arc->edges.last; 01206 BLI_remlink(&other_arc->edges, test_edge); 01207 MEM_freeN(test_edge); 01208 } 01209 } 01210 } 01211 01212 BLI_remlink(&arc->edges, first_edge); 01213 MEM_freeN(first_edge); 01214 BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->head); 01215 } 01216 else 01217 { 01218 RigEdge *next_edge = first_edge->next; 01219 01220 if (next_edge) 01221 { 01222 BLI_remlink(&arc->edges, first_edge); 01223 MEM_freeN(first_edge); 01224 01225 copy_v3_v3(arc->head->p, next_edge->head); 01226 01227 /* remove null edge in other arcs too */ 01228 for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) 01229 { 01230 if (other_arc != arc) 01231 { 01232 RigEdge *test_edge; 01233 if (other_arc->head == arc->head) 01234 { 01235 test_edge = other_arc->edges.first; 01236 BLI_remlink(&other_arc->edges, test_edge); 01237 MEM_freeN(test_edge); 01238 } 01239 else if (other_arc->tail == arc->head) 01240 { 01241 test_edge = other_arc->edges.last; 01242 BLI_remlink(&other_arc->edges, test_edge); 01243 MEM_freeN(test_edge); 01244 } 01245 } 01246 } 01247 } 01248 } 01249 } 01250 } 01251 } 01252 01253 if (last_edge->bone == NULL) 01254 { 01255 if (len_v3v3(last_edge->head, arc->tail->p) <= 0.001f) 01256 { 01257 BLI_remlink(&arc->edges, last_edge); 01258 MEM_freeN(last_edge); 01259 } 01260 else if (arc->tail->degree == 1) 01261 { 01262 RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, last_edge->head, 0.001f); 01263 01264 if (new_node) 01265 { 01266 RigEdge *previous_edge = last_edge->prev; 01267 01268 BLI_remlink(&arc->edges, last_edge); 01269 MEM_freeN(last_edge); 01270 BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->tail); 01271 01272 /* set previous angle to 0, since there's no following edges */ 01273 if (previous_edge) 01274 { 01275 previous_edge->angle = 0; 01276 } 01277 } 01278 else 01279 { 01280 RigEdge *previous_edge = last_edge->prev; 01281 01282 if (previous_edge) 01283 { 01284 BLI_remlink(&arc->edges, last_edge); 01285 MEM_freeN(last_edge); 01286 01287 copy_v3_v3(arc->tail->p, previous_edge->tail); 01288 previous_edge->angle = 0; 01289 } 01290 } 01291 } 01292 } 01293 } 01294 } 01295 01296 static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, int selected) 01297 { 01298 EditBone *bone, *last_bone = root_bone; 01299 RigArc *arc = NULL; 01300 int contain_head = 0; 01301 01302 for(bone = root_bone; bone; bone = nextEditBoneChild(list, bone, 0)) 01303 { 01304 int nb_children; 01305 01306 if (selected == 0 || (bone->flag & BONE_SELECTED)) 01307 { 01308 if ((bone->flag & BONE_NO_DEFORM) == 0) 01309 { 01310 BLI_ghash_insert(rg->bones_map, bone->name, bone); 01311 01312 if (arc == NULL) 01313 { 01314 arc = newRigArc(rg); 01315 01316 if (starting_node == NULL) 01317 { 01318 starting_node = newRigNodeHead(rg, arc, root_bone->head); 01319 } 01320 else 01321 { 01322 addRigNodeHead(rg, arc, starting_node); 01323 } 01324 } 01325 01326 if (bone->parent && (bone->flag & BONE_CONNECTED) == 0) 01327 { 01328 RIG_addEdgeToArc(arc, bone->head, NULL); 01329 } 01330 01331 RIG_addEdgeToArc(arc, bone->tail, bone); 01332 01333 last_bone = bone; 01334 01335 if (strcmp(bone->name, "head") == 0) 01336 { 01337 contain_head = 1; 01338 } 01339 } 01340 else if ((bone->flag & BONE_EDITMODE_LOCKED) == 0) /* ignore locked bones */ 01341 { 01342 RIG_addControlBone(rg, bone); 01343 } 01344 } 01345 01346 nb_children = countEditBoneChildren(list, bone); 01347 if (nb_children > 1) 01348 { 01349 RigNode *end_node = NULL; 01350 int i; 01351 01352 if (arc != NULL) 01353 { 01354 end_node = newRigNodeTail(rg, arc, bone->tail); 01355 } 01356 else 01357 { 01358 end_node = newRigNode(rg, bone->tail); 01359 } 01360 01361 for (i = 0; i < nb_children; i++) 01362 { 01363 root_bone = nextEditBoneChild(list, bone, i); 01364 RIG_arcFromBoneChain(rg, list, root_bone, end_node, selected); 01365 } 01366 01367 /* arc ends here, break */ 01368 break; 01369 } 01370 } 01371 01372 /* If the loop exited without forking */ 01373 if (arc != NULL && bone == NULL) 01374 { 01375 newRigNodeTail(rg, arc, last_bone->tail); 01376 } 01377 01378 if (contain_head) 01379 { 01380 rg->head = arc->tail; 01381 } 01382 } 01383 01384 /*******************************************************************************************************/ 01385 static void RIG_findHead(RigGraph *rg) 01386 { 01387 if (rg->head == NULL) 01388 { 01389 if (BLI_countlist(&rg->arcs) == 1) 01390 { 01391 RigArc *arc = rg->arcs.first; 01392 01393 rg->head = (RigNode*)arc->head; 01394 } 01395 else 01396 { 01397 RigArc *arc; 01398 01399 for (arc = rg->arcs.first; arc; arc = arc->next) 01400 { 01401 RigEdge *edge = arc->edges.last; 01402 01403 if (edge->bone->flag & (BONE_TIPSEL|BONE_SELECTED)) 01404 { 01405 rg->head = arc->tail; 01406 break; 01407 } 01408 } 01409 } 01410 01411 if (rg->head == NULL) 01412 { 01413 rg->head = rg->nodes.first; 01414 } 01415 } 01416 } 01417 01418 /*******************************************************************************************************/ 01419 01420 static void RIG_printNode(RigNode *node, const char name[]) 01421 { 01422 printf("%s %p %i <%0.3f, %0.3f, %0.3f>\n", name, (void *)node, node->degree, node->p[0], node->p[1], node->p[2]); 01423 01424 if (node->symmetry_flag & SYM_TOPOLOGICAL) 01425 { 01426 if (node->symmetry_flag & SYM_AXIAL) 01427 printf("Symmetry AXIAL\n"); 01428 else if (node->symmetry_flag & SYM_RADIAL) 01429 printf("Symmetry RADIAL\n"); 01430 01431 print_v3("symmetry axis", node->symmetry_axis); 01432 } 01433 } 01434 01435 void RIG_printArcBones(RigArc *arc) 01436 { 01437 RigEdge *edge; 01438 01439 for (edge = arc->edges.first; edge; edge = edge->next) 01440 { 01441 if (edge->bone) 01442 printf("%s ", edge->bone->name); 01443 else 01444 printf("---- "); 01445 } 01446 printf("\n"); 01447 } 01448 01449 static void RIG_printCtrl(RigControl *ctrl, char *indent) 01450 { 01451 char text[128]; 01452 01453 printf("%sBone: %s\n", indent, ctrl->bone->name); 01454 printf("%sLink: %s\n", indent, ctrl->link ? ctrl->link->name : "!NONE!"); 01455 01456 BLI_snprintf(text, sizeof(text), "%soffset", indent); 01457 print_v3(text, ctrl->offset); 01458 01459 printf("%sFlag: %i\n", indent, ctrl->flag); 01460 } 01461 01462 static void RIG_printLinkedCtrl(RigGraph *rg, EditBone *bone, int tabs) 01463 { 01464 RigControl *ctrl; 01465 char indent[64]; 01466 char *s = indent; 01467 int i; 01468 01469 for (i = 0; i < tabs; i++) 01470 { 01471 s[0] = '\t'; 01472 s++; 01473 } 01474 s[0] = 0; 01475 01476 for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) 01477 { 01478 if (ctrl->link == bone) 01479 { 01480 RIG_printCtrl(ctrl, indent); 01481 RIG_printLinkedCtrl(rg, ctrl->bone, tabs + 1); 01482 } 01483 } 01484 } 01485 01486 void RIG_printArc(RigGraph *rg, RigArc *arc) 01487 { 01488 RigEdge *edge; 01489 01490 RIG_printNode((RigNode*)arc->head, "head"); 01491 01492 for (edge = arc->edges.first; edge; edge = edge->next) 01493 { 01494 printf("\tinner joints %0.3f %0.3f %0.3f\n", edge->tail[0], edge->tail[1], edge->tail[2]); 01495 printf("\t\tlength %f\n", edge->length); 01496 printf("\t\tangle %f\n", edge->angle * 180 / M_PI); 01497 if (edge->bone) 01498 { 01499 printf("\t\t%s\n", edge->bone->name); 01500 RIG_printLinkedCtrl(rg, edge->bone, 3); 01501 } 01502 } 01503 printf("symmetry level: %i flag: %i group %i\n", arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group); 01504 01505 RIG_printNode((RigNode*)arc->tail, "tail"); 01506 } 01507 01508 void RIG_printGraph(RigGraph *rg) 01509 { 01510 RigArc *arc; 01511 01512 printf("---- ARCS ----\n"); 01513 for (arc = rg->arcs.first; arc; arc = arc->next) 01514 { 01515 RIG_printArc(rg, arc); 01516 printf("\n"); 01517 } 01518 01519 if (rg->head) 01520 { 01521 RIG_printNode(rg->head, "HEAD NODE:"); 01522 } 01523 else 01524 { 01525 printf("HEAD NODE: NONE\n"); 01526 } 01527 } 01528 01529 /*******************************************************************************************************/ 01530 01531 RigGraph *RIG_graphFromArmature(const bContext *C, Object *ob, bArmature *arm) 01532 { 01533 Object *obedit = CTX_data_edit_object(C); 01534 Scene *scene = CTX_data_scene(C); 01535 EditBone *ebone; 01536 RigGraph *rg; 01537 01538 rg = newRigGraph(); 01539 01540 if (obedit == ob) 01541 { 01542 rg->editbones = ((bArmature *)obedit->data)->edbo; 01543 } 01544 else 01545 { 01546 rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones"); 01547 make_boneList(rg->editbones, &arm->bonebase, NULL, NULL); 01548 rg->flag |= RIG_FREE_BONELIST; 01549 } 01550 01551 rg->ob = ob; 01552 01553 /* Do the rotations */ 01554 for (ebone = rg->editbones->first; ebone; ebone=ebone->next){ 01555 if (ebone->parent == NULL) 01556 { 01557 RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 0); 01558 } 01559 } 01560 01561 BLI_removeDoubleNodes((BGraph*)rg, 0.001); 01562 01563 RIG_removeNormalNodes(rg); 01564 01565 RIG_removeUneededOffsets(rg); 01566 01567 BLI_buildAdjacencyList((BGraph*)rg); 01568 01569 RIG_findHead(rg); 01570 01571 BLI_markdownSymmetry((BGraph*)rg, (BNode*)rg->head, scene->toolsettings->skgen_symmetry_limit); 01572 01573 RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */ 01574 01575 if (BLI_isGraphCyclic((BGraph*)rg)) 01576 { 01577 printf("armature cyclic\n"); 01578 } 01579 01580 return rg; 01581 } 01582 01583 static RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm) 01584 { 01585 Object *obedit = CTX_data_edit_object(C); 01586 Scene *scene = CTX_data_scene(C); 01587 EditBone *ebone; 01588 RigGraph *rg; 01589 01590 rg = newRigGraph(); 01591 01592 if (obedit == ob) 01593 { 01594 rg->editbones = arm->edbo; 01595 } 01596 else 01597 { 01598 rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones"); 01599 make_boneList(rg->editbones, &arm->bonebase, NULL, NULL); 01600 rg->flag |= RIG_FREE_BONELIST; 01601 } 01602 01603 rg->ob = ob; 01604 01605 /* Do the rotations */ 01606 for (ebone = rg->editbones->first; ebone; ebone=ebone->next){ 01607 if (ebone->parent == NULL) 01608 { 01609 RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 1); 01610 } 01611 } 01612 01613 BLI_removeDoubleNodes((BGraph*)rg, 0.001); 01614 01615 RIG_removeNormalNodes(rg); 01616 01617 RIG_removeUneededOffsets(rg); 01618 01619 BLI_buildAdjacencyList((BGraph*)rg); 01620 01621 RIG_findHead(rg); 01622 01623 BLI_markdownSymmetry((BGraph*)rg, (BNode*)rg->head, scene->toolsettings->skgen_symmetry_limit); 01624 01625 RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */ 01626 01627 if (BLI_isGraphCyclic((BGraph*)rg)) 01628 { 01629 printf("armature cyclic\n"); 01630 } 01631 01632 return rg; 01633 } 01634 /************************************ GENERATING *****************************************************/ 01635 01636 #if 0 01637 static EditBone *add_editbonetolist(char *name, ListBase *list) 01638 { 01639 EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone"); 01640 01641 BLI_strncpy(bone->name, name, sizeof(bone->name)); 01642 unique_editbone_name(list, bone->name, NULL); 01643 01644 BLI_addtail(list, bone); 01645 01646 bone->flag |= BONE_TIPSEL; 01647 bone->weight= 1.0F; 01648 bone->dist= 0.25F; 01649 bone->xwidth= 0.1; 01650 bone->zwidth= 0.1; 01651 bone->ease1= 1.0; 01652 bone->ease2= 1.0; 01653 bone->rad_head= 0.10; 01654 bone->rad_tail= 0.05; 01655 bone->segments= 1; 01656 bone->layer= 1;//arm->layer; 01657 01658 return bone; 01659 } 01660 #endif 01661 01662 #if 0 /* UNUSED */ 01663 static void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level_limit) 01664 { 01665 while (node->multi_level > multi_level_limit && node->link_up) 01666 { 01667 node = node->link_up; 01668 } 01669 01670 while (node->multi_level < multi_level_limit && node->link_down) 01671 { 01672 node = node->link_down; 01673 } 01674 01675 if (node->multi_level == multi_level_limit) 01676 { 01677 int i; 01678 01679 for (i = 0; i < node->degree; i++) 01680 { 01681 ReebArc *earc = node->arcs[i]; 01682 01683 if (earc->flag == ARC_FREE && earc->head == node) 01684 { 01685 ReebNode *other = BIF_otherNodeFromIndex(earc, node); 01686 01687 earc->flag = ARC_USED; 01688 01689 //generateBonesForArc(rigg, earc, node, other); 01690 generateMissingArcsFromNode(rigg, other, multi_level_limit); 01691 } 01692 } 01693 } 01694 } 01695 01696 static void generateMissingArcs(RigGraph *rigg) 01697 { 01698 ReebGraph *reebg; 01699 int multi_level_limit = 5; 01700 01701 for (reebg = rigg->link_mesh; reebg; reebg = reebg->link_up) 01702 { 01703 ReebArc *earc; 01704 01705 for (earc = reebg->arcs.first; earc; earc = earc->next) 01706 { 01707 if (earc->flag == ARC_USED) 01708 { 01709 generateMissingArcsFromNode(rigg, earc->head, multi_level_limit); 01710 generateMissingArcsFromNode(rigg, earc->tail, multi_level_limit); 01711 } 01712 } 01713 } 01714 } 01715 #endif 01716 01717 /************************************ RETARGETTING *****************************************************/ 01718 01719 static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize); 01720 01721 static void repositionTailControl(RigGraph *rigg, RigControl *ctrl); 01722 01723 static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize) 01724 { 01725 if ((ctrl->flag & RIG_CTRL_DONE) == RIG_CTRL_DONE) 01726 { 01727 RigControl *ctrl_child; 01728 01729 #if 0 01730 printf("CTRL: %s LINK: %s", ctrl->bone->name, ctrl->link->name); 01731 01732 if (ctrl->link_tail) 01733 { 01734 printf(" TAIL: %s", ctrl->link_tail->name); 01735 } 01736 01737 printf("\n"); 01738 #endif 01739 01740 /* if there was a tail link: apply link, recalc resize factor and qrot */ 01741 if (ctrl->tail_mode != TL_NONE) 01742 { 01743 float *tail_vec = NULL; 01744 float v1[3], v2[3], qtail[4]; 01745 01746 if (ctrl->tail_mode == TL_TAIL) 01747 { 01748 tail_vec = ctrl->link_tail->tail; 01749 } 01750 else if (ctrl->tail_mode == TL_HEAD) 01751 { 01752 tail_vec = ctrl->link_tail->head; 01753 } 01754 01755 sub_v3_v3v3(v1, ctrl->bone->tail, ctrl->bone->head); 01756 sub_v3_v3v3(v2, tail_vec, ctrl->bone->head); 01757 01758 copy_v3_v3(ctrl->bone->tail, tail_vec); 01759 01760 rotation_between_vecs_to_quat(qtail, v1, v2); 01761 mul_qt_qtqt(ctrl->qrot, qtail, ctrl->qrot); 01762 01763 resize = len_v3(v2) / len_v3v3(ctrl->head, ctrl->tail); 01764 } 01765 01766 ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, ctrl->qrot); 01767 01768 /* Cascade to connected control bones */ 01769 for (ctrl_child = rigg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) 01770 { 01771 if (ctrl_child->link == ctrl->bone) 01772 { 01773 repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, ctrl->qrot, resize); 01774 } 01775 if (ctrl_child->link_tail == ctrl->bone) 01776 { 01777 repositionTailControl(rigg, ctrl_child); 01778 } 01779 } 01780 } 01781 } 01782 01783 static void repositionTailControl(RigGraph *rigg, RigControl *ctrl) 01784 { 01785 ctrl->flag |= RIG_CTRL_TAIL_DONE; 01786 01787 finalizeControl(rigg, ctrl, 1); /* resize will be recalculated anyway so we don't need it */ 01788 } 01789 01790 static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float UNUSED(tail[3]), float qrot[4], float resize) 01791 { 01792 float parent_offset[3], tail_offset[3]; 01793 01794 copy_v3_v3(parent_offset, ctrl->offset); 01795 mul_v3_fl(parent_offset, resize); 01796 mul_qt_v3(qrot, parent_offset); 01797 01798 add_v3_v3v3(ctrl->bone->head, head, parent_offset); 01799 01800 ctrl->flag |= RIG_CTRL_HEAD_DONE; 01801 01802 copy_qt_qt(ctrl->qrot, qrot); 01803 01804 if (ctrl->tail_mode == TL_NONE) 01805 { 01806 sub_v3_v3v3(tail_offset, ctrl->tail, ctrl->head); 01807 mul_v3_fl(tail_offset, resize); 01808 mul_qt_v3(qrot, tail_offset); 01809 01810 add_v3_v3v3(ctrl->bone->tail, ctrl->bone->head, tail_offset); 01811 01812 ctrl->flag |= RIG_CTRL_TAIL_DONE; 01813 } 01814 01815 finalizeControl(rigg, ctrl, resize); 01816 } 01817 01818 static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec0[3], float vec1[3], float up_axis[3]) 01819 { 01820 Scene *scene = CTX_data_scene(C); 01821 EditBone *bone; 01822 RigControl *ctrl; 01823 float qrot[4], resize; 01824 float v1[3], v2[3]; 01825 float l1, l2; 01826 01827 bone = edge->bone; 01828 01829 sub_v3_v3v3(v1, edge->tail, edge->head); 01830 sub_v3_v3v3(v2, vec1, vec0); 01831 01832 l1 = normalize_v3(v1); 01833 l2 = normalize_v3(v2); 01834 01835 resize = l2 / l1; 01836 01837 rotation_between_vecs_to_quat(qrot, v1, v2); 01838 01839 copy_v3_v3(bone->head, vec0); 01840 copy_v3_v3(bone->tail, vec1); 01841 01842 if (!is_zero_v3(up_axis)) 01843 { 01844 float qroll[4]; 01845 01846 if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_VIEW) 01847 { 01848 bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis); 01849 } 01850 else if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT) 01851 { 01852 bone->roll = rollBoneByQuatJoint(edge, edge->prev, qrot, qroll, up_axis); 01853 } 01854 else 01855 { 01856 unit_qt(qroll); 01857 } 01858 01859 mul_qt_qtqt(qrot, qroll, qrot); 01860 } 01861 else 01862 { 01863 bone->roll = rollBoneByQuat(bone, edge->up_axis, qrot); 01864 } 01865 01866 for (ctrl = rigg->controls.first; ctrl; ctrl = ctrl->next) 01867 { 01868 if (ctrl->link == bone) 01869 { 01870 repositionControl(rigg, ctrl, vec0, vec1, qrot, resize); 01871 } 01872 if (ctrl->link_tail == bone) 01873 { 01874 repositionTailControl(rigg, ctrl); 01875 } 01876 } 01877 } 01878 01879 static RetargetMode detectArcRetargetMode(RigArc *arc); 01880 static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start); 01881 01882 01883 static RetargetMode detectArcRetargetMode(RigArc *iarc) 01884 { 01885 RetargetMode mode = RETARGET_AGGRESSIVE; 01886 ReebArc *earc = iarc->link_mesh; 01887 RigEdge *edge; 01888 int large_angle = 0; 01889 float avg_angle = 0; 01890 /* float avg_length = 0; */ /* UNUSED */ 01891 int nb_edges = 0; 01892 01893 01894 for (edge = iarc->edges.first; edge; edge = edge->next) 01895 { 01896 avg_angle += edge->angle; 01897 nb_edges++; 01898 } 01899 01900 avg_angle /= nb_edges - 1; /* -1 because last edge doesn't have an angle */ 01901 01902 /* avg_length = iarc->length / nb_edges; */ /* UNUSED */ 01903 01904 01905 if (nb_edges > 2) 01906 { 01907 for (edge = iarc->edges.first; edge; edge = edge->next) 01908 { 01909 if (fabs(edge->angle - avg_angle) > M_PI / 6) 01910 { 01911 large_angle = 1; 01912 } 01913 } 01914 } 01915 else if (nb_edges == 2 && avg_angle > 0) 01916 { 01917 large_angle = 1; 01918 } 01919 01920 01921 if (large_angle == 0) 01922 { 01923 mode = RETARGET_LENGTH; 01924 } 01925 01926 if (earc->bcount <= (iarc->count - 1)) 01927 { 01928 mode = RETARGET_LENGTH; 01929 } 01930 01931 return mode; 01932 } 01933 01934 #ifndef USE_THREADS 01935 static void printMovesNeeded(int *positions, int nb_positions) 01936 { 01937 int moves = 0; 01938 int i; 01939 01940 for (i = 0; i < nb_positions; i++) 01941 { 01942 moves += positions[i] - (i + 1); 01943 } 01944 01945 printf("%i moves needed\n", moves); 01946 } 01947 01948 static void printPositions(int *positions, int nb_positions) 01949 { 01950 int i; 01951 01952 for (i = 0; i < nb_positions; i++) 01953 { 01954 printf("%i ", positions[i]); 01955 } 01956 printf("\n"); 01957 } 01958 #endif 01959 01960 #define MAX_COST FLT_MAX /* FIX ME */ 01961 01962 static float costDistance(BArcIterator *iter, float *vec0, float *vec1, int i0, int i1, float distance_weight) 01963 { 01964 EmbedBucket *bucket = NULL; 01965 float max_dist = 0; 01966 float v1[3], v2[3], c[3]; 01967 float v1_inpf; 01968 01969 if (distance_weight > 0) 01970 { 01971 sub_v3_v3v3(v1, vec0, vec1); 01972 01973 v1_inpf = dot_v3v3(v1, v1); 01974 01975 if (v1_inpf > 0) 01976 { 01977 int j; 01978 for (j = i0 + 1; j < i1 - 1; j++) 01979 { 01980 float dist; 01981 01982 bucket = IT_peek(iter, j); 01983 01984 sub_v3_v3v3(v2, bucket->p, vec1); 01985 01986 cross_v3_v3v3(c, v1, v2); 01987 01988 dist = dot_v3v3(c, c) / v1_inpf; 01989 01990 max_dist = dist > max_dist ? dist : max_dist; 01991 } 01992 01993 return distance_weight * max_dist; 01994 } 01995 else 01996 { 01997 return MAX_COST; 01998 } 01999 } 02000 else 02001 { 02002 return 0; 02003 } 02004 } 02005 02006 static float costAngle(float original_angle, float vec_first[3], float vec_second[3], float angle_weight) 02007 { 02008 if (angle_weight > 0) 02009 { 02010 float current_angle; 02011 02012 if (!is_zero_v3(vec_first) && !is_zero_v3(vec_second)) 02013 { 02014 current_angle = saacos(dot_v3v3(vec_first, vec_second)); 02015 02016 return angle_weight * fabsf(current_angle - original_angle); 02017 } 02018 else 02019 { 02020 return angle_weight * (float)M_PI; 02021 } 02022 } 02023 else 02024 { 02025 return 0; 02026 } 02027 } 02028 02029 static float costLength(float original_length, float current_length, float length_weight) 02030 { 02031 if (current_length == 0) 02032 { 02033 return MAX_COST; 02034 } 02035 else 02036 { 02037 float length_ratio = fabs((current_length - original_length) / original_length); 02038 return length_weight * length_ratio * length_ratio; 02039 } 02040 } 02041 02042 #if 0 02043 static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2) 02044 { 02045 float vec[3]; 02046 float length; 02047 02048 sub_v3_v3v3(vec, vec2, vec1); 02049 length = normalize_v3(vec); 02050 02051 return costLength(edge->length, length) + costDistance(iter, vec1, vec2, i1, i2); 02052 } 02053 #endif 02054 02055 static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge, float *vec0, float *vec1, float *vec2, int i1, int i2, float angle_weight, float length_weight, float distance_weight) 02056 { 02057 float vec_second[3], vec_first[3]; 02058 float length2; 02059 float new_cost = 0; 02060 02061 sub_v3_v3v3(vec_second, vec2, vec1); 02062 length2 = normalize_v3(vec_second); 02063 02064 02065 /* Angle cost */ 02066 if (edge->prev) 02067 { 02068 sub_v3_v3v3(vec_first, vec1, vec0); 02069 normalize_v3(vec_first); 02070 02071 new_cost += costAngle(edge->prev->angle, vec_first, vec_second, angle_weight); 02072 } 02073 02074 /* Length cost */ 02075 new_cost += costLength(edge->length, length2, length_weight); 02076 02077 /* Distance cost */ 02078 new_cost += costDistance(iter, vec1, vec2, i1, i2, distance_weight); 02079 02080 return new_cost; 02081 } 02082 02083 static int indexMemoNode(int nb_positions, int previous, int current, int joints_left) 02084 { 02085 return joints_left * nb_positions * nb_positions + current * nb_positions + previous; 02086 } 02087 02088 static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions, int joints_left) 02089 { 02090 int previous = 0, current = 0; 02091 int i = 0; 02092 02093 for (i = 0; joints_left > 0; joints_left--, i++) 02094 { 02095 MemoNode *node; 02096 node = table + indexMemoNode(nb_positions, previous, current, joints_left); 02097 02098 positions[i] = node->next; 02099 02100 previous = current; 02101 current = node->next; 02102 } 02103 } 02104 02105 static MemoNode * solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache, int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, int joints_left, float angle_weight, float length_weight, float distance_weight) 02106 { 02107 MemoNode *node; 02108 int index = indexMemoNode(nb_positions, previous, current, joints_left); 02109 02110 node = table + index; 02111 02112 if (node->weight != 0) 02113 { 02114 return node; 02115 } 02116 else if (joints_left == 0) 02117 { 02118 float *vec0 = vec_cache[previous]; 02119 float *vec1 = vec_cache[current]; 02120 float *vec2 = vec_cache[nb_positions + 1]; 02121 02122 node->weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, iter->length, angle_weight, length_weight, distance_weight); 02123 02124 return node; 02125 } 02126 else 02127 { 02128 MemoNode *min_node = NULL; 02129 float *vec0 = vec_cache[previous]; 02130 float *vec1 = vec_cache[current]; 02131 float min_weight= 0.0f; 02132 int min_next= 0; 02133 int next; 02134 02135 for (next = current + 1; next <= nb_positions - (joints_left - 1); next++) 02136 { 02137 MemoNode *next_node; 02138 float *vec2 = vec_cache[next]; 02139 float weight = 0.0f; 02140 02141 /* ADD WEIGHT OF PREVIOUS - CURRENT - NEXT triple */ 02142 weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, next, angle_weight, length_weight, distance_weight); 02143 02144 if (weight >= MAX_COST) 02145 { 02146 continue; 02147 } 02148 02149 /* add node weight */ 02150 next_node = solveJoints(table, iter, vec_cache, nb_joints, nb_positions, current, next, edge->next, joints_left - 1, angle_weight, length_weight, distance_weight); 02151 weight += next_node->weight; 02152 02153 if (min_node == NULL || weight < min_weight) 02154 { 02155 min_weight = weight; 02156 min_node = next_node; 02157 min_next = next; 02158 } 02159 } 02160 02161 if (min_node) 02162 { 02163 node->weight = min_weight; 02164 node->next = min_next; 02165 return node; 02166 } 02167 else 02168 { 02169 node->weight = MAX_COST; 02170 return node; 02171 } 02172 } 02173 02174 } 02175 02176 static int testFlipArc(RigArc *iarc, RigNode *inode_start) 02177 { 02178 ReebArc *earc = iarc->link_mesh; 02179 ReebNode *enode_start = BIF_NodeFromIndex(earc, inode_start->link_mesh); 02180 02181 /* no flip needed if both nodes are the same */ 02182 if ((enode_start == earc->head && inode_start == iarc->head) || (enode_start == earc->tail && inode_start == iarc->tail)) 02183 { 02184 return 0; 02185 } 02186 else 02187 { 02188 return 1; 02189 } 02190 } 02191 02192 static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start) 02193 { 02194 ReebArcIterator arc_iter; 02195 BArcIterator *iter = (BArcIterator*)&arc_iter; 02196 RigEdge *edge; 02197 EmbedBucket *bucket = NULL; 02198 ReebNode *node_start, *node_end; 02199 ReebArc *earc = iarc->link_mesh; 02200 float angle_weight = 1.0; // GET FROM CONTEXT 02201 float length_weight = 1.0; 02202 float distance_weight = 1.0; 02203 #ifndef USE_THREADS 02204 float min_cost = FLT_MAX; 02205 #endif 02206 float *vec0, *vec1; 02207 int *best_positions; 02208 int nb_edges = BLI_countlist(&iarc->edges); 02209 int nb_joints = nb_edges - 1; 02210 RetargetMethod method = METHOD_MEMOIZE; 02211 int i; 02212 02213 if (nb_joints > earc->bcount) 02214 { 02215 printf("NOT ENOUGH BUCKETS!\n"); 02216 return; 02217 } 02218 02219 best_positions = MEM_callocN(sizeof(int) * nb_joints, "Best positions"); 02220 02221 if (testFlipArc(iarc, inode_start)) 02222 { 02223 node_start = earc->tail; 02224 node_end = earc->head; 02225 } 02226 else 02227 { 02228 node_start = earc->head; 02229 node_end = earc->tail; 02230 } 02231 02232 /* equal number of joints and potential position, just fill them in */ 02233 if (nb_joints == earc->bcount) 02234 { 02235 int i; 02236 02237 /* init with first values */ 02238 for (i = 0; i < nb_joints; i++) 02239 { 02240 best_positions[i] = i + 1; 02241 } 02242 } 02243 if (method == METHOD_MEMOIZE) 02244 { 02245 int nb_positions = earc->bcount; 02246 int nb_memo_nodes = nb_positions * nb_positions * (nb_joints + 1); 02247 MemoNode *table = MEM_callocN(nb_memo_nodes * sizeof(MemoNode), "memoization table"); 02248 #ifndef USE_THREADS 02249 MemoNode *result; 02250 #endif 02251 float **positions_cache = MEM_callocN(sizeof(float*) * (nb_positions + 2), "positions cache"); 02252 int i; 02253 02254 positions_cache[0] = node_start->p; 02255 positions_cache[nb_positions + 1] = node_end->p; 02256 02257 initArcIterator(iter, earc, node_start); 02258 02259 for (i = 1; i <= nb_positions; i++) 02260 { 02261 EmbedBucket *bucket = IT_peek(iter, i); 02262 positions_cache[i] = bucket->p; 02263 } 02264 02265 #ifndef USE_THREADS 02266 result = solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight); 02267 min_cost = result->weight; 02268 #else 02269 solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight); 02270 #endif 02271 02272 copyMemoPositions(best_positions, table, earc->bcount, nb_joints); 02273 02274 MEM_freeN(table); 02275 MEM_freeN(positions_cache); 02276 } 02277 02278 vec0 = node_start->p; 02279 initArcIterator(iter, earc, node_start); 02280 02281 #ifndef USE_THREADS 02282 printPositions(best_positions, nb_joints); 02283 printMovesNeeded(best_positions, nb_joints); 02284 printf("min_cost %f\n", min_cost); 02285 printf("buckets: %i\n", earc->bcount); 02286 #endif 02287 02288 /* set joints to best position */ 02289 for (edge = iarc->edges.first, i = 0; 02290 edge; 02291 edge = edge->next, i++) 02292 { 02293 float *no = NULL; 02294 if (i < nb_joints) 02295 { 02296 bucket = IT_peek(iter, best_positions[i]); 02297 vec1 = bucket->p; 02298 no = bucket->no; 02299 } 02300 else 02301 { 02302 vec1 = node_end->p; 02303 no = node_end->no; 02304 } 02305 02306 if (edge->bone) 02307 { 02308 repositionBone(C, rigg, edge, vec0, vec1, no); 02309 } 02310 02311 vec0 = vec1; 02312 } 02313 02314 MEM_freeN(best_positions); 02315 } 02316 02317 static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start) 02318 { 02319 ReebArcIterator arc_iter; 02320 BArcIterator *iter = (BArcIterator*)&arc_iter; 02321 ReebArc *earc = iarc->link_mesh; 02322 ReebNode *node_start, *node_end; 02323 RigEdge *edge; 02324 EmbedBucket *bucket = NULL; 02325 float embedding_length = 0; 02326 float *vec0 = NULL; 02327 float *vec1 = NULL; 02328 float *previous_vec = NULL; 02329 02330 02331 if (testFlipArc(iarc, inode_start)) 02332 { 02333 node_start = (ReebNode*)earc->tail; 02334 node_end = (ReebNode*)earc->head; 02335 } 02336 else 02337 { 02338 node_start = (ReebNode*)earc->head; 02339 node_end = (ReebNode*)earc->tail; 02340 } 02341 02342 initArcIterator(iter, earc, node_start); 02343 02344 bucket = IT_next(iter); 02345 02346 vec0 = node_start->p; 02347 02348 while (bucket != NULL) 02349 { 02350 vec1 = bucket->p; 02351 02352 embedding_length += len_v3v3(vec0, vec1); 02353 02354 vec0 = vec1; 02355 bucket = IT_next(iter); 02356 } 02357 02358 embedding_length += len_v3v3(node_end->p, vec1); 02359 02360 /* fit bones */ 02361 initArcIterator(iter, earc, node_start); 02362 02363 bucket = IT_next(iter); 02364 02365 vec0 = node_start->p; 02366 previous_vec = vec0; 02367 vec1 = bucket->p; 02368 02369 for (edge = iarc->edges.first; edge; edge = edge->next) 02370 { 02371 float new_bone_length = edge->length / iarc->length * embedding_length; 02372 float *no = NULL; 02373 float length = 0; 02374 02375 while (bucket && new_bone_length > length) 02376 { 02377 length += len_v3v3(previous_vec, vec1); 02378 bucket = IT_next(iter); 02379 previous_vec = vec1; 02380 vec1 = bucket->p; 02381 no = bucket->no; 02382 } 02383 02384 if (bucket == NULL) 02385 { 02386 vec1 = node_end->p; 02387 no = node_end->no; 02388 } 02389 02390 /* no need to move virtual edges (space between unconnected bones) */ 02391 if (edge->bone) 02392 { 02393 repositionBone(C, rigg, edge, vec0, vec1, no); 02394 } 02395 02396 vec0 = vec1; 02397 previous_vec = vec1; 02398 } 02399 } 02400 02401 static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start) 02402 { 02403 #ifdef USE_THREADS 02404 RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam"); 02405 02406 p->rigg = rigg; 02407 p->iarc = iarc; 02408 p->inode_start = inode_start; 02409 p->context = C; 02410 02411 BLI_insert_work(rigg->worker, p); 02412 #else 02413 RetargetParam p; 02414 02415 p.rigg = rigg; 02416 p.iarc = iarc; 02417 p.inode_start = inode_start; 02418 p.context = C; 02419 02420 exec_retargetArctoArc(&p); 02421 #endif 02422 } 02423 02424 void *exec_retargetArctoArc(void *param) 02425 { 02426 RetargetParam *p = (RetargetParam*)param; 02427 RigGraph *rigg = p->rigg; 02428 RigArc *iarc = p->iarc; 02429 bContext *C = p->context; 02430 RigNode *inode_start = p->inode_start; 02431 ReebArc *earc = iarc->link_mesh; 02432 02433 if (BLI_countlist(&iarc->edges) == 1) 02434 { 02435 RigEdge *edge = iarc->edges.first; 02436 02437 if (testFlipArc(iarc, inode_start)) 02438 { 02439 repositionBone(C, rigg, edge, earc->tail->p, earc->head->p, earc->head->no); 02440 } 02441 else 02442 { 02443 repositionBone(C, rigg, edge, earc->head->p, earc->tail->p, earc->tail->no); 02444 } 02445 } 02446 else 02447 { 02448 RetargetMode mode = detectArcRetargetMode(iarc); 02449 02450 if (mode == RETARGET_AGGRESSIVE) 02451 { 02452 retargetArctoArcAggresive(C, rigg, iarc, inode_start); 02453 } 02454 else 02455 { 02456 retargetArctoArcLength(C, rigg, iarc, inode_start); 02457 } 02458 } 02459 02460 #ifdef USE_THREADS 02461 MEM_freeN(p); 02462 #endif 02463 02464 return NULL; 02465 } 02466 02467 static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node) 02468 { 02469 ReebNode *enode = top_node; 02470 ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); 02471 int ishape, eshape; 02472 02473 ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)inode, NULL, 0) % SHAPE_LEVELS; 02474 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS; 02475 02476 inode->link_mesh = enode; 02477 02478 while (ishape == eshape && enode->link_down) 02479 { 02480 inode->link_mesh = enode; 02481 02482 enode = enode->link_down; 02483 reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); /* replace with call to link_down once that exists */ 02484 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS; 02485 } 02486 } 02487 02488 static void markMultiResolutionChildArc(ReebNode *end_enode, ReebNode *enode) 02489 { 02490 int i; 02491 02492 for(i = 0; i < enode->degree; i++) 02493 { 02494 ReebArc *earc = (ReebArc*)enode->arcs[i]; 02495 02496 if (earc->flag == ARC_FREE) 02497 { 02498 earc->flag = ARC_TAKEN; 02499 02500 if (earc->tail->degree > 1 && earc->tail != end_enode) 02501 { 02502 markMultiResolutionChildArc(end_enode, earc->tail); 02503 } 02504 break; 02505 } 02506 } 02507 } 02508 02509 static void markMultiResolutionArc(ReebArc *start_earc) 02510 { 02511 if (start_earc->link_up) 02512 { 02513 ReebArc *earc; 02514 for (earc = start_earc->link_up ; earc; earc = earc->link_up) 02515 { 02516 earc->flag = ARC_TAKEN; 02517 02518 if (earc->tail->index != start_earc->tail->index) 02519 { 02520 markMultiResolutionChildArc(earc->tail, earc->tail); 02521 } 02522 } 02523 } 02524 } 02525 02526 static void matchMultiResolutionArc(RigGraph *rigg, RigNode *start_node, RigArc *next_iarc, ReebArc *next_earc) 02527 { 02528 ReebNode *enode = next_earc->head; 02529 ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); 02530 int ishape, eshape; 02531 02532 ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)start_node, (BArc*)next_iarc, 1) % SHAPE_LEVELS; 02533 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, (BArc*)next_earc, 1) % SHAPE_LEVELS; 02534 02535 while (ishape != eshape && next_earc->link_up) 02536 { 02537 next_earc->flag = ARC_TAKEN; // mark previous as taken, to prevent backtrack on lower levels 02538 02539 next_earc = next_earc->link_up; 02540 reebg = reebg->link_up; 02541 enode = next_earc->head; 02542 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, (BArc*)next_earc, 1) % SHAPE_LEVELS; 02543 } 02544 02545 next_earc->flag = ARC_USED; 02546 next_iarc->link_mesh = next_earc; 02547 02548 /* mark all higher levels as taken too */ 02549 markMultiResolutionArc(next_earc); 02550 // while (next_earc->link_up) 02551 // { 02552 // next_earc = next_earc->link_up; 02553 // next_earc->flag = ARC_TAKEN; 02554 // } 02555 } 02556 02557 static void matchMultiResolutionStartingNode(RigGraph *rigg, ReebGraph *reebg, RigNode *inode) 02558 { 02559 ReebNode *enode; 02560 int ishape, eshape; 02561 02562 enode = reebg->nodes.first; 02563 02564 ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)inode, NULL, 0) % SHAPE_LEVELS; 02565 eshape = BLI_subtreeShape((BGraph*)rigg->link_mesh, (BNode*)enode, NULL, 0) % SHAPE_LEVELS; 02566 02567 while (ishape != eshape && reebg->link_up) 02568 { 02569 reebg = reebg->link_up; 02570 02571 enode = reebg->nodes.first; 02572 02573 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS; 02574 } 02575 02576 inode->link_mesh = enode; 02577 } 02578 02579 static void findCorrespondingArc(RigGraph *rigg, RigArc *start_arc, RigNode *start_node, RigArc *next_iarc, int root) 02580 { 02581 ReebNode *enode = start_node->link_mesh; 02582 ReebArc *next_earc; 02583 int symmetry_level = next_iarc->symmetry_level; 02584 int symmetry_group = next_iarc->symmetry_group; 02585 int symmetry_flag = next_iarc->symmetry_flag; 02586 int i; 02587 02588 next_iarc->link_mesh = NULL; 02589 02590 // if (root) 02591 // { 02592 // printf("-----------------------\n"); 02593 // printf("MATCHING LIMB\n"); 02594 // RIG_printArcBones(next_iarc); 02595 // } 02596 02597 for(i = 0; i < enode->degree; i++) 02598 { 02599 next_earc = (ReebArc*)enode->arcs[i]; 02600 02601 // if (next_earc->flag == ARC_FREE) 02602 // { 02603 // printf("candidate (level %i ?= %i) (flag %i ?= %i) (group %i ?= %i)\n", 02604 // symmetry_level, next_earc->symmetry_level, 02605 // symmetry_flag, next_earc->symmetry_flag, 02606 // symmetry_group, next_earc->symmetry_flag); 02607 // } 02608 02609 if (next_earc->flag == ARC_FREE && 02610 next_earc->symmetry_flag == symmetry_flag && 02611 next_earc->symmetry_group == symmetry_group && 02612 next_earc->symmetry_level == symmetry_level) 02613 { 02614 // printf("CORRESPONDING ARC FOUND\n"); 02615 // printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group); 02616 02617 matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc); 02618 break; 02619 } 02620 } 02621 02622 /* not found, try at higher nodes (lower node might have filtered internal arcs, messing shape of tree */ 02623 if (next_iarc->link_mesh == NULL) 02624 { 02625 // printf("NO CORRESPONDING ARC FOUND - GOING TO HIGHER LEVELS\n"); 02626 02627 if (enode->link_up) 02628 { 02629 start_node->link_mesh = enode->link_up; 02630 findCorrespondingArc(rigg, start_arc, start_node, next_iarc, 0); 02631 } 02632 } 02633 02634 /* still not found, print debug info */ 02635 if (root && next_iarc->link_mesh == NULL) 02636 { 02637 start_node->link_mesh = enode; /* linking back with root node */ 02638 02639 // printf("NO CORRESPONDING ARC FOUND\n"); 02640 // RIG_printArcBones(next_iarc); 02641 // 02642 // printf("ON NODE %i, multilevel %i\n", enode->index, enode->multi_level); 02643 // 02644 // printf("LOOKING FOR\n"); 02645 // printf("flag %i -- level %i -- flag %i -- group %i\n", ARC_FREE, symmetry_level, symmetry_flag, symmetry_group); 02646 // 02647 // printf("CANDIDATES\n"); 02648 // for(i = 0; i < enode->degree; i++) 02649 // { 02650 // next_earc = (ReebArc*)enode->arcs[i]; 02651 // printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group); 02652 // } 02653 02654 /* Emergency matching */ 02655 for(i = 0; i < enode->degree; i++) 02656 { 02657 next_earc = (ReebArc*)enode->arcs[i]; 02658 02659 if (next_earc->flag == ARC_FREE && next_earc->symmetry_level == symmetry_level) 02660 { 02661 // printf("USING: \n"); 02662 // printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group); 02663 matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc); 02664 break; 02665 } 02666 } 02667 } 02668 02669 } 02670 02671 static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, RigNode *start_node) 02672 { 02673 RigNode *inode = start_node; 02674 int i; 02675 02676 /* no start arc on first node */ 02677 if (start_arc) 02678 { 02679 ReebNode *enode = start_node->link_mesh; 02680 ReebArc *earc = start_arc->link_mesh; 02681 02682 retargetArctoArc(C, rigg, start_arc, start_node); 02683 02684 enode = BIF_otherNodeFromIndex(earc, enode); 02685 inode = (RigNode*)BLI_otherNode((BArc*)start_arc, (BNode*)inode); 02686 02687 /* match with lowest node with correct shape */ 02688 matchMultiResolutionNode(rigg, inode, enode); 02689 } 02690 02691 for(i = 0; i < inode->degree; i++) 02692 { 02693 RigArc *next_iarc = (RigArc*)inode->arcs[i]; 02694 02695 /* no back tracking */ 02696 if (next_iarc != start_arc) 02697 { 02698 findCorrespondingArc(rigg, start_arc, inode, next_iarc, 1); 02699 if (next_iarc->link_mesh) 02700 { 02701 retargetSubgraph(C, rigg, next_iarc, inode); 02702 } 02703 } 02704 } 02705 } 02706 02707 static void finishRetarget(RigGraph *rigg) 02708 { 02709 #ifdef USE_THREADS 02710 BLI_end_worker(rigg->worker); 02711 #endif 02712 } 02713 02714 static void adjustGraphs(bContext *C, RigGraph *rigg) 02715 { 02716 bArmature *arm= rigg->ob->data; 02717 RigArc *arc; 02718 02719 for (arc = rigg->arcs.first; arc; arc = arc->next) 02720 { 02721 if (arc->link_mesh) 02722 { 02723 retargetArctoArc(C, rigg, arc, arc->head); 02724 } 02725 } 02726 02727 finishRetarget(rigg); 02728 02729 /* Turn the list into an armature */ 02730 arm->edbo = rigg->editbones; 02731 ED_armature_from_edit(rigg->ob); 02732 02733 ED_undo_push(C, "Retarget Skeleton"); 02734 } 02735 02736 static void retargetGraphs(bContext *C, RigGraph *rigg) 02737 { 02738 bArmature *arm= rigg->ob->data; 02739 ReebGraph *reebg = rigg->link_mesh; 02740 RigNode *inode; 02741 02742 /* flag all ReebArcs as free */ 02743 BIF_flagMultiArcs(reebg, ARC_FREE); 02744 02745 /* return to first level */ 02746 inode = rigg->head; 02747 02748 matchMultiResolutionStartingNode(rigg, reebg, inode); 02749 02750 retargetSubgraph(C, rigg, NULL, inode); 02751 02752 //generateMissingArcs(rigg); 02753 02754 finishRetarget(rigg); 02755 02756 /* Turn the list into an armature */ 02757 arm->edbo = rigg->editbones; 02758 ED_armature_from_edit(rigg->ob); 02759 } 02760 02761 const char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index) 02762 { 02763 RigArc *arc = BLI_findlink(&rg->arcs, arc_index); 02764 RigEdge *iedge; 02765 02766 if (arc == NULL) 02767 { 02768 return "None"; 02769 } 02770 02771 if (bone_index == BLI_countlist(&arc->edges)) 02772 { 02773 return "Last joint"; 02774 } 02775 02776 iedge = BLI_findlink(&arc->edges, bone_index); 02777 02778 if (iedge == NULL) 02779 { 02780 return "Done"; 02781 } 02782 02783 if (iedge->bone == NULL) 02784 { 02785 return "Bone offset"; 02786 } 02787 02788 return iedge->bone->name; 02789 } 02790 02791 int RIG_nbJoints(RigGraph *rg) 02792 { 02793 RigArc *arc; 02794 int total = 0; 02795 02796 total += BLI_countlist(&rg->nodes); 02797 02798 for (arc = rg->arcs.first; arc; arc = arc->next) 02799 { 02800 total += BLI_countlist(&arc->edges) - 1; /* -1 because end nodes are already counted */ 02801 } 02802 02803 return total; 02804 } 02805 02806 static void BIF_freeRetarget(void) 02807 { 02808 if (GLOBAL_RIGG) 02809 { 02810 RIG_freeRigGraph((BGraph*)GLOBAL_RIGG); 02811 GLOBAL_RIGG = NULL; 02812 } 02813 } 02814 02815 void BIF_retargetArmature(bContext *C) 02816 { 02817 ReebGraph *reebg; 02818 double start_time, end_time; 02819 double gstart_time, gend_time; 02820 double reeb_time, rig_time=0.0, retarget_time=0.0, total_time; 02821 02822 gstart_time = start_time = PIL_check_seconds_timer(); 02823 02824 reebg = BIF_ReebGraphMultiFromEditMesh(C); 02825 02826 end_time = PIL_check_seconds_timer(); 02827 reeb_time = end_time - start_time; 02828 02829 printf("Reeb Graph created\n"); 02830 02831 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { 02832 Object *ob = base->object; 02833 02834 if (ob->type==OB_ARMATURE) 02835 { 02836 RigGraph *rigg; 02837 bArmature *arm; 02838 02839 arm = ob->data; 02840 02841 /* Put the armature into editmode */ 02842 02843 02844 start_time = PIL_check_seconds_timer(); 02845 02846 rigg = RIG_graphFromArmature(C, ob, arm); 02847 02848 end_time = PIL_check_seconds_timer(); 02849 rig_time = end_time - start_time; 02850 02851 printf("Armature graph created\n"); 02852 02853 //RIG_printGraph(rigg); 02854 02855 rigg->link_mesh = reebg; 02856 02857 printf("retargetting %s\n", ob->id.name); 02858 02859 start_time = PIL_check_seconds_timer(); 02860 02861 retargetGraphs(C, rigg); 02862 02863 end_time = PIL_check_seconds_timer(); 02864 retarget_time = end_time - start_time; 02865 02866 BIF_freeRetarget(); 02867 02868 GLOBAL_RIGG = rigg; 02869 02870 break; /* only one armature at a time */ 02871 } 02872 } 02873 CTX_DATA_END; 02874 02875 02876 gend_time = PIL_check_seconds_timer(); 02877 02878 total_time = gend_time - gstart_time; 02879 02880 printf("-----------\n"); 02881 printf("runtime: \t%.3f\n", total_time); 02882 printf("reeb: \t\t%.3f (%.1f%%)\n", reeb_time, reeb_time / total_time * 100); 02883 printf("rig: \t\t%.3f (%.1f%%)\n", rig_time, rig_time / total_time * 100); 02884 printf("retarget: \t%.3f (%.1f%%)\n", retarget_time, retarget_time / total_time * 100); 02885 printf("-----------\n"); 02886 02887 ED_undo_push(C, "Retarget Skeleton"); 02888 02889 // XXX 02890 // allqueue(REDRAWVIEW3D, 0); 02891 } 02892 02893 void BIF_retargetArc(bContext *C, ReebArc *earc, RigGraph *template_rigg) 02894 { 02895 Object *obedit = CTX_data_edit_object(C); 02896 Scene *scene = CTX_data_scene(C); 02897 bArmature *armedit = obedit->data; 02898 Object *ob; 02899 RigGraph *rigg; 02900 RigArc *iarc; 02901 char *side_string = scene->toolsettings->skgen_side_string; 02902 char *num_string = scene->toolsettings->skgen_num_string; 02903 int free_template = 0; 02904 02905 if (template_rigg) 02906 { 02907 ob = template_rigg->ob; 02908 } 02909 else 02910 { 02911 free_template = 1; 02912 ob = obedit; 02913 template_rigg = armatureSelectedToGraph(C, ob, ob->data); 02914 } 02915 02916 if (template_rigg->arcs.first == NULL) 02917 { 02918 // XXX 02919 // error("No Template and no deforming bones selected"); 02920 return; 02921 } 02922 02923 rigg = cloneRigGraph(template_rigg, armedit->edbo, obedit, side_string, num_string); 02924 02925 iarc = rigg->arcs.first; 02926 02927 iarc->link_mesh = earc; 02928 iarc->head->link_mesh = earc->head; 02929 iarc->tail->link_mesh = earc->tail; 02930 02931 retargetArctoArc(C, rigg, iarc, iarc->head); 02932 02933 finishRetarget(rigg); 02934 02935 /* free template if it comes from the edit armature */ 02936 if (free_template) 02937 { 02938 RIG_freeRigGraph((BGraph*)template_rigg); 02939 } 02940 RIG_freeRigGraph((BGraph*)rigg); 02941 02942 ED_armature_validate_active(armedit); 02943 02944 // XXX 02945 // allqueue(REDRAWVIEW3D, 0); 02946 } 02947 02948 void BIF_adjustRetarget(bContext *C) 02949 { 02950 if (GLOBAL_RIGG) 02951 { 02952 adjustGraphs(C, GLOBAL_RIGG); 02953 } 02954 }