Mesh: Draw: Replace extractor abstraction for face dots position buffer
Part of #116901.
This commit is contained in:
@@ -650,7 +650,6 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_area);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_angle);
|
||||
EXTRACT_ADD_REQUESTED(vbo, mesh_analysis);
|
||||
EXTRACT_ADD_REQUESTED(vbo, fdots_pos);
|
||||
EXTRACT_ADD_REQUESTED(vbo, fdots_uv);
|
||||
EXTRACT_ADD_REQUESTED(vbo, fdots_edituv_data);
|
||||
EXTRACT_ADD_REQUESTED(vbo, skin_roots);
|
||||
@@ -671,12 +670,12 @@ 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_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))
|
||||
!DRW_vbo_requested(buffers.vbo.pos) && !DRW_vbo_requested(buffers.vbo.fdots_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;
|
||||
}
|
||||
@@ -727,6 +726,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_vbo_requested(buffers.vbo.fdots_pos)) {
|
||||
struct TaskData {
|
||||
MeshRenderData &mr;
|
||||
MeshBufferCache &mbc;
|
||||
};
|
||||
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_position(data.mr, *data.mbc.buff.vbo.fdots_pos);
|
||||
},
|
||||
new TaskData{*mr, mbc},
|
||||
[](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.nor)) {
|
||||
struct TaskData {
|
||||
MeshRenderData &mr;
|
||||
@@ -1010,13 +1024,6 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
EXTRACT_ADD_REQUESTED(vbo, attr[i]);
|
||||
}
|
||||
|
||||
/* We use only one extractor for face dots, as the work is done in a single compute shader. */
|
||||
if (DRW_vbo_requested(buffers.vbo.fdots_nor) || DRW_vbo_requested(buffers.vbo.fdots_pos) ||
|
||||
DRW_ibo_requested(buffers.ibo.fdots))
|
||||
{
|
||||
extractors.append(&extract_fdots_pos);
|
||||
}
|
||||
|
||||
EXTRACT_ADD_REQUESTED(ibo, edituv_points);
|
||||
EXTRACT_ADD_REQUESTED(ibo, edituv_tris);
|
||||
EXTRACT_ADD_REQUESTED(ibo, edituv_lines);
|
||||
@@ -1038,7 +1045,9 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
!DRW_vbo_requested(buffers.vbo.orco) && !DRW_vbo_requested(buffers.vbo.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.weights))
|
||||
!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))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1082,6 +1091,13 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
if (DRW_vbo_requested(buffers.vbo.weights)) {
|
||||
extract_weights_subdiv(mr, subdiv_cache, cache, *buffers.vbo.weights);
|
||||
}
|
||||
if (DRW_vbo_requested(buffers.vbo.fdots_nor) || DRW_vbo_requested(buffers.vbo.fdots_pos) ||
|
||||
DRW_ibo_requested(buffers.ibo.fdots))
|
||||
{
|
||||
/* We use only one extractor for face dots, as the work is done in a single compute shader. */
|
||||
extract_face_dots_subdiv(
|
||||
subdiv_cache, *buffers.vbo.fdots_pos, buffers.vbo.fdots_nor, *buffers.ibo.fdots);
|
||||
}
|
||||
|
||||
void *data_stack = MEM_mallocN(extractors.data_size_total(), __func__);
|
||||
uint32_t data_offset = 0;
|
||||
|
||||
@@ -362,6 +362,12 @@ void extract_positions_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
gpu::VertBuf &vbo,
|
||||
gpu::VertBuf *orco_vbo);
|
||||
|
||||
void extract_face_dots_position(const MeshRenderData &mr, gpu::VertBuf &vbo);
|
||||
void extract_face_dots_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
gpu::VertBuf &fdots_pos,
|
||||
gpu::VertBuf *fdots_nor,
|
||||
gpu::IndexBuf &fdots);
|
||||
|
||||
void extract_normals(const MeshRenderData &mr, bool use_hq, gpu::VertBuf &vbo);
|
||||
void extract_normals_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
gpu::VertBuf &pos_nor,
|
||||
@@ -443,7 +449,6 @@ extern const MeshExtract extract_edituv_data;
|
||||
extern const MeshExtract extract_edituv_stretch_area;
|
||||
extern const MeshExtract extract_edituv_stretch_angle;
|
||||
extern const MeshExtract extract_mesh_analysis;
|
||||
extern const MeshExtract extract_fdots_pos;
|
||||
extern const MeshExtract extract_fdots_uv;
|
||||
extern const MeshExtract extract_fdots_edituv_data;
|
||||
extern const MeshExtract extract_skin_roots;
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Face-dots positions
|
||||
* \{ */
|
||||
|
||||
static GPUVertFormat *get_fdots_pos_format()
|
||||
{
|
||||
static GPUVertFormat format = {0};
|
||||
@@ -36,103 +32,84 @@ static GPUVertFormat *get_fdots_nor_format_subdiv()
|
||||
return &format;
|
||||
}
|
||||
|
||||
static void extract_fdots_pos_init(const MeshRenderData &mr,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void *buf,
|
||||
void *tls_data)
|
||||
static void extract_face_dot_positions_mesh(const MeshRenderData &mr, MutableSpan<float3> vbo_data)
|
||||
{
|
||||
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buf);
|
||||
GPUVertFormat *format = get_fdots_pos_format();
|
||||
GPU_vertbuf_init_with_format(vbo, format);
|
||||
GPU_vertbuf_data_alloc(vbo, mr.faces_num);
|
||||
void *vbo_data = GPU_vertbuf_get_data(vbo);
|
||||
*(float(**)[3])tls_data = static_cast<float(*)[3]>(vbo_data);
|
||||
const Span<float3> positions = mr.vert_positions;
|
||||
const OffsetIndices faces = mr.faces;
|
||||
const Span<int> corner_verts = mr.corner_verts;
|
||||
if (mr.use_subsurf_fdots) {
|
||||
const BitSpan facedot_tags = mr.mesh->runtime->subsurf_face_dot_tags;
|
||||
threading::parallel_for(faces.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int face : range) {
|
||||
const Span<int> face_verts = corner_verts.slice(faces[face]);
|
||||
const int *vert = std::find_if(face_verts.begin(), face_verts.end(), [&](const int vert) {
|
||||
return facedot_tags[vert].test();
|
||||
});
|
||||
if (vert == face_verts.end()) {
|
||||
vbo_data[face] = float3(0);
|
||||
}
|
||||
else {
|
||||
vbo_data[face] = positions[*vert];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
threading::parallel_for(faces.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int face : range) {
|
||||
vbo_data[face] = bke::mesh::face_center_calc(positions, corner_verts.slice(faces[face]));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_fdots_pos_iter_face_bm(const MeshRenderData &mr,
|
||||
const BMFace *f,
|
||||
const int f_index,
|
||||
void *data)
|
||||
static void extract_face_dot_positions_bm(const MeshRenderData &mr, MutableSpan<float3> vbo_data)
|
||||
{
|
||||
float(*center)[3] = *static_cast<float(**)[3]>(data);
|
||||
|
||||
float *co = center[f_index];
|
||||
zero_v3(co);
|
||||
|
||||
BMLoop *l_iter, *l_first;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
add_v3_v3(co, bm_vert_co_get(mr, l_iter->v));
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
mul_v3_fl(co, 1.0f / float(f->len));
|
||||
}
|
||||
|
||||
static void extract_fdots_pos_iter_face_mesh(const MeshRenderData &mr,
|
||||
const int face_index,
|
||||
void *data)
|
||||
{
|
||||
float(*center)[3] = *static_cast<float(**)[3]>(data);
|
||||
float *co = center[face_index];
|
||||
zero_v3(co);
|
||||
|
||||
const BitSpan facedot_tags = mr.mesh->runtime->subsurf_face_dot_tags;
|
||||
|
||||
for (const int corner : mr.faces[face_index]) {
|
||||
const int vert = mr.corner_verts[corner];
|
||||
if (mr.use_subsurf_fdots) {
|
||||
if (facedot_tags[vert]) {
|
||||
copy_v3_v3(center[face_index], mr.vert_positions[vert]);
|
||||
break;
|
||||
const BMesh &bm = *mr.bm;
|
||||
threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) {
|
||||
for (const int face_index : range) {
|
||||
const BMFace &face = *BM_face_at_index(&const_cast<BMesh &>(bm), face_index);
|
||||
if (mr.bm_vert_coords.is_empty()) {
|
||||
BM_face_calc_center_median(&face, vbo_data[face_index]);
|
||||
}
|
||||
else {
|
||||
BM_face_calc_center_median_vcos(&bm, &face, vbo_data[face_index], mr.bm_vert_coords);
|
||||
}
|
||||
}
|
||||
else {
|
||||
add_v3_v3(center[face_index], mr.vert_positions[vert]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!mr.use_subsurf_fdots) {
|
||||
mul_v3_fl(co, 1.0f / float(mr.faces[face_index].size()));
|
||||
void extract_face_dots_position(const MeshRenderData &mr, gpu::VertBuf &vbo)
|
||||
{
|
||||
GPUVertFormat *format = get_fdots_pos_format();
|
||||
GPU_vertbuf_init_with_format(&vbo, format);
|
||||
GPU_vertbuf_data_alloc(&vbo, mr.corners_num + mr.loose_indices_num);
|
||||
|
||||
MutableSpan vbo_data(static_cast<float3 *>(GPU_vertbuf_get_data(&vbo)),
|
||||
GPU_vertbuf_get_vertex_len(&vbo));
|
||||
if (mr.extract_type == MR_EXTRACT_MESH) {
|
||||
extract_face_dot_positions_mesh(mr, vbo_data);
|
||||
}
|
||||
else {
|
||||
extract_face_dot_positions_bm(mr, vbo_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_fdots_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData & /*mr*/,
|
||||
MeshBatchCache &cache,
|
||||
void *buffer,
|
||||
void * /*data*/)
|
||||
void extract_face_dots_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
gpu::VertBuf &fdots_pos,
|
||||
gpu::VertBuf *fdots_nor,
|
||||
gpu::IndexBuf &fdots)
|
||||
{
|
||||
/* We "extract" positions, normals, and indices at once. */
|
||||
gpu::VertBuf *fdots_pos_vbo = static_cast<gpu::VertBuf *>(buffer);
|
||||
gpu::VertBuf *fdots_nor_vbo = cache.final.buff.vbo.fdots_nor;
|
||||
gpu::IndexBuf *fdots_pos_ibo = cache.final.buff.ibo.fdots;
|
||||
|
||||
/* The normals may not be requested. */
|
||||
if (fdots_nor_vbo) {
|
||||
if (fdots_nor) {
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
fdots_nor_vbo, get_fdots_nor_format_subdiv(), subdiv_cache.num_coarse_faces);
|
||||
fdots_nor, get_fdots_nor_format_subdiv(), subdiv_cache.num_coarse_faces);
|
||||
}
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
fdots_pos_vbo, get_fdots_pos_format(), subdiv_cache.num_coarse_faces);
|
||||
GPU_indexbuf_init_build_on_device(fdots_pos_ibo, subdiv_cache.num_coarse_faces);
|
||||
draw_subdiv_build_fdots_buffers(subdiv_cache, fdots_pos_vbo, fdots_nor_vbo, fdots_pos_ibo);
|
||||
&fdots_pos, get_fdots_pos_format(), subdiv_cache.num_coarse_faces);
|
||||
GPU_indexbuf_init_build_on_device(&fdots, subdiv_cache.num_coarse_faces);
|
||||
draw_subdiv_build_fdots_buffers(subdiv_cache, &fdots_pos, fdots_nor, &fdots);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_fdots_pos()
|
||||
{
|
||||
MeshExtract extractor = {nullptr};
|
||||
extractor.init = extract_fdots_pos_init;
|
||||
extractor.init_subdiv = extract_fdots_init_subdiv;
|
||||
extractor.iter_face_bm = extract_fdots_pos_iter_face_bm;
|
||||
extractor.iter_face_mesh = extract_fdots_pos_iter_face_mesh;
|
||||
extractor.data_type = MR_DATA_NONE;
|
||||
extractor.data_size = sizeof(float(*)[3]);
|
||||
extractor.use_threading = true;
|
||||
extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.fdots_pos);
|
||||
return extractor;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
const MeshExtract extract_fdots_pos = create_extractor_fdots_pos();
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
Reference in New Issue
Block a user