Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008, Blender Foundation 00019 * This is a new part of Blender 00020 * 00021 * Contributor(s): Joshua Leung 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <stdio.h> 00032 #include <string.h> 00033 #include <stdlib.h> 00034 #include <stddef.h> 00035 #include <math.h> 00036 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "BLI_blenlib.h" 00040 #include "BLI_math.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "DNA_gpencil_types.h" 00044 #include "DNA_scene_types.h" 00045 00046 #include "BKE_fcurve.h" 00047 #include "BKE_gpencil.h" 00048 00049 #include "ED_anim_api.h" 00050 #include "ED_gpencil.h" 00051 #include "ED_keyframes_edit.h" 00052 00053 #include "gpencil_intern.h" 00054 00055 /* ***************************************** */ 00056 /* NOTE ABOUT THIS FILE: 00057 * This file contains code for editing Grease Pencil data in the Action Editor 00058 * as a 'keyframes', so that a user can adjust the timing of Grease Pencil drawings. 00059 * Therefore, this file mostly contains functions for selecting Grease-Pencil frames. 00060 */ 00061 /* ***************************************** */ 00062 /* Generics - Loopers */ 00063 00064 /* Loops over the gp-frames for a gp-layer, and applies the given callback */ 00065 short gplayer_frames_looper (bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *)) 00066 { 00067 bGPDframe *gpf; 00068 00069 /* error checker */ 00070 if (gpl == NULL) 00071 return 0; 00072 00073 /* do loop */ 00074 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { 00075 /* execute callback */ 00076 if (gpf_cb(gpf, scene)) 00077 return 1; 00078 } 00079 00080 /* nothing to return */ 00081 return 0; 00082 } 00083 00084 /* ****************************************** */ 00085 /* Data Conversion Tools */ 00086 00087 /* make a listing all the gp-frames in a layer as cfraelems */ 00088 void gplayer_make_cfra_list (bGPDlayer *gpl, ListBase *elems, short onlysel) 00089 { 00090 bGPDframe *gpf; 00091 CfraElem *ce; 00092 00093 /* error checking */ 00094 if (ELEM(NULL, gpl, elems)) 00095 return; 00096 00097 /* loop through gp-frames, adding */ 00098 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { 00099 if ((onlysel == 0) || (gpf->flag & GP_FRAME_SELECT)) { 00100 ce= MEM_callocN(sizeof(CfraElem), "CfraElem"); 00101 00102 ce->cfra= (float)gpf->framenum; 00103 ce->sel= (gpf->flag & GP_FRAME_SELECT) ? 1 : 0; 00104 00105 BLI_addtail(elems, ce); 00106 } 00107 } 00108 } 00109 00110 /* ***************************************** */ 00111 /* Selection Tools */ 00112 00113 /* check if one of the frames in this layer is selected */ 00114 short is_gplayer_frame_selected (bGPDlayer *gpl) 00115 { 00116 bGPDframe *gpf; 00117 00118 /* error checking */ 00119 if (gpl == NULL) 00120 return 0; 00121 00122 /* stop at the first one found */ 00123 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { 00124 if (gpf->flag & GP_FRAME_SELECT) 00125 return 1; 00126 } 00127 00128 /* not found */ 00129 return 0; 00130 } 00131 00132 /* helper function - select gp-frame based on SELECT_* mode */ 00133 static void gpframe_select (bGPDframe *gpf, short select_mode) 00134 { 00135 if (gpf == NULL) 00136 return; 00137 00138 switch (select_mode) { 00139 case SELECT_ADD: 00140 gpf->flag |= GP_FRAME_SELECT; 00141 break; 00142 case SELECT_SUBTRACT: 00143 gpf->flag &= ~GP_FRAME_SELECT; 00144 break; 00145 case SELECT_INVERT: 00146 gpf->flag ^= GP_FRAME_SELECT; 00147 break; 00148 } 00149 } 00150 00151 /* set all/none/invert select (like above, but with SELECT_* modes) */ 00152 void select_gpencil_frames (bGPDlayer *gpl, short select_mode) 00153 { 00154 bGPDframe *gpf; 00155 00156 /* error checking */ 00157 if (gpl == NULL) 00158 return; 00159 00160 /* handle according to mode */ 00161 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { 00162 gpframe_select(gpf, select_mode); 00163 } 00164 } 00165 00166 /* set all/none/invert select */ 00167 void set_gplayer_frame_selection (bGPDlayer *gpl, short mode) 00168 { 00169 /* error checking */ 00170 if (gpl == NULL) 00171 return; 00172 00173 /* now call the standard function */ 00174 select_gpencil_frames(gpl, mode); 00175 } 00176 00177 /* select the frame in this layer that occurs on this frame (there should only be one at most) */ 00178 void select_gpencil_frame (bGPDlayer *gpl, int selx, short select_mode) 00179 { 00180 bGPDframe *gpf; 00181 00182 if (gpl == NULL) 00183 return; 00184 00185 /* search through frames for a match */ 00186 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { 00187 /* there should only be one frame with this frame-number */ 00188 if (gpf->framenum == selx) { 00189 gpframe_select(gpf, select_mode); 00190 break; 00191 } 00192 } 00193 } 00194 00195 /* select the frames in this layer that occur within the bounds specified */ 00196 void borderselect_gplayer_frames (bGPDlayer *gpl, float min, float max, short select_mode) 00197 { 00198 bGPDframe *gpf; 00199 00200 if (gpl == NULL) 00201 return; 00202 00203 /* only select those frames which are in bounds */ 00204 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { 00205 if (IN_RANGE(gpf->framenum, min, max)) 00206 gpframe_select(gpf, select_mode); 00207 } 00208 } 00209 00210 /* ***************************************** */ 00211 /* Frame Editing Tools */ 00212 00213 /* Delete selected frames */ 00214 void delete_gplayer_frames (bGPDlayer *gpl) 00215 { 00216 bGPDframe *gpf, *gpfn; 00217 00218 /* error checking */ 00219 if (gpl == NULL) 00220 return; 00221 00222 /* check for frames to delete */ 00223 for (gpf= gpl->frames.first; gpf; gpf= gpfn) { 00224 gpfn= gpf->next; 00225 00226 if (gpf->flag & GP_FRAME_SELECT) 00227 gpencil_layer_delframe(gpl, gpf); 00228 } 00229 } 00230 00231 /* Duplicate selected frames from given gp-layer */ 00232 void duplicate_gplayer_frames (bGPDlayer *gpl) 00233 { 00234 bGPDframe *gpf, *gpfn; 00235 00236 /* error checking */ 00237 if (gpl == NULL) 00238 return; 00239 00240 /* duplicate selected frames */ 00241 for (gpf= gpl->frames.first; gpf; gpf= gpfn) { 00242 gpfn= gpf->next; 00243 00244 /* duplicate this frame */ 00245 if (gpf->flag & GP_FRAME_SELECT) { 00246 bGPDframe *gpfd; 00247 00248 /* duplicate frame, and deselect self */ 00249 gpfd= gpencil_frame_duplicate(gpf); 00250 gpf->flag &= ~GP_FRAME_SELECT; 00251 00252 BLI_insertlinkafter(&gpl->frames, gpf, gpfd); 00253 } 00254 } 00255 } 00256 00257 #if 0 // XXX disabled until grease pencil code stabilises again 00258 /* -------------------------------------- */ 00259 /* Copy and Paste Tools */ 00260 /* - The copy/paste buffer currently stores a set of GP_Layers, with temporary 00261 * GP_Frames with the necessary strokes 00262 * - Unless there is only one element in the buffer, names are also tested to check for compatibility. 00263 * - All pasted frames are offset by the same amount. This is calculated as the difference in the times of 00264 * the current frame and the 'first keyframe' (i.e. the earliest one in all channels). 00265 * - The earliest frame is calculated per copy operation. 00266 */ 00267 00268 /* globals for copy/paste data (like for other copy/paste buffers) */ 00269 ListBase gpcopybuf = {NULL, NULL}; 00270 static int gpcopy_firstframe= 999999999; 00271 00272 /* This function frees any MEM_calloc'ed copy/paste buffer data */ 00273 void free_gpcopybuf () 00274 { 00275 free_gpencil_layers(&gpcopybuf); 00276 00277 gpcopybuf.first= gpcopybuf.last= NULL; 00278 gpcopy_firstframe= 999999999; 00279 } 00280 00281 /* This function adds data to the copy/paste buffer, freeing existing data first 00282 * Only the selected GP-layers get their selected keyframes copied. 00283 */ 00284 void copy_gpdata () 00285 { 00286 ListBase act_data = {NULL, NULL}; 00287 bActListElem *ale; 00288 int filter; 00289 void *data; 00290 short datatype; 00291 00292 /* clear buffer first */ 00293 free_gpcopybuf(); 00294 00295 /* get data */ 00296 data= get_action_context(&datatype); 00297 if (data == NULL) return; 00298 if (datatype != ACTCONT_GPENCIL) return; 00299 00300 /* filter data */ 00301 filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL); 00302 actdata_filter(&act_data, filter, data, datatype); 00303 00304 /* assume that each of these is an ipo-block */ 00305 for (ale= act_data.first; ale; ale= ale->next) { 00306 bGPDlayer *gpls, *gpln; 00307 bGPDframe *gpf, *gpfn; 00308 00309 /* get new layer to put into buffer */ 00310 gpls= (bGPDlayer *)ale->data; 00311 gpln= MEM_callocN(sizeof(bGPDlayer), "GPCopyPasteLayer"); 00312 00313 gpln->frames.first= gpln->frames.last= NULL; 00314 BLI_strncpy(gpln->info, gpls->info, sizeof(gpln->info)); 00315 00316 BLI_addtail(&gpcopybuf, gpln); 00317 00318 /* loop over frames, and copy only selected frames */ 00319 for (gpf= gpls->frames.first; gpf; gpf= gpf->next) { 00320 /* if frame is selected, make duplicate it and its strokes */ 00321 if (gpf->flag & GP_FRAME_SELECT) { 00322 /* add frame to buffer */ 00323 gpfn= gpencil_frame_duplicate(gpf); 00324 BLI_addtail(&gpln->frames, gpfn); 00325 00326 /* check if this is the earliest frame encountered so far */ 00327 if (gpf->framenum < gpcopy_firstframe) 00328 gpcopy_firstframe= gpf->framenum; 00329 } 00330 } 00331 } 00332 00333 /* check if anything ended up in the buffer */ 00334 if (ELEM(NULL, gpcopybuf.first, gpcopybuf.last)) 00335 error("Nothing copied to buffer"); 00336 00337 /* free temp memory */ 00338 BLI_freelistN(&act_data); 00339 } 00340 00341 void paste_gpdata (Scene *scene) 00342 { 00343 ListBase act_data = {NULL, NULL}; 00344 bActListElem *ale; 00345 int filter; 00346 void *data; 00347 short datatype; 00348 00349 const int offset = (CFRA - gpcopy_firstframe); 00350 short no_name= 0; 00351 00352 /* check if buffer is empty */ 00353 if (ELEM(NULL, gpcopybuf.first, gpcopybuf.last)) { 00354 error("No data in buffer to paste"); 00355 return; 00356 } 00357 /* check if single channel in buffer (disregard names if so) */ 00358 if (gpcopybuf.first == gpcopybuf.last) 00359 no_name= 1; 00360 00361 /* get data */ 00362 data= get_action_context(&datatype); 00363 if (data == NULL) return; 00364 if (datatype != ACTCONT_GPENCIL) return; 00365 00366 /* filter data */ 00367 filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT); 00368 actdata_filter(&act_data, filter, data, datatype); 00369 00370 /* from selected channels */ 00371 for (ale= act_data.first; ale; ale= ale->next) { 00372 bGPDlayer *gpld= (bGPDlayer *)ale->data; 00373 bGPDlayer *gpls= NULL; 00374 bGPDframe *gpfs, *gpf; 00375 00376 /* find suitable layer from buffer to use to paste from */ 00377 for (gpls= gpcopybuf.first; gpls; gpls= gpls->next) { 00378 /* check if layer name matches */ 00379 if ((no_name) || (strcmp(gpls->info, gpld->info)==0)) 00380 break; 00381 } 00382 00383 /* this situation might occur! */ 00384 if (gpls == NULL) 00385 continue; 00386 00387 /* add frames from buffer */ 00388 for (gpfs= gpls->frames.first; gpfs; gpfs= gpfs->next) { 00389 /* temporarily apply offset to buffer-frame while copying */ 00390 gpfs->framenum += offset; 00391 00392 /* get frame to copy data into (if no frame returned, then just ignore) */ 00393 gpf= gpencil_layer_getframe(gpld, gpfs->framenum, 1); 00394 if (gpf) { 00395 bGPDstroke *gps, *gpsn; 00396 ScrArea *sa; 00397 00398 /* get area that gp-data comes from */ 00399 //sa= gpencil_data_findowner((bGPdata *)ale->owner); 00400 sa = NULL; 00401 00402 /* this should be the right frame... as it may be a pre-existing frame, 00403 * must make sure that only compatible stroke types get copied over 00404 * - we cannot just add a duplicate frame, as that would cause errors 00405 * - need to check for compatible types to minimise memory usage (copying 'junk' over) 00406 */ 00407 for (gps= gpfs->strokes.first; gps; gps= gps->next) { 00408 short stroke_ok; 00409 00410 /* if there's an area, check that it supports this type of stroke */ 00411 if (sa) { 00412 stroke_ok= 0; 00413 00414 /* check if spacetype supports this type of stroke 00415 * - NOTE: must sync this with gp_paint_initstroke() in gpencil.c 00416 */ 00417 switch (sa->spacetype) { 00418 case SPACE_VIEW3D: /* 3D-View: either screen-aligned or 3d-space */ 00419 if ((gps->flag == 0) || (gps->flag & GP_STROKE_3DSPACE)) 00420 stroke_ok= 1; 00421 break; 00422 00423 case SPACE_NODE: /* Nodes Editor: either screen-aligned or view-aligned */ 00424 case SPACE_IMAGE: /* Image Editor: either screen-aligned or view\image-aligned */ 00425 case SPACE_CLIP: /* Image Editor: either screen-aligned or view\image-aligned */ 00426 if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DSPACE)) 00427 stroke_ok= 1; 00428 break; 00429 00430 case SPACE_SEQ: /* Sequence Editor: either screen-aligned or view-aligned */ 00431 if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DIMAGE)) 00432 stroke_ok= 1; 00433 break; 00434 } 00435 } 00436 else 00437 stroke_ok= 1; 00438 00439 /* if stroke is ok, we make a copy of this stroke and add to frame */ 00440 if (stroke_ok) { 00441 /* make a copy of stroke, then of its points array */ 00442 gpsn= MEM_dupallocN(gps); 00443 gpsn->points= MEM_dupallocN(gps->points); 00444 00445 /* append stroke to frame */ 00446 BLI_addtail(&gpf->strokes, gpsn); 00447 } 00448 } 00449 00450 /* if no strokes (i.e. new frame) added, free gpf */ 00451 if (gpf->strokes.first == NULL) 00452 gpencil_layer_delframe(gpld, gpf); 00453 } 00454 00455 /* unapply offset from buffer-frame */ 00456 gpfs->framenum -= offset; 00457 } 00458 } 00459 00460 /* free temp memory */ 00461 BLI_freelistN(&act_data); 00462 00463 /* undo and redraw stuff */ 00464 BIF_undo_push("Paste Grease Pencil Frames"); 00465 } 00466 00467 /* -------------------------------------- */ 00468 /* Snap Tools */ 00469 00470 static short snap_gpf_nearest (bGPDframe *gpf, Scene *scene) 00471 { 00472 if (gpf->flag & GP_FRAME_SELECT) 00473 gpf->framenum= (int)(floor(gpf->framenum+0.5)); 00474 return 0; 00475 } 00476 00477 static short snap_gpf_nearestsec (bGPDframe *gpf, Scene *scene) 00478 { 00479 float secf = (float)FPS; 00480 if (gpf->flag & GP_FRAME_SELECT) 00481 gpf->framenum= (int)(floor(gpf->framenum/secf + 0.5f) * secf); 00482 return 0; 00483 } 00484 00485 static short snap_gpf_cframe (bGPDframe *gpf, Scene *scene) 00486 { 00487 if (gpf->flag & GP_FRAME_SELECT) 00488 gpf->framenum= (int)CFRA; 00489 return 0; 00490 } 00491 00492 static short snap_gpf_nearmarker (bGPDframe *gpf, Scene *scene) 00493 { 00494 if (gpf->flag & GP_FRAME_SELECT) 00495 gpf->framenum= (int)find_nearest_marker_time(&scene->markers, (float)gpf->framenum); 00496 return 0; 00497 } 00498 00499 00500 /* snap selected frames to ... */ 00501 void snap_gplayer_frames (bGPDlayer *gpl, Scene *scene, short mode) 00502 { 00503 switch (mode) { 00504 case 1: /* snap to nearest frame */ 00505 gplayer_frames_looper(gpl, scene, snap_gpf_nearest); 00506 break; 00507 case 2: /* snap to current frame */ 00508 gplayer_frames_looper(gpl, scene, snap_gpf_cframe); 00509 break; 00510 case 3: /* snap to nearest marker */ 00511 gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker); 00512 break; 00513 case 4: /* snap to nearest second */ 00514 gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec); 00515 break; 00516 default: /* just in case */ 00517 gplayer_frames_looper(gpl, scene, snap_gpf_nearest); 00518 break; 00519 } 00520 } 00521 00522 /* -------------------------------------- */ 00523 /* Mirror Tools */ 00524 00525 static short mirror_gpf_cframe (bGPDframe *gpf, Scene *scene) 00526 { 00527 int diff; 00528 00529 if (gpf->flag & GP_FRAME_SELECT) { 00530 diff= CFRA - gpf->framenum; 00531 gpf->framenum= CFRA; 00532 } 00533 00534 return 0; 00535 } 00536 00537 static short mirror_gpf_yaxis (bGPDframe *gpf, Scene *scene) 00538 { 00539 int diff; 00540 00541 if (gpf->flag & GP_FRAME_SELECT) { 00542 diff= -gpf->framenum; 00543 gpf->framenum= diff; 00544 } 00545 00546 return 0; 00547 } 00548 00549 static short mirror_gpf_xaxis (bGPDframe *gpf, Scene *scene) 00550 { 00551 int diff; 00552 00553 if (gpf->flag & GP_FRAME_SELECT) { 00554 diff= -gpf->framenum; 00555 gpf->framenum= diff; 00556 } 00557 00558 return 0; 00559 } 00560 00561 static short mirror_gpf_marker (bGPDframe *gpf, Scene *scene) 00562 { 00563 static TimeMarker *marker; 00564 static short initialised = 0; 00565 int diff; 00566 00567 /* In order for this mirror function to work without 00568 * any extra arguments being added, we use the case 00569 * of bezt==NULL to denote that we should find the 00570 * marker to mirror over. The static pointer is safe 00571 * to use this way, as it will be set to null after 00572 * each cycle in which this is called. 00573 */ 00574 00575 if (gpf) { 00576 /* mirroring time */ 00577 if ((gpf->flag & GP_FRAME_SELECT) && (marker)) { 00578 diff= (marker->frame - gpf->framenum); 00579 gpf->framenum= (marker->frame + diff); 00580 } 00581 } 00582 else { 00583 /* initialisation time */ 00584 if (initialised) { 00585 /* reset everything for safety */ 00586 marker = NULL; 00587 initialised = 0; 00588 } 00589 else { 00590 /* try to find a marker */ 00591 marker= ED_markers_get_first_selected(&scene->markers); 00592 if(marker) { 00593 initialised= 1; 00594 } 00595 } 00596 } 00597 00598 return 0; 00599 } 00600 00601 00602 /* mirror selected gp-frames on... */ 00603 void mirror_gplayer_frames (bGPDlayer *gpl, Scene *scene, short mode) 00604 { 00605 switch (mode) { 00606 case 1: /* mirror over current frame */ 00607 gplayer_frames_looper(gpl, scene, mirror_gpf_cframe); 00608 break; 00609 case 2: /* mirror over frame 0 */ 00610 gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); 00611 break; 00612 case 3: /* mirror over value 0 */ 00613 gplayer_frames_looper(gpl, scene, mirror_gpf_xaxis); 00614 break; 00615 case 4: /* mirror over marker */ 00616 mirror_gpf_marker(NULL, NULL); 00617 gplayer_frames_looper(gpl, scene, mirror_gpf_marker); 00618 mirror_gpf_marker(NULL, NULL); 00619 break; 00620 default: /* just in case */ 00621 gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); 00622 break; 00623 } 00624 } 00625 00626 /* ***************************************** */ 00627 #endif // XXX disabled until Grease Pencil code stabilises again...