|
Blender
V2.59
|
00001 /* 00002 * $Id: anim_deps.c 35242 2011-02-27 20:29:51Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation, Joshua Leung 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <string.h> 00035 00036 #include "MEM_guardedalloc.h" 00037 00038 #include "DNA_anim_types.h" 00039 #include "DNA_armature_types.h" 00040 #include "DNA_object_types.h" 00041 #include "DNA_node_types.h" 00042 #include "DNA_scene_types.h" 00043 #include "DNA_sequence_types.h" 00044 00045 #include "BLI_blenlib.h" 00046 #include "BLI_utildefines.h" 00047 00048 #include "BKE_animsys.h" 00049 #include "BKE_action.h" 00050 #include "BKE_context.h" 00051 #include "BKE_depsgraph.h" 00052 #include "BKE_global.h" 00053 #include "BKE_node.h" 00054 #include "BKE_sequencer.h" 00055 #include "BKE_utildefines.h" 00056 00057 #include "RNA_access.h" 00058 00059 #include "ED_anim_api.h" 00060 00061 /* **************************** depsgraph tagging ******************************** */ 00062 00063 /* tags the given anim list element for refreshes (if applicable) 00064 * due to Animation Editor editing 00065 */ 00066 void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale) 00067 { 00068 ID *id; 00069 FCurve *fcu; 00070 AnimData *adt; 00071 00072 id= ale->id; 00073 if (!id) 00074 return; 00075 00076 /* tag AnimData for refresh so that other views will update in realtime with these changes */ 00077 adt= BKE_animdata_from_id(id); 00078 if (adt) 00079 adt->recalc |= ADT_RECALC_ANIM; 00080 00081 /* update data */ 00082 fcu= (ale->datatype == ALE_FCURVE)? ale->key_data: NULL; 00083 00084 if (fcu && fcu->rna_path) { 00085 /* if we have an fcurve, call the update for the property we 00086 are editing, this is then expected to do the proper redraws 00087 and depsgraph updates */ 00088 PointerRNA id_ptr, ptr; 00089 PropertyRNA *prop; 00090 00091 RNA_id_pointer_create(id, &id_ptr); 00092 00093 if(RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) 00094 RNA_property_update_main(G.main, scene, &ptr, prop); 00095 } 00096 else { 00097 /* in other case we do standard depsgaph update, ideally 00098 we'd be calling property update functions here too ... */ 00099 DAG_id_tag_update(id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); // XXX or do we want something more restrictive? 00100 } 00101 } 00102 00103 /* tags the given ID block for refreshes (if applicable) due to 00104 * Animation Editor editing */ 00105 void ANIM_id_update(Scene *UNUSED(scene), ID *id) 00106 { 00107 if (id) { 00108 AnimData *adt= BKE_animdata_from_id(id); 00109 00110 /* tag AnimData for refresh so that other views will update in realtime with these changes */ 00111 if (adt) 00112 adt->recalc |= ADT_RECALC_ANIM; 00113 00114 /* set recalc flags */ 00115 DAG_id_tag_update(id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); // XXX or do we want something more restrictive? 00116 } 00117 } 00118 00119 /* **************************** animation data <-> data syncing ******************************** */ 00120 /* This code here is used to synchronise the 00121 * - selection (to find selected data easier) 00122 * - ... (insert other relevant items here later) 00123 * status in relevant Blender data with the status stored in animation channels. 00124 * 00125 * This should be called in the refresh() callbacks for various editors in 00126 * response to appropriate notifiers. 00127 */ 00128 00129 /* perform syncing updates for Action Groups */ 00130 static void animchan_sync_group (bAnimContext *UNUSED(ac), bAnimListElem *ale) 00131 { 00132 bActionGroup *agrp= (bActionGroup *)ale->data; 00133 ID *owner_id= ale->id; 00134 00135 /* major priority is selection status 00136 * so we need both a group and an owner 00137 */ 00138 if (ELEM(NULL, agrp, owner_id)) 00139 return; 00140 00141 /* for standard Objects, check if group is the name of some bone */ 00142 if (GS(owner_id->name) == ID_OB) { 00143 Object *ob= (Object *)owner_id; 00144 00145 /* check if there are bones, and whether the name matches any 00146 * NOTE: this feature will only really work if groups by default contain the F-Curves for a single bone 00147 */ 00148 if (ob->pose) { 00149 bPoseChannel *pchan= get_pose_channel(ob->pose, agrp->name); 00150 00151 /* if one matches, sync the selection status */ 00152 if (pchan) { 00153 if (pchan->bone->flag & BONE_SELECTED) 00154 agrp->flag |= AGRP_SELECTED; 00155 else 00156 agrp->flag &= ~AGRP_SELECTED; 00157 } 00158 } 00159 } 00160 } 00161 00162 /* perform syncing updates for F-Curves */ 00163 static void animchan_sync_fcurve (bAnimContext *UNUSED(ac), bAnimListElem *ale) 00164 { 00165 FCurve *fcu= (FCurve *)ale->data; 00166 ID *owner_id= ale->id; 00167 00168 /* major priority is selection status, so refer to the checks done in anim_filter.c 00169 * skip_fcurve_selected_data() for reference about what's going on here... 00170 */ 00171 if (ELEM3(NULL, fcu, fcu->rna_path, owner_id)) 00172 return; 00173 00174 if (GS(owner_id->name) == ID_OB) { 00175 Object *ob= (Object *)owner_id; 00176 00177 /* only affect if F-Curve involves pose.bones */ 00178 if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) { 00179 bPoseChannel *pchan; 00180 char *bone_name; 00181 00182 /* get bone-name, and check if this bone is selected */ 00183 bone_name= BLI_getQuotedStr(fcu->rna_path, "pose.bones["); 00184 pchan= get_pose_channel(ob->pose, bone_name); 00185 if (bone_name) MEM_freeN(bone_name); 00186 00187 /* F-Curve selection depends on whether the bone is selected */ 00188 if ((pchan) && (pchan->bone)) { 00189 if (pchan->bone->flag & BONE_SELECTED) 00190 fcu->flag |= FCURVE_SELECTED; 00191 else 00192 fcu->flag &= ~FCURVE_SELECTED; 00193 } 00194 } 00195 } 00196 else if (GS(owner_id->name) == ID_SCE) { 00197 Scene *scene = (Scene *)owner_id; 00198 00199 /* only affect if F-Curve involves sequence_editor.sequences */ 00200 if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) { 00201 Editing *ed= seq_give_editing(scene, FALSE); 00202 Sequence *seq; 00203 char *seq_name; 00204 00205 /* get strip name, and check if this strip is selected */ 00206 seq_name= BLI_getQuotedStr(fcu->rna_path, "sequences_all["); 00207 seq = get_seq_by_name(ed->seqbasep, seq_name, FALSE); 00208 if (seq_name) MEM_freeN(seq_name); 00209 00210 /* can only add this F-Curve if it is selected */ 00211 if (seq) { 00212 if (seq->flag & SELECT) 00213 fcu->flag |= FCURVE_SELECTED; 00214 else 00215 fcu->flag &= ~FCURVE_SELECTED; 00216 } 00217 } 00218 } 00219 else if (GS(owner_id->name) == ID_NT) { 00220 bNodeTree *ntree = (bNodeTree *)owner_id; 00221 00222 /* check for selected nodes */ 00223 if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) { 00224 bNode *node; 00225 char *node_name; 00226 00227 /* get strip name, and check if this strip is selected */ 00228 node_name= BLI_getQuotedStr(fcu->rna_path, "nodes["); 00229 node = nodeFindNodebyName(ntree, node_name); 00230 if (node_name) MEM_freeN(node_name); 00231 00232 /* can only add this F-Curve if it is selected */ 00233 if (node) { 00234 if (node->flag & NODE_SELECT) 00235 fcu->flag |= FCURVE_SELECTED; 00236 else 00237 fcu->flag &= ~FCURVE_SELECTED; 00238 } 00239 } 00240 } 00241 } 00242 00243 /* ---------------- */ 00244 00245 /* Main call to be exported to animation editors */ 00246 void ANIM_sync_animchannels_to_data (const bContext *C) 00247 { 00248 bAnimContext ac; 00249 ListBase anim_data = {NULL, NULL}; 00250 bAnimListElem *ale; 00251 int filter; 00252 00253 /* get animation context info for filtering the channels */ 00254 // TODO: check on whether we need to set the area specially instead, since active area might not be ok? 00255 if (ANIM_animdata_get_context(C, &ac) == 0) 00256 return; 00257 00258 /* filter data */ 00259 /* NOTE: we want all channels, since we want to be able to set selection status on some of them even when collapsed */ 00260 filter= ANIMFILTER_CHANNELS; 00261 ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); 00262 00263 /* flush settings as appropriate depending on the types of the channels */ 00264 for (ale= anim_data.first; ale; ale= ale->next) { 00265 switch (ale->type) { 00266 case ANIMTYPE_GROUP: 00267 animchan_sync_group(&ac, ale); 00268 break; 00269 00270 case ANIMTYPE_FCURVE: 00271 animchan_sync_fcurve(&ac, ale); 00272 break; 00273 } 00274 } 00275 00276 BLI_freelistN(&anim_data); 00277 }