Grease Pencil - Available in Image Editor:

Grease Pencil is now available in the image editor. It is important to note that the strokes drawn WILL NOT become part of the image visible at the time.

Unfortunately, 'fancy' stroke drawing cannot be enabled for use with the 'Stick to View' setting here, as the scaling is wrong.
This commit is contained in:
Joshua Leung 2008-09-05 07:12:04 +00:00
parent 18fe6c27ff
commit e8621cf05e
10 changed files with 158 additions and 36 deletions

@ -4173,6 +4173,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sima->cumap= newdataadr(fd, sima->cumap);
if(sima->cumap)
direct_link_curvemapping(fd, sima->cumap);
sima->gpd= newdataadr(fd, sima->gpd);
if (sima->gpd)
link_gpencil(fd, sima->gpd);
sima->iuser.ok= 1;
}
else if(sl->spacetype==SPACE_NODE) {

@ -1699,6 +1699,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "SpaceImage", 1, sl);
if(sima->cumap)
write_curvemapping(wd, sima->cumap);
if(sima->gpd)
write_gpencil(wd, sima->gpd);
}
else if(sl->spacetype==SPACE_IMASEL) {
writestruct(wd, DATA, "SpaceImaSel", 1, sl);

@ -65,6 +65,7 @@ struct SpaceOops;
#define IMAGE_HANDLER_PREVIEW 33
#define IMAGE_HANDLER_GAME_PROPERTIES 34
#define IMAGE_HANDLER_VIEW_PROPERTIES 35
#define IMAGE_HANDLER_GREASEPENCIL 36
/*#define IMAGE_HANDLER_TRANSFORM_PROPERTIES 36*/
/* action handler codes */

@ -538,6 +538,7 @@ typedef struct SpaceImaSel {
#define SI_DRAW_TILE 1<<19
#define SI_SMOOTH_UV 1<<20
#define SI_DRAW_STRETCH 1<<21
#define SI_DISPGP 1<<22
/* SpaceIpo->flag */
#define SIPO_LOCK_VIEW 1<<0

@ -394,7 +394,7 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick
/* ----- Existing Strokes Drawing (3D and Point) ------ */
/* draw a given stroke - just a single dot (only one point) */
static void gp_draw_stroke_point (bGPDspoint *points, short thickness, short sflag, int winx, int winy)
static void gp_draw_stroke_point (bGPDspoint *points, short thickness, short sflag, int offsx, int offsy, int winx, int winy)
{
/* draw point */
if (sflag & GP_STROKE_3DSPACE) {
@ -410,6 +410,10 @@ static void gp_draw_stroke_point (bGPDspoint *points, short thickness, short sfl
co[0]= points->x;
co[1]= points->y;
}
else if (sflag & GP_STROKE_2DIMAGE) {
co[0]= points->x;
co[1]= points->y;
}
else {
co[0]= (points->x / 1000 * winx);
co[1]= (points->y / 1000 * winy);
@ -473,10 +477,11 @@ static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thicknes
/* ----- Fancy 2D-Stroke Drawing ------ */
/* draw a given stroke in 2d */
static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag,
short debug, int offsx, int offsy, int winx, int winy)
{
/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better */
if (thickness < GP_DRAWTHICKNESS_SPECIAL) {
if ((thickness < GP_DRAWTHICKNESS_SPECIAL) || (dflag & GP_DRAWDATA_ONLYI2D)) {
bGPDspoint *pt;
int i;
@ -485,6 +490,12 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
if (sflag & GP_STROKE_2DSPACE) {
glVertex2f(pt->x, pt->y);
}
else if (sflag & GP_STROKE_2DIMAGE) {
const float x= pt->x;
const float y= pt->y;
glVertex2f(x, y);
}
else {
const float x= (pt->x / 1000 * winx);
const float y= (pt->y / 1000 * winy);
@ -514,6 +525,10 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
s0[0]= pt1->x; s0[1]= pt1->y;
s1[0]= pt2->x; s1[1]= pt2->y;
}
else if (sflag & GP_STROKE_2DIMAGE) {
s0[0]= pt1->x; s0[1]= pt1->y;
s1[0]= pt2->x; s1[1]= pt2->y;
}
else {
s0[0]= (pt1->x / 1000 * winx);
s0[1]= (pt1->y / 1000 * winy);
@ -656,6 +671,13 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
if (sflag & GP_STROKE_2DSPACE) {
glVertex2f(pt->x, pt->y);
}
else if (sflag & GP_STROKE_2DIMAGE) {
// fixme
const float x= pt->x;
const float y= pt->y;
glVertex2f(x, y);
}
else {
const float x= (pt->x / 1000 * winx);
const float y= (pt->y / 1000 * winy);
@ -670,8 +692,8 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
/* ----- General Drawing ------ */
/* draw a set of strokes */
static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, short debug,
short lthick, float color[4])
static void gp_draw_strokes (bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag,
short debug, short lthick, float color[4])
{
bGPDstroke *gps;
@ -697,16 +719,16 @@ static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, shor
/* check which stroke-drawer to use */
if (gps->totpoints == 1)
gp_draw_stroke_point(gps->points, lthick, gps->flag, winx, winy);
gp_draw_stroke_point(gps->points, lthick, gps->flag, offsx, offsy, winx, winy);
else if (dflag & GP_DRAWDATA_ONLY3D)
gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
else if (gps->totpoints > 1)
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy);
}
}
/* draw grease-pencil datablock */
static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
static void gp_draw_data (bGPdata *gpd, int offsx, int offsy, int winx, int winy, int dflag)
{
bGPDlayer *gpl, *actlay=NULL;
@ -758,7 +780,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
tcolor[3] = color[3] - (i/gpl->gstep);
gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@ -770,7 +792,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
tcolor[3] = color[3] - (i/gpl->gstep);
gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@ -783,12 +805,12 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* draw the strokes for the ghost frames (at half of the alpha set by user) */
if (gpf->prev) {
tcolor[3] = (color[3] / 7);
gp_draw_strokes(gpf->prev, winx, winy, dflag, debug, lthick, tcolor);
gp_draw_strokes(gpf->prev, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
}
if (gpf->next) {
tcolor[3] = (color[3] / 4);
gp_draw_strokes(gpf->next, winx, winy, dflag, debug, lthick, tcolor);
gp_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
}
/* restore alpha */
@ -798,7 +820,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* draw the strokes already in active frame */
tcolor[3]= color[3];
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
gp_draw_strokes(gpf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
/* 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)
@ -866,6 +888,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
void draw_gpencil_2dimage (ScrArea *sa, ImBuf *ibuf)
{
bGPdata *gpd;
int offsx, offsy, sizex, sizey;
int dflag = 0;
/* check that we have grease-pencil stuff to draw */
@ -873,9 +896,34 @@ void draw_gpencil_2dimage (ScrArea *sa, ImBuf *ibuf)
gpd= gpencil_data_getactive(sa);
if (gpd == NULL) return;
/* calculate rect */
switch (sa->spacetype) {
case SPACE_IMAGE: /* image */
{
SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
// fixme... are these settings still needed?
offsx= 0;
offsy= 0;
sizex= sa->winx;
sizey= sa->winy;
myortho2(sima->v2d.cur.xmin, sima->v2d.cur.xmax, sima->v2d.cur.ymin, sima->v2d.cur.ymax);
}
break;
default: /* for spacetype not yet handled */
offsx= 0;
offsy= 0;
sizex= sa->winx;
sizey= sa->winy;
break;
}
/* draw it! */
dflag = (GP_DRAWDATA_ONLYI2D|GP_DRAWDATA_NOSTATUS);
gp_draw_data(gpd, sa->winx, sa->winy, dflag);
gp_draw_data(gpd, offsx, offsy, sizex, sizey, dflag);
}
/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
@ -893,7 +941,7 @@ void draw_gpencil_2dview (ScrArea *sa, short onlyv2d)
/* draw it! */
if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D|GP_DRAWDATA_NOSTATUS);
gp_draw_data(gpd, sa->winx, sa->winy, dflag);
gp_draw_data(gpd, 0, 0, sa->winx, sa->winy, dflag);
}
/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
@ -910,7 +958,7 @@ void draw_gpencil_3dview (ScrArea *sa, short only3d)
/* draw it! */
if (only3d) dflag |= (GP_DRAWDATA_ONLY3D|GP_DRAWDATA_NOSTATUS);
gp_draw_data(gpd, sa->winx, sa->winy, dflag);
gp_draw_data(gpd, 0, 0, sa->winx, sa->winy, dflag);
}
/* draw grease-pencil sketches to opengl render window assuming that matrices are already set correctly */
@ -924,7 +972,7 @@ void draw_gpencil_oglrender (View3D *v3d, int winx, int winy)
if (gpd == NULL) return;
/* pass 1: draw 3d-strokes ------------ > */
gp_draw_data(gpd, winx, winy, (GP_DRAWDATA_NOSTATUS|GP_DRAWDATA_ONLY3D));
gp_draw_data(gpd, 0, 0, winx, winy, (GP_DRAWDATA_NOSTATUS|GP_DRAWDATA_ONLY3D));
/* pass 2: draw 2d-strokes ------------ > */
/* adjust view matrices */
@ -932,7 +980,7 @@ void draw_gpencil_oglrender (View3D *v3d, int winx, int winy)
glLoadIdentity();
/* draw it! */
gp_draw_data(gpd, winx, winy, GP_DRAWDATA_NOSTATUS);
gp_draw_data(gpd, 0, 0, winx, winy, GP_DRAWDATA_NOSTATUS);
}
/* ************************************************** */

@ -52,6 +52,7 @@
#include "DNA_camera_types.h"
#include "DNA_color_types.h"
#include "DNA_image_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
@ -79,6 +80,7 @@
#include "BDR_editface.h"
#include "BDR_drawobject.h"
#include "BDR_drawmesh.h"
#include "BDR_gpencil.h"
#include "BDR_imagepaint.h"
#include "BIF_cursors.h"
@ -86,6 +88,7 @@
#include "BIF_graphics.h"
#include "BIF_mywindow.h"
#include "BIF_drawimage.h"
#include "BIF_drawgpencil.h"
#include "BIF_resources.h"
#include "BIF_interface.h"
#include "BIF_interface_icons.h"
@ -1778,6 +1781,45 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVI
}
static void image_panel_gpencil(short cntrl) // IMAGE_HANDLER_GREASEPENCIL
{
uiBlock *block;
SpaceImage *sima;
sima= curarea->spacedata.first;
block= uiNewBlock(&curarea->uiblocks, "image_panel_gpencil", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(IMAGE_HANDLER_GREASEPENCIL); // for close and esc
if (uiNewPanel(curarea, block, "Grease Pencil", "SpaceImage", 100, 30, 318, 204)==0) return;
/* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
if (sima->flag & SI_DISPGP) {
if (sima->gpd == NULL)
gpencil_data_setactive(curarea, gpencil_data_addnew());
}
if (sima->flag & SI_DISPGP) {
bGPdata *gpd= sima->gpd;
short newheight;
/* this is a variable height panel, newpanel doesnt force new size on existing panels */
/* so first we make it default height */
uiNewPanelHeight(block, 204);
/* draw button for showing gpencil settings and drawings */
uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor (draw using Shift-LMB)");
/* extend the panel if the contents won't fit */
newheight= draw_gpencil_panel(block, gpd, curarea);
uiNewPanelHeight(block, newheight);
}
else {
uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor");
uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
}
}
static void image_blockhandlers(ScrArea *sa)
{
SpaceImage *sima= sa->spacedata.first;
@ -1788,7 +1830,6 @@ static void image_blockhandlers(ScrArea *sa)
for(a=0; a<SPACE_MAXHANDLER; a+=2) {
switch(sima->blockhandler[a]) {
case IMAGE_HANDLER_PROPERTIES:
image_panel_properties(sima->blockhandler[a+1]);
break;
@ -1807,6 +1848,9 @@ static void image_blockhandlers(ScrArea *sa)
case IMAGE_HANDLER_PREVIEW:
image_panel_preview(sa, sima->blockhandler[a+1]);
break;
case IMAGE_HANDLER_GREASEPENCIL:
image_panel_gpencil(sima->blockhandler[a+1]);
break;
}
/* clear action value for event */
sima->blockhandler[a+1]= 0;
@ -2340,9 +2384,17 @@ void drawimagespace(ScrArea *sa, void *spacedata)
draw_image_transform(ibuf, xuser_asp, yuser_asp);
/* draw grease-pencil ('image' strokes) */
if (sima->flag & SI_DISPGP)
draw_gpencil_2dimage(sa, ibuf);
mywinset(sa->win); /* restore scissor after gla call... */
myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
/* draw grease-pencil (screen strokes) */
if (sima->flag & SI_DISPGP)
draw_gpencil_2dview(sa, 0);
if(G.rendering==0) {
draw_image_view_tool();
}

@ -62,6 +62,7 @@
#include "BKE_blender.h"
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_image.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@ -1137,7 +1138,7 @@ static void gp_session_initpaint (tGPsdata *p)
/* set the current area */
p->sa= curarea;
p->v2d= &sima->v2d;
//p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
}
break;
/* unsupported views */
@ -1249,21 +1250,14 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
else if ( (gpd->sbuffer_sflag & GP_STROKE_2DIMAGE) &&
(p->v2d) && (p->ibuf) )
{
ImBuf *ibuf= p->ibuf;
float x, y;
/* convert to 'canvas' coordinates, then adjust for view */
/* convert to 'canvas' coordinates (not need to adjust to canvas) */
areamouseco_to_ipoco(p->v2d, mval, &x, &y);
if (ibuf) {
out[0]= x*ibuf->x;
out[1]= y*ibuf->y;
}
else {
out[0]= x;
out[1]= y;
}
}
/* 2d - relative to screen (viewport area) */
else {
@ -1637,6 +1631,8 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode)
break;
case SPACE_IMAGE:
{
/* check if any ibuf available */
if (p->ibuf)
p->gpd->sbuffer_sflag |= GP_STROKE_2DIMAGE;
}
break;

@ -477,6 +477,9 @@ static void do_image_viewmenu(void *arg, int event)
G.sima->flag ^= SI_LOCAL_UV;
allqueue(REDRAWIMAGE, 0);
break;
case 15: /* Grease Pencil... */
add_blockhandler(curarea, IMAGE_HANDLER_GREASEPENCIL, UI_PNL_UNSTOW);
break;
}
allqueue(REDRAWVIEW3D, 0);
}
@ -499,6 +502,8 @@ static uiBlock *image_viewmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Curves Tool...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Composite Preview...|Shift P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Grease Pencil...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
if(G.sima->flag & SI_LOCAL_UV) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "UV Local View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "UV Local View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
if(!(G.sima->flag & SI_LOCAL_UV)) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "UV Global View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");

@ -5337,6 +5337,14 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(uiDoBlocks(&sa->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* grease-pencil drawing before draw-tool */
if (event == LEFTMOUSE) {
if (gpencil_do_paint(sa, L_MOUSE)) return;
}
else if (event == RIGHTMOUSE) {
if (gpencil_do_paint(sa, R_MOUSE)) return;
}
if (sima->image && (sima->flag & SI_DRAWTOOL)) {
switch(event) {
case CKEY:
@ -6340,6 +6348,8 @@ void freespacelist(ScrArea *sa)
SpaceImage *sima= (SpaceImage *)sl;
if(sima->cumap)
curvemapping_free(sima->cumap);
if(sima->gpd)
free_gpencil_data(sima->gpd);
}
else if(sl->spacetype==SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl;
@ -6407,6 +6417,10 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
SpaceSeq *sseq= (SpaceSeq *)sl;
sseq->gpd= gpencil_data_duplicate(sseq->gpd);
}
else if(sl->spacetype==SPACE_IMAGE) {
SpaceImage *sima= (SpaceImage *)sl;
sima->gpd= gpencil_data_duplicate(sima->gpd);
}
sl= sl->next;
}