diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-04-21 14:14:11 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-04-21 15:06:06 +0300 |
commit | bfa888cef28955501195dfbee002bc793685e527 (patch) | |
tree | a7ed19cdc57089f3c728337761bd08a23764814d /source/blender/blenkernel/intern | |
parent | c7f00feabaa334cd839a9e7904ee0fc1b8d8d718 (diff) |
Cleanup: move draw-cache creation from BKE to DRW
Creating draw-cache should only ever be used by the draw-manager.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve_render.c | 1043 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist_render.c | 167 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lattice.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lattice_render.c | 504 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_render.c | 1443 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_update.c | 12 |
8 files changed, 55 insertions, 3167 deletions
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 10da97f5761..084af644588 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -52,7 +52,6 @@ #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" @@ -4660,3 +4659,20 @@ void BKE_curve_eval_path(EvaluationContext *UNUSED(eval_ctx), printf("%s on %s\n", __func__, curve->id.name); } } + +/* Draw Engine */ +void (*BKE_curve_batch_cache_dirty_cb)(Curve *cu, int mode) = NULL; +void (*BKE_curve_batch_cache_free_cb)(Curve *cu) = NULL; + +void BKE_curve_batch_cache_dirty(Curve *cu, int mode) +{ + if (cu->batch_cache) { + BKE_curve_batch_cache_dirty_cb(cu, mode); + } +} +void BKE_curve_batch_cache_free(Curve *cu) +{ + if (cu->batch_cache) { + BKE_curve_batch_cache_free_cb(cu); + } +}
\ No newline at end of file diff --git a/source/blender/blenkernel/intern/curve_render.c b/source/blender/blenkernel/intern/curve_render.c deleted file mode 100644 index 4ef350d3868..00000000000 --- a/source/blender/blenkernel/intern/curve_render.c +++ /dev/null @@ -1,1043 +0,0 @@ -/* - * ***** 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 "BKE_font.h" -#include "BKE_displist_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; - } -} - -static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_curve_cache) -{ - int normal_len = 0; - const BevList *bl; - const Nurb *nu; - for (bl = ob_curve_cache->bev.first, nu = lb->first; nu && bl; bl = bl->next, nu = nu->next) { - int nr = bl->nr; - int skip = nu->resolu / 16; -#if 0 - while (nr-- > 0) { /* accounts for empty bevel lists */ - normal_len += 1; - nr -= skip; - } -#else - normal_len += max_ii((nr + max_ii(skip - 1, 0)) / (skip + 1), 0); -#endif - } - return normal_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; - - /* edit mode normal's */ - struct { - /* 'edge_len == len * 2' - * 'vert_len == len * 3' */ - int len; - } normal; - - struct { - EditFont *edit_font; - } text; - - bool hide_handles; - bool hide_normals; - - /* borrow from 'Object' */ - CurveCache *ob_curve_cache; - - /* borrow from 'Curve' */ - 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, - /* Edit-mode normals */ - CU_DATATYPE_NORMAL = 1 << 2, - /* Geometry */ - CU_DATATYPE_SURFACE = 1 << 3, - /* Text */ - CU_DATATYPE_TEXT_SELECT = 1 << 4, -}; - -/* - * 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 *rdata = MEM_callocN(sizeof(*rdata), __func__); - rdata->types = types; - ListBase *nurbs; - - rdata->hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0; - rdata->hide_normals = (cu->drawflag & CU_HIDE_NORMALS) != 0; - - rdata->actnu = cu->actnu; - rdata->actvert = cu->actvert; - - rdata->ob_curve_cache = ob_curve_cache; - - if (types & CU_DATATYPE_WIRE) { - curve_render_wire_verts_edges_len_get( - rdata->ob_curve_cache, - &rdata->wire.vert_len, &rdata->wire.edge_len); - } - - if (cu->editnurb) { - EditNurb *editnurb = cu->editnurb; - nurbs = &editnurb->nurbs; - - if (types & CU_DATATYPE_OVERLAY) { - curve_render_overlay_verts_edges_len_get( - nurbs, rdata->hide_handles, - &rdata->overlay.vert_len, - rdata->hide_handles ? NULL : &rdata->overlay.edge_len); - - rdata->actnu = cu->actnu; - rdata->actvert = cu->actvert; - } - if (types & CU_DATATYPE_NORMAL) { - rdata->normal.len = curve_render_normal_len_get(nurbs, rdata->ob_curve_cache); - } - } - else { - nurbs = &cu->nurb; - } - - rdata->nurbs = nurbs; - - rdata->text.edit_font = cu->editfont; - - return rdata; -} - -static void curve_render_data_free(CurveRenderData *rdata) -{ -#if 0 - if (rdata->loose_verts) { - MEM_freeN(rdata->loose_verts); - } -#endif - MEM_freeN(rdata); -} - -static int curve_render_data_overlay_verts_len_get(const CurveRenderData *rdata) -{ - BLI_assert(rdata->types & CU_DATATYPE_OVERLAY); - return rdata->overlay.vert_len; -} - -static int curve_render_data_overlay_edges_len_get(const CurveRenderData *rdata) -{ - BLI_assert(rdata->types & CU_DATATYPE_OVERLAY); - return rdata->overlay.edge_len; -} - -static int curve_render_data_wire_verts_len_get(const CurveRenderData *rdata) -{ - BLI_assert(rdata->types & CU_DATATYPE_WIRE); - return rdata->wire.vert_len; -} - -static int curve_render_data_wire_edges_len_get(const CurveRenderData *rdata) -{ - BLI_assert(rdata->types & CU_DATATYPE_WIRE); - return rdata->wire.edge_len; -} - -static int curve_render_data_normal_len_get(const CurveRenderData *rdata) -{ - BLI_assert(rdata->types & CU_DATATYPE_NORMAL); - return rdata->normal.len; -} - -enum { - VFLAG_VERTEX_SELECTED = 1 << 0, - VFLAG_VERTEX_ACTIVE = 1 << 1, -}; - -/* ---------------------------------------------------------------------- */ -/* Curve Batch Cache */ - -typedef struct CurveBatchCache { - /* center-line */ - struct { - VertexBuffer *verts; - VertexBuffer *edges; - Batch *batch; - ElementList *elem; - } wire; - - /* normals */ - struct { - VertexBuffer *verts; - VertexBuffer *edges; - Batch *batch; - ElementList *elem; - } normal; - - /* control handles and vertices */ - struct { - Batch *edges; - Batch *verts; - } overlay; - - struct { - Batch *batch; - } surface; - - /* 3d text */ - struct { - Batch *select; - Batch *cursor; - } text; - - /* settings to determine if cache is invalid */ - bool is_dirty; - - bool hide_handles; - bool hide_normals; - - float normal_size; - - 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) || (cu->editfont != NULL))) { - return false; - } - - if (cache->is_editmode) { - if (cu->editnurb) { - if ((cache->hide_handles != ((cu->drawflag & CU_HIDE_HANDLES) != 0))) { - return false; - } - else if ((cache->hide_normals != ((cu->drawflag & CU_HIDE_NORMALS) != 0))) { - return false; - } - } - else if (cu->editfont) { - /* TODO */ - } - } - - if (cache->is_dirty == false) { - return true; - } - else { - /* TODO: check number of vertices/edges? */ - if (cache->is_editmode) { - 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->drawflag & CU_HIDE_HANDLES) != 0; - cache->hide_normals = (cu->drawflag & CU_HIDE_NORMALS) != 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) || (cu->editfont != 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) { - /* editnurb */ - BATCH_DISCARD_ALL_SAFE(cache->overlay.verts); - BATCH_DISCARD_ALL_SAFE(cache->overlay.edges); - - /* editfont */ - BATCH_DISCARD_ALL_SAFE(cache->text.select); - BATCH_DISCARD_ALL_SAFE(cache->text.cursor); - } -} - -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); - - BATCH_DISCARD_ALL_SAFE(cache->surface.batch); - - if (cache->wire.batch) { - BATCH_DISCARD_ALL_SAFE(cache->wire.batch); - cache->wire.verts = NULL; - cache->wire.edges = NULL; - cache->wire.elem = NULL; - } - else { - VERTEXBUFFER_DISCARD_SAFE(cache->wire.verts); - VERTEXBUFFER_DISCARD_SAFE(cache->wire.edges); - ELEMENTLIST_DISCARD_SAFE(cache->wire.elem); - } - - if (cache->normal.batch) { - BATCH_DISCARD_ALL_SAFE(cache->normal.batch); - cache->normal.verts = NULL; - cache->normal.edges = NULL; - cache->normal.elem = NULL; - } - else { - VERTEXBUFFER_DISCARD_SAFE(cache->normal.verts); - VERTEXBUFFER_DISCARD_SAFE(cache->normal.edges); - ELEMENTLIST_DISCARD_SAFE(cache->normal.elem); - } - - /* 3d text */ - BATCH_DISCARD_ALL_SAFE(cache->text.cursor); - BATCH_DISCARD_ALL_SAFE(cache->text.select); -} - -void BKE_curve_batch_cache_free(Curve *cu) -{ - BKE_curve_batch_cache_clear(cu); - MEM_SAFE_FREE(cu->batch_cache); -} - -/* -------------------------------------------------------------------- */ - -/** \name Private Curve Cache API - * \{ */ - -/* Batch cache usage. */ -static VertexBuffer *curve_batch_cache_get_wire_verts(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_WIRE); - BLI_assert(rdata->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(rdata); - - 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 = rdata->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 *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_WIRE); - BLI_assert(rdata->ob_curve_cache != NULL); - - if (cache->wire.edges == NULL) { - const int vert_len = curve_render_data_wire_verts_len_get(rdata); - const int edge_len = curve_render_data_wire_edges_len_get(rdata); - int edge_len_used = 0; - - ElementListBuilder elb; - ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len); - - int i = 0; - for (const BevList *bl = rdata->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_used += 1; - } - } - } - - if (rdata->hide_handles) { - BLI_assert(edge_len_used <= edge_len); - } - else { - BLI_assert(edge_len_used == edge_len); - } - - cache->wire.elem = ElementList_build(&elb); - } - - return cache->wire.elem; -} - -static VertexBuffer *curve_batch_cache_get_normal_verts(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_NORMAL); - BLI_assert(rdata->ob_curve_cache != NULL); - - if (cache->normal.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 normal_len = curve_render_data_normal_len_get(rdata); - const int vert_len = normal_len * 3; - - VertexBuffer *vbo = cache->normal.verts = VertexBuffer_create_with_format(&format); - VertexBuffer_allocate_data(vbo, vert_len); - int vbo_len_used = 0; - - const BevList *bl; - const Nurb *nu; - - for (bl = rdata->ob_curve_cache->bev.first, nu = rdata->nurbs->first; - nu && bl; - bl = bl->next, nu = nu->next) - { - const BevPoint *bevp = bl->bevpoints; - int nr = bl->nr; - int skip = nu->resolu / 16; - - while (nr-- > 0) { /* accounts for empty bevel lists */ - const float fac = bevp->radius * cache->normal_size; - float vec_a[3]; /* Offset perpendicular to the curve */ - float vec_b[3]; /* Delta along the curve */ - - vec_a[0] = fac; - vec_a[1] = 0.0f; - vec_a[2] = 0.0f; - - mul_qt_v3(bevp->quat, vec_a); - madd_v3_v3fl(vec_a, bevp->dir, -fac); - - reflect_v3_v3v3(vec_b, vec_a, bevp->dir); - negate_v3(vec_b); - - add_v3_v3(vec_a, bevp->vec); - add_v3_v3(vec_b, bevp->vec); - - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, vec_a); - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, bevp->vec); - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, vec_b); - - bevp += skip + 1; - nr -= skip; - } - } - BLI_assert(vbo_len_used == vert_len); - } - - return cache->normal.verts; -} - -static ElementList *curve_batch_cache_get_normal_edges(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_NORMAL); - BLI_assert(rdata->ob_curve_cache != NULL); - - if (cache->normal.edges == NULL) { - const int normal_len = curve_render_data_normal_len_get(rdata); - const int vert_len = normal_len * 3; - const int edge_len = normal_len * 2; - - ElementListBuilder elb; - ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len); - - int vbo_len_used = 0; - for (int i = 0; i < normal_len; i++) { - add_line_vertices(&elb, vbo_len_used + 0, vbo_len_used + 1); - add_line_vertices(&elb, vbo_len_used + 1, vbo_len_used + 2); - vbo_len_used += 3; - } - - BLI_assert(vbo_len_used == vert_len); - - cache->normal.elem = ElementList_build(&elb); - } - - return cache->normal.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 *rdata = 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(rdata); - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - int i = 0; - for (Nurb *nu = rdata->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 == rdata->actvert); - char vflag; - - if (rdata->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 == rdata->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) && (rdata->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(rdata); - 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 = rdata->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 == rdata->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(rdata); -} - -static Batch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_SURFACE); - if (cache->surface.batch == NULL) { - cache->surface.batch = BLI_displist_batch_calc_surface(&rdata->ob_curve_cache->disp); - } - return cache->surface.batch; -} - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Private Object/Font Cache API - * \{ */ - - -static Batch *curve_batch_cache_get_overlay_select(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT); - if (cache->text.select == NULL) { - EditFont *ef = rdata->text.edit_font; - static VertexFormat format = { 0 }; - static unsigned int pos_id; - if (format.attrib_ct == 0) { - pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); - } - - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - const int vbo_len_capacity = ef->selboxes_len * 6; - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - - float box[4][3]; - - /* fill in xy below */ - box[0][2] = box[1][2] = box[2][2] = box[3][2] = 0.001; - - for (int i = 0; i < ef->selboxes_len; i++) { - EditFontSelBox *sb = &ef->selboxes[i]; - - float selboxw; - if (i + 1 != ef->selboxes_len) { - if (ef->selboxes[i + 1].y == sb->y) - selboxw = ef->selboxes[i + 1].x - sb->x; - else - selboxw = sb->w; - } - else { - selboxw = sb->w; - } - - if (sb->rot == 0.0f) { - copy_v2_fl2(box[0], sb->x, sb->y); - copy_v2_fl2(box[1], sb->x + selboxw, sb->y); - copy_v2_fl2(box[2], sb->x + selboxw, sb->y + sb->h); - copy_v2_fl2(box[3], sb->x, sb->y + sb->h); - } - else { - float mat[2][2]; - - angle_to_mat2(mat, sb->rot); - - copy_v2_fl2(box[0], sb->x, sb->y); - - copy_v2_fl2(box[1], selboxw, 0.0f); - mul_m2v2(mat, box[1]); - add_v2_v2(box[1], &sb->x); - - copy_v2_fl2(box[2], selboxw, sb->h); - mul_m2v2(mat, box[2]); - add_v2_v2(box[2], &sb->x); - - copy_v2_fl2(box[3], 0.0f, sb->h); - mul_m2v2(mat, box[3]); - add_v2_v2(box[3], &sb->x); - } - - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, box[0]); - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, box[1]); - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, box[2]); - - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, box[0]); - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, box[2]); - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used++, box[3]); - } - BLI_assert(vbo_len_used == vbo_len_capacity); - cache->text.select = Batch_create(PRIM_TRIANGLES, vbo, NULL); - } - return cache->text.select; -} - -static Batch *curve_batch_cache_get_overlay_cursor(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT); - if (cache->text.cursor == NULL) { - static VertexFormat format = { 0 }; - static unsigned int pos_id; - if (format.attrib_ct == 0) { - pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT); - } - - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - const int vbo_len_capacity = 4; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - for (int i = 0; i < 4; i++) { - VertexBuffer_set_attrib(vbo, pos_id, i, rdata->text.edit_font->textcurs[i]); - } - cache->text.cursor = Batch_create(PRIM_TRIANGLE_FAN, vbo, NULL); - } - return cache->text.cursor; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ - -/** \name Public Object/Curve API - * \{ */ - -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 *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_WIRE); - - cache->wire.batch = Batch_create( - PRIM_LINES, - curve_batch_cache_get_wire_verts(rdata, cache), - curve_batch_cache_get_wire_edges(rdata, cache)); - - curve_render_data_free(rdata); - } - return cache->wire.batch; -} - -Batch *BKE_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve_cache, float normal_size) -{ - CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->normal.batch != NULL) { - cache->normal_size = normal_size; - if (cache->normal_size != normal_size) { - BATCH_DISCARD_ALL_SAFE(cache->normal.batch); - } - } - cache->normal_size = normal_size; - - if (cache->normal.batch == NULL) { - /* create batch from Curve */ - CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_NORMAL); - - cache->normal.batch = Batch_create( - PRIM_LINES, - curve_batch_cache_get_normal_verts(rdata, cache), - curve_batch_cache_get_normal_edges(rdata, cache)); - - curve_render_data_free(rdata); - cache->normal_size = normal_size; - } - return cache->normal.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; -} - -Batch *BKE_curve_batch_cache_get_triangles_with_normals( - struct Curve *cu, struct CurveCache *ob_curve_cache) -{ - CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->surface.batch == NULL) { - CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE); - - curve_batch_cache_get_pos_and_normals(rdata, cache); - - curve_render_data_free(rdata); - } - - return cache->surface.batch; -} - - -/* -------------------------------------------------------------------- */ - -/** \name Public Object/Font API - * \{ */ - -Batch *BKE_curve_batch_cache_get_overlay_select(Curve *cu) -{ - CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->text.select == NULL) { - CurveRenderData *rdata = curve_render_data_create(cu, NULL, CU_DATATYPE_TEXT_SELECT); - - curve_batch_cache_get_overlay_select(rdata, cache); - - curve_render_data_free(rdata); - } - - return cache->text.select; -} - -Batch *BKE_curve_batch_cache_get_overlay_cursor(Curve *cu) -{ - CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->text.cursor == NULL) { - CurveRenderData *rdata = curve_render_data_create(cu, NULL, CU_DATATYPE_TEXT_SELECT); - - curve_batch_cache_get_overlay_cursor(rdata, cache); - - curve_render_data_free(rdata); - } - - return cache->text.cursor; -} - -/** \} */
\ No newline at end of file diff --git a/source/blender/blenkernel/intern/displist_render.c b/source/blender/blenkernel/intern/displist_render.c deleted file mode 100644 index 01aa0c1217e..00000000000 --- a/source/blender/blenkernel/intern/displist_render.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * ***** 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/displist_render.c - * \ingroup bke - * - * \brief DispList API for render engines - * - * \note DispList may be removed soon! This is a utility for object types that use render. - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math_vector.h" - -#include "DNA_curve_types.h" - -#include "BKE_displist.h" -#include "BKE_displist_render.h" - -#include "GPU_batch.h" - -static int dl_vert_len(const DispList *dl) -{ - switch (dl->type) { - case DL_INDEX3: - case DL_INDEX4: - return dl->nr; - case DL_SURF: - return dl->parts * dl->nr; - } - return 0; -} - -static int dl_tri_len(const DispList *dl) -{ - switch (dl->type) { - case DL_INDEX3: - return dl->parts; - case DL_INDEX4: - return dl->parts * 2; - case DL_SURF: - return dl->totindex * 2; - } - return 0; -} - -/* see: displist_get_allverts */ -static int curve_render_surface_vert_len_get(const ListBase *lb) -{ - int vert_len = 0; - for (const DispList *dl = lb->first; dl; dl = dl->next) { - vert_len += dl_vert_len(dl); - } - return vert_len; -} - -static int curve_render_surface_tri_len_get(const ListBase *lb) -{ - int tri_len = 0; - for (const DispList *dl = lb->first; dl; dl = dl->next) { - tri_len += dl_tri_len(dl); - } - return tri_len; -} - -Batch *BLI_displist_batch_calc_surface(ListBase *lb) -{ - const int tri_len = curve_render_surface_tri_len_get(lb); - if (tri_len == 0) { - return NULL; - } - - static VertexFormat format = { 0 }; - static unsigned int pos_id, nor_id; - if (format.attrib_ct == 0) { - /* initialize vertex format */ - pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); - nor_id = VertexFormat_add_attrib(&format, "nor", COMP_F32, 3, KEEP_FLOAT); - } - - const int vert_len = curve_render_surface_vert_len_get(lb); - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - { - const int vbo_len_capacity = vert_len; - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - - BKE_displist_normals_add(lb); - - for (const DispList *dl = lb->first; dl; dl = dl->next) { - const bool ndata_is_single = dl->type == DL_INDEX3; - if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { - const float *fp_co = dl->verts; - const float *fp_no = dl->nors; - const int vbo_end = vbo_len_used + dl_vert_len(dl); - while (vbo_len_used < vbo_end) { - VertexBuffer_set_attrib(vbo, pos_id, vbo_len_used, fp_co); - if (fp_no) { - VertexBuffer_set_attrib(vbo, nor_id, vbo_len_used, fp_no); - if (ndata_is_single == false) { - fp_no += 3; - } - } - fp_co += 3; - vbo_len_used += 1; - } - } - } - } - - { - ElementListBuilder elb; - ElementListBuilder_init(&elb, PRIM_TRIANGLES, tri_len, vert_len); - - int ofs = 0; - int tri_len_used = 0; - for (const DispList *dl = lb->first; dl; dl = dl->next) { - if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { - if (dl->type == DL_INDEX3) { - const int *idx = dl->index; - const int i_end = dl->parts; - for (int i = 0; i < i_end; i++) { - add_triangle_vertices(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); - tri_len_used += 1; - idx += 3; - } - } - else if (ELEM(dl->type, DL_INDEX4, DL_SURF)) { - const int *idx = dl->index; - const int i_end = dl->totindex; - for (int i = 0; i < i_end; i++) { - add_triangle_vertices(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); - tri_len_used += 1; - add_triangle_vertices(&elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); - tri_len_used += 1; - idx += 4; - } - } - ofs += dl_vert_len(dl); - } - } - - return Batch_create(PRIM_TRIANGLES, vbo, ElementList_build(&elb)); - } -} diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index c567f9b0d6f..c03aa0cd155 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -57,7 +57,6 @@ #include "BKE_global.h" #include "BKE_key.h" #include "BKE_lattice.h" -#include "BKE_lattice_render.h" #include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_library_remap.h" @@ -1234,3 +1233,19 @@ void BKE_lattice_eval_geometry(struct EvaluationContext *UNUSED(eval_ctx), { } +/* Draw Engine */ +void (*BKE_lattice_batch_cache_dirty_cb)(Lattice *lt, int mode) = NULL; +void (*BKE_lattice_batch_cache_free_cb)(Lattice *lt) = NULL; + +void BKE_lattice_batch_cache_dirty(Lattice *lt, int mode) +{ + if (lt->batch_cache) { + BKE_lattice_batch_cache_dirty_cb(lt, mode); + } +} +void BKE_lattice_batch_cache_free(Lattice *lt) +{ + if (lt->batch_cache) { + BKE_lattice_batch_cache_free_cb(lt); + } +}
\ No newline at end of file diff --git a/source/blender/blenkernel/intern/lattice_render.c b/source/blender/blenkernel/intern/lattice_render.c deleted file mode 100644 index 19353ab62e7..00000000000 --- a/source/blender/blenkernel/intern/lattice_render.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * ***** 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. - * - * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/blenkernel/intern/lattice_render.c - * \ingroup bke - * - * \brief Lattice API for render engines - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math_vector.h" - -#include "DNA_curve_types.h" -#include "DNA_lattice_types.h" - -#include "BKE_lattice_render.h" - -#include "GPU_batch.h" - -#define SELECT 1 - -/** - * TODO - * - 'DispList' is currently not used - * (we could avoid using since it will be removed) - */ - -/* ---------------------------------------------------------------------- */ -/* Lattice Interface, direct access to basic data. */ - -static int vert_len_calc(int u, int v, int w) -{ - if (u <= 0 || v <= 0 || w <= 0) { - return 0; - } - return u * v * w; -} - -static int edge_len_calc(int u, int v, int w) -{ - if (u <= 0 || v <= 0 || w <= 0) { - return 0; - } - return (((((u - 1) * v) + - ((v - 1) * u)) * w) + - ((w - 1) * (u * v))); -} - -static int lattice_render_verts_len_get(Lattice *lt) -{ - if (lt->editlatt) { - lt = lt->editlatt->latt; - } - - const int u = lt->pntsu; - const int v = lt->pntsv; - const int w = lt->pntsw; - - if ((lt->flag & LT_OUTSIDE) == 0) { - return vert_len_calc(u, v, w); - } - else { - /* TODO remove internal coords */ - return vert_len_calc(u, v, w); - } -} - -static int lattice_render_edges_len_get(Lattice *lt) -{ - if (lt->editlatt) { - lt = lt->editlatt->latt; - } - - const int u = lt->pntsu; - const int v = lt->pntsv; - const int w = lt->pntsw; - - if ((lt->flag & LT_OUTSIDE) == 0) { - return edge_len_calc(u, v, w); - } - else { - /* TODO remove internal coords */ - return edge_len_calc(u, v, w); - } -} - -/* ---------------------------------------------------------------------- */ -/* Lattice Interface, indirect, partially cached access to complex data. */ - -typedef struct LatticeRenderData { - int types; - - int vert_len; - int edge_len; - - struct { - int u_len, v_len, w_len; - } dims; - bool show_only_outside; - - struct EditLatt *edit_latt; - BPoint *bp; - - int actbp; -} LatticeRenderData; - -enum { - LR_DATATYPE_VERT = 1 << 0, - LR_DATATYPE_EDGE = 1 << 1, - LR_DATATYPE_OVERLAY = 1 << 2, -}; - -static LatticeRenderData *lattice_render_data_create(Lattice *lt, const int types) -{ - LatticeRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__); - rdata->types = types; - - if (lt->editlatt) { - EditLatt *editlatt = lt->editlatt; - lt = editlatt->latt; - - rdata->edit_latt = editlatt; - - if (types & (LR_DATATYPE_VERT)) { - rdata->vert_len = lattice_render_verts_len_get(lt); - } - if (types & (LR_DATATYPE_EDGE)) { - rdata->edge_len = lattice_render_edges_len_get(lt); - } - if (types & LR_DATATYPE_OVERLAY) { - rdata->actbp = lt->actbp; - } - } - else { - if (types & (LR_DATATYPE_VERT)) { - rdata->vert_len = lattice_render_verts_len_get(lt); - } - if (types & (LR_DATATYPE_EDGE)) { - rdata->edge_len = lattice_render_edges_len_get(lt); - /*no edge data */ - } - } - - rdata->bp = lt->def; - - rdata->dims.u_len = lt->pntsu; - rdata->dims.v_len = lt->pntsv; - rdata->dims.w_len = lt->pntsw; - - rdata->show_only_outside = (lt->flag & LT_OUTSIDE) != 0; - rdata->actbp = lt->actbp; - - return rdata; -} - -static void lattice_render_data_free(LatticeRenderData *rdata) -{ -#if 0 - if (rdata->loose_verts) { - MEM_freeN(rdata->loose_verts); - } -#endif - MEM_freeN(rdata); -} - -static int lattice_render_data_verts_len_get(const LatticeRenderData *rdata) -{ - BLI_assert(rdata->types & LR_DATATYPE_VERT); - return rdata->vert_len; -} - -static int lattice_render_data_edges_len_get(const LatticeRenderData *rdata) -{ - BLI_assert(rdata->types & LR_DATATYPE_EDGE); - return rdata->edge_len; -} - -static const BPoint *lattice_render_data_vert_bpoint(const LatticeRenderData *rdata, const int vert_idx) -{ - BLI_assert(rdata->types & LR_DATATYPE_VERT); - return &rdata->bp[vert_idx]; -} - -enum { - VFLAG_VERTEX_SELECTED = 1 << 0, - VFLAG_VERTEX_ACTIVE = 1 << 1, -}; - -/* ---------------------------------------------------------------------- */ -/* Lattice Batch Cache */ - -typedef struct LatticeBatchCache { - VertexBuffer *pos; - ElementList *edges; - - Batch *all_verts; - Batch *all_edges; - - Batch *overlay_verts; - - /* settings to determine if cache is invalid */ - bool is_dirty; - - struct { - int u_len, v_len, w_len; - } dims; - bool show_only_outside; - - bool is_editmode; -} LatticeBatchCache; - -/* Batch cache management. */ - -static bool lattice_batch_cache_valid(Lattice *lt) -{ - LatticeBatchCache *cache = lt->batch_cache; - - if (cache == NULL) { - return false; - } - - if (cache->is_editmode != (lt->editlatt != NULL)) { - return false; - } - - if (cache->is_dirty == false) { - return true; - } - else { - if (cache->is_editmode) { - return false; - } - else if ((cache->dims.u_len != lt->pntsu) || - (cache->dims.v_len != lt->pntsv) || - (cache->dims.w_len != lt->pntsw) || - ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) - { - return false; - } - } - - return true; -} - -static void lattice_batch_cache_init(Lattice *lt) -{ - LatticeBatchCache *cache = lt->batch_cache; - - if (!cache) { - cache = lt->batch_cache = MEM_callocN(sizeof(*cache), __func__); - } - else { - memset(cache, 0, sizeof(*cache)); - } - - cache->dims.u_len = lt->pntsu; - cache->dims.v_len = lt->pntsv; - cache->dims.w_len = lt->pntsw; - cache->show_only_outside = (lt->flag & LT_OUTSIDE) != 0; - - cache->is_editmode = lt->editlatt != NULL; - - cache->is_dirty = false; -} - -static LatticeBatchCache *lattice_batch_cache_get(Lattice *lt) -{ - if (!lattice_batch_cache_valid(lt)) { - BKE_lattice_batch_cache_clear(lt); - lattice_batch_cache_init(lt); - } - return lt->batch_cache; -} - -void BKE_lattice_batch_cache_dirty(Lattice *lt) -{ - LatticeBatchCache *cache = lt->batch_cache; - if (cache) { - cache->is_dirty = true; - } -} - -void BKE_lattice_batch_selection_dirty(Lattice *lt) -{ - LatticeBatchCache *cache = lt->batch_cache; - if (cache) { - /* TODO Separate Flag vbo */ - BATCH_DISCARD_ALL_SAFE(cache->overlay_verts); - } -} - -void BKE_lattice_batch_cache_clear(Lattice *lt) -{ - LatticeBatchCache *cache = lt->batch_cache; - if (!cache) { - return; - } - - BATCH_DISCARD_SAFE(cache->all_verts); - BATCH_DISCARD_SAFE(cache->all_edges); - BATCH_DISCARD_ALL_SAFE(cache->overlay_verts); - - VERTEXBUFFER_DISCARD_SAFE(cache->pos); - ELEMENTLIST_DISCARD_SAFE(cache->edges); -} - -void BKE_lattice_batch_cache_free(Lattice *lt) -{ - BKE_lattice_batch_cache_clear(lt); - MEM_SAFE_FREE(lt->batch_cache); -} - -/* Batch cache usage. */ -static VertexBuffer *lattice_batch_cache_get_pos(LatticeRenderData *rdata, LatticeBatchCache *cache) -{ - BLI_assert(rdata->types & LR_DATATYPE_VERT); - - if (cache->pos == 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 = lattice_render_data_verts_len_get(rdata); - - cache->pos = VertexBuffer_create_with_format(&format); - VertexBuffer_allocate_data(cache->pos, vert_len); - for (int i = 0; i < vert_len; ++i) { - const BPoint *bp = lattice_render_data_vert_bpoint(rdata, i); - VertexBuffer_set_attrib(cache->pos, pos_id, i, bp->vec); - } - } - - return cache->pos; -} - -static ElementList *lattice_batch_cache_get_edges(LatticeRenderData *rdata, LatticeBatchCache *cache) -{ - BLI_assert(rdata->types & (LR_DATATYPE_VERT | LR_DATATYPE_EDGE)); - - if (cache->edges == NULL) { - const int vert_len = lattice_render_data_verts_len_get(rdata); - const int edge_len = lattice_render_data_edges_len_get(rdata); - int edge_len_real = 0; - - ElementListBuilder elb; - ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len); - -#define LATT_INDEX(u, v, w) \ - ((((w) * rdata->dims.v_len + (v)) * rdata->dims.u_len) + (u)) - - for (int w = 0; w < rdata->dims.w_len; w++) { - int wxt = (w == 0 || w == rdata->dims.w_len - 1); - for (int v = 0; v < rdata->dims.v_len; v++) { - int vxt = (v == 0 || v == rdata->dims.v_len - 1); - for (int u = 0; u < rdata->dims.u_len; u++) { - int uxt = (u == 0 || u == rdata->dims.u_len - 1); - - if (w && ((uxt || vxt) || !rdata->show_only_outside)) { - add_line_vertices(&elb, LATT_INDEX(u, v, w - 1), LATT_INDEX(u, v, w)); - BLI_assert(edge_len_real <= edge_len); - edge_len_real++; - } - if (v && ((uxt || wxt) || !rdata->show_only_outside)) { - add_line_vertices(&elb, LATT_INDEX(u, v - 1, w), LATT_INDEX(u, v, w)); - BLI_assert(edge_len_real <= edge_len); - edge_len_real++; - } - if (u && ((vxt || wxt) || !rdata->show_only_outside)) { - add_line_vertices(&elb, LATT_INDEX(u - 1, v, w), LATT_INDEX(u, v, w)); - BLI_assert(edge_len_real <= edge_len); - edge_len_real++; - } - } - } - } - -#undef LATT_INDEX - - if (rdata->show_only_outside) { - BLI_assert(edge_len_real <= edge_len); - } - else { - BLI_assert(edge_len_real == edge_len); - } - - cache->edges = ElementList_build(&elb); - } - - return cache->edges; -} - -static void lattice_batch_cache_create_overlay_batches(Lattice *lt) -{ - /* Since LR_DATATYPE_OVERLAY is slow to generate, generate them all at once */ - int options = LR_DATATYPE_VERT | LR_DATATYPE_OVERLAY; - - LatticeBatchCache *cache = lattice_batch_cache_get(lt); - LatticeRenderData *rdata = lattice_render_data_create(lt, 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); - } - - const int vert_len = lattice_render_data_verts_len_get(rdata); - - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - VertexBuffer_allocate_data(vbo, vert_len); - for (int i = 0; i < vert_len; ++i) { - const BPoint *bp = lattice_render_data_vert_bpoint(rdata, i); - - char vflag = 0; - if (bp->f1 & SELECT) { - if (i == rdata->actbp) { - vflag |= VFLAG_VERTEX_ACTIVE; - } - else { - vflag |= VFLAG_VERTEX_SELECTED; - } - } - - VertexBuffer_set_attrib(vbo, pos_id, i, bp->vec); - VertexBuffer_set_attrib(vbo, data_id, i, &vflag); - } - - cache->overlay_verts = Batch_create(PRIM_POINTS, vbo, NULL); - } - - lattice_render_data_free(rdata); -} - -Batch *BKE_lattice_batch_cache_get_all_edges(Lattice *lt) -{ - LatticeBatchCache *cache = lattice_batch_cache_get(lt); - - if (cache->all_edges == NULL) { - /* create batch from Lattice */ - LatticeRenderData *rdata = lattice_render_data_create(lt, LR_DATATYPE_VERT | LR_DATATYPE_EDGE); - - cache->all_edges = Batch_create(PRIM_LINES, lattice_batch_cache_get_pos(rdata, cache), - lattice_batch_cache_get_edges(rdata, cache)); - - lattice_render_data_free(rdata); - } - - return cache->all_edges; -} - -Batch *BKE_lattice_batch_cache_get_all_verts(Lattice *lt) -{ - LatticeBatchCache *cache = lattice_batch_cache_get(lt); - - if (cache->all_verts == NULL) { - LatticeRenderData *rdata = lattice_render_data_create(lt, LR_DATATYPE_VERT); - - cache->all_verts = Batch_create(PRIM_POINTS, lattice_batch_cache_get_pos(rdata, cache), NULL); - - lattice_render_data_free(rdata); - } - - return cache->all_verts; -} - -Batch *BKE_lattice_batch_cache_get_overlay_verts(Lattice *lt) -{ - LatticeBatchCache *cache = lattice_batch_cache_get(lt); - - if (cache->overlay_verts == NULL) { - lattice_batch_cache_create_overlay_batches(lt); - } - - return cache->overlay_verts; -} diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index f8ff3316452..d45223f2a51 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -50,7 +50,6 @@ #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_mesh.h" -#include "BKE_mesh_render.h" #include "BKE_displist.h" #include "BKE_library.h" #include "BKE_library_query.h" @@ -2679,3 +2678,20 @@ void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx), BKE_mesh_texspace_calc(mesh); } } + +/* Draw Engine */ +void (*BKE_mesh_batch_cache_dirty_cb)(Mesh *me, int mode) = NULL; +void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = NULL; + +void BKE_mesh_batch_cache_dirty(Mesh *me, int mode) +{ + if (me->batch_cache) { + BKE_mesh_batch_cache_dirty_cb(me, mode); + } +} +void BKE_mesh_batch_cache_free(Mesh *me) +{ + if (me->batch_cache) { + BKE_mesh_batch_cache_free_cb(me); + } +}
\ No newline at end of file diff --git a/source/blender/blenkernel/intern/mesh_render.c b/source/blender/blenkernel/intern/mesh_render.c deleted file mode 100644 index df23db1b2d4..00000000000 --- a/source/blender/blenkernel/intern/mesh_render.c +++ /dev/null @@ -1,1443 +0,0 @@ -/* - * ***** 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. - * - * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/blenkernel/intern/mesh_render.c - * \ingroup bke - * - * \brief Mesh API for render engines - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math_vector.h" - -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" - -#include "BKE_customdata.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editmesh.h" -#include "BKE_mesh.h" -#include "BKE_mesh_render.h" - -#include "bmesh.h" - -#include "GPU_batch.h" - -/* ---------------------------------------------------------------------- */ -/* Mesh/BMesh Interface, direct access to basic data. */ - -static int mesh_render_verts_len_get(Mesh *me) -{ - return me->edit_btmesh ? me->edit_btmesh->bm->totvert : me->totvert; -} - -static int mesh_render_edges_len_get(Mesh *me) -{ - return me->edit_btmesh ? me->edit_btmesh->bm->totedge : me->totedge; -} - -static int mesh_render_looptri_len_get(Mesh *me) -{ - return me->edit_btmesh ? me->edit_btmesh->tottri : poly_to_tri_count(me->totpoly, me->totloop); -} - -static int mesh_render_polys_len_get(Mesh *me) -{ - return me->edit_btmesh ? me->edit_btmesh->bm->totface : me->totpoly; -} - -static int UNUSED_FUNCTION(mesh_render_loops_len_get)(Mesh *me) -{ - return me->edit_btmesh ? me->edit_btmesh->bm->totloop : me->totloop; -} - -/* ---------------------------------------------------------------------- */ -/* Mesh/BMesh Interface, indirect, partially cached access to complex data. */ - -typedef struct EdgeAdjacentPolys { - int count; - int face_index[2]; -} EdgeAdjacentPolys; - -typedef struct EdgeDrawAttr { - unsigned char v_flag; - unsigned char e_flag; - unsigned char crease; - unsigned char bweight; -} EdgeDrawAttr; - -typedef struct MeshRenderData { - int types; - - int vert_len; - int edge_len; - int tri_len; - int loop_len; - int poly_len; - int loose_vert_len; - int loose_edge_len; - - BMEditMesh *edit_bmesh; - MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; - - BMVert *eve_act; - BMEdge *eed_act; - BMFace *efa_act; - - int crease_ofs; - int bweight_ofs; - - /* Data created on-demand (usually not for bmesh-based data). */ - EdgeAdjacentPolys *edges_adjacent_polys; - MLoopTri *mlooptri; - int *loose_edges; - int *loose_verts; - - float (*poly_normals)[3]; - short (*poly_normals_short)[3]; - short (*vert_normals_short)[3]; -} MeshRenderData; - -enum { - MR_DATATYPE_VERT = 1 << 0, - MR_DATATYPE_EDGE = 1 << 1, - MR_DATATYPE_LOOPTRI = 1 << 2, - MR_DATATYPE_LOOP = 1 << 3, - MR_DATATYPE_POLY = 1 << 4, - MR_DATATYPE_OVERLAY = 1 << 5, -}; - -/** - * These functions look like they would be slow but they will typically return true on the first iteration. - * Only false when all attached elements are hidden. - */ -static bool bm_vert_has_visible_edge(const BMVert *v) -{ - const BMEdge *e_iter, *e_first; - - e_iter = e_first = v->e; - do { - if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) { - return true; - } - } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first); - return false; -} - -static bool bm_edge_has_visible_face(const BMEdge *e) -{ - const BMLoop *l_iter, *l_first; - l_iter = l_first = e->l; - do { - if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) { - return true; - } - } while ((l_iter = l_iter->radial_next) != l_first); - return false; -} - - -static MeshRenderData *mesh_render_data_create(Mesh *me, const int types) -{ - MeshRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__); - rdata->types = types; - - if (me->edit_btmesh) { - BMEditMesh *embm = me->edit_btmesh; - BMesh *bm = embm->bm; - - rdata->edit_bmesh = embm; - - int bm_ensure_types = 0; - if (types & (MR_DATATYPE_VERT)) { - rdata->vert_len = bm->totvert; - bm_ensure_types |= BM_VERT; - } - if (types & (MR_DATATYPE_EDGE)) { - rdata->edge_len = bm->totedge; - bm_ensure_types |= BM_EDGE; - } - if (types & MR_DATATYPE_LOOPTRI) { - BKE_editmesh_tessface_calc(embm); - rdata->tri_len = embm->tottri; - } - if (types & MR_DATATYPE_LOOP) { - rdata->loop_len = bm->totloop; - bm_ensure_types |= BM_LOOP; - } - if (types & MR_DATATYPE_POLY) { - rdata->poly_len = bm->totface; - bm_ensure_types |= BM_FACE; - } - if (types & MR_DATATYPE_OVERLAY) { - rdata->efa_act = BM_mesh_active_face_get(bm, false, true); - rdata->eed_act = BM_mesh_active_edge_get(bm); - rdata->eve_act = BM_mesh_active_vert_get(bm); - rdata->crease_ofs = CustomData_get_offset(&bm->edata, CD_CREASE); - rdata->bweight_ofs = CustomData_get_offset(&bm->edata, CD_BWEIGHT); - } - BM_mesh_elem_index_ensure(bm, bm_ensure_types); - BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP); - if (types & MR_DATATYPE_OVERLAY) { - rdata->loose_vert_len = rdata->loose_edge_len = 0; - - int *lverts = rdata->loose_verts = MEM_mallocN(rdata->vert_len * sizeof(int), "Loose Vert"); - int *ledges = rdata->loose_edges = MEM_mallocN(rdata->edge_len * sizeof(int), "Loose Edges"); - - { - BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); - BMVert **vtable = bm->vtable; - for (int i = 0; i < bm->totvert; i++) { - const BMVert *v = vtable[i]; - if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { - /* Loose vert */ - if (v->e == NULL || !bm_vert_has_visible_edge(v)) { - lverts[rdata->loose_vert_len++] = i; - } - } - } - } - - { - BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0); - BMEdge **etable = bm->etable; - for (int i = 0; i < bm->totedge; i++) { - const BMEdge *e = etable[i]; - if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { - /* Loose edge */ - if (e->l == NULL || !bm_edge_has_visible_face(e)) { - ledges[rdata->loose_edge_len++] = i; - } - } - } - } - - rdata->loose_verts = MEM_reallocN(rdata->loose_verts, rdata->loose_vert_len * sizeof(int)); - rdata->loose_edges = MEM_reallocN(rdata->loose_edges, rdata->loose_edge_len * sizeof(int)); - } - } - else { - if (types & (MR_DATATYPE_VERT)) { - rdata->vert_len = me->totvert; - rdata->mvert = CustomData_get_layer(&me->vdata, CD_MVERT); - } - if (types & (MR_DATATYPE_EDGE)) { - rdata->edge_len = me->totedge; - rdata->medge = CustomData_get_layer(&me->edata, CD_MEDGE); - } - if (types & MR_DATATYPE_LOOPTRI) { - const int tri_len = rdata->tri_len = poly_to_tri_count(me->totpoly, me->totloop); - rdata->mlooptri = MEM_mallocN(sizeof(*rdata->mlooptri) * tri_len, __func__); - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, rdata->mlooptri); - } - if (types & MR_DATATYPE_LOOP) { - rdata->loop_len = me->totloop; - rdata->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP); - } - if (types & MR_DATATYPE_POLY) { - rdata->poly_len = me->totpoly; - rdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY); - } - } - - return rdata; -} - -static void mesh_render_data_free(MeshRenderData *rdata) -{ - if (rdata->loose_verts) { - MEM_freeN(rdata->loose_verts); - } - if (rdata->loose_edges) { - MEM_freeN(rdata->loose_edges); - } - if (rdata->edges_adjacent_polys) { - MEM_freeN(rdata->edges_adjacent_polys); - } - if (rdata->mlooptri) { - MEM_freeN(rdata->mlooptri); - } - if (rdata->poly_normals) { - MEM_freeN(rdata->poly_normals); - } - if (rdata->poly_normals_short) { - MEM_freeN(rdata->poly_normals_short); - } - if (rdata->vert_normals_short) { - MEM_freeN(rdata->vert_normals_short); - } - MEM_freeN(rdata); -} - -static int mesh_render_data_verts_len_get(const MeshRenderData *rdata) -{ - BLI_assert(rdata->types & MR_DATATYPE_VERT); - return rdata->vert_len; -} - -static int mesh_render_data_loose_verts_len_get(const MeshRenderData *rdata) -{ - BLI_assert(rdata->types & MR_DATATYPE_OVERLAY); - return rdata->loose_vert_len; -} - -static int mesh_render_data_edges_len_get(const MeshRenderData *rdata) -{ - BLI_assert(rdata->types & MR_DATATYPE_EDGE); - return rdata->edge_len; -} - -static int mesh_render_data_loose_edges_len_get(const MeshRenderData *rdata) -{ - BLI_assert(rdata->types & MR_DATATYPE_OVERLAY); - return rdata->loose_edge_len; -} - -static int mesh_render_data_looptri_len_get(const MeshRenderData *rdata) -{ - BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI); - return rdata->tri_len; -} - -static int UNUSED_FUNCTION(mesh_render_data_loops_len_get)(const MeshRenderData *rdata) -{ - BLI_assert(rdata->types & MR_DATATYPE_LOOP); - return rdata->loop_len; -} - -static int mesh_render_data_polys_len_get(const MeshRenderData *rdata) -{ - BLI_assert(rdata->types & MR_DATATYPE_POLY); - return rdata->poly_len; -} - -static float *mesh_render_data_vert_co(const MeshRenderData *rdata, const int vert_idx) -{ - BLI_assert(rdata->types & MR_DATATYPE_VERT); - - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMVert *bv = BM_vert_at_index(bm, vert_idx); - return bv->co; - } - else { - return rdata->mvert[vert_idx].co; - } -} - -static short *mesh_render_data_vert_nor(const MeshRenderData *rdata, const int vert_idx) -{ - BLI_assert(rdata->types & MR_DATATYPE_VERT); - - if (rdata->edit_bmesh) { - static short fno[3]; - BMesh *bm = rdata->edit_bmesh->bm; - BMVert *bv = BM_vert_at_index(bm, vert_idx); - normal_float_to_short_v3(fno, bv->no); - return fno; - } - else { - return rdata->mvert[vert_idx].no; - } -} - -static bool mesh_render_data_edge_verts_indices_get( - const MeshRenderData *rdata, const int edge_idx, - int r_vert_idx[2]) -{ - BLI_assert(rdata->types & MR_DATATYPE_EDGE); - - if (rdata->edit_bmesh) { - const BMEdge *bm_edge = BM_edge_at_index(rdata->edit_bmesh->bm, edge_idx); - if (BM_elem_flag_test(bm_edge, BM_ELEM_HIDDEN)) { - return false; - } - r_vert_idx[0] = BM_elem_index_get(bm_edge->v1); - r_vert_idx[1] = BM_elem_index_get(bm_edge->v2); - } - else { - const MEdge *me = &rdata->medge[edge_idx]; - r_vert_idx[0] = me->v1; - r_vert_idx[1] = me->v2; - } - return true; -} - -static bool mesh_render_data_pnors_pcenter_select_get( - MeshRenderData *rdata, const int poly, - float r_pnors[3], float r_center[3], bool *r_selected) -{ - BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); - - if (rdata->edit_bmesh) { - const BMFace *bf = BM_face_at_index(rdata->edit_bmesh->bm, poly); - if (BM_elem_flag_test(bf, BM_ELEM_HIDDEN)) { - return false; - } - BM_face_calc_center_mean(bf, r_center); - BM_face_calc_normal(bf, r_pnors); - *r_selected = (BM_elem_flag_test(bf, BM_ELEM_SELECT) != 0) ? true : false; - } - else { - MVert *mvert = rdata->mvert; - const MPoly *mpoly = rdata->mpoly + poly; - const MLoop *mloop = rdata->mloop + mpoly->loopstart; - - BKE_mesh_calc_poly_center(mpoly, mloop, mvert, r_center); - BKE_mesh_calc_poly_normal(mpoly, mloop, mvert, r_pnors); - - *r_selected = false; /* No selection if not in edit mode */ - } - - return true; -} - -static bool mesh_render_data_edge_vcos_manifold_pnors( - MeshRenderData *rdata, const int edge_index, - float **r_vco1, float **r_vco2, float **r_pnor1, float **r_pnor2, bool *r_is_manifold) -{ - BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); - - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMEdge *bm_edge = BM_edge_at_index(bm, edge_index); - if (BM_elem_flag_test(bm_edge, BM_ELEM_HIDDEN)) { - return false; - } - *r_vco1 = bm_edge->v1->co; - *r_vco2 = bm_edge->v2->co; - if (BM_edge_is_manifold(bm_edge)) { - *r_pnor1 = bm_edge->l->f->no; - *r_pnor2 = bm_edge->l->radial_next->f->no; - *r_is_manifold = true; - } - else { - *r_is_manifold = false; - } - } - else { - MVert *mvert = rdata->mvert; - MEdge *medge = rdata->medge; - EdgeAdjacentPolys *eap = rdata->edges_adjacent_polys; - float (*pnors)[3] = rdata->poly_normals; - - if (!eap) { - const MLoop *mloop = rdata->mloop; - const MPoly *mpoly = rdata->mpoly; - const int poly_len = rdata->poly_len; - const bool do_pnors = (pnors == NULL); - - eap = rdata->edges_adjacent_polys = MEM_callocN(sizeof(*eap) * rdata->edge_len, __func__); - if (do_pnors) { - pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * poly_len, __func__); - } - - for (int i = 0; i < poly_len; i++, mpoly++) { - if (do_pnors) { - BKE_mesh_calc_poly_normal(mpoly, mloop + mpoly->loopstart, mvert, pnors[i]); - } - - const int loopend = mpoly->loopstart + mpoly->totloop; - for (int j = mpoly->loopstart; j < loopend; j++) { - const int edge_idx = mloop[j].e; - if (eap[edge_idx].count < 2) { - eap[edge_idx].face_index[eap[edge_idx].count] = i; - } - eap[edge_idx].count++; - } - } - } - BLI_assert(eap && pnors); - - *r_vco1 = mvert[medge[edge_index].v1].co; - *r_vco2 = mvert[medge[edge_index].v2].co; - if (eap[edge_index].count == 2) { - *r_pnor1 = pnors[eap[edge_index].face_index[0]]; - *r_pnor2 = pnors[eap[edge_index].face_index[1]]; - *r_is_manifold = true; - } - else { - *r_is_manifold = false; - } - } - - return true; -} - -static bool mesh_render_data_looptri_vert_indices_get( - const MeshRenderData *rdata, const int tri_idx, - int r_vert_idx[3]) -{ - BLI_assert(rdata->types & (MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP)); - - if (rdata->edit_bmesh) { - const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx]; - if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) { - return false; - } - r_vert_idx[0] = BM_elem_index_get(bm_looptri[0]->v); - r_vert_idx[1] = BM_elem_index_get(bm_looptri[1]->v); - r_vert_idx[2] = BM_elem_index_get(bm_looptri[2]->v); - } - else { - const unsigned int *l_idx = rdata->mlooptri[tri_idx].tri; - const MLoop *l_tri[3] = {&rdata->mloop[l_idx[0]], &rdata->mloop[l_idx[1]], &rdata->mloop[l_idx[2]]}; - r_vert_idx[0] = l_tri[0]->v; - r_vert_idx[1] = l_tri[1]->v; - r_vert_idx[2] = l_tri[2]->v; - } - - return true; -} - -/** - * Version of #mesh_render_data_looptri_verts_indices_get that assigns - * edge indices too \a r_edges_idx (-1 for non-existant edges). - */ -static bool mesh_render_data_looptri_vert_edge_indices_get( - const MeshRenderData *rdata, const int tri_idx, - int r_vert_idx[3], int r_edges_idx[3]) -{ - BLI_assert(rdata->types & (MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP)); - - unsigned int e_pair_edge[2]; - unsigned int e_pair_loop[2]; - - if (rdata->edit_bmesh) { - const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx]; - - if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) { - return false; - } - - /* assign 'r_edges_idx' & 'r_vert_idx' */ - int j, j_next; - for (j = 2, j_next = 0; j_next < 3; j = j_next++) { - const BMLoop *l = bm_looptri[j], *l_next = bm_looptri[j_next]; - const BMEdge *e = l->e; - ARRAY_SET_ITEMS(e_pair_edge, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2)); - ARRAY_SET_ITEMS(e_pair_loop, BM_elem_index_get(l->v), BM_elem_index_get(l_next->v)); - if ((e_pair_edge[0] == e_pair_loop[0] && e_pair_edge[1] == e_pair_loop[1]) || - (e_pair_edge[0] == e_pair_loop[1] && e_pair_edge[1] == e_pair_loop[0])) - { - r_edges_idx[j] = BM_elem_index_get(l->e); - } - else { - r_edges_idx[j] = -1; - } - r_vert_idx[j] = e_pair_loop[0]; /* BM_elem_index_get(l->v) */ - } - } - else { - const unsigned int *l_idx = rdata->mlooptri[tri_idx].tri; - const MLoop *l_tri[3] = {&rdata->mloop[l_idx[0]], &rdata->mloop[l_idx[1]], &rdata->mloop[l_idx[2]]}; - - /* assign 'r_edges_idx' & 'r_vert_idx' */ - int j, j_next; - for (j = 2, j_next = 0; j_next < 3; j = j_next++) { - const MLoop *l = l_tri[j], *l_next = l_tri[j_next]; - const MEdge *e = &rdata->medge[l->e]; \ - ARRAY_SET_ITEMS(e_pair_edge, e->v1, e->v2); - ARRAY_SET_ITEMS(e_pair_loop, l->v, l_next->v); - if ((e_pair_edge[0] == e_pair_loop[0] && e_pair_edge[1] == e_pair_loop[1]) || - (e_pair_edge[0] == e_pair_loop[1] && e_pair_edge[1] == e_pair_loop[0])) - { - r_edges_idx[j] = l->e; - } - else { - r_edges_idx[j] = -1; - } - r_vert_idx[j] = e_pair_loop[0]; /* l->v */ - } - } - - return true; -} - -static bool mesh_render_data_looptri_cos_nors_smooth_get( - MeshRenderData *rdata, const int tri_idx, - float *(*r_vert_cos)[3], short **r_tri_nor, short *(*r_vert_nors)[3], bool *r_is_smooth) -{ - BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); - - if (rdata->edit_bmesh) { - const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx]; - - if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) { - return false; - } - - short (*pnors_short)[3] = rdata->poly_normals_short; - short (*vnors_short)[3] = rdata->vert_normals_short; - - if (!pnors_short) { - BMesh *bm = rdata->edit_bmesh->bm; - BMIter fiter; - BMFace *face; - int i; - - pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__); - BM_ITER_MESH_INDEX(face, &fiter, bm, BM_FACES_OF_MESH, i) { - normal_float_to_short_v3(pnors_short[i], face->no); - } - } - if (!vnors_short) { - BMesh *bm = rdata->edit_bmesh->bm; - BMIter viter; - BMVert *vert; - int i; - - vnors_short = rdata->vert_normals_short = MEM_mallocN(sizeof(*vnors_short) * rdata->vert_len, __func__); - BM_ITER_MESH_INDEX(vert, &viter, bm, BM_VERT, i) { - normal_float_to_short_v3(vnors_short[i], vert->no); - } - } - - (*r_vert_cos)[0] = bm_looptri[0]->v->co; - (*r_vert_cos)[1] = bm_looptri[1]->v->co; - (*r_vert_cos)[2] = bm_looptri[2]->v->co; - *r_tri_nor = pnors_short[BM_elem_index_get(bm_looptri[0]->f)]; - (*r_vert_nors)[0] = vnors_short[BM_elem_index_get(bm_looptri[0]->v)]; - (*r_vert_nors)[1] = vnors_short[BM_elem_index_get(bm_looptri[1]->v)]; - (*r_vert_nors)[2] = vnors_short[BM_elem_index_get(bm_looptri[2]->v)]; - - *r_is_smooth = BM_elem_flag_test_bool(bm_looptri[0]->f, BM_ELEM_SMOOTH); - } - else { - const MLoopTri *mlt = &rdata->mlooptri[tri_idx]; - short (*pnors_short)[3] = rdata->poly_normals_short; - - if (!pnors_short) { - float (*pnors)[3] = rdata->poly_normals; - - if (!pnors) { - pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * rdata->poly_len, __func__); - BKE_mesh_calc_normals_poly( - rdata->mvert, NULL, rdata->vert_len, - rdata->mloop, rdata->mpoly, rdata->loop_len, rdata->poly_len, pnors, true); - } - - pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__); - for (int i = 0; i < rdata->poly_len; i++) { - normal_float_to_short_v3(pnors_short[i], pnors[i]); - } - } - - (*r_vert_cos)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].co; - (*r_vert_cos)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].co; - (*r_vert_cos)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].co; - *r_tri_nor = pnors_short[mlt->poly]; - (*r_vert_nors)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].no; - (*r_vert_nors)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].no; - (*r_vert_nors)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].no; - - *r_is_smooth = (rdata->mpoly[mlt->poly].flag & ME_SMOOTH) != 0; - } - return true; -} - -/* First 2 bytes are bit flags - * 3rd is for sharp edges - * 4rd is for creased edges */ -enum { - VFLAG_VERTEX_ACTIVE = 1 << 0, - VFLAG_VERTEX_SELECTED = 1 << 1, - VFLAG_FACE_ACTIVE = 1 << 2, - VFLAG_FACE_SELECTED = 1 << 3, -}; - -enum { - VFLAG_EDGE_EXISTS = 1 << 0, - VFLAG_EDGE_ACTIVE = 1 << 1, - VFLAG_EDGE_SELECTED = 1 << 2, - VFLAG_EDGE_SEAM = 1 << 3, - VFLAG_EDGE_SHARP = 1 << 4, - /* Beware to not go over 1 << 7 - * (see gpu_shader_edit_mesh_overlay_geom.glsl) */ -}; - -static unsigned char mesh_render_data_looptri_flag(MeshRenderData *rdata, const int f) -{ - unsigned char fflag = 0; - - if (rdata->edit_bmesh) { - BMFace *bf = rdata->edit_bmesh->looptris[f][0]->f; - - if (bf == rdata->efa_act) - fflag |= VFLAG_FACE_ACTIVE; - - if (BM_elem_flag_test(bf, BM_ELEM_SELECT)) - fflag |= VFLAG_FACE_SELECTED; - } - - return fflag; -} - -static EdgeDrawAttr *mesh_render_data_edge_flag(MeshRenderData *rdata, const int e) -{ - static EdgeDrawAttr eattr; - memset(&eattr, 0, sizeof(eattr)); - - if (e == -1) { - return &eattr; - } - - /* if edge exists */ - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMEdge *be = NULL; - - be = BM_edge_at_index(bm, e); - - eattr.e_flag |= VFLAG_EDGE_EXISTS; - - if (be == rdata->eed_act) - eattr.e_flag |= VFLAG_EDGE_ACTIVE; - - if (BM_elem_flag_test(be, BM_ELEM_SELECT)) - eattr.e_flag |= VFLAG_EDGE_SELECTED; - - if (BM_elem_flag_test(be, BM_ELEM_SEAM)) - eattr.e_flag |= VFLAG_EDGE_SEAM; - - if (!BM_elem_flag_test(be, BM_ELEM_SMOOTH)) - eattr.e_flag |= VFLAG_EDGE_SHARP; - - /* Use a byte for value range */ - if (rdata->crease_ofs != -1) { - float crease = BM_ELEM_CD_GET_FLOAT(be, rdata->crease_ofs); - if (crease > 0) { - eattr.crease = (char)(crease * 255.0f); - } - } - - /* Use a byte for value range */ - if (rdata->bweight_ofs != -1) { - float bweight = BM_ELEM_CD_GET_FLOAT(be, rdata->bweight_ofs); - if (bweight > 0) { - eattr.bweight = (char)(bweight * 255.0f); - } - } - } - else { - eattr.e_flag |= VFLAG_EDGE_EXISTS; - } - - return &eattr; -} - -static unsigned char mesh_render_data_vertex_flag(MeshRenderData *rdata, const int v) -{ - - unsigned char vflag = 0; - - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMVert *bv = BM_vert_at_index(bm, v); - - /* Current vertex */ - if (bv == rdata->eve_act) - vflag |= VFLAG_VERTEX_ACTIVE; - - if (BM_elem_flag_test(bv, BM_ELEM_SELECT)) - vflag |= VFLAG_VERTEX_SELECTED; - } - - return vflag; -} - -static void add_overlay_tri( - MeshRenderData *rdata, VertexBuffer *vbo, const unsigned int pos_id, const unsigned int edgeMod_id, - const int tri_vert_idx[3], const int tri_edge_idx[3], const int f, const int base_vert_idx) -{ - const float *pos; - EdgeDrawAttr *eattr; - unsigned char fflag; - unsigned char vflag; - - pos = mesh_render_data_vert_co(rdata, tri_vert_idx[0]); - eattr = mesh_render_data_edge_flag(rdata, tri_edge_idx[1]); - fflag = mesh_render_data_looptri_flag(rdata, f); - vflag = mesh_render_data_vertex_flag(rdata, tri_vert_idx[0]); - eattr->v_flag = fflag | vflag; - VertexBuffer_set_attrib(vbo, pos_id, base_vert_idx + 0, pos); - VertexBuffer_set_attrib(vbo, edgeMod_id, base_vert_idx + 0, eattr); - - pos = mesh_render_data_vert_co(rdata, tri_vert_idx[1]); - eattr = mesh_render_data_edge_flag(rdata, tri_edge_idx[2]); - vflag = mesh_render_data_vertex_flag(rdata, tri_vert_idx[1]); - eattr->v_flag = fflag | vflag; - VertexBuffer_set_attrib(vbo, pos_id, base_vert_idx + 1, pos); - VertexBuffer_set_attrib(vbo, edgeMod_id, base_vert_idx + 1, eattr); - - pos = mesh_render_data_vert_co(rdata, tri_vert_idx[2]); - eattr = mesh_render_data_edge_flag(rdata, tri_edge_idx[0]); - vflag = mesh_render_data_vertex_flag(rdata, tri_vert_idx[2]); - eattr->v_flag = fflag | vflag; - VertexBuffer_set_attrib(vbo, pos_id, base_vert_idx + 2, pos); - VertexBuffer_set_attrib(vbo, edgeMod_id, base_vert_idx + 2, eattr); -} - -static void add_overlay_loose_edge( - MeshRenderData *rdata, VertexBuffer *vbo, const unsigned int pos_id, const unsigned int edgeMod_id, - const int v1, const int v2, const int e, const int base_vert_idx) -{ - EdgeDrawAttr *eattr = mesh_render_data_edge_flag(rdata, e); - const float *pos = mesh_render_data_vert_co(rdata, v1); - eattr->v_flag = mesh_render_data_vertex_flag(rdata, v1); - VertexBuffer_set_attrib(vbo, pos_id, base_vert_idx + 0, pos); - VertexBuffer_set_attrib(vbo, edgeMod_id, base_vert_idx + 0, eattr); - - pos = mesh_render_data_vert_co(rdata, v2); - eattr->v_flag = mesh_render_data_vertex_flag(rdata, v2); - VertexBuffer_set_attrib(vbo, pos_id, base_vert_idx + 1, pos); - VertexBuffer_set_attrib(vbo, edgeMod_id, base_vert_idx + 1, eattr); -} - -static void add_overlay_loose_vert( - MeshRenderData *rdata, VertexBuffer *vbo, const unsigned int pos_id, const unsigned int edgeMod_id, - const int v, const int base_vert_idx) -{ - unsigned char vflag[4] = {0, 0, 0, 0}; - const float *pos = mesh_render_data_vert_co(rdata, v); - vflag[0] = mesh_render_data_vertex_flag(rdata, v); - VertexBuffer_set_attrib(vbo, pos_id, base_vert_idx + 0, pos); - VertexBuffer_set_attrib(vbo, edgeMod_id, base_vert_idx + 0, vflag); -} - -/* ---------------------------------------------------------------------- */ -/* Mesh Batch Cache */ - -typedef struct MeshBatchCache { - VertexBuffer *pos_in_order; - VertexBuffer *nor_in_order; - ElementList *edges_in_order; - ElementList *triangles_in_order; - - Batch *all_verts; - Batch *all_edges; - Batch *all_triangles; - - VertexBuffer *pos_with_normals; - Batch *triangles_with_normals; - Batch *points_with_normals; - Batch *fancy_edges; /* owns its vertex buffer (not shared) */ - - /* TODO : split in 2 buffers to avoid unnecessary - * data transfer when selecting/deselecting - * and combine into one batch and use offsets to render - * Tri / edges / verts separately */ - Batch *overlay_triangles; - Batch *overlay_loose_verts; - Batch *overlay_loose_edges; - Batch *overlay_facedots; - - /* settings to determine if cache is invalid */ - bool is_dirty; - int edge_len; - int tri_len; - int poly_len; - int vert_len; - bool is_editmode; -} MeshBatchCache; - -/* Batch cache management. */ - -static bool mesh_batch_cache_valid(Mesh *me) -{ - MeshBatchCache *cache = me->batch_cache; - - if (cache == NULL) { - return false; - } - - if (cache->is_editmode != (me->edit_btmesh != NULL)) { - return false; - } - - if (cache->is_dirty == false) { - return true; - } - else { - if (cache->is_editmode) { - return false; - } - else if ((cache->vert_len != mesh_render_verts_len_get(me)) || - (cache->edge_len != mesh_render_edges_len_get(me)) || - (cache->tri_len != mesh_render_looptri_len_get(me)) || - (cache->poly_len != mesh_render_polys_len_get(me))) - { - return false; - } - } - - return true; -} - -static void mesh_batch_cache_init(Mesh *me) -{ - MeshBatchCache *cache = me->batch_cache; - - if (!cache) { - cache = me->batch_cache = MEM_callocN(sizeof(*cache), __func__); - } - else { - memset(cache, 0, sizeof(*cache)); - } - - cache->is_editmode = me->edit_btmesh != NULL; - - if (cache->is_editmode == false) { - cache->edge_len = mesh_render_edges_len_get(me); - cache->tri_len = mesh_render_looptri_len_get(me); - cache->poly_len = mesh_render_polys_len_get(me); - cache->vert_len = mesh_render_verts_len_get(me); - } - - cache->is_dirty = false; -} - -static MeshBatchCache *mesh_batch_cache_get(Mesh *me) -{ - if (!mesh_batch_cache_valid(me)) { - BKE_mesh_batch_cache_clear(me); - mesh_batch_cache_init(me); - } - return me->batch_cache; -} - -void BKE_mesh_batch_cache_dirty(Mesh *me) -{ - MeshBatchCache *cache = me->batch_cache; - if (cache) { - cache->is_dirty = true; - } -} - -void BKE_mesh_batch_selection_dirty(Mesh *me) -{ - MeshBatchCache *cache = me->batch_cache; - if (cache) { - /* TODO Separate Flag vbo */ - BATCH_DISCARD_ALL_SAFE(cache->overlay_triangles); - BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_verts); - BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_edges); - BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots); - } -} - -void BKE_mesh_batch_cache_clear(Mesh *me) -{ - MeshBatchCache *cache = me->batch_cache; - if (!cache) { - return; - } - - BATCH_DISCARD_SAFE(cache->all_verts); - BATCH_DISCARD_SAFE(cache->all_edges); - BATCH_DISCARD_SAFE(cache->all_triangles); - - VERTEXBUFFER_DISCARD_SAFE(cache->pos_in_order); - ELEMENTLIST_DISCARD_SAFE(cache->edges_in_order); - ELEMENTLIST_DISCARD_SAFE(cache->triangles_in_order); - - BATCH_DISCARD_ALL_SAFE(cache->overlay_triangles); - BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_verts); - BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_edges); - BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots); - - BATCH_DISCARD_SAFE(cache->triangles_with_normals); - BATCH_DISCARD_SAFE(cache->points_with_normals); - VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_normals); - - BATCH_DISCARD_ALL_SAFE(cache->fancy_edges); -} - -void BKE_mesh_batch_cache_free(Mesh *me) -{ - BKE_mesh_batch_cache_clear(me); - MEM_SAFE_FREE(me->batch_cache); -} - -/* Batch cache usage. */ - -static VertexBuffer *mesh_batch_cache_get_pos_and_normals(MeshRenderData *rdata, MeshBatchCache *cache) -{ - BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); - - if (cache->pos_with_normals == NULL) { - unsigned int vidx = 0, nidx = 0; - - static VertexFormat format = { 0 }; - static unsigned int pos_id, nor_id; - if (format.attrib_ct == 0) { - /* initialize vertex format */ - pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); - nor_id = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT); - } - - const int tri_len = mesh_render_data_looptri_len_get(rdata); - - VertexBuffer *vbo = cache->pos_with_normals = VertexBuffer_create_with_format(&format); - - const int vbo_len_capacity = tri_len * 3; - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - - for (int i = 0; i < tri_len; i++) { - float *tri_vert_cos[3]; - short *tri_nor, *tri_vert_nors[3]; - bool is_smooth; - - if (mesh_render_data_looptri_cos_nors_smooth_get( - rdata, i, &tri_vert_cos, &tri_nor, &tri_vert_nors, &is_smooth)) - { - if (is_smooth) { - VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_vert_nors[0]); - VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_vert_nors[1]); - VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_vert_nors[2]); - } - else { - VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor); - VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor); - VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor); - } - - VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[0]); - VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[1]); - VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[2]); - } - } - vbo_len_used = vidx; - - if (vbo_len_capacity != vbo_len_used) { - VertexBuffer_resize_data(vbo, vbo_len_used); - } - } - return cache->pos_with_normals; -} -static VertexBuffer *mesh_batch_cache_get_pos_and_nor_in_order(MeshRenderData *rdata, MeshBatchCache *cache) -{ - BLI_assert(rdata->types & MR_DATATYPE_VERT); - - if (cache->pos_in_order == NULL) { - static VertexFormat format = { 0 }; - static unsigned pos_id, nor_id; - if (format.attrib_ct == 0) { - /* initialize vertex format */ - pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); - nor_id = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT); - } - - VertexBuffer *vbo = cache->pos_in_order = VertexBuffer_create_with_format(&format); - const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata); - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - for (int i = 0; i < vbo_len_capacity; ++i) { - VertexBuffer_set_attrib(vbo, pos_id, i, mesh_render_data_vert_co(rdata, i)); - VertexBuffer_set_attrib(vbo, nor_id, i, mesh_render_data_vert_nor(rdata, i)); - } - } - - return cache->pos_in_order; -} - -static ElementList *mesh_batch_cache_get_edges_in_order(MeshRenderData *rdata, MeshBatchCache *cache) -{ - BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE)); - - if (cache->edges_in_order == NULL) { - printf("Caching edges in order...\n"); - const int vert_len = mesh_render_data_verts_len_get(rdata); - const int edge_len = mesh_render_data_edges_len_get(rdata); - - ElementListBuilder elb; - ElementListBuilder_init(&elb, PRIM_LINES, edge_len, vert_len); - for (int i = 0; i < edge_len; ++i) { - int vert_idx[2]; - if (mesh_render_data_edge_verts_indices_get(rdata, i, vert_idx)) { - add_line_vertices(&elb, vert_idx[0], vert_idx[1]); - } - } - cache->edges_in_order = ElementList_build(&elb); - } - - return cache->edges_in_order; -} - -static ElementList *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdata, MeshBatchCache *cache) -{ - BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); - - if (cache->triangles_in_order == NULL) { - const int vert_len = mesh_render_data_verts_len_get(rdata); - const int tri_len = mesh_render_data_looptri_len_get(rdata); - - ElementListBuilder elb; - ElementListBuilder_init(&elb, PRIM_TRIANGLES, tri_len, vert_len); - for (int i = 0; i < tri_len; ++i) { - int tri_vert_idx[3]; - if (mesh_render_data_looptri_vert_indices_get(rdata, i, tri_vert_idx)) { - add_triangle_vertices(&elb, tri_vert_idx[0], tri_vert_idx[1], tri_vert_idx[2]); - } - } - cache->triangles_in_order = ElementList_build(&elb); - } - - return cache->triangles_in_order; -} - -Batch *BKE_mesh_batch_cache_get_all_edges(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->all_edges == NULL) { - /* create batch from Mesh */ - MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE); - - cache->all_edges = Batch_create(PRIM_LINES, mesh_batch_cache_get_pos_and_nor_in_order(rdata, cache), - mesh_batch_cache_get_edges_in_order(rdata, cache)); - - mesh_render_data_free(rdata); - } - - return cache->all_edges; -} - -Batch *BKE_mesh_batch_cache_get_all_triangles(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->all_triangles == NULL) { - /* create batch from DM */ - MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI); - - cache->all_triangles = Batch_create(PRIM_TRIANGLES, mesh_batch_cache_get_pos_and_nor_in_order(rdata, cache), - mesh_batch_cache_get_triangles_in_order(rdata, cache)); - - mesh_render_data_free(rdata); - } - - return cache->all_triangles; -} - -Batch *BKE_mesh_batch_cache_get_triangles_with_normals(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->triangles_with_normals == NULL) { - MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY); - - cache->triangles_with_normals = Batch_create(PRIM_TRIANGLES, mesh_batch_cache_get_pos_and_normals(rdata, cache), NULL); - - mesh_render_data_free(rdata); - } - - return cache->triangles_with_normals; -} - -Batch *BKE_mesh_batch_cache_get_points_with_normals(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->points_with_normals == NULL) { - MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY); - - cache->points_with_normals = Batch_create(PRIM_POINTS, mesh_batch_cache_get_pos_and_normals(rdata, cache), NULL); - - mesh_render_data_free(rdata); - } - - return cache->points_with_normals; -} - -Batch *BKE_mesh_batch_cache_get_all_verts(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->all_verts == NULL) { - /* create batch from DM */ - MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT); - - cache->all_verts = Batch_create(PRIM_POINTS, mesh_batch_cache_get_pos_and_nor_in_order(rdata, cache), NULL); - - mesh_render_data_free(rdata); - } - - return cache->all_verts; -} - -Batch *BKE_mesh_batch_cache_get_fancy_edges(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->fancy_edges == NULL) { - /* create batch from DM */ - static VertexFormat format = { 0 }; - static unsigned int pos_id, n1_id, n2_id; - if (format.attrib_ct == 0) { - /* initialize vertex format */ - pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); - -#if USE_10_10_10 /* takes 1/3 the space */ - n1_id = VertexFormat_add_attrib(&format, "N1", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT); - n2_id = VertexFormat_add_attrib(&format, "N2", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT); -#else - n1_id = VertexFormat_add_attrib(&format, "N1", COMP_F32, 3, KEEP_FLOAT); - n2_id = VertexFormat_add_attrib(&format, "N2", COMP_F32, 3, KEEP_FLOAT); -#endif - } - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - - MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY); - - const int edge_len = mesh_render_data_edges_len_get(rdata); - - const int vbo_len_capacity = edge_len * 2; /* these are PRIM_LINE verts, not mesh verts */ - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - for (int i = 0; i < edge_len; ++i) { - float *vcos1, *vcos2; - float *pnor1 = NULL, *pnor2 = NULL; - bool is_manifold; - - if (mesh_render_data_edge_vcos_manifold_pnors(rdata, i, &vcos1, &vcos2, &pnor1, &pnor2, &is_manifold)) { - -#if USE_10_10_10 - PackedNormal n1value = { .x = 0, .y = 0, .z = +511 }; - PackedNormal n2value = { .x = 0, .y = 0, .z = -511 }; - - if (is_manifold) { - n1value = convert_i10_v3(pnor1); - n2value = convert_i10_v3(pnor2); - } - - const PackedNormal *n1 = &n1value; - const PackedNormal *n2 = &n2value; -#else - const float dummy1[3] = { 0.0f, 0.0f, +1.0f }; - const float dummy2[3] = { 0.0f, 0.0f, -1.0f }; - - const float *n1 = (is_manifold) ? pnor1 : dummy1; - const float *n2 = (is_manifold) ? pnor2 : dummy2; -#endif - - VertexBuffer_set_attrib(vbo, pos_id, 2 * i, vcos1); - VertexBuffer_set_attrib(vbo, n1_id, 2 * i, n1); - VertexBuffer_set_attrib(vbo, n2_id, 2 * i, n2); - - VertexBuffer_set_attrib(vbo, pos_id, 2 * i + 1, vcos2); - VertexBuffer_set_attrib(vbo, n1_id, 2 * i + 1, n1); - VertexBuffer_set_attrib(vbo, n2_id, 2 * i + 1, n2); - - vbo_len_used += 2; - } - } - if (vbo_len_used != vbo_len_capacity) { - VertexBuffer_resize_data(vbo, vbo_len_used); - } - - cache->fancy_edges = Batch_create(PRIM_LINES, vbo, NULL); - - mesh_render_data_free(rdata); - } - - return cache->fancy_edges; -} - -static void mesh_batch_cache_create_overlay_batches(Mesh *me) -{ - /* Since MR_DATATYPE_OVERLAY is slow to generate, generate them all at once */ - int options = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOPTRI | MR_DATATYPE_OVERLAY; - - MeshBatchCache *cache = mesh_batch_cache_get(me); - MeshRenderData *rdata = mesh_render_data_create(me, options); - - 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, 4, KEEP_INT); - } - - const int tri_len = mesh_render_data_looptri_len_get(rdata); - const int ledge_len = mesh_render_data_loose_edges_len_get(rdata); - const int lvert_len = mesh_render_data_loose_verts_len_get(rdata); - - if (cache->overlay_triangles == NULL) { - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - const int vbo_len_capacity = tri_len * 3; - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - - for (int i = 0; i < tri_len; ++i) { - int tri_vert_idx[3], tri_edge_idx[3]; - if (mesh_render_data_looptri_vert_edge_indices_get(rdata, i, tri_vert_idx, tri_edge_idx)) { - add_overlay_tri( - rdata, vbo, pos_id, data_id, - tri_vert_idx, tri_edge_idx, i, vbo_len_used); - vbo_len_used += 3; - } - } - if (vbo_len_used != vbo_len_capacity) { - VertexBuffer_resize_data(vbo, vbo_len_used); - } - cache->overlay_triangles = Batch_create(PRIM_TRIANGLES, vbo, NULL); - } - - if (cache->overlay_loose_edges == NULL) { - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - const int vbo_len_capacity = ledge_len * 2; - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - - for (int i = 0; i < ledge_len; ++i) { - int vert_idx[2]; - bool ok = mesh_render_data_edge_verts_indices_get(rdata, rdata->loose_edges[i], vert_idx); - assert(ok); /* we don't add */ - add_overlay_loose_edge( - rdata, vbo, pos_id, data_id, - vert_idx[0], vert_idx[1], rdata->loose_edges[i], vbo_len_used); - vbo_len_used += 2; - } - BLI_assert(vbo_len_used == vbo_len_capacity); - cache->overlay_loose_edges = Batch_create(PRIM_LINES, vbo, NULL); - } - - if (cache->overlay_loose_verts == NULL) { - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - const int vbo_len_capacity = lvert_len; - int vbo_len_used = 0; - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - - for (int i = 0; i < lvert_len; ++i) { - add_overlay_loose_vert(rdata, vbo, pos_id, data_id, - rdata->loose_verts[i], vbo_len_used); - vbo_len_used += 1; - } - BLI_assert(vbo_len_used == vbo_len_capacity); - cache->overlay_loose_verts = Batch_create(PRIM_POINTS, vbo, NULL); - } - - mesh_render_data_free(rdata); -} - -Batch *BKE_mesh_batch_cache_get_overlay_triangles(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->overlay_triangles == NULL) { - mesh_batch_cache_create_overlay_batches(me); - } - - return cache->overlay_triangles; -} - -Batch *BKE_mesh_batch_cache_get_overlay_loose_edges(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->overlay_loose_edges == NULL) { - mesh_batch_cache_create_overlay_batches(me); - } - - return cache->overlay_loose_edges; -} - -Batch *BKE_mesh_batch_cache_get_overlay_loose_verts(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->overlay_loose_verts == NULL) { - mesh_batch_cache_create_overlay_batches(me); - } - - return cache->overlay_loose_verts; -} - -Batch *BKE_mesh_batch_cache_get_overlay_facedots(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->overlay_facedots == NULL) { - MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY); - - 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); -#if USE_10_10_10 - data_id = VertexFormat_add_attrib(&format, "norAndFlag", COMP_I10, 4, NORMALIZE_INT_TO_FLOAT); -#else - data_id = VertexFormat_add_attrib(&format, "norAndFlag", COMP_F32, 4, KEEP_FLOAT); -#endif - } - - const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata); - int vbo_len_used = 0; - - VertexBuffer *vbo = VertexBuffer_create_with_format(&format); - VertexBuffer_allocate_data(vbo, vbo_len_capacity); - - for (int i = 0; i < vbo_len_capacity; ++i) { - float pcenter[3], pnor[3]; - bool selected = false; - - if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) { - -#if USE_10_10_10 - PackedNormal nor = { .x = 0, .y = 0, .z = -511 }; - nor = convert_i10_v3(pnor); - nor.w = selected ? 1 : 0; - VertexBuffer_set_attrib(vbo, data_id, i, &nor); -#else - float nor[4] = {pnor[0], pnor[1], pnor[2], selected ? 1 : 0}; - VertexBuffer_set_attrib(vbo, data_id, i, nor); -#endif - - VertexBuffer_set_attrib(vbo, pos_id, i, pcenter); - - vbo_len_used += 1; - } - } - if (vbo_len_used != vbo_len_capacity) { - VertexBuffer_resize_data(vbo, vbo_len_used); - } - - cache->overlay_facedots = Batch_create(PRIM_POINTS, vbo, NULL); - - mesh_render_data_free(rdata); - } - - return cache->overlay_facedots; -} - -#undef MESH_RENDER_FUNCTION diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 3d9bbc338ea..b4cf9b16247 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -43,6 +43,7 @@ #include "BKE_armature.h" #include "BKE_action.h" #include "BKE_constraint.h" +#include "BKE_curve.h" #include "BKE_DerivedMesh.h" #include "BKE_animsys.h" #include "BKE_displist.h" @@ -56,12 +57,9 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_material.h" +#include "BKE_mesh.h" #include "BKE_image.h" -#include "BKE_curve_render.h" -#include "BKE_lattice_render.h" -#include "BKE_mesh_render.h" - #include "DEG_depsgraph.h" #define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf @@ -347,15 +345,15 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx, switch (ob->type) { case OB_MESH: - BKE_mesh_batch_cache_dirty(ob->data); + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); break; case OB_LATTICE: - BKE_lattice_batch_cache_dirty(ob->data); + BKE_lattice_batch_cache_dirty(ob->data, BKE_LATTICE_BATCH_DIRTY_ALL); break; case OB_CURVE: case OB_FONT: case OB_SURF: - BKE_curve_batch_cache_dirty(ob->data); + BKE_curve_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_ALL); break; } |