2018-07-31 10:22:19 +02:00
|
|
|
/*
|
|
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2008, Blender Foundation
|
|
|
|
* This is a new part of Blender
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup draw
|
2018-07-31 10:22:19 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "BLI_polyfill_2d.h"
|
|
|
|
#include "BLI_math_color.h"
|
|
|
|
|
|
|
|
#include "DNA_meshdata_types.h"
|
|
|
|
#include "DNA_gpencil_types.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
|
2018-08-27 14:20:40 +10:00
|
|
|
#include "BKE_deform.h"
|
|
|
|
#include "BKE_gpencil.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
#include "DRW_render.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "ED_gpencil.h"
|
|
|
|
#include "ED_view3d.h"
|
|
|
|
|
|
|
|
#include "UI_resources.h"
|
|
|
|
|
|
|
|
#include "gpencil_engine.h"
|
|
|
|
|
|
|
|
/* Helper to add stroke point to vbo */
|
|
|
|
static void gpencil_set_stroke_point(
|
2018-08-15 16:07:16 +02:00
|
|
|
GPUVertBuf *vbo, const bGPDspoint *pt, int idx,
|
2018-07-31 10:22:19 +02:00
|
|
|
uint pos_id, uint color_id,
|
|
|
|
uint thickness_id, uint uvdata_id, short thickness,
|
|
|
|
const float ink[4])
|
|
|
|
{
|
|
|
|
|
|
|
|
float alpha = ink[3] * pt->strength;
|
|
|
|
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
|
|
|
|
float col[4];
|
|
|
|
ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha);
|
|
|
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, color_id, idx, col);
|
|
|
|
|
|
|
|
/* transfer both values using the same shader variable */
|
|
|
|
float uvdata[2] = { pt->uv_fac, pt->uv_rot };
|
|
|
|
GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata);
|
|
|
|
|
|
|
|
/* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */
|
|
|
|
float thick = max_ff(pt->pressure * thickness, 1.0f);
|
|
|
|
GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick);
|
|
|
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Helper to add a new fill point and texture coordinates to vertex buffer */
|
|
|
|
static void gpencil_set_fill_point(
|
|
|
|
GPUVertBuf *vbo, int idx, bGPDspoint *pt, const float fcolor[4], float uv[2],
|
|
|
|
uint pos_id, uint color_id, uint text_id)
|
|
|
|
{
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
|
|
|
|
GPU_vertbuf_attr_set(vbo, color_id, idx, fcolor);
|
|
|
|
GPU_vertbuf_attr_set(vbo, text_id, idx, uv);
|
|
|
|
}
|
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
static void gpencil_vbo_ensure_size(GpencilBatchCacheElem *be, int totvertex)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
2018-11-20 19:26:16 +01:00
|
|
|
if (be->vbo->vertex_alloc <= be->vbo_len + totvertex) {
|
|
|
|
uint newsize = be->vbo->vertex_alloc + (((totvertex / GPENCIL_VBO_BLOCK_SIZE) + 1) * GPENCIL_VBO_BLOCK_SIZE);
|
|
|
|
GPU_vertbuf_data_resize(be->vbo, newsize);
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
2018-11-20 19:26:16 +01:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
/* create batch geometry data for points stroke shader */
|
|
|
|
void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be, bGPDstroke *gps, short thickness, const float ink[4])
|
|
|
|
{
|
|
|
|
int totvertex = gps->totpoints;
|
|
|
|
if (be->vbo == NULL) {
|
|
|
|
be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
be->thickness_id = GPU_vertformat_attr_add(&be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
|
|
be->uvdata_id = GPU_vertformat_attr_add(&be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
2019-04-15 10:32:06 +02:00
|
|
|
be->prev_pos_id = GPU_vertformat_attr_add(&be->format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2018-11-20 19:26:16 +01:00
|
|
|
|
|
|
|
be->vbo = GPU_vertbuf_create_with_format(&be->format);
|
|
|
|
GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
|
|
|
|
be->vbo_len = 0;
|
|
|
|
}
|
2018-11-21 15:53:17 +01:00
|
|
|
gpencil_vbo_ensure_size(be, totvertex);
|
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
/* draw stroke curve */
|
|
|
|
const bGPDspoint *pt = gps->points;
|
|
|
|
float alpha;
|
|
|
|
float col[4];
|
|
|
|
|
|
|
|
for (int i = 0; i < gps->totpoints; i++, pt++) {
|
|
|
|
/* set point */
|
|
|
|
alpha = ink[3] * pt->strength;
|
|
|
|
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
|
|
|
|
ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha);
|
|
|
|
|
|
|
|
float thick = max_ff(pt->pressure * thickness, 1.0f);
|
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, col);
|
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &thick);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
/* transfer both values using the same shader variable */
|
|
|
|
float uvdata[2] = { pt->uv_fac, pt->uv_rot };
|
2018-11-20 19:26:16 +01:00
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->uvdata_id, be->vbo_len, uvdata);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
|
2019-04-15 10:32:06 +02:00
|
|
|
|
|
|
|
/* use previous point to determine stroke direction */
|
|
|
|
bGPDspoint *pt2 = NULL;
|
|
|
|
if (i == 0) {
|
|
|
|
if (gps->totpoints > 1) {
|
|
|
|
/* extrapolate a point before first point */
|
|
|
|
float fpt[3];
|
|
|
|
pt2 = &gps->points[1];
|
|
|
|
interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f);
|
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt->x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pt2 = &gps->points[i - 1];
|
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt2->x);
|
|
|
|
}
|
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create batch geometry data for stroke shader */
|
2018-11-20 19:26:16 +01:00
|
|
|
void DRW_gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be, bGPDstroke *gps, short thickness, const float ink[4])
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
bGPDspoint *points = gps->points;
|
|
|
|
int totpoints = gps->totpoints;
|
|
|
|
/* if cyclic needs more vertex */
|
|
|
|
int cyclic_add = (gps->flag & GP_STROKE_CYCLIC) ? 1 : 0;
|
2018-11-20 19:26:16 +01:00
|
|
|
int totvertex = totpoints + cyclic_add + 2;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
if (be->vbo == NULL) {
|
|
|
|
be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
be->thickness_id = GPU_vertformat_attr_add(&be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
|
|
be->uvdata_id = GPU_vertformat_attr_add(&be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo = GPU_vertbuf_create_with_format(&be->format);
|
|
|
|
GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
|
|
|
|
be->vbo_len = 0;
|
|
|
|
}
|
2018-11-21 15:53:17 +01:00
|
|
|
gpencil_vbo_ensure_size(be, totvertex);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
/* draw stroke curve */
|
|
|
|
const bGPDspoint *pt = points;
|
|
|
|
for (int i = 0; i < totpoints; i++, pt++) {
|
|
|
|
/* first point for adjacency (not drawn) */
|
|
|
|
if (i == 0) {
|
|
|
|
if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
be->vbo, &points[totpoints - 1], be->vbo_len,
|
|
|
|
be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
else {
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
be->vbo, &points[1], be->vbo_len,
|
|
|
|
be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* set point */
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
be->vbo, pt, be->vbo_len,
|
|
|
|
be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
|
|
|
|
/* draw line to first point to complete the cycle */
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
be->vbo, &points[0], be->vbo_len,
|
|
|
|
be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
2018-07-31 10:22:19 +02:00
|
|
|
/* now add adjacency point (not drawn) */
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
be->vbo, &points[1], be->vbo_len,
|
|
|
|
be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
/* last adjacency point (not drawn) */
|
|
|
|
else {
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
be->vbo, &points[totpoints - 2], be->vbo_len,
|
|
|
|
be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
2018-11-20 19:26:16 +01:00
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
/* create batch geometry data for stroke shader */
|
|
|
|
void DRW_gpencil_get_fill_geom(struct GpencilBatchCacheElem *be, Object *ob, bGPDstroke *gps, const float color[4])
|
|
|
|
{
|
|
|
|
BLI_assert(gps->totpoints >= 3);
|
|
|
|
|
|
|
|
/* Calculate triangles cache for filling area (must be done only after changes) */
|
2018-12-28 08:48:37 +01:00
|
|
|
if ((gps->flag & GP_STROKE_RECALC_GEOMETRY) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) {
|
2018-11-20 19:26:16 +01:00
|
|
|
DRW_gpencil_triangulate_stroke_fill(ob, gps);
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_assert(gps->tot_triangles >= 1);
|
|
|
|
int totvertex = gps->tot_triangles * 3;
|
|
|
|
|
|
|
|
if (be->vbo == NULL) {
|
|
|
|
be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
be->uvdata_id = GPU_vertformat_attr_add(&be->format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
|
|
|
be->vbo = GPU_vertbuf_create_with_format(&be->format);
|
|
|
|
GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
|
|
|
|
be->vbo_len = 0;
|
|
|
|
}
|
2018-11-21 15:53:17 +01:00
|
|
|
gpencil_vbo_ensure_size(be, totvertex);
|
2018-11-20 19:26:16 +01:00
|
|
|
|
|
|
|
/* Draw all triangles for filling the polygon (cache must be calculated before) */
|
|
|
|
bGPDtriangle *stroke_triangle = gps->triangles;
|
|
|
|
for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
|
|
|
|
for (int j = 0; j < 3; j++) {
|
|
|
|
gpencil_set_fill_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
be->vbo, be->vbo_len, &gps->points[stroke_triangle->verts[j]], color, stroke_triangle->uv[j],
|
|
|
|
be->pos_id, be->color_id, be->uvdata_id);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len++;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* create batch geometry data for current buffer stroke shader */
|
2018-08-15 16:07:16 +02:00
|
|
|
GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
ARegion *ar = draw_ctx->ar;
|
|
|
|
RegionView3D *rv3d = draw_ctx->rv3d;
|
|
|
|
ToolSettings *ts = scene->toolsettings;
|
|
|
|
Object *ob = draw_ctx->obact;
|
|
|
|
|
|
|
|
tGPspoint *points = gpd->runtime.sbuffer;
|
|
|
|
int totpoints = gpd->runtime.sbuffer_size;
|
2018-12-15 17:21:47 +01:00
|
|
|
/* if cyclic needs more vertex */
|
|
|
|
int cyclic_add = (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC) ? 1 : 0;
|
|
|
|
int totvertex = totpoints + cyclic_add + 2;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
static GPUVertFormat format = { 0 };
|
|
|
|
static uint pos_id, color_id, thickness_id, uvdata_id;
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
|
|
uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-12-15 17:21:47 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, totvertex);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
/* draw stroke curve */
|
|
|
|
const tGPspoint *tpt = points;
|
2018-12-15 17:21:47 +01:00
|
|
|
bGPDspoint pt, pt2, pt3;
|
2018-07-31 10:22:19 +02:00
|
|
|
int idx = 0;
|
|
|
|
|
|
|
|
/* get origin to reproject point */
|
|
|
|
float origin[3];
|
|
|
|
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
|
2018-11-26 13:49:17 +11:00
|
|
|
ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < totpoints; i++, tpt++) {
|
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
|
2019-03-17 19:47:31 +01:00
|
|
|
ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
/* first point for adjacency (not drawn) */
|
|
|
|
if (i == 0) {
|
2018-12-15 17:21:47 +01:00
|
|
|
if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
|
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 1], &pt2);
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
vbo, &pt2, idx,
|
|
|
|
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
|
2018-12-15 17:21:47 +01:00
|
|
|
idx++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
else {
|
2018-12-15 17:21:47 +01:00
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2);
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
vbo, &pt2, idx,
|
|
|
|
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
|
2018-12-15 17:21:47 +01:00
|
|
|
idx++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
}
|
2018-12-15 17:21:47 +01:00
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
/* set point */
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2018-08-15 16:07:16 +02:00
|
|
|
vbo, &pt, idx,
|
2018-07-31 20:11:55 +10:00
|
|
|
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* last adjacency point (not drawn) */
|
2018-12-15 17:21:47 +01:00
|
|
|
if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
|
|
|
|
/* draw line to first point to complete the cycle */
|
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, &points[0], &pt2);
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
vbo, &pt2, idx,
|
|
|
|
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
|
2018-12-15 17:21:47 +01:00
|
|
|
idx++;
|
|
|
|
/* now add adjacency point (not drawn) */
|
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt3);
|
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
vbo, &pt3, idx,
|
|
|
|
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
|
2018-12-15 17:21:47 +01:00
|
|
|
idx++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
2018-12-15 17:21:47 +01:00
|
|
|
/* last adjacency point (not drawn) */
|
2018-07-31 10:22:19 +02:00
|
|
|
else {
|
2018-12-15 17:21:47 +01:00
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2);
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2019-03-15 08:53:22 +11:00
|
|
|
vbo, &pt2, idx,
|
|
|
|
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
|
2018-12-15 17:21:47 +01:00
|
|
|
idx++;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create batch geometry data for current buffer point shader */
|
2018-08-15 16:07:16 +02:00
|
|
|
GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
ARegion *ar = draw_ctx->ar;
|
|
|
|
RegionView3D *rv3d = draw_ctx->rv3d;
|
|
|
|
ToolSettings *ts = scene->toolsettings;
|
|
|
|
Object *ob = draw_ctx->obact;
|
|
|
|
|
|
|
|
tGPspoint *points = gpd->runtime.sbuffer;
|
|
|
|
int totpoints = gpd->runtime.sbuffer_size;
|
|
|
|
|
|
|
|
static GPUVertFormat format = { 0 };
|
|
|
|
static uint pos_id, color_id, thickness_id, uvdata_id;
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
|
|
uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
GPU_vertbuf_data_alloc(vbo, totpoints);
|
|
|
|
|
|
|
|
/* draw stroke curve */
|
|
|
|
const tGPspoint *tpt = points;
|
|
|
|
bGPDspoint pt;
|
|
|
|
int idx = 0;
|
|
|
|
|
|
|
|
/* get origin to reproject point */
|
|
|
|
float origin[3];
|
|
|
|
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
|
2018-11-26 13:49:17 +11:00
|
|
|
ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < totpoints; i++, tpt++) {
|
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
|
2019-03-17 19:47:31 +01:00
|
|
|
ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
/* set point */
|
2018-07-31 20:11:55 +10:00
|
|
|
gpencil_set_stroke_point(
|
2018-08-15 16:07:16 +02:00
|
|
|
vbo, &pt, idx,
|
2018-07-31 20:11:55 +10:00
|
|
|
pos_id, color_id, thickness_id, uvdata_id,
|
|
|
|
thickness, gpd->runtime.scolor);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
|
2018-12-15 17:21:47 +01:00
|
|
|
return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create batch geometry data for current buffer control point shader */
|
|
|
|
GPUBatch *DRW_gpencil_get_buffer_ctrlpoint_geom(bGPdata *gpd)
|
|
|
|
{
|
|
|
|
bGPDcontrolpoint *cps = gpd->runtime.cp_points;
|
|
|
|
int totpoints = gpd->runtime.tot_cp_points;
|
|
|
|
|
2019-01-11 19:15:23 +01:00
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
ToolSettings *ts = scene->toolsettings;
|
|
|
|
|
|
|
|
if (ts->gp_sculpt.guide.use_guide) {
|
|
|
|
totpoints++;
|
|
|
|
}
|
2019-01-21 10:41:39 +11:00
|
|
|
|
2018-12-15 17:21:47 +01:00
|
|
|
static GPUVertFormat format = { 0 };
|
|
|
|
static uint pos_id, color_id, size_id;
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
size_id = GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
|
|
color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
GPU_vertbuf_data_alloc(vbo, totpoints);
|
|
|
|
|
|
|
|
int idx = 0;
|
|
|
|
for (int i = 0; i < gpd->runtime.tot_cp_points; i++) {
|
|
|
|
bGPDcontrolpoint *cp = &cps[i];
|
2018-12-17 16:25:58 +01:00
|
|
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, color_id, idx, cp->color);
|
2018-12-15 17:21:47 +01:00
|
|
|
|
|
|
|
/* scale size */
|
|
|
|
float size = cp->size * 0.8f;
|
|
|
|
GPU_vertbuf_attr_set(vbo, size_id, idx, &size);
|
|
|
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, idx, &cp->x);
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
|
2019-01-11 19:15:23 +01:00
|
|
|
if (ts->gp_sculpt.guide.use_guide) {
|
|
|
|
float size = 10 * 0.8f;
|
|
|
|
float color[4];
|
|
|
|
float position[3];
|
|
|
|
if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_CUSTOM) {
|
|
|
|
UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
|
|
|
|
copy_v3_v3(position, ts->gp_sculpt.guide.location);
|
|
|
|
}
|
|
|
|
else if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_OBJECT && ts->gp_sculpt.guide.reference_object != NULL) {
|
|
|
|
UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color);
|
|
|
|
copy_v3_v3(position, ts->gp_sculpt.guide.reference_object->loc);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
UI_GetThemeColor4fv(TH_REDALERT, color);
|
|
|
|
copy_v3_v3(position, scene->cursor.location);
|
|
|
|
}
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, idx, position);
|
|
|
|
GPU_vertbuf_attr_set(vbo, size_id, idx, &size);
|
|
|
|
GPU_vertbuf_attr_set(vbo, color_id, idx, color);
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create batch geometry data for current buffer fill shader */
|
|
|
|
GPUBatch *DRW_gpencil_get_buffer_fill_geom(bGPdata *gpd)
|
|
|
|
{
|
|
|
|
if (gpd == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const tGPspoint *points = gpd->runtime.sbuffer;
|
|
|
|
int totpoints = gpd->runtime.sbuffer_size;
|
|
|
|
if (totpoints < 3) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
ARegion *ar = draw_ctx->ar;
|
|
|
|
ToolSettings *ts = scene->toolsettings;
|
|
|
|
Object *ob = draw_ctx->obact;
|
|
|
|
|
|
|
|
/* get origin to reproject point */
|
|
|
|
float origin[3];
|
|
|
|
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
|
2018-11-26 13:49:17 +11:00
|
|
|
ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
int tot_triangles = totpoints - 2;
|
|
|
|
/* allocate memory for temporary areas */
|
|
|
|
uint (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, __func__);
|
|
|
|
float (*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, __func__);
|
|
|
|
|
|
|
|
/* Convert points to array and triangulate
|
2018-09-02 18:28:27 +10:00
|
|
|
* Here a cache is not used because while drawing the information changes all the time, so the cache
|
|
|
|
* would be recalculated constantly, so it is better to do direct calculation for each function call
|
|
|
|
*/
|
2018-07-31 10:22:19 +02:00
|
|
|
for (int i = 0; i < totpoints; i++) {
|
|
|
|
const tGPspoint *pt = &points[i];
|
|
|
|
points2d[i][0] = pt->x;
|
|
|
|
points2d[i][1] = pt->y;
|
|
|
|
}
|
|
|
|
BLI_polyfill_calc(points2d, (uint)totpoints, 0, tmp_triangles);
|
|
|
|
|
|
|
|
static GPUVertFormat format = { 0 };
|
|
|
|
static uint pos_id, color_id;
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
|
|
|
/* draw triangulation data */
|
|
|
|
if (tot_triangles > 0) {
|
|
|
|
GPU_vertbuf_data_alloc(vbo, tot_triangles * 3);
|
|
|
|
|
|
|
|
const tGPspoint *tpt;
|
|
|
|
bGPDspoint pt;
|
|
|
|
|
|
|
|
int idx = 0;
|
|
|
|
for (int i = 0; i < tot_triangles; i++) {
|
|
|
|
for (int j = 0; j < 3; j++) {
|
|
|
|
tpt = &points[tmp_triangles[i][j]];
|
|
|
|
ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt.x);
|
|
|
|
GPU_vertbuf_attr_set(vbo, color_id, idx, gpd->runtime.sfill);
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear memory */
|
|
|
|
if (tmp_triangles) {
|
|
|
|
MEM_freeN(tmp_triangles);
|
|
|
|
}
|
|
|
|
if (points2d) {
|
|
|
|
MEM_freeN(points2d);
|
|
|
|
}
|
|
|
|
|
|
|
|
return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw selected verts for strokes being edited */
|
2018-11-20 19:26:16 +01:00
|
|
|
void DRW_gpencil_get_edit_geom(struct GpencilBatchCacheElem *be, bGPDstroke *gps, float alpha, short dflag)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
Object *ob = draw_ctx->obact;
|
|
|
|
bGPdata *gpd = ob->data;
|
2018-12-13 12:41:29 +01:00
|
|
|
const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
int vgindex = ob->actdef - 1;
|
|
|
|
if (!BLI_findlink(&ob->defbase, vgindex)) {
|
|
|
|
vgindex = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get size of verts:
|
2018-09-02 18:28:27 +10:00
|
|
|
* - The selected state needs to be larger than the unselected state so that
|
|
|
|
* they stand out more.
|
|
|
|
* - We use the theme setting for size of the unselected verts
|
|
|
|
*/
|
2018-07-31 10:22:19 +02:00
|
|
|
float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
|
|
|
|
float vsize;
|
|
|
|
if ((int)bsize > 8) {
|
|
|
|
vsize = 10.0f;
|
|
|
|
bsize = 8.0f;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vsize = bsize + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* for now, we assume that the base color of the points is not too close to the real color */
|
|
|
|
float selectColor[4];
|
|
|
|
UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
|
|
|
|
selectColor[3] = alpha;
|
|
|
|
|
2018-09-04 16:59:14 +02:00
|
|
|
float unselectColor[4];
|
|
|
|
UI_GetThemeColor3fv(TH_GP_VERTEX, unselectColor);
|
|
|
|
unselectColor[3] = alpha;
|
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
if (be->vbo == NULL) {
|
|
|
|
be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
be->thickness_id = GPU_vertformat_attr_add(&be->format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo = GPU_vertbuf_create_with_format(&be->format);
|
2019-01-11 16:58:18 +01:00
|
|
|
GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len = 0;
|
|
|
|
}
|
2018-11-21 15:53:17 +01:00
|
|
|
gpencil_vbo_ensure_size(be, gps->totpoints);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
/* Draw start and end point differently if enabled stroke direction hint */
|
|
|
|
bool show_direction_hint = (dflag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1);
|
|
|
|
|
|
|
|
/* Draw all the stroke points (selected or not) */
|
|
|
|
bGPDspoint *pt = gps->points;
|
|
|
|
MDeformVert *dvert = gps->dvert;
|
|
|
|
|
|
|
|
float fcolor[4];
|
|
|
|
float fsize = 0;
|
2018-08-26 16:39:01 +02:00
|
|
|
for (int i = 0; i < gps->totpoints; i++, pt++) {
|
2018-07-31 10:22:19 +02:00
|
|
|
/* weight paint */
|
|
|
|
if (is_weight_paint) {
|
2019-01-20 20:31:11 +01:00
|
|
|
float weight = (dvert && dvert->dw && (vgindex > -1)) ? defvert_find_weight(dvert, vgindex) : 0.0f;
|
2018-07-31 10:22:19 +02:00
|
|
|
float hue = 2.0f * (1.0f - weight) / 3.0f;
|
|
|
|
hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]);
|
|
|
|
selectColor[3] = 1.0f;
|
|
|
|
copy_v4_v4(fcolor, selectColor);
|
|
|
|
fsize = vsize;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (show_direction_hint && i == 0) {
|
|
|
|
/* start point in green bigger */
|
|
|
|
ARRAY_SET_ITEMS(fcolor, 0.0f, 1.0f, 0.0f, 1.0f);
|
|
|
|
fsize = vsize + 4;
|
|
|
|
}
|
|
|
|
else if (show_direction_hint && (i == gps->totpoints - 1)) {
|
|
|
|
/* end point in red smaller */
|
|
|
|
ARRAY_SET_ITEMS(fcolor, 1.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
fsize = vsize + 1;
|
|
|
|
}
|
|
|
|
else if (pt->flag & GP_SPOINT_SELECT) {
|
|
|
|
copy_v4_v4(fcolor, selectColor);
|
|
|
|
fsize = vsize;
|
|
|
|
}
|
|
|
|
else {
|
2018-09-04 16:59:14 +02:00
|
|
|
copy_v4_v4(fcolor, unselectColor);
|
2018-07-31 10:22:19 +02:00
|
|
|
fsize = bsize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor);
|
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &fsize);
|
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
|
|
|
|
be->vbo_len++;
|
2018-08-26 16:39:01 +02:00
|
|
|
if (gps->dvert != NULL) {
|
|
|
|
dvert++;
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw lines for strokes being edited */
|
2018-11-20 19:26:16 +01:00
|
|
|
void DRW_gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be, bGPDstroke *gps, float alpha, short UNUSED(dflag))
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
Object *ob = draw_ctx->obact;
|
|
|
|
bGPdata *gpd = ob->data;
|
2018-12-13 12:41:29 +01:00
|
|
|
const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
int vgindex = ob->actdef - 1;
|
|
|
|
if (!BLI_findlink(&ob->defbase, vgindex)) {
|
|
|
|
vgindex = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
float selectColor[4];
|
|
|
|
UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
|
|
|
|
selectColor[3] = alpha;
|
|
|
|
float linecolor[4];
|
|
|
|
copy_v4_v4(linecolor, gpd->line_color);
|
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
if (be->vbo == NULL) {
|
|
|
|
be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo = GPU_vertbuf_create_with_format(&be->format);
|
2019-01-11 16:58:18 +01:00
|
|
|
GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
|
2018-11-20 19:26:16 +01:00
|
|
|
be->vbo_len = 0;
|
|
|
|
}
|
2018-11-21 15:53:17 +01:00
|
|
|
gpencil_vbo_ensure_size(be, gps->totpoints);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
/* Draw all the stroke lines (selected or not) */
|
|
|
|
bGPDspoint *pt = gps->points;
|
|
|
|
MDeformVert *dvert = gps->dvert;
|
|
|
|
|
|
|
|
float fcolor[4];
|
2018-08-26 16:39:01 +02:00
|
|
|
for (int i = 0; i < gps->totpoints; i++, pt++) {
|
2018-07-31 10:22:19 +02:00
|
|
|
/* weight paint */
|
|
|
|
if (is_weight_paint) {
|
2019-01-20 20:31:11 +01:00
|
|
|
float weight = (dvert && dvert->dw && (vgindex > -1)) ? defvert_find_weight(dvert, vgindex) : 0.0f;
|
2018-07-31 10:22:19 +02:00
|
|
|
float hue = 2.0f * (1.0f - weight) / 3.0f;
|
|
|
|
hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]);
|
|
|
|
selectColor[3] = 1.0f;
|
|
|
|
copy_v4_v4(fcolor, selectColor);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (pt->flag & GP_SPOINT_SELECT) {
|
|
|
|
copy_v4_v4(fcolor, selectColor);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
copy_v4_v4(fcolor, linecolor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-20 19:26:16 +01:00
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor);
|
|
|
|
GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
|
|
|
|
be->vbo_len++;
|
2018-08-26 16:39:01 +02:00
|
|
|
|
|
|
|
if (gps->dvert != NULL) {
|
|
|
|
dvert++;
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 20:11:55 +10:00
|
|
|
static void set_grid_point(
|
|
|
|
GPUVertBuf *vbo, int idx, float col_grid[4],
|
|
|
|
uint pos_id, uint color_id,
|
2018-11-04 13:00:19 +01:00
|
|
|
float v1, float v2, const int axis)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
GPU_vertbuf_attr_set(vbo, color_id, idx, col_grid);
|
|
|
|
|
|
|
|
float pos[3];
|
2018-11-04 13:00:19 +01:00
|
|
|
/* Set the grid in the selected axis */
|
2018-11-05 07:11:23 +11:00
|
|
|
switch (axis) {
|
2018-11-04 13:00:19 +01:00
|
|
|
case GP_LOCKAXIS_X:
|
|
|
|
{
|
2018-11-05 07:11:23 +11:00
|
|
|
ARRAY_SET_ITEMS(pos, 0.0f, v1, v2);
|
2018-11-04 13:00:19 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GP_LOCKAXIS_Y:
|
|
|
|
{
|
2018-11-05 07:11:23 +11:00
|
|
|
ARRAY_SET_ITEMS(pos, v1, 0.0f, v2);
|
2018-11-04 13:00:19 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GP_LOCKAXIS_Z:
|
2018-11-05 07:11:23 +11:00
|
|
|
default: /* view aligned */
|
2018-11-04 13:00:19 +01:00
|
|
|
{
|
2018-11-05 07:11:23 +11:00
|
|
|
ARRAY_SET_ITEMS(pos, v1, v2, 0.0f);
|
2018-11-04 13:00:19 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, idx, pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw grid lines */
|
2018-10-04 23:27:34 +02:00
|
|
|
GPUBatch *DRW_gpencil_get_grid(Object *ob)
|
2018-07-31 10:22:19 +02:00
|
|
|
{
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
ToolSettings *ts = scene->toolsettings;
|
|
|
|
View3D *v3d = draw_ctx->v3d;
|
2018-10-04 23:27:34 +02:00
|
|
|
bGPdata *gpd = (bGPdata *)ob->data;
|
|
|
|
const bool do_center = (gpd->grid.lines <= 0) ? false : true;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
float col_grid[4];
|
|
|
|
|
|
|
|
/* verify we have something to draw and valid values */
|
2018-10-04 23:27:34 +02:00
|
|
|
if (gpd->grid.scale[0] == 0.0f) {
|
|
|
|
gpd->grid.scale[0] = 1.0f;
|
2018-10-03 22:42:45 +02:00
|
|
|
}
|
2018-10-04 23:27:34 +02:00
|
|
|
if (gpd->grid.scale[1] == 0.0f) {
|
|
|
|
gpd->grid.scale[1] = 1.0f;
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (v3d->overlay.gpencil_grid_opacity < 0.1f) {
|
|
|
|
v3d->overlay.gpencil_grid_opacity = 0.1f;
|
|
|
|
}
|
|
|
|
|
2018-10-04 23:27:34 +02:00
|
|
|
/* set color */
|
|
|
|
copy_v3_v3(col_grid, gpd->grid.color);
|
2018-07-31 10:22:19 +02:00
|
|
|
col_grid[3] = v3d->overlay.gpencil_grid_opacity;
|
|
|
|
|
2018-11-04 13:00:19 +01:00
|
|
|
const int axis = ts->gp_sculpt.lock_axis;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
const char *grid_unit = NULL;
|
2018-10-04 23:27:34 +02:00
|
|
|
const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines;
|
|
|
|
const float grid_w = gpd->grid.scale[0] * ED_scene_grid_scale(scene, &grid_unit);
|
|
|
|
const float grid_h = gpd->grid.scale[1] * ED_scene_grid_scale(scene, &grid_unit);
|
2018-10-03 22:42:45 +02:00
|
|
|
const float space_w = (grid_w / gridlines);
|
|
|
|
const float space_h = (grid_h / gridlines);
|
2018-10-08 23:21:44 +02:00
|
|
|
const float offset[2] = { gpd->grid.offset[0], gpd->grid.offset[1] };
|
2018-07-31 10:22:19 +02:00
|
|
|
|
|
|
|
const uint vertex_len = 2 * (gridlines * 4 + 2);
|
|
|
|
|
|
|
|
static GPUVertFormat format = { 0 };
|
|
|
|
static uint pos_id, color_id;
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
GPU_vertbuf_data_alloc(vbo, vertex_len);
|
|
|
|
|
|
|
|
int idx = 0;
|
|
|
|
|
|
|
|
for (int a = 1; a <= gridlines; a++) {
|
2018-10-03 22:42:45 +02:00
|
|
|
const float line_w = a * space_w;
|
|
|
|
const float line_h = a * space_h;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], -line_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], -line_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], +line_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], +line_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
|
|
|
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], -grid_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], +grid_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], -grid_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], +grid_h + offset[1], axis);
|
2018-07-31 10:22:19 +02:00
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
/* center lines */
|
2018-10-03 22:14:38 +02:00
|
|
|
if (do_center) {
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], 0.0f + offset[1], axis);
|
2018-10-03 22:14:38 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], 0.0f + offset[1], axis);
|
2018-10-03 22:14:38 +02:00
|
|
|
idx++;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], -grid_h + offset[1], axis);
|
2018-10-03 22:14:38 +02:00
|
|
|
idx++;
|
2018-10-08 23:21:44 +02:00
|
|
|
set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], +grid_h + offset[1], axis);
|
2018-10-03 22:14:38 +02:00
|
|
|
idx++;
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
}
|