Mesh: Draw: Replace extractor abstraction for paint mask lines buffer
Part of #116901. A straightfoward change this time; the algorithm wasn't adjusted, it was just put inside of a single loop. I did change some nested if statements to continue statements to reduce indentation though.
This commit is contained in:
@@ -657,7 +657,6 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
}
|
||||
EXTRACT_ADD_REQUESTED(vbo, attr_viewer);
|
||||
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_adjacency);
|
||||
EXTRACT_ADD_REQUESTED(ibo, edituv_tris);
|
||||
EXTRACT_ADD_REQUESTED(ibo, edituv_lines);
|
||||
@@ -675,7 +674,8 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
!DRW_vbo_requested(buffers.vbo.tan) && !DRW_vbo_requested(buffers.vbo.edit_data) &&
|
||||
!DRW_vbo_requested(buffers.vbo.face_idx) && !DRW_vbo_requested(buffers.vbo.edge_idx) &&
|
||||
!DRW_vbo_requested(buffers.vbo.vert_idx) && !DRW_vbo_requested(buffers.vbo.fdot_idx) &&
|
||||
!DRW_vbo_requested(buffers.vbo.weights) && !DRW_vbo_requested(buffers.vbo.fdots_uv))
|
||||
!DRW_vbo_requested(buffers.vbo.weights) && !DRW_vbo_requested(buffers.vbo.fdots_uv) &&
|
||||
!DRW_ibo_requested(buffers.ibo.lines_paint_mask))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -961,6 +961,21 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
[](void *task_data) { delete static_cast<TaskData *>(task_data); });
|
||||
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
|
||||
}
|
||||
if (DRW_ibo_requested(buffers.ibo.lines_paint_mask)) {
|
||||
struct TaskData {
|
||||
MeshRenderData &mr;
|
||||
MeshBufferList &buffers;
|
||||
};
|
||||
TaskNode *task_node = BLI_task_graph_node_create(
|
||||
&task_graph,
|
||||
[](void *__restrict task_data) {
|
||||
const TaskData &data = *static_cast<TaskData *>(task_data);
|
||||
extract_lines_paint_mask(data.mr, *data.buffers.ibo.lines_paint_mask);
|
||||
},
|
||||
new TaskData{*mr, buffers},
|
||||
[](void *task_data) { delete static_cast<TaskData *>(task_data); });
|
||||
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
|
||||
}
|
||||
|
||||
if (use_thread) {
|
||||
/* First run the requested extractors that do not support asynchronous ranges. */
|
||||
@@ -1062,7 +1077,6 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
EXTRACT_ADD_REQUESTED(vbo, uv);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_area);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_angle);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_adjacency);
|
||||
EXTRACT_ADD_REQUESTED(vbo, sculpt_data);
|
||||
|
||||
@@ -1076,7 +1090,8 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
!DRW_vbo_requested(buffers.vbo.edit_data) && !DRW_vbo_requested(buffers.vbo.face_idx) &&
|
||||
!DRW_vbo_requested(buffers.vbo.edge_idx) && !DRW_vbo_requested(buffers.vbo.vert_idx) &&
|
||||
!DRW_vbo_requested(buffers.vbo.weights) && !DRW_vbo_requested(buffers.vbo.fdots_nor) &&
|
||||
!DRW_vbo_requested(buffers.vbo.fdots_pos) && !DRW_ibo_requested(buffers.ibo.fdots))
|
||||
!DRW_vbo_requested(buffers.vbo.fdots_pos) && !DRW_ibo_requested(buffers.ibo.fdots) &&
|
||||
!DRW_ibo_requested(buffers.ibo.lines_paint_mask))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1130,6 +1145,9 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
extract_face_dots_subdiv(
|
||||
subdiv_cache, *buffers.vbo.fdots_pos, buffers.vbo.fdots_nor, *buffers.ibo.fdots);
|
||||
}
|
||||
if (DRW_ibo_requested(buffers.ibo.lines_paint_mask)) {
|
||||
extract_lines_paint_mask_subdiv(mr, subdiv_cache, *buffers.ibo.lines_paint_mask);
|
||||
}
|
||||
|
||||
void *data_stack = MEM_mallocN(extractors.data_size_total(), __func__);
|
||||
uint32_t data_offset = 0;
|
||||
|
||||
@@ -442,7 +442,11 @@ void extract_face_dots(const MeshRenderData &mr, gpu::IndexBuf &face_dots);
|
||||
|
||||
void extract_face_dots_uv(const MeshRenderData &mr, gpu::VertBuf &vbo);
|
||||
|
||||
extern const MeshExtract extract_lines_paint_mask;
|
||||
void extract_lines_paint_mask(const MeshRenderData &mr, gpu::IndexBuf &lines);
|
||||
void extract_lines_paint_mask_subdiv(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache,
|
||||
gpu::IndexBuf &lines);
|
||||
|
||||
extern const MeshExtract extract_lines_adjacency;
|
||||
extern const MeshExtract extract_edituv_tris;
|
||||
extern const MeshExtract extract_edituv_lines;
|
||||
|
||||
@@ -17,164 +17,128 @@
|
||||
#include "extract_mesh.hh"
|
||||
|
||||
namespace blender::draw {
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Paint Mask Line Indices
|
||||
* \{ */
|
||||
|
||||
struct MeshExtract_LinePaintMask_Data {
|
||||
GPUIndexBufBuilder elb;
|
||||
/** One bit per edge set if face is selected. */
|
||||
BLI_bitmap *select_map;
|
||||
};
|
||||
|
||||
static void extract_lines_paint_mask_init(const MeshRenderData &mr,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void * /*ibo*/,
|
||||
void *tls_data)
|
||||
void extract_lines_paint_mask(const MeshRenderData &mr, gpu::IndexBuf &lines)
|
||||
{
|
||||
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(tls_data);
|
||||
data->select_map = BLI_BITMAP_NEW(mr.edges_num, __func__);
|
||||
GPU_indexbuf_init(&data->elb, GPU_PRIM_LINES, mr.edges_num, mr.corners_num);
|
||||
}
|
||||
const OffsetIndices faces = mr.faces;
|
||||
const Span<int> corner_edges = mr.corner_edges;
|
||||
const Span<bool> hide_edge = mr.hide_edge;
|
||||
const Span<bool> select_poly = mr.select_poly;
|
||||
const Span<int> orig_index_edge = mr.orig_index_edge ?
|
||||
Span<int>(mr.orig_index_edge, mr.edges_num) :
|
||||
Span<int>();
|
||||
|
||||
static void extract_lines_paint_mask_iter_face_mesh(const MeshRenderData &mr,
|
||||
const int face_index,
|
||||
void *_data)
|
||||
{
|
||||
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(_data);
|
||||
const IndexRange face = mr.faces[face_index];
|
||||
GPUIndexBufBuilder builder;
|
||||
const int max_index = mr.corners_num;
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_LINES, mr.edges_num, max_index);
|
||||
MutableSpan<uint2> data = GPU_indexbuf_get_data(&builder).cast<uint2>();
|
||||
|
||||
for (const int corner : face) {
|
||||
const int e_index = mr.corner_edges[corner];
|
||||
|
||||
if (!((mr.use_hide && !mr.hide_edge.is_empty() && mr.hide_edge[e_index]) ||
|
||||
((mr.orig_index_edge) && (mr.orig_index_edge[e_index] == ORIGINDEX_NONE))))
|
||||
{
|
||||
|
||||
const int corner_next = bke::mesh::face_corner_next(face, corner);
|
||||
if (!mr.select_poly.is_empty() && mr.select_poly[face_index]) {
|
||||
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, e_index)) {
|
||||
/* Hide edge as it has more than 2 selected loop. */
|
||||
GPU_indexbuf_set_line_restart(&data->elb, e_index);
|
||||
BLI_bitmap *select_map = BLI_BITMAP_NEW(mr.edges_num, __func__);
|
||||
threading::parallel_for(faces.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int face_index : range) {
|
||||
const IndexRange face = faces[face_index];
|
||||
for (const int corner : face) {
|
||||
const int edge = corner_edges[corner];
|
||||
if ((!hide_edge.is_empty() && hide_edge[edge]) ||
|
||||
(!orig_index_edge.is_empty() && (orig_index_edge[edge] == ORIGINDEX_NONE)))
|
||||
{
|
||||
data[edge] = uint2(gpu::RESTART_INDEX);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
/* First selected loop. Set edge visible, overwriting any unselected loop. */
|
||||
GPU_indexbuf_set_line_verts(&data->elb, e_index, corner, corner_next);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Set these unselected loop only if this edge has no other selected loop. */
|
||||
if (!BLI_BITMAP_TEST(data->select_map, e_index)) {
|
||||
GPU_indexbuf_set_line_verts(&data->elb, e_index, corner, corner_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
GPU_indexbuf_set_line_restart(&data->elb, e_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_lines_paint_mask_finish(const MeshRenderData & /*mr*/,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void *buf,
|
||||
void *_data)
|
||||
{
|
||||
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(_data);
|
||||
gpu::IndexBuf *ibo = static_cast<gpu::IndexBuf *>(buf);
|
||||
GPU_indexbuf_build_in_place(&data->elb, ibo);
|
||||
MEM_freeN(data->select_map);
|
||||
}
|
||||
|
||||
static void extract_lines_paint_mask_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void * /*buf*/,
|
||||
void *tls_data)
|
||||
{
|
||||
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(tls_data);
|
||||
data->select_map = BLI_BITMAP_NEW(mr.edges_num, __func__);
|
||||
GPU_indexbuf_init(&data->elb,
|
||||
GPU_PRIM_LINES,
|
||||
subdiv_cache.num_subdiv_edges,
|
||||
subdiv_cache.num_subdiv_loops * 2);
|
||||
}
|
||||
|
||||
static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
void *_data,
|
||||
uint subdiv_quad_index,
|
||||
const int coarse_quad_index)
|
||||
{
|
||||
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(_data);
|
||||
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache.edges_orig_index);
|
||||
int *subdiv_loop_subdiv_edge_index = subdiv_cache.subdiv_loop_subdiv_edge_index;
|
||||
|
||||
const IndexRange subdiv_face(subdiv_quad_index * 4, 4);
|
||||
|
||||
for (const int corner : subdiv_face) {
|
||||
const uint coarse_edge_index = uint(subdiv_loop_edge_index[corner]);
|
||||
const uint subdiv_edge_index = uint(subdiv_loop_subdiv_edge_index[corner]);
|
||||
|
||||
if (coarse_edge_index == -1u) {
|
||||
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);
|
||||
}
|
||||
else {
|
||||
if (!((mr.use_hide && !mr.hide_edge.is_empty() && mr.hide_edge[coarse_edge_index]) ||
|
||||
((mr.orig_index_edge) && (mr.orig_index_edge[coarse_edge_index] == ORIGINDEX_NONE))))
|
||||
{
|
||||
const int corner_next = bke::mesh::face_corner_next(subdiv_face, corner);
|
||||
if (!mr.select_poly.is_empty() && mr.select_poly[coarse_quad_index]) {
|
||||
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, coarse_edge_index)) {
|
||||
const int corner_next = bke::mesh::face_corner_next(face, corner);
|
||||
if (!select_poly.is_empty() && select_poly[face_index]) {
|
||||
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(select_map, edge)) {
|
||||
/* Hide edge as it has more than 2 selected loop. */
|
||||
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);
|
||||
data[edge] = uint2(gpu::RESTART_INDEX);
|
||||
}
|
||||
else {
|
||||
/* First selected loop. Set edge visible, overwriting any unselected loop. */
|
||||
GPU_indexbuf_set_line_verts(&data->elb, subdiv_edge_index, corner, corner_next);
|
||||
data[edge] = uint2(corner, corner_next);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Set these unselected loop only if this edge has no other selected loop. */
|
||||
if (!BLI_BITMAP_TEST(data->select_map, coarse_edge_index)) {
|
||||
GPU_indexbuf_set_line_verts(&data->elb, subdiv_edge_index, corner, corner_next);
|
||||
if (!BLI_BITMAP_TEST(select_map, edge)) {
|
||||
data[edge] = uint2(corner, corner_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);
|
||||
}
|
||||
});
|
||||
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, max_index, true, &lines);
|
||||
|
||||
MEM_freeN(select_map);
|
||||
}
|
||||
|
||||
void extract_lines_paint_mask_subdiv(const MeshRenderData &mr,
|
||||
const DRWSubdivCache &subdiv_cache,
|
||||
gpu::IndexBuf &lines)
|
||||
{
|
||||
const Span<bool> hide_edge = mr.hide_edge;
|
||||
const Span<bool> select_poly = mr.select_poly;
|
||||
const Span<int> orig_index_edge = mr.orig_index_edge ?
|
||||
Span<int>(mr.orig_index_edge, mr.edges_num) :
|
||||
Span<int>();
|
||||
const Span<int> subdiv_loop_face_index(subdiv_cache.subdiv_loop_face_index,
|
||||
subdiv_cache.num_subdiv_loops);
|
||||
const Span<int> subdiv_loop_subdiv_edge_index(subdiv_cache.subdiv_loop_subdiv_edge_index,
|
||||
subdiv_cache.num_subdiv_loops);
|
||||
const Span<int> subdiv_loop_edge_index(
|
||||
static_cast<const int *>(GPU_vertbuf_get_data(subdiv_cache.edges_orig_index)),
|
||||
subdiv_cache.num_subdiv_edges);
|
||||
|
||||
GPUIndexBufBuilder builder;
|
||||
const int max_index = subdiv_cache.num_subdiv_loops;
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_LINES, subdiv_cache.num_subdiv_edges, max_index);
|
||||
MutableSpan<uint2> data = GPU_indexbuf_get_data(&builder).cast<uint2>();
|
||||
|
||||
BLI_bitmap *select_map = BLI_BITMAP_NEW(mr.edges_num, __func__);
|
||||
const int quads_num = subdiv_cache.num_subdiv_quads;
|
||||
threading::parallel_for(IndexRange(quads_num), 4096, [&](const IndexRange range) {
|
||||
for (const int subdiv_quad_index : range) {
|
||||
const int coarse_quad_index = subdiv_loop_face_index[subdiv_quad_index * 4];
|
||||
const IndexRange subdiv_face(subdiv_quad_index * 4, 4);
|
||||
for (const int corner : subdiv_face) {
|
||||
const uint coarse_edge_index = uint(subdiv_loop_edge_index[corner]);
|
||||
const uint subdiv_edge_index = uint(subdiv_loop_subdiv_edge_index[corner]);
|
||||
if (coarse_edge_index == -1u) {
|
||||
data[subdiv_edge_index] = uint2(gpu::RESTART_INDEX);
|
||||
continue;
|
||||
}
|
||||
if ((!hide_edge.is_empty() && hide_edge[coarse_edge_index]) ||
|
||||
(!orig_index_edge.is_empty() &&
|
||||
(orig_index_edge[coarse_edge_index] == ORIGINDEX_NONE)))
|
||||
{
|
||||
data[subdiv_edge_index] = uint2(gpu::RESTART_INDEX);
|
||||
continue;
|
||||
}
|
||||
|
||||
const int corner_next = bke::mesh::face_corner_next(subdiv_face, corner);
|
||||
if (!select_poly.is_empty() && select_poly[coarse_quad_index]) {
|
||||
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(select_map, coarse_edge_index)) {
|
||||
/* Hide edge as it has more than 2 selected loop. */
|
||||
data[subdiv_edge_index] = uint2(gpu::RESTART_INDEX);
|
||||
}
|
||||
else {
|
||||
/* First selected loop. Set edge visible, overwriting any unselected loop. */
|
||||
data[subdiv_edge_index] = uint2(corner, corner_next);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Set these unselected loop only if this edge has no other selected loop. */
|
||||
if (!BLI_BITMAP_TEST(select_map, coarse_edge_index)) {
|
||||
data[subdiv_edge_index] = uint2(corner, corner_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, max_index, true, &lines);
|
||||
|
||||
MEM_freeN(select_map);
|
||||
}
|
||||
|
||||
static void extract_lines_paint_mask_finish_subdiv(const DRWSubdivCache & /*subdiv_cache*/,
|
||||
const MeshRenderData &mr,
|
||||
MeshBatchCache &cache,
|
||||
void *buf,
|
||||
void *_data)
|
||||
{
|
||||
extract_lines_paint_mask_finish(mr, cache, buf, _data);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_lines_paint_mask()
|
||||
{
|
||||
MeshExtract extractor = {nullptr};
|
||||
extractor.init = extract_lines_paint_mask_init;
|
||||
extractor.iter_face_mesh = extract_lines_paint_mask_iter_face_mesh;
|
||||
extractor.finish = extract_lines_paint_mask_finish;
|
||||
extractor.init_subdiv = extract_lines_paint_mask_init_subdiv;
|
||||
extractor.iter_subdiv_mesh = extract_lines_paint_mask_iter_subdiv_mesh;
|
||||
extractor.finish_subdiv = extract_lines_paint_mask_finish_subdiv;
|
||||
extractor.data_type = MR_DATA_NONE;
|
||||
extractor.data_size = sizeof(MeshExtract_LinePaintMask_Data);
|
||||
extractor.use_threading = false;
|
||||
extractor.mesh_buffer_offset = offsetof(MeshBufferList, ibo.lines_paint_mask);
|
||||
return extractor;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
const MeshExtract extract_lines_paint_mask = create_extractor_lines_paint_mask();
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
Reference in New Issue
Block a user