Fix T68380 Skin modifier root not displayed
This commit is contained in:
parent
8956666899
commit
4ddf3215a7
Notes:
blender-bot
2023-02-14 06:00:47 +01:00
Referenced by commit 7e78fbf2de
, Fix assert and memleak in recent Skin Root Display patch
|
@ -293,6 +293,7 @@ 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_mesh_skin_root_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)
|
||||
|
|
|
@ -81,7 +81,7 @@ BLI_INLINE int mesh_render_mat_len_get(Mesh *me)
|
|||
|
||||
typedef struct MeshBufferCache {
|
||||
/* Every VBO below contains at least enough
|
||||
* data for every loops in the mesh (except fdots).
|
||||
* data for every loops in the mesh (except fdots and skin roots).
|
||||
* For some VBOs, it extends to (in this exact order) :
|
||||
* loops + loose_edges*2 + loose_verts */
|
||||
struct {
|
||||
|
@ -104,6 +104,7 @@ typedef struct MeshBufferCache {
|
|||
GPUVertBuf *fdots_uv;
|
||||
// GPUVertBuf *fdots_edit_data; /* inside fdots_nor for now. */
|
||||
GPUVertBuf *fdots_edituv_data;
|
||||
GPUVertBuf *skin_roots;
|
||||
/* Selection */
|
||||
GPUVertBuf *vert_idx; /* extend */
|
||||
GPUVertBuf *edge_idx; /* extend */
|
||||
|
@ -157,6 +158,7 @@ typedef enum DRWBatchFlag {
|
|||
MBC_WIRE_LOOPS = (1 << 24),
|
||||
MBC_WIRE_LOOPS_UVS = (1 << 25),
|
||||
MBC_SURF_PER_MAT = (1 << 26),
|
||||
MBC_SKIN_ROOTS = (1 << 27),
|
||||
} DRWBatchFlag;
|
||||
|
||||
#define MBC_EDITUV \
|
||||
|
@ -185,6 +187,7 @@ typedef struct MeshBatchCache {
|
|||
GPUBatch *edit_lnor;
|
||||
GPUBatch *edit_fdots;
|
||||
GPUBatch *edit_mesh_analysis;
|
||||
GPUBatch *edit_skin_roots;
|
||||
/* Edit UVs */
|
||||
GPUBatch *edituv_faces_stretch_area;
|
||||
GPUBatch *edituv_faces_stretch_angle;
|
||||
|
|
|
@ -3859,6 +3859,69 @@ static const MeshExtract extract_fdots_edituv_data = {
|
|||
};
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Skin Modifier Roots
|
||||
* \{ */
|
||||
|
||||
typedef struct SkinRootData {
|
||||
float size;
|
||||
float local_pos[3];
|
||||
} SkinRootData;
|
||||
|
||||
static void *extract_skin_roots_init(const MeshRenderData *mr, void *buf)
|
||||
{
|
||||
/* Exclusively for edit mode. */
|
||||
BLI_assert(mr->bm);
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
GPU_vertformat_attr_add(&format, "local_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
}
|
||||
GPUVertBuf *vbo = buf;
|
||||
GPU_vertbuf_init_with_format(vbo, &format);
|
||||
GPU_vertbuf_data_alloc(vbo, mr->bm->totvert);
|
||||
|
||||
SkinRootData *vbo_data = (SkinRootData *)vbo->data;
|
||||
|
||||
int root_len = 0;
|
||||
int cd_ofs = CustomData_get_offset(&mr->bm->vdata, CD_MVERT_SKIN);
|
||||
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
BM_ITER_MESH (eve, &iter, mr->bm, BM_VERTS_OF_MESH) {
|
||||
const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_ofs);
|
||||
if (vs->flag & MVERT_SKIN_ROOT) {
|
||||
vbo_data->size = (vs->radius[0] + vs->radius[1]) * 0.5f;
|
||||
copy_v3_v3(vbo_data->local_pos, eve->co);
|
||||
vbo_data++;
|
||||
root_len++;
|
||||
}
|
||||
}
|
||||
|
||||
/* It's really unlikely that all verts will be roots. Resize to avoid loosing VRAM. */
|
||||
GPU_vertbuf_data_len_set(vbo, root_len);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const MeshExtract extract_skin_roots = {
|
||||
extract_skin_roots_init,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
false,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Selection Index
|
||||
* \{ */
|
||||
|
@ -4358,6 +4421,7 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache,
|
|||
EXTRACT(vbo, edge_idx);
|
||||
EXTRACT(vbo, vert_idx);
|
||||
EXTRACT(vbo, fdot_idx);
|
||||
EXTRACT(vbo, skin_roots);
|
||||
|
||||
EXTRACT(ibo, tris);
|
||||
EXTRACT(ibo, lines);
|
||||
|
|
|
@ -142,6 +142,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edit_edges(struct Mesh *me);
|
|||
struct GPUBatch *DRW_mesh_batch_cache_get_edit_vnors(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_edit_lnors(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_edit_skin_roots(struct Mesh *me);
|
||||
/* edit-mesh selection */
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me);
|
||||
|
|
|
@ -879,6 +879,13 @@ GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(Mesh *me)
|
|||
return DRW_batch_request(&cache->batch.edit_fdots);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edit_skin_roots(Mesh *me)
|
||||
{
|
||||
MeshBatchCache *cache = mesh_batch_cache_get(me);
|
||||
mesh_batch_cache_add_request(cache, MBC_SKIN_ROOTS);
|
||||
return DRW_batch_request(&cache->batch.edit_skin_roots);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -1319,6 +1326,18 @@ void DRW_mesh_batch_cache_create_requested(
|
|||
DRW_vbo_request(cache->batch.edit_fdots, &mbufcache->vbo.fdots_pos);
|
||||
DRW_vbo_request(cache->batch.edit_fdots, &mbufcache->vbo.fdots_nor);
|
||||
}
|
||||
if (DRW_batch_requested(cache->batch.edit_skin_roots, GPU_PRIM_LINES)) {
|
||||
DRW_vbo_request(cache->batch.edit_skin_roots, &mbufcache->vbo.skin_roots);
|
||||
/* HACK(fclem): This is a workaround the deferred batch init
|
||||
* that prevent drawing using DRW_shgroup_call_instances_with_attribs.
|
||||
* So we instead create the whole instancing batch here.
|
||||
* Note that we use GPU_PRIM_LINES instead of expected GPU_PRIM_LINE_STRIP
|
||||
* in order to mimic the old stipple pattern. */
|
||||
cache->batch.edit_skin_roots->inst = cache->batch.edit_skin_roots->verts[0];
|
||||
cache->batch.edit_skin_roots->verts[0] = NULL;
|
||||
GPUBatch *circle = DRW_cache_screenspace_circle_get();
|
||||
GPU_batch_vertbuf_add(cache->batch.edit_skin_roots, circle->verts[0]);
|
||||
}
|
||||
|
||||
/* Selection */
|
||||
if (DRW_batch_requested(cache->batch.edit_selection_verts, GPU_PRIM_POINTS)) {
|
||||
|
|
|
@ -83,6 +83,7 @@ void DRW_globals_update(void)
|
|||
UI_GetThemeColor4fv(TH_VNORMAL, gb->colorVNormal);
|
||||
UI_GetThemeColor4fv(TH_LNORMAL, gb->colorLNormal);
|
||||
UI_GetThemeColor4fv(TH_FACE_DOT, gb->colorFaceDot);
|
||||
UI_GetThemeColor4fv(TH_SKIN_ROOT, gb->colorSkinRoot);
|
||||
UI_GetThemeColor4fv(TH_BACK, gb->colorBackground);
|
||||
|
||||
/* Custom median color to slightly affect the edit mesh colors. */
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef struct GlobalsUboStorage {
|
|||
float colorVNormal[4];
|
||||
float colorLNormal[4];
|
||||
float colorFaceDot[4];
|
||||
float colorSkinRoot[4];
|
||||
|
||||
float colorDeselect[4];
|
||||
float colorOutline[4];
|
||||
|
|
|
@ -55,6 +55,7 @@ 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_edit_mesh_skin_root_vert_glsl[];
|
||||
extern char datatoc_common_globals_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
|
||||
|
@ -114,6 +115,7 @@ typedef struct EDIT_MESH_Shaders {
|
|||
GPUShader *overlay_edge_flat;
|
||||
GPUShader *overlay_face;
|
||||
GPUShader *overlay_facedot;
|
||||
GPUShader *overlay_skin_root;
|
||||
|
||||
GPUShader *overlay_mix;
|
||||
GPUShader *overlay_facefill;
|
||||
|
@ -141,6 +143,7 @@ typedef struct EDIT_MESH_ComponentShadingGroupList {
|
|||
DRWShadingGroup *faces;
|
||||
DRWShadingGroup *faces_cage;
|
||||
DRWShadingGroup *facedots;
|
||||
DRWShadingGroup *skin_roots;
|
||||
} EDIT_MESH_ComponentShadingGroupList;
|
||||
|
||||
typedef struct EDIT_MESH_PrivateData {
|
||||
|
@ -266,6 +269,12 @@ static void EDIT_MESH_engine_init(void *vedata)
|
|||
.frag = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, NULL},
|
||||
});
|
||||
sh_data->overlay_skin_root = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){lib, datatoc_edit_mesh_skin_root_vert_glsl, NULL},
|
||||
.frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, NULL},
|
||||
});
|
||||
|
||||
MEM_freeN(lib);
|
||||
|
||||
sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl,
|
||||
|
@ -341,6 +350,7 @@ static void edit_mesh_create_overlay_passes(float face_alpha,
|
|||
GPUShader *edge_sh = (select_vert) ? sh_data->overlay_edge : sh_data->overlay_edge_flat;
|
||||
GPUShader *face_sh = sh_data->overlay_face;
|
||||
GPUShader *facedot_sh = sh_data->overlay_facedot;
|
||||
GPUShader *skin_root_sh = sh_data->overlay_skin_root;
|
||||
|
||||
/* Faces */
|
||||
passes->faces = DRW_pass_create("Edit Mesh Faces", DRW_STATE_WRITE_COLOR | statemod);
|
||||
|
@ -388,6 +398,10 @@ static void edit_mesh_create_overlay_passes(float face_alpha,
|
|||
if (rv3d->rflag & RV3D_CLIPPING) {
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES);
|
||||
}
|
||||
|
||||
grp = shgrps->skin_roots = DRW_shgroup_create(skin_root_sh, passes->verts);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
|
||||
}
|
||||
if (select_face) {
|
||||
grp = shgrps->facedots = DRW_shgroup_create(facedot_sh, passes->verts);
|
||||
|
@ -632,21 +646,24 @@ static void EDIT_MESH_cache_init(void *vedata)
|
|||
|
||||
static void edit_mesh_add_ob_to_pass(Scene *scene,
|
||||
Object *ob,
|
||||
DRWShadingGroup *skin_roots_shgrp,
|
||||
DRWShadingGroup *vert_shgrp,
|
||||
DRWShadingGroup *edge_shgrp,
|
||||
DRWShadingGroup *face_shgrp,
|
||||
DRWShadingGroup *face_cage_shgrp,
|
||||
DRWShadingGroup *facedot_shgrp)
|
||||
{
|
||||
struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter;
|
||||
struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter, *skin_roots;
|
||||
ToolSettings *tsettings = scene->toolsettings;
|
||||
|
||||
bool has_edit_mesh_cage = false;
|
||||
bool has_skin_roots = false;
|
||||
/* TODO: Should be its own function. */
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
BMEditMesh *embm = me->edit_mesh;
|
||||
if (embm) {
|
||||
has_edit_mesh_cage = embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final);
|
||||
has_skin_roots = CustomData_get_offset(&embm->bm->vdata, CD_MVERT_SKIN) != -1;
|
||||
}
|
||||
|
||||
face_shgrp = (has_edit_mesh_cage) ? face_cage_shgrp : face_shgrp;
|
||||
|
@ -659,6 +676,21 @@ static void edit_mesh_add_ob_to_pass(Scene *scene,
|
|||
if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
|
||||
geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
|
||||
DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
|
||||
|
||||
if (has_skin_roots) {
|
||||
DRWShadingGroup *grp = DRW_shgroup_create_sub(skin_roots_shgrp);
|
||||
/* We need to upload the matrix. But the ob can be temporary allocated so we cannot
|
||||
* use direct reference to ob->obmat. */
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[0]", ob->obmat[0]);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[1]", ob->obmat[1]);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[2]", ob->obmat[2]);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[3]", ob->obmat[3]);
|
||||
|
||||
skin_roots = DRW_mesh_batch_cache_get_edit_skin_roots(ob->data);
|
||||
/* NOTE(fclem) We cannot use ob here since it would offset the instance attribs with
|
||||
* baseinstance offset. */
|
||||
DRW_shgroup_call(grp, skin_roots, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0) {
|
||||
|
@ -721,6 +753,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
|
|||
if (g_data->do_zbufclip) {
|
||||
edit_mesh_add_ob_to_pass(scene,
|
||||
ob,
|
||||
g_data->edit_shgrps.skin_roots,
|
||||
g_data->edit_shgrps.verts,
|
||||
g_data->edit_shgrps.edges,
|
||||
g_data->facefill_occluded_shgrp,
|
||||
|
@ -730,6 +763,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
|
|||
else if (do_in_front) {
|
||||
edit_mesh_add_ob_to_pass(scene,
|
||||
ob,
|
||||
g_data->edit_in_front_shgrps.skin_roots,
|
||||
g_data->edit_in_front_shgrps.verts,
|
||||
g_data->edit_in_front_shgrps.edges,
|
||||
g_data->edit_in_front_shgrps.faces,
|
||||
|
@ -739,6 +773,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
|
|||
else {
|
||||
edit_mesh_add_ob_to_pass(scene,
|
||||
ob,
|
||||
g_data->edit_shgrps.skin_roots,
|
||||
g_data->edit_shgrps.verts,
|
||||
g_data->edit_shgrps.edges,
|
||||
g_data->edit_shgrps.faces,
|
||||
|
|
|
@ -34,6 +34,7 @@ layout(std140) uniform globalsBlock
|
|||
vec4 colorVNormal;
|
||||
vec4 colorLNormal;
|
||||
vec4 colorFaceDot;
|
||||
vec4 colorSkinRoot;
|
||||
vec4 colorDeselect;
|
||||
vec4 colorOutline;
|
||||
vec4 colorLightNoAlpha;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/* Need dedicated obmat since we use instancing attribs
|
||||
* (we cannot let have baseinstance mess them). */
|
||||
uniform vec4 editModelMat[4];
|
||||
uniform vec3 screen_vecs[2];
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec2 pos;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in float size;
|
||||
in vec3 local_pos;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
mat4 obmat = mat4(editModelMat[0], editModelMat[1], editModelMat[2], editModelMat[3]);
|
||||
/* Could be optimized... but it is only for a handful of verts so not a priority. */
|
||||
mat3 imat = inverse(mat3(obmat));
|
||||
vec3 right = normalize(imat * vec3(screen_vecs[0]));
|
||||
vec3 up = normalize(imat * vec3(screen_vecs[1]));
|
||||
vec3 screen_pos = (right * pos.x + up * pos.y) * size;
|
||||
vec4 pos_4d = obmat * vec4(local_pos + screen_pos, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * pos_4d;
|
||||
finalColor = colorSkinRoot;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(pos_4d.xyz);
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue