Exemple #1
0
void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports)
{
	ScrArea *sa = CTX_wm_area(C);
	
	/* If the old action only has a single user (that it's about to lose),
	 * warn user about it
	 *
	 * TODO: Maybe we should just save it for them? But then, there's the problem of
	 *       trying to get rid of stuff that's actually unwanted!
	 */
	if (act->id.us == 1) {
		BKE_reportf(reports, RPT_WARNING,
		            "Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
		            act->id.name + 2);
	}
	
	/* If in Tweak Mode, don't unlink. Instead, this 
	 * becomes a shortcut to exit Tweak Mode instead
	 */
	if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
		/* Exit Tweak Mode */
		BKE_nla_tweakmode_exit(adt);
		
		/* Flush this to the Action Editor (if that's where this change was initiated) */
		if (sa->spacetype == SPACE_ACTION) {
			actedit_change_action(C, NULL);
		}
	}
	else {
		/* Unlink normally - Setting it to NULL should be enough to get the old one unlinked */
		if (sa->spacetype == SPACE_ACTION) {
			/* clear action editor -> action */
			actedit_change_action(C, NULL);
		}
		else {
			/* clear AnimData -> action */
			PointerRNA ptr;
			PropertyRNA *prop;
			
			/* create AnimData RNA pointers */
			RNA_pointer_create(id, &RNA_AnimData, adt, &ptr);
			prop = RNA_struct_find_property(&ptr, "action");
			
			/* clear... */
			RNA_property_pointer_set(&ptr, prop, PointerRNA_NULL);
			RNA_property_update(C, &ptr, prop);
		}
	}
}
Exemple #2
0
static int action_stash_create_exec(bContext *C, wmOperator *op)
{
	SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
	AnimData *adt = ED_actedit_animdata_from_context(C);
	
	/* Check for no action... */
	if (saction->action == NULL) {
		/* just create a new action */
		bAction *action = action_create_new(C, NULL);
		actedit_change_action(C, action);
	}
	else if (adt) {
		/* Perform stashing operation */
		if (action_has_motion(adt->action) == 0) {
			/* don't do anything if this action is empty... */
			BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
			return OPERATOR_CANCELLED;
		}
		else {
			/* stash the action */
			if (BKE_nla_action_stash(adt)) {
				bAction *new_action = NULL;
				
				/* create new action not based on the old one (since the "new" operator already does that) */
				new_action = action_create_new(C, NULL);
				
				/* The stash operation will remove the user already,
				 * so the flushing step later shouldn't double up
				 * the usercount fixes. Hence, we must unset this ref
				 * first before setting the new action.
				 */
				saction->action = NULL;
				actedit_change_action(C, new_action);
			}
			else {
				/* action has already been added - simply warn about this, and clear */
				BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
				actedit_change_action(C, NULL);
			}
		}
	}
	
	/* Send notifiers that stuff has changed */
	WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
	return OPERATOR_FINISHED;
}
Exemple #3
0
static int action_layer_next_exec(bContext *C, wmOperator *op)
{
	AnimData *adt = ED_actedit_animdata_from_context(C);
	NlaTrack *act_track;
	
	Scene *scene = CTX_data_scene(C);
	float ctime = BKE_scene_frame_get(scene);
	
	/* Get active track */
	act_track = BKE_nlatrack_find_tweaked(adt);
	
	if (act_track == NULL) {
		BKE_report(op->reports, RPT_ERROR, "Could not find current NLA Track");
		return OPERATOR_CANCELLED;
	}
	
	/* Find next action, and hook it up */
	if (act_track->next) {
		NlaTrack *nlt;
		
		/* Find next action to use */
		for (nlt = act_track->next; nlt; nlt = nlt->next) {
			NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
			
			if (strip) {
				action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
				break;
			}
		}
	}
	else {
		/* No more actions (strips) - Go back to editing the original active action
		 * NOTE: This will mean exiting tweakmode...
		 */
		BKE_nla_tweakmode_exit(adt);
		
		/* Deal with solo flags...
		 * Assume: Solo Track == NLA Muting
		 */
		if (adt->flag & ADT_NLA_SOLO_TRACK) {
			/* turn off solo flags on tracks */
			act_track->flag &= ~NLATRACK_SOLO;
			adt->flag &= ~ADT_NLA_SOLO_TRACK;
			
			/* turn on NLA muting (to keep same effect) */
			adt->flag |= ADT_NLA_EVAL_OFF;
			
			// TODO: Needs restpose flushing (when we get reference track)
		}
	}
	
	/* Update the action that this editor now uses
	 * NOTE: The calls above have already handled the usercount/animdata side of things
	 */
	actedit_change_action(C, adt->action);
	return OPERATOR_FINISHED;
}
Exemple #4
0
static int action_layer_prev_exec(bContext *C, wmOperator *op)
{
	AnimData *adt = ED_actedit_animdata_from_context(C);
	NlaTrack *act_track;
	NlaTrack *nlt;
	
	Scene *scene = CTX_data_scene(C);
	float ctime = BKE_scene_frame_get(scene);
	
	/* Sanity Check */
	if (adt == NULL) {
		BKE_report(op->reports, RPT_ERROR, "Internal Error: Could not find Animation Data/NLA Stack to use");
		return OPERATOR_CANCELLED;
	}
	
	/* Get active track */
	act_track = BKE_nlatrack_find_tweaked(adt);
	
	/* If there is no active track, that means we are using the active action... */
	if (act_track) {
		/* Active Track - Start from the one below it */
		nlt = act_track->prev;
	}
	else {
		/* Active Action - Use the top-most track */
		nlt = adt->nla_tracks.last;
	}
	
	/* Find previous action and hook it up */
	for (; nlt; nlt = nlt->prev) {
		NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
		
		if (strip) {
			action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
			break;
		}
	}
	
	/* Update the action that this editor now uses
	 * NOTE: The calls above have already handled the usercount/animdata side of things
	 */
	actedit_change_action(C, adt->action);
	return OPERATOR_FINISHED;
}
Exemple #5
0
void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports, bool force_delete)
{
	ScrArea *sa = CTX_wm_area(C);
	
	/* If the old action only has a single user (that it's about to lose),
	 * warn user about it
	 *
	 * TODO: Maybe we should just save it for them? But then, there's the problem of
	 *       trying to get rid of stuff that's actually unwanted!
	 */
	if (act->id.us == 1) {
		BKE_reportf(reports, RPT_WARNING,
		            "Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
		            act->id.name + 2);
	}
	
	/* Clear Fake User and remove action stashing strip (if present) */
	if (force_delete) {
		/* Remove stashed strip binding this action to this datablock */
		/* XXX: we cannot unlink it from *OTHER* datablocks that may also be stashing it,
		 * but GE users only seem to use/care about single-object binding for now so this
		 * should be fine
		 */
		if (adt) {
			NlaTrack *nlt, *nlt_next;
			NlaStrip *strip, *nstrip;
			
			for (nlt = adt->nla_tracks.first; nlt; nlt = nlt_next) {
				nlt_next = nlt->next;
				
				if (strstr(nlt->name, DATA_("[Action Stash]"))) {
					for (strip = nlt->strips.first; strip; strip = nstrip) {
						nstrip = strip->next;
						
						if (strip->act == act) {
							/* Remove this strip, and the track too if it doesn't have anything else */
							free_nlastrip(&nlt->strips, strip);
							
							if (nlt->strips.first == NULL) {
								BLI_assert(nstrip == NULL);
								free_nlatrack(&adt->nla_tracks, nlt);
							}
						}
					}
				}
			}
		}
		
		/* Clear Fake User */
		id_fake_user_clear(&act->id);
	}
	
	/* If in Tweak Mode, don't unlink. Instead, this 
	 * becomes a shortcut to exit Tweak Mode instead
	 */
	if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
		/* Exit Tweak Mode */
		BKE_nla_tweakmode_exit(adt);
		
		/* Flush this to the Action Editor (if that's where this change was initiated) */
		if (sa->spacetype == SPACE_ACTION) {
			actedit_change_action(C, NULL);
		}
	}
	else {
		/* Unlink normally - Setting it to NULL should be enough to get the old one unlinked */
		if (sa->spacetype == SPACE_ACTION) {
			/* clear action editor -> action */
			actedit_change_action(C, NULL);
		}
		else {
			/* clear AnimData -> action */
			PointerRNA ptr;
			PropertyRNA *prop;
			
			/* create AnimData RNA pointers */
			RNA_pointer_create(id, &RNA_AnimData, adt, &ptr);
			prop = RNA_struct_find_property(&ptr, "action");
			
			/* clear... */
			RNA_property_pointer_set(&ptr, prop, PointerRNA_NULL);
			RNA_property_update(C, &ptr, prop);
		}
	}
}