/* 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 */
			BEZ_DESEL(&fcu->bezt[i]);
			i++;
			
			/* Select the copied key */
			BEZ_SEL(&fcu->bezt[i]);
		}
	}
}
Exemple #2
0
/* flush selection map values to the given beztriple */
short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt)
{
	char *map = ked->data;
	short on = map[ked->curIndex];
	
	/* select or deselect based on whether the map allows it or not */
	if (on) {
		BEZ_SEL(bezt);
	}
	else {
		BEZ_DESEL(bezt);
	}
	
	return 0;
}
Exemple #3
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 {
		BEZ_DESEL(bezt);
	}
	
	return 0;
}
Exemple #4
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 (BEZSELECTED(bezt)) {
						BEZ_DESEL(bezt);
					}
					else {
						BEZ_SEL(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) {
					BEZ_SEL(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 (BEZSELECTED(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, ANIMTYPE_FCURVE);
	}

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