Retopology: Use Material Colors In Overlay #114969

Closed
Jeroen Bakker wants to merge 8 commits from Jeroen-Bakker:viewport/retopo-material-colors into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
11 changed files with 113 additions and 9 deletions

View File

@ -7100,6 +7100,9 @@ class VIEW3D_PT_overlay_edit_mesh_shading(Panel):
sub = row.row()
sub.active = overlay.show_retopology
sub.prop(overlay, "retopology_offset", text="Retopology")
if overlay.show_retopology:
sub = col.row()
sub.prop(overlay, "retopology_color_type", expand=True)
col.prop(overlay, "show_weight", text="Vertex Group Weights")
if overlay.show_weight:

View File

@ -107,6 +107,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_edit_mesh_depth();
grp = pd->edit_mesh_depth_grp[i] = DRW_shgroup_create(sh, psl->edit_mesh_depth_ps[i]);
DRW_shgroup_uniform_float_copy(grp, "retopologyOffset", retopology_offset);
DRW_shgroup_uniform_vec4(grp, "retopologyColor", G_draw.block.color_face_retopology, 1);
}
{
/* Normals */
@ -126,6 +127,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_float_copy(
grp, "normalScreenSize", v3d->overlay.normals_constant_screen_size);
DRW_shgroup_uniform_float_copy(grp, "retopologyOffset", retopology_offset);
DRW_shgroup_uniform_vec4(grp, "retopologyColor", G_draw.block.color_face_retopology, 1);
}
{
/* Mesh Analysis Pass */
@ -167,6 +169,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_bool_copy(grp, "selectFace", select_face);
DRW_shgroup_uniform_bool_copy(grp, "wireShading", is_wire_shmode);
DRW_shgroup_uniform_float_copy(grp, "retopologyOffset", retopology_offset);
DRW_shgroup_uniform_vec4(grp, "retopologyColor", G_draw.block.color_face_retopology, 1);
}
if (do_zbufclip) {
@ -187,6 +190,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_bool_copy(grp, "selectEdge", select_edge);
DRW_shgroup_uniform_bool_copy(grp, "do_smooth_wire", do_smooth_wire);
DRW_shgroup_uniform_float_copy(grp, "retopologyOffset", retopology_offset);
DRW_shgroup_uniform_vec4(grp, "retopologyColor", G_draw.block.color_face_retopology, 1);
/* Verts */
state |= DRW_STATE_WRITE_DEPTH;
@ -201,11 +205,13 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tex);
DRW_shgroup_uniform_ivec4_copy(grp, "dataMask", vert_mask);
DRW_shgroup_uniform_float_copy(grp, "retopologyOffset", retopology_offset);
DRW_shgroup_uniform_vec4(grp, "retopologyColor", G_draw.block.color_face_retopology, 1);
sh = OVERLAY_shader_edit_mesh_skin_root();
grp = pd->edit_mesh_skin_roots_grp[i] = DRW_shgroup_create(sh, psl->edit_mesh_verts_ps[i]);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "retopologyOffset", retopology_offset);
DRW_shgroup_uniform_vec4(grp, "retopologyColor", G_draw.block.color_face_retopology, 1);
}
/* Face-dots */
if (select_face && show_face_dots) {
@ -216,6 +222,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tex);
DRW_shgroup_uniform_ivec4_copy(grp, "dataMask", vert_mask);
DRW_shgroup_uniform_float_copy(grp, "retopologyOffset", retopology_offset);
DRW_shgroup_uniform_vec4(grp, "retopologyColor", G_draw.block.color_face_retopology, 1);
DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
}
else {
@ -249,10 +256,32 @@ static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob
pd->edit_mesh_faces_grp[in_front];
skin_roots_shgrp = pd->edit_mesh_skin_roots_grp[in_front];
const bool show_retopology = pd->overlay.edit_flag & V3D_OVERLAY_EDIT_RETOPOLOGY;
const bool use_retopology_material_colors = pd->overlay.retopology_color_type ==
V3D_RETOPOLOGY_COLOR_MATERIAL;
if (show_retopology && use_retopology_material_colors) {
const int material_count = DRW_cache_object_material_count_get(ob);
GPUBatch **batches = DRW_mesh_batch_cache_get_edit_surface(me);
float alpha = G_draw.block.color_face_retopology[3];
for (int64_t material_slot : blender::IndexRange(material_count)) {
GPUBatch *geom = batches[material_slot];
if (geom == nullptr) {
continue;
}
Material *material = BKE_object_material_get_eval(ob, material_slot + 1);
float4 retopology_color = material ? float4(material->r, material->g, material->b, alpha) :
float4(0.8f, 0.8f, 0.8f, alpha);
DRWShadingGroup *grp = DRW_shgroup_create_sub(face_shgrp);
DRW_shgroup_uniform_vec4_copy(grp, "retopologyColor", retopology_color);
DRW_shgroup_call_no_cull(grp, geom, ob);
}
}
else {
geom_tris = DRW_mesh_batch_cache_get_edit_triangles(me);
DRW_shgroup_call_no_cull(face_shgrp, geom_tris, ob);
}
geom_edges = DRW_mesh_batch_cache_get_edit_edges(me);
geom_tris = DRW_mesh_batch_cache_get_edit_triangles(me);
DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
DRW_shgroup_call_no_cull(face_shgrp, geom_tris, ob);
if (pd->edit_mesh.select_vert) {
geom_verts = DRW_mesh_batch_cache_get_edit_vertices(me);

View File

@ -22,6 +22,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common)
.push_constant(Type::BOOL, "selectEdge")
.push_constant(Type::FLOAT, "alpha")
.push_constant(Type::FLOAT, "retopologyOffset")
.push_constant(Type::VEC4, "retopologyColor")
.push_constant(Type::IVEC4, "dataMask")
.vertex_source("overlay_edit_mesh_vert.glsl")
.additional_info("draw_modelmat", "draw_globals");
@ -37,6 +38,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common_no_geom)
.push_constant(Type::BOOL, "selectEdge")
.push_constant(Type::FLOAT, "alpha")
.push_constant(Type::FLOAT, "retopologyOffset")
.push_constant(Type::VEC4, "retopologyColor")
.push_constant(Type::IVEC4, "dataMask")
.vertex_source("overlay_edit_mesh_vert_no_geom.glsl")
.additional_info("draw_modelmat", "draw_globals");

View File

@ -58,7 +58,7 @@ vec4 EDIT_MESH_face_color(uint face_flag)
bool face_retopo = (retopologyOffset > 0.0);
vec4 selected_face_col = (selectFace) ? colorFaceModeSelect : colorFaceSelect;
vec4 color = colorFace;
color = face_retopo ? colorFaceRetopology : color;
color = face_retopo ? retopologyColor : color;
color = face_freestyle ? colorFaceFreestyle : color;
color = face_selected ? selected_face_col : color;
if (selectFace && face_active) {

View File

@ -216,7 +216,8 @@ enum DRWBatchFlag {
MBC_WIRE_LOOPS_UVS = (1u << MBC_BATCH_INDEX(wire_loops_uvs)),
MBC_SCULPT_OVERLAYS = (1u << MBC_BATCH_INDEX(sculpt_overlays)),
MBC_VIEWER_ATTRIBUTE_OVERLAY = (1u << MBC_BATCH_INDEX(surface_viewer_attribute)),
MBC_SURFACE_PER_MAT = (1u << MBC_BATCH_LEN),
MBC_EDIT_SURFACE_PER_MAT = (1u << MBC_BATCH_LEN),
MBC_SURFACE_PER_MAT = (1u << (MBC_BATCH_LEN + 1)),
};
ENUM_OPERATORS(DRWBatchFlag, MBC_SURFACE_PER_MAT);
@ -267,6 +268,7 @@ struct MeshBatchCache {
GPUIndexBuf **tris_per_mat;
GPUBatch **surface_per_mat;
GPUBatch **edit_surface_per_mat;
DRWSubdivCache *subdiv_cache;

View File

@ -185,6 +185,7 @@ GPUBatch *DRW_mesh_batch_cache_get_all_edges(Mesh *me);
GPUBatch *DRW_mesh_batch_cache_get_loose_edges(Mesh *me);
GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold);
GPUBatch *DRW_mesh_batch_cache_get_surface(Mesh *me);
GPUBatch **DRW_mesh_batch_cache_get_edit_surface(Mesh *me);
GPUBatch *DRW_mesh_batch_cache_get_surface_edges(Object *object, Mesh *me);
GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Object *object,
Mesh *me,

View File

@ -106,7 +106,7 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
MBC_EDIT_SELECTION_VERTS | MBC_EDIT_SELECTION_EDGES | MBC_EDIT_SELECTION_FACES |
MBC_ALL_VERTS | MBC_ALL_EDGES | MBC_LOOSE_EDGES | MBC_EDGE_DETECTION |
MBC_WIRE_EDGES | MBC_WIRE_LOOPS | MBC_SCULPT_OVERLAYS | MBC_VIEWER_ATTRIBUTE_OVERLAY |
MBC_SURFACE_PER_MAT;
MBC_SURFACE_PER_MAT | MBC_EDIT_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.lnor):
return MBC_SURFACE | MBC_EDIT_LNOR | MBC_WIRE_LOOPS | MBC_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.edge_fac):
@ -124,7 +124,7 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
case BUFFER_INDEX(vbo.orco):
return MBC_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.edit_data):
return MBC_EDIT_TRIANGLES | MBC_EDIT_EDGES | MBC_EDIT_VERTICES;
return MBC_EDIT_TRIANGLES | MBC_EDIT_EDGES | MBC_EDIT_VERTICES | MBC_EDIT_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.edituv_data):
return MBC_EDITUV_FACES | MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE |
MBC_EDITUV_EDGES | MBC_EDITUV_VERTS;
@ -195,12 +195,13 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
case BUFFER_INDEX(ibo.edituv_fdots):
return MBC_EDITUV_FACEDOTS;
case TRIS_PER_MAT_INDEX:
return MBC_SURFACE_PER_MAT;
return MBC_SURFACE_PER_MAT | MBC_EDIT_SURFACE_PER_MAT;
}
return (DRWBatchFlag)0;
}
static void mesh_batch_cache_discard_surface_batches(MeshBatchCache &cache);
static void mesh_batch_cache_discard_edit_surface_batches(MeshBatchCache &cache);
static void mesh_batch_cache_clear(MeshBatchCache &cache);
static void mesh_batch_cache_discard_batch(MeshBatchCache &cache, const DRWBatchFlag batch_map)
@ -216,6 +217,9 @@ static void mesh_batch_cache_discard_batch(MeshBatchCache &cache, const DRWBatch
if (batch_map & MBC_SURFACE_PER_MAT) {
mesh_batch_cache_discard_surface_batches(cache);
}
if (batch_map & MBC_EDIT_SURFACE_PER_MAT) {
mesh_batch_cache_discard_edit_surface_batches(cache);
}
}
/* Return true is all layers in _b_ are inside _a_. */
@ -599,6 +603,8 @@ static void mesh_batch_cache_init(Object *object, Mesh *me)
cache->mat_len = mesh_render_mat_len_get(object, me);
cache->surface_per_mat = static_cast<GPUBatch **>(
MEM_callocN(sizeof(*cache->surface_per_mat) * cache->mat_len, __func__));
cache->edit_surface_per_mat = static_cast<GPUBatch **>(
MEM_callocN(sizeof(*cache->edit_surface_per_mat) * cache->mat_len, __func__));
cache->tris_per_mat = static_cast<GPUIndexBuf **>(
MEM_callocN(sizeof(*cache->tris_per_mat) * cache->mat_len, __func__));
@ -648,6 +654,27 @@ static void mesh_batch_cache_request_surface_batches(MeshBatchCache &cache)
}
}
static void mesh_batch_cache_request_edit_surface_batches(MeshBatchCache &cache)
{
mesh_batch_cache_add_request(cache, MBC_EDIT_TRIANGLES);
DRW_batch_request(&cache.batch.edit_triangles);
for (int i = 0; i < cache.mat_len; i++) {
DRW_batch_request(&cache.edit_surface_per_mat[i]);
}
}
/* Free batches with material-mapped looptris.
* NOTE: The updating of the indices buffers (#tris_per_mat) is handled in the extractors.
* No need to discard them here. */
static void mesh_batch_cache_discard_edit_surface_batches(MeshBatchCache &cache)
{
GPU_BATCH_DISCARD_SAFE(cache.batch.edit_triangles);
for (int i = 0; i < cache.mat_len; i++) {
GPU_BATCH_DISCARD_SAFE(cache.edit_surface_per_mat[i]);
}
cache.batch_ready &= ~MBC_EDIT_TRIANGLES;
}
/* Free batches with material-mapped looptris.
* NOTE: The updating of the indices buffers (#tris_per_mat) is handled in the extractors.
* No need to discard they here. */
@ -827,7 +854,9 @@ static void mesh_batch_cache_clear(MeshBatchCache &cache)
mesh_batch_cache_discard_shaded_tri(cache);
mesh_batch_cache_discard_uvedit(cache);
mesh_batch_cache_discard_edit_surface_batches(cache);
MEM_SAFE_FREE(cache.surface_per_mat);
MEM_SAFE_FREE(cache.edit_surface_per_mat);
cache.mat_len = 0;
cache.batch_ready = (DRWBatchFlag)0;
@ -1086,10 +1115,18 @@ GPUVertBuf *DRW_mesh_batch_cache_pos_vertbuf_get(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_edit_triangles(Mesh *me)
{
MeshBatchCache &cache = *mesh_batch_cache_get(me);
mesh_batch_cache_add_request(cache, MBC_EDIT_TRIANGLES);
// mesh_batch_cache_add_request(cache, MBC_EDIT_TRIANGLES);

I'm not sure about always requesting the material IBOs even for normal edit mode.

I'm not sure about always requesting the material IBOs even for normal edit mode.
mesh_batch_cache_request_edit_surface_batches(cache);
return DRW_batch_request(&cache.batch.edit_triangles);
}
GPUBatch **DRW_mesh_batch_cache_get_edit_surface(Mesh *me)
{
MeshBatchCache &cache = *mesh_batch_cache_get(me);
mesh_batch_cache_request_edit_surface_batches(cache);
return cache.edit_surface_per_mat;
}
GPUBatch *DRW_mesh_batch_cache_get_edit_edges(Mesh *me)
{
MeshBatchCache &cache = *mesh_batch_cache_get(me);
@ -1657,6 +1694,17 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
}
}
assert_deps_valid(MBC_EDIT_SURFACE_PER_MAT,
{BUFFER_INDEX(vbo.pos_nor), BUFFER_INDEX(vbo.edit_data)});
assert_deps_valid(MBC_EDIT_SURFACE_PER_MAT, {TRIS_PER_MAT_INDEX});
for (int i = 0; i < cache.mat_len; i++) {
if (DRW_batch_requested(cache.edit_surface_per_mat[i], GPU_PRIM_TRIS)) {
DRW_ibo_request(cache.edit_surface_per_mat[i], &cache.tris_per_mat[i]);
DRW_vbo_request(cache.edit_surface_per_mat[i], &mbuflist->vbo.pos_nor);
DRW_vbo_request(cache.edit_surface_per_mat[i], &mbuflist->vbo.edit_data);
}
}
mbuflist = (do_cage) ? &cache.cage.buff : &cache.final.buff;
/* Edit Mesh */

View File

@ -42,6 +42,7 @@
.wireframe_threshold = 1.0f, \
.wireframe_opacity = 1.0f, \
.retopology_offset = 0.2f, \
.retopology_color_type = V3D_RETOPOLOGY_COLOR_THEME, \
.viewer_attribute_opacity = 1.0f, \
.xray_alpha_bone = 0.5f, \
.bone_wire_alpha = 1.0f, \

View File

@ -37,6 +37,12 @@ typedef enum eV3DShadingColorType {
V3D_SHADING_VERTEX_COLOR = 5,
} eV3DShadingColorType;
/** #View3DOverlay.retopology_color_type */
typedef enum eV3DRetopologyColorType {
V3D_RETOPOLOGY_COLOR_THEME = 0,
V3D_RETOPOLOGY_COLOR_MATERIAL = 1,
} eV3DRetopologyColorType;
/** #View3DShading.background_type */
typedef enum eV3DShadingBackgroundType {
V3D_SHADING_BACKGROUND_THEME = 0,

View File

@ -219,6 +219,7 @@ typedef struct View3DOverlay {
float wireframe_threshold;
float wireframe_opacity;
float retopology_offset;
int retopology_color_type;
/** Grease pencil settings. */
float gpencil_paper_opacity;
@ -232,7 +233,6 @@ typedef struct View3DOverlay {
/** Curves sculpt mode settings. */
float sculpt_curves_cage_opacity;
char _pad[4];
} View3DOverlay;
/** #View3DOverlay.handle_display */

View File

@ -430,6 +430,12 @@ static const EnumPropertyItem rna_enum_shading_color_type_items[] = {
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem rna_enum_retopology_color_type_items[] = {
{V3D_RETOPOLOGY_COLOR_THEME, "THEME", 0, "Theme", "Show theme color"},
{V3D_RETOPOLOGY_COLOR_MATERIAL, "MATERIAL", 0, "Material", "Show material color"},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem rna_enum_shading_wire_color_type_items[] = {
{V3D_SHADING_SINGLE_COLOR,
"THEME",
@ -4594,6 +4600,12 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, nullptr);
prop = RNA_def_property(srna, "retopology_color_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, nullptr, "overlay.retopology_color_type");
RNA_def_property_enum_items(prop, rna_enum_retopology_color_type_items);
RNA_def_property_ui_text(prop, "Retopology Color", "Color to use for retopology overlay");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, nullptr);
prop = RNA_def_property(srna, "show_face_normals", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "overlay.edit_flag", V3D_OVERLAY_EDIT_FACE_NORMALS);
RNA_def_property_ui_text(prop, "Display Normals", "Display face normals as lines");