| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-03-21 01:14:04 +00:00
										 |  |  |  * $Id$ | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version.  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2008 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Contributor(s): Blender Foundation, Joshua Leung | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | #include "DNA_anim_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | #include "DNA_armature_types.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | #include "DNA_node_types.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  | #include "DNA_scene_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | #include "DNA_sequence_types.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_blenlib.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | #include "BKE_animsys.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | #include "BKE_action.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							|  |  |  | #include "BKE_depsgraph.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | #include "BKE_node.h"
 | 
					
						
							|  |  |  | #include "BKE_sequencer.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  | #include "BKE_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | #include "ED_anim_api.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-23 19:47:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | /* **************************** depsgraph tagging ******************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | /* tags the given anim list element for refreshes (if applicable)
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  |  * due to Animation Editor editing  | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ID *id; | 
					
						
							|  |  |  | 	FCurve *fcu; | 
					
						
							|  |  |  | 	AnimData *adt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	id= ale->id; | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	if (!id) | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* tag AnimData for refresh so that other views will update in realtime with these changes */ | 
					
						
							|  |  |  | 	adt= BKE_animdata_from_id(id); | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	if (adt) | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | 		adt->recalc |= ADT_RECALC_ANIM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* update data */ | 
					
						
							|  |  |  | 	fcu= (ale->datatype == ALE_FCURVE)? ale->key_data: NULL; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	if (fcu && fcu->rna_path) { | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | 		/* if we have an fcurve, call the update for the property we
 | 
					
						
							|  |  |  | 		   are editing, this is then expected to do the proper redraws | 
					
						
							|  |  |  | 		   and depsgraph updates  */ | 
					
						
							|  |  |  | 		PointerRNA id_ptr, ptr; | 
					
						
							|  |  |  | 		PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | 		RNA_id_pointer_create(id, &id_ptr); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 		if(RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) | 
					
						
							|  |  |  | 			RNA_property_update_main(G.main, scene, &ptr, prop); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* in other case we do standard depsgaph update, ideally
 | 
					
						
							|  |  |  | 		   we'd be calling property update functions here too ... */ | 
					
						
							|  |  |  | 		DAG_id_flush_update(id, OB_RECALC); // XXX or do we want something more restrictive?
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* tags the given ID block for refreshes (if applicable) due to 
 | 
					
						
							|  |  |  |  * Animation Editor editing */ | 
					
						
							|  |  |  | void ANIM_id_update(Scene *scene, ID *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	if (id) { | 
					
						
							| 
									
										
										
										
											2009-12-08 18:28:09 +00:00
										 |  |  | 		AnimData *adt= BKE_animdata_from_id(id); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* tag AnimData for refresh so that other views will update in realtime with these changes */ | 
					
						
							|  |  |  | 		if (adt) | 
					
						
							|  |  |  | 			adt->recalc |= ADT_RECALC_ANIM; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 		/* set recalc flags */ | 
					
						
							|  |  |  | 		DAG_id_flush_update(id, OB_RECALC); // XXX or do we want something more restrictive?
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | /* **************************** animation data <-> data syncing ******************************** */ | 
					
						
							|  |  |  | /* This code here is used to synchronise the 
 | 
					
						
							|  |  |  |  *	- selection (to find selected data easier) | 
					
						
							|  |  |  |  *	- ... (insert other relevant items here later)  | 
					
						
							|  |  |  |  * status in relevant Blender data with the status stored in animation channels. | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  |  * This should be called in the refresh() callbacks for various editors in  | 
					
						
							|  |  |  |  * response to appropriate notifiers. | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* perform syncing updates for Action Groups */ | 
					
						
							|  |  |  | static void animchan_sync_group (bAnimContext *ac, bAnimListElem *ale) | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	bActionGroup *agrp= (bActionGroup *)ale->data; | 
					
						
							|  |  |  | 	ID *owner_id= ale->id; | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	/* major priority is selection status
 | 
					
						
							|  |  |  | 	 * so we need both a group and an owner | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (ELEM(NULL, agrp, owner_id)) | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	/* for standard Objects, check if group is the name of some bone */ | 
					
						
							|  |  |  | 	if (GS(owner_id->name) == ID_OB) { | 
					
						
							|  |  |  | 		Object *ob= (Object *)owner_id; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* check if there are bones, and whether the name matches any 
 | 
					
						
							|  |  |  | 		 * NOTE: this feature will only really work if groups by default contain the F-Curves for a single bone | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		if (ob->pose) { | 
					
						
							|  |  |  | 			bPoseChannel *pchan= get_pose_channel(ob->pose, agrp->name); | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 			/* if one matches, sync the selection status */ | 
					
						
							|  |  |  | 			if (pchan) { | 
					
						
							|  |  |  | 				if (pchan->bone->flag & BONE_SELECTED) | 
					
						
							|  |  |  | 					agrp->flag |= AGRP_SELECTED; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					agrp->flag &= ~AGRP_SELECTED; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | /* perform syncing updates for F-Curves */ | 
					
						
							|  |  |  | static void animchan_sync_fcurve (bAnimContext *ac, bAnimListElem *ale) | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	FCurve *fcu= (FCurve *)ale->data; | 
					
						
							|  |  |  | 	ID *owner_id= ale->id; | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	/* major priority is selection status, so refer to the checks done in anim_filter.c 
 | 
					
						
							|  |  |  | 	 * skip_fcurve_selected_data() for reference about what's going on here... | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (ELEM3(NULL, fcu, fcu->rna_path, owner_id)) | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	if (GS(owner_id->name) == ID_OB) { | 
					
						
							|  |  |  | 		Object *ob= (Object *)owner_id; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* only affect if F-Curve involves pose.bones */ | 
					
						
							|  |  |  | 		if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) { | 
					
						
							|  |  |  | 			bPoseChannel *pchan; | 
					
						
							|  |  |  | 			char *bone_name; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/* get bone-name, and check if this bone is selected */ | 
					
						
							|  |  |  | 			bone_name= BLI_getQuotedStr(fcu->rna_path, "pose.bones["); | 
					
						
							|  |  |  | 			pchan= get_pose_channel(ob->pose, bone_name); | 
					
						
							|  |  |  | 			if (bone_name) MEM_freeN(bone_name); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/* F-Curve selection depends on whether the bone is selected */ | 
					
						
							|  |  |  | 			if ((pchan) && (pchan->bone)) { | 
					
						
							|  |  |  | 				if (pchan->bone->flag & BONE_SELECTED) | 
					
						
							|  |  |  | 					fcu->flag |= FCURVE_SELECTED; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					fcu->flag &= ~FCURVE_SELECTED; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (GS(owner_id->name) == ID_SCE) { | 
					
						
							|  |  |  | 		Scene *scene = (Scene *)owner_id; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* only affect if F-Curve involves sequence_editor.sequences */ | 
					
						
							|  |  |  | 		if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) { | 
					
						
							|  |  |  | 			Editing *ed= seq_give_editing(scene, FALSE); | 
					
						
							|  |  |  | 			Sequence *seq; | 
					
						
							|  |  |  | 			char *seq_name; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/* get strip name, and check if this strip is selected */ | 
					
						
							|  |  |  | 			seq_name= BLI_getQuotedStr(fcu->rna_path, "sequences_all["); | 
					
						
							|  |  |  | 			seq = get_seq_by_name(ed->seqbasep, seq_name, FALSE); | 
					
						
							|  |  |  | 			if (seq_name) MEM_freeN(seq_name); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/* can only add this F-Curve if it is selected */ | 
					
						
							|  |  |  | 			if (seq) { | 
					
						
							|  |  |  | 				if (seq->flag & SELECT) | 
					
						
							|  |  |  | 					fcu->flag |= FCURVE_SELECTED; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					fcu->flag &= ~FCURVE_SELECTED; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (GS(owner_id->name) == ID_NT) { | 
					
						
							|  |  |  | 		bNodeTree *ntree = (bNodeTree *)owner_id; | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 		/* check for selected nodes */ | 
					
						
							|  |  |  | 		if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) { | 
					
						
							|  |  |  | 			bNode *node; | 
					
						
							|  |  |  | 			char *node_name; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/* get strip name, and check if this strip is selected */ | 
					
						
							|  |  |  | 			node_name= BLI_getQuotedStr(fcu->rna_path, "nodes["); | 
					
						
							|  |  |  | 			node = nodeFindNodebyName(ntree, node_name); | 
					
						
							|  |  |  | 			if (node_name) MEM_freeN(node_name); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/* can only add this F-Curve if it is selected */ | 
					
						
							|  |  |  | 			if (node) { | 
					
						
							|  |  |  | 				if (node->flag & NODE_SELECT) | 
					
						
							|  |  |  | 					fcu->flag |= FCURVE_SELECTED; | 
					
						
							| 
									
										
										
										
											2009-01-05 09:54:39 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 					fcu->flag &= ~FCURVE_SELECTED; | 
					
						
							| 
									
										
										
										
											2009-01-05 09:54:39 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ---------------- */ | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | /* Main call to be exported to animation editors */ | 
					
						
							|  |  |  | void ANIM_sync_animchannels_to_data (const bContext *C) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bAnimContext ac; | 
					
						
							|  |  |  | 	ListBase anim_data = {NULL, NULL}; | 
					
						
							|  |  |  | 	bAnimListElem *ale; | 
					
						
							|  |  |  | 	int filter; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* get animation context info for filtering the channels */ | 
					
						
							|  |  |  | 	// TODO: check on whether we need to set the area specially instead, since active area might not be ok?
 | 
					
						
							|  |  |  | 	if (ANIM_animdata_get_context(C, &ac) == 0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* filter data */ | 
					
						
							|  |  |  | 		/* NOTE: we want all channels, since we want to be able to set selection status on some of them even when collapsed */ | 
					
						
							|  |  |  | 	filter= ANIMFILTER_CHANNELS; | 
					
						
							|  |  |  | 	ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* flush settings as appropriate depending on the types of the channels */ | 
					
						
							|  |  |  | 	for (ale= anim_data.first; ale; ale= ale->next) { | 
					
						
							|  |  |  | 		switch (ale->type) { | 
					
						
							|  |  |  | 			case ANIMTYPE_GROUP: | 
					
						
							|  |  |  | 				animchan_sync_group(&ac, ale); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			case ANIMTYPE_FCURVE: | 
					
						
							|  |  |  | 				animchan_sync_fcurve(&ac, ale); | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-12-21 09:52:43 +00:00
										 |  |  | 	BLI_freelistN(&anim_data); | 
					
						
							| 
									
										
										
										
											2009-01-03 11:35:39 +00:00
										 |  |  | } |