2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-01-14 16:13:50 +00:00
|
|
|
* ***** 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-01-14 16:13:50 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2008, Blender Foundation
|
|
|
|
* This is a new part of Blender
|
|
|
|
*
|
|
|
|
* Contributor(s): Joshua Leung
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
2011-02-27 20:29:51 +00:00
|
|
|
|
|
|
|
/** \file blender/editors/gpencil/drawgpencil.c
|
|
|
|
* \ingroup edgpencil
|
|
|
|
*/
|
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
|
|
|
|
2010-08-31 11:31:21 +00:00
|
|
|
#include "BLO_sys_types.h"
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2012-06-11 00:21:50 +00:00
|
|
|
#include "BLI_math.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
#include "DNA_gpencil_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
#include "DNA_space_types.h"
|
2010-08-25 08:31:52 +00:00
|
|
|
#include "DNA_view3d_types.h"
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
#include "BKE_context.h"
|
|
|
|
#include "BKE_global.h"
|
2.5
Patch from Joshua, converting Grease Pencil to 2.5.
All GP data now is an ID block, allowing re-use, link and append.
For better contextual control within 2.5, these GP ID's will get
linked to actual data, like NodeTrees, Scenes, Images or Objects.
That will ensure Undo works, and opens up exciting new use cases
as well. :)
Patch note: on reading files, GPencils linked from editors will
get moved to the main library, using standard naming (indicating
where it was used), and with "Fake User" set. That way the user
can manually relink the pencils where appropriate.
We can check on just linking GP to some default, like 3d window
pencils to Scene? Nice to experiment with.
Notes for Joshua:
- for reading old GPencil, it has to use old code as well, meaning
to tread data as "indirect data, within another ID".
- Saving ID data means the chunk in file BHead needs the ID_GD code,
and not "DATA", which indicates 'indirect data'. That's the file
format spec.
- I've added do_versions_gpencil_2_50(), feel free to further tweak
things here, like linking things to scene or so.
- Formerly GPencil saved 2.50 files won't convert gpencil
2009-04-20 10:13:55 +00:00
|
|
|
#include "BKE_gpencil.h"
|
2011-01-07 19:18:31 +00:00
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
#include "WM_api.h"
|
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
#include "BIF_glutil.h"
|
|
|
|
|
|
|
|
#include "ED_gpencil.h"
|
|
|
|
#include "ED_sequencer.h"
|
2010-08-25 08:31:52 +00:00
|
|
|
#include "ED_view3d.h"
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
#include "gpencil_intern.h"
|
|
|
|
|
|
|
|
/* ************************************************** */
|
|
|
|
/* GREASE PENCIL DRAWING */
|
|
|
|
|
|
|
|
/* ----- General Defines ------ */
|
|
|
|
|
|
|
|
/* flags for sflag */
|
2011-04-14 04:22:52 +00:00
|
|
|
typedef enum eDrawStrokeFlags {
|
2012-05-08 18:29:02 +00:00
|
|
|
GP_DRAWDATA_NOSTATUS = (1 << 0), /* don't draw status info */
|
|
|
|
GP_DRAWDATA_ONLY3D = (1 << 1), /* only draw 3d-strokes */
|
|
|
|
GP_DRAWDATA_ONLYV2D = (1 << 2), /* only draw 'canvas' strokes */
|
|
|
|
GP_DRAWDATA_ONLYI2D = (1 << 3), /* only draw 'image' strokes */
|
|
|
|
GP_DRAWDATA_IEDITHACK = (1 << 4), /* special hack for drawing strokes in Image Editor (weird coordinates) */
|
|
|
|
GP_DRAWDATA_NO_XRAY = (1 << 5), /* don't draw xray in 3D view (which is default) */
|
2011-04-14 04:22:52 +00:00
|
|
|
} eDrawStrokeFlags;
|
|
|
|
|
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* thickness above which we should use special drawing */
|
2012-05-08 18:29:02 +00:00
|
|
|
#define GP_DRAWTHICKNESS_SPECIAL 3
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* ----- Tool Buffer Drawing ------ */
|
|
|
|
|
|
|
|
/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
|
2012-05-08 18:29:02 +00:00
|
|
|
static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickness, short dflag, short sflag)
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
tGPspoint *pt;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* error checking */
|
|
|
|
if ((points == NULL) || (totpoints <= 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* check if buffer can be drawn */
|
2012-05-08 18:29:02 +00:00
|
|
|
if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
|
2009-01-14 16:13:50 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* if drawing a single point, draw it larger */
|
|
|
|
if (totpoints == 1) {
|
|
|
|
/* draw point */
|
|
|
|
glBegin(GL_POINTS);
|
2012-05-08 18:29:02 +00:00
|
|
|
glVertex2iv(&points->x);
|
2009-01-14 16:13:50 +00:00
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
else if (sflag & GP_STROKE_ERASER) {
|
|
|
|
/* don't draw stroke at all! */
|
|
|
|
}
|
|
|
|
else {
|
2011-10-12 03:46:38 +00:00
|
|
|
float oldpressure = points[0].pressure;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* draw stroke curve */
|
2012-03-31 00:59:17 +00:00
|
|
|
if (G.debug & G_DEBUG) setlinestyle(2);
|
2011-10-12 03:46:38 +00:00
|
|
|
|
|
|
|
glLineWidth(oldpressure * thickness);
|
2009-01-14 16:13:50 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
2011-10-12 03:46:38 +00:00
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
|
2009-08-30 06:10:38 +00:00
|
|
|
/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
|
|
|
|
* and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
|
|
|
|
*/
|
2011-03-27 14:59:55 +00:00
|
|
|
if (fabsf(pt->pressure - oldpressure) > 0.2f) {
|
2009-01-14 16:13:50 +00:00
|
|
|
glEnd();
|
|
|
|
glLineWidth(pt->pressure * thickness);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
|
2009-08-30 06:10:38 +00:00
|
|
|
/* need to roll-back one point to ensure that there are no gaps in the stroke */
|
2011-11-26 05:10:53 +00:00
|
|
|
if (i != 0) glVertex2iv(&(pt - 1)->x);
|
|
|
|
|
2009-08-30 06:10:38 +00:00
|
|
|
/* now the point we want... */
|
2011-11-26 05:10:53 +00:00
|
|
|
glVertex2iv(&pt->x);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
oldpressure = pt->pressure;
|
|
|
|
}
|
|
|
|
else
|
2011-11-26 05:10:53 +00:00
|
|
|
glVertex2iv(&pt->x);
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
glEnd();
|
2011-10-12 03:46:38 +00:00
|
|
|
|
2011-10-12 17:06:15 +00:00
|
|
|
/* reset for predictable OpenGL context */
|
2011-10-12 03:46:38 +00:00
|
|
|
glLineWidth(1.0f);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
2012-03-31 00:59:17 +00:00
|
|
|
if (G.debug & G_DEBUG) setlinestyle(0);
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----- Existing Strokes Drawing (3D and Point) ------ */
|
|
|
|
|
|
|
|
/* draw a given stroke - just a single dot (only one point) */
|
2012-05-08 18:29:02 +00:00
|
|
|
static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, int offsx, int offsy, int winx, int winy)
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
/* draw point */
|
|
|
|
if (sflag & GP_STROKE_3DSPACE) {
|
|
|
|
glBegin(GL_POINTS);
|
2012-05-08 18:29:02 +00:00
|
|
|
glVertex3fv(&points->x);
|
2009-01-14 16:13:50 +00:00
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float co[2];
|
|
|
|
|
|
|
|
/* get coordinates of point */
|
|
|
|
if (sflag & GP_STROKE_2DSPACE) {
|
2012-05-08 18:29:02 +00:00
|
|
|
co[0] = points->x;
|
|
|
|
co[1] = points->y;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
else if (sflag & GP_STROKE_2DIMAGE) {
|
2012-05-08 18:29:02 +00:00
|
|
|
co[0] = (points->x * winx) + offsx;
|
|
|
|
co[1] = (points->y * winy) + offsy;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-05-08 18:29:02 +00:00
|
|
|
co[0] = (points->x / 100 * winx) + offsx;
|
|
|
|
co[1] = (points->y / 100 * winy) + offsy;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple dot looks ok
|
2012-05-08 18:29:02 +00:00
|
|
|
* - also mandatory in if Image Editor 'image-based' dot
|
2009-01-14 16:13:50 +00:00
|
|
|
*/
|
|
|
|
if ( (thickness < GP_DRAWTHICKNESS_SPECIAL) ||
|
2012-05-08 18:29:02 +00:00
|
|
|
((dflag & GP_DRAWDATA_IEDITHACK) && (sflag & GP_STROKE_2DSPACE)) )
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
glBegin(GL_POINTS);
|
2012-05-08 18:29:02 +00:00
|
|
|
glVertex2fv(co);
|
2009-01-14 16:13:50 +00:00
|
|
|
glEnd();
|
|
|
|
}
|
2012-03-06 18:40:15 +00:00
|
|
|
else {
|
2009-01-14 16:13:50 +00:00
|
|
|
/* draw filled circle as is done in circf (but without the matrix push/pops which screwed things up) */
|
|
|
|
GLUquadricObj *qobj = gluNewQuadric();
|
|
|
|
|
|
|
|
gluQuadricDrawStyle(qobj, GLU_FILL);
|
|
|
|
|
|
|
|
/* need to translate drawing position, but must reset after too! */
|
2012-04-11 08:15:13 +00:00
|
|
|
glTranslatef(co[0], co[1], 0.0);
|
2009-01-14 16:13:50 +00:00
|
|
|
gluDisk(qobj, 0.0, thickness, 32, 1);
|
2012-04-11 08:15:13 +00:00
|
|
|
glTranslatef(-co[0], -co[1], 0.0);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
gluDeleteQuadric(qobj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
|
2012-05-08 18:29:02 +00:00
|
|
|
static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, short debug)
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
bGPDspoint *pt;
|
|
|
|
float oldpressure = 0.0f;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* draw stroke curve */
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2012-05-08 18:29:02 +00:00
|
|
|
for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
|
2009-08-30 06:10:38 +00:00
|
|
|
/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
|
|
|
|
* and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
|
|
|
|
*/
|
2011-03-27 14:59:55 +00:00
|
|
|
if (fabsf(pt->pressure - oldpressure) > 0.2f) {
|
2009-01-14 16:13:50 +00:00
|
|
|
glEnd();
|
|
|
|
glLineWidth(pt->pressure * thickness);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
|
2009-08-30 06:10:38 +00:00
|
|
|
/* need to roll-back one point to ensure that there are no gaps in the stroke */
|
2011-11-26 05:10:53 +00:00
|
|
|
if (i != 0) glVertex3fv(&(pt - 1)->x);
|
2012-06-11 00:21:50 +00:00
|
|
|
|
2009-08-30 06:10:38 +00:00
|
|
|
/* now the point we want... */
|
2011-11-26 05:10:53 +00:00
|
|
|
glVertex3fv(&pt->x);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
oldpressure = pt->pressure;
|
|
|
|
}
|
2011-11-26 05:10:53 +00:00
|
|
|
else {
|
|
|
|
glVertex3fv(&pt->x);
|
|
|
|
}
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
/* draw debug points of curve on top? */
|
|
|
|
if (debug) {
|
|
|
|
glBegin(GL_POINTS);
|
2012-05-08 18:29:02 +00:00
|
|
|
for (i = 0, pt = points; i < totpoints && pt; i++, pt++)
|
2011-11-26 05:10:53 +00:00
|
|
|
glVertex3fv(&pt->x);
|
2009-01-14 16:13:50 +00:00
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----- Fancy 2D-Stroke Drawing ------ */
|
|
|
|
|
|
|
|
/* draw a given stroke in 2d */
|
2012-05-08 18:29:02 +00:00
|
|
|
static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
|
|
|
|
short debug, int offsx, int offsy, int winx, int winy)
|
2009-08-30 13:32:08 +00:00
|
|
|
{
|
2010-09-30 17:23:39 +00:00
|
|
|
/* otherwise thickness is twice that of the 3D view */
|
2012-05-08 18:29:02 +00:00
|
|
|
float thickness = (float)thickness_s * 0.5f;
|
2010-09-30 17:23:39 +00:00
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better
|
2012-05-08 18:29:02 +00:00
|
|
|
* - 'smooth' opengl lines are also required if Image Editor 'image-based' stroke
|
2009-01-14 16:13:50 +00:00
|
|
|
*/
|
|
|
|
if ( (thickness < GP_DRAWTHICKNESS_SPECIAL) ||
|
2012-05-08 18:29:02 +00:00
|
|
|
((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) )
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
bGPDspoint *pt;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2012-05-08 18:29:02 +00:00
|
|
|
for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
|
2009-01-14 16:13:50 +00:00
|
|
|
if (sflag & GP_STROKE_2DSPACE) {
|
|
|
|
glVertex2f(pt->x, pt->y);
|
|
|
|
}
|
|
|
|
else if (sflag & GP_STROKE_2DIMAGE) {
|
2012-05-08 18:29:02 +00:00
|
|
|
const float x = (pt->x * winx) + offsx;
|
|
|
|
const float y = (pt->y * winy) + offsy;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
glVertex2f(x, y);
|
|
|
|
}
|
|
|
|
else {
|
2012-05-08 18:29:02 +00:00
|
|
|
const float x = (pt->x / 100 * winx) + offsx;
|
|
|
|
const float y = (pt->y / 100 * winy) + offsy;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
glVertex2f(x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
2012-03-02 16:05:54 +00:00
|
|
|
/* tessellation code - draw stroke as series of connected quads with connection
|
2009-01-14 16:13:50 +00:00
|
|
|
* edges rotated to minimise shrinking artifacts, and rounded endcaps
|
|
|
|
*/
|
2012-03-06 18:40:15 +00:00
|
|
|
else {
|
2009-01-14 16:13:50 +00:00
|
|
|
bGPDspoint *pt1, *pt2;
|
|
|
|
float pm[2];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
for (i = 0, pt1 = points, pt2 = points + 1; i < (totpoints - 1); i++, pt1++, pt2++) {
|
|
|
|
float s0[2], s1[2]; /* segment 'center' points */
|
|
|
|
float t0[2], t1[2]; /* tessellated coordinates */
|
|
|
|
float m1[2], m2[2]; /* gradient and normal */
|
|
|
|
float mt[2], sc[2]; /* gradient for thickness, point for end-cap */
|
|
|
|
float pthick; /* thickness at segment point */
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* get x and y coordinates from points */
|
|
|
|
if (sflag & GP_STROKE_2DSPACE) {
|
2012-05-08 18:29:02 +00:00
|
|
|
s0[0] = pt1->x; s0[1] = pt1->y;
|
|
|
|
s1[0] = pt2->x; s1[1] = pt2->y;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
else if (sflag & GP_STROKE_2DIMAGE) {
|
2012-05-08 18:29:02 +00:00
|
|
|
s0[0] = (pt1->x * winx) + offsx;
|
|
|
|
s0[1] = (pt1->y * winy) + offsy;
|
|
|
|
s1[0] = (pt2->x * winx) + offsx;
|
|
|
|
s1[1] = (pt2->y * winy) + offsy;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-05-08 18:29:02 +00:00
|
|
|
s0[0] = (pt1->x / 100 * winx) + offsx;
|
|
|
|
s0[1] = (pt1->y / 100 * winy) + offsy;
|
|
|
|
s1[0] = (pt2->x / 100 * winx) + offsx;
|
|
|
|
s1[1] = (pt2->y / 100 * winy) + offsy;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* calculate gradient and normal - 'angle'=(ny/nx) */
|
2012-05-08 18:29:02 +00:00
|
|
|
m1[1] = s1[1] - s0[1];
|
|
|
|
m1[0] = s1[0] - s0[0];
|
2009-11-10 20:43:45 +00:00
|
|
|
normalize_v2(m1);
|
2012-05-08 18:29:02 +00:00
|
|
|
m2[1] = -m1[0];
|
|
|
|
m2[0] = m1[1];
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* always use pressure from first point here */
|
2012-05-08 18:29:02 +00:00
|
|
|
pthick = (pt1->pressure * thickness);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* if the first segment, start of segment is segment's normal */
|
|
|
|
if (i == 0) {
|
|
|
|
/* draw start cap first
|
|
|
|
* - make points slightly closer to center (about halfway across)
|
|
|
|
*/
|
2012-05-08 18:29:02 +00:00
|
|
|
mt[0] = m2[0] * pthick * 0.5f;
|
|
|
|
mt[1] = m2[1] * pthick * 0.5f;
|
|
|
|
sc[0] = s0[0] - (m1[0] * pthick * 0.75f);
|
|
|
|
sc[1] = s0[1] - (m1[1] * pthick * 0.75f);
|
2012-06-11 00:21:50 +00:00
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
t0[0] = sc[0] - mt[0];
|
|
|
|
t0[1] = sc[1] - mt[1];
|
|
|
|
t1[0] = sc[0] + mt[0];
|
|
|
|
t1[1] = sc[1] + mt[1];
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
glVertex2fv(t0);
|
|
|
|
glVertex2fv(t1);
|
|
|
|
|
|
|
|
/* calculate points for start of segment */
|
2012-05-08 18:29:02 +00:00
|
|
|
mt[0] = m2[0] * pthick;
|
|
|
|
mt[1] = m2[1] * pthick;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
t0[0] = s0[0] - mt[0];
|
|
|
|
t0[1] = s0[1] - mt[1];
|
|
|
|
t1[0] = s0[0] + mt[0];
|
|
|
|
t1[1] = s0[1] + mt[1];
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* draw this line twice (first to finish off start cap, then for stroke) */
|
|
|
|
glVertex2fv(t1);
|
|
|
|
glVertex2fv(t0);
|
|
|
|
glVertex2fv(t0);
|
|
|
|
glVertex2fv(t1);
|
|
|
|
}
|
|
|
|
/* if not the first segment, use bisector of angle between segments */
|
|
|
|
else {
|
2012-05-08 18:29:02 +00:00
|
|
|
float mb[2]; /* bisector normal */
|
|
|
|
float athick, dfac; /* actual thickness, difference between thicknesses */
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* calculate gradient of bisector (as average of normals) */
|
2012-05-08 18:29:02 +00:00
|
|
|
mb[0] = (pm[0] + m2[0]) / 2;
|
|
|
|
mb[1] = (pm[1] + m2[1]) / 2;
|
2009-11-10 20:43:45 +00:00
|
|
|
normalize_v2(mb);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* calculate gradient to apply
|
2012-05-08 18:29:02 +00:00
|
|
|
* - as basis, use just pthick * bisector gradient
|
2009-01-14 16:13:50 +00:00
|
|
|
* - if cross-section not as thick as it should be, add extra padding to fix it
|
|
|
|
*/
|
2012-05-08 18:29:02 +00:00
|
|
|
mt[0] = mb[0] * pthick;
|
|
|
|
mt[1] = mb[1] * pthick;
|
|
|
|
athick = len_v2(mt);
|
|
|
|
dfac = pthick - (athick * 2);
|
2012-06-11 00:21:50 +00:00
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) {
|
2009-01-14 16:13:50 +00:00
|
|
|
mt[0] += (mb[0] * dfac);
|
|
|
|
mt[1] += (mb[1] * dfac);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* calculate points for start of segment */
|
2012-05-08 18:29:02 +00:00
|
|
|
t0[0] = s0[0] - mt[0];
|
|
|
|
t0[1] = s0[1] - mt[1];
|
|
|
|
t1[0] = s0[0] + mt[0];
|
|
|
|
t1[1] = s0[1] + mt[1];
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* draw this line twice (once for end of current segment, and once for start of next) */
|
|
|
|
glVertex2fv(t1);
|
|
|
|
glVertex2fv(t0);
|
|
|
|
glVertex2fv(t0);
|
|
|
|
glVertex2fv(t1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if last segment, also draw end of segment (defined as segment's normal) */
|
2012-05-08 18:29:02 +00:00
|
|
|
if (i == totpoints - 2) {
|
2009-01-14 16:13:50 +00:00
|
|
|
/* for once, we use second point's pressure (otherwise it won't be drawn) */
|
2012-05-08 18:29:02 +00:00
|
|
|
pthick = (pt2->pressure * thickness);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* calculate points for end of segment */
|
2012-05-08 18:29:02 +00:00
|
|
|
mt[0] = m2[0] * pthick;
|
|
|
|
mt[1] = m2[1] * pthick;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
t0[0] = s1[0] - mt[0];
|
|
|
|
t0[1] = s1[1] - mt[1];
|
|
|
|
t1[0] = s1[0] + mt[0];
|
|
|
|
t1[1] = s1[1] + mt[1];
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
/* draw this line twice (once for end of stroke, and once for endcap)*/
|
|
|
|
glVertex2fv(t1);
|
|
|
|
glVertex2fv(t0);
|
|
|
|
glVertex2fv(t0);
|
|
|
|
glVertex2fv(t1);
|
|
|
|
|
|
|
|
|
|
|
|
/* draw end cap as last step
|
|
|
|
* - make points slightly closer to center (about halfway across)
|
|
|
|
*/
|
2012-05-08 18:29:02 +00:00
|
|
|
mt[0] = m2[0] * pthick * 0.5f;
|
|
|
|
mt[1] = m2[1] * pthick * 0.5f;
|
|
|
|
sc[0] = s1[0] + (m1[0] * pthick * 0.75f);
|
|
|
|
sc[1] = s1[1] + (m1[1] * pthick * 0.75f);
|
2012-06-11 00:21:50 +00:00
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
t0[0] = sc[0] - mt[0];
|
|
|
|
t0[1] = sc[1] - mt[1];
|
|
|
|
t1[0] = sc[0] + mt[0];
|
|
|
|
t1[1] = sc[1] + mt[1];
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
glVertex2fv(t1);
|
|
|
|
glVertex2fv(t0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* store stroke's 'natural' normal for next stroke to use */
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_v2_v2(pm, m2);
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw debug points of curve on top? (original stroke points) */
|
|
|
|
if (debug) {
|
|
|
|
bGPDspoint *pt;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
glBegin(GL_POINTS);
|
2012-05-08 18:29:02 +00:00
|
|
|
for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
|
2009-01-14 16:13:50 +00:00
|
|
|
if (sflag & GP_STROKE_2DSPACE) {
|
2011-11-26 05:10:53 +00:00
|
|
|
glVertex2fv(&pt->x);
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
else if (sflag & GP_STROKE_2DIMAGE) {
|
2012-05-08 18:29:02 +00:00
|
|
|
const float x = (float)((pt->x * winx) + offsx);
|
|
|
|
const float y = (float)((pt->y * winy) + offsy);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
glVertex2f(x, y);
|
|
|
|
}
|
|
|
|
else {
|
2012-05-08 18:29:02 +00:00
|
|
|
const float x = (float)(pt->x / 100 * winx) + offsx;
|
|
|
|
const float y = (float)(pt->y / 100 * winy) + offsy;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
glVertex2f(x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----- General Drawing ------ */
|
|
|
|
|
|
|
|
/* draw a set of strokes */
|
2012-05-08 18:29:02 +00:00
|
|
|
static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag,
|
|
|
|
short debug, short lthick, float color[4])
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
bGPDstroke *gps;
|
|
|
|
|
|
|
|
/* set color first (may need to reset it again later too) */
|
2011-05-04 12:00:11 +00:00
|
|
|
glColor4fv(color);
|
2009-01-14 16:13:50 +00:00
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
2009-01-14 16:13:50 +00:00
|
|
|
/* check if stroke can be drawn - checks here generally fall into pairs */
|
|
|
|
if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE))
|
|
|
|
continue;
|
|
|
|
if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE))
|
|
|
|
continue;
|
|
|
|
if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE))
|
|
|
|
continue;
|
|
|
|
if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE))
|
|
|
|
continue;
|
|
|
|
if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE))
|
|
|
|
continue;
|
|
|
|
if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE))
|
|
|
|
continue;
|
2011-03-03 17:59:04 +00:00
|
|
|
if ((gps->points == NULL) || (gps->totpoints < 1))
|
2009-01-14 16:13:50 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* check which stroke-drawer to use */
|
|
|
|
if (gps->totpoints == 1)
|
2011-04-14 04:22:52 +00:00
|
|
|
gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
|
2011-04-01 11:55:21 +00:00
|
|
|
else if (dflag & GP_DRAWDATA_ONLY3D) {
|
2012-05-08 18:29:02 +00:00
|
|
|
const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY);
|
2011-04-14 04:22:52 +00:00
|
|
|
int mask_orig = 0;
|
|
|
|
|
|
|
|
if (no_xray) {
|
2011-04-01 11:55:21 +00:00
|
|
|
glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
|
|
|
|
glDepthMask(0);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2011-04-14 04:22:52 +00:00
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* first arg is normally rv3d->dist, but this isn't available here and seems to work quite well without */
|
2011-04-01 11:55:21 +00:00
|
|
|
bglPolygonOffset(1.0f, 1.0f);
|
2012-03-03 16:31:46 +00:00
|
|
|
#if 0
|
2011-04-01 11:55:21 +00:00
|
|
|
glEnable(GL_POLYGON_OFFSET_LINE);
|
|
|
|
glPolygonOffset(-1.0f, -1.0f);
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2011-04-01 11:55:21 +00:00
|
|
|
}
|
2011-04-14 04:22:52 +00:00
|
|
|
|
2010-10-14 01:22:14 +00:00
|
|
|
gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug);
|
2011-04-14 04:22:52 +00:00
|
|
|
|
|
|
|
if (no_xray) {
|
2011-04-01 11:55:21 +00:00
|
|
|
glDepthMask(mask_orig);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
2011-04-14 04:22:52 +00:00
|
|
|
|
2011-04-01 11:55:21 +00:00
|
|
|
bglPolygonOffset(0.0, 0.0);
|
2012-03-03 16:31:46 +00:00
|
|
|
#if 0
|
2011-04-01 11:55:21 +00:00
|
|
|
glDisable(GL_POLYGON_OFFSET_LINE);
|
|
|
|
glPolygonOffset(0, 0);
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2011-04-01 11:55:21 +00:00
|
|
|
}
|
|
|
|
}
|
2009-01-14 16:13:50 +00:00
|
|
|
else if (gps->totpoints > 1)
|
|
|
|
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw grease-pencil datablock */
|
2012-05-08 18:29:02 +00:00
|
|
|
static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag)
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
2011-03-28 02:34:55 +00:00
|
|
|
bGPDlayer *gpl;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
2009-08-30 13:32:08 +00:00
|
|
|
/* reset line drawing style (in case previous user didn't reset) */
|
|
|
|
setlinestyle(0);
|
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* turn on smooth lines (i.e. anti-aliasing) */
|
|
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
|
|
|
|
/* turn on alpha-blending */
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
|
|
|
/* loop over layers, drawing them */
|
2012-05-08 18:29:02 +00:00
|
|
|
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
2009-01-14 16:13:50 +00:00
|
|
|
bGPDframe *gpf;
|
|
|
|
|
|
|
|
short debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? 1 : 0;
|
2012-05-08 18:29:02 +00:00
|
|
|
short lthick = gpl->thickness;
|
2009-01-14 16:13:50 +00:00
|
|
|
float color[4], tcolor[4];
|
|
|
|
|
|
|
|
/* don't draw layer if hidden */
|
|
|
|
if (gpl->flag & GP_LAYER_HIDE)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* get frame to draw */
|
2012-05-08 18:29:02 +00:00
|
|
|
gpf = gpencil_layer_getframe(gpl, cfra, 0);
|
2009-01-14 16:13:50 +00:00
|
|
|
if (gpf == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* set color, stroke thickness, and point size */
|
|
|
|
glLineWidth(lthick);
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v4_v4(color, gpl->color); // just for copying 4 array elements
|
|
|
|
copy_v4_v4(tcolor, gpl->color); // additional copy of color (for ghosting)
|
2011-05-04 12:00:11 +00:00
|
|
|
glColor4fv(color);
|
2009-01-14 16:13:50 +00:00
|
|
|
glPointSize((float)(gpl->thickness + 2));
|
2011-04-14 04:22:52 +00:00
|
|
|
|
2011-04-01 11:55:21 +00:00
|
|
|
/* apply xray layer setting */
|
2012-05-08 18:29:02 +00:00
|
|
|
if (gpl->flag & GP_LAYER_NO_XRAY) dflag |= GP_DRAWDATA_NO_XRAY;
|
|
|
|
else dflag &= ~GP_DRAWDATA_NO_XRAY;
|
2011-04-14 04:22:52 +00:00
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* draw 'onionskins' (frame left + right) */
|
|
|
|
if (gpl->flag & GP_LAYER_ONIONSKIN) {
|
|
|
|
/* drawing method - only immediately surrounding (gstep = 0), or within a frame range on either side (gstep > 0)*/
|
|
|
|
if (gpl->gstep) {
|
|
|
|
bGPDframe *gf;
|
|
|
|
float fac;
|
|
|
|
|
|
|
|
/* draw previous frames first */
|
2012-05-08 18:29:02 +00:00
|
|
|
for (gf = gpf->prev; gf; gf = gf->prev) {
|
2009-01-14 16:13:50 +00:00
|
|
|
/* check if frame is drawable */
|
|
|
|
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
|
|
|
|
/* alpha decreases with distance from curframe index */
|
2012-05-08 18:29:02 +00:00
|
|
|
fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
|
2011-04-12 10:13:09 +00:00
|
|
|
tcolor[3] = color[3] * fac * 0.66f;
|
2009-01-14 16:13:50 +00:00
|
|
|
gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now draw next frames */
|
2012-05-08 18:29:02 +00:00
|
|
|
for (gf = gpf->next; gf; gf = gf->next) {
|
2009-01-14 16:13:50 +00:00
|
|
|
/* check if frame is drawable */
|
|
|
|
if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
|
|
|
|
/* alpha decreases with distance from curframe index */
|
2012-05-08 18:29:02 +00:00
|
|
|
fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep + 1));
|
2011-04-12 10:13:09 +00:00
|
|
|
tcolor[3] = color[3] * fac * 0.66f;
|
2009-01-14 16:13:50 +00:00
|
|
|
gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* restore alpha */
|
2011-05-04 12:00:11 +00:00
|
|
|
glColor4fv(color);
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* 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, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gpf->next) {
|
|
|
|
tcolor[3] = (color[3] / 4);
|
|
|
|
gp_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* restore alpha */
|
2011-05-04 12:00:11 +00:00
|
|
|
glColor4fv(color);
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw the strokes already in active frame */
|
2012-05-08 18:29:02 +00:00
|
|
|
tcolor[3] = color[3];
|
2009-01-14 16:13:50 +00:00
|
|
|
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)
|
|
|
|
*/
|
2011-09-06 07:59:18 +00:00
|
|
|
if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
|
2012-05-08 18:29:02 +00:00
|
|
|
(gpf->flag & GP_FRAME_PAINT))
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
/* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */
|
|
|
|
gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* turn off alpha blending, then smooth lines */
|
|
|
|
glDisable(GL_BLEND); // alpha blending
|
|
|
|
glDisable(GL_LINE_SMOOTH); // smooth lines
|
|
|
|
|
|
|
|
/* restore initial gl conditions */
|
|
|
|
glLineWidth(1.0);
|
|
|
|
glPointSize(1.0);
|
|
|
|
glColor4f(0, 0, 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----- Grease Pencil Sketches Drawing API ------ */
|
|
|
|
|
2009-08-28 12:41:45 +00:00
|
|
|
// ............................
|
|
|
|
// XXX
|
|
|
|
// We need to review the calls below, since they may be/are not that suitable for
|
|
|
|
// the new ways that we intend to be drawing data...
|
|
|
|
// ............................
|
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */
|
2012-06-11 00:46:22 +00:00
|
|
|
void draw_gpencil_2dimage(const bContext *C)
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
2012-05-08 18:29:02 +00:00
|
|
|
ScrArea *sa = CTX_wm_area(C);
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2009-01-14 16:13:50 +00:00
|
|
|
bGPdata *gpd;
|
|
|
|
int offsx, offsy, sizex, sizey;
|
|
|
|
int dflag = GP_DRAWDATA_NOSTATUS;
|
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
gpd = gpencil_data_get_active(C); // XXX
|
2009-01-14 16:13:50 +00:00
|
|
|
if (gpd == NULL) return;
|
|
|
|
|
|
|
|
/* calculate rect */
|
|
|
|
switch (sa->spacetype) {
|
|
|
|
case SPACE_IMAGE: /* image */
|
2011-11-07 12:55:18 +00:00
|
|
|
case SPACE_CLIP: /* clip */
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
/* just draw using standard scaling (settings here are currently ignored anyways) */
|
|
|
|
// FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled
|
2012-05-08 18:29:02 +00:00
|
|
|
offsx = 0;
|
|
|
|
offsy = 0;
|
|
|
|
sizex = ar->winx;
|
|
|
|
sizey = ar->winy;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax);
|
|
|
|
|
2012-05-08 18:29:02 +00:00
|
|
|
dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
2012-05-08 18:29:02 +00:00
|
|
|
break;
|
2009-01-14 16:13:50 +00:00
|
|
|
case SPACE_SEQ: /* sequence */
|
|
|
|
{
|
2012-06-11 00:21:50 +00:00
|
|
|
/* just draw using standard scaling (settings here are currently ignored anyways) */
|
|
|
|
offsx = 0;
|
|
|
|
offsy = 0;
|
|
|
|
sizex = ar->winx;
|
|
|
|
sizey = ar->winy;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
2012-06-11 00:21:50 +00:00
|
|
|
/* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated
|
|
|
|
* and everything moved to standard View2d
|
|
|
|
*/
|
|
|
|
dflag |= GP_DRAWDATA_ONLYV2D;
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
2012-05-08 18:29:02 +00:00
|
|
|
break;
|
2009-01-14 16:13:50 +00:00
|
|
|
default: /* for spacetype not yet handled */
|
2012-05-08 18:29:02 +00:00
|
|
|
offsx = 0;
|
|
|
|
offsy = 0;
|
|
|
|
sizex = ar->winx;
|
|
|
|
sizey = ar->winy;
|
2009-01-14 16:13:50 +00:00
|
|
|
|
|
|
|
dflag |= GP_DRAWDATA_ONLYI2D;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* draw it! */
|
|
|
|
gp_draw_data(gpd, offsx, offsy, sizex, sizey, CFRA, dflag);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
|
|
|
|
* Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes
|
|
|
|
*/
|
2012-06-11 00:46:22 +00:00
|
|
|
void draw_gpencil_view2d(const bContext *C, short onlyv2d)
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
2012-05-08 18:29:02 +00:00
|
|
|
ScrArea *sa = CTX_wm_area(C);
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2009-01-14 16:13:50 +00:00
|
|
|
bGPdata *gpd;
|
|
|
|
int dflag = 0;
|
|
|
|
|
|
|
|
/* check that we have grease-pencil stuff to draw */
|
|
|
|
if (sa == NULL) return;
|
2012-05-08 18:29:02 +00:00
|
|
|
gpd = gpencil_data_get_active(C); // XXX
|
2009-01-14 16:13:50 +00:00
|
|
|
if (gpd == NULL) return;
|
|
|
|
|
2009-08-30 13:32:08 +00:00
|
|
|
/* special hack for Image Editor */
|
|
|
|
// FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled
|
2011-11-07 12:55:18 +00:00
|
|
|
if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP))
|
2009-08-30 13:32:08 +00:00
|
|
|
dflag |= GP_DRAWDATA_IEDITHACK;
|
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* draw it! */
|
2012-05-08 18:29:02 +00:00
|
|
|
if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS);
|
2009-01-14 16:13:50 +00:00
|
|
|
gp_draw_data(gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
|
|
|
|
* Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, second time with only3d=0 for screen-aligned strokes
|
|
|
|
*/
|
2010-08-25 08:31:52 +00:00
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, short only3d)
|
2009-01-14 16:13:50 +00:00
|
|
|
{
|
|
|
|
bGPdata *gpd;
|
|
|
|
int dflag = 0;
|
2010-08-25 08:31:52 +00:00
|
|
|
rcti rect;
|
2012-05-08 18:29:02 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2009-11-09 08:03:43 +00:00
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* check that we have grease-pencil stuff to draw */
|
2012-05-08 18:29:02 +00:00
|
|
|
gpd = gpencil_data_get_active_v3d(scene); // XXX
|
2011-04-14 04:22:52 +00:00
|
|
|
if (gpd == NULL) return;
|
2009-11-09 08:03:43 +00:00
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* when rendering to the offscreen buffer we don't want to
|
2010-08-25 08:31:52 +00:00
|
|
|
* deal with the camera border, otherwise map the coords to the camera border. */
|
2011-04-14 04:22:52 +00:00
|
|
|
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
|
2010-08-25 08:31:52 +00:00
|
|
|
rctf rectf;
|
2011-11-19 18:35:42 +00:00
|
|
|
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, TRUE); /* no shift */
|
2010-08-25 08:31:52 +00:00
|
|
|
BLI_copy_rcti_rctf(&rect, &rectf);
|
|
|
|
}
|
|
|
|
else {
|
2012-03-24 02:51:46 +00:00
|
|
|
rect.xmin = 0;
|
|
|
|
rect.ymin = 0;
|
|
|
|
rect.xmax = ar->winx;
|
|
|
|
rect.ymax = ar->winy;
|
2010-08-25 08:31:52 +00:00
|
|
|
}
|
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* draw it! */
|
2012-05-08 18:29:02 +00:00
|
|
|
if (only3d) dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
|
2010-08-25 08:31:52 +00:00
|
|
|
|
|
|
|
gp_draw_data(gpd, rect.xmin, rect.ymin, rect.xmax, rect.ymax, CFRA, dflag);
|
2009-01-14 16:13:50 +00:00
|
|
|
}
|
2009-11-09 08:03:43 +00:00
|
|
|
|
2009-01-14 16:13:50 +00:00
|
|
|
/* ************************************************** */
|