Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editaction_gpencil.c')
-rw-r--r--source/blender/src/editaction_gpencil.c755
1 files changed, 0 insertions, 755 deletions
diff --git a/source/blender/src/editaction_gpencil.c b/source/blender/src/editaction_gpencil.c
deleted file mode 100644
index fb070624e8f..00000000000
--- a/source/blender/src/editaction_gpencil.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2008, Blender Foundation
- * This is a new part of Blender
- *
- * Contributor(s): Joshua Leung
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <math.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "MEM_guardedalloc.h"
-
-#include "BMF_Api.h"
-
-#include "BLI_arithb.h"
-#include "BLI_blenlib.h"
-
-#include "DNA_listBase.h"
-#include "DNA_action_types.h"
-#include "DNA_gpencil_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_view2d_types.h"
-
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
-#include "BKE_blender.h"
-#include "BKE_ipo.h"
-
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-#include "BIF_butspace.h"
-#include "BIF_graphics.h"
-#include "BIF_interface.h"
-#include "BIF_mywindow.h"
-#include "BIF_resources.h"
-#include "BIF_space.h"
-#include "BIF_screen.h"
-#include "BIF_toolbox.h"
-#include "BIF_toets.h"
-
-#include "BIF_editaction.h"
-#include "BSE_editaction_types.h"
-
-#include "BDR_gpencil.h"
-#include "BIF_drawgpencil.h"
-
-#include "BSE_drawipo.h"
-#include "BSE_headerbuttons.h"
-#include "BSE_time.h"
-#include "BSE_view.h"
-
-#include "blendef.h"
-#include "butspace.h"
-
-#include "PIL_time.h"
-#include "mydevice.h"
-
-/* ***************************************** */
-/* NOTE ABOUT THIS FILE:
- * This file contains code for editing Grease Pencil data in the Action Editor
- * as a 'keyframes', so that a user can adjust the timing of Grease Pencil drawings.
- * Therefore, this file mostly contains functions for selecting Grease-Pencil frames.
- */
-/* ***************************************** */
-/* Generics - Loopers */
-
-/* Loops over the gp-frames for a gp-layer, and applies the given callback */
-short gplayer_frames_looper (bGPDlayer *gpl, short (*gpf_cb)(bGPDframe *))
-{
- bGPDframe *gpf;
-
- /* error checker */
- if (gpl == NULL)
- return 0;
-
- /* do loop */
- for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- /* execute callback */
- if (gpf_cb(gpf))
- return 1;
- }
-
- /* nothing to return */
- return 0;
-}
-
-/* ****************************************** */
-/* Data Conversion Tools */
-
-/* make a listing all the gp-frames in a layer as cfraelems */
-void gplayer_make_cfra_list (bGPDlayer *gpl, ListBase *elems, short onlysel)
-{
- bGPDframe *gpf;
- CfraElem *ce;
-
- /* error checking */
- if (ELEM(NULL, gpl, elems))
- return;
-
- /* loop through gp-frames, adding */
- for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- if ((onlysel == 0) || (gpf->flag & GP_FRAME_SELECT)) {
- ce= MEM_callocN(sizeof(CfraElem), "CfraElem");
-
- ce->cfra= (float)gpf->framenum;
- ce->sel= (gpf->flag & GP_FRAME_SELECT) ? 1 : 0;
-
- BLI_addtail(elems, ce);
- }
- }
-}
-
-/* ***************************************** */
-/* Selection Tools */
-
-/* check if one of the frames in this layer is selected */
-short is_gplayer_frame_selected (bGPDlayer *gpl)
-{
- bGPDframe *gpf;
-
- /* error checking */
- if (gpl == NULL)
- return 0;
-
- /* stop at the first one found */
- for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- if (gpf->flag & GP_FRAME_SELECT)
- return 1;
- }
-
- /* not found */
- return 0;
-}
-
-/* helper function - select gp-frame based on SELECT_* mode */
-static void gpframe_select (bGPDframe *gpf, short select_mode)
-{
- switch (select_mode) {
- case SELECT_ADD:
- gpf->flag |= GP_FRAME_SELECT;
- break;
- case SELECT_SUBTRACT:
- gpf->flag &= ~GP_FRAME_SELECT;
- break;
- case SELECT_INVERT:
- gpf->flag ^= GP_FRAME_SELECT;
- break;
- }
-}
-
-/* set all/none/invert select (like above, but with SELECT_* modes) */
-void select_gpencil_frames (bGPDlayer *gpl, short select_mode)
-{
- bGPDframe *gpf;
-
- /* error checking */
- if (gpl == NULL)
- return;
-
- /* handle according to mode */
- for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- gpframe_select(gpf, select_mode);
- }
-}
-
-/* set all/none/invert select */
-void set_gplayer_frame_selection (bGPDlayer *gpl, short mode)
-{
- /* error checking */
- if (gpl == NULL)
- return;
-
- /* convert mode to select_mode */
- switch (mode) {
- case 2:
- mode= SELECT_INVERT;
- break;
- case 1:
- mode= SELECT_ADD;
- break;
- case 0:
- mode= SELECT_SUBTRACT;
- break;
- default:
- return;
- }
-
- /* now call the standard function */
- select_gpencil_frames (gpl, mode);
-}
-
-/* select the frame in this layer that occurs on this frame (there should only be one at most) */
-void select_gpencil_frame (bGPDlayer *gpl, int selx, short select_mode)
-{
- bGPDframe *gpf;
-
- /* search through frames for a match */
- for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- /* there should only be one frame with this frame-number */
- if (gpf->framenum == selx) {
- gpframe_select(gpf, select_mode);
- break;
- }
- }
-}
-
-/* select the frames in this layer that occur within the bounds specified */
-void borderselect_gplayer_frames (bGPDlayer *gpl, float min, float max, short select_mode)
-{
- bGPDframe *gpf;
-
- /* only select those frames which are in bounds */
- for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- if (IN_RANGE(gpf->framenum, min, max))
- gpframe_select(gpf, select_mode);
- }
-}
-
-
-/* De-selects or inverts the selection of Layers for a grease-pencil block
- * mode: 0 = default behaviour (select all), 1 = test if (de)select all, 2 = invert all
- */
-void deselect_gpencil_layers (void *data, short mode)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter, sel=1;
-
- /* filter data */
- filter= ACTFILTER_VISIBLE;
- actdata_filter(&act_data, filter, data, ACTCONT_GPENCIL);
-
- /* See if we should be selecting or deselecting */
- if (mode == 1) {
- for (ale= act_data.first; ale; ale= ale->next) {
- if (sel == 0)
- break;
-
- if (ale->flag & GP_LAYER_SELECT)
- sel= 0;
- }
- }
- else
- sel= 0;
-
- /* Now set the flags */
- for (ale= act_data.first; ale; ale= ale->next) {
- bGPDlayer *gpl= (bGPDlayer *)ale->data;
-
- if (mode == 2)
- gpl->flag ^= GP_LAYER_SELECT;
- else if (sel)
- gpl->flag |= GP_LAYER_SELECT;
- else
- gpl->flag &= ~GP_LAYER_SELECT;
-
- gpl->flag &= ~GP_LAYER_ACTIVE;
- }
-
- /* Cleanup */
- BLI_freelistN(&act_data);
-}
-
-/* ***************************************** */
-/* Frame Editing Tools */
-
-/* Delete selected grease-pencil layers */
-void delete_gpencil_layers (void)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale, *next;
- void *data;
- short datatype;
- int filter;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
- if (datatype != ACTCONT_GPENCIL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_CHANNELS | ACTFILTER_SEL);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* clean up grease-pencil layers */
- for (ale= act_data.first; ale; ale= next) {
- bGPdata *gpd= (bGPdata *)ale->owner;
- bGPDlayer *gpl= (bGPDlayer *)ale->data;
- next= ale->next;
-
- /* free layer and its data */
- if (SEL_GPL(gpl)) {
- free_gpencil_frames(gpl);
- BLI_freelinkN(&gpd->layers, gpl);
- }
-
- /* free temp memory */
- BLI_freelinkN(&act_data, ale);
- }
-
- BIF_undo_push("Delete GPencil Layers");
- allspace(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 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);
- }
-}
-
-/* Duplicate selected frames from given gp-layer */
-void duplicate_gplayer_frames (bGPDlayer *gpl)
-{
- bGPDframe *gpf, *gpfn;
-
- /* error checking */
- if (gpl == NULL)
- return;
-
- /* duplicate selected frames */
- for (gpf= gpl->frames.first; gpf; gpf= gpfn) {
- gpfn= gpf->next;
-
- /* duplicate this frame */
- if (gpf->flag & GP_FRAME_SELECT) {
- bGPDframe *gpfd;
-
- /* duplicate frame, and deselect self */
- gpfd= gpencil_frame_duplicate(gpf);
- gpf->flag &= ~GP_FRAME_SELECT;
-
- BLI_insertlinkafter(&gpl->frames, gpf, gpfd);
- }
- }
-}
-
-/* -------------------------------------- */
-/* Copy and Paste Tools */
-/* - The copy/paste buffer currently stores a set of GP_Layers, with temporary
- * GP_Frames with the necessary strokes
- * - Unless there is only one element in the buffer, names are also tested to check for compatability.
- * - All pasted frames are offset by the same amount. This is calculated as the difference in the times of
- * the current frame and the 'first keyframe' (i.e. the earliest one in all channels).
- * - The earliest frame is calculated per copy operation.
- */
-
-/* globals for copy/paste data (like for other copy/paste buffers) */
-ListBase gpcopybuf = {NULL, NULL};
-static int gpcopy_firstframe= 999999999;
-
-/* This function frees any MEM_calloc'ed copy/paste buffer data */
-void free_gpcopybuf ()
-{
- free_gpencil_layers(&gpcopybuf);
-
- gpcopybuf.first= gpcopybuf.last= NULL;
- gpcopy_firstframe= 999999999;
-}
-
-/* This function adds data to the copy/paste buffer, freeing existing data first
- * Only the selected GP-layers get their selected keyframes copied.
- */
-void copy_gpdata ()
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
-
- /* clear buffer first */
- free_gpcopybuf();
-
- /* get data */
- data= get_action_context(&datatype);
- if (data == NULL) return;
- if (datatype != ACTCONT_GPENCIL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* assume that each of these is an ipo-block */
- for (ale= act_data.first; ale; ale= ale->next) {
- bGPDlayer *gpls, *gpln;
- bGPDframe *gpf, *gpfn;
-
- /* get new layer to put into buffer */
- gpls= (bGPDlayer *)ale->data;
- gpln= MEM_callocN(sizeof(bGPDlayer), "GPCopyPasteLayer");
-
- gpln->frames.first= gpln->frames.last= NULL;
- strcpy(gpln->info, gpls->info);
-
- BLI_addtail(&gpcopybuf, gpln);
-
- /* loop over frames, and copy only selected frames */
- for (gpf= gpls->frames.first; gpf; gpf= gpf->next) {
- /* if frame is selected, make duplicate it and its strokes */
- if (gpf->flag & GP_FRAME_SELECT) {
- /* add frame to buffer */
- gpfn= gpencil_frame_duplicate(gpf);
- BLI_addtail(&gpln->frames, gpfn);
-
- /* check if this is the earliest frame encountered so far */
- if (gpf->framenum < gpcopy_firstframe)
- gpcopy_firstframe= gpf->framenum;
- }
- }
- }
-
- /* check if anything ended up in the buffer */
- if (ELEM(NULL, gpcopybuf.first, gpcopybuf.last))
- error("Nothing copied to buffer");
-
- /* free temp memory */
- BLI_freelistN(&act_data);
-}
-
-void paste_gpdata ()
-{
- 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);
-
- /* 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 */
- allqueue(REDRAWVIEW3D, 0);
- //allqueue(REDRAWNODES, 0);
- allqueue(REDRAWACTION, 0);
- BIF_undo_push("Paste Grease Pencil Frames");
-}
-
-/* -------------------------------------- */
-/* Snap Tools */
-
-static short snap_gpf_nearest (bGPDframe *gpf)
-{
- if (gpf->flag & GP_FRAME_SELECT)
- gpf->framenum= (int)(floor(gpf->framenum+0.5));
- return 0;
-}
-
-static short snap_gpf_nearestsec (bGPDframe *gpf)
-{
- float secf = (float)FPS;
- if (gpf->flag & GP_FRAME_SELECT)
- gpf->framenum= (int)(floor(gpf->framenum/secf + 0.5f) * secf);
- return 0;
-}
-
-static short snap_gpf_cframe (bGPDframe *gpf)
-{
- if (gpf->flag & GP_FRAME_SELECT)
- gpf->framenum= (int)CFRA;
- return 0;
-}
-
-static short snap_gpf_nearmarker (bGPDframe *gpf)
-{
- if (gpf->flag & GP_FRAME_SELECT)
- gpf->framenum= (int)find_nearest_marker_time((float)gpf->framenum);
- return 0;
-}
-
-
-/* snap selected frames to ... */
-void snap_gplayer_frames (bGPDlayer *gpl, short mode)
-{
- switch (mode) {
- case 1: /* snap to nearest frame */
- gplayer_frames_looper(gpl, snap_gpf_nearest);
- break;
- case 2: /* snap to current frame */
- gplayer_frames_looper(gpl, snap_gpf_cframe);
- break;
- case 3: /* snap to nearest marker */
- gplayer_frames_looper(gpl, snap_gpf_nearmarker);
- break;
- case 4: /* snap to nearest second */
- gplayer_frames_looper(gpl, snap_gpf_nearestsec);
- break;
- default: /* just in case */
- gplayer_frames_looper(gpl, snap_gpf_nearest);
- break;
- }
-}
-
-/* -------------------------------------- */
-/* Mirror Tools */
-
-static short mirror_gpf_cframe (bGPDframe *gpf)
-{
- int diff;
-
- if (gpf->flag & GP_FRAME_SELECT) {
- diff= CFRA - gpf->framenum;
- gpf->framenum= CFRA;
- }
-
- return 0;
-}
-
-static short mirror_gpf_yaxis (bGPDframe *gpf)
-{
- int diff;
-
- if (gpf->flag & GP_FRAME_SELECT) {
- diff= -gpf->framenum;
- gpf->framenum= diff;
- }
-
- return 0;
-}
-
-static short mirror_gpf_xaxis (bGPDframe *gpf)
-{
- int diff;
-
- if (gpf->flag & GP_FRAME_SELECT) {
- diff= -gpf->framenum;
- gpf->framenum= diff;
- }
-
- return 0;
-}
-
-static short mirror_gpf_marker (bGPDframe *gpf)
-{
- static TimeMarker *marker;
- static short initialised = 0;
- int diff;
-
- /* In order for this mirror function to work without
- * any extra arguments being added, we use the case
- * of bezt==NULL to denote that we should find the
- * marker to mirror over. The static pointer is safe
- * to use this way, as it will be set to null after
- * each cycle in which this is called.
- */
-
- if (gpf) {
- /* mirroring time */
- if ((gpf->flag & GP_FRAME_SELECT) && (marker)) {
- diff= (marker->frame - gpf->framenum);
- gpf->framenum= (marker->frame + diff);
- }
- }
- else {
- /* initialisation time */
- if (initialised) {
- /* reset everything for safety */
- marker = NULL;
- initialised = 0;
- }
- else {
- /* try to find a marker */
- for (marker= G.scene->markers.first; marker; marker=marker->next) {
- if (marker->flag & SELECT) {
- initialised = 1;
- break;
- }
- }
-
- if (initialised == 0)
- marker = NULL;
- }
- }
-
- return 0;
-}
-
-
-/* mirror selected gp-frames on... */
-void mirror_gplayer_frames (bGPDlayer *gpl, short mode)
-{
- switch (mode) {
- case 1: /* mirror over current frame */
- gplayer_frames_looper(gpl, mirror_gpf_cframe);
- break;
- case 2: /* mirror over frame 0 */
- gplayer_frames_looper(gpl, mirror_gpf_yaxis);
- break;
- case 3: /* mirror over value 0 */
- gplayer_frames_looper(gpl, mirror_gpf_xaxis);
- break;
- case 4: /* mirror over marker */
- mirror_gpf_marker(NULL);
- gplayer_frames_looper(gpl, mirror_gpf_marker);
- mirror_gpf_marker(NULL);
- break;
- default: /* just in case */
- gplayer_frames_looper(gpl, mirror_gpf_yaxis);
- break;
- }
-}
-
-/* ***************************************** */