Revision: 39960
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39960
Author:   nazgul
Date:     2011-09-06 07:59:18 +0000 (Tue, 06 Sep 2011)
Log Message:
-----------
Grease pencil: non-blocking sketch sessions

- Implement own undo stack for grease pencil, so now there'll be no keymaps 
conflicts.
- Supported redo's during sketch session.
- Get rid of flag stored in Globals -- use undo stack to check if grease pencil 
session is active.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_global.h
    trunk/blender/source/blender/editors/gpencil/CMakeLists.txt
    trunk/blender/source/blender/editors/gpencil/drawgpencil.c
    trunk/blender/source/blender/editors/gpencil/gpencil_intern.h
    trunk/blender/source/blender/editors/gpencil/gpencil_paint.c
    trunk/blender/source/blender/editors/include/ED_gpencil.h
    trunk/blender/source/blender/editors/util/undo.c

Added Paths:
-----------
    trunk/blender/source/blender/editors/gpencil/gpencil_undo.c

Modified: trunk/blender/source/blender/blenkernel/BKE_global.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_global.h        2011-09-06 
07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/blenkernel/BKE_global.h        2011-09-06 
07:59:18 UTC (rev 39960)
@@ -111,7 +111,7 @@
 #define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the 
userprefs */
 
 /* #define G_NOFROZEN  (1 << 17) also removed */
-#define G_GREASEPENCIL         (1 << 17)
+/* #define G_GREASEPENCIL      (1 << 17)   also removed */
 
 /* #define G_AUTOMATKEYS       (1 << 30)   also removed */
 

Modified: trunk/blender/source/blender/editors/gpencil/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/editors/gpencil/CMakeLists.txt 2011-09-06 
07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/CMakeLists.txt 2011-09-06 
07:59:18 UTC (rev 39960)
@@ -42,6 +42,7 @@
        gpencil_edit.c
        gpencil_ops.c
        gpencil_paint.c
+       gpencil_undo.c
 
        gpencil_intern.h
 )

Modified: trunk/blender/source/blender/editors/gpencil/drawgpencil.c
===================================================================
--- trunk/blender/source/blender/editors/gpencil/drawgpencil.c  2011-09-06 
07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/drawgpencil.c  2011-09-06 
07:59:18 UTC (rev 39960)
@@ -644,7 +644,7 @@
                /* Check if may need to draw the active stroke cache, only if 
this layer is the active layer
                 * that is being edited. (Stroke buffer is currently stored in 
gp-data)
                 */
-               if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) &&
+               if (ED_gpencil_session_active() && (gpl->flag & 
GP_LAYER_ACTIVE) &&
                        (gpf->flag & GP_FRAME_PAINT)) 
                {
                        /* Buffer stroke needs to be drawn with a different 
linestyle to help differentiate them from normal strokes. */

Modified: trunk/blender/source/blender/editors/gpencil/gpencil_intern.h
===================================================================
--- trunk/blender/source/blender/editors/gpencil/gpencil_intern.h       
2011-09-06 07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/gpencil_intern.h       
2011-09-06 07:59:18 UTC (rev 39960)
@@ -37,6 +37,7 @@
 /* ***************************************************** */
 /* Operator Defines */
 
+struct bGPdata;
 struct wmOperatorType;
 
 /* drawing ---------- */
@@ -61,7 +62,12 @@
 
 void GPENCIL_OT_convert(struct wmOperatorType *ot);
 
+/* undo stack ---------- */
 
+void gpencil_undo_init(struct bGPdata *gpd);
+void gpencil_undo_push(struct bGPdata *gpd);
+void gpencil_undo_finish(void);
+
 /******************************************************* */
 /* FILTERED ACTION DATA - TYPES  ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */
 

Modified: trunk/blender/source/blender/editors/gpencil/gpencil_paint.c
===================================================================
--- trunk/blender/source/blender/editors/gpencil/gpencil_paint.c        
2011-09-06 07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/gpencil_paint.c        
2011-09-06 07:59:18 UTC (rev 39960)
@@ -152,7 +152,7 @@
                /* check if current context can support GPencil data */
                if (gpencil_data_get_pointers(C, NULL) != NULL) {
                        /* check if Grease Pencil isn't already running */
-                       if ((G.f & G_GREASEPENCIL) == 0)
+                       if (ED_gpencil_session_active() == 0)
                                return 1;
                        else
                                CTX_wm_operator_poll_msg_set(C, "Grease Pencil 
operator is already active");
@@ -893,8 +893,10 @@
        /* clear memory of buffer (or allocate it if starting a new session) */
        if (gpd->sbuffer)
                memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX);
-       else
+       else {
+               //printf("\t\tGP - allocate sbuffer\n");
                gpd->sbuffer= 
MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
+       }
        
        /* reset indices */
        gpd->sbuffer_size = 0;
@@ -1051,8 +1053,11 @@
                p->gpd= *gpd_ptr;
        }
        
-       /* set edit flags - so that buffer will get drawn */
-       G.f |= G_GREASEPENCIL;
+       if(ED_gpencil_session_active()==0) {
+               /* initialize undo stack,
+                  also, existing undo stack would make buffer drawn */
+               gpencil_undo_init(p->gpd);
+       }
        
        /* clear out buffer (stored in gp-data), in case something contaminated 
it */
        gp_session_validatebuffer(p);
@@ -1078,6 +1083,7 @@
        
        /* free stroke buffer */
        if (gpd->sbuffer) {
+               //printf("\t\tGP - free sbuffer\n");
                MEM_freeN(gpd->sbuffer);
                gpd->sbuffer= NULL;
        }
@@ -1247,7 +1253,8 @@
 static void gp_paint_cleanup (tGPsdata *p)
 {
        /* finish off a stroke */
-       gp_paint_strokeend(p);
+       if(p->gpd)
+               gp_paint_strokeend(p);
        
        /* "unlock" frame */
        if (p->gpf)
@@ -1260,8 +1267,8 @@
 {
        tGPsdata *p= op->customdata;
        
-       /* clear edit flags */
-       G.f &= ~G_GREASEPENCIL;
+       /* clear undo stack */
+       gpencil_undo_finish();
        
        /* restore cursor to indicate end of drawing */
        WM_cursor_restore(CTX_wm_window(C));
@@ -1592,6 +1599,7 @@
                //printf("\tGP - hotkey invoked... waiting for click-drag\n");
        }
        
+       WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL, NULL);
        /* add a modal handler for this operator, so that we can then draw 
continuous strokes */
        WM_event_add_modal_handler(C, op);
        return OPERATOR_RUNNING_MODAL;
@@ -1609,16 +1617,60 @@
        return 0;
 }
 
+static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
+{
+       tGPsdata *p= op->customdata;
+
+       /* we must check that we're still within the area that we're set up to 
work from
+        * otherwise we could crash (see bug #20586)
+        */
+       if (CTX_wm_area(C) != p->sa) {
+               printf("\t\t\tGP - wrong area execution abort! \n");
+               p->status= GP_STATUS_ERROR;
+       }
+
+       /* free pointer used by previous stroke */
+       if(p)
+               MEM_freeN(p);
+
+       //printf("\t\tGP - start stroke \n");
+
+       /* we may need to set up paint env again if we're resuming */
+       // XXX: watch it with the paintmode! in future, it'd be nice to allow 
changing paint-mode when in sketching-sessions
+       // XXX: with tablet events, we may event want to check for eraser here, 
for nicer tablet support
+
+       gpencil_draw_init(C, op);
+
+       p= op->customdata;
+
+       if(p->status != GP_STATUS_ERROR)
+               p->status= GP_STATUS_PAINTING;
+
+       return op->customdata;
+}
+
+static void gpencil_stroke_end(wmOperator *op)
+{
+       tGPsdata *p= op->customdata;
+
+       gp_paint_cleanup(p);
+
+       gpencil_undo_push(p->gpd);
+
+       gp_session_cleanup(p);
+
+       p->status= GP_STATUS_IDLING;
+
+       p->gpd= NULL;
+       p->gpl= NULL;
+       p->gpf= NULL;
+}
+
 /* events handling during interactive drawing part of operator */
 static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
 {
        tGPsdata *p= op->customdata;
-       //int estate = OPERATOR_PASS_THROUGH; /* default exit state - not 
handled, so let others have a share of the pie */
-       /* currently, grease pencil conflicts with such operators as undo and 
set object mode
-          which makes behavior of operator totally unpredictable and crash for 
some cases.
-          the only way to solve this proper is to ger rid of pointers to data 
which can
-          chage stored in operator custom data (sergey) */
-       int estate = OPERATOR_RUNNING_MODAL;
+       int estate = OPERATOR_PASS_THROUGH; /* default exit state - not 
handled, so let others have a share of the pie */
        
        // if (event->type == NDOF_MOTION)
        //      return OPERATOR_PASS_THROUGH;
@@ -1652,11 +1704,13 @@
                        if (GPENCIL_SKETCH_SESSIONS_ON(p->scene)) {
                                /* end stroke only, and then wait to resume 
painting soon */
                                //printf("\t\tGP - end stroke only\n");
-                               gp_paint_cleanup(p);
-                               p->status= GP_STATUS_IDLING;
+                               gpencil_stroke_end(op);
                                
                                /* we've just entered idling state, so this 
event was processed (but no others yet) */
                                estate = OPERATOR_RUNNING_MODAL;
+
+                               /* stroke could be smoothed, send notifier to 
refresh screen */
+                               ED_region_tag_redraw(p->ar);
                        }
                        else {
                                //printf("\t\tGP - end of stroke + op\n");
@@ -1664,35 +1718,19 @@
                                estate = OPERATOR_FINISHED;
                        }
                }
-               else {
+               else if (event->val == KM_PRESS) {
                        /* not painting, so start stroke (this should be 
mouse-button down) */
                        
-                       /* we must check that we're still within the area that 
we're set up to work from
-                        * otherwise we could crash (see bug #20586)
-                        */
-                       if (CTX_wm_area(C) != p->sa) {
-                               //printf("\t\t\tGP - wrong area execution 
abort! \n");
-                               p->status= GP_STATUS_ERROR;
+                       p= gpencil_stroke_begin(C, op);
+
+                       if (p->status == GP_STATUS_ERROR) {
                                estate = OPERATOR_CANCELLED;
                        }
-                       else {
-                               //printf("\t\tGP - start stroke \n");
-                               p->status= GP_STATUS_PAINTING;
-                               
-                               /* we may need to set up paint env again if 
we're resuming */
-                               // XXX: watch it with the paintmode! in future, 
it'd be nice to allow changing paint-mode when in sketching-sessions
-                               // XXX: with tablet events, we may event want 
to check for eraser here, for nicer tablet support
-                               gp_paint_initstroke(p, p->paintmode);
-                               
-                               if (p->status == GP_STATUS_ERROR) {
-                                       estate = OPERATOR_CANCELLED;
-                               }
-                       }
+               } else {
+                       p->status = GP_STATUS_IDLING;
                }
        }
        
-       
-       
        /* handle mode-specific events */
        if (p->status == GP_STATUS_PAINTING) {
                /* handle painting mouse-movements? */
@@ -1704,7 +1742,7 @@
                        
                        /* finish painting operation if anything went wrong 
just now */
                        if (p->status == GP_STATUS_ERROR) {
-                               //printf("\t\t\t\tGP - add error done! \n");
+                               printf("\t\t\t\tGP - add error done! \n");
                                estate = OPERATOR_CANCELLED;
                        }
                        else {
@@ -1721,28 +1759,6 @@
                        estate = OPERATOR_RUNNING_MODAL;
                }
        }
-       else if (p->status == GP_STATUS_IDLING) {
-               /* standard undo/redo shouldn't be allowed to execute or else 
it causes crashes, so catch it here */
-               // FIXME: this is a hardcoded hotkey that can't be changed
-               // TODO: catch redo as well, but how?
-               if (event->type == ZKEY && event->val == KM_RELEASE) {
-                       /* oskey = cmd key on macs as they seem to use cmd-z 
for undo as well? */
-                       if ((event->ctrl) || (event->oskey)) {
-                               /* just delete last stroke, which will look 
like undo to the end user */
-                               //printf("caught attempted undo event... 
deleting last stroke \n");
-                               gpencil_frame_delete_laststroke(p->gpl, p->gpf);
-                               /* undoing the last line can free p->gpf
-                                * note, could do this in a bit more of an 
elegant way then a search but it at least prevents a crash */
-                               if(BLI_findindex(&p->gpl->frames, p->gpf) == 
-1) {
-                                       p->gpf= NULL;
-                               }
-
-                               /* event handled, so force refresh */

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to