Fix #144035: Image Editor ignores face selection
Introduced in 24d08e0bae
The above commit introduced a new batch for drawing UVs in the Image
editor that does not consider face selection when drawing the
corresponding UV map. This was done to reuse the IBO used in object
mode.
Unfortunately, this change didn't account for the case of being able to
select faces in the 3D Viewport (i.e. in Edit or Texture Paint mode)
while also viewing the Image Editor in Paint Mode.
To fix this, the following changes have been made:
* Introduce a new case when drawing the `MeshUV` overlay for objects
being edited.
* Add two new IBO types and a new batch type to clearly differentiate
between the above cases when extracting mesh data.
* Fixes some incorrect usage of the `sync_selection` concept
Pull Request: https://projects.blender.org/blender/blender/pulls/144105
This commit is contained in:
@@ -787,7 +787,7 @@ class MeshUVs : Overlay {
|
||||
ResourceHandleRange 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);
|
||||
gpu::Batch *geom = DRW_mesh_batch_cache_get_all_uv_wireframe(*ob, mesh);
|
||||
wireframe_ps_.draw_expand(geom, GPU_PRIM_TRIS, 2, 1, res_handle);
|
||||
}
|
||||
if (show_face_overlay_ && has_active_object_uvmap && space_image->uv_face_opacity > 0.0f) {
|
||||
@@ -807,10 +807,17 @@ class MeshUVs : Overlay {
|
||||
|
||||
Object &ob = *ob_ref.object;
|
||||
Mesh &mesh = DRW_object_get_data_for_drawing<Mesh>(ob);
|
||||
const Mesh &mesh_orig = DRW_object_get_data_for_drawing<Mesh>(
|
||||
*DEG_get_original(ob_ref.object));
|
||||
|
||||
const SpaceImage *space_image = reinterpret_cast<const SpaceImage *>(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;
|
||||
/* Sculpt is left out here because selection does not exist in it. */
|
||||
const bool is_paint_mode = ELEM(
|
||||
state.ctx_mode, CTX_MODE_PAINT_TEXTURE, CTX_MODE_PAINT_VERTEX, CTX_MODE_PAINT_WEIGHT);
|
||||
const bool use_face_selection = (mesh_orig.editflag & ME_EDIT_PAINT_FACE_SEL);
|
||||
const bool is_face_selectable = (is_edit_object || (is_paint_mode && use_face_selection));
|
||||
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(
|
||||
@@ -819,6 +826,7 @@ class MeshUVs : Overlay {
|
||||
|
||||
ResourceHandleRange res_handle = manager.unique_handle(ob_ref);
|
||||
|
||||
/* Fully editable UVs in the UV Editor. */
|
||||
if (has_active_edit_uvmap && is_uv_editable) {
|
||||
if (show_uv_edit_) {
|
||||
gpu::Batch *geom = DRW_mesh_batch_cache_get_edituv_edges(ob, mesh);
|
||||
@@ -856,13 +864,30 @@ class MeshUVs : Overlay {
|
||||
|
||||
analysis_ps_.draw(geom, res_handle);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((has_active_object_uvmap || has_active_edit_uvmap) && !is_uv_editable) {
|
||||
/* Selectable faces in 3D viewport that sync with image editor paint mode. */
|
||||
if ((has_active_object_uvmap || has_active_edit_uvmap) && is_face_selectable) {
|
||||
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_overlay_ && space_image->uv_face_opacity > 0.0f) || select_face_) {
|
||||
gpu::Batch *geom = DRW_mesh_batch_cache_get_uv_faces(ob, mesh);
|
||||
faces_ps_.draw(geom, res_handle);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Non-selectable & non-editable faces in image editor paint mode. */
|
||||
if ((has_active_object_uvmap || has_active_edit_uvmap) && !is_uv_editable &&
|
||||
!is_face_selectable)
|
||||
{
|
||||
if (show_wireframe_) {
|
||||
gpu::Batch *geom = DRW_mesh_batch_cache_get_all_uv_wireframe(ob, mesh);
|
||||
wireframe_ps_.draw_expand(geom, GPU_PRIM_TRIS, 2, 1, res_handle);
|
||||
}
|
||||
if (show_face_overlay_ && 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);
|
||||
|
||||
@@ -127,6 +127,8 @@ enum class IBOType : int8_t {
|
||||
FaceDots,
|
||||
LinesPaintMask,
|
||||
LinesAdjacency,
|
||||
UVTris,
|
||||
AllUVLines,
|
||||
UVLines,
|
||||
EditUVTris,
|
||||
EditUVLines,
|
||||
@@ -179,6 +181,7 @@ struct MeshBatchList {
|
||||
gpu::Batch *wire_edges;
|
||||
/* Loops around faces. no edges between selected faces */
|
||||
gpu::Batch *paint_overlay_wire_loops;
|
||||
gpu::Batch *wire_loops_all_uvs;
|
||||
gpu::Batch *wire_loops_uvs;
|
||||
gpu::Batch *wire_loops_edituvs;
|
||||
gpu::Batch *sculpt_overlays;
|
||||
@@ -219,11 +222,12 @@ enum DRWBatchFlag : uint64_t {
|
||||
MBC_EDGE_DETECTION = (1u << MBC_BATCH_INDEX(edge_detection)),
|
||||
MBC_WIRE_EDGES = (1u << MBC_BATCH_INDEX(wire_edges)),
|
||||
MBC_PAINT_OVERLAY_WIRE_LOOPS = (1u << MBC_BATCH_INDEX(paint_overlay_wire_loops)),
|
||||
MBC_WIRE_LOOPS_ALL_UVS = (1u << MBC_BATCH_INDEX(wire_loops_all_uvs)),
|
||||
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_PAINT_OVERLAY_VERTS = (1u << MBC_BATCH_INDEX(paint_overlay_verts)),
|
||||
MBC_PAINT_OVERLAY_VERTS = (uint64_t(1u) << MBC_BATCH_INDEX(paint_overlay_verts)),
|
||||
MBC_PAINT_OVERLAY_SURFACE = (uint64_t(1u) << MBC_BATCH_INDEX(paint_overlay_surface)),
|
||||
MBC_SURFACE_PER_MAT = (uint64_t(1u) << MBC_BATCH_LEN),
|
||||
};
|
||||
@@ -318,7 +322,7 @@ 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_UV_FACES | \
|
||||
MBC_WIRE_LOOPS_UVS | MBC_WIRE_LOOPS_EDITUVS)
|
||||
MBC_WIRE_LOOPS_ALL_UVS | MBC_WIRE_LOOPS_UVS | MBC_WIRE_LOOPS_EDITUVS)
|
||||
|
||||
void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
const Scene &scene,
|
||||
|
||||
@@ -188,14 +188,20 @@ 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);
|
||||
case IBOType::UVTris:
|
||||
created_ibos[i] = extract_edituv_tris(mr, false);
|
||||
break;
|
||||
case IBOType::EditUVTris:
|
||||
created_ibos[i] = extract_edituv_tris(mr);
|
||||
created_ibos[i] = extract_edituv_tris(mr, true);
|
||||
break;
|
||||
case IBOType::AllUVLines:
|
||||
created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::All);
|
||||
break;
|
||||
case IBOType::UVLines:
|
||||
created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::Selection);
|
||||
break;
|
||||
case IBOType::EditUVLines:
|
||||
created_ibos[i] = extract_edituv_lines(mr, true);
|
||||
created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::Edit);
|
||||
break;
|
||||
case IBOType::EditUVPoints:
|
||||
created_ibos[i] = extract_edituv_points(mr);
|
||||
@@ -465,8 +471,14 @@ 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::AllUVLines)) {
|
||||
buffers.ibos.add_new(IBOType::AllUVLines,
|
||||
extract_edituv_lines_subdiv(mr, subdiv_cache, UvExtractionMode::All));
|
||||
}
|
||||
if (ibos_to_create.contains(IBOType::UVLines)) {
|
||||
buffers.ibos.add_new(IBOType::UVLines, extract_edituv_lines_subdiv(mr, subdiv_cache, false));
|
||||
buffers.ibos.add_new(
|
||||
IBOType::UVLines,
|
||||
extract_edituv_lines_subdiv(mr, subdiv_cache, UvExtractionMode::Selection));
|
||||
}
|
||||
if (vbos_to_create.contains(VBOType::EditUVStretchArea)) {
|
||||
buffers.vbos.add_new(
|
||||
@@ -485,7 +497,7 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
}
|
||||
if (ibos_to_create.contains(IBOType::EditUVLines)) {
|
||||
buffers.ibos.add_new(IBOType::EditUVLines,
|
||||
extract_edituv_lines_subdiv(mr, subdiv_cache, true));
|
||||
extract_edituv_lines_subdiv(mr, subdiv_cache, UvExtractionMode::Edit));
|
||||
}
|
||||
if (ibos_to_create.contains(IBOType::EditUVPoints)) {
|
||||
buffers.ibos.add_new(IBOType::EditUVPoints, extract_edituv_points_subdiv(mr, subdiv_cache));
|
||||
|
||||
@@ -276,6 +276,7 @@ blender::gpu::Batch *DRW_mesh_batch_cache_get_edituv_facedots(Object &object, Me
|
||||
* \{ */
|
||||
|
||||
blender::gpu::Batch *DRW_mesh_batch_cache_get_uv_faces(Object &object, Mesh &mesh);
|
||||
blender::gpu::Batch *DRW_mesh_batch_cache_get_all_uv_wireframe(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);
|
||||
|
||||
|
||||
@@ -555,15 +555,19 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache &cache)
|
||||
|
||||
static void mesh_batch_cache_discard_uvedit(MeshBatchCache &cache)
|
||||
{
|
||||
discard_buffers(
|
||||
cache,
|
||||
{VBOType::EditUVStretchAngle,
|
||||
VBOType::EditUVStretchArea,
|
||||
VBOType::UVs,
|
||||
VBOType::EditUVData,
|
||||
VBOType::FaceDotUV,
|
||||
VBOType::FaceDotEditUVData},
|
||||
{IBOType::EditUVTris, IBOType::EditUVLines, IBOType::EditUVPoints, IBOType::EditUVFaceDots});
|
||||
discard_buffers(cache,
|
||||
{VBOType::EditUVStretchAngle,
|
||||
VBOType::EditUVStretchArea,
|
||||
VBOType::UVs,
|
||||
VBOType::EditUVData,
|
||||
VBOType::FaceDotUV,
|
||||
VBOType::FaceDotEditUVData},
|
||||
{IBOType::EditUVTris,
|
||||
IBOType::EditUVLines,
|
||||
IBOType::EditUVPoints,
|
||||
IBOType::EditUVFaceDots,
|
||||
IBOType::UVLines,
|
||||
IBOType::UVTris});
|
||||
|
||||
cache.tot_area = 0.0f;
|
||||
cache.tot_uv_area = 0.0f;
|
||||
@@ -575,10 +579,14 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache &cache)
|
||||
|
||||
static void mesh_batch_cache_discard_uvedit_select(MeshBatchCache &cache)
|
||||
{
|
||||
discard_buffers(
|
||||
cache,
|
||||
{VBOType::EditUVData, VBOType::FaceDotEditUVData},
|
||||
{IBOType::EditUVTris, IBOType::EditUVLines, IBOType::EditUVPoints, IBOType::EditUVFaceDots});
|
||||
discard_buffers(cache,
|
||||
{VBOType::EditUVData, VBOType::FaceDotEditUVData},
|
||||
{IBOType::EditUVTris,
|
||||
IBOType::EditUVLines,
|
||||
IBOType::EditUVPoints,
|
||||
IBOType::EditUVFaceDots,
|
||||
IBOType::UVLines,
|
||||
IBOType::UVTris});
|
||||
}
|
||||
|
||||
void DRW_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
|
||||
@@ -1061,6 +1069,14 @@ gpu::Batch *DRW_mesh_batch_cache_get_uv_faces(Object &object, Mesh &mesh)
|
||||
return DRW_batch_request(&cache.batch.uv_faces);
|
||||
}
|
||||
|
||||
gpu::Batch *DRW_mesh_batch_cache_get_all_uv_wireframe(Object &object, Mesh &mesh)
|
||||
{
|
||||
MeshBatchCache &cache = *mesh_batch_cache_get(mesh);
|
||||
edituv_request_active_uv(cache, object, mesh);
|
||||
cache.batch_requested |= MBC_WIRE_LOOPS_ALL_UVS;
|
||||
return DRW_batch_request(&cache.batch.wire_loops_all_uvs);
|
||||
}
|
||||
|
||||
gpu::Batch *DRW_mesh_batch_cache_get_uv_wireframe(Object &object, Mesh &mesh)
|
||||
{
|
||||
MeshBatchCache &cache = *mesh_batch_cache_get(mesh);
|
||||
@@ -1168,9 +1184,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_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))
|
||||
(MBC_SURFACE | MBC_SURFACE_PER_MAT | MBC_WIRE_LOOPS_ALL_UVS | 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) {
|
||||
@@ -1248,6 +1264,7 @@ 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_all_uvs);
|
||||
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);
|
||||
@@ -1405,6 +1422,14 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph,
|
||||
IBOType::Lines,
|
||||
{VBOType::Position, VBOType::CornerNormal, VBOType::EdgeFactor}});
|
||||
}
|
||||
if (batches_to_create & MBC_WIRE_LOOPS_ALL_UVS) {
|
||||
BatchCreateData batch{
|
||||
*cache.batch.wire_loops_all_uvs, GPU_PRIM_LINES, list, IBOType::AllUVLines, {}};
|
||||
if (cache.cd_used.uv != 0) {
|
||||
batch.vbos.append(VBOType::UVs);
|
||||
}
|
||||
batch_info.append(std::move(batch));
|
||||
}
|
||||
if (batches_to_create & MBC_WIRE_LOOPS_UVS) {
|
||||
BatchCreateData batch{
|
||||
*cache.batch.wire_loops_uvs, GPU_PRIM_LINES, list, IBOType::UVLines, {}};
|
||||
@@ -1422,7 +1447,15 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph,
|
||||
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, {}};
|
||||
const bool use_face_selection = (mesh.editflag & ME_EDIT_PAINT_FACE_SEL);
|
||||
/* Sculpt mode does not support selection, therefore the generic `is_paint_mode` check cannot
|
||||
* be used */
|
||||
const bool is_face_selectable =
|
||||
ELEM(ob.mode, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) &&
|
||||
use_face_selection;
|
||||
|
||||
const IBOType ibo = is_face_selectable || is_editmode ? IBOType::UVTris : IBOType::Tris;
|
||||
BatchCreateData batch{*cache.batch.uv_faces, GPU_PRIM_TRIS, list, ibo, {}};
|
||||
if (cache.cd_used.uv != 0) {
|
||||
batch.vbos.append(VBOType::UVs);
|
||||
}
|
||||
|
||||
@@ -324,9 +324,10 @@ inline ResourceHandleRange Manager::unique_handle(const ObjectRef &ref)
|
||||
inline ResourceHandleRange Manager::resource_handle(const ObjectRef &ref, float inflate_bounds)
|
||||
{
|
||||
bool is_active_object = ref.is_active(object_active);
|
||||
bool is_edit_mode = object_active && DRW_object_is_in_edit_mode(object_active) &&
|
||||
ref.object->mode == object_active->mode;
|
||||
|
||||
bool is_active_edit_mode = object_active &&
|
||||
(DRW_object_is_in_edit_mode(object_active) ||
|
||||
ELEM(object_active->mode, OB_MODE_TEXTURE_PAINT, OB_MODE_SCULPT)) &&
|
||||
ref.object->mode == object_active->mode;
|
||||
if (ref.duplis_) {
|
||||
uint start = resource_len_;
|
||||
|
||||
@@ -334,7 +335,7 @@ inline ResourceHandleRange Manager::resource_handle(const ObjectRef &ref, float
|
||||
proto_bounds.sync(*ref.object, inflate_bounds);
|
||||
|
||||
ObjectInfos proto_info;
|
||||
proto_info.sync(ref, is_active_object, is_edit_mode);
|
||||
proto_info.sync(ref, is_active_object, is_active_edit_mode);
|
||||
|
||||
for (const DupliObject *dupli : *ref.duplis_) {
|
||||
matrix_buf.current().get_or_resize(resource_len_).sync(float4x4(dupli->mat));
|
||||
@@ -351,7 +352,9 @@ inline ResourceHandleRange Manager::resource_handle(const ObjectRef &ref, float
|
||||
else {
|
||||
matrix_buf.current().get_or_resize(resource_len_).sync(*ref.object);
|
||||
bounds_buf.current().get_or_resize(resource_len_).sync(*ref.object, inflate_bounds);
|
||||
infos_buf.current().get_or_resize(resource_len_).sync(ref, is_active_object, is_edit_mode);
|
||||
infos_buf.current()
|
||||
.get_or_resize(resource_len_)
|
||||
.sync(ref, is_active_object, is_active_edit_mode);
|
||||
return ResourceHandle(resource_len_++, (ref.object->transflag & OB_NEG_SCALE) != 0);
|
||||
}
|
||||
}
|
||||
@@ -363,8 +366,10 @@ inline ResourceHandleRange Manager::resource_handle(const ObjectRef &ref,
|
||||
{
|
||||
BLI_assert(!ref.duplis_);
|
||||
bool is_active_object = ref.is_active(object_active);
|
||||
bool is_edit_mode = object_active && DRW_object_is_in_edit_mode(object_active) &&
|
||||
ref.object->mode == object_active->mode;
|
||||
bool is_active_edit_mode = object_active &&
|
||||
(DRW_object_is_in_edit_mode(object_active) ||
|
||||
ELEM(object_active->mode, OB_MODE_TEXTURE_PAINT, OB_MODE_SCULPT)) &&
|
||||
ref.object->mode == object_active->mode;
|
||||
if (model_matrix) {
|
||||
matrix_buf.current().get_or_resize(resource_len_).sync(*model_matrix);
|
||||
}
|
||||
@@ -377,7 +382,9 @@ inline ResourceHandleRange Manager::resource_handle(const ObjectRef &ref,
|
||||
else {
|
||||
bounds_buf.current().get_or_resize(resource_len_).sync(*ref.object);
|
||||
}
|
||||
infos_buf.current().get_or_resize(resource_len_).sync(ref, is_active_object, is_edit_mode);
|
||||
infos_buf.current()
|
||||
.get_or_resize(resource_len_)
|
||||
.sync(ref, is_active_object, is_active_edit_mode);
|
||||
return ResourceHandle(resource_len_++, (ref.object->transflag & OB_NEG_SCALE) != 0);
|
||||
}
|
||||
|
||||
@@ -404,11 +411,15 @@ inline ResourceHandle Manager::resource_handle_for_psys(const ObjectRef &ref,
|
||||
{
|
||||
BLI_assert(!ref.duplis_);
|
||||
bool is_active_object = ref.is_active(object_active);
|
||||
bool is_edit_mode = object_active && DRW_object_is_in_edit_mode(object_active) &&
|
||||
ref.object->mode == object_active->mode;
|
||||
bool is_active_edit_mode = object_active &&
|
||||
(DRW_object_is_in_edit_mode(object_active) ||
|
||||
ELEM(object_active->mode, OB_MODE_TEXTURE_PAINT, OB_MODE_SCULPT)) &&
|
||||
ref.object->mode == object_active->mode;
|
||||
matrix_buf.current().get_or_resize(resource_len_).sync(model_matrix);
|
||||
bounds_buf.current().get_or_resize(resource_len_).sync();
|
||||
infos_buf.current().get_or_resize(resource_len_).sync(ref, is_active_object, is_edit_mode);
|
||||
infos_buf.current()
|
||||
.get_or_resize(resource_len_)
|
||||
.sync(ref, is_active_object, is_active_edit_mode);
|
||||
return ResourceHandle(resource_len_++, (ref.object->transflag & OB_NEG_SCALE) != 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -360,13 +360,20 @@ gpu::VertBufPtr extract_edituv_stretch_angle_subdiv(const MeshRenderData &mr,
|
||||
gpu::VertBufPtr extract_edituv_data(const MeshRenderData &mr);
|
||||
gpu::VertBufPtr extract_edituv_data_subdiv(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache);
|
||||
gpu::IndexBufPtr extract_edituv_tris(const MeshRenderData &mr);
|
||||
gpu::IndexBufPtr extract_edituv_tris(const MeshRenderData &mr, bool edit_uvs);
|
||||
gpu::IndexBufPtr extract_edituv_tris_subdiv(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache);
|
||||
gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, bool edit_uvs);
|
||||
|
||||
enum class UvExtractionMode : int8_t {
|
||||
Edit,
|
||||
Selection,
|
||||
All,
|
||||
};
|
||||
|
||||
gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, UvExtractionMode mode);
|
||||
gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache,
|
||||
bool edit_uvs);
|
||||
UvExtractionMode mode);
|
||||
gpu::IndexBufPtr extract_edituv_points(const MeshRenderData &mr);
|
||||
gpu::IndexBufPtr extract_edituv_points_subdiv(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache);
|
||||
|
||||
@@ -27,7 +27,7 @@ inline bool skip_bm_face(const BMFace &face, const bool sync_selection)
|
||||
if (BM_elem_flag_test(&face, BM_ELEM_HIDDEN)) {
|
||||
return true;
|
||||
}
|
||||
if (!sync_selection) {
|
||||
if (sync_selection) {
|
||||
if (!BM_elem_flag_test_bool(&face, BM_ELEM_SELECT)) {
|
||||
return true;
|
||||
}
|
||||
@@ -104,17 +104,32 @@ static gpu::IndexBufPtr extract_edituv_tris_mesh(const MeshRenderData &mr,
|
||||
const Span<int3> corner_tris = mr.mesh->corner_tris();
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selection = IndexMask::from_predicate(
|
||||
faces.index_range(), GrainSize(4096), memory, [&](const int face) {
|
||||
const BMFace *face_orig = bm_original_face_get(mr, face);
|
||||
if (!face_orig) {
|
||||
return false;
|
||||
}
|
||||
if (skip_bm_face(*face_orig, sync_selection)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
IndexMask selection;
|
||||
if (mr.bm) {
|
||||
selection = IndexMask::from_predicate(
|
||||
faces.index_range(), GrainSize(4096), memory, [&](const int face) {
|
||||
const BMFace *face_orig = bm_original_face_get(mr, face);
|
||||
if (!face_orig) {
|
||||
return false;
|
||||
}
|
||||
if (skip_bm_face(*face_orig, sync_selection)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (mr.hide_poly.is_empty()) {
|
||||
selection = faces.index_range();
|
||||
}
|
||||
else {
|
||||
selection = IndexMask::from_bools_inverse(faces.index_range(), mr.hide_poly, memory);
|
||||
}
|
||||
|
||||
if (sync_selection) {
|
||||
selection = IndexMask::from_bools(selection, mr.select_poly, memory);
|
||||
}
|
||||
}
|
||||
|
||||
if (selection.size() == faces.size()) {
|
||||
return gpu::IndexBufPtr(GPU_indexbuf_build_from_memory(GPU_PRIM_TRIS,
|
||||
@@ -147,9 +162,9 @@ static gpu::IndexBufPtr extract_edituv_tris_mesh(const MeshRenderData &mr,
|
||||
return gpu::IndexBufPtr(GPU_indexbuf_build_ex(&builder, 0, mr.corners_num, false));
|
||||
}
|
||||
|
||||
gpu::IndexBufPtr extract_edituv_tris(const MeshRenderData &mr)
|
||||
gpu::IndexBufPtr extract_edituv_tris(const MeshRenderData &mr, const bool edit_uvs)
|
||||
{
|
||||
const bool sync_selection = (mr.toolsettings->uv_flag & UV_FLAG_SYNC_SELECT) != 0;
|
||||
const bool sync_selection = ((mr.toolsettings->uv_flag & UV_FLAG_SYNC_SELECT) != 0) || !edit_uvs;
|
||||
if (mr.extract_type == MeshExtractType::BMesh) {
|
||||
return extract_edituv_tris_bm(mr, sync_selection);
|
||||
}
|
||||
@@ -314,7 +329,7 @@ static gpu::IndexBufPtr extract_edituv_lines_mesh(const MeshRenderData &mr,
|
||||
if (!mr.hide_poly.is_empty()) {
|
||||
visible = IndexMask::from_bools_inverse(visible, mr.hide_poly, memory);
|
||||
}
|
||||
if (!sync_selection) {
|
||||
if (sync_selection) {
|
||||
if (mr.select_poly.is_empty()) {
|
||||
visible = {};
|
||||
}
|
||||
@@ -346,9 +361,20 @@ static gpu::IndexBufPtr extract_edituv_lines_mesh(const MeshRenderData &mr,
|
||||
return result;
|
||||
}
|
||||
|
||||
gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, bool edit_uvs)
|
||||
gpu::IndexBufPtr extract_edituv_lines(const MeshRenderData &mr, const UvExtractionMode mode)
|
||||
{
|
||||
const bool sync_selection = ((mr.toolsettings->uv_flag & UV_FLAG_SYNC_SELECT) != 0) || !edit_uvs;
|
||||
bool sync_selection = true;
|
||||
switch (mode) {
|
||||
case UvExtractionMode::All:
|
||||
sync_selection = false;
|
||||
break;
|
||||
case UvExtractionMode::Edit:
|
||||
sync_selection = ((mr.toolsettings->uv_flag & UV_FLAG_SYNC_SELECT) != 0);
|
||||
break;
|
||||
case UvExtractionMode::Selection:
|
||||
sync_selection = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mr.extract_type == MeshExtractType::BMesh) {
|
||||
return extract_edituv_lines_bm(mr, sync_selection);
|
||||
@@ -450,9 +476,20 @@ static gpu::IndexBufPtr extract_edituv_lines_subdiv_mesh(const MeshRenderData &m
|
||||
|
||||
gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache,
|
||||
bool edit_uvs)
|
||||
const UvExtractionMode mode)
|
||||
{
|
||||
const bool sync_selection = ((mr.toolsettings->uv_flag & UV_FLAG_SYNC_SELECT) != 0) || !edit_uvs;
|
||||
bool sync_selection = true;
|
||||
switch (mode) {
|
||||
case UvExtractionMode::All:
|
||||
sync_selection = false;
|
||||
break;
|
||||
case UvExtractionMode::Edit:
|
||||
sync_selection = ((mr.toolsettings->uv_flag & UV_FLAG_SYNC_SELECT) != 0);
|
||||
break;
|
||||
case UvExtractionMode::Selection:
|
||||
sync_selection = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mr.extract_type == MeshExtractType::BMesh) {
|
||||
return extract_edituv_lines_subdiv_bm(mr, subdiv_cache, sync_selection);
|
||||
|
||||
Reference in New Issue
Block a user