Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h10
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c1130
-rw-r--r--source/blender/editors/space_view3d/drawobject.c131
3 files changed, 667 insertions, 604 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 385147039d6..dfdbd7f47e7 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -125,11 +125,11 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edit_loose_edges_nor(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_edit_loose_verts(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(struct Mesh *me);
/* edit-mesh selection */
-struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset);
-struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide);
-struct GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me, uint select_id_offset);
-struct GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me, uint select_id_offset);
-struct GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me, uint select_id_offset);
+struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me);
/* Object mode Wireframe overlays */
struct GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(struct Mesh *me);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index be37787ae7c..6e28bd6a916 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1236,6 +1236,12 @@ static int mesh_render_data_loops_len_get(const MeshRenderData *rdata)
return rdata->loop_len;
}
+static int mesh_render_data_loops_len_get_maybe_mapped(const MeshRenderData *rdata)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_LOOP);
+ return ((rdata->mapped.use == false) ? rdata->loop_len : rdata->mapped.loop_len);
+}
+
static int mesh_render_data_polys_len_get(const MeshRenderData *rdata)
{
BLI_assert(rdata->types & MR_DATATYPE_POLY);
@@ -1952,7 +1958,7 @@ static bool drw_mesh_weight_state_compare(const struct DRW_MeshWeightState *a, c
}
static void drw_mesh_weight_state_extract(
- Object *ob, Mesh *me, ToolSettings *ts, bool paint_mode,
+ Object *ob, Mesh *me, const ToolSettings *ts, bool paint_mode,
struct DRW_MeshWeightState *wstate)
{
/* Extract complete vertex weight group selection state and mode flags. */
@@ -2022,6 +2028,12 @@ typedef struct MeshBatchCache {
GPUVertBuf *data_ledges;
GPUVertBuf *data_lverts;
GPUVertBuf *lnor;
+ /* Selection */
+ GPUVertBuf *loop_pos;
+ GPUVertBuf *loop_vert_idx;
+ GPUVertBuf *loop_edge_idx;
+ GPUVertBuf *loop_face_idx;
+ GPUVertBuf *facedots_idx;
} edit;
/* Index Buffers:
@@ -2038,6 +2050,10 @@ typedef struct MeshBatchCache {
/* Contains indices to unique edit vertices to not
* draw the same vert multiple times (because of tesselation). */
GPUIndexBuf *edit_verts_points;
+ /* Edit mode selection. */
+ GPUIndexBuf *edit_loops_points; /* verts */
+ GPUIndexBuf *edit_loops_lines; /* edges */
+ GPUIndexBuf *edit_loops_tris; /* faces */
} ibo;
struct {
@@ -2053,6 +2069,11 @@ typedef struct MeshBatchCache {
GPUBatch *edit_triangles_lnor;
GPUBatch *edit_loose_edges_nor;
GPUBatch *edit_facedots;
+ /* Edit selection */
+ GPUBatch *edit_selection_verts;
+ GPUBatch *edit_selection_edges;
+ GPUBatch *edit_selection_faces;
+ GPUBatch *edit_selection_facedots;
/* Common display / Other */
GPUBatch *all_verts;
GPUBatch *all_edges;
@@ -2729,460 +2750,327 @@ static void mesh_create_pos_and_nor_tess(MeshRenderData *rdata, GPUVertBuf *vbo,
}
}
-static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
- MeshRenderData *rdata, const bool use_hide,
- GPUVertBuf **r_vbo)
+BLI_INLINE void mesh_edit_add_select_index(GPUVertBufRaw *buf, GPUVertCompType comp, uint index)
{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
-
- if (*r_vbo == NULL) {
- *r_vbo = GPU_vertbuf_create(GPU_USAGE_STATIC);
- mesh_create_pos_and_nor_tess(rdata, *r_vbo, use_hide);
+ /* We don't need to sanitize the value because the elements
+ * with these undefined values will never get drawn. */
+ switch (comp) {
+ case GPU_COMP_U32:
+ *((uint *)GPU_vertbuf_raw_step(buf)) = index;
+ break;
+ case GPU_COMP_U16:
+ *((ushort *)GPU_vertbuf_raw_step(buf)) = (ushort)index;
+ break;
+ case GPU_COMP_U8:
+ *((uchar *)GPU_vertbuf_raw_step(buf)) = (uchar)index;
+ break;
+ default:
+ BLI_assert(0);
+ break;
}
- return *r_vbo;
}
-static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_edit(
- MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
-{
- return mesh_batch_cache_get_tri_pos_and_normals_ex(
- rdata, use_hide,
- use_hide ? &cache->pos_with_normals_visible_only_edit : &cache->pos_with_normals_edit);
-}
+#define SELECT_COMP_FORMAT(el_len) (el_len > 0xFF ? (el_len > 0xFFFF ? GPU_COMP_U32 : GPU_COMP_U16) : GPU_COMP_U8)
-/* DEPRECATED Need to be ported */
-static GPUVertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag(
- MeshRenderData *rdata, MeshBatchCache *cache)
-{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
-
- if (cache->edit.pos_nor_data_facedots == NULL) {
- cache->edit.pos_nor_data_facedots = GPU_vertbuf_create(GPU_USAGE_STATIC);
- mesh_create_edit_facedots(rdata, cache->edit.pos_nor_data_facedots);
- }
-
- return cache->edit.pos_nor_data_facedots;
-}
-
-static GPUVertBuf *mesh_batch_cache_get_edges_visible(
- MeshRenderData *rdata, MeshBatchCache *cache)
+static void mesh_create_edit_select_id(
+ MeshRenderData *rdata,
+ GPUVertBuf *vbo_pos, GPUVertBuf *vbo_verts, GPUVertBuf *vbo_edges, GPUVertBuf *vbo_faces)
{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
-
- if (cache->ed_edge_pos == NULL) {
- static GPUVertFormat format = { 0 };
- static struct { uint pos, data; } attr_id;
- if (format.attr_len == 0) {
- attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- }
-
- const int vbo_len_capacity = mesh_render_data_edges_len_get_maybe_mapped(rdata) * 2;
- int vidx = 0;
-
- GPUVertBuf *vbo = cache->ed_edge_pos = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
-
- if (rdata->mapped.use == false) {
- if (rdata->edit_bmesh) {
- BMesh *bm = rdata->edit_bmesh->bm;
- BMIter iter;
- BMEdge *eed;
+ const int vert_len = mesh_render_data_verts_len_get_maybe_mapped(rdata);
+ const int edge_len = mesh_render_data_edges_len_get_maybe_mapped(rdata);
+ const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata);
+ const int lvert_len = mesh_render_data_loose_verts_len_get_maybe_mapped(rdata);
+ const int ledge_len = mesh_render_data_loose_edges_len_get_maybe_mapped(rdata);
+ const int loop_len = mesh_render_data_loops_len_get_maybe_mapped(rdata);
+ const int tot_loop_len = loop_len + ledge_len * 2 + lvert_len;
+
+ /* Choose the most compact vertex format. */
+ GPUVertCompType vert_comp = SELECT_COMP_FORMAT(vert_len);
+ GPUVertCompType edge_comp = SELECT_COMP_FORMAT(edge_len);
+ GPUVertCompType face_comp = SELECT_COMP_FORMAT(poly_len);
+
+ GPUVertFormat format_vert = { 0 }, format_edge = { 0 }, format_face = { 0 }, format_pos = { 0 };
+ struct { uint vert, edge, face, pos; } attr_id;
+ attr_id.vert = GPU_vertformat_attr_add(&format_vert, "color", vert_comp, 1, GPU_FETCH_INT);
+ attr_id.edge = GPU_vertformat_attr_add(&format_edge, "color", edge_comp, 1, GPU_FETCH_INT);
+ attr_id.face = GPU_vertformat_attr_add(&format_face, "color", face_comp, 1, GPU_FETCH_INT);
+ attr_id.pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ GPUVertBufRaw raw_verts, raw_edges, raw_faces, raw_pos;
+ if (DRW_TEST_ASSIGN_VBO(vbo_pos)) {
+ GPU_vertbuf_init_with_format(vbo_pos, &format_pos);
+ GPU_vertbuf_data_alloc(vbo_pos, tot_loop_len);
+ GPU_vertbuf_attr_get_raw_data(vbo_pos, attr_id.pos, &raw_pos);
+ }
+ if (DRW_TEST_ASSIGN_VBO(vbo_verts)) {
+ GPU_vertbuf_init_with_format(vbo_verts, &format_vert);
+ GPU_vertbuf_data_alloc(vbo_verts, tot_loop_len);
+ GPU_vertbuf_attr_get_raw_data(vbo_verts, attr_id.vert, &raw_verts);
+ }
+ if (DRW_TEST_ASSIGN_VBO(vbo_edges)) {
+ GPU_vertbuf_init_with_format(vbo_edges, &format_edge);
+ GPU_vertbuf_data_alloc(vbo_edges, tot_loop_len);
+ GPU_vertbuf_attr_get_raw_data(vbo_edges, attr_id.edge, &raw_edges);
+ }
+ if (DRW_TEST_ASSIGN_VBO(vbo_faces)) {
+ GPU_vertbuf_init_with_format(vbo_faces, &format_face);
+ GPU_vertbuf_data_alloc(vbo_faces, tot_loop_len);
+ GPU_vertbuf_attr_get_raw_data(vbo_faces, attr_id.face, &raw_faces);
+ }
+
+ if (rdata->edit_bmesh && rdata->mapped.use == false) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter_efa, iter_loop, iter_edge, iter_vert;
+ BMFace *efa;
+ BMEdge *eed;
+ BMVert *eve;
+ BMLoop *loop;
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co);
- vidx += 1;
- GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co);
- vidx += 1;
- }
+ /* Face Loops */
+ BM_ITER_MESH (efa, &iter_efa, bm, BM_FACES_OF_MESH) {
+ int fidx = BM_elem_index_get(efa);
+ BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) {
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), loop->v->co);
}
- }
- else {
- /* not yet done! */
- BLI_assert(0);
- }
- }
- else {
- BMesh *bm = rdata->edit_bmesh->bm;
- const MVert *mvert = rdata->mapped.me_cage->mvert;
- const MEdge *medge = rdata->mapped.me_cage->medge;
- const int *e_origindex = rdata->mapped.e_origindex;
- for (int i = 0; i < rdata->mapped.edge_len; i++) {
- const int e_orig = e_origindex[i];
- if (e_orig != ORIGINDEX_NONE) {
- BMEdge *eed = BM_edge_at_index(bm, e_orig);
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- const MEdge *ed = &medge[i];
- GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mvert[ed->v1].co);
- vidx += 1;
- GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mvert[ed->v2].co);
- vidx += 1;
- }
+ if (vbo_verts) {
+ int vidx = BM_elem_index_get(loop->v);
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
}
- }
- }
- const int vbo_len_used = vidx;
- if (vbo_len_used != vbo_len_capacity) {
- GPU_vertbuf_data_resize(vbo, vbo_len_used);
- }
- UNUSED_VARS_NDEBUG(vbo_len_used);
- }
-
- return cache->ed_edge_pos;
-}
-
-static GPUVertBuf *mesh_batch_cache_get_verts_visible(
- MeshRenderData *rdata, MeshBatchCache *cache)
-{
- BLI_assert(rdata->types & MR_DATATYPE_VERT);
-
- if (cache->ed_vert_pos == NULL) {
- static GPUVertFormat format = { 0 };
- static struct { uint pos, data; } attr_id;
- if (format.attr_len == 0) {
- attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- }
-
- const int vbo_len_capacity = mesh_render_data_verts_len_get_maybe_mapped(rdata);
- uint vidx = 0;
-
- GPUVertBuf *vbo = cache->ed_vert_pos = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
- if (rdata->mapped.use == false) {
- if (rdata->edit_bmesh) {
- BMesh *bm = rdata->edit_bmesh->bm;
- BMIter iter;
- BMVert *eve;
-
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co);
- vidx += 1;
- }
+ if (vbo_edges) {
+ int eidx = BM_elem_index_get(loop->e);
+ mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
}
- }
- else {
- for (int i = 0; i < vbo_len_capacity; i++) {
- const MVert *mv = &rdata->mvert[i];
- if (!(mv->flag & ME_HIDE)) {
- GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co);
- vidx += 1;
- }
+ if (vbo_faces) {
+ mesh_edit_add_select_index(&raw_faces, face_comp, fidx);
}
}
}
- else {
- BMesh *bm = rdata->edit_bmesh->bm;
- const MVert *mvert = rdata->mapped.me_cage->mvert;
- const int *v_origindex = rdata->mapped.v_origindex;
- for (int i = 0; i < vbo_len_capacity; i++) {
- const int v_orig = v_origindex[i];
- if (v_orig != ORIGINDEX_NONE) {
- BMVert *eve = BM_vert_at_index(bm, v_orig);
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- const MVert *mv = &mvert[i];
- GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co);
- vidx += 1;
- }
+ /* Loose edges */
+ BM_ITER_MESH (eed, &iter_edge, bm, BM_EDGES_OF_MESH) {
+ if (eed->l != NULL) {
+ continue;
+ }
+ BM_ITER_ELEM (eve, &iter_vert, eed, BM_VERTS_OF_EDGE) {
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), eve->co);
+ }
+ if (vbo_verts) {
+ int vidx = BM_elem_index_get(eve);
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
+ }
+ if (vbo_edges) {
+ int eidx = BM_elem_index_get(eed);
+ mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
}
}
}
- const uint vbo_len_used = vidx;
- if (vbo_len_used != vbo_len_capacity) {
- GPU_vertbuf_data_resize(vbo, vbo_len_used);
+ /* Loose verts */
+ BM_ITER_MESH (eve, &iter_vert, bm, BM_VERTS_OF_MESH) {
+ if (eve->e != NULL) {
+ continue;
+ }
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), eve->co);
+ }
+ if (vbo_verts) {
+ int vidx = BM_elem_index_get(eve);
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
+ }
}
-
- UNUSED_VARS_NDEBUG(vbo_len_used);
}
+ else if (rdata->mapped.use == true) {
+ const MPoly *mpoly = rdata->mapped.me_cage->mpoly;
+ const MEdge *medge = rdata->mapped.me_cage->medge;
+ const MVert *mvert = rdata->mapped.me_cage->mvert;
+ const MLoop *mloop = rdata->mapped.me_cage->mloop;
+ BMesh *bm = rdata->edit_bmesh->bm;
- return cache->ed_vert_pos;
-}
-
-static GPUVertBuf *mesh_create_facedot_select_id(
- MeshRenderData *rdata, uint select_id_offset)
-{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
-
- GPUVertBuf *vbo;
- {
- static GPUVertFormat format = { 0 };
- static struct { uint pos, col; } attr_id;
- if (format.attr_len == 0) {
- attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
- }
-
- const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
- int vidx = 0;
-
- vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
- uint select_index = select_id_offset;
-
- if (rdata->edit_bmesh) {
- BMesh *bm = rdata->edit_bmesh->bm;
- BMIter iter;
- BMEdge *efa;
+ const int *v_origindex = rdata->mapped.v_origindex;
+ const int *e_origindex = rdata->mapped.e_origindex;
+ const int *p_origindex = rdata->mapped.p_origindex;
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- int select_id;
- GPU_select_index_get(select_index, &select_id);
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
+ /* Face Loops */
+ for (int poly = 0; poly < poly_len; poly++, mpoly++) {
+ const MLoop *l = &mloop[mpoly->loopstart];
+ int fidx = p_origindex[poly];
+ for (int i = 0; i < mpoly->totloop; i++, l++) {
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[l->v].co);
+ }
+ if (vbo_verts) {
+ int vidx = v_origindex[l->v];
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
+ }
+ if (vbo_edges) {
+ int eidx = e_origindex[l->e];
+ mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
+ }
+ if (vbo_faces) {
+ mesh_edit_add_select_index(&raw_faces, face_comp, fidx);
}
- select_index += 1;
}
}
- else {
- /* not yet done! */
- BLI_assert(0);
- }
- const int vbo_len_used = vidx;
- if (vbo_len_used != vbo_len_capacity) {
- GPU_vertbuf_data_resize(vbo, vbo_len_used);
- }
- }
-
- return vbo;
-}
-
-static GPUVertBuf *mesh_create_edges_select_id(
- MeshRenderData *rdata, uint select_id_offset)
-{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
-
- GPUVertBuf *vbo;
- {
- static GPUVertFormat format = { 0 };
- static struct { uint pos, col; } attr_id;
- if (format.attr_len == 0) {
- attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
- }
-
- const int vbo_len_capacity = mesh_render_data_edges_len_get_maybe_mapped(rdata) * 2;
- int vidx = 0;
-
- vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
-
- if (rdata->mapped.use == false) {
- uint select_index = select_id_offset;
- if (rdata->edit_bmesh) {
- BMesh *bm = rdata->edit_bmesh->bm;
- BMIter iter;
- BMEdge *eed;
-
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- int select_id;
- GPU_select_index_get(select_index, &select_id);
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
+ /* Loose edges */
+ for (int e = 0; e < edge_len; e++, medge++) {
+ int eidx = e_origindex[e];
+ if (eidx != ORIGINDEX_NONE && (medge->flag & ME_LOOSEEDGE)) {
+ for (int i = 0; i < 2; ++i) {
+ int vidx = (i == 0) ? medge->v1 : medge->v2;
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[vidx].co);
+ }
+ if (vbo_verts) {
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
+ }
+ if (vbo_edges) {
+ mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
}
- select_index += 1;
}
}
- else {
- /* not yet done! */
- BLI_assert(0);
- }
}
- else {
- BMesh *bm = rdata->edit_bmesh->bm;
- const int *e_origindex = rdata->mapped.e_origindex;
- for (int i = 0; i < rdata->mapped.edge_len; i++) {
- const int e_orig = e_origindex[i];
- if (e_orig != ORIGINDEX_NONE) {
- BMEdge *eed = BM_edge_at_index(bm, e_orig);
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- uint select_index = select_id_offset + e_orig;
- int select_id;
- GPU_select_index_get(select_index, &select_id);
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
+ /* Loose verts */
+ for (int v = 0; v < vert_len; v++, mvert++) {
+ int vidx = v_origindex[v];
+ if (vidx != ORIGINDEX_NONE) {
+ BMVert *eve = BM_vert_at_index(bm, vidx);
+ if (eve->e == NULL) {
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert->co);
+ }
+ if (vbo_verts) {
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
}
}
}
}
- const int vbo_len_used = vidx;
- if (vbo_len_used != vbo_len_capacity) {
- GPU_vertbuf_data_resize(vbo, vbo_len_used);
- }
}
+ else {
+ const MPoly *mpoly = rdata->mpoly;
+ const MVert *mvert = rdata->mvert;
+ const MLoop *mloop = rdata->mloop;
- return vbo;
-}
-
-static GPUVertBuf *mesh_create_verts_select_id(
- MeshRenderData *rdata, uint select_id_offset)
-{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
-
- GPUVertBuf *vbo;
- {
- static GPUVertFormat format = { 0 };
- static struct { uint pos, col; } attr_id;
- if (format.attr_len == 0) {
- attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
- }
-
- const int vbo_len_capacity = mesh_render_data_verts_len_get_maybe_mapped(rdata);
- int vidx = 0;
-
- vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
-
- if (rdata->mapped.use == false) {
- uint select_index = select_id_offset;
- if (rdata->edit_bmesh) {
- BMesh *bm = rdata->edit_bmesh->bm;
- BMIter iter;
- BMVert *eve;
-
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- int select_id;
- GPU_select_index_get(select_index, &select_id);
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
- }
- select_index += 1;
+ const int *v_origindex = CustomData_get_layer(&rdata->me->vdata, CD_ORIGINDEX);
+ const int *e_origindex = CustomData_get_layer(&rdata->me->edata, CD_ORIGINDEX);
+ const int *p_origindex = CustomData_get_layer(&rdata->me->pdata, CD_ORIGINDEX);
+
+ /* Face Loops */
+ for (int poly = 0; poly < poly_len; poly++, mpoly++) {
+ const MLoop *l = &mloop[mpoly->loopstart];
+ int fidx = p_origindex ? p_origindex[poly] : poly;
+ for (int i = 0; i < mpoly->totloop; i++, l++) {
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[l->v].co);
+ }
+ if (vbo_verts) {
+ int vidx = v_origindex ? v_origindex[l->v] : l->v;
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
+ }
+ if (vbo_edges) {
+ int eidx = e_origindex ? e_origindex[l->e] : l->e;
+ mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
+ }
+ if (vbo_faces) {
+ mesh_edit_add_select_index(&raw_faces, face_comp, fidx);
}
}
- else {
- for (int i = 0; i < vbo_len_capacity; i++) {
- const MVert *mv = &rdata->mvert[i];
- if (!(mv->flag & ME_HIDE)) {
- int select_id;
- GPU_select_index_get(select_index, &select_id);
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
+ }
+ /* TODO(fclem): Until we find a way to detect
+ * loose verts easily outside of edit mode, this
+ * will remain disabled. */
+#if 0
+ /* Loose edges */
+ for (int e = 0; e < edge_len; e++, medge++) {
+ int eidx = e_origindex[e];
+ if (eidx != ORIGINDEX_NONE && (medge->flag & ME_LOOSEEDGE)) {
+ for (int i = 0; i < 2; ++i) {
+ int vidx = (i == 0) ? medge->v1 : medge->v2;
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[vidx].co);
+ }
+ if (vbo_verts) {
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
+ }
+ if (vbo_edges) {
+ mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
}
- select_index += 1;
}
}
}
- else {
- BMesh *bm = rdata->edit_bmesh->bm;
- const int *v_origindex = rdata->mapped.v_origindex;
- for (int i = 0; i < vbo_len_capacity; i++) {
- const int v_orig = v_origindex[i];
- if (v_orig != ORIGINDEX_NONE) {
- BMVert *eve = BM_vert_at_index(bm, v_orig);
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- uint select_index = select_id_offset + v_orig;
- int select_id;
- GPU_select_index_get(select_index, &select_id);
- GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
- vidx += 1;
+ /* Loose verts */
+ for (int v = 0; v < vert_len; v++, mvert++) {
+ int vidx = v_origindex[v];
+ if (vidx != ORIGINDEX_NONE) {
+ MVert *eve = BM_vert_at_index(bm, vidx);
+ if (eve->e == NULL) {
+ if (vbo_pos) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert->co);
+ }
+ if (vbo_verts) {
+ mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
}
}
}
}
- const int vbo_len_used = vidx;
- if (vbo_len_used != vbo_len_capacity) {
- GPU_vertbuf_data_resize(vbo, vbo_len_used);
- }
+#endif
}
-
- return vbo;
+ /* Don't resize */
}
-static GPUVertBuf *mesh_create_tri_select_id(
- MeshRenderData *rdata, bool use_hide, uint select_id_offset)
+/* TODO: We could use gl_PrimitiveID as index instead of using another VBO. */
+static void mesh_create_edit_facedots_select_id(
+ MeshRenderData *rdata,
+ GPUVertBuf *vbo)
{
- BLI_assert(
- rdata->types &
- (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
-
- GPUVertBuf *vbo;
- {
- uint cidx = 0;
-
- static GPUVertFormat format = { 0 };
- static struct { uint col; } attr_id;
- if (format.attr_len == 0) {
- attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
- }
-
- const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata);
-
- vbo = GPU_vertbuf_create_with_format(&format);
+ const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata);
- const int vbo_len_capacity = tri_len * 3;
- int vbo_len_used = 0;
- GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ GPUVertCompType comp = SELECT_COMP_FORMAT(poly_len);
+ GPUVertFormat format = { 0 };
+ struct { uint idx; } attr_id;
+ attr_id.idx = GPU_vertformat_attr_add(&format, "color", comp, 1, GPU_FETCH_INT);
- if (rdata->mapped.use == false) {
- if (rdata->edit_bmesh) {
- for (int i = 0; i < tri_len; i++) {
- const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
- /* Assume 'use_hide' */
- if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
- const int poly_index = BM_elem_index_get(ltri[0]->f);
- int select_id;
- GPU_select_index_get(poly_index + select_id_offset, &select_id);
- for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
- GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
- }
- }
- }
- }
- else {
- const int *p_origindex = NULL;
- if (rdata->me != NULL) {
- p_origindex = CustomData_get_layer(&rdata->me->pdata, CD_ORIGINDEX);
- }
+ GPUVertBufRaw idx_step;
+ GPU_vertbuf_init_with_format(vbo, &format);
+ GPU_vertbuf_data_alloc(vbo, poly_len);
+ GPU_vertbuf_attr_get_raw_data(vbo, attr_id.idx, &idx_step);
- for (int i = 0; i < tri_len; i++) {
- const MLoopTri *mlt = &rdata->mlooptri[i];
- const int poly_index = mlt->poly;
- if (!(use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE))) {
- int orig_index = p_origindex ? p_origindex[poly_index] : poly_index;
- if (orig_index != ORIGINDEX_NONE) {
- int select_id;
- GPU_select_index_get(orig_index + select_id_offset, &select_id);
- for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
- GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
- }
- }
- }
+ /* Keep in sync with mesh_create_edit_facedots(). */
+ if (rdata->mapped.use == false) {
+ if (rdata->edit_bmesh) {
+ for (int poly = 0; poly < poly_len; poly++) {
+ const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, poly);
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ mesh_edit_add_select_index(&idx_step, comp, poly);
}
}
}
else {
- BMesh *bm = rdata->edit_bmesh->bm;
- Mesh *me_cage = rdata->mapped.me_cage;
- const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage);
- for (int i = 0; i < tri_len; i++) {
- const MLoopTri *mlt = &mlooptri[i];
- const int p_orig = rdata->mapped.p_origindex[mlt->poly];
- if (p_orig != ORIGINDEX_NONE) {
- /* Assume 'use_hide' */
- BMFace *efa = BM_face_at_index(bm, p_orig);
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- int select_id;
- GPU_select_index_get(select_id_offset + p_orig, &select_id);
- for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
- GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
- }
- }
+ for (int poly = 0; poly < poly_len; poly++) {
+ mesh_edit_add_select_index(&idx_step, comp, poly);
+ }
+ }
+ }
+ else {
+ const int *p_origindex = rdata->mapped.p_origindex;
+ for (int poly = 0; poly < poly_len; poly++) {
+ const int p_orig = p_origindex[poly];
+ if (p_orig != ORIGINDEX_NONE) {
+ const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, p_orig);
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ mesh_edit_add_select_index(&idx_step, comp, poly);
}
}
}
- vbo_len_used = cidx;
+ }
- if (vbo_len_capacity != vbo_len_used) {
- GPU_vertbuf_data_resize(vbo, vbo_len_used);
- }
+ /* Resize & Finish */
+ int facedot_len_used = GPU_vertbuf_raw_used(&idx_step);
+ if (facedot_len_used != poly_len) {
+ GPU_vertbuf_data_resize(vbo, facedot_len_used);
}
- return vbo;
}
+#undef SELECT_COMP_FORMAT
static void mesh_create_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
{
@@ -3261,7 +3149,7 @@ static void mesh_create_weights(MeshRenderData *rdata, GPUVertBuf *vbo, DRW_Mesh
GPU_vertbuf_attr_fill(vbo, attr_id.weight, vert_weight);
}
-static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo, const bool use_face_sel)
+static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
{
/* TODO deduplicate format creation*/
static GPUVertFormat format = { 0 };
@@ -3330,6 +3218,7 @@ static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo,
const MLoop *mloop = rdata->mloop + mpoly->loopstart;
const float (*lnors)[3] = (rdata->loop_normals) ? &rdata->loop_normals[mpoly->loopstart] : NULL;
const GPUPackedNormal *fnor = (mpoly->flag & ME_SMOOTH) ? NULL : &rdata->poly_normals_pack[a];
+ const int hide_select_flag = (mpoly->flag & ME_HIDE) ? -1 : ((mpoly->flag & ME_FACE_SEL) ? 1 : 0);
for (int b = 0; b < mpoly->totloop; b++, mloop++) {
copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop->v].co);
GPUPackedNormal *pnor = (GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step);
@@ -3342,9 +3231,7 @@ static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo,
else {
*pnor = GPU_normal_convert_i10_s3(mvert[mloop->v].no);
}
- if (use_face_sel) {
- pnor->w = (mpoly->flag & ME_HIDE) ? -1 : ((mpoly->flag & ME_FACE_SEL) ? 1 : 0);
- }
+ pnor->w = hide_select_flag;
}
}
@@ -4424,6 +4311,267 @@ static void mesh_create_loops_tris(
}
}
+static void mesh_create_edit_loops_points_lines(MeshRenderData *rdata, GPUIndexBuf *ibo_verts, GPUIndexBuf *ibo_edges)
+{
+ BMIter iter_efa, iter_loop, iter_edge, iter_vert;
+ BMFace *efa;
+ BMEdge *eed;
+ BMVert *eve;
+ BMLoop *loop;
+ int i;
+
+ const int loop_len = mesh_render_data_loops_len_get_maybe_mapped(rdata);
+ const int edge_len = mesh_render_data_edges_len_get_maybe_mapped(rdata);
+ const int vert_len = mesh_render_data_verts_len_get_maybe_mapped(rdata);
+ const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata);
+ const int lvert_len = mesh_render_data_loose_verts_len_get_maybe_mapped(rdata);
+ const int ledge_len = mesh_render_data_loose_edges_len_get_maybe_mapped(rdata);
+ const int tot_loop_len = loop_len + ledge_len * 2 + lvert_len;
+
+ GPUIndexBufBuilder elb_vert, elb_edge;
+ if (DRW_TEST_ASSIGN_IBO(ibo_edges)) {
+ GPU_indexbuf_init(&elb_edge, GPU_PRIM_LINES, loop_len + ledge_len, tot_loop_len);
+ }
+ if (DRW_TEST_ASSIGN_IBO(ibo_verts)) {
+ GPU_indexbuf_init(&elb_vert, GPU_PRIM_POINTS, tot_loop_len, tot_loop_len);
+ }
+
+ int loop_idx = 0;
+ if (rdata->edit_bmesh && (rdata->mapped.use == false)) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ /* Face Loops */
+ BM_ITER_MESH (efa, &iter_efa, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ BM_ITER_ELEM_INDEX (loop, &iter_loop, efa, BM_LOOPS_OF_FACE, i) {
+ if (ibo_verts) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx + i);
+ }
+ if (ibo_edges) {
+ int v1 = loop_idx + i;
+ int v2 = loop_idx + ((i + 1) % efa->len);
+ GPU_indexbuf_add_line_verts(&elb_edge, v1, v2);
+ }
+ }
+ }
+ loop_idx += efa->len;
+ }
+ /* Loose edges */
+ if (ibo_verts || ibo_edges) {
+ BM_ITER_MESH (eed, &iter_edge, bm, BM_EDGES_OF_MESH) {
+ if (eed->l == NULL) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ if (ibo_verts) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx + 0);
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx + 1);
+ }
+ if (ibo_edges) {
+ GPU_indexbuf_add_line_verts(&elb_edge, loop_idx + 0, loop_idx + 1);
+ }
+ }
+ loop_idx += 2;
+ }
+ }
+ }
+ /* Loose verts */
+ if (ibo_verts) {
+ BM_ITER_MESH (eve, &iter_vert, bm, BM_VERTS_OF_MESH) {
+ if (eve->e == NULL) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx);
+ }
+ loop_idx += 1;
+ }
+ }
+ }
+ }
+ else if (rdata->mapped.use) {
+ const MPoly *mpoly = rdata->mapped.me_cage->mpoly;
+ const MEdge *medge = rdata->mapped.me_cage->medge;
+ BMesh *bm = rdata->edit_bmesh->bm;
+
+ const int *v_origindex = rdata->mapped.v_origindex;
+ const int *e_origindex = rdata->mapped.e_origindex;
+ const int *p_origindex = rdata->mapped.p_origindex;
+
+ /* Face Loops */
+ for (int poly = 0; poly < poly_len; poly++, mpoly++) {
+ int fidx = p_origindex[poly];
+ if (fidx != ORIGINDEX_NONE) {
+ efa = BM_face_at_index(bm, fidx);
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ const MLoop *mloop = &rdata->mapped.me_cage->mloop[mpoly->loopstart];
+ for (i = 0; i < mpoly->totloop; ++i, ++mloop) {
+ if (ibo_verts && (v_origindex[mloop->v] != ORIGINDEX_NONE)) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx + i);
+ }
+ if (ibo_edges && (e_origindex[mloop->e] != ORIGINDEX_NONE)) {
+ int v1 = loop_idx + i;
+ int v2 = loop_idx + ((i + 1) % mpoly->totloop);
+ GPU_indexbuf_add_line_verts(&elb_edge, v1, v2);
+ }
+ }
+ }
+ }
+ loop_idx += mpoly->totloop;
+ }
+ /* Loose edges */
+ for (int e = 0; e < edge_len; e++, medge++) {
+ if (medge->flag & ME_LOOSEEDGE) {
+ int eidx = e_origindex[e];
+ if (eidx != ORIGINDEX_NONE) {
+ eed = BM_edge_at_index(bm, eidx);
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ for (int j = 0; j < 2; ++j) {
+ int v = (j == 0) ? medge->v1 : medge->v2;
+ if (ibo_verts && (v_origindex[v] != ORIGINDEX_NONE)) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx + j);
+ }
+ if (ibo_edges) {
+ GPU_indexbuf_add_generic_vert(&elb_edge, loop_idx + j);
+ }
+ }
+ }
+ }
+ loop_idx += 2;
+ }
+ }
+ /* Loose verts */
+ for (int v = 0; v < vert_len; v++) {
+ int vidx = v_origindex[v];
+ if (vidx != ORIGINDEX_NONE) {
+ eve = BM_vert_at_index(bm, vidx);
+ if (eve->e == NULL) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ if (ibo_verts) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx);
+ }
+ }
+ loop_idx += 1;
+ }
+ }
+ }
+ }
+ else {
+ const MPoly *mpoly = rdata->mpoly;
+
+ /* Face Loops */
+ for (int poly = 0; poly < poly_len; poly++, mpoly++) {
+ if ((mpoly->flag & ME_HIDE) == 0) {
+ for (i = 0; i < mpoly->totloop; ++i) {
+ if (ibo_verts) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx + i);
+ }
+ if (ibo_edges) {
+ int v1 = loop_idx + i;
+ int v2 = loop_idx + ((i + 1) % mpoly->totloop);
+ GPU_indexbuf_add_line_verts(&elb_edge, v1, v2);
+ }
+ }
+ }
+ loop_idx += mpoly->totloop;
+ }
+ /* TODO(fclem): Until we find a way to detect
+ * loose verts easily outside of edit mode, this
+ * will remain disabled. */
+#if 0
+ /* Loose edges */
+ for (int e = 0; e < edge_len; e++, medge++) {
+ if (medge->flag & ME_LOOSEEDGE) {
+ int eidx = e_origindex[e];
+ if (eidx != ORIGINDEX_NONE) {
+ if ((medge->flag & ME_HIDE) == 0) {
+ for (int j = 0; j < 2; ++j) {
+ if (ibo_verts) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx + j);
+ }
+ if (ibo_edges) {
+ GPU_indexbuf_add_generic_vert(&elb_edge, loop_idx + j);
+ }
+ }
+ }
+ }
+ loop_idx += 2;
+ }
+ }
+ /* Loose verts */
+ for (int v = 0; v < vert_len; v++, mvert++) {
+ int vidx = v_origindex[v];
+ if (vidx != ORIGINDEX_NONE) {
+ if ((mvert->flag & ME_HIDE) == 0) {
+ if (ibo_verts) {
+ GPU_indexbuf_add_generic_vert(&elb_vert, loop_idx);
+ }
+ if (ibo_edges) {
+ GPU_indexbuf_add_generic_vert(&elb_edge, loop_idx);
+ }
+ }
+ loop_idx += 1;
+ }
+ }
+#endif
+ }
+
+ if (ibo_verts) {
+ GPU_indexbuf_build_in_place(&elb_vert, ibo_verts);
+ }
+ if (ibo_edges) {
+ GPU_indexbuf_build_in_place(&elb_edge, ibo_edges);
+ }
+}
+
+static void mesh_create_edit_loops_tris(MeshRenderData *rdata, GPUIndexBuf *ibo)
+{
+ const int loop_len = mesh_render_data_loops_len_get_maybe_mapped(rdata);
+ const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata);
+
+ GPUIndexBufBuilder elb;
+ /* TODO alloc minmum necessary. */
+ GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, loop_len * 3);
+
+ if (rdata->edit_bmesh && (rdata->mapped.use == false)) {
+ for (int i = 0; i < tri_len; i++) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+ const BMFace *bm_face = bm_looptri[0]->f;
+ /* use_hide always for edit-mode */
+ if (BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) {
+ continue;
+ }
+ GPU_indexbuf_add_tri_verts(&elb, BM_elem_index_get(bm_looptri[0]),
+ BM_elem_index_get(bm_looptri[1]),
+ BM_elem_index_get(bm_looptri[2]));
+ }
+ }
+ else if (rdata->mapped.use == true) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ Mesh *me_cage = rdata->mapped.me_cage;
+
+ const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage);
+ for (int i = 0; i < tri_len; i++) {
+ const MLoopTri *mlt = &mlooptri[i];
+ const int p_orig = rdata->mapped.p_origindex[mlt->poly];
+ if (p_orig != ORIGINDEX_NONE) {
+ /* Assume 'use_hide' */
+ BMFace *efa = BM_face_at_index(bm, p_orig);
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ GPU_indexbuf_add_tri_verts(&elb, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
+ }
+ }
+ }
+ }
+ else {
+ const MLoopTri *mlt = rdata->mlooptri;
+ for (int i = 0; i < tri_len; i++, mlt++) {
+ const MPoly *mpoly = &rdata->mpoly[mlt->poly];
+ /* Assume 'use_hide' */
+ if ((mpoly->flag & ME_HIDE) == 0) {
+ GPU_indexbuf_add_tri_verts(&elb, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
+ }
+ }
+ }
+
+ GPU_indexbuf_build_in_place(&elb, ibo);
+}
+
/** \} */
@@ -4629,143 +4777,28 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Mesh *me)
/** \name Edit Mode selection API
* \{ */
-GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(Mesh *me, bool use_hide, uint select_id_offset)
-{
- MeshBatchCache *cache = mesh_batch_cache_get(me);
-
- if (cache->triangles_with_select_id_offset != select_id_offset) {
- cache->triangles_with_select_id_offset = select_id_offset;
- GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
- }
-
- if (cache->triangles_with_select_id == NULL) {
- const int datatype =
- MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
- MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- if (rdata->mapped.supported) {
- rdata->mapped.use = true;
- }
-
- cache->triangles_with_select_id = GPU_batch_create_ex(
- GPU_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide, select_id_offset), NULL, GPU_BATCH_OWNS_VBO);
-
- GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals_edit(rdata, cache, use_hide);
- GPU_batch_vertbuf_add(cache->triangles_with_select_id, vbo_tris);
-
- mesh_render_data_free(rdata);
- }
-
- return cache->triangles_with_select_id;
-}
-
-/**
- * Same as #DRW_mesh_batch_cache_get_triangles_with_select_id
- * without the ID's, use to mask out geometry, eg - dont select face-dots behind other faces.
- */
-GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(Mesh *me, bool use_hide)
+GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- if (cache->triangles_with_select_mask == NULL) {
- const int datatype =
- MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
- MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- if (rdata->mapped.supported) {
- rdata->mapped.use = true;
- }
-
- GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals_edit(rdata, cache, use_hide);
-
- cache->triangles_with_select_mask = GPU_batch_create(
- GPU_PRIM_TRIS, vbo_tris, NULL);
-
- mesh_render_data_free(rdata);
- }
-
- return cache->triangles_with_select_mask;
+ return DRW_batch_request(&cache->batch.edit_selection_faces);
}
-
-GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me, uint select_id_offset)
+GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
-
- if (cache->facedot_with_select_id_offset != select_id_offset) {
- cache->facedot_with_select_id_offset = select_id_offset;
- GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
- }
-
- if (cache->facedot_with_select_id == NULL) {
- MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
-
- /* We only want the 'pos', not the normals or flag.
- * Use since this is almost certainly already created. */
- cache->facedot_with_select_id = GPU_batch_create(
- GPU_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL);
-
- GPU_batch_vertbuf_add_ex(
- cache->facedot_with_select_id,
- mesh_create_facedot_select_id(rdata, select_id_offset), true);
-
- mesh_render_data_free(rdata);
- }
-
- return cache->facedot_with_select_id;
+ return DRW_batch_request(&cache->batch.edit_selection_facedots);
}
-GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me, uint select_id_offset)
+GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
-
- if (cache->edges_with_select_id_offset != select_id_offset) {
- cache->edges_with_select_id_offset = select_id_offset;
- GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
- }
-
- if (cache->edges_with_select_id == NULL) {
- MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
- if (rdata->mapped.supported) {
- rdata->mapped.use = true;
- }
-
- cache->edges_with_select_id = GPU_batch_create(
- GPU_PRIM_LINES, mesh_batch_cache_get_edges_visible(rdata, cache), NULL);
-
- GPU_batch_vertbuf_add_ex(
- cache->edges_with_select_id,
- mesh_create_edges_select_id(rdata, select_id_offset), true);
-
- mesh_render_data_free(rdata);
- }
-
- return cache->edges_with_select_id;
+ return DRW_batch_request(&cache->batch.edit_selection_edges);
}
-GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me, uint select_id_offset)
+GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
-
- if (cache->verts_with_select_id_offset != select_id_offset) {
- cache->verts_with_select_id_offset = select_id_offset;
- GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
- }
-
- if (cache->verts_with_select_id == NULL) {
- MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT);
- if (rdata->mapped.supported) {
- rdata->mapped.use = true;
- }
-
- cache->verts_with_select_id = GPU_batch_create(
- GPU_PRIM_POINTS, mesh_batch_cache_get_verts_visible(rdata, cache), NULL);
-
- GPU_batch_vertbuf_add_ex(
- cache->verts_with_select_id,
- mesh_create_verts_select_id(rdata, select_id_offset), true);
-
- mesh_render_data_free(rdata);
- }
-
- return cache->verts_with_select_id;
+ return DRW_batch_request(&cache->batch.edit_selection_verts);
}
/** \} */
@@ -5402,6 +5435,31 @@ void DRW_mesh_batch_cache_create_requested(
if (DRW_batch_requested(cache->batch.edit_facedots, GPU_PRIM_POINTS)) {
DRW_vbo_request(cache->batch.edit_facedots, &cache->edit.pos_nor_data_facedots);
}
+ if (DRW_batch_requested(cache->batch.edit_triangles_nor, GPU_PRIM_POINTS)) {
+ DRW_ibo_request(cache->batch.edit_triangles_nor, &cache->ibo.edit_verts_points);
+ DRW_vbo_request(cache->batch.edit_triangles_nor, &cache->edit.pos_nor);
+ }
+
+ /* TODO reuse ordered.loop_pos_nor if possible. */
+ if (DRW_batch_requested(cache->batch.edit_selection_verts, GPU_PRIM_POINTS)) {
+ DRW_ibo_request(cache->batch.edit_selection_verts, &cache->ibo.edit_loops_points);
+ DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_pos);
+ DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_vert_idx);
+ }
+ if (DRW_batch_requested(cache->batch.edit_selection_edges, GPU_PRIM_LINES)) {
+ DRW_ibo_request(cache->batch.edit_selection_edges, &cache->ibo.edit_loops_lines);
+ DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_pos);
+ DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_edge_idx);
+ }
+ if (DRW_batch_requested(cache->batch.edit_selection_faces, GPU_PRIM_TRIS)) {
+ DRW_ibo_request(cache->batch.edit_selection_faces, &cache->ibo.edit_loops_tris);
+ DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_pos);
+ DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_face_idx);
+ }
+ if (DRW_batch_requested(cache->batch.edit_selection_facedots, GPU_PRIM_POINTS)) {
+ DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.pos_nor_data_facedots);
+ DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.facedots_idx);
+ }
for (int i = 0; i < cache->mat_len; ++i) {
if (DRW_batch_requested(cache->surf_per_mat[i], GPU_PRIM_TRIS)) {
@@ -5454,7 +5512,16 @@ void DRW_mesh_batch_cache_create_requested(
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor_lverts, MR_DATATYPE_VERT | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_OVERLAY);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor_data_facedots, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.lnor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_pos, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_vert_idx, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_edge_idx, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_face_idx, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_idx, MR_DATATYPE_POLY);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_verts_points, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
+ /* TODO: Some of the flags here may not be needed. */
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_points, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_tris, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
Mesh *me_original = me;
MBC_GET_FINAL_MESH(me);
@@ -5473,7 +5540,7 @@ void DRW_mesh_batch_cache_create_requested(
mesh_create_weights(rdata, cache->ordered.weights, &cache->weight_state);
}
if (DRW_vbo_requested(cache->ordered.loop_pos_nor)) {
- mesh_create_loop_pos_and_nor(rdata, cache->ordered.loop_pos_nor, use_face_sel);
+ mesh_create_loop_pos_and_nor(rdata, cache->ordered.loop_pos_nor);
}
if (DRW_vbo_requested(cache->ordered.loop_uv_tan)) {
mesh_create_loop_uv_and_tan(rdata, cache->ordered.loop_uv_tan);
@@ -5538,6 +5605,25 @@ void DRW_mesh_batch_cache_create_requested(
if (DRW_vbo_requested(cache->edit.pos_nor_data_facedots)) {
mesh_create_edit_facedots(rdata, cache->edit.pos_nor_data_facedots);
}
+ if (DRW_vbo_requested(cache->edit.loop_pos) ||
+ DRW_vbo_requested(cache->edit.loop_vert_idx) ||
+ DRW_vbo_requested(cache->edit.loop_edge_idx) ||
+ DRW_vbo_requested(cache->edit.loop_face_idx))
+ {
+ mesh_create_edit_select_id(rdata, cache->edit.loop_pos, cache->edit.loop_vert_idx,
+ cache->edit.loop_edge_idx, cache->edit.loop_face_idx);
+ }
+ if (DRW_vbo_requested(cache->edit.facedots_idx)) {
+ mesh_create_edit_facedots_select_id(rdata, cache->edit.facedots_idx);
+ }
+ if (DRW_ibo_requested(cache->ibo.edit_loops_points) ||
+ DRW_ibo_requested(cache->ibo.edit_loops_lines))
+ {
+ mesh_create_edit_loops_points_lines(rdata, cache->ibo.edit_loops_points, cache->ibo.edit_loops_lines);
+ }
+ if (DRW_ibo_requested(cache->ibo.edit_loops_tris)) {
+ mesh_create_edit_loops_tris(rdata, cache->ibo.edit_loops_tris);
+ }
mesh_render_data_free(rdata);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 409f0300530..f778021a2db 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -190,99 +190,61 @@ bool view3d_camera_border_hack_test = false;
/* ***************** BACKBUF SEL (BBS) ********* */
-static void bbs_obmode_mesh_verts(Object *ob, int offset)
-{
- Mesh *me = ob->data;
- GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GPU_batch_draw(batch);
-}
-
-static void bbs_mesh_verts(BMEditMesh *em, int offset)
+static void bbs_mesh_verts(GPUBatch *batch, int offset)
{
GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
- Mesh *me = em->ob->data;
- GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
GPU_batch_draw(batch);
}
-static void bbs_mesh_wire(BMEditMesh *em, int offset)
+static void bbs_mesh_wire(GPUBatch *batch, int offset)
{
GPU_line_width(1.0f);
+ glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
- Mesh *me = em->ob->data;
- GPUBatch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
GPU_batch_draw(batch);
+
+ glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
}
-static void bbs_mesh_face(BMEditMesh *em, const bool use_select)
+/* two options, facecolors or black */
+static void bbs_mesh_face(GPUBatch *batch, const bool use_select)
{
- Mesh *me = em->ob->data;
- GPUBatch *batch;
-
if (use_select) {
- batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
+ GPU_batch_uniform_1ui(batch, "offset", 1);
GPU_batch_draw(batch);
}
else {
- int selcol;
- GPU_select_index_get(0, &selcol);
- batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
- GPU_batch_uniform_1ui(batch, "color", selcol);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID);
+ GPU_batch_uniform_1ui(batch, "id", 0);
GPU_batch_draw(batch);
}
}
-static void bbs_mesh_face_dot(BMEditMesh *em)
+static void bbs_mesh_face_dot(GPUBatch *batch)
{
- Mesh *me = em->ob->data;
- GPUBatch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
+ GPU_batch_uniform_1ui(batch, "offset", 1);
GPU_batch_draw(batch);
}
-/* two options, facecolors or black */
-static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
- Object *ob, bool use_faceselect)
-{
- if (use_faceselect) {
- bbs_mesh_face(em, true);
-
- if (check_ob_drawface_dot(scene, v3d, ob->dt)) {
- bbs_mesh_face_dot(em);
- }
- }
- else {
- bbs_mesh_face(em, false);
- }
-}
-
static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene), Object *ob)
{
Mesh *me = ob->data;
- /* Only draw faces to mask out verts, we don't want their selection ID's. */
- const int G_f_orig = G.f;
- G.f &= ~G_BACKBUFSEL;
-
- {
- int selcol;
- GPUBatch *batch;
- GPU_select_index_get(0, &selcol);
- batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
- GPU_batch_uniform_1ui(batch, "color", selcol);
- GPU_batch_draw(batch);
- }
+ GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
- G.f |= (G_f_orig & G_BACKBUFSEL);
+ /* Only draw faces to mask out verts, we don't want their selection ID's. */
+ bbs_mesh_face(geom_faces, false);
+ bbs_mesh_verts(geom_verts, 1);
- bbs_obmode_mesh_verts(ob, 1);
bm_vertoffs = me->totvert + 1;
}
@@ -290,15 +252,12 @@ static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob)
{
Mesh *me = ob->data;
Mesh *me_orig = DEG_get_original_object(ob)->data;
- GPUBatch *batch;
- if ((me_orig->editflag & ME_EDIT_PAINT_FACE_SEL)) {
- batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
- }
- else {
- batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1);
- }
- GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
- GPU_batch_draw(batch);
+
+ const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
+ GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, use_hide);
+
+ bbs_mesh_face(geom_faces, true);
}
void draw_object_backbufsel(
@@ -311,8 +270,6 @@ void draw_object_backbufsel(
}
GPU_matrix_mul(ob->obmat);
-
- glClearDepth(1.0); GPU_clear(GPU_DEPTH_BIT);
GPU_depth_test(true);
switch (ob->type) {
@@ -320,10 +277,30 @@ void draw_object_backbufsel(
if (ob->mode & OB_MODE_EDIT) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
+ const bool draw_facedot = check_ob_drawface_dot(scene, v3d, ob->dt);
+ const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
- bbs_mesh_solid_EM(em, scene, v3d, ob, (select_mode & SCE_SELECT_FACE) != 0);
+ GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
+ geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ if (select_mode & SCE_SELECT_EDGE) {
+ geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
+ }
+ if (select_mode & SCE_SELECT_VERTEX) {
+ geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
+ }
+ if (draw_facedot) {
+ geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
+ }
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
+
+ bbs_mesh_face(geom_faces, use_faceselect);
+
+ if (use_faceselect && draw_facedot) {
+ bbs_mesh_face_dot(geom_facedots);
+ }
+
if (select_mode & SCE_SELECT_FACE)
bm_solidoffs = 1 + em->bm->totface;
else {
@@ -334,7 +311,7 @@ void draw_object_backbufsel(
/* we draw edges if edge select mode */
if (select_mode & SCE_SELECT_EDGE) {
- bbs_mesh_wire(em, bm_solidoffs);
+ bbs_mesh_wire(geom_edges, bm_solidoffs);
bm_wireoffs = bm_solidoffs + em->bm->totedge;
}
else {
@@ -344,7 +321,7 @@ void draw_object_backbufsel(
/* we draw verts if vert select mode. */
if (select_mode & SCE_SELECT_VERTEX) {
- bbs_mesh_verts(em, bm_wireoffs);
+ bbs_mesh_verts(geom_verts, bm_wireoffs);
bm_vertoffs = bm_wireoffs + em->bm->totvert;
}
else {
@@ -354,7 +331,7 @@ void draw_object_backbufsel(
ED_view3d_polygon_offset(rv3d, 0.0);
}
else {
- Mesh *me = ob->data;
+ Mesh *me = DEG_get_original_object(ob)->data;
if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
/* currently vertex select supports weight paint and vertex paint*/
((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))