Beispiel #1
0
/* Get the min/max keyframes*/
static void get_keyframe_extents (bAnimContext *ac, float *min, float *max, const short onlySel)
{
	ListBase anim_data = {NULL, NULL};
	bAnimListElem *ale;
	int filter;
	
	/* get data to filter, from Action or Dopesheet */
	filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
	
	/* set large values to try to override */
	*min= 999999999.0f;
	*max= -999999999.0f;
	
	/* check if any channels to set range with */
	if (anim_data.first) {
		/* go through channels, finding max extents */
		for (ale= anim_data.first; ale; ale= ale->next) {
			AnimData *adt= ANIM_nla_mapping_get(ac, ale);
			FCurve *fcu= (FCurve *)ale->key_data;
			float tmin, tmax;
			
			/* get range and apply necessary scaling before processing */
			calc_fcurve_range(fcu, &tmin, &tmax, onlySel);
			
			if (adt) {
				tmin= BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
				tmax= BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP);
			}
			
			/* try to set cur using these values, if they're more extreme than previously set values */
			*min= MIN2(*min, tmin);
			*max= MAX2(*max, tmax);
		}
		
		/* free memory */
		BLI_freelistN(&anim_data);
	}
	else {
		/* set default range */
		if (ac->scene) {
			*min= (float)ac->scene->r.sfra;
			*max= (float)ac->scene->r.efra;
		}
		else {
			*min= -5;
			*max= 100;
		}
	}
}
Beispiel #2
0
/* Calculate the extents of given action */
void calc_action_range(const bAction *act, float *start, float *end, short incl_modifiers)
{
	FCurve *fcu;
	float min = 999999999.0f, max = -999999999.0f;
	short foundvert = 0, foundmod = 0;

	if (act) {
		for (fcu = act->curves.first; fcu; fcu = fcu->next) {
			/* if curve has keyframes, consider them first */
			if (fcu->totvert) {
				float nmin, nmax;
				
				/* get extents for this curve */
				/* TODO: allow enabling/disabling this? */
				calc_fcurve_range(fcu, &nmin, &nmax, false, true);
				
				/* compare to the running tally */
				min = min_ff(min, nmin);
				max = max_ff(max, nmax);
				
				foundvert = 1;
			}
			
			/* if incl_modifiers is enabled, need to consider modifiers too
			 *	- only really care about the last modifier
			 */
			if ((incl_modifiers) && (fcu->modifiers.last)) {
				FModifier *fcm = fcu->modifiers.last;
				
				/* only use the maximum sensible limits of the modifiers if they are more extreme */
				switch (fcm->type) {
					case FMODIFIER_TYPE_LIMITS: /* Limits F-Modifier */
					{
						FMod_Limits *fmd = (FMod_Limits *)fcm->data;
						
						if (fmd->flag & FCM_LIMIT_XMIN) {
							min = min_ff(min, fmd->rect.xmin);
						}
						if (fmd->flag & FCM_LIMIT_XMAX) {
							max = max_ff(max, fmd->rect.xmax);
						}
						break;
					}
					case FMODIFIER_TYPE_CYCLES: /* Cycles F-Modifier */
					{
						FMod_Cycles *fmd = (FMod_Cycles *)fcm->data;
						
						if (fmd->before_mode != FCM_EXTRAPOLATE_NONE)
							min = MINAFRAMEF;
						if (fmd->after_mode != FCM_EXTRAPOLATE_NONE)
							max = MAXFRAMEF;
						break;
					}
					/* TODO: function modifier may need some special limits */
						
					default: /* all other standard modifiers are on the infinite range... */
						min = MINAFRAMEF;
						max = MAXFRAMEF;
						break;
				}
				
				foundmod = 1;
			}
		}
	}
	
	if (foundvert || foundmod) {
		if (min == max) max += 1.0f;
		*start = min;
		*end = max;
	}
	else {
		*start = 0.0f;
		*end = 1.0f;
	}
}
Beispiel #3
0
/* Get the min/max keyframes*/
static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const short onlySel)
{
	ListBase anim_data = {NULL, NULL};
	bAnimListElem *ale;
	int filter;
	bool found = false;
	
	/* get data to filter, from Action or Dopesheet */
	/* XXX: what is sel doing here?!
	 *      Commented it, was breaking things (eg. the "auto preview range" tool). */
	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL *//*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
	
	/* set large values to try to override */
	*min = 999999999.0f;
	*max = -999999999.0f;
	
	/* check if any channels to set range with */
	if (anim_data.first) {
		/* go through channels, finding max extents */
		for (ale = anim_data.first; ale; ale = ale->next) {
			AnimData *adt = ANIM_nla_mapping_get(ac, ale);
			if (ale->datatype == ALE_GPFRAME) {
				bGPDlayer *gpl = ale->data;
				bGPDframe *gpf;

				/* find gp-frame which is less than or equal to cframe */
				for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
					const float framenum = (float)gpf->framenum;
					*min = min_ff(*min, framenum);
					*max = max_ff(*max, framenum);
					found = true;
				}
			}
			else if (ale->datatype == ALE_MASKLAY) {
				MaskLayer *masklay = ale->data;
				MaskLayerShape *masklay_shape;

				/* find mask layer which is less than or equal to cframe */
				for (masklay_shape = masklay->splines_shapes.first;
				     masklay_shape;
				     masklay_shape = masklay_shape->next)
				{
					const float framenum = (float)masklay_shape->frame;
					*min = min_ff(*min, framenum);
					*max = max_ff(*max, framenum);
					found = true;
				}
			}
			else {
				FCurve *fcu = (FCurve *)ale->key_data;
				float tmin, tmax;

				/* get range and apply necessary scaling before processing */
				if (calc_fcurve_range(fcu, &tmin, &tmax, onlySel, TRUE)) {

					if (adt) {
						tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
						tmax = BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP);
					}

					/* try to set cur using these values, if they're more extreme than previously set values */
					*min = min_ff(*min, tmin);
					*max = max_ff(*max, tmax);
					found = true;
				}
			}
		}
		
		/* free memory */
		BLI_freelistN(&anim_data);
	}
	else {
		/* set default range */
		if (ac->scene) {
			*min = (float)ac->scene->r.sfra;
			*max = (float)ac->scene->r.efra;
		}
		else {
			*min = -5;
			*max = 100;
		}
	}

	return found;
}