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:
authorClément Foucault <foucault.clem@gmail.com>2017-03-09 03:29:58 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-03-09 03:30:26 +0300
commit49ef1a25b8d361a75211c29baa131d6958072685 (patch)
tree0cc20b85a96cd2549ee5c9c8699ec2fa78c69f85
parent4b31f1e5911e32cab3c2971572fae604d2e86808 (diff)
Edit Mesh overlay: Ported Display Normals option
-rw-r--r--release/scripts/startup/bl_ui/properties_collection.py4
-rw-r--r--source/blender/blenkernel/BKE_mesh_render.h1
-rw-r--r--source/blender/blenkernel/intern/mesh_render.c130
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/intern/draw_cache.c24
-rw-r--r--source/blender/draw/intern/draw_cache.h2
-rw-r--r--source/blender/draw/intern/draw_manager.c1
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c131
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_face_vert.glsl18
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_geom.glsl15
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_vert.glsl24
-rw-r--r--source/blender/makesrna/intern/rna_scene.c34
12 files changed, 312 insertions, 74 deletions
diff --git a/release/scripts/startup/bl_ui/properties_collection.py b/release/scripts/startup/bl_ui/properties_collection.py
index 6debbaf3aac..7cbdeb6e61d 100644
--- a/release/scripts/startup/bl_ui/properties_collection.py
+++ b/release/scripts/startup/bl_ui/properties_collection.py
@@ -128,6 +128,10 @@ class COLLECTION_PT_edit_mode_settings(CollectionButtonsPanel, Panel):
col = layout.column()
template_engine_settings(col, settings, "show_occlude_wire")
template_engine_settings(col, settings, "backwire_opacity")
+ template_engine_settings(col, settings, "face_normals_show")
+ template_engine_settings(col, settings, "vert_normals_show")
+ template_engine_settings(col, settings, "loop_normals_show")
+ template_engine_settings(col, settings, "normals_length")
if __name__ == "__main__": # only for live edit.
diff --git a/source/blender/blenkernel/BKE_mesh_render.h b/source/blender/blenkernel/BKE_mesh_render.h
index 0b51dc3d9d7..0869c96abf0 100644
--- a/source/blender/blenkernel/BKE_mesh_render.h
+++ b/source/blender/blenkernel/BKE_mesh_render.h
@@ -39,6 +39,7 @@ void BKE_mesh_batch_cache_free(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_all_edges(struct Mesh *me);
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_points_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_triangles(struct Mesh *me);
diff --git a/source/blender/blenkernel/intern/mesh_render.c b/source/blender/blenkernel/intern/mesh_render.c
index 67991d08f9d..dbe99acc10b 100644
--- a/source/blender/blenkernel/intern/mesh_render.c
+++ b/source/blender/blenkernel/intern/mesh_render.c
@@ -318,6 +318,22 @@ static float *mesh_render_data_vert_co(const MeshRenderData *mrdata, const int v
}
}
+static short *mesh_render_data_vert_nor(const MeshRenderData *mrdata, const int vert_idx)
+{
+ BLI_assert(mrdata->types & MR_DATATYPE_VERT);
+
+ if (mrdata->edit_bmesh) {
+ static short fno[3];
+ BMesh *bm = mrdata->edit_bmesh->bm;
+ BMVert *bv = BM_vert_at_index(bm, vert_idx);
+ normal_float_to_short_v3(fno, bv->no);
+ return fno;
+ }
+ else {
+ return mrdata->mvert[vert_idx].no;
+ }
+}
+
static void mesh_render_data_edge_verts_indices_get(const MeshRenderData *mrdata, const int edge_idx, int r_vert_idx[2])
{
BLI_assert(mrdata->types & MR_DATATYPE_EDGE);
@@ -710,6 +726,7 @@ static void add_overlay_loose_vert(
typedef struct MeshBatchCache {
VertexBuffer *pos_in_order;
+ VertexBuffer *nor_in_order;
ElementList *edges_in_order;
ElementList *triangles_in_order;
@@ -717,7 +734,9 @@ typedef struct MeshBatchCache {
Batch *all_edges;
Batch *all_triangles;
- Batch *triangles_with_normals; /* owns its vertex buffer */
+ 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
@@ -855,9 +874,10 @@ void BKE_mesh_batch_cache_clear(Mesh *me)
if (cache->overlay_loose_edges) Batch_discard_all(cache->overlay_loose_edges);
if (cache->overlay_facedots) Batch_discard_all(cache->overlay_facedots);
- if (cache->triangles_with_normals) {
- Batch_discard_all(cache->triangles_with_normals);
- }
+ if (cache->triangles_with_normals) Batch_discard(cache->triangles_with_normals);
+ if (cache->points_with_normals) Batch_discard(cache->points_with_normals);
+ if (cache->pos_with_normals) VertexBuffer_discard(cache->pos_with_normals);
+
if (cache->fancy_edges) {
Batch_discard_all(cache->fancy_edges);
@@ -872,16 +892,61 @@ void BKE_mesh_batch_cache_free(Mesh *me)
/* Batch cache usage. */
-static VertexBuffer *mesh_batch_cache_get_pos_in_order(MeshRenderData *mrdata, MeshBatchCache *cache)
+static VertexBuffer *mesh_batch_cache_get_pos_and_normals(MeshRenderData *mrdata, MeshBatchCache *cache)
+{
+ BLI_assert(mrdata->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 = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
+ nor_id = add_attrib(&format, "nor", GL_SHORT, 3, NORMALIZE_INT_TO_FLOAT);
+ }
+
+ const int tottri = mesh_render_data_looptri_num_get(mrdata);
+
+ cache->pos_with_normals = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(cache->pos_with_normals, tottri * 3);
+
+ for (int i = 0; i < tottri; i++) {
+ float *tri_vert_cos[3];
+ short *tri_nor, *tri_vert_nors[3];
+
+ const bool is_smooth = mesh_render_data_looptri_cos_nors_smooth_get(mrdata, i, &tri_vert_cos, &tri_nor, &tri_vert_nors);
+
+ if (is_smooth) {
+ setAttrib(cache->pos_with_normals, nor_id, nidx++, tri_vert_nors[0]);
+ setAttrib(cache->pos_with_normals, nor_id, nidx++, tri_vert_nors[1]);
+ setAttrib(cache->pos_with_normals, nor_id, nidx++, tri_vert_nors[2]);
+ }
+ else {
+ setAttrib(cache->pos_with_normals, nor_id, nidx++, tri_nor);
+ setAttrib(cache->pos_with_normals, nor_id, nidx++, tri_nor);
+ setAttrib(cache->pos_with_normals, nor_id, nidx++, tri_nor);
+ }
+
+ setAttrib(cache->pos_with_normals, pos_id, vidx++, tri_vert_cos[0]);
+ setAttrib(cache->pos_with_normals, pos_id, vidx++, tri_vert_cos[1]);
+ setAttrib(cache->pos_with_normals, pos_id, vidx++, tri_vert_cos[2]);
+ }
+ }
+ return cache->pos_with_normals;
+}
+static VertexBuffer *mesh_batch_cache_get_pos_and_nor_in_order(MeshRenderData *mrdata, MeshBatchCache *cache)
{
BLI_assert(mrdata->types & MR_DATATYPE_VERT);
if (cache->pos_in_order == NULL) {
static VertexFormat format = { 0 };
- static unsigned pos_id;
+ static unsigned pos_id, nor_id;
if (format.attrib_ct == 0) {
/* initialize vertex format */
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
+ nor_id = add_attrib(&format, "nor", GL_SHORT, 3, NORMALIZE_INT_TO_FLOAT);
}
const int vertex_ct = mesh_render_data_verts_num_get(mrdata);
@@ -890,6 +955,7 @@ static VertexBuffer *mesh_batch_cache_get_pos_in_order(MeshRenderData *mrdata, M
VertexBuffer_allocate_data(cache->pos_in_order, vertex_ct);
for (int i = 0; i < vertex_ct; ++i) {
setAttrib(cache->pos_in_order, pos_id, i, mesh_render_data_vert_co(mrdata, i));
+ setAttrib(cache->pos_in_order, nor_id, i, mesh_render_data_vert_nor(mrdata, i));
}
}
@@ -948,7 +1014,7 @@ Batch *BKE_mesh_batch_cache_get_all_edges(Mesh *me)
/* create batch from Mesh */
MeshRenderData *mrdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
- cache->all_edges = Batch_create(GL_LINES, mesh_batch_cache_get_pos_in_order(mrdata, cache),
+ cache->all_edges = Batch_create(GL_LINES, mesh_batch_cache_get_pos_and_nor_in_order(mrdata, cache),
mesh_batch_cache_get_edges_in_order(mrdata, cache));
mesh_render_data_free(mrdata);
@@ -965,7 +1031,7 @@ Batch *BKE_mesh_batch_cache_get_all_triangles(Mesh *me)
/* create batch from DM */
MeshRenderData *mrdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI);
- cache->all_triangles = Batch_create(GL_TRIANGLES, mesh_batch_cache_get_pos_in_order(mrdata, cache),
+ cache->all_triangles = Batch_create(GL_TRIANGLES, mesh_batch_cache_get_pos_and_nor_in_order(mrdata, cache),
mesh_batch_cache_get_triangles_in_order(mrdata, cache));
mesh_render_data_free(mrdata);
@@ -979,50 +1045,29 @@ Batch *BKE_mesh_batch_cache_get_triangles_with_normals(Mesh *me)
MeshBatchCache *cache = mesh_batch_cache_get(me);
if (cache->triangles_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 = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
- nor_id = add_attrib(&format, "nor", GL_SHORT, 3, NORMALIZE_INT_TO_FLOAT);
- }
-
MeshRenderData *mrdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
- const int tottri = mesh_render_data_looptri_num_get(mrdata);
- VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
- VertexBuffer_allocate_data(vbo, tottri * 3);
+ cache->triangles_with_normals = Batch_create(GL_TRIANGLES, mesh_batch_cache_get_pos_and_normals(mrdata, cache), NULL);
- for (int i = 0; i < tottri; i++) {
- float *tri_vert_cos[3];
- short *tri_nor, *tri_vert_nors[3];
+ mesh_render_data_free(mrdata);
+ }
- const bool is_smooth = mesh_render_data_looptri_cos_nors_smooth_get(mrdata, i, &tri_vert_cos, &tri_nor, &tri_vert_nors);
+ return cache->triangles_with_normals;
+}
- if (is_smooth) {
- setAttrib(vbo, nor_id, nidx++, tri_vert_nors[0]);
- setAttrib(vbo, nor_id, nidx++, tri_vert_nors[1]);
- setAttrib(vbo, nor_id, nidx++, tri_vert_nors[2]);
- }
- else {
- setAttrib(vbo, nor_id, nidx++, tri_nor);
- setAttrib(vbo, nor_id, nidx++, tri_nor);
- setAttrib(vbo, nor_id, nidx++, tri_nor);
- }
+Batch *BKE_mesh_batch_cache_get_points_with_normals(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
- setAttrib(vbo, pos_id, vidx++, tri_vert_cos[0]);
- setAttrib(vbo, pos_id, vidx++, tri_vert_cos[1]);
- setAttrib(vbo, pos_id, vidx++, tri_vert_cos[2]);
- }
+ if (cache->points_with_normals == NULL) {
+ MeshRenderData *mrdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
- cache->triangles_with_normals = Batch_create(GL_TRIANGLES, vbo, NULL);
+ cache->points_with_normals = Batch_create(GL_POINTS, mesh_batch_cache_get_pos_and_normals(mrdata, cache), NULL);
mesh_render_data_free(mrdata);
}
- return cache->triangles_with_normals;
+ return cache->points_with_normals;
}
Batch *BKE_mesh_batch_cache_get_all_verts(Mesh *me)
@@ -1033,8 +1078,7 @@ Batch *BKE_mesh_batch_cache_get_all_verts(Mesh *me)
/* create batch from DM */
MeshRenderData *mrdata = mesh_render_data_create(me, MR_DATATYPE_VERT);
- cache->all_verts = Batch_create(GL_POINTS, mesh_batch_cache_get_pos_in_order(mrdata, cache), NULL);
- Batch_set_builtin_program(cache->all_verts, GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ cache->all_verts = Batch_create(GL_POINTS, mesh_batch_cache_get_pos_and_nor_in_order(mrdata, cache), NULL);
mesh_render_data_free(mrdata);
}
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index c04063d22f8..0b7060fc55e 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -91,6 +91,8 @@ data_to_c_simple(modes/shaders/edit_overlay_mix_frag.glsl SRC)
data_to_c_simple(modes/shaders/edit_overlay_mix_vert.glsl SRC)
data_to_c_simple(modes/shaders/edit_overlay_facefill_vert.glsl SRC)
data_to_c_simple(modes/shaders/edit_overlay_facefill_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC)
list(APPEND INC
)
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 7514a0c806a..2b5f2d2ab2b 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -1291,6 +1291,30 @@ Batch *DRW_cache_surface_get(Object *ob)
return surface;
}
+Batch *DRW_cache_surface_verts_get(Object *ob)
+{
+ Batch *surface = NULL;
+
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ surface = BKE_mesh_batch_cache_get_points_with_normals(me);
+
+ return surface;
+}
+
+Batch *DRW_cache_verts_get(Object *ob)
+{
+ Batch *surface = NULL;
+
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ surface = BKE_mesh_batch_cache_get_all_verts(me);
+
+ return surface;
+}
+
#if 0 /* TODO */
struct Batch *DRW_cache_surface_material_get(Object *ob, int nr) {
/* TODO */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 66aa5400df5..0af7f3d08b1 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -76,5 +76,7 @@ void DRW_cache_wire_overlay_get(
struct Batch *DRW_cache_face_centers_get(struct Object *ob);
struct Batch *DRW_cache_wire_outline_get(struct Object *ob);
struct Batch *DRW_cache_surface_get(struct Object *ob);
+struct Batch *DRW_cache_surface_verts_get(struct Object *ob);
+struct Batch *DRW_cache_verts_get(struct Object *ob);
#endif /* __DRAW_CACHE_H__ */ \ No newline at end of file
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 54e5fa5440c..32f3bdffc4d 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -63,7 +63,6 @@
extern char datatoc_gpu_shader_2D_vert_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
-extern char datatoc_gpu_shader_basic_vert_glsl[];
/* Structures */
typedef enum {
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index e671e9f059b..1d5b064ebbd 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -35,11 +35,12 @@
/* keep it under MAX_PASSES */
typedef struct EDIT_MESH_PassList {
- struct DRWPass *depth_pass_hidden_wire;
- struct DRWPass *edit_face_overlay_pass;
- struct DRWPass *edit_face_occluded_pass;
- struct DRWPass *mix_occlude_pass;
- struct DRWPass *facefill_occlude_pass;
+ struct DRWPass *depth_hidden_wire;
+ struct DRWPass *edit_face_overlay;
+ struct DRWPass *edit_face_occluded;
+ struct DRWPass *mix_occlude;
+ struct DRWPass *facefill_occlude;
+ struct DRWPass *normals;
} EDIT_MESH_PassList;
/* keep it under MAX_BUFFERS */
@@ -63,6 +64,10 @@ typedef struct EDIT_MESH_Data {
static DRWShadingGroup *depth_shgrp_hidden_wire;
+static DRWShadingGroup *fnormals_shgrp;
+static DRWShadingGroup *vnormals_shgrp;
+static DRWShadingGroup *lnormals_shgrp;
+
static DRWShadingGroup *face_overlay_shgrp;
static DRWShadingGroup *ledges_overlay_shgrp;
static DRWShadingGroup *lverts_overlay_shgrp;
@@ -75,6 +80,7 @@ static DRWShadingGroup *facedot_occluded_shgrp;
static DRWShadingGroup *facefill_occluded_shgrp;
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
static struct GPUShader *overlay_tri_sh = NULL;
static struct GPUShader *overlay_tri_fast_sh = NULL;
@@ -86,6 +92,9 @@ static struct GPUShader *overlay_vert_sh = NULL;
static struct GPUShader *overlay_facedot_sh = NULL;
static struct GPUShader *overlay_mix_sh = NULL;
static struct GPUShader *overlay_facefill_sh = NULL;
+static struct GPUShader *normals_face_sh = NULL;
+static struct GPUShader *normals_sh = NULL;
+static struct GPUShader *depth_sh = NULL;
extern char datatoc_edit_overlay_frag_glsl[];
extern char datatoc_edit_overlay_vert_glsl[];
@@ -98,6 +107,10 @@ extern char datatoc_edit_overlay_mix_vert_glsl[];
extern char datatoc_edit_overlay_mix_frag_glsl[];
extern char datatoc_edit_overlay_facefill_vert_glsl[];
extern char datatoc_edit_overlay_facefill_frag_glsl[];
+extern char datatoc_edit_normals_vert_glsl[];
+extern char datatoc_edit_normals_geom_glsl[];
+
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
static void EDIT_MESH_engine_init(void)
{
@@ -160,6 +173,17 @@ static void EDIT_MESH_engine_init(void)
overlay_facefill_sh = DRW_shader_create(datatoc_edit_overlay_facefill_vert_glsl, NULL,
datatoc_edit_overlay_facefill_frag_glsl, NULL);
}
+ if (!normals_face_sh) {
+ normals_face_sh = DRW_shader_create(datatoc_edit_normals_vert_glsl, datatoc_edit_normals_geom_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl, "#define FACE_NORMALS\n");
+ }
+ if (!normals_sh) {
+ normals_sh = DRW_shader_create(datatoc_edit_normals_vert_glsl, datatoc_edit_normals_geom_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
+ }
+ if (!depth_sh) {
+ depth_sh = DRW_shader_create_3D_depth_only();
+ }
}
static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWShadingGroup **ledges_shgrp,
@@ -170,9 +194,9 @@ static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWS
const struct bContext *C = DRW_get_context();
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Scene *scene = CTX_data_scene(C);
- ToolSettings *ts = scene->toolsettings;
+ ToolSettings *tsettings = scene->toolsettings;
- if ((ts->selectmode & SCE_SELECT_VERTEX) != 0) {
+ if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
ledge_sh = overlay_edge_vcol_sh;
if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
@@ -199,12 +223,12 @@ static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWS
*ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
DRW_shgroup_uniform_vec2(*ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
- if ((ts->selectmode & (SCE_SELECT_VERTEX)) != 0) {
+ if ((tsettings->selectmode & (SCE_SELECT_VERTEX)) != 0) {
*lverts_shgrp = DRW_shgroup_create(overlay_vert_sh, pass);
DRW_shgroup_uniform_vec2(*lverts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
}
- if ((ts->selectmode & (SCE_SELECT_FACE)) != 0) {
+ if ((tsettings->selectmode & (SCE_SELECT_FACE)) != 0) {
*facedot_shgrp = DRW_shgroup_create(overlay_facedot_sh, pass);
}
@@ -213,6 +237,7 @@ static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWS
static float backwire_opacity;
static float face_mod;
+static float size_normal;
static void EDIT_MESH_cache_init(void)
{
@@ -227,35 +252,51 @@ static void EDIT_MESH_cache_init(void)
bool do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0);
static float zero = 0.0f;
- static struct GPUShader *depth_sh;
+
+ {
+ /* Complementary Depth Pass */
+ psl->depth_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ depth_shgrp_hidden_wire = DRW_shgroup_create(depth_sh, psl->depth_hidden_wire);
+ }
- if (!depth_sh)
- depth_sh = DRW_shader_create_3D_depth_only();
+ {
+ /* Normals */
+ psl->normals = DRW_pass_create("Edit Mesh Normals Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS);
+
+ fnormals_shgrp = DRW_shgroup_create(normals_face_sh, psl->normals);
+ DRW_shgroup_uniform_float(fnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(fnormals_shgrp, "color", ts.colorNormal, 1);
- psl->depth_pass_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
- depth_shgrp_hidden_wire = DRW_shgroup_create(depth_sh, psl->depth_pass_hidden_wire);
+ vnormals_shgrp = DRW_shgroup_create(normals_sh, psl->normals);
+ DRW_shgroup_uniform_float(vnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(vnormals_shgrp, "color", ts.colorVNormal, 1);
+
+ lnormals_shgrp = DRW_shgroup_create(normals_sh, psl->normals);
+ DRW_shgroup_uniform_float(lnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(lnormals_shgrp, "color", ts.colorLNormal, 1);
+ }
if (!do_zbufclip) {
- psl->edit_face_overlay_pass = edit_mesh_create_overlay_pass(&face_overlay_shgrp, &ledges_overlay_shgrp, &lverts_overlay_shgrp,
+ psl->edit_face_overlay = edit_mesh_create_overlay_pass(&face_overlay_shgrp, &ledges_overlay_shgrp, &lverts_overlay_shgrp,
&facedot_overlay_shgrp, &face_mod, DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND);
}
else {
/* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
- psl->edit_face_occluded_pass = edit_mesh_create_overlay_pass(&face_occluded_shgrp, &ledges_occluded_shgrp, &lverts_occluded_shgrp,
+ psl->edit_face_occluded = edit_mesh_create_overlay_pass(&face_occluded_shgrp, &ledges_occluded_shgrp, &lverts_occluded_shgrp,
&facedot_occluded_shgrp, &zero, DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH);
/* however we loose the front faces value (because we need the depth of occluded wires and
* faces are alpha blended ) so we recover them in a new pass. */
- psl->facefill_occlude_pass = DRW_pass_create("Front Face Color", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
- facefill_occluded_shgrp = DRW_shgroup_create(overlay_facefill_sh, psl->facefill_occlude_pass);
+ psl->facefill_occlude = DRW_pass_create("Front Face Color", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+ facefill_occluded_shgrp = DRW_shgroup_create(overlay_facefill_sh, psl->facefill_occlude);
DRW_shgroup_uniform_block(facefill_occluded_shgrp, "globalsBlock", globals_ubo, 0);
/* we need a full screen pass to combine the result */
struct Batch *quad = DRW_cache_fullscreen_quad_get();
static float mat[4][4]; /* not even used but avoid crash */
- psl->mix_occlude_pass = DRW_pass_create("Mix Occluded Wires", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
- DRWShadingGroup *mix_shgrp = DRW_shgroup_create(overlay_mix_sh, psl->mix_occlude_pass);
+ psl->mix_occlude = DRW_pass_create("Mix Occluded Wires", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
+ DRWShadingGroup *mix_shgrp = DRW_shgroup_create(overlay_mix_sh, psl->mix_occlude);
DRW_shgroup_call_add(mix_shgrp, quad, mat);
DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
DRW_shgroup_uniform_buffer(mix_shgrp, "wireColor", &txl->occlude_wire_color_tx, 0);
@@ -268,7 +309,7 @@ static void edit_mesh_add_ob_to_pass(Scene *scene, Object *ob, DRWShadingGroup *
DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp)
{
struct Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
- ToolSettings *ts = scene->toolsettings;
+ ToolSettings *tsettings = scene->toolsettings;
DRW_cache_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
@@ -277,10 +318,10 @@ static void edit_mesh_add_ob_to_pass(Scene *scene, Object *ob, DRWShadingGroup *
if (facefill_shgrp)
DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
- if ((ts->selectmode & SCE_SELECT_VERTEX) != 0)
+ if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0)
DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
- if ((ts->selectmode & SCE_SELECT_FACE) != 0) {
+ if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) {
geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
}
@@ -298,7 +339,12 @@ static void EDIT_MESH_cache_populate(Object *ob)
if (ob == obedit) {
CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
- backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity"); /* should be done only once */
+ backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity"); /* Updating uniform */
+
+ bool fnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "face_normals_show");
+ bool vnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "vert_normals_show");
+ bool lnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "loop_normals_show");
+ size_normal = BKE_collection_engine_property_value_get_float(ces_mode_ed, "normals_length"); /* Updating uniform */
face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
@@ -307,6 +353,21 @@ static void EDIT_MESH_cache_populate(Object *ob)
DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
}
+ if (fnormals_do) {
+ geom = DRW_cache_face_centers_get(ob);
+ DRW_shgroup_call_add(fnormals_shgrp, geom, ob->obmat);
+ }
+
+ if (vnormals_do) {
+ geom = DRW_cache_verts_get(ob);
+ DRW_shgroup_call_add(vnormals_shgrp, geom, ob->obmat);
+ }
+
+ if (lnormals_do) {
+ geom = DRW_cache_surface_verts_get(ob);
+ DRW_shgroup_call_add(lnormals_shgrp, geom, ob->obmat);
+ }
+
if ((v3d->flag & V3D_ZBUF_SELECT) == 0) {
edit_mesh_add_ob_to_pass(scene, ob, face_occluded_shgrp, ledges_occluded_shgrp,
lverts_occluded_shgrp, facedot_occluded_shgrp, facefill_occluded_shgrp);
@@ -327,30 +388,32 @@ static void EDIT_MESH_draw_scene(void)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- DRW_draw_pass(psl->depth_pass_hidden_wire);
+ DRW_draw_pass(psl->depth_hidden_wire);
- if (psl->edit_face_occluded_pass) {
+ if (psl->edit_face_occluded) {
float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* render facefill */
- DRW_draw_pass(psl->facefill_occlude_pass);
+ DRW_draw_pass(psl->facefill_occlude);
/* Render wires on a separate framebuffer */
DRW_framebuffer_bind(fbl->occlude_wire_fb);
DRW_framebuffer_clear(true, true, clearcol, 1.0f);
- DRW_draw_pass(psl->edit_face_occluded_pass);
+ DRW_draw_pass(psl->normals);
+ DRW_draw_pass(psl->edit_face_occluded);
/* detach textures */
DRW_framebuffer_texture_detach(dtxl->depth);
/* Combine with scene buffer */
DRW_framebuffer_bind(dfbl->default_fb);
- DRW_draw_pass(psl->mix_occlude_pass);
+ DRW_draw_pass(psl->mix_occlude);
/* reattach */
DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0);
}
else {
- DRW_draw_pass(psl->edit_face_overlay_pass);
+ DRW_draw_pass(psl->normals);
+ DRW_draw_pass(psl->edit_face_overlay);
}
}
@@ -358,6 +421,10 @@ void EDIT_MESH_collection_settings_create(CollectionEngineSettings *ces)
{
BLI_assert(ces);
BKE_collection_engine_property_add_int(ces, "show_occlude_wire", false);
+ BKE_collection_engine_property_add_int(ces, "face_normals_show", false);
+ BKE_collection_engine_property_add_int(ces, "vert_normals_show", false);
+ BKE_collection_engine_property_add_int(ces, "loop_normals_show", false);
+ BKE_collection_engine_property_add_float(ces, "normals_length", 0.1);
BKE_collection_engine_property_add_float(ces, "backwire_opacity", 0.5);
}
@@ -383,6 +450,10 @@ static void EDIT_MESH_engine_free(void)
DRW_shader_free(overlay_mix_sh);
if (overlay_facefill_sh)
DRW_shader_free(overlay_facefill_sh);
+ if (normals_face_sh)
+ DRW_shader_free(normals_face_sh);
+ if (normals_sh)
+ DRW_shader_free(normals_sh);
}
DrawEngineType draw_engine_edit_mesh_type = {
diff --git a/source/blender/draw/modes/shaders/edit_normals_face_vert.glsl b/source/blender/draw/modes/shaders/edit_normals_face_vert.glsl
new file mode 100644
index 00000000000..9c70eabc056
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_face_vert.glsl
@@ -0,0 +1,18 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+uniform mat4 ProjectionMatrix;
+uniform float normalSize;
+
+in vec3 pos;
+in vec4 norAndFlag;
+
+flat out vec4 v1;
+flat out vec4 v2;
+
+void main()
+{
+ v1 = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 n = normalize(NormalMatrix * norAndFlag.xyz); /* viewspace */
+ v2 = v1 + ProjectionMatrix * vec4(n * normalSize, 0.0);
+}
diff --git a/source/blender/draw/modes/shaders/edit_normals_geom.glsl b/source/blender/draw/modes/shaders/edit_normals_geom.glsl
new file mode 100644
index 00000000000..d17823f2f5a
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_geom.glsl
@@ -0,0 +1,15 @@
+
+layout(points) in;
+layout(line_strip, max_vertices=2) out;
+
+flat in vec4 v1[1];
+flat in vec4 v2[1];
+
+void main()
+{
+ gl_Position = v1[0];
+ EmitVertex();
+ gl_Position = v2[0];
+ EmitVertex();
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_normals_vert.glsl b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
new file mode 100644
index 00000000000..3e00181c8dd
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
@@ -0,0 +1,24 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+uniform mat4 ProjectionMatrix;
+uniform float normalSize;
+
+in vec3 pos;
+
+#ifdef FACE_NORMALS
+in vec4 norAndFlag;
+#define nor norAndFlag.xyz
+#else
+in vec3 nor;
+#endif
+
+flat out vec4 v1;
+flat out vec4 v2;
+
+void main()
+{
+ v1 = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 n = normalize(NormalMatrix * nor); /* viewspace */
+ v2 = v1 + ProjectionMatrix * vec4(n * normalSize, 0.0);
+}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 55b94c244bf..5e92965f449 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2503,6 +2503,10 @@ RNA_LAYER_MODE_OBJECT_GET_SET_BOOL(show_backface_culling)
/* mesh engine */
RNA_LAYER_MODE_EDIT_GET_SET_BOOL(show_occlude_wire)
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(face_normals_show)
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(vert_normals_show)
+RNA_LAYER_MODE_EDIT_GET_SET_BOOL(loop_normals_show)
+RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(normals_length)
RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(backwire_opacity)
#undef RNA_LAYER_ENGINE_GET_SET
@@ -6105,6 +6109,36 @@ static void rna_def_layer_collection_mode_settings_edit(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_CollectionEngineSettings_update");
RNA_LAYER_MODE_EDIT_USE(show_occlude_wire)
+ prop = RNA_def_property(srna, "face_normals_show", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Draw Normals", "Display face normals as lines");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_face_normals_show_get", "rna_LayerEngineSettings_EditMode_face_normals_show_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_CollectionEngineSettings_update");
+ RNA_LAYER_MODE_EDIT_USE(face_normals_show)
+
+ prop = RNA_def_property(srna, "vert_normals_show", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Draw Vertex Normals", "Display vertex normals as lines");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_vert_normals_show_get", "rna_LayerEngineSettings_EditMode_vert_normals_show_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_CollectionEngineSettings_update");
+ RNA_LAYER_MODE_EDIT_USE(vert_normals_show)
+
+ prop = RNA_def_property(srna, "loop_normals_show", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Draw Split Normals", "Display vertex-per-face normals as lines");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_EditMode_loop_normals_show_get", "rna_LayerEngineSettings_EditMode_loop_normals_show_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_CollectionEngineSettings_update");
+ RNA_LAYER_MODE_EDIT_USE(loop_normals_show)
+
+ prop = RNA_def_property(srna, "normals_length", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_ui_text(prop, "Normal Size", "Display size for normals in the 3D view");
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_EditMode_normals_length_get", "rna_LayerEngineSettings_EditMode_normals_length_set", NULL);
+ RNA_def_property_range(prop, 0.00001, 1000.0);
+ RNA_def_property_ui_range(prop, 0.01, 10.0, 10.0, 2);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_CollectionEngineSettings_update");
+ RNA_LAYER_MODE_EDIT_USE(normals_length)
+
prop = RNA_def_property(srna, "backwire_opacity", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_ui_text(prop, "Backwire Opacity", "Opacity when rendering transparent wires");
RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_EditMode_backwire_opacity_get", "rna_LayerEngineSettings_EditMode_backwire_opacity_set", NULL);