示例#1
0
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
{
	ID *id;
	bAction *action;
	FCurve *fcu;
	bool driven;

	fcu = ui_but_get_fcurve(but, NULL, &action, &driven);

	if (fcu && !driven) {
		id = but->rnapoin.id.data;

		/* TODO: this should probably respect the keyingset only option for anim */
		if (autokeyframe_cfra_can_key(scene, id)) {
			ReportList *reports = CTX_wm_reports(C);
			short flag = ANIM_get_keyframing_flags(scene, 1);

			fcu->flag &= ~FCURVE_SELECTED;

			/* Note: We use but->rnaindex instead of fcu->array_index,
			 *       because a button may control all items of an array at once.
			 *       E.g., color wheels (see T42567). */
			BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
			insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
			                fcu->rna_path, but->rnaindex, cfra, flag);

			WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
		}
	}
}
示例#2
0
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
{
	ID *id;
	bAction *action;
	FCurve *fcu;
	bool driven;
	bool special;

	fcu = ui_but_get_fcurve(but, NULL, &action, &driven, &special);
	
	if (fcu == NULL)
		return;
	
	if (special) {
		/* NLA Strip property */
		if (IS_AUTOKEY_ON(scene)) {
			ReportList *reports = CTX_wm_reports(C);
			ToolSettings *ts = scene->toolsettings;
			
			insert_keyframe_direct(reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, 0);
			WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
		}
	}
	else if (driven) {
		/* Driver - Try to insert keyframe using the driver's input as the frame,
		 * making it easier to set up corrective drivers
		 */
		if (IS_AUTOKEY_ON(scene)) {
			ReportList *reports = CTX_wm_reports(C);
			ToolSettings *ts = scene->toolsettings;
			
			insert_keyframe_direct(reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, INSERTKEY_DRIVER);
			WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
		}
	}
	else {
		id = but->rnapoin.id.data;
		
		/* TODO: this should probably respect the keyingset only option for anim */
		if (autokeyframe_cfra_can_key(scene, id)) {
			ReportList *reports = CTX_wm_reports(C);
			ToolSettings *ts = scene->toolsettings;
			short flag = ANIM_get_keyframing_flags(scene, 1);
			
			fcu->flag &= ~FCURVE_SELECTED;
			
			/* Note: We use but->rnaindex instead of fcu->array_index,
			 *       because a button may control all items of an array at once.
			 *       E.g., color wheels (see T42567). */
			BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
			insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
			                fcu->rna_path, but->rnaindex, cfra, ts->keyframe_type, flag);
			
			WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
		}
	}
}
示例#3
0
/* this function is responsible for snapping keyframes to frame-times */
static void insert_action_keys(bAnimContext *ac, short mode) 
{
	ListBase anim_data = {NULL, NULL};
	bAnimListElem *ale;
	int filter;
	
	ReportList *reports = ac->reports;
	Scene *scene = ac->scene;
	short flag = 0;
	
	/* filter data */
	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
	if (mode == 2) filter |= ANIMFILTER_SEL;
	else if (mode == 3) filter |= ANIMFILTER_ACTGROUPED;
	
	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
	
	/* init keyframing flag */
	flag = ANIM_get_keyframing_flags(scene, 1);
	
	/* insert keyframes */
	for (ale = anim_data.first; ale; ale = ale->next) {
		AnimData *adt = ANIM_nla_mapping_get(ac, ale);
		FCurve *fcu = (FCurve *)ale->key_data;
		float cfra;
		
		/* adjust current frame for NLA-scaling */
		if (adt)
			cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
		else 
			cfra = (float)CFRA;
			
		/* read value from property the F-Curve represents, or from the curve only?
		 * - ale->id != NULL:    Typically, this means that we have enough info to try resolving the path
		 * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
		 *                       so it's easier for now to just read the F-Curve directly.
		 *                       (TODO: add the full-blown PointerRNA relative parsing case here...)
		 */
		if (ale->id && !ale->owner)
			insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
		else
			insert_vert_fcurve(fcu, cfra, fcu->curval, 0);

		ale->update |= ANIM_UPDATE_DEFAULT;
	}

	ANIM_animdata_update(ac, &anim_data);
	ANIM_animdata_freelist(&anim_data);
}
示例#4
0
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
{
	ID *id;
	bAction *action;
	FCurve *fcu;
	bool driven;
	bool special;

	fcu = ui_but_get_fcurve(but, NULL, &action, &driven, &special);
	
	if (fcu == NULL)
		return;
	
	if (special) {
		/* NLA Strip property */
		if (IS_AUTOKEY_ON(scene)) {
			ReportList *reports = CTX_wm_reports(C);
			PointerRNA ptr = {{NULL}};
			PropertyRNA *prop = NULL;
			int index;
			
			UI_context_active_but_prop_get(C, &ptr, &prop, &index);
			
			insert_keyframe_direct(reports, ptr, prop, fcu, cfra, 0);
			WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
		}
	}
	else if (!driven) {
		id = but->rnapoin.id.data;

		/* TODO: this should probably respect the keyingset only option for anim */
		if (autokeyframe_cfra_can_key(scene, id)) {
			ReportList *reports = CTX_wm_reports(C);
			short flag = ANIM_get_keyframing_flags(scene, 1);

			fcu->flag &= ~FCURVE_SELECTED;

			/* Note: We use but->rnaindex instead of fcu->array_index,
			 *       because a button may control all items of an array at once.
			 *       E.g., color wheels (see T42567). */
			BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
			insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
			                fcu->rna_path, but->rnaindex, cfra, flag);

			WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
		}
	}
}
示例#5
0
/* this function is responsible for snapping keyframes to frame-times */
static void insert_action_keys(bAnimContext *ac, short mode) 
{
	ListBase anim_data = {NULL, NULL};
	bAnimListElem *ale;
	int filter;
	
	ReportList *reports = ac->reports;
	Scene *scene = ac->scene;
	short flag = 0;
	
	/* filter data */
	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
	if (mode == 2) filter |= ANIMFILTER_SEL;
	else if (mode == 3) filter |= ANIMFILTER_ACTGROUPED;
	
	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
	
	/* init keyframing flag */
	flag = ANIM_get_keyframing_flags(scene, 1);
	
	/* insert keyframes */
	for (ale = anim_data.first; ale; ale = ale->next) {
		AnimData *adt = ANIM_nla_mapping_get(ac, ale);
		FCurve *fcu = (FCurve *)ale->key_data;
		float cfra;
		
		/* adjust current frame for NLA-scaling */
		if (adt)
			cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
		else 
			cfra = (float)CFRA;
			
		/* if there's an id */
		if (ale->id)
			insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
		else
			insert_vert_fcurve(fcu, cfra, fcu->curval, 0);
	}
	
	BLI_freelistN(&anim_data);
}
示例#6
0
static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	short flag = 0, keyingflag = 0;
	
	/* validate flags 
	 *	- absolute KeyingSets should be created by default
	 */
	flag |= KEYINGSET_ABSOLUTE;
	
	/* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
	keyingflag = ANIM_get_keyframing_flags(scene, 0);
	
	/* call the API func, and set the active keyingset index */
	BKE_keyingset_add(&scene->keyingsets, NULL, NULL, flag, keyingflag);
	
	scene->active_keyingset = BLI_countlist(&scene->keyingsets);
	
	/* send notifiers */
	WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
	
	return OPERATOR_FINISHED;
}
示例#7
0
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
{
	ID *id;
	bAction *action;
	FCurve *fcu;
	bool driven;

	fcu = ui_but_get_fcurve(but, &action, &driven);

	if (fcu && !driven) {
		id = but->rnapoin.id.data;

		/* TODO: this should probably respect the keyingset only option for anim */
		if (autokeyframe_cfra_can_key(scene, id)) {
			ReportList *reports = CTX_wm_reports(C);
			short flag = ANIM_get_keyframing_flags(scene, 1);

			fcu->flag &= ~FCURVE_SELECTED;
			insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
			WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
		}
	}
}
示例#8
0
/* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
 * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
 * Returns the number of channels that keyframes were added to
 */
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
{
	Scene *scene = CTX_data_scene(C);
	ReportList *reports = CTX_wm_reports(C);
	KS_Path *ksp;
	int kflag = 0, success = 0;
	char *groupname = NULL;
	
	/* sanity checks */
	if (ks == NULL)
		return 0;
	
	/* get flags to use */
	if (mode == MODIFYKEY_MODE_INSERT) {
		/* use KeyingSet's flags as base */
		kflag = ks->keyingflag;
		
		/* suppliment with info from the context */
		kflag |= ANIM_get_keyframing_flags(scene, 1);
	}
	else if (mode == MODIFYKEY_MODE_DELETE)
		kflag = 0;
	
	/* if relative Keying Sets, poll and build up the paths */
	success = ANIM_validate_keyingset(C, dsources, ks);
	
	if (success != 0) {
		/* return error code if failed */
		return success;
	}
	
	/* apply the paths as specified in the KeyingSet now */
	for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
		int arraylen, i;
		short kflag2;
		
		/* skip path if no ID pointer is specified */
		if (ksp->id == NULL) {
			BKE_reportf(reports, RPT_WARNING,
			            "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s[%d]')",
			            ks->name, ksp->rna_path, ksp->array_index);
			continue;
		}
		
		/* since keying settings can be defined on the paths too, extend the path before using it */
		kflag2 = (kflag | ksp->keyingflag);
		
		/* get pointer to name of group to add channels to */
		if (ksp->groupmode == KSP_GROUP_NONE)
			groupname = NULL;
		else if (ksp->groupmode == KSP_GROUP_KSNAME)
			groupname = ks->name;
		else
			groupname = ksp->group;
		
		/* init arraylen and i - arraylen should be greater than i so that
		 * normal non-array entries get keyframed correctly
		 */
		i = ksp->array_index;
		arraylen = i;
		
		/* get length of array if whole array option is enabled */
		if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
			PointerRNA id_ptr, ptr;
			PropertyRNA *prop;
			
			RNA_id_pointer_create(ksp->id, &id_ptr);
			if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop))
				arraylen = RNA_property_array_length(&ptr, prop);
		}
		
		/* we should do at least one step */
		if (arraylen == i)
			arraylen++;
		
		/* for each possible index, perform operation 
		 *	- assume that arraylen is greater than index
		 */
		for (; i < arraylen; i++) {
			/* action to take depends on mode */
			if (mode == MODIFYKEY_MODE_INSERT)
				success += insert_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
			else if (mode == MODIFYKEY_MODE_DELETE)
				success += delete_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
		}
		
		/* set recalc-flags */
		switch (GS(ksp->id->name)) {
			case ID_OB: /* Object (or Object-Related) Keyframes */
			{
				Object *ob = (Object *)ksp->id;
				
				// XXX: only object transforms?
				DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
				break;
			}
		}
		
		/* send notifiers for updates (this doesn't require context to work!) */
		WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
	}
	
	/* return the number of channels successfully affected */
	return success;
}
示例#9
0
static int add_keyingset_button_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	KeyingSet *ks = NULL;
	PropertyRNA *prop = NULL;
	PointerRNA ptr = {{NULL}};
	char *path = NULL;
	short success = 0;
	int index = 0, pflag = 0;
	const bool all = RNA_boolean_get(op->ptr, "all");
	
	/* verify the Keying Set to use:
	 *	- use the active one for now (more control over this can be added later)
	 *	- add a new one if it doesn't exist 
	 */
	if (scene->active_keyingset == 0) {
		short flag = 0, keyingflag = 0;
		
		/* validate flags 
		 *	- absolute KeyingSets should be created by default
		 */
		flag |= KEYINGSET_ABSOLUTE;
		
		keyingflag |= ANIM_get_keyframing_flags(scene, 0);
		
		if (IS_AUTOKEY_FLAG(scene, XYZ2RGB)) 
			keyingflag |= INSERTKEY_XYZ2RGB;
			
		/* call the API func, and set the active keyingset index */
		ks = BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag);
		
		scene->active_keyingset = BLI_countlist(&scene->keyingsets);
	}
	else if (scene->active_keyingset < 0) {
		BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set");
		return OPERATOR_CANCELLED;
	}
	else {
		ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
	}
	
	/* try to add to keyingset using property retrieved from UI */
	uiContextActiveProperty(C, &ptr, &prop, &index);
	
	/* check if property is able to be added */
	if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
		path = RNA_path_from_ID_to_property(&ptr, prop);
		
		if (path) {
			/* set flags */
			if (all) {
				pflag |= KSP_FLAG_WHOLE_ARRAY;
				
				/* we need to set the index for this to 0, even though it may break in some cases, this is 
				 * necessary if we want the entire array for most cases to get included without the user
				 * having to worry about where they clicked
				 */
				index = 0;
			}
				
			/* add path to this setting */
			BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
			ks->active_path = BLI_countlist(&ks->paths);
			success = 1;
			
			/* free the temp path created */
			MEM_freeN(path);
		}
	}
	
	if (success) {
		/* send updates */
		WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
		
		/* show notification/report header, so that users notice that something changed */
		BKE_reportf(op->reports, RPT_INFO, "Property added to Keying Set: '%s'", ks->name);
	}
	
	return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}