Exemple #1
0
/* delete active frame - wrapper around API calls */
static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	bGPdata *gpd = gpencil_data_get_active(C);
	bGPDlayer *gpl = gpencil_layer_getactive(gpd);
	bGPDframe *gpf = gpencil_layer_getframe(gpl, CFRA, 0);
	
	/* if there's no existing Grease-Pencil data there, add some */
	if (gpd == NULL) {
		BKE_report(op->reports, RPT_ERROR, "No grease pencil data");
		return OPERATOR_CANCELLED;
	}
	if (ELEM(NULL, gpl, gpf)) {
		BKE_report(op->reports, RPT_ERROR, "No active frame to delete");
		return OPERATOR_CANCELLED;
	}
	
	/* delete it... */
	gpencil_layer_delframe(gpl, gpf);
	
	/* notifiers */
	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
	
	return OPERATOR_FINISHED;
}
Exemple #2
0
static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, PointerRNA *frame_ptr)
{
	bGPDframe *frame = frame_ptr->data;
	if (BLI_findindex(&layer->frames, frame) == -1) {
		BKE_report(reports, RPT_ERROR, "Frame not found in grease pencil layer");
		return;
	}

	gpencil_layer_delframe(layer, frame);
	RNA_POINTER_INVALIDATE(frame_ptr);

	WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
Exemple #3
0
/* Delete selected frames */
void delete_gplayer_frames (bGPDlayer *gpl)
{
	bGPDframe *gpf, *gpfn;
	
	/* error checking */
	if (gpl == NULL)
		return;
		
	/* check for frames to delete */
	for (gpf= gpl->frames.first; gpf; gpf= gpfn) {
		gpfn= gpf->next;
		
		if (gpf->flag & GP_FRAME_SELECT)
			gpencil_layer_delframe(gpl, gpf);
	}
}
Exemple #4
0
/* delete the last stroke of the given frame */
void gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf)
{
	bGPDstroke *gps = (gpf) ? gpf->strokes.last : NULL;
	int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */
	
	/* error checking */
	if (ELEM(NULL, gpf, gps))
		return;
	
	/* free the stroke and its data */
	MEM_freeN(gps->points);
	BLI_freelinkN(&gpf->strokes, gps);
	
	/* if frame has no strokes after this, delete it */
	if (BLI_listbase_is_empty(&gpf->strokes)) {
		gpencil_layer_delframe(gpl, gpf);
		gpencil_layer_getframe(gpl, cfra, 0);
	}
}
/* Delete selected frames */
bool ED_gplayer_frames_delete(bGPDlayer *gpl)
{
	bGPDframe *gpf, *gpfn;
	bool changed = false;
	
	/* error checking */
	if (gpl == NULL)
		return false;
	
	/* check for frames to delete */
	for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
		gpfn = gpf->next;
		
		if (gpf->flag & GP_FRAME_SELECT)
			changed |= gpencil_layer_delframe(gpl, gpf);
	}
	
	return changed;
}
/* Pastes keyframes from buffer, and reports success */
bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
{
	ListBase anim_data = {NULL, NULL};
	bAnimListElem *ale;
	int filter;
	
	Scene *scene = ac->scene;
	bool no_name = false;
	int offset = 0;
	
	/* check if buffer is empty */
	if (BLI_listbase_is_empty(&gp_anim_copybuf)) {
		BKE_report(ac->reports, RPT_ERROR, "No data in buffer to paste");
		return false;
	}
	
	/* check if single channel in buffer (disregard names if so)  */
	if (gp_anim_copybuf.first == gp_anim_copybuf.last) {
		no_name = true;
	}
	
	/* methods of offset (eKeyPasteOffset) */
	switch (offset_mode) {
		case KEYFRAME_PASTE_OFFSET_CFRA_START:
			offset = (CFRA - gp_anim_copy_firstframe);
			break;
		case KEYFRAME_PASTE_OFFSET_CFRA_END:
			offset = (CFRA - gp_anim_copy_lastframe);
			break;
		case KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE:
			offset = (CFRA - gp_anim_copy_cfra);
			break;
		case KEYFRAME_PASTE_OFFSET_NONE:
			offset = 0;
			break;
	}

	
	/* filter data */
	// TODO: try doing it with selection, then without selection imits
	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
	
	/* from selected channels */
	for (ale = anim_data.first; ale; ale = ale->next) {
		bGPDlayer *gpld = (bGPDlayer *)ale->data;
		bGPDlayer *gpls = NULL;
		bGPDframe *gpfs, *gpf;
		
		
		/* find suitable layer from buffer to use to paste from */
		for (gpls = gp_anim_copybuf.first; gpls; gpls = gpls->next) {
			/* check if layer name matches */
			if ((no_name) || STREQ(gpls->info, gpld->info)) {
				break;
			}
		}
		
		/* this situation might occur! */
		if (gpls == NULL)
			continue;
		
		/* add frames from buffer */
		for (gpfs = gpls->frames.first; gpfs; gpfs = gpfs->next) {
			/* temporarily apply offset to buffer-frame while copying */
			gpfs->framenum += offset;
			
			/* get frame to copy data into (if no frame returned, then just ignore) */
			gpf = gpencil_layer_getframe(gpld, gpfs->framenum, 1);
			if (gpf) {
				bGPDstroke *gps, *gpsn;
				
				/* This should be the right frame... as it may be a pre-existing frame,
				 * must make sure that only compatible stroke types get copied over
				 *	- We cannot just add a duplicate frame, as that would cause errors
				 *  - For now, we don't check if the types will be compatible since we
				 *    don't have enough info to do so. Instead, we simply just paste,
				 *    af it works, it will show up.
				 */
				for (gps = gpfs->strokes.first; gps; gps = gps->next) {
					/* make a copy of stroke, then of its points array */
					gpsn = MEM_dupallocN(gps);
					gpsn->points = MEM_dupallocN(gps->points);
					/* duplicate triangle information */
					gpsn->triangles = MEM_dupallocN(gps->triangles);
					/* append stroke to frame */
					BLI_addtail(&gpf->strokes, gpsn);				
				}
				
				/* if no strokes (i.e. new frame) added, free gpf */
				if (BLI_listbase_is_empty(&gpf->strokes))
					gpencil_layer_delframe(gpld, gpf);
			}
			
			/* unapply offset from buffer-frame */
			gpfs->framenum -= offset;
		}
	}
	
	/* clean up */
	ANIM_animdata_freelist(&anim_data);
	return true;
}
Exemple #7
0
void paste_gpdata (Scene *scene)
{
	ListBase act_data = {NULL, NULL};
	bActListElem *ale;
	int filter;
	void *data;
	short datatype;
	
	const int offset = (CFRA - gpcopy_firstframe);
	short no_name= 0;
	
	/* check if buffer is empty */
	if (ELEM(NULL, gpcopybuf.first, gpcopybuf.last)) {
		error("No data in buffer to paste");
		return;
	}
	/* check if single channel in buffer (disregard names if so)  */
	if (gpcopybuf.first == gpcopybuf.last)
		no_name= 1;
	
	/* get data */
	data= get_action_context(&datatype);
	if (data == NULL) return;
	if (datatype != ACTCONT_GPENCIL) return;
	
	/* filter data */
	filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT);
	actdata_filter(&act_data, filter, data, datatype);
	
	/* from selected channels */
	for (ale= act_data.first; ale; ale= ale->next) {
		bGPDlayer *gpld= (bGPDlayer *)ale->data;
		bGPDlayer *gpls= NULL;
		bGPDframe *gpfs, *gpf;
		
		/* find suitable layer from buffer to use to paste from */
		for (gpls= gpcopybuf.first; gpls; gpls= gpls->next) {
			/* check if layer name matches */
			if ((no_name) || (strcmp(gpls->info, gpld->info)==0))
				break;
		}
		
		/* this situation might occur! */
		if (gpls == NULL)
			continue;
		
		/* add frames from buffer */
		for (gpfs= gpls->frames.first; gpfs; gpfs= gpfs->next) {
			/* temporarily apply offset to buffer-frame while copying */
			gpfs->framenum += offset;
			
			/* get frame to copy data into (if no frame returned, then just ignore) */
			gpf= gpencil_layer_getframe(gpld, gpfs->framenum, 1);
			if (gpf) {
				bGPDstroke *gps, *gpsn;
				ScrArea *sa;
				
				/* get area that gp-data comes from */
				//sa= gpencil_data_findowner((bGPdata *)ale->owner);	
				sa = NULL;
				
				/* this should be the right frame... as it may be a pre-existing frame, 
				 * must make sure that only compatible stroke types get copied over 
				 *	- we cannot just add a duplicate frame, as that would cause errors
				 *	- need to check for compatible types to minimise memory usage (copying 'junk' over)
				 */
				for (gps= gpfs->strokes.first; gps; gps= gps->next) {
					short stroke_ok;
					
					/* if there's an area, check that it supports this type of stroke */
					if (sa) {
						stroke_ok= 0;
						
						/* check if spacetype supports this type of stroke
						 *	- NOTE: must sync this with gp_paint_initstroke() in gpencil.c
						 */
						switch (sa->spacetype) {
							case SPACE_VIEW3D: /* 3D-View: either screen-aligned or 3d-space */
								if ((gps->flag == 0) || (gps->flag & GP_STROKE_3DSPACE))
									stroke_ok= 1;
								break;
								
							case SPACE_NODE: /* Nodes Editor: either screen-aligned or view-aligned */
							case SPACE_IMAGE: /* Image Editor: either screen-aligned or view\image-aligned */
								if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DSPACE))
									stroke_ok= 1;
								break;
								
							case SPACE_SEQ: /* Sequence Editor: either screen-aligned or view-aligned */
								if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DIMAGE))
									stroke_ok= 1;
								break;
						}
					}
					else
						stroke_ok= 1;
					
					/* if stroke is ok, we make a copy of this stroke and add to frame */
					if (stroke_ok) {
						/* make a copy of stroke, then of its points array */
						gpsn= MEM_dupallocN(gps);
						gpsn->points= MEM_dupallocN(gps->points);
						
						/* append stroke to frame */
						BLI_addtail(&gpf->strokes, gpsn);
					}
				}
				
				/* if no strokes (i.e. new frame) added, free gpf */
				if (gpf->strokes.first == NULL)
					gpencil_layer_delframe(gpld, gpf);
			}
			
			/* unapply offset from buffer-frame */
			gpfs->framenum -= offset;
		}
	}
	
	/* free temp memory */
	BLI_freelistN(&act_data);
	
	/* undo and redraw stuff */
	BIF_undo_push("Paste Grease Pencil Frames");
}