diff --git a/scripts/startup/bl_ui/space_image.py b/scripts/startup/bl_ui/space_image.py index 1343c8c5f26..43d7b21dd02 100644 --- a/scripts/startup/bl_ui/space_image.py +++ b/scripts/startup/bl_ui/space_image.py @@ -109,7 +109,6 @@ class IMAGE_MT_view(Menu): layout.separator() if paint.brush and (context.image_paint_object or sima.mode == 'PAINT'): - layout.prop(uv, "show_texpaint") layout.prop(tool_settings, "show_uv_local_view", text="Show Same Material") layout.menu("INFO_MT_area") @@ -1682,7 +1681,7 @@ class IMAGE_PT_overlay_uv_edit_geometry(Panel): row.prop(uvedit, "show_faces", text="Faces") -class IMAGE_PT_overlay_texture_paint(Panel): +class IMAGE_PT_overlay_uv_display(Panel): bl_space_type = 'IMAGE_EDITOR' bl_region_type = 'HEADER' bl_label = "Geometry" @@ -1691,7 +1690,7 @@ class IMAGE_PT_overlay_texture_paint(Panel): @classmethod def poll(cls, context): sima = context.space_data - return (sima and (sima.show_paint)) + return (sima and not (sima.show_uvedit)) def draw(self, context): layout = self.layout @@ -1701,7 +1700,8 @@ class IMAGE_PT_overlay_texture_paint(Panel): overlay = sima.overlay layout.active = overlay.show_overlays - layout.prop(uvedit, "show_texpaint") + layout.prop(uvedit, "show_uv") + layout.prop(uvedit, "uv_face_opacity") class IMAGE_PT_overlay_image(Panel): @@ -1814,7 +1814,7 @@ classes = ( IMAGE_PT_overlay_guides, IMAGE_PT_overlay_uv_stretch, IMAGE_PT_overlay_uv_edit_geometry, - IMAGE_PT_overlay_texture_paint, + IMAGE_PT_overlay_uv_display, IMAGE_PT_overlay_image, IMAGE_AST_brush_paint, ) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index c67e4efa105..c51547af1b5 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 16 +#define BLENDER_FILE_SUBVERSION 17 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index cd3c7b9e544..aedc2ab9e4b 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -4431,6 +4431,43 @@ static void asset_browser_add_list_view(Main *bmain) } } +static void version_show_texpaint_to_show_uv(Main *bmain) +{ + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima = reinterpret_cast(sl); + if (sima->flag & SI_NO_DRAW_TEXPAINT) { + sima->flag |= SI_NO_DRAW_UV_GUIDE; + } + } + } + } + } +} + +static void version_set_uv_face_overlay_defaults(Main *bmain) +{ + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima = reinterpret_cast(sl); + /* Remove ID Code from screen name */ + const char *workspace_name = screen->id.name + 2; + /* Don't set uv_face_opacity for Texture Paint or Shading since these are workspaces + * where it's important to have unobstructed view of the Image Editor to see Image + * Textures. UV Editing is the only other default workspace with an Image Editor.*/ + if (STREQ(workspace_name, "UV Editing")) { + sima->uv_face_opacity = 1.0f; + } + } + } + } + } +} + void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 1)) { @@ -6642,6 +6679,11 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 17)) { + version_show_texpaint_to_show_uv(bmain); + version_set_uv_face_overlay_defaults(bmain); + } + /* Always run this versioning; meshes are written with the legacy format which always needs to * be converted to the new format on file load. Can be moved to a subversion check in a larger * breaking release. */ diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index 334156ea421..c27f5a8d43b 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -132,6 +132,11 @@ static void blo_update_defaults_screen(bScreen *screen, if (sima->mode == SI_MODE_VIEW) { sima->mode = SI_MODE_UV; } + sima->uv_face_opacity = 1.0f; + } + else if (STREQ(workspace_name, "Texture Paint") || STREQ(workspace_name, "Shading")) { + SpaceImage *sima = static_cast(area->spacedata.first); + sima->uv_face_opacity = 0.0f; } } else if (area->spacetype == SPACE_ACTION) { diff --git a/source/blender/draw/engines/overlay/overlay_next_instance.cc b/source/blender/draw/engines/overlay/overlay_next_instance.cc index 8a44803e218..9034cd27e1a 100644 --- a/source/blender/draw/engines/overlay/overlay_next_instance.cc +++ b/source/blender/draw/engines/overlay/overlay_next_instance.cc @@ -467,6 +467,7 @@ void Instance::begin_sync() void Instance::object_sync(ObjectRef &ob_ref, Manager &manager) { + const bool in_object_mode = ob_ref.object->mode == OB_MODE_OBJECT; const bool in_edit_mode = ob_ref.object->mode == OB_MODE_EDIT; const bool in_paint_mode = object_is_paint_mode(ob_ref.object); const bool in_sculpt_mode = object_is_sculpt_mode(ob_ref); @@ -487,13 +488,27 @@ void Instance::object_sync(ObjectRef &ob_ref, Manager &manager) layer.particles.edit_object_sync(manager, ob_ref, resources, state); } + /* For 2D UV overlays. */ + if (!state.hide_overlays && state.is_space_image()) { + switch (ob_ref.object->type) { + case OB_MESH: + if (in_edit_paint_mode) { + /* TODO(fclem): Find a better place / condition. */ + layer.mesh_uvs.edit_object_sync(manager, ob_ref, resources, state); + } + else if (in_object_mode) { + layer.mesh_uvs.object_sync(manager, ob_ref, resources, state); + } + default: + break; + } + } + if (in_paint_mode && !state.hide_overlays) { switch (ob_ref.object->type) { case OB_MESH: /* TODO(fclem): Make it part of a #Meshes. */ layer.paints.object_sync(manager, ob_ref, resources, state); - /* For wire-frames. */ - layer.mesh_uvs.edit_object_sync(manager, ob_ref, resources, state); break; case OB_GREASE_PENCIL: layer.grease_pencil.paint_object_sync(manager, ob_ref, resources, state); @@ -522,8 +537,6 @@ void Instance::object_sync(ObjectRef &ob_ref, Manager &manager) switch (ob_ref.object->type) { case OB_MESH: layer.meshes.edit_object_sync(manager, ob_ref, resources, state); - /* TODO(fclem): Find a better place / condition. */ - layer.mesh_uvs.edit_object_sync(manager, ob_ref, resources, state); break; case OB_ARMATURE: layer.armatures.edit_object_sync(manager, ob_ref, resources, state); diff --git a/source/blender/draw/engines/overlay/overlay_next_mesh.hh b/source/blender/draw/engines/overlay/overlay_next_mesh.hh index 14a48f6055b..890538488c8 100644 --- a/source/blender/draw/engines/overlay/overlay_next_mesh.hh +++ b/source/blender/draw/engines/overlay/overlay_next_mesh.hh @@ -552,12 +552,10 @@ class MeshUVs : Overlay { const SpaceImage *space_image = reinterpret_cast(state.space_data); ::Image *image = space_image->image; const bool space_mode_is_paint = space_image->mode == SI_MODE_PAINT; - const bool space_mode_is_view = space_image->mode == SI_MODE_VIEW; const bool space_mode_is_mask = space_image->mode == SI_MODE_MASK; const bool space_mode_is_uv = space_image->mode == SI_MODE_UV; const bool object_mode_is_edit = state.object_mode & OB_MODE_EDIT; - const bool object_mode_is_paint = state.object_mode & OB_MODE_TEXTURE_PAINT; const bool is_viewer = image && ELEM(image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE); const bool is_tiled_image = image && (image->source == IMA_SRC_TILED); @@ -618,22 +616,16 @@ class MeshUVs : Overlay { { /* Wireframe UV Overlay. */ const bool show_wireframe_uv_edit = space_image->flag & SI_DRAWSHADOW; - const bool show_wireframe_tex_paint = !(space_image->flag & SI_NO_DRAW_TEXPAINT); + const bool show_wireframe_uv_guide = !(space_image->flag & SI_NO_DRAW_UV_GUIDE); if (space_mode_is_uv && object_mode_is_edit) { show_wireframe_ = show_wireframe_uv_edit; } - else if (space_mode_is_uv && object_mode_is_paint) { - show_wireframe_ = show_wireframe_tex_paint; - } - else if (space_mode_is_paint && (object_mode_is_paint || object_mode_is_edit)) { - show_wireframe_ = show_wireframe_tex_paint; - } - else if (space_mode_is_view && object_mode_is_paint) { - show_wireframe_ = show_wireframe_tex_paint; - } else { - show_wireframe_ = false; + show_wireframe_ = show_wireframe_uv_guide; + if (!show_face_) { + show_face_ = show_wireframe_; + } } } { @@ -716,13 +708,17 @@ class MeshUVs : Overlay { } if (show_face_) { + const float opacity = (object_mode_is_edit && space_mode_is_uv) ? + space_image->uv_opacity : + space_image->uv_face_opacity; + auto &pass = faces_ps_; pass.init(); pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA); pass.shader_set(res.shaders->uv_edit_face.get()); pass.bind_ubo(OVERLAY_GLOBALS_SLOT, &res.globals_buf); pass.bind_ubo(DRW_CLIPPING_UBO_SLOT, &res.clip_planes_buf); - pass.push_constant("uvOpacity", space_image->uv_opacity); + pass.push_constant("uvOpacity", opacity); } if (show_mesh_analysis_) { @@ -743,10 +739,40 @@ class MeshUVs : Overlay { per_mesh_area_2d_.clear(); } + void object_sync(Manager &manager, + const ObjectRef &ob_ref, + Resources & /*res*/, + const State &state) final + { + if (!enabled_ || ob_ref.object->type != OB_MESH || + !((ob_ref.object->base_flag & BASE_SELECTED) || (ob_ref.object == state.object_active))) + { + return; + } + + Object *ob = ob_ref.object; + Mesh &mesh = DRW_object_get_data_for_drawing(*ob); + + const SpaceImage *space_image = reinterpret_cast(state.space_data); + const bool has_active_object_uvmap = CustomData_get_active_layer(&mesh.corner_data, + CD_PROP_FLOAT2) != -1; + + ResourceHandle res_handle = manager.unique_handle(ob_ref); + + if (show_wireframe_ && has_active_object_uvmap) { + gpu::Batch *geom = DRW_mesh_batch_cache_get_uv_wireframe(*ob, mesh); + wireframe_ps_.draw_expand(geom, GPU_PRIM_TRIS, 2, 1, res_handle); + } + if (show_face_ && has_active_object_uvmap && space_image->uv_face_opacity > 0.0f) { + gpu::Batch *geom = DRW_mesh_batch_cache_get_uv_faces(*ob, mesh); + faces_ps_.draw(geom, res_handle); + } + } + void edit_object_sync(Manager &manager, const ObjectRef &ob_ref, Resources & /*res*/, - const State & /*state*/) final + const State &state) final { if (!enabled_ || ob_ref.object->type != OB_MESH) { return; @@ -755,7 +781,9 @@ class MeshUVs : Overlay { Object &ob = *ob_ref.object; Mesh &mesh = DRW_object_get_data_for_drawing(ob); + const SpaceImage *space_image = reinterpret_cast(state.space_data); const bool is_edit_object = DRW_object_is_in_edit_mode(&ob); + const bool is_uv_editable = is_edit_object && space_image->mode == SI_MODE_UV; const bool has_active_object_uvmap = CustomData_get_active_layer(&mesh.corner_data, CD_PROP_FLOAT2) != -1; const bool has_active_edit_uvmap = is_edit_object && (CustomData_get_active_layer( @@ -764,7 +792,7 @@ class MeshUVs : Overlay { ResourceHandle res_handle = manager.unique_handle(ob_ref); - if (has_active_edit_uvmap) { + if (has_active_edit_uvmap && is_uv_editable) { if (show_uv_edit) { gpu::Batch *geom = DRW_mesh_batch_cache_get_edituv_edges(ob, mesh); edges_ps_.draw_expand(geom, GPU_PRIM_TRIS, 2, 1, res_handle); @@ -781,6 +809,10 @@ class MeshUVs : Overlay { gpu::Batch *geom = DRW_mesh_batch_cache_get_edituv_faces(ob, mesh); faces_ps_.draw(geom, res_handle); } + if (show_wireframe_) { + gpu::Batch *geom = DRW_mesh_batch_cache_get_edituv_wireframe(ob, mesh); + wireframe_ps_.draw_expand(geom, GPU_PRIM_TRIS, 2, 1, res_handle); + } if (show_mesh_analysis_) { int index_3d, index_2d; @@ -799,9 +831,15 @@ class MeshUVs : Overlay { } } - if (show_wireframe_ && (has_active_object_uvmap || has_active_edit_uvmap)) { - gpu::Batch *geom = DRW_mesh_batch_cache_get_uv_edges(ob, mesh); - wireframe_ps_.draw_expand(geom, GPU_PRIM_TRIS, 2, 1, res_handle); + if ((has_active_object_uvmap || has_active_edit_uvmap) && !is_uv_editable) { + if (show_wireframe_) { + gpu::Batch *geom = DRW_mesh_batch_cache_get_uv_wireframe(ob, mesh); + wireframe_ps_.draw_expand(geom, GPU_PRIM_TRIS, 2, 1, res_handle); + } + if (show_face_ && space_image->uv_face_opacity > 0.0f) { + gpu::Batch *geom = DRW_mesh_batch_cache_get_uv_faces(ob, mesh); + faces_ps_.draw(geom, res_handle); + } } } diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh index 6626d58a238..54c5daf4185 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh @@ -331,6 +331,8 @@ VERTEX_SOURCE("overlay_edit_uv_edges_vert.glsl") FRAGMENT_SOURCE("overlay_edit_uv_edges_frag.glsl") ADDITIONAL_INFO(draw_view) ADDITIONAL_INFO(draw_modelmat) +ADDITIONAL_INFO(draw_object_infos) +ADDITIONAL_INFO(draw_resource_id_varying) ADDITIONAL_INFO(gpu_index_buffer_load) ADDITIONAL_INFO(draw_globals) GPU_SHADER_CREATE_END() @@ -346,6 +348,8 @@ VERTEX_SOURCE("overlay_edit_uv_faces_vert.glsl") FRAGMENT_SOURCE("overlay_varying_color.glsl") ADDITIONAL_INFO(draw_view) ADDITIONAL_INFO(draw_modelmat) +ADDITIONAL_INFO(draw_object_infos) +ADDITIONAL_INFO(draw_resource_id_varying) ADDITIONAL_INFO(draw_globals) GPU_SHADER_CREATE_END() diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh index f3e7b7b9b83..b8af1d15173 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh @@ -119,6 +119,8 @@ VERTEX_SOURCE("overlay_edit_uv_edges_vert.glsl") FRAGMENT_SOURCE("overlay_edit_uv_edges_frag.glsl") ADDITIONAL_INFO(draw_view) ADDITIONAL_INFO(draw_modelmat) +ADDITIONAL_INFO(draw_object_infos) +ADDITIONAL_INFO(draw_resource_id_varying) ADDITIONAL_INFO(gpu_index_buffer_load) ADDITIONAL_INFO(draw_globals) GPU_SHADER_CREATE_END() diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl index f3209d41936..ed9909b8adc 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl @@ -18,6 +18,8 @@ FRAGMENT_SHADER_CREATE_INFO(overlay_edit_uv_edges) #define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS) #define GRID_LINE_SMOOTH_END (0.5 + DISC_RADIUS) +#include "draw_object_infos_lib.glsl" +#include "gpu_shader_utildefines_lib.glsl" #include "overlay_common_lib.glsl" void main() @@ -73,7 +75,10 @@ void main() vec4 final_color = mix(outer_color, inner_color, 1.0 - mix_w * outer_color.a); final_color.a *= 1.0 - (outer_color.a > 0.0 ? mix_w_outer : mix_w); - final_color.a *= alpha; + + eObjectInfoFlag ob_flag = drw_object_infos().flag; + bool is_active = flag_test(ob_flag, OBJECT_ACTIVE); + final_color.a *= is_active ? alpha : (alpha * 0.25); fragColor = final_color; } diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl index 91ef96393c6..7cfef8eeb0d 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl @@ -184,6 +184,8 @@ void main() vert_out[0] = vertex_main(vert_in[0]); vert_out[1] = vertex_main(vert_in[1]); + drw_ResourceID_iface.resource_index = drw_resource_id(); + /* Discard by default. */ gl_Position = vec4(NAN_FLT); geometry_main(vert_out, out_vertex_id, out_primitive_id, out_invocation_id); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl index cad6c138cf3..d6ad679f496 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl @@ -7,7 +7,9 @@ VERTEX_SHADER_CREATE_INFO(overlay_edit_uv_faces) #include "draw_model_lib.glsl" +#include "draw_object_infos_lib.glsl" #include "draw_view_lib.glsl" +#include "gpu_shader_utildefines_lib.glsl" void main() { @@ -16,8 +18,10 @@ void main() bool is_selected = (flag & FACE_UV_SELECT) != 0u; bool is_active = (flag & FACE_UV_ACTIVE) != 0u; + eObjectInfoFlag ob_flag = drw_object_infos().flag; + bool is_object_active = flag_test(ob_flag, OBJECT_ACTIVE); finalColor = (is_selected) ? colorFaceSelect : colorFace; finalColor = (is_active) ? colorEditMeshActive : finalColor; - finalColor.a *= uvOpacity; + finalColor.a *= is_object_active ? uvOpacity : (uvOpacity * 0.25); } diff --git a/source/blender/draw/intern/draw_cache_extract.hh b/source/blender/draw/intern/draw_cache_extract.hh index 6da5ec6bca1..e9c1eb8a573 100644 --- a/source/blender/draw/intern/draw_cache_extract.hh +++ b/source/blender/draw/intern/draw_cache_extract.hh @@ -126,6 +126,7 @@ enum class IBOType : int8_t { FaceDots, LinesPaintMask, LinesAdjacency, + UVLines, EditUVTris, EditUVLines, EditUVPoints, @@ -168,6 +169,7 @@ struct MeshBatchList { gpu::Batch *edit_selection_faces; gpu::Batch *edit_selection_fdots; /* Common display / Other */ + gpu::Batch *uv_faces; gpu::Batch *all_verts; gpu::Batch *all_edges; gpu::Batch *loose_edges; @@ -178,6 +180,7 @@ struct MeshBatchList { gpu::Batch *wire_loops; /* Same as wire_loops but only has uvs. */ gpu::Batch *wire_loops_uvs; + gpu::Batch *wire_loops_edituvs; gpu::Batch *sculpt_overlays; gpu::Batch *surface_viewer_attribute; }; @@ -197,6 +200,7 @@ enum DRWBatchFlag { MBC_EDIT_FACEDOTS = (1u << MBC_BATCH_INDEX(edit_fdots)), MBC_EDIT_MESH_ANALYSIS = (1u << MBC_BATCH_INDEX(edit_mesh_analysis)), MBC_SKIN_ROOTS = (1u << MBC_BATCH_INDEX(edit_skin_roots)), + MBC_UV_FACES = (1u << MBC_BATCH_INDEX(uv_faces)), MBC_EDITUV_FACES_STRETCH_AREA = (1u << MBC_BATCH_INDEX(edituv_faces_stretch_area)), MBC_EDITUV_FACES_STRETCH_ANGLE = (1u << MBC_BATCH_INDEX(edituv_faces_stretch_angle)), MBC_EDITUV_FACES = (1u << MBC_BATCH_INDEX(edituv_faces)), @@ -214,6 +218,7 @@ enum DRWBatchFlag { MBC_WIRE_EDGES = (1u << MBC_BATCH_INDEX(wire_edges)), MBC_WIRE_LOOPS = (1u << MBC_BATCH_INDEX(wire_loops)), MBC_WIRE_LOOPS_UVS = (1u << MBC_BATCH_INDEX(wire_loops_uvs)), + MBC_WIRE_LOOPS_EDITUVS = (1u << MBC_BATCH_INDEX(wire_loops_edituvs)), 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), @@ -310,7 +315,8 @@ struct MeshBatchCache { #define MBC_EDITUV \ (MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES | \ - MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_EDITUV_FACEDOTS | MBC_WIRE_LOOPS_UVS) + MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_EDITUV_FACEDOTS | MBC_UV_FACES | \ + MBC_WIRE_LOOPS_UVS | MBC_WIRE_LOOPS_EDITUVS) void mesh_buffer_cache_create_requested(TaskGraph &task_graph, const Scene &scene, diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index ebaa432393f..5a6c145225d 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -158,11 +158,14 @@ void mesh_buffer_cache_create_requested(TaskGraph & /*task_graph*/, case IBOType::LinesAdjacency: created_ibos[i] = extract_lines_adjacency(mr, cache.is_manifold); break; + case IBOType::UVLines: + created_ibos[i] = extract_edituv_lines(mr, false); + break; case IBOType::EditUVTris: created_ibos[i] = extract_edituv_tris(mr); break; case IBOType::EditUVLines: - created_ibos[i] = extract_edituv_lines(mr); + created_ibos[i] = extract_edituv_lines(mr, true); break; case IBOType::EditUVPoints: created_ibos[i] = extract_edituv_points(mr); @@ -418,6 +421,9 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, /* Make sure UVs are computed before edituv stuffs. */ buffers.vbos.add_new(VBOType::UVs, extract_uv_maps_subdiv(subdiv_cache, cache)); } + if (ibos_to_create.contains(IBOType::UVLines)) { + buffers.ibos.add_new(IBOType::UVLines, extract_edituv_lines_subdiv(mr, subdiv_cache, false)); + } if (vbos_to_create.contains(VBOType::EditUVStretchArea)) { buffers.vbos.add_new( VBOType::EditUVStretchArea, @@ -434,7 +440,8 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, buffers.ibos.add_new(IBOType::EditUVTris, extract_edituv_tris_subdiv(mr, subdiv_cache)); } if (ibos_to_create.contains(IBOType::EditUVLines)) { - buffers.ibos.add_new(IBOType::EditUVLines, extract_edituv_lines_subdiv(mr, subdiv_cache)); + buffers.ibos.add_new(IBOType::EditUVLines, + extract_edituv_lines_subdiv(mr, subdiv_cache, true)); } if (ibos_to_create.contains(IBOType::EditUVPoints)) { buffers.ibos.add_new(IBOType::EditUVPoints, extract_edituv_points_subdiv(mr, subdiv_cache)); diff --git a/source/blender/draw/intern/draw_cache_impl.hh b/source/blender/draw/intern/draw_cache_impl.hh index afd47f4fcda..138c5e3e2b7 100644 --- a/source/blender/draw/intern/draw_cache_impl.hh +++ b/source/blender/draw/intern/draw_cache_impl.hh @@ -255,6 +255,7 @@ blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_faces_stretch_area(Object & blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(Object &object, Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_faces(Object &object, Mesh &mesh); +blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_wireframe(Object &object, Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_edges(Object &object, Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_verts(Object &object, Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_facedots(Object &object, Mesh &mesh); @@ -265,7 +266,8 @@ blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_facedots(Object &object, Me /** \name For Image UV Editor * \{ */ -blender::gpu::Batch *DRW_mesh_batch_cache_get_uv_edges(Object &object, Mesh &mesh); +blender::gpu::Batch *DRW_mesh_batch_cache_get_uv_faces(Object &object, Mesh &mesh); +blender::gpu::Batch *DRW_mesh_batch_cache_get_uv_wireframe(Object &object, Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh &mesh); /** \} */ diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index a463595f481..edb1ff6317b 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -1042,7 +1042,15 @@ gpu::Batch *DRW_mesh_batch_cache_get_edituv_facedots(Object &object, Mesh &mesh) return DRW_batch_request(&cache.batch.edituv_fdots); } -gpu::Batch *DRW_mesh_batch_cache_get_uv_edges(Object &object, Mesh &mesh) +gpu::Batch *DRW_mesh_batch_cache_get_uv_faces(Object &object, Mesh &mesh) +{ + MeshBatchCache &cache = *mesh_batch_cache_get(mesh); + edituv_request_active_uv(cache, object, mesh); + mesh_batch_cache_add_request(cache, MBC_UV_FACES); + return DRW_batch_request(&cache.batch.uv_faces); +} + +gpu::Batch *DRW_mesh_batch_cache_get_uv_wireframe(Object &object, Mesh &mesh) { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); edituv_request_active_uv(cache, object, mesh); @@ -1050,6 +1058,14 @@ gpu::Batch *DRW_mesh_batch_cache_get_uv_edges(Object &object, Mesh &mesh) return DRW_batch_request(&cache.batch.wire_loops_uvs); } +gpu::Batch *DRW_mesh_batch_cache_get_edituv_wireframe(Object &object, Mesh &mesh) +{ + MeshBatchCache &cache = *mesh_batch_cache_get(mesh); + edituv_request_active_uv(cache, object, mesh); + mesh_batch_cache_add_request(cache, MBC_WIRE_LOOPS_EDITUVS); + return DRW_batch_request(&cache.batch.wire_loops_edituvs); +} + gpu::Batch *DRW_mesh_batch_cache_get_surface_edges(Mesh &mesh) { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); @@ -1141,8 +1157,9 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, } if (batch_requested & - (MBC_SURFACE | MBC_SURFACE_PER_MAT | MBC_WIRE_LOOPS_UVS | MBC_EDITUV_FACES_STRETCH_AREA | - MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS)) + (MBC_SURFACE | MBC_SURFACE_PER_MAT | MBC_WIRE_LOOPS_UVS | MBC_WIRE_LOOPS_EDITUVS | + MBC_UV_FACES | MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE | + MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS)) { /* Modifiers will only generate an orco layer if the mesh is deformed. */ if (cache.cd_needed.orco != 0) { @@ -1219,7 +1236,9 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, } /* We only clear the batches as they may already have been * referenced. */ + GPU_BATCH_CLEAR_SAFE(cache.batch.uv_faces); GPU_BATCH_CLEAR_SAFE(cache.batch.wire_loops_uvs); + GPU_BATCH_CLEAR_SAFE(cache.batch.wire_loops_edituvs); GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_faces_stretch_area); GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_faces_stretch_angle); GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_faces); @@ -1365,7 +1384,22 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, } if (batches_to_create & MBC_WIRE_LOOPS_UVS) { BatchCreateData batch{ - *cache.batch.wire_loops_uvs, GPU_PRIM_LINES, list, IBOType::EditUVLines, {}}; + *cache.batch.wire_loops_uvs, GPU_PRIM_LINES, list, IBOType::UVLines, {}}; + if (cache.cd_used.uv != 0) { + batch.vbos.append(VBOType::UVs); + } + batch_info.append(std::move(batch)); + } + if (batches_to_create & MBC_WIRE_LOOPS_EDITUVS) { + BatchCreateData batch{ + *cache.batch.wire_loops_edituvs, GPU_PRIM_LINES, list, IBOType::EditUVLines, {}}; + if (cache.cd_used.uv != 0) { + batch.vbos.append(VBOType::UVs); + } + batch_info.append(std::move(batch)); + } + if (batches_to_create & MBC_UV_FACES) { + BatchCreateData batch{*cache.batch.uv_faces, GPU_PRIM_TRIS, list, IBOType::Tris, {}}; if (cache.cd_used.uv != 0) { batch.vbos.append(VBOType::UVs); } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index 97925930ead..9134eb44a21 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -352,9 +352,10 @@ gpu::VertBufPtr extract_edituv_data_subdiv(const MeshRenderData &mr, gpu::IndexBufPtr extract_edituv_tris(const MeshRenderData &mr); gpu::IndexBufPtr extract_edituv_tris_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache); -gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr); +gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, bool edit_uvs); gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr, - const DRWSubdivCache &subdiv_cache); + const DRWSubdivCache &subdiv_cache, + bool edit_uvs); gpu::IndexBufPtr extract_edituv_points(const MeshRenderData &mr); gpu::IndexBufPtr extract_edituv_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc index 97e542a6d98..9772eaa36c9 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc @@ -239,9 +239,9 @@ static gpu::IndexBufPtr extract_edituv_lines_mesh(const MeshRenderData &mr, return gpu::IndexBufPtr(GPU_indexbuf_build_ex(&builder, 0, mr.corners_num, false)); } -gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr) +gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, bool edit_uvs) { - const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0; + const bool sync_selection = ((mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0) || !edit_uvs; if (mr.extract_type == MeshExtractType::BMesh) { return extract_edituv_lines_bm(mr, sync_selection); @@ -334,9 +334,10 @@ static gpu::IndexBufPtr extract_edituv_lines_subdiv_mesh(const MeshRenderData &m } gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr, - const DRWSubdivCache &subdiv_cache) + const DRWSubdivCache &subdiv_cache, + bool edit_uvs) { - const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0; + const bool sync_selection = ((mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0) || !edit_uvs; if (mr.extract_type == MeshExtractType::BMesh) { return extract_edituv_lines_subdiv_bm(mr, subdiv_cache, sync_selection); diff --git a/source/blender/editors/space_image/space_image.cc b/source/blender/editors/space_image/space_image.cc index 4db95765424..1d385215ed9 100644 --- a/source/blender/editors/space_image/space_image.cc +++ b/source/blender/editors/space_image/space_image.cc @@ -102,6 +102,7 @@ static SpaceLink *image_create(const ScrArea * /*area*/, const Scene * /*scene*/ simage->lock = true; simage->flag = SI_SHOW_GPENCIL | SI_USE_ALPHA | SI_COORDFLOATS; simage->uv_opacity = 1.0f; + simage->uv_face_opacity = 1.0f; simage->stretch_opacity = 1.0f; simage->overlay.flag = SI_OVERLAY_SHOW_OVERLAYS | SI_OVERLAY_SHOW_GRID_BACKGROUND; @@ -310,6 +311,10 @@ static void image_listener(const wmSpaceTypeListenerParams *params) ED_area_tag_refresh(area); ED_area_tag_redraw(area); break; + case ND_OB_ACTIVE: + case ND_OB_SELECT: + ED_area_tag_redraw(area); + break; case ND_MODE: ED_paint_cursor_start(¶ms->scene->toolsettings->imapaint.paint, ED_image_tools_paint_poll); @@ -397,12 +402,18 @@ static void image_listener(const wmSpaceTypeListenerParams *params) /* \note With a geometry nodes modifier, the UVs on `ob` can change in response to * any change on `wmn->reference`. If we could track the upstream dependencies, * unnecessary redraws could be reduced. Until then, just redraw. See #98594. */ - if (ob && (ob->mode & OB_MODE_EDIT)) { + if (ob && (ob->mode & OB_MODE_EDIT) && sima->mode == SI_MODE_UV) { if (sima->lock && (sima->flag & SI_DRAWSHADOW)) { ED_area_tag_refresh(area); ED_area_tag_redraw(area); } } + else if (ob) { + if (sima->lock && !(sima->flag & SI_NO_DRAW_UV_GUIDE)) { + ED_area_tag_refresh(area); + ED_area_tag_redraw(area); + } + } break; } } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index d645f4ae788..bd0d087b923 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1297,6 +1297,8 @@ typedef struct SpaceImage { int flag; float uv_opacity; + float uv_face_opacity; + char _pad2[4]; float stretch_opacity; @@ -1378,7 +1380,9 @@ typedef enum eSpaceImage_Flag { SI_FLAG_UNUSED_24 = (1 << 24), - SI_NO_DRAW_TEXPAINT = (1 << 25), +#ifdef DNA_DEPRECATED_ALLOW + SI_NO_DRAW_TEXPAINT = (1 << 25), /* deprecated - use SI_NO_DRAW_UV_GUIDE instead, see #135102 */ +#endif SI_DRAW_METADATA = (1 << 26), SI_SHOW_R = (1 << 27), @@ -1386,6 +1390,8 @@ typedef enum eSpaceImage_Flag { SI_SHOW_B = (1 << 29), SI_GRID_OVER_IMAGE = (1 << 30), + + SI_NO_DRAW_UV_GUIDE = (1 << 31), } eSpaceImage_Flag; typedef enum eSpaceImageOverlay_Flag { diff --git a/source/blender/makesrna/intern/rna_space.cc b/source/blender/makesrna/intern/rna_space.cc index a7145d3a98e..f6129deffea 100644 --- a/source/blender/makesrna/intern/rna_space.cc +++ b/source/blender/makesrna/intern/rna_space.cc @@ -3860,10 +3860,9 @@ static void rna_def_space_image_uv(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Metadata", "Display metadata properties of the image"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr); - prop = RNA_def_property(srna, "show_texpaint", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, nullptr, "flag", SI_NO_DRAW_TEXPAINT); - RNA_def_property_ui_text( - prop, "Display Texture Paint UVs", "Display overlay of texture paint UV layer"); + prop = RNA_def_property(srna, "show_uv", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, nullptr, "flag", SI_NO_DRAW_UV_GUIDE); + RNA_def_property_ui_text(prop, "Display UVs", "Display overlay of UV layer"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr); prop = RNA_def_property(srna, "show_pixel_coords", PROP_BOOLEAN, PROP_NONE); @@ -3914,6 +3913,12 @@ static void rna_def_space_image_uv(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Opacity", "Opacity of UV overlays"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr); + prop = RNA_def_property(srna, "uv_face_opacity", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, nullptr, "uv_face_opacity"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "UV Face Opacity", "Opacity of faces in UV overlays"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr); + prop = RNA_def_property(srna, "stretch_opacity", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, nullptr, "stretch_opacity"); RNA_def_property_range(prop, 0.0f, 1.0f);