[Bf-blender-cvs] [26fc6c71c4] blender2.8: Edit Mode overlays: separate multiple shaders for loose edges and verts
Clément Foucault
noreply at git.blender.org
Thu Mar 2 01:10:42 CET 2017
Commit: 26fc6c71c411e9ba3650a8f5dbb16167a528f984
Author: Clément Foucault
Date: Wed Mar 1 14:07:04 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB26fc6c71c411e9ba3650a8f5dbb16167a528f984
Edit Mode overlays: separate multiple shaders for loose edges and verts
===================================================================
M source/blender/blenkernel/BKE_mesh_render.h
M source/blender/blenkernel/intern/mesh_render.c
M source/blender/draw/intern/draw_cache.c
M source/blender/draw/intern/draw_cache.h
M source/blender/draw/intern/draw_mode_pass.c
M source/blender/draw/intern/draw_mode_pass.h
M source/blender/draw/modes/edit_mesh_mode.c
M source/blender/editors/space_view3d/drawobject.c
M source/blender/gpu/CMakeLists.txt
M source/blender/gpu/GPU_shader.h
M source/blender/gpu/intern/gpu_shader.c
A source/blender/gpu/shaders/gpu_shader_edit_overlay_geom_edge.glsl
R083 source/blender/gpu/shaders/gpu_shader_edit_overlay_geom.glsl source/blender/gpu/shaders/gpu_shader_edit_overlay_geom_tri.glsl
A source/blender/gpu/shaders/gpu_shader_edit_overlay_geom_vert.glsl
===================================================================
diff --git a/source/blender/blenkernel/BKE_mesh_render.h b/source/blender/blenkernel/BKE_mesh_render.h
index f4e322fca6..0370426d41 100644
--- a/source/blender/blenkernel/BKE_mesh_render.h
+++ b/source/blender/blenkernel/BKE_mesh_render.h
@@ -40,6 +40,8 @@ struct Batch *BKE_mesh_batch_cache_get_all_triangles(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_all_verts(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
-struct Batch *BKE_mesh_batch_cache_get_overlay_edges(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_overlay_triangles(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me);
#endif /* __BKE_MESH_RENDER_H__ */
diff --git a/source/blender/blenkernel/intern/mesh_render.c b/source/blender/blenkernel/intern/mesh_render.c
index 2e9ea90792..9488b80f20 100644
--- a/source/blender/blenkernel/intern/mesh_render.c
+++ b/source/blender/blenkernel/intern/mesh_render.c
@@ -123,15 +123,11 @@ typedef struct MeshRenderData {
enum {
MR_DATATYPE_VERT = 1 << 0,
- MR_DATATYPE_LOOSE_VERT = 1 << 1,
- MR_DATATYPE_EDGE = 1 << 2,
- MR_DATATYPE_LOOSE_EDGE = 1 << 3,
- MR_DATATYPE_LOOPTRI = 1 << 4,
- MR_DATATYPE_LOOP = 1 << 5,
- MR_DATATYPE_POLY = 1 << 6,
- MR_DATATYPE_ACTIVE = 1 << 7,
- MR_DATATYPE_CREASE = 1 << 8,
- MR_DATATYPE_BWEIGHT = 1 << 9,
+ 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,
};
static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
@@ -146,11 +142,11 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
mrdata->edit_bmesh = embm;
int bm_ensure_types = 0;
- if (types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOSE_VERT)) {
+ if (types & (MR_DATATYPE_VERT)) {
mrdata->totvert = bm->totvert;
bm_ensure_types |= BM_VERT;
}
- if (types & (MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_EDGE)) {
+ if (types & (MR_DATATYPE_EDGE)) {
mrdata->totedge = bm->totedge;
bm_ensure_types |= BM_EDGE;
}
@@ -166,72 +162,56 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
mrdata->totpoly = bm->totface;
bm_ensure_types |= BM_FACE;
}
- if (types & MR_DATATYPE_ACTIVE) {
+ if (types & MR_DATATYPE_OVERLAY) {
mrdata->efa_act = BM_mesh_active_face_get(bm, false, true);
mrdata->eed_act = BM_mesh_active_edge_get(bm);
mrdata->eve_act = BM_mesh_active_vert_get(bm);
- }
- if (types & MR_DATATYPE_CREASE) {
mrdata->crease_ofs = CustomData_get_offset(&bm->edata, CD_CREASE);
- }
- if (types & MR_DATATYPE_BWEIGHT) {
mrdata->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_LOOSE_VERT) {
- mrdata->types |= MR_DATATYPE_VERT;
- mrdata->totlvert = 0;
- /* XXX slow, looping twice */
+ if (types & MR_DATATYPE_OVERLAY) {
+ mrdata->totlvert = mrdata->totledge = 0;
+
+ int *lverts = mrdata->loose_verts = MEM_mallocN(mrdata->totvert * sizeof(int), "Loose Vert");
+ int *ledges = mrdata->loose_edges = MEM_mallocN(mrdata->totedge * sizeof(int), "Loose Edges");
+
for (int i = 0; i < mrdata->totvert; ++i) {
BMVert *bv = BM_vert_at_index(bm, i);
- if (BM_vert_edge_count_ex(bv, 1) == 0) {
+
+ /* Loose vert */
+ if (bv->e == NULL) {
+ lverts[mrdata->totlvert] = BM_elem_index_get(bv);
mrdata->totlvert++;
+ continue;
}
- }
- int *lverts = mrdata->loose_verts = MEM_mallocN(mrdata->totlvert * sizeof(int), "Loose Vert");
-
- int li = 0;
- if (mrdata->totlvert > 0) {
- for (int i = 0; i < mrdata->totvert; ++i) {
- BMVert *bv = BM_vert_at_index(bm, i);
- if (BM_vert_edge_count_ex(bv, 1) == 0) {
- lverts[li++] = i;
+ /* Find Loose Edges */
+ BMEdge *e_iter, *e_first;
+ e_first = e_iter = bv->e;
+ do {
+ if (e_iter->l == NULL) {
+ BMVert *other_vert = BM_edge_other_vert(e_iter, bv);
+
+ /* Verify we do not add the same edge twice */
+ if (BM_elem_index_get(other_vert) > i) {
+ ledges[mrdata->totledge] = BM_elem_index_get(e_iter);
+ mrdata->totledge++;
+ }
}
- }
- }
- }
- if (types & MR_DATATYPE_LOOSE_EDGE) {
- mrdata->types |= MR_DATATYPE_EDGE;
- mrdata->totledge = 0;
- /* XXX slow, looping twice */
- for (int i = 0; i < mrdata->totedge; ++i) {
- BMEdge *bv = BM_edge_at_index(bm, i);
- if (BM_edge_is_wire(bv)) {
- mrdata->totledge++;
- }
- }
-
- int *ledges = mrdata->loose_edges = MEM_mallocN(mrdata->totledge * sizeof(int), "Loose Egde");
-
- int li = 0;
- if (mrdata->totledge > 0) {
- for (int i = 0; i < mrdata->totedge; ++i) {
- BMEdge *bv = BM_edge_at_index(bm, i);
- if (BM_edge_is_wire(bv)) {
- ledges[li++] = i;
- }
- }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, bv)) != e_first);
}
+ mrdata->loose_verts = MEM_reallocN(mrdata->loose_verts, mrdata->totlvert * sizeof(int));
+ mrdata->loose_edges = MEM_reallocN(mrdata->loose_edges, mrdata->totledge * sizeof(int));
}
}
else {
- if (types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOSE_VERT)) {
+ if (types & (MR_DATATYPE_VERT)) {
mrdata->totvert = me->totvert;
mrdata->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
}
- if (types & (MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_EDGE)) {
+ if (types & (MR_DATATYPE_EDGE)) {
mrdata->totedge = me->totedge;
mrdata->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
}
@@ -248,16 +228,6 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
mrdata->totpoly = me->totpoly;
mrdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
}
- if (types & MR_DATATYPE_LOOSE_VERT) {
- mrdata->types |= MR_DATATYPE_VERT;
- mrdata->totlvert = 0;
- /* TODO */
- }
- if (types & MR_DATATYPE_LOOSE_EDGE) {
- mrdata->types |= MR_DATATYPE_EDGE;
- mrdata->totledge = 0;
- /* TODO */
- }
}
return mrdata;
@@ -300,7 +270,7 @@ static int mesh_render_data_verts_num_get(const MeshRenderData *mrdata)
static int mesh_render_data_loose_verts_num_get(const MeshRenderData *mrdata)
{
- BLI_assert(mrdata->types & MR_DATATYPE_LOOSE_VERT);
+ BLI_assert(mrdata->types & MR_DATATYPE_OVERLAY);
return mrdata->totlvert;
}
@@ -312,7 +282,7 @@ static int mesh_render_data_edges_num_get(const MeshRenderData *mrdata)
static int mesh_render_data_loose_edges_num_get(const MeshRenderData *mrdata)
{
- BLI_assert(mrdata->types & MR_DATATYPE_LOOSE_EDGE);
+ BLI_assert(mrdata->types & MR_DATATYPE_OVERLAY);
return mrdata->totledge;
}
@@ -547,6 +517,171 @@ static bool mesh_render_data_looptri_cos_nors_smooth_get(
}
}
+/* 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_overlay_geom.glsl) */
+};
+
+static unsigned char mesh_render_data_looptri_flag(MeshRenderData *mrdata, const int f)
+{
+ unsigned char fflag = 0;
+
+ if (mrdata->edit_bmesh) {
+ BMFace *bf = mrdata->edit_bmesh->looptris[f][0]->f;
+
+ if (bf == mrdata->efa_act)
+ fflag |= VFLAG_FACE_ACTIVE;
+
+ if (BM_elem_flag_test(bf, BM_ELEM_SELECT))
+ fflag |= VFLAG_FACE_SELECTED;
+ }
+
+ return fflag;
+}
+
+static unsigned char *mesh_render_data_edge_flag(
+ MeshRenderData *mrdata, const int v1, const int v2, const int e)
+{
+ static unsigned char eflag[4];
+ memset(eflag, 0, sizeof(char) * 4);
+
+ /* if edge exists */
+ if (mrdata->edit_bmesh) {
+ BMesh *bm = mrdata->edit_bmesh->bm;
+ BMEdge *be = NULL;
+
+ if (e != -1) be = BM_edge_at_index(bm, e);
+ else be = BM_edge_exists(BM_vert_at_index(bm, v1),
+ BM_vert_at_index(bm, v2));
+
+ if (be != NULL) {
+
+ eflag[1] |= VFLAG_EDGE_EXISTS;
+
+ if (be == mrdata->eed_act)
+ eflag[1] |= VFLAG_EDGE_ACTIVE;
+
+ if (BM_elem_flag_test(be, BM_ELEM_SELECT))
+ eflag[1] |= VFLAG_EDGE_SELECTED;
+
+ if (BM_elem_flag_test(be, BM_ELEM_SEAM))
+ eflag[1] |= VFLAG_EDGE_SEAM;
+
+ if (!BM_elem_flag_test(be, BM_ELEM_SMOOTH))
+ eflag[1] |= VFLAG_EDGE_SHARP;
+
+ /* Use a byte for value range */
+ if (mrdata->crease_ofs != -1) {
+ float crease = BM_ELEM_CD_GET_FLOAT(be, mrdata->crease_ofs);
+ if (crease > 0) {
+ eflag[2] = (char)(crease * 255.0f);
+ }
+ }
+
+ /* Use a byte for value range */
+ if (mrdata->bweight_ofs != -1) {
+ float bweight = BM_ELEM_CD_GET_FLOAT(be, mrdata->bweight_ofs);
+ if (bweight > 0) {
+ eflag[3] = (char)(bweight * 255.0f);
+ }
+ }
+ }
+ }
+ else if ((e == -1) && mesh_render_data_edge_exists(mrdata, v1, v2)) {
+ eflag[1] |= VFLAG_EDGE_EXISTS;
+ }
+
+ return eflag;
+}
+
+static unsigned char mesh_render_data_vertex_flag(MeshRenderData *mrdata, const int v)
+{
+
+ unsigned char vflag = 0;
+
+ if (mrdata->edit_bmesh) {
+ BMesh *bm = mrdata->edit_bmesh->bm;
+ BMVert *bv = BM_vert_at_index(bm, v);
+
+ /* Current vertex */
+ if (bv == mrdata->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 *mrdata, VertexBuffer *vbo, const unsigned int pos_id, const unsigned int edgeMod_id,
+ const int v1, const int v2, const int v3, const int f, const int base_vert_idx)
+{
+ const float *pos = mesh_render_data_vert_co(mrdata, v1);
+ unsigned char *eflag = mesh_render_data_edge_flag(mrdata, v2, v3, -1);
+ unsigned char fflag = mesh_render_data_looptri_flag(mrdata, f);
+ unsigned char vflag = mesh_render_
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list