diff options
8 files changed, 186 insertions, 0 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index bdf450fab9c..abbf8a2b47b 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -277,6 +277,8 @@ data_to_c_simple(modes/shaders/edit_mesh_overlay_geom.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC) +data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl SRC) +data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_handle_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_handle_geom.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC) diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 26063df1082..490f478225b 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -3283,6 +3283,12 @@ GPUBatch *DRW_cache_mesh_face_wireframe_get(Object *ob) return DRW_mesh_batch_cache_get_wireframes_face(ob->data); } +GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + return DRW_mesh_batch_cache_get_edit_mesh_analysis(ob->data); +} + void DRW_cache_mesh_sculpt_coords_ensure(Object *ob) { BLI_assert(ob->type == OB_MESH); diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index c9ae0a01cb9..129b180957a 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -140,6 +140,7 @@ struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_surface_vertpaint_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob); void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index e4ce3ed9d49..8ab64aa26b9 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -157,6 +157,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edituv_facedots(struct Mesh *me); /* For Image UV editor. */ struct GPUBatch *DRW_mesh_batch_cache_get_uv_edges(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(struct Mesh *me); void DRW_mesh_cache_sculpt_coords_ensure(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 dcc249e90cf..b2e960f461f 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1911,6 +1911,7 @@ typedef struct MeshBatchCache { GPUVertBuf *loop_data; GPUVertBuf *loop_lnor; GPUVertBuf *facedots_pos_nor_data; + GPUVertBuf *loop_mesh_analysis; /* UV data without modifier applied. * Vertex count is always the one of the cage. */ GPUVertBuf *loop_uv; @@ -1958,6 +1959,7 @@ typedef struct MeshBatchCache { GPUBatch *edit_edges; GPUBatch *edit_lnor; GPUBatch *edit_facedots; + GPUBatch *edit_mesh_analysis; /* Edit UVs */ GPUBatch *edituv_faces_strech_area; GPUBatch *edituv_faces_strech_angle; @@ -2169,6 +2171,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode) GPU_BATCH_DISCARD_SAFE(cache->batch.edit_vertices); GPU_BATCH_DISCARD_SAFE(cache->batch.edit_edges); GPU_BATCH_DISCARD_SAFE(cache->batch.edit_facedots); + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_mesh_analysis); /* Paint mode selection */ /* TODO only do that in paint mode. */ GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor); @@ -3383,6 +3386,72 @@ static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_fac } } +static void mesh_create_edit_mesh_analysis(MeshRenderData *rdata, + GPUVertBuf *vbo_mesh_analysis) +{ + const MeshStatVis *mesh_stat_vis = &rdata->toolsettings->statvis; + + int mesh_analysis_len_used = 0; + + const uint loops_len = mesh_render_data_loops_len_get(rdata); + BMesh *bm = rdata->edit_bmesh->bm; + BMIter iter_efa, iter_loop; + BMFace *efa; + BMLoop *loop; + + static struct { + uint weight; + } attr_id; + static GPUVertFormat mesh_analysis_format = {0}; + if (mesh_analysis_format.attr_len == 0) { + attr_id.weight = GPU_vertformat_attr_add( + &mesh_analysis_format, "weight_color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + } + + /* TODO(jbakker): Maybe move data generation to mesh_render_data_create() */ + BKE_editmesh_statvis_calc(rdata->edit_bmesh, rdata->edit_data, mesh_stat_vis); + + if (DRW_TEST_ASSIGN_VBO(vbo_mesh_analysis)) { + GPU_vertbuf_init_with_format(vbo_mesh_analysis, &mesh_analysis_format); + GPU_vertbuf_data_alloc(vbo_mesh_analysis, loops_len); + } + + const bool is_vertex_data = mesh_stat_vis->type == SCE_STATVIS_SHARP; + if (is_vertex_data) { + BM_ITER_MESH (efa, &iter_efa, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) { + uint vertex_index = BM_elem_index_get(loop->v); + GPU_vertbuf_attr_set(vbo_mesh_analysis, + attr_id.weight, + mesh_analysis_len_used, + &rdata->edit_bmesh->derivedVertColor[vertex_index]); + mesh_analysis_len_used += 1; + } + } + } + else { + uint face_index; + BM_ITER_MESH_INDEX (efa, &iter_efa, bm, BM_FACES_OF_MESH, face_index) { + BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) { + GPU_vertbuf_attr_set(vbo_mesh_analysis, + attr_id.weight, + mesh_analysis_len_used, + &rdata->edit_bmesh->derivedFaceColor[face_index]); + mesh_analysis_len_used += 1; + } + } + } + + // Free temp data in edit bmesh + BKE_editmesh_color_free(rdata->edit_bmesh); + + /* Resize & Finish */ + if (mesh_analysis_len_used != loops_len) { + if (vbo_mesh_analysis != NULL) { + GPU_vertbuf_data_resize(vbo_mesh_analysis, mesh_analysis_len_used); + } + } +} /* Indices */ #define NO_EDGE INT_MAX @@ -4195,6 +4264,12 @@ GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me) return DRW_batch_request(&cache->batch.wire_edges); } +GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + return DRW_batch_request(&cache->batch.edit_mesh_analysis); +} + GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len, @@ -4898,6 +4973,13 @@ void DRW_mesh_batch_cache_create_requested( DRW_vbo_request(cache->batch.edit_facedots, &cache->edit.facedots_pos_nor_data); } + /* Mesh Analysis */ + if (DRW_batch_requested(cache->batch.edit_mesh_analysis, GPU_PRIM_TRIS)) { + DRW_ibo_request(cache->batch.edit_mesh_analysis, &cache->ibo.edit_loops_tris); + DRW_vbo_request(cache->batch.edit_mesh_analysis, &cache->edit.loop_pos_nor); + DRW_vbo_request(cache->batch.edit_mesh_analysis, &cache->edit.loop_mesh_analysis); + } + /* Edit UV */ if (DRW_batch_requested(cache->batch.edituv_faces, GPU_PRIM_TRI_FAN)) { DRW_ibo_request(cache->batch.edituv_faces, &cache->ibo.edituv_loops_tri_fans); @@ -5050,6 +5132,9 @@ void DRW_mesh_batch_cache_create_requested( cache->edit.facedots_pos_nor_data, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, + cache->edit.loop_mesh_analysis, + MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_stretch_angle, combined_edit_flag); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_stretch_area, combined_edit_flag); DRW_ADD_FLAG_FROM_VBO_REQUEST( @@ -5177,6 +5262,9 @@ void DRW_mesh_batch_cache_create_requested( if (DRW_ibo_requested(cache->ibo.edit_loops_tris)) { mesh_create_edit_loops_tris(rdata, cache->ibo.edit_loops_tris); } + if (DRW_vbo_requested(cache->edit.loop_mesh_analysis)) { + mesh_create_edit_mesh_analysis(rdata, cache->edit.loop_mesh_analysis); + } /* UV editor */ /** diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index 31f1515d8f5..a83926f6568 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -55,6 +55,8 @@ extern char datatoc_edit_mesh_overlay_geom_glsl[]; extern char datatoc_edit_mesh_overlay_mix_frag_glsl[]; extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[]; extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[]; +extern char datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl[]; +extern char datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl[]; extern char datatoc_edit_normals_vert_glsl[]; extern char datatoc_edit_normals_geom_glsl[]; extern char datatoc_common_globals_lib_glsl[]; @@ -75,6 +77,7 @@ typedef struct EDIT_MESH_PassList { struct DRWPass *edit_face_occluded; struct DRWPass *mix_occlude; struct DRWPass *facefill_occlude; + struct DRWPass *mesh_analysis_pass; struct DRWPass *normals; } EDIT_MESH_PassList; @@ -115,6 +118,10 @@ typedef struct EDIT_MESH_Shaders { GPUShader *normals_loop; GPUShader *normals; GPUShader *depth; + + /* Mesh analysis shader */ + GPUShader *mesh_analysis_face; + GPUShader *mesh_analysis_vertex; } EDIT_MESH_Shaders; /* *********** STATIC *********** */ @@ -149,6 +156,7 @@ typedef struct EDIT_MESH_PrivateData { DRWShadingGroup *facedot_shgrp_in_front; DRWShadingGroup *facefill_occluded_shgrp; + DRWShadingGroup *mesh_analysis_shgrp; int data_mask[4]; int ghost_ob; @@ -278,6 +286,22 @@ static void EDIT_MESH_engine_init(void *vedata) .defs = (const char *[]){sh_cfg_data->def, NULL}, }); + /* Mesh Analysis */ + sh_data->mesh_analysis_face = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, + datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl, + NULL}, + .frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, "#define FACE_COLOR\n", NULL}, + }); + sh_data->mesh_analysis_vertex = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, + datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl, + NULL}, + .frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, "#define VERTEX_COLOR\n", NULL}, + }); + sh_data->depth = DRW_shader_create_3d_depth_only(draw_ctx->sh_cfg); } } @@ -509,6 +533,18 @@ static void EDIT_MESH_cache_init(void *vedata) } } + { + /* Mesh Analysis Pass */ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND; + psl->mesh_analysis_pass = DRW_pass_create("Mesh Analysis", state); + const bool is_vertex_color = scene->toolsettings->statvis.type == SCE_STATVIS_SHARP; + stl->g_data->mesh_analysis_shgrp = DRW_shgroup_create( + is_vertex_color ? sh_data->mesh_analysis_vertex : sh_data->mesh_analysis_face, + psl->mesh_analysis_pass); + if (rv3d->rflag & RV3D_CLIPPING) { + DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->mesh_analysis_shgrp, rv3d); + } + } /* For in front option */ psl->edit_face_overlay_in_front = edit_mesh_create_overlay_pass( &face_mod, @@ -628,6 +664,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0; bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0; bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0; + bool do_show_mesh_analysis = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_STATVIS) != 0; bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0; bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0; bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0; @@ -656,6 +693,19 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) DRW_shgroup_call_add(g_data->fweights_shgrp, geom, ob->obmat); } + if (do_show_mesh_analysis) { + Mesh *me = (Mesh *)ob->data; + BMEditMesh *embm = me->edit_mesh; + const bool is_original = embm->mesh_eval_final && \ + (embm->mesh_eval_final->runtime.is_original == true); + if (is_original) { + geom = DRW_cache_mesh_surface_mesh_analysis_get(ob); + if (geom) { + DRW_shgroup_call_add(g_data->mesh_analysis_shgrp, geom, ob->obmat); + } + } + } + if (do_occlude_wire || do_in_front) { geom = DRW_cache_mesh_surface_get(ob); DRW_shgroup_call_add(do_in_front ? g_data->depth_shgrp_hidden_wire_in_front : @@ -731,6 +781,7 @@ static void EDIT_MESH_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DRW_draw_pass(psl->weight_faces); + DRW_draw_pass(psl->mesh_analysis_pass); DRW_draw_pass(psl->depth_hidden_wire); diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl new file mode 100644 index 00000000000..8581453e810 --- /dev/null +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl @@ -0,0 +1,14 @@ +out vec4 fragColor; + +#ifdef FACE_COLOR +flat in vec4 weightColor; +#endif + +#ifdef VERTEX_COLOR +in vec4 weightColor; +#endif + +void main() +{ + fragColor = weightColor; +} diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl new file mode 100644 index 00000000000..94d8d2e701c --- /dev/null +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl @@ -0,0 +1,23 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ModelMatrix; + +in vec3 pos; +in vec4 weight_color; + +#ifdef FACE_COLOR +flat out vec4 weightColor; +#endif + +#ifdef VERTEX_COLOR +out vec4 weightColor; +#endif + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + weightColor = vec4(weight_color.rgb, 1.0); + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); +#endif +} |