Mesh: Avoid function call overhead when extracting UV lines indices
Similar to other changes from #116901.
This commit is contained in:
@@ -224,6 +224,14 @@ void mesh_render_data_loop_edge_flag(const MeshRenderData &mr,
|
||||
const BMUVOffsets &offsets,
|
||||
EditLoopData &eattr);
|
||||
|
||||
/* In the GPU vertex buffers, the value for each vertex is duplicated to each of its vertex
|
||||
* corners. So the edges on the GPU connect face corners rather than vertices. */
|
||||
inline uint2 edge_from_corners(const IndexRange face, const int corner)
|
||||
{
|
||||
const int corner_next = bke::mesh::face_corner_next(face, corner);
|
||||
return uint2(corner, corner_next);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void extract_mesh_loose_edge_data(const Span<T> vert_data,
|
||||
const Span<int2> edges,
|
||||
|
||||
@@ -154,33 +154,46 @@ void extract_edituv_tris_subdiv(const MeshRenderData &mr,
|
||||
|
||||
static void extract_edituv_lines_bm(const MeshRenderData &mr,
|
||||
const bool sync_selection,
|
||||
GPUIndexBufBuilder &builder)
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
const BMesh &bm = *mr.bm;
|
||||
GPUIndexBufBuilder builder;
|
||||
/* The entire data array might not be used. It might be beneficial to count the number of visible
|
||||
* edges first, especially if that allows parallelizing filling the data array. */
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_LINES, mr.corners_num, mr.corners_num);
|
||||
MutableSpan<uint2> data = GPU_indexbuf_get_data(&builder).cast<uint2>();
|
||||
int line_index = 0;
|
||||
|
||||
const BMFace *face;
|
||||
BMIter f_iter;
|
||||
BM_ITER_MESH (face, &f_iter, &const_cast<BMesh &>(bm), BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH (face, &f_iter, mr.bm, BM_FACES_OF_MESH) {
|
||||
if (skip_bm_face(*face, sync_selection)) {
|
||||
continue;
|
||||
}
|
||||
const BMLoop *loop = BM_FACE_FIRST_LOOP(face);
|
||||
for ([[maybe_unused]] const int i : IndexRange(face->len)) {
|
||||
GPU_indexbuf_add_line_verts(
|
||||
&builder, BM_elem_index_get(loop), BM_elem_index_get(loop->next));
|
||||
data[line_index++] = uint2(BM_elem_index_get(loop), BM_elem_index_get(loop->next));
|
||||
loop = loop->next;
|
||||
}
|
||||
}
|
||||
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, mr.corners_num, false, &ibo);
|
||||
}
|
||||
|
||||
static void extract_edituv_lines_mesh(const MeshRenderData &mr,
|
||||
const bool sync_selection,
|
||||
GPUIndexBufBuilder &builder)
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
const OffsetIndices faces = mr.faces;
|
||||
const Span<int> corner_edges = mr.corner_edges;
|
||||
const Span<int> orig_index_edge = mr.orig_index_edge ?
|
||||
Span<int>(mr.orig_index_edge, mr.edges_num) :
|
||||
Span<int>();
|
||||
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_LINES, mr.corners_num, mr.corners_num);
|
||||
MutableSpan<uint2> data = GPU_indexbuf_get_data(&builder).cast<uint2>();
|
||||
int line_index = 0;
|
||||
|
||||
if (mr.bm) {
|
||||
for (const int face_index : faces.index_range()) {
|
||||
const IndexRange face = faces[face_index];
|
||||
@@ -196,8 +209,7 @@ static void extract_edituv_lines_mesh(const MeshRenderData &mr,
|
||||
if (!orig_index_edge.is_empty() && orig_index_edge[edge] == ORIGINDEX_NONE) {
|
||||
continue;
|
||||
}
|
||||
const int corner_next = bke::mesh::face_corner_next(face, corner);
|
||||
GPU_indexbuf_add_line_verts(&builder, corner, corner_next);
|
||||
data[line_index++] = edge_from_corners(face, corner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,39 +234,42 @@ static void extract_edituv_lines_mesh(const MeshRenderData &mr,
|
||||
if (!orig_index_edge.is_empty() && orig_index_edge[edge] == ORIGINDEX_NONE) {
|
||||
continue;
|
||||
}
|
||||
const int corner_next = bke::mesh::face_corner_next(face, corner);
|
||||
GPU_indexbuf_add_line_verts(&builder, corner, corner_next);
|
||||
data[line_index++] = edge_from_corners(face, corner);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, mr.corners_num, false, &ibo);
|
||||
}
|
||||
|
||||
void extract_edituv_lines(const MeshRenderData &mr, gpu::IndexBuf &ibo)
|
||||
{
|
||||
const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
|
||||
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_LINES, mr.corners_num, mr.corners_num);
|
||||
if (mr.extract_type == MeshExtractType::BMesh) {
|
||||
extract_edituv_lines_bm(mr, sync_selection, builder);
|
||||
extract_edituv_lines_bm(mr, sync_selection, ibo);
|
||||
}
|
||||
else {
|
||||
extract_edituv_lines_mesh(mr, sync_selection, builder);
|
||||
extract_edituv_lines_mesh(mr, sync_selection, ibo);
|
||||
}
|
||||
|
||||
GPU_indexbuf_build_in_place(&builder, &ibo);
|
||||
}
|
||||
|
||||
static void extract_edituv_lines_subdiv_bm(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache,
|
||||
const bool sync_selection,
|
||||
GPUIndexBufBuilder &builder)
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
const BMesh &bm = *mr.bm;
|
||||
const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
|
||||
const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
|
||||
subdiv_cache.num_subdiv_loops);
|
||||
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(
|
||||
&builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
|
||||
MutableSpan<uint2> data = GPU_indexbuf_get_data(&builder).cast<uint2>();
|
||||
int line_index = 0;
|
||||
|
||||
for (const int subdiv_quad : IndexRange(subdiv_cache.num_subdiv_quads)) {
|
||||
const int coarse_face = subdiv_loop_face_index[subdiv_quad * 4];
|
||||
const BMFace &face_orig = *BM_face_at_index(&const_cast<BMesh &>(bm), coarse_face);
|
||||
@@ -267,17 +282,24 @@ static void extract_edituv_lines_subdiv_bm(const MeshRenderData &mr,
|
||||
if (coarse_edge == -1) {
|
||||
continue;
|
||||
}
|
||||
const int subdiv_corner_next = bke::mesh::face_corner_next(subdiv_face, subdiv_corner);
|
||||
GPU_indexbuf_add_line_verts(&builder, subdiv_corner, subdiv_corner_next);
|
||||
data[line_index++] = edge_from_corners(subdiv_face, subdiv_corner);
|
||||
}
|
||||
}
|
||||
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, subdiv_cache.num_subdiv_loops, false, &ibo);
|
||||
}
|
||||
|
||||
static void extract_edituv_lines_subdiv_mesh(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache,
|
||||
const bool sync_selection,
|
||||
GPUIndexBufBuilder &builder)
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(
|
||||
&builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
|
||||
MutableSpan<uint2> data = GPU_indexbuf_get_data(&builder).cast<uint2>();
|
||||
int line_index = 0;
|
||||
|
||||
/* NOTE: #subdiv_loop_edge_index already has the #CD_ORIGINDEX layer baked in. */
|
||||
const Span<int> subdiv_loop_edge_index = subdiv_cache.edges_orig_index->data<int>();
|
||||
const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
|
||||
@@ -309,10 +331,11 @@ static void extract_edituv_lines_subdiv_mesh(const MeshRenderData &mr,
|
||||
if (coarse_edge == -1) {
|
||||
continue;
|
||||
}
|
||||
const int subdiv_corner_next = bke::mesh::face_corner_next(subdiv_face, subdiv_corner);
|
||||
GPU_indexbuf_add_line_verts(&builder, subdiv_corner, subdiv_corner_next);
|
||||
data[line_index++] = edge_from_corners(subdiv_face, subdiv_corner);
|
||||
}
|
||||
}
|
||||
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, subdiv_cache.num_subdiv_loops, false, &ibo);
|
||||
}
|
||||
|
||||
void extract_edituv_lines_subdiv(const MeshRenderData &mr,
|
||||
@@ -321,17 +344,12 @@ void extract_edituv_lines_subdiv(const MeshRenderData &mr,
|
||||
{
|
||||
const bool sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
|
||||
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(
|
||||
&builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_loops, subdiv_cache.num_subdiv_loops);
|
||||
if (mr.extract_type == MeshExtractType::BMesh) {
|
||||
extract_edituv_lines_subdiv_bm(mr, subdiv_cache, sync_selection, builder);
|
||||
extract_edituv_lines_subdiv_bm(mr, subdiv_cache, sync_selection, ibo);
|
||||
}
|
||||
else {
|
||||
extract_edituv_lines_subdiv_mesh(mr, subdiv_cache, sync_selection, builder);
|
||||
extract_edituv_lines_subdiv_mesh(mr, subdiv_cache, sync_selection, ibo);
|
||||
}
|
||||
|
||||
GPU_indexbuf_build_in_place(&builder, &ibo);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -38,14 +38,6 @@ static IndexMask calc_mesh_edge_visibility(const MeshRenderData &mr,
|
||||
return visible;
|
||||
}
|
||||
|
||||
/* In the GPU vertex buffers, the value for each vertex is duplicated to each of its vertex
|
||||
* corners. So the edges on the GPU connect face corners rather than vertices. */
|
||||
static uint2 edge_from_corners(const IndexRange face, const int corner)
|
||||
{
|
||||
const int corner_next = bke::mesh::face_corner_next(face, corner);
|
||||
return uint2(corner, corner_next);
|
||||
}
|
||||
|
||||
static void fill_loose_lines_ibo(const MeshRenderData &mr,
|
||||
const IndexMask &visible,
|
||||
MutableSpan<uint2> data)
|
||||
|
||||
Reference in New Issue
Block a user