62341a5d6ae460dddfc0f290e5474ff6e532f352
[blender.git] / source / blender / editors / animation / anim_deps.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation, Joshua Leung
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <stdlib.h>
30 #include <math.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_action_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "BLI_blenlib.h"
40
41 #include "BKE_action.h"
42 #include "BKE_context.h"
43 #include "BKE_depsgraph.h"
44 #include "BKE_main.h"
45 #include "BKE_scene.h"
46 #include "BKE_screen.h"
47 #include "BKE_utildefines.h"
48
49 #include "RNA_access.h"
50 #include "RNA_define.h"
51
52 #include "ED_anim_api.h"
53 #include "ED_screen.h"
54
55 #include "WM_api.h"
56 #include "WM_types.h"
57
58 /* ***************** depsgraph calls and anim updates ************* */
59 /* ***************** only these can be called from editors ******** */
60
61 void ED_anim_dag_flush_update(const bContext *C)
62 {
63         DAG_ids_flush_update(0);
64 }
65
66 /* flushes changes from object to all relations in scene */
67 void ED_anim_object_flush_update(const bContext *C, Object *ob)
68 {
69         DAG_id_update_flags(&ob->id);
70 }
71
72 /* **************************** pose <-> action syncing ******************************** */
73 /* Summary of what needs to be synced between poses and actions:
74  *      1) Flags
75  *              a) Visibility (only for pose to action) 
76  *              b) Selection status (both ways)
77  *      2) Group settings  (only for pose to action) - do we also need to make sure same groups exist?
78  *      3) Grouping (only for pose to action for now)
79  */
80
81 /* XXX OBSOLETE CODE WARNING:
82  * With the Animato system, the code below is somewhat obsolete now...
83  */
84  
85 /* Notifier from Action/Dopesheet (this may be extended to include other things such as Python...)
86  * Channels in action changed, so update pose channels/groups to reflect changes.
87  *
88  * An object (usually 'active' Object) needs to be supplied, so that its Pose-Channels can be synced with
89  * the channels in its active Action.
90  */
91 void ANIM_action_to_pose_sync (Object *ob)
92 {
93         bAction *act= (bAction *)ob->action;
94         bActionChannel *achan;
95         bPoseChannel *pchan;
96         
97         /* error checking */
98         if ((ob == NULL) || (ob->type != OB_ARMATURE) || ELEM(NULL, act, ob->pose))
99                 return;
100         
101         /* 1b) loop through all Action-Channels (there should be fewer channels to search through here in general) */
102         for (achan= act->chanbase.first; achan; achan= achan->next) {
103                 /* find matching pose-channel */
104                 pchan= get_pose_channel(ob->pose, achan->name);
105                 
106                 /* sync active and selected flags */
107                 if (pchan && pchan->bone) {
108                         /* selection */
109                         if (achan->flag & ACHAN_SELECTED)
110                                 pchan->bone->flag |= BONE_SELECTED;
111                         else
112                                 pchan->bone->flag &= ~BONE_SELECTED;
113                         
114                         /* active */
115                         if (achan->flag & ACHAN_HILIGHTED)
116                                 pchan->bone->flag |= BONE_ACTIVE;
117                         else
118                                 pchan->bone->flag &= ~BONE_ACTIVE;
119                 }
120         }
121         
122         // TODO: add grouping changes too? For now, these tools aren't exposed to users in animation editors yet...
123
124  
125 /* Notifier from 3D-View/Outliner (this is likely to include other sources too...)
126  * Pose channels/groups changed, so update action channels
127  *
128  * An object (usually 'active' Object) needs to be supplied, so that its Pose-Channels can be synced with
129  * the channels in its active Action.
130  */
131 void ANIM_pose_to_action_sync (Object *ob, ScrArea *sa)
132 {
133 #if 0 // XXX old animation system
134         SpaceAction *saction= (SpaceAction *)sa->spacedata.first;
135         bArmature *arm= (bArmature *)ob->data;
136         bAction *act= (bAction *)ob->action;
137         bActionChannel *achan;
138         //bActionGroup *agrp, *bgrp;
139         bPoseChannel *pchan;
140         
141         /* error checking */
142         if ((ob == NULL) || (ob->type != OB_ARMATURE) || ELEM3(NULL, arm, act, ob->pose))
143                 return;
144                 
145         /* 1) loop through all Action-Channels (there should be fewer channels to search through here in general) */
146         for (achan= act->chanbase.first; achan; achan= achan->next) {
147                 /* find matching pose-channel */
148                 pchan= get_pose_channel(ob->pose, achan->name);
149                 
150                 /* sync selection and visibility settings */
151                 if (pchan && pchan->bone) {
152                         /* visibility - if layer is hidden, or if bone itself is hidden */
153                         if (!(saction->flag & SACTION_NOHIDE) && !(saction->pin)) {
154                                 if (!(pchan->bone->layer & arm->layer) || (pchan->bone->flag & BONE_HIDDEN_P))
155                                         achan->flag |= ACHAN_HIDDEN;
156                                 else
157                                         achan->flag &= ~ACHAN_HIDDEN;
158                         }
159                                 
160                         /* selection */
161                         if (pchan->bone->flag & BONE_SELECTED)
162                                 achan->flag |= ACHAN_SELECTED;
163                         else
164                                 achan->flag &= ~ACHAN_SELECTED;
165                 }
166         }
167         
168         // XXX step 2 needs to be coded still... currently missing action/bone group API to do any more work here...    
169         // XXX step 3 needs to be coded still... it's a messy case to deal with (we'll use the temp indices for this?)
170 #endif // XXX old animation system
171 }