Beispiel #1
0
/* duplicate selected keyframes for the given F-Curve */
void duplicate_fcurve_keys(FCurve *fcu)
{
	BezTriple *newbezt;
	int i;
	
	/* this can only work when there is an F-Curve, and also when there are some BezTriples */
	if (ELEM(NULL, fcu, fcu->bezt))
		return;
	
	for (i = 0; i < fcu->totvert; i++) {
		/* If a key is selected */
		if (fcu->bezt[i].f2 & SELECT) {
			/* Expand the list */
			newbezt = MEM_callocN(sizeof(BezTriple) * (fcu->totvert + 1), "beztriple");
			
			memcpy(newbezt, fcu->bezt, sizeof(BezTriple) * (i + 1));
			memcpy(newbezt + i + 1, fcu->bezt + i, sizeof(BezTriple));
			memcpy(newbezt + i + 2, fcu->bezt + i + 1, sizeof(BezTriple) * (fcu->totvert - (i + 1)));
			fcu->totvert++;
			
			/* reassign pointers... (free old, and add new) */
			MEM_freeN(fcu->bezt);
			fcu->bezt = newbezt;
			
			/* Unselect the current key */
			BEZT_DESEL_ALL(&fcu->bezt[i]);
			i++;
			
			/* Select the copied key */
			BEZT_SEL_ALL(&fcu->bezt[i]);
		}
	}
}
Beispiel #2
0
/* flush selection map values to the given beztriple */
short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt)
{
	const char *map = ked->data;
	short on = map[ked->curIndex];
	
	/* select or deselect based on whether the map allows it or not */
	if (on) {
		BEZT_SEL_ALL(bezt);
	}
	else {
		BEZT_DESEL_ALL(bezt);
	}
	
	return 0;
}
void ED_curve_nurb_deselect_all(Nurb *nu)
{
	int i;

	if (nu->bezt) {
		BezTriple *bezt;
		for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
			BEZT_DESEL_ALL(bezt);
		}
	}
	else if (nu->bp) {
		BPoint *bp;
		for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
			bp->f1 &= ~SELECT;
		}
	}
}
Beispiel #4
0
static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt) 
{
	/* if we've got info on what to deselect, use it, otherwise deselect all */
	if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
		if (ked->curflags & KEYFRAME_OK_KEY)
			bezt->f2 &= ~SELECT;
		if (ked->curflags & KEYFRAME_OK_H1)
			bezt->f1 &= ~SELECT;
		if (ked->curflags & KEYFRAME_OK_H2)
			bezt->f3 &= ~SELECT;
	}
	else {
		BEZT_DESEL_ALL(bezt);
	}
	
	return 0;
}
Beispiel #5
0
/* helper for paste_animedit_keys() - performs the actual pasting */
static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float offset, const eKeyMergeMode merge_mode, bool flip)
{
	BezTriple *bezt;
	int i;

	/* First de-select existing FCurve's keyframes */
	for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
		BEZT_DESEL_ALL(bezt);
	}

	/* mix mode with existing data */
	switch (merge_mode) {
		case KEYFRAME_PASTE_MERGE_MIX:
			/* do-nothing */
			break;
			
		case KEYFRAME_PASTE_MERGE_OVER:
			/* remove all keys */
			clear_fcurve_keys(fcu);
			break;
			
		case KEYFRAME_PASTE_MERGE_OVER_RANGE:
		case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL:
		{
			float f_min;
			float f_max;
			
			if (merge_mode == KEYFRAME_PASTE_MERGE_OVER_RANGE) {
				f_min = aci->bezt[0].vec[1][0] + offset;
				f_max = aci->bezt[aci->totvert - 1].vec[1][0] + offset;
			}
			else { /* Entire Range */
				f_min = animcopy_firstframe + offset;
				f_max = animcopy_lastframe + offset;
			}
			
			/* remove keys in range */
			if (f_min < f_max) {
				/* select verts in range for removal */
				for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
					if ((f_min < bezt[0].vec[1][0]) && (bezt[0].vec[1][0] < f_max)) {
						bezt->f2 |= SELECT;
					}
				}
				
				/* remove frames in the range */
				delete_fcurve_keys(fcu);
			}
			break;
		}
	}
	
	/* just start pasting, with the first keyframe on the current frame, and so on */
	for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) {
		/* temporarily apply offset to src beztriple while copying */
		if (flip)
			do_curve_mirror_flippping(aci, bezt);
		
		bezt->vec[0][0] += offset;
		bezt->vec[1][0] += offset;
		bezt->vec[2][0] += offset;
		
		/* insert the keyframe
		 * NOTE: we do not want to inherit handles from existing keyframes in this case!
		 */
		
		insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL);
		
		/* un-apply offset from src beztriple after copying */
		bezt->vec[0][0] -= offset;
		bezt->vec[1][0] -= offset;
		bezt->vec[2][0] -= offset;
		
		if (flip)
			do_curve_mirror_flippping(aci, bezt);
	}
	
	/* recalculate F-Curve's handles? */
	calchandles_fcurve(fcu);
}
Beispiel #6
0
/* option 1) select keyframe directly under mouse */
static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_mode, short curves_only)
{
	SpaceIpo *sipo = (SpaceIpo *)ac->sl;
	tNearestVertInfo *nvi;
	BezTriple *bezt = NULL;
	
	/* find the beztriple that we're selecting, and the handle that was clicked on */
	nvi = find_nearest_fcurve_vert(ac, mval);
	
	/* check if anything to select */
	if (nvi == NULL)
		return;
	
	/* deselect all other curves? */
	if (select_mode == SELECT_REPLACE) {
		/* reset selection mode */
		select_mode = SELECT_ADD;
		
		/* deselect all other keyframes (+ F-Curves too) */
		deselect_graph_keys(ac, 0, SELECT_SUBTRACT, true);
		
		/* deselect other channels too, but only only do this if 
		 * selection of channel when the visibility of keyframes 
		 * doesn't depend on this 
		 */
		if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0)
			ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
	}
	
	/* if points can be selected on this F-Curve */
	// TODO: what about those with no keyframes?
	if ((curves_only == 0) && ((nvi->fcu->flag & FCURVE_PROTECTED) == 0)) {
		/* only if there's keyframe */
		if (nvi->bezt) {
			bezt = nvi->bezt; /* used to check bezt seletion is set */
			/* depends on selection mode */
			if (select_mode == SELECT_INVERT) {
				/* keyframe - invert select of all */
				if (nvi->hpoint == NEAREST_HANDLE_KEY) {
					if (BEZT_ISSEL_ANY(bezt)) {
						BEZT_DESEL_ALL(bezt);
					}
					else {
						BEZT_SEL_ALL(bezt);
					}
				}
				
				/* handles - toggle selection of relevant handle */
				else if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
					/* toggle selection */
					bezt->f1 ^= SELECT;
				}
				else {
					/* toggle selection */
					bezt->f3 ^= SELECT;
				}
			}
			else {
				/* if the keyframe was clicked on, select all verts of given beztriple */
				if (nvi->hpoint == NEAREST_HANDLE_KEY) {
					BEZT_SEL_ALL(bezt);
				}
				/* otherwise, select the handle that applied */
				else if (nvi->hpoint == NEAREST_HANDLE_LEFT) 
					bezt->f1 |= SELECT;
				else 
					bezt->f3 |= SELECT;
			}
		}
		else if (nvi->fpt) {
			// TODO: need to handle sample points
		}
	}
	else {
		KeyframeEditFunc select_cb;
		KeyframeEditData ked;
		
		/* initialize keyframe editing data */
		memset(&ked, 0, sizeof(KeyframeEditData));
		
		/* set up BezTriple edit callbacks */
		select_cb = ANIM_editkeyframes_select(select_mode);
		
		/* select all keyframes */
		ANIM_fcurve_keyframes_loop(&ked, nvi->fcu, NULL, select_cb, NULL);
	}
	
	/* only change selection of channel when the visibility of keyframes doesn't depend on this */
	if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
		/* select or deselect curve? */
		if (bezt) {
			/* take selection status from item that got hit, to prevent flip/flop on channel 
			 * selection status when shift-selecting (i.e. "SELECT_INVERT") points
			 */
			if (BEZT_ISSEL_ANY(bezt))
				nvi->fcu->flag |= FCURVE_SELECTED;
			else
				nvi->fcu->flag &= ~FCURVE_SELECTED;
		}
		else {
			/* didn't hit any channel, so just apply that selection mode to the curve's selection status */
			if (select_mode == SELECT_INVERT)
				nvi->fcu->flag ^= FCURVE_SELECTED;
			else if (select_mode == SELECT_ADD)
				nvi->fcu->flag |= FCURVE_SELECTED;
		}
	}

	/* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
	/* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) otherwise the active flag won't be set [#26452] */
	if (nvi->fcu->flag & FCURVE_SELECTED) {
		int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
		ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype);
	}

	/* free temp sample data for filtering */
	MEM_freeN(nvi);
}