Draw Manager: curve support
Draws the curve centerline and editmode verts/handles. Handle theme colors, and normal display still need adding.
This commit is contained in:
38
source/blender/blenkernel/BKE_curve_render.h
Normal file
38
source/blender/blenkernel/BKE_curve_render.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* ***** 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,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BKE_CURVE_RENDER_H__
|
||||
#define __BKE_CURVE_RENDER_H__
|
||||
|
||||
/** \file BKE_curve_render.h
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
struct Batch;
|
||||
struct Curve;
|
||||
|
||||
void BKE_curve_batch_cache_dirty(struct Curve *cu);
|
||||
void BKE_curve_batch_selection_dirty(struct Curve *cu);
|
||||
void BKE_curve_batch_cache_clear(struct Curve *cu);
|
||||
void BKE_curve_batch_cache_free(struct Curve *cu);
|
||||
struct Batch *BKE_curve_batch_cache_get_wire_edge(struct Curve *cu, struct CurveCache *ob_curve_cache);
|
||||
struct Batch *BKE_curve_batch_cache_get_overlay_edges(struct Curve *cu);
|
||||
struct Batch *BKE_curve_batch_cache_get_overlay_verts(struct Curve *cu);
|
||||
|
||||
#endif /* __BKE_CURVE_RENDER_H__ */
|
||||
@@ -93,6 +93,7 @@ set(SRC
|
||||
intern/context.c
|
||||
intern/crazyspace.c
|
||||
intern/curve.c
|
||||
intern/curve_render.c
|
||||
intern/customdata.c
|
||||
intern/customdata_file.c
|
||||
intern/data_transfer.c
|
||||
@@ -225,6 +226,7 @@ set(SRC
|
||||
BKE_context.h
|
||||
BKE_crazyspace.h
|
||||
BKE_curve.h
|
||||
BKE_curve_render.h
|
||||
BKE_customdata.h
|
||||
BKE_customdata_file.h
|
||||
BKE_data_transfer.h
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_curve_render.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_font.h"
|
||||
#include "BKE_global.h"
|
||||
@@ -127,6 +128,8 @@ void BKE_curve_free(Curve *cu)
|
||||
{
|
||||
BKE_animdata_free((ID *)cu, false);
|
||||
|
||||
BKE_curve_batch_cache_free(cu);
|
||||
|
||||
BKE_nurbList_free(&cu->nurb);
|
||||
BKE_curve_editfont_free(cu);
|
||||
|
||||
|
||||
641
source/blender/blenkernel/intern/curve_render.c
Normal file
641
source/blender/blenkernel/intern/curve_render.c
Normal file
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* ***** 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,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2017 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenkernel/intern/curve_render.c
|
||||
* \ingroup bke
|
||||
*
|
||||
* \brief Curve API for render engines
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_curve_render.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
#define SELECT 1
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* - Ensure `CurveCache`, `SEQUENCER_DAG_WORKAROUND`.
|
||||
* - Check number of verts/edges to see if cache is valid.
|
||||
* - Check if 'overlay_edges' can use single attribyte per edge, not 2 (for selection drawing).
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Curve Interface, direct access to basic data. */
|
||||
|
||||
static void curve_render_overlay_verts_edges_len_get(
|
||||
ListBase *lb, bool hide_handles,
|
||||
int *r_vert_len, int *r_edge_len)
|
||||
{
|
||||
BLI_assert(r_vert_len || r_edge_len);
|
||||
int vert_len = 0;
|
||||
int edge_len = 0;
|
||||
for (Nurb *nu = lb->first; nu; nu = nu->next) {
|
||||
if (nu->bezt) {
|
||||
vert_len += hide_handles ? nu->pntsu : (nu->pntsu * 3);
|
||||
/* 2x handles per point*/
|
||||
edge_len += 2 * nu->pntsu;
|
||||
}
|
||||
else if (nu->bp) {
|
||||
vert_len += nu->pntsu;
|
||||
/* segments between points */
|
||||
edge_len += nu->pntsu - 1;
|
||||
}
|
||||
}
|
||||
if (r_vert_len) {
|
||||
*r_vert_len = vert_len;
|
||||
}
|
||||
if (r_edge_len) {
|
||||
*r_edge_len = edge_len;
|
||||
}
|
||||
}
|
||||
|
||||
static void curve_render_wire_verts_edges_len_get(
|
||||
const CurveCache *ob_curve_cache,
|
||||
int *r_vert_len, int *r_edge_len)
|
||||
{
|
||||
BLI_assert(r_vert_len || r_edge_len);
|
||||
int vert_len = 0;
|
||||
int edge_len = 0;
|
||||
for (const BevList *bl = ob_curve_cache->bev.first; bl; bl = bl->next) {
|
||||
if (bl->nr > 0) {
|
||||
const bool is_cyclic = bl->poly != -1;
|
||||
|
||||
/* verts */
|
||||
vert_len += bl->nr;
|
||||
|
||||
/* edges */
|
||||
edge_len += bl->nr;
|
||||
if (!is_cyclic) {
|
||||
edge_len -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r_vert_len) {
|
||||
*r_vert_len = vert_len;
|
||||
}
|
||||
if (r_edge_len) {
|
||||
*r_edge_len = edge_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Curve Interface, indirect, partially cached access to complex data. */
|
||||
|
||||
typedef struct CurveRenderData {
|
||||
int types;
|
||||
|
||||
struct {
|
||||
int vert_len;
|
||||
int edge_len;
|
||||
} overlay;
|
||||
|
||||
struct {
|
||||
int vert_len;
|
||||
int edge_len;
|
||||
} wire;
|
||||
|
||||
bool hide_handles;
|
||||
|
||||
/* borrow from 'Object' */
|
||||
CurveCache *ob_curve_cache;
|
||||
|
||||
/* borrow from 'Curve' */
|
||||
struct EditNurb *edit_latt;
|
||||
ListBase *nurbs;
|
||||
|
||||
/* edit, index in nurb list */
|
||||
int actnu;
|
||||
/* edit, index in active nurb (BPoint or BezTriple) */
|
||||
int actvert;
|
||||
} CurveRenderData;
|
||||
|
||||
enum {
|
||||
/* Wire center-line */
|
||||
CU_DATATYPE_WIRE = 1 << 0,
|
||||
/* Edit-mode verts and optionally handles */
|
||||
CU_DATATYPE_OVERLAY = 1 << 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* ob_curve_cache can be NULL, only needed for CU_DATATYPE_WIRE
|
||||
*/
|
||||
static CurveRenderData *curve_render_data_create(Curve *cu, CurveCache *ob_curve_cache, const int types)
|
||||
{
|
||||
CurveRenderData *lrdata = MEM_callocN(sizeof(*lrdata), __func__);
|
||||
lrdata->types = types;
|
||||
ListBase *nurbs;
|
||||
|
||||
lrdata->hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0;
|
||||
lrdata->actnu = cu->actnu;
|
||||
lrdata->actvert = cu->actvert;
|
||||
|
||||
lrdata->ob_curve_cache = ob_curve_cache;
|
||||
|
||||
if (types & CU_DATATYPE_WIRE) {
|
||||
curve_render_wire_verts_edges_len_get(
|
||||
lrdata->ob_curve_cache,
|
||||
&lrdata->wire.vert_len, &lrdata->wire.edge_len);
|
||||
}
|
||||
|
||||
if (cu->editnurb) {
|
||||
EditNurb *editnurb = cu->editnurb;
|
||||
nurbs = &editnurb->nurbs;
|
||||
|
||||
lrdata->edit_latt = editnurb;
|
||||
|
||||
if (types & CU_DATATYPE_OVERLAY) {
|
||||
curve_render_overlay_verts_edges_len_get(
|
||||
nurbs, lrdata->hide_handles,
|
||||
&lrdata->overlay.vert_len,
|
||||
lrdata->hide_handles ? NULL : &lrdata->overlay.edge_len);
|
||||
|
||||
lrdata->actnu = cu->actnu;
|
||||
lrdata->actvert = cu->actvert;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nurbs = &cu->nurb;
|
||||
}
|
||||
|
||||
lrdata->nurbs = nurbs;
|
||||
|
||||
return lrdata;
|
||||
}
|
||||
|
||||
static void curve_render_data_free(CurveRenderData *lrdata)
|
||||
{
|
||||
#if 0
|
||||
if (lrdata->loose_verts) {
|
||||
MEM_freeN(lrdata->loose_verts);
|
||||
}
|
||||
#endif
|
||||
MEM_freeN(lrdata);
|
||||
}
|
||||
|
||||
static int curve_render_data_overlay_verts_len_get(const CurveRenderData *lrdata)
|
||||
{
|
||||
BLI_assert(lrdata->types & CU_DATATYPE_OVERLAY);
|
||||
return lrdata->overlay.vert_len;
|
||||
}
|
||||
|
||||
static int curve_render_data_overlay_edges_len_get(const CurveRenderData *lrdata)
|
||||
{
|
||||
BLI_assert(lrdata->types & CU_DATATYPE_OVERLAY);
|
||||
return lrdata->overlay.edge_len;
|
||||
}
|
||||
|
||||
static int curve_render_data_wire_verts_len_get(const CurveRenderData *lrdata)
|
||||
{
|
||||
BLI_assert(lrdata->types & CU_DATATYPE_WIRE);
|
||||
return lrdata->wire.vert_len;
|
||||
}
|
||||
|
||||
static int curve_render_data_wire_edges_len_get(const CurveRenderData *lrdata)
|
||||
{
|
||||
BLI_assert(lrdata->types & CU_DATATYPE_WIRE);
|
||||
return lrdata->wire.edge_len;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static const BPoint *curve_render_data_vert_bpoint(const CurveRenderData *lrdata, const int vert_idx)
|
||||
{
|
||||
BLI_assert(lrdata->types & CU_DATATYPE_VERT);
|
||||
return &lrdata->bp[vert_idx];
|
||||
}
|
||||
#endif
|
||||
|
||||
enum {
|
||||
VFLAG_VERTEX_SELECTED = 1 << 0,
|
||||
VFLAG_VERTEX_ACTIVE = 1 << 1,
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Curve Batch Cache */
|
||||
|
||||
typedef struct CurveBatchCache {
|
||||
VertexBuffer *wire_verts;
|
||||
VertexBuffer *wire_edges;
|
||||
Batch *wire_batch;
|
||||
|
||||
ElementList *wire_elem;
|
||||
|
||||
/* control handles and vertices */
|
||||
Batch *overlay_edges;
|
||||
Batch *overlay_verts;
|
||||
|
||||
/* settings to determine if cache is invalid */
|
||||
bool is_dirty;
|
||||
|
||||
bool hide_handles;
|
||||
|
||||
bool is_editmode;
|
||||
} CurveBatchCache;
|
||||
|
||||
/* Batch cache management. */
|
||||
|
||||
static bool curve_batch_cache_valid(Curve *cu)
|
||||
{
|
||||
CurveBatchCache *cache = cu->batch_cache;
|
||||
|
||||
if (cache == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cache->is_editmode != (cu->editnurb != NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cache->is_dirty == false) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
/* TODO: check number of vertices/edges? */
|
||||
if (cache->is_editmode) {
|
||||
return false;
|
||||
}
|
||||
else if ((cache->hide_handles != ((cu->drawflag & CU_HIDE_HANDLES) != 0))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void curve_batch_cache_init(Curve *cu)
|
||||
{
|
||||
CurveBatchCache *cache = cu->batch_cache;
|
||||
|
||||
if (!cache) {
|
||||
cache = cu->batch_cache = MEM_callocN(sizeof(*cache), __func__);
|
||||
}
|
||||
else {
|
||||
memset(cache, 0, sizeof(*cache));
|
||||
}
|
||||
|
||||
cache->hide_handles = (cu->flag & CU_HIDE_HANDLES) != 0;
|
||||
|
||||
#if 0
|
||||
ListBase *nurbs;
|
||||
if (cu->editnurb) {
|
||||
EditNurb *editnurb = cu->editnurb;
|
||||
nurbs = &editnurb->nurbs;
|
||||
}
|
||||
else {
|
||||
nurbs = &cu->nurb;
|
||||
}
|
||||
#endif
|
||||
|
||||
cache->is_editmode = cu->editnurb != NULL;
|
||||
|
||||
cache->is_dirty = false;
|
||||
}
|
||||
|
||||
static CurveBatchCache *curve_batch_cache_get(Curve *cu)
|
||||
{
|
||||
if (!curve_batch_cache_valid(cu)) {
|
||||
BKE_curve_batch_cache_clear(cu);
|
||||
curve_batch_cache_init(cu);
|
||||
}
|
||||
return cu->batch_cache;
|
||||
}
|
||||
|
||||
void BKE_curve_batch_cache_dirty(Curve *cu)
|
||||
{
|
||||
CurveBatchCache *cache = cu->batch_cache;
|
||||
if (cache) {
|
||||
cache->is_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_curve_batch_selection_dirty(Curve *cu)
|
||||
{
|
||||
CurveBatchCache *cache = cu->batch_cache;
|
||||
if (cache) {
|
||||
BATCH_DISCARD_ALL_SAFE(cache->overlay_verts);
|
||||
BATCH_DISCARD_ALL_SAFE(cache->overlay_edges);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_curve_batch_cache_clear(Curve *cu)
|
||||
{
|
||||
CurveBatchCache *cache = cu->batch_cache;
|
||||
if (!cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
BATCH_DISCARD_ALL_SAFE(cache->overlay_verts);
|
||||
BATCH_DISCARD_ALL_SAFE(cache->overlay_edges);
|
||||
|
||||
if (cache->wire_batch) {
|
||||
/* Also handles: 'cache->wire_verts', 'cache->wire_edges', 'cache->wire_elem' */
|
||||
BATCH_DISCARD_ALL_SAFE(cache->wire_batch);
|
||||
}
|
||||
else {
|
||||
VERTEXBUFFER_DISCARD_SAFE(cache->wire_verts);
|
||||
VERTEXBUFFER_DISCARD_SAFE(cache->wire_edges);
|
||||
ELEMENTLIST_DISCARD_SAFE(cache->wire_elem);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_curve_batch_cache_free(Curve *cu)
|
||||
{
|
||||
BKE_curve_batch_cache_clear(cu);
|
||||
MEM_SAFE_FREE(cu->batch_cache);
|
||||
}
|
||||
|
||||
/* Batch cache usage. */
|
||||
static VertexBuffer *curve_batch_cache_get_wire_verts(CurveRenderData *lrdata, CurveBatchCache *cache)
|
||||
{
|
||||
BLI_assert(lrdata->types & CU_DATATYPE_WIRE);
|
||||
BLI_assert(lrdata->ob_curve_cache != NULL);
|
||||
|
||||
if (cache->wire_verts == NULL) {
|
||||
static VertexFormat format = { 0 };
|
||||
static unsigned pos_id;
|
||||
if (format.attrib_ct == 0) {
|
||||
/* initialize vertex format */
|
||||
pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
|
||||
}
|
||||
|
||||
const int vert_len = curve_render_data_wire_verts_len_get(lrdata);
|
||||
|
||||
VertexBuffer *vbo = cache->wire_verts = VertexBuffer_create_with_format(&format);
|
||||
VertexBuffer_allocate_data(vbo, vert_len);
|
||||
int vbo_len_used = 0;
|
||||
for (const BevList *bl = lrdata->ob_curve_cache->bev.first; bl; bl = bl->next) {
|
||||
if (bl->nr > 0) {
|
||||
const int i_end = vbo_len_used + bl->nr;
|
||||
for (const BevPoint *bevp = bl->bevpoints; vbo_len_used < i_end; vbo_len_used++, bevp++) {
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bevp->vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_assert(vbo_len_used == vert_len);
|
||||
}
|
||||
|
||||
return cache->wire_verts;
|
||||
}
|
||||
|
||||
static ElementList *curve_batch_cache_get_wire_edges(CurveRenderData *lrdata, CurveBatchCache *cache)
|
||||
{
|
||||
BLI_assert(lrdata->types & CU_DATATYPE_WIRE);
|
||||
BLI_assert(lrdata->ob_curve_cache != NULL);
|
||||
|
||||
if (cache->wire_edges == NULL) {
|
||||
const int vert_len = curve_render_data_wire_verts_len_get(lrdata);
|
||||
const int edge_len = curve_render_data_wire_edges_len_get(lrdata);
|
||||
int edge_len_real = 0;
|
||||
|
||||
ElementListBuilder elb;
|
||||
ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len);
|
||||
|
||||
int i = 0;
|
||||
for (const BevList *bl = lrdata->ob_curve_cache->bev.first; bl; bl = bl->next) {
|
||||
if (bl->nr > 0) {
|
||||
const bool is_cyclic = bl->poly != -1;
|
||||
const int i_end = i + (bl->nr);
|
||||
int i_prev;
|
||||
if (is_cyclic) {
|
||||
i_prev = i + (bl->nr - 1);
|
||||
}
|
||||
else {
|
||||
i_prev = i;
|
||||
i += 1;
|
||||
}
|
||||
for (; i < i_end; i_prev = i++) {
|
||||
add_line_vertices(&elb, i_prev, i);
|
||||
edge_len_real += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lrdata->hide_handles) {
|
||||
BLI_assert(edge_len_real <= edge_len);
|
||||
}
|
||||
else {
|
||||
BLI_assert(edge_len_real == edge_len);
|
||||
}
|
||||
|
||||
cache->wire_elem = ElementList_build(&elb);
|
||||
}
|
||||
|
||||
return cache->wire_elem;
|
||||
}
|
||||
|
||||
static void curve_batch_cache_create_overlay_batches(Curve *cu)
|
||||
{
|
||||
/* Since CU_DATATYPE_OVERLAY is slow to generate, generate them all at once */
|
||||
int options = CU_DATATYPE_OVERLAY;
|
||||
|
||||
CurveBatchCache *cache = curve_batch_cache_get(cu);
|
||||
CurveRenderData *lrdata = curve_render_data_create(cu, NULL, options);
|
||||
|
||||
if (cache->overlay_verts == NULL) {
|
||||
static VertexFormat format = { 0 };
|
||||
static unsigned pos_id, data_id;
|
||||
if (format.attrib_ct == 0) {
|
||||
/* initialize vertex format */
|
||||
pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
|
||||
data_id = VertexFormat_add_attrib(&format, "data", COMP_U8, 1, KEEP_INT);
|
||||
}
|
||||
|
||||
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
|
||||
const int vbo_len_capacity = curve_render_data_overlay_verts_len_get(lrdata);
|
||||
int vbo_len_used = 0;
|
||||
VertexBuffer_allocate_data(vbo, vbo_len_capacity);
|
||||
int i = 0;
|
||||
for (Nurb *nu = lrdata->nurbs->first; nu; nu = nu->next) {
|
||||
if (nu->bezt) {
|
||||
int a = 0;
|
||||
for (const BezTriple *bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == false) {
|
||||
const bool is_active = (i == lrdata->actvert);
|
||||
char vflag;
|
||||
|
||||
if (lrdata->hide_handles) {
|
||||
vflag = (bezt->f2 & SELECT) ?
|
||||
(is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bezt->vec[1]);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
vflag = ((&bezt->f1)[j] & SELECT) ?
|
||||
(is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bezt->vec[j]);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
else if (nu->bp) {
|
||||
int a = 0;
|
||||
for (const BPoint *bp = nu->bp; a < nu->pntsu; a++, bp++) {
|
||||
if (bp->hide == false) {
|
||||
const bool is_active = (i == lrdata->actvert);
|
||||
char vflag;
|
||||
vflag = (bp->f1 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bp->vec);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
i += nu->pntsu;
|
||||
}
|
||||
if (vbo_len_capacity != vbo_len_used) {
|
||||
VertexBuffer_resize_data(vbo, vbo_len_used);
|
||||
}
|
||||
|
||||
cache->overlay_verts = Batch_create(PRIM_POINTS, vbo, NULL);
|
||||
}
|
||||
|
||||
|
||||
if ((cache->overlay_edges == NULL) && (lrdata->hide_handles == false)) {
|
||||
/* Note: we could reference indices to vertices (above) */
|
||||
|
||||
static VertexFormat format = { 0 };
|
||||
static unsigned pos_id, data_id;
|
||||
if (format.attrib_ct == 0) {
|
||||
/* initialize vertex format */
|
||||
pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
|
||||
data_id = VertexFormat_add_attrib(&format, "data", COMP_U8, 1, KEEP_INT);
|
||||
}
|
||||
|
||||
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
|
||||
const int edge_len = curve_render_data_overlay_edges_len_get(lrdata);
|
||||
const int vbo_len_capacity = edge_len * 2;
|
||||
int vbo_len_used = 0;
|
||||
VertexBuffer_allocate_data(vbo, vbo_len_capacity);
|
||||
int i = 0;
|
||||
for (Nurb *nu = lrdata->nurbs->first; nu; nu = nu->next) {
|
||||
if (nu->bezt) {
|
||||
int a = 0;
|
||||
for (const BezTriple *bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == false) {
|
||||
const bool is_active = (i == lrdata->actvert);
|
||||
char vflag;
|
||||
|
||||
vflag = (bezt->f1 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bezt->vec[0]);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
|
||||
/* same vertex twice, only check different selection */
|
||||
for (int j = 0; j < 2; j++) {
|
||||
vflag = ((j ? bezt->f3 : bezt->f1) & SELECT) ?
|
||||
(is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bezt->vec[1]);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
}
|
||||
|
||||
vflag = (bezt->f3 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bezt->vec[2]);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
else if (nu->bp) {
|
||||
int a = 1;
|
||||
for (const BPoint *bp_prev = nu->bp, *bp_curr = &nu->bp[1]; a < nu->pntsu; a++, bp_prev = bp_curr++) {
|
||||
if ((bp_prev->hide == false) && (bp_curr->hide == false)) {
|
||||
char vflag;
|
||||
vflag = ((bp_prev->f1 & SELECT) && (bp_curr->f1 & SELECT)) ? VFLAG_VERTEX_SELECTED : 0;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bp_prev->vec);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, bp_curr->vec);
|
||||
VertexBuffer_set_attrib(vbo, data_id, vbo_len_used, &vflag);
|
||||
vbo_len_used += 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vbo_len_capacity != vbo_len_used) {
|
||||
VertexBuffer_resize_data(vbo, vbo_len_used);
|
||||
}
|
||||
|
||||
cache->overlay_edges = Batch_create(PRIM_LINES, vbo, NULL);
|
||||
}
|
||||
|
||||
curve_render_data_free(lrdata);
|
||||
}
|
||||
|
||||
Batch *BKE_curve_batch_cache_get_wire_edge(Curve *cu, CurveCache *ob_curve_cache)
|
||||
{
|
||||
CurveBatchCache *cache = curve_batch_cache_get(cu);
|
||||
|
||||
if (cache->wire_batch == NULL) {
|
||||
/* create batch from Curve */
|
||||
CurveRenderData *lrdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_WIRE);
|
||||
|
||||
cache->wire_batch = Batch_create(
|
||||
PRIM_LINES,
|
||||
curve_batch_cache_get_wire_verts(lrdata, cache),
|
||||
curve_batch_cache_get_wire_edges(lrdata, cache));
|
||||
|
||||
curve_render_data_free(lrdata);
|
||||
}
|
||||
|
||||
return cache->wire_batch;
|
||||
}
|
||||
|
||||
Batch *BKE_curve_batch_cache_get_overlay_edges(Curve *cu)
|
||||
{
|
||||
CurveBatchCache *cache = curve_batch_cache_get(cu);
|
||||
|
||||
if (cache->overlay_edges == NULL) {
|
||||
curve_batch_cache_create_overlay_batches(cu);
|
||||
}
|
||||
|
||||
return cache->overlay_edges;
|
||||
}
|
||||
|
||||
Batch *BKE_curve_batch_cache_get_overlay_verts(Curve *cu)
|
||||
{
|
||||
CurveBatchCache *cache = curve_batch_cache_get(cu);
|
||||
|
||||
if (cache->overlay_verts == NULL) {
|
||||
curve_batch_cache_create_overlay_batches(cu);
|
||||
}
|
||||
|
||||
return cache->overlay_verts;
|
||||
}
|
||||
@@ -58,8 +58,9 @@
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
#include "BKE_mesh_render.h"
|
||||
#include "BKE_curve_render.h"
|
||||
#include "BKE_lattice_render.h"
|
||||
#include "BKE_mesh_render.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
@@ -351,6 +352,9 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
|
||||
case OB_LATTICE:
|
||||
BKE_lattice_batch_cache_dirty(ob->data);
|
||||
break;
|
||||
case OB_CURVE:
|
||||
BKE_curve_batch_cache_dirty(ob->data);
|
||||
break;
|
||||
}
|
||||
|
||||
ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME);
|
||||
|
||||
@@ -3854,6 +3854,7 @@ static void direct_link_curve(FileData *fd, Curve *cu)
|
||||
|
||||
cu->editnurb = NULL;
|
||||
cu->editfont = NULL;
|
||||
cu->batch_cache = NULL;
|
||||
|
||||
for (nu = cu->nurb.first; nu; nu = nu->next) {
|
||||
nu->bezt = newdataadr(fd, nu->bezt);
|
||||
|
||||
@@ -130,6 +130,8 @@ data_to_c_simple(modes/shaders/edit_mesh_overlay_facedot_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_curve_overlay_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_lattice_overlay_loosevert_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC)
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_mesh_render.h"
|
||||
#include "BKE_curve_render.h"
|
||||
#include "BKE_lattice_render.h"
|
||||
#include "BKE_mesh_render.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
@@ -1592,6 +1593,47 @@ Batch *DRW_cache_mesh_verts_get(Object *ob)
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** \name Curve
|
||||
* \{ */
|
||||
|
||||
Batch *DRW_cache_curve_edge_wire_get(Object *ob)
|
||||
{
|
||||
Batch *surface = NULL;
|
||||
|
||||
BLI_assert(ob->type == OB_CURVE);
|
||||
|
||||
struct Curve *cu = ob->data;
|
||||
surface = BKE_curve_batch_cache_get_wire_edge(cu, ob->curve_cache);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
Batch *DRW_cache_curve_edge_overlay_get(Object *ob)
|
||||
{
|
||||
Batch *surface = NULL;
|
||||
|
||||
BLI_assert(ob->type == OB_CURVE);
|
||||
|
||||
struct Curve *cu = ob->data;
|
||||
surface = BKE_curve_batch_cache_get_overlay_edges(cu);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
Batch *DRW_cache_curve_vert_overlay_get(Object *ob)
|
||||
{
|
||||
Batch *surface = NULL;
|
||||
|
||||
BLI_assert(ob->type == OB_CURVE);
|
||||
|
||||
struct Curve *cu = ob->data;
|
||||
surface = BKE_curve_batch_cache_get_overlay_verts(cu);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** \name Lattice
|
||||
* \{ */
|
||||
|
||||
|
||||
@@ -88,6 +88,11 @@ struct Batch *DRW_cache_mesh_surface_get(struct Object *ob);
|
||||
struct Batch *DRW_cache_mesh_surface_verts_get(struct Object *ob);
|
||||
struct Batch *DRW_cache_mesh_verts_get(struct Object *ob);
|
||||
|
||||
/* Curve */
|
||||
struct Batch *DRW_cache_curve_edge_wire_get(struct Object *ob);
|
||||
struct Batch *DRW_cache_curve_edge_overlay_get(struct Object *ob);
|
||||
struct Batch *DRW_cache_curve_vert_overlay_get(struct Object *ob);
|
||||
|
||||
/* Lattice */
|
||||
struct Batch *DRW_cache_lattice_verts_get(struct Object *ob);
|
||||
struct Batch *DRW_cache_lattice_wire_get(struct Object *ob);
|
||||
|
||||
@@ -39,6 +39,14 @@
|
||||
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
|
||||
extern struct GlobalsUboStorage ts; /* draw_common.c */
|
||||
|
||||
extern char datatoc_common_globals_lib_glsl[];
|
||||
extern char datatoc_edit_curve_overlay_loosevert_vert_glsl[];
|
||||
extern char datatoc_edit_curve_overlay_frag_glsl[];
|
||||
|
||||
extern char datatoc_gpu_shader_3D_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
|
||||
extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
|
||||
|
||||
/* *********** LISTS *********** */
|
||||
/* All lists are per viewport specific datas.
|
||||
* They are all free when viewport changes engines
|
||||
@@ -50,7 +58,9 @@ typedef struct EDIT_CURVE_PassList {
|
||||
/* Declare all passes here and init them in
|
||||
* EDIT_CURVE_cache_init().
|
||||
* Only contains (DRWPass *) */
|
||||
struct DRWPass *pass;
|
||||
struct DRWPass *wire_pass;
|
||||
struct DRWPass *overlay_edge_pass;
|
||||
struct DRWPass *overlay_vert_pass;
|
||||
} EDIT_CURVE_PassList;
|
||||
|
||||
typedef struct EDIT_CURVE_FramebufferList {
|
||||
@@ -93,15 +103,22 @@ static struct {
|
||||
* Add sources to source/blender/draw/modes/shaders
|
||||
* init in EDIT_CURVE_engine_init();
|
||||
* free in EDIT_CURVE_engine_free(); */
|
||||
struct GPUShader *custom_shader;
|
||||
struct GPUShader *wire_sh;
|
||||
|
||||
struct GPUShader *overlay_edge_sh; /* handles and nurbs control cage */
|
||||
struct GPUShader *overlay_vert_sh;
|
||||
|
||||
} e_data = {NULL}; /* Engine data */
|
||||
|
||||
typedef struct g_data {
|
||||
|
||||
|
||||
/* This keeps the references of the shading groups for
|
||||
* easy access in EDIT_CURVE_cache_populate() */
|
||||
DRWShadingGroup *group;
|
||||
|
||||
/* resulting curve as 'wire' for curves (and optionally normals) */
|
||||
DRWShadingGroup *wire_shgrp;
|
||||
|
||||
DRWShadingGroup *overlay_edge_shgrp;
|
||||
DRWShadingGroup *overlay_vert_shgrp;
|
||||
} g_data; /* Transient data */
|
||||
|
||||
/* *********** FUNCTIONS *********** */
|
||||
@@ -132,8 +149,19 @@ static void EDIT_CURVE_engine_init(void *vedata)
|
||||
* tex, 2);
|
||||
*/
|
||||
|
||||
if (!e_data.custom_shader) {
|
||||
e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
if (!e_data.wire_sh) {
|
||||
e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
}
|
||||
|
||||
if (!e_data.overlay_edge_sh) {
|
||||
e_data.overlay_edge_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
}
|
||||
|
||||
if (!e_data.overlay_vert_sh) {
|
||||
e_data.overlay_vert_sh = DRW_shader_create_with_lib(
|
||||
datatoc_edit_curve_overlay_loosevert_vert_glsl, NULL,
|
||||
datatoc_edit_curve_overlay_frag_glsl,
|
||||
datatoc_common_globals_lib_glsl, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,22 +178,28 @@ static void EDIT_CURVE_cache_init(void *vedata)
|
||||
}
|
||||
|
||||
{
|
||||
/* Create a pass */
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
|
||||
psl->pass = DRW_pass_create("My Pass", state);
|
||||
/* Center-Line (wire) */
|
||||
psl->wire_pass = DRW_pass_create(
|
||||
"Curve Wire",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE);
|
||||
stl->g_data->wire_shgrp = DRW_shgroup_create(e_data.wire_sh, psl->wire_pass);
|
||||
|
||||
/* Create a shadingGroup using a function in draw_common.c or custom one */
|
||||
/*
|
||||
* stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
|
||||
* -- or --
|
||||
* stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
|
||||
*/
|
||||
stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
|
||||
|
||||
/* Uniforms need a pointer to it's value so be sure it's accessible at
|
||||
* any given time (i.e. use static vars) */
|
||||
static float color[4] = {0.2f, 0.5f, 0.3f, 1.0};
|
||||
DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1);
|
||||
/* TODO: following handle theme colors,
|
||||
* For now use overlay vert shader for handles (we want them colored):
|
||||
* TH_NURB_ULINE, TH_NURB_SEL_ULINE, TH_HANDLE_* */
|
||||
psl->overlay_edge_pass = DRW_pass_create(
|
||||
"Curve Handle Overlay",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_WIRE);
|
||||
/* TODO: following handle theme colors,
|
||||
* For now use overlay vert shader for handles (we want them colored) */
|
||||
stl->g_data->overlay_edge_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->overlay_edge_pass);
|
||||
|
||||
psl->overlay_vert_pass = DRW_pass_create(
|
||||
"Curve Vert Overlay",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH);
|
||||
|
||||
stl->g_data->overlay_vert_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->overlay_vert_pass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -175,15 +209,29 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
|
||||
{
|
||||
EDIT_CURVE_PassList *psl = ((EDIT_CURVE_Data *)vedata)->psl;
|
||||
EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
|
||||
const struct bContext *C = DRW_get_context();
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *obedit = scene->obedit;
|
||||
|
||||
UNUSED_VARS(psl, stl);
|
||||
|
||||
if (ob->type == OB_MESH) {
|
||||
/* Get geometry cache */
|
||||
struct Batch *geom = DRW_cache_mesh_surface_get(ob);
|
||||
if (ob->type == OB_CURVE) {
|
||||
if (ob == obedit) {
|
||||
/* Get geometry cache */
|
||||
struct Batch *geom;
|
||||
|
||||
/* Add geom to a shading group */
|
||||
DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat);
|
||||
// geom = DRW_cache_mesh_surface_get(ob);
|
||||
|
||||
geom = DRW_cache_curve_edge_wire_get(ob);
|
||||
DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat);
|
||||
|
||||
/* Add geom to a shading group */
|
||||
geom = DRW_cache_curve_edge_overlay_get(ob);
|
||||
DRW_shgroup_call_add(stl->g_data->overlay_edge_shgrp, geom, ob->obmat);
|
||||
|
||||
geom = DRW_cache_curve_vert_overlay_get(ob);
|
||||
DRW_shgroup_call_add(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +267,9 @@ static void EDIT_CURVE_draw_scene(void *vedata)
|
||||
*/
|
||||
|
||||
/* ... or just render passes on default framebuffer. */
|
||||
DRW_draw_pass(psl->pass);
|
||||
DRW_draw_pass(psl->wire_pass);
|
||||
DRW_draw_pass(psl->overlay_edge_pass);
|
||||
DRW_draw_pass(psl->overlay_vert_pass);
|
||||
|
||||
/* If you changed framebuffer, double check you rebind
|
||||
* the default one with its textures attached before finishing */
|
||||
|
||||
@@ -1190,6 +1190,18 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OB_CURVE:
|
||||
{
|
||||
Object *obedit = scene->obedit;
|
||||
if (ob != obedit) {
|
||||
struct Batch *geom = DRW_cache_curve_edge_wire_get(ob);
|
||||
int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
|
||||
DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_shgroup_or(stl, theme_id, stl->g_data->wire);
|
||||
DRW_shgroup_call_add(shgroup, geom, ob->obmat);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_LAMP:
|
||||
DRW_shgroup_lamp(stl, ob, sl);
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
flat in int vertFlag;
|
||||
|
||||
#define VERTEX_SELECTED (1 << 0)
|
||||
#define VERTEX_ACTIVE (1 << 1)
|
||||
|
||||
#if __VERSION__ == 120
|
||||
#define FragColor gl_FragColor
|
||||
#else
|
||||
out vec4 FragColor;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
/* TODO: vertex size */
|
||||
|
||||
if ((vertFlag & VERTEX_SELECTED) != 0) {
|
||||
FragColor = colorVertexSelect;
|
||||
}
|
||||
else if ((vertFlag & VERTEX_ACTIVE) != 0) {
|
||||
FragColor = colorEditMeshActive;
|
||||
}
|
||||
else {
|
||||
FragColor = colorVertex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
/* Draw Curve Vertices */
|
||||
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
uniform vec2 viewportSize;
|
||||
|
||||
in vec3 pos;
|
||||
in int data;
|
||||
|
||||
/* these are the same for all vertices
|
||||
* and does not need interpolation */
|
||||
flat out int vertFlag;
|
||||
flat out int clipCase;
|
||||
|
||||
/* See fragment shader */
|
||||
noperspective out vec4 eData1;
|
||||
flat out vec4 eData2;
|
||||
|
||||
/* project to screen space */
|
||||
vec2 proj(vec4 pos)
|
||||
{
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
clipCase = 0;
|
||||
|
||||
vec4 pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
|
||||
/* only verterx position 0 is used */
|
||||
eData1 = eData2 = vec4(1e10);
|
||||
eData2.zw = proj(pPos);
|
||||
|
||||
vertFlag = data;
|
||||
|
||||
gl_PointSize = sizeEdgeFix;
|
||||
gl_Position = pPos;
|
||||
}
|
||||
@@ -47,12 +47,14 @@
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_lattice_render.h"
|
||||
#include "BKE_mesh_render.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "BKE_curve_render.h"
|
||||
#include "BKE_lattice_render.h"
|
||||
#include "BKE_mesh_render.h"
|
||||
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_transform.h"
|
||||
@@ -932,6 +934,9 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
case OB_MESH:
|
||||
BKE_mesh_batch_selection_dirty(ob->data);
|
||||
break;
|
||||
case OB_CURVE:
|
||||
BKE_curve_batch_selection_dirty(ob->data);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
BKE_lattice_batch_selection_dirty(ob->data);
|
||||
break;
|
||||
|
||||
@@ -266,6 +266,7 @@ typedef struct Curve {
|
||||
|
||||
char pad2[2];
|
||||
|
||||
void *batch_cache;
|
||||
} Curve;
|
||||
|
||||
#define CURVE_VFONT_ANY(cu) \
|
||||
|
||||
Reference in New Issue
Block a user