Mesh: Draw: Replace extractor abstraction for face dots index buffer
Part of #116901.
Very similar to 07eac30070.
This commit is contained in:
@@ -659,7 +659,6 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
}
|
||||
EXTRACT_ADD_REQUESTED(vbo, attr_viewer);
|
||||
|
||||
EXTRACT_ADD_REQUESTED(ibo, fdots);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_adjacency);
|
||||
EXTRACT_ADD_REQUESTED(ibo, edituv_tris);
|
||||
@@ -671,12 +670,13 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
|
||||
if (extractors.is_empty() && !DRW_ibo_requested(buffers.ibo.lines) &&
|
||||
!DRW_ibo_requested(buffers.ibo.lines_loose) && !DRW_ibo_requested(buffers.ibo.tris) &&
|
||||
!DRW_ibo_requested(buffers.ibo.points) && !DRW_vbo_requested(buffers.vbo.pos) &&
|
||||
!DRW_vbo_requested(buffers.vbo.nor) && !DRW_vbo_requested(buffers.vbo.vnor) &&
|
||||
!DRW_vbo_requested(buffers.vbo.fdots_nor) && !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_ibo_requested(buffers.ibo.points) && !DRW_ibo_requested(buffers.ibo.fdots) &&
|
||||
!DRW_vbo_requested(buffers.vbo.pos) && !DRW_vbo_requested(buffers.vbo.nor) &&
|
||||
!DRW_vbo_requested(buffers.vbo.vnor) && !DRW_vbo_requested(buffers.vbo.fdots_nor) &&
|
||||
!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))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -826,6 +826,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.fdots)) {
|
||||
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_face_dots(data.mr, *data.buffers.ibo.fdots);
|
||||
},
|
||||
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 (DRW_vbo_requested(buffers.vbo.edit_data)) {
|
||||
struct TaskData {
|
||||
MeshRenderData &mr;
|
||||
|
||||
@@ -427,7 +427,8 @@ void extract_weights_subdiv(const MeshRenderData &mr,
|
||||
const MeshBatchCache &cache,
|
||||
gpu::VertBuf &vbo);
|
||||
|
||||
extern const MeshExtract extract_fdots;
|
||||
void extract_face_dots(const MeshRenderData &mr, gpu::IndexBuf &face_dots);
|
||||
|
||||
extern const MeshExtract extract_lines_paint_mask;
|
||||
extern const MeshExtract extract_lines_adjacency;
|
||||
extern const MeshExtract extract_edituv_tris;
|
||||
|
||||
@@ -11,88 +11,63 @@
|
||||
#include "extract_mesh.hh"
|
||||
|
||||
namespace blender::draw {
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Face-dots Indices
|
||||
* \{ */
|
||||
|
||||
static void extract_fdots_init(const MeshRenderData &mr,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void * /*buf*/,
|
||||
void *tls_data)
|
||||
static IndexMask calc_face_visibility_mesh(const MeshRenderData &mr, IndexMaskMemory &memory)
|
||||
{
|
||||
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
|
||||
GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr.faces_num, mr.faces_num);
|
||||
}
|
||||
|
||||
static void extract_fdots_iter_face_bm(const MeshRenderData & /*mr*/,
|
||||
const BMFace *f,
|
||||
const int f_index,
|
||||
void *_userdata)
|
||||
{
|
||||
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
|
||||
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
||||
GPU_indexbuf_set_point_vert(elb, f_index, f_index);
|
||||
IndexMask visible(mr.faces_num);
|
||||
if (!mr.hide_poly.is_empty()) {
|
||||
visible = IndexMask::from_bools_inverse(visible, mr.hide_poly, memory);
|
||||
}
|
||||
else {
|
||||
GPU_indexbuf_set_point_restart(elb, f_index);
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_fdots_iter_face_mesh(const MeshRenderData &mr,
|
||||
const int face_index,
|
||||
void *_userdata)
|
||||
{
|
||||
const bool hidden = mr.use_hide && !mr.hide_poly.is_empty() && mr.hide_poly[face_index];
|
||||
|
||||
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
|
||||
if (mr.use_subsurf_fdots) {
|
||||
const OffsetIndices faces = mr.faces;
|
||||
const Span<int> corner_verts = mr.corner_verts;
|
||||
const BitSpan facedot_tags = mr.mesh->runtime->subsurf_face_dot_tags;
|
||||
visible = IndexMask::from_predicate(visible, GrainSize(4096), memory, [&](const int i) {
|
||||
const Span<int> face_verts = corner_verts.slice(faces[i]);
|
||||
return std::any_of(face_verts.begin(), face_verts.end(), [&](const int vert) {
|
||||
return facedot_tags[vert];
|
||||
});
|
||||
});
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
for (const int corner : mr.faces[face_index]) {
|
||||
const int vert = mr.corner_verts[corner];
|
||||
if (facedot_tags[vert] && !hidden) {
|
||||
GPU_indexbuf_set_point_vert(elb, face_index, face_index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
GPU_indexbuf_set_point_restart(elb, face_index);
|
||||
static void index_mask_to_ibo(const IndexMask &mask, gpu::IndexBuf &ibo)
|
||||
{
|
||||
const int max_index = mask.min_array_size();
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_POINTS, mask.size(), max_index);
|
||||
MutableSpan<uint> data = GPU_indexbuf_get_data(&builder);
|
||||
mask.to_indices<int>(data.cast<int>());
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, max_index, false, &ibo);
|
||||
}
|
||||
|
||||
static void extract_face_dots_mesh(const MeshRenderData &mr, gpu::IndexBuf &face_dots)
|
||||
{
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask visible_faces = calc_face_visibility_mesh(mr, memory);
|
||||
index_mask_to_ibo(visible_faces, face_dots);
|
||||
}
|
||||
|
||||
static void extract_face_dots_bm(const MeshRenderData &mr, gpu::IndexBuf &face_dots)
|
||||
{
|
||||
BMesh &bm = *mr.bm;
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask visible_faces = IndexMask::from_predicate(
|
||||
IndexRange(bm.totface), GrainSize(4096), memory, [&](const int i) {
|
||||
return !BM_elem_flag_test_bool(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN);
|
||||
});
|
||||
index_mask_to_ibo(visible_faces, face_dots);
|
||||
}
|
||||
|
||||
void extract_face_dots(const MeshRenderData &mr, gpu::IndexBuf &face_dots)
|
||||
{
|
||||
if (mr.extract_type == MR_EXTRACT_MESH) {
|
||||
extract_face_dots_mesh(mr, face_dots);
|
||||
}
|
||||
else {
|
||||
if (!hidden) {
|
||||
GPU_indexbuf_set_point_vert(elb, face_index, face_index);
|
||||
}
|
||||
else {
|
||||
GPU_indexbuf_set_point_restart(elb, face_index);
|
||||
}
|
||||
extract_face_dots_bm(mr, face_dots);
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_fdots_finish(const MeshRenderData & /*mr*/,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void *buf,
|
||||
void *_userdata)
|
||||
{
|
||||
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
|
||||
gpu::IndexBuf *ibo = static_cast<gpu::IndexBuf *>(buf);
|
||||
GPU_indexbuf_build_in_place(elb, ibo);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_fdots()
|
||||
{
|
||||
MeshExtract extractor = {nullptr};
|
||||
extractor.init = extract_fdots_init;
|
||||
extractor.iter_face_bm = extract_fdots_iter_face_bm;
|
||||
extractor.iter_face_mesh = extract_fdots_iter_face_mesh;
|
||||
extractor.finish = extract_fdots_finish;
|
||||
extractor.data_type = MR_DATA_NONE;
|
||||
extractor.data_size = sizeof(GPUIndexBufBuilder);
|
||||
extractor.use_threading = false;
|
||||
extractor.mesh_buffer_offset = offsetof(MeshBufferList, ibo.fdots);
|
||||
return extractor;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
const MeshExtract extract_fdots = create_extractor_fdots();
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
Reference in New Issue
Block a user