Cleanup: Remove unused MeshExtract virtual iteration abstraction

Part of #116901.
This has been removed step by step in the previous commits.
This commit is contained in:
Hans Goudey
2024-06-03 23:10:00 -04:00
committed by Hans Goudey
parent eb4f3516a6
commit 24055d1837
4 changed files with 7 additions and 697 deletions

View File

@@ -50,23 +50,6 @@ enum {
DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE = (1 << 2),
};
enum eMRIterType {
MR_ITER_CORNER_TRI = 1 << 0,
MR_ITER_POLY = 1 << 1,
MR_ITER_LOOSE_EDGE = 1 << 2,
MR_ITER_LOOSE_VERT = 1 << 3,
};
ENUM_OPERATORS(eMRIterType, MR_ITER_LOOSE_VERT)
enum eMRDataType {
MR_DATA_NONE = 0,
MR_DATA_POLY_NOR = 1 << 1,
MR_DATA_LOOP_NOR = 1 << 2,
MR_DATA_LOOSE_GEOM = 1 << 4,
MR_DATA_POLYS_SORTED = 1 << 6,
};
ENUM_OPERATORS(eMRDataType, MR_DATA_POLYS_SORTED)
int mesh_render_mat_len_get(const Object &object, const Mesh &mesh);
struct MeshBufferList {

View File

@@ -9,15 +9,10 @@
*/
#include "MEM_guardedalloc.h"
#include <optional>
#include "atomic_ops.h"
#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#include "BLI_array.hh"
#include "BLI_math_bits.h"
#include "BLI_task.h"
#include "BLI_vector.hh"
@@ -51,455 +46,11 @@ int mesh_render_mat_len_get(const Object &object, const Mesh &mesh)
return std::max<int>(1, mesh.totcol);
}
/* ---------------------------------------------------------------------- */
/** \name Mesh Elements Extract Struct
* \{ */
using TaskId = int;
using TaskLen = int;
struct ExtractorRunData {
/* Extractor where this run data belongs to. */
const MeshExtract *extractor;
/* During iteration the VBO/IBO that is being build. */
void *buffer = nullptr;
uint32_t data_offset = 0;
ExtractorRunData(const MeshExtract *extractor) : extractor(extractor) {}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("DRAW:ExtractorRunData")
#endif
};
class ExtractorRunDatas : public Vector<ExtractorRunData> {
public:
void filter_into(ExtractorRunDatas &result, eMRIterType iter_type, const bool is_mesh) const
{
for (const ExtractorRunData &data : *this) {
const MeshExtract *extractor = data.extractor;
if ((iter_type & MR_ITER_CORNER_TRI) && *(&extractor->iter_looptri_bm + is_mesh)) {
result.append(data);
continue;
}
if ((iter_type & MR_ITER_POLY) && *(&extractor->iter_face_bm + is_mesh)) {
result.append(data);
continue;
}
if ((iter_type & MR_ITER_LOOSE_EDGE) && *(&extractor->iter_loose_edge_bm + is_mesh)) {
result.append(data);
continue;
}
if ((iter_type & MR_ITER_LOOSE_VERT) && *(&extractor->iter_loose_vert_bm + is_mesh)) {
result.append(data);
continue;
}
}
}
void filter_threaded_extractors_into(ExtractorRunDatas &result)
{
for (const ExtractorRunData &data : *this) {
const MeshExtract *extractor = data.extractor;
if (extractor->use_threading) {
result.append(extractor);
}
}
}
eMRIterType iter_types() const
{
eMRIterType iter_type = static_cast<eMRIterType>(0);
for (const ExtractorRunData &data : *this) {
const MeshExtract *extractor = data.extractor;
iter_type |= mesh_extract_iter_type(extractor);
}
return iter_type;
}
uint iter_types_len() const
{
const eMRIterType iter_type = iter_types();
uint bits = uint(iter_type);
return count_bits_i(bits);
}
eMRDataType data_types()
{
eMRDataType data_type = static_cast<eMRDataType>(0);
for (const ExtractorRunData &data : *this) {
const MeshExtract *extractor = data.extractor;
data_type |= extractor->data_type;
}
return data_type;
}
size_t data_size_total()
{
size_t data_size = 0;
for (const ExtractorRunData &data : *this) {
const MeshExtract *extractor = data.extractor;
data_size += extractor->data_size;
}
return data_size;
}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("DRAW:ExtractorRunDatas")
#endif
};
/** \} */
/* ---------------------------------------------------------------------- */
/** \name ExtractTaskData
* \{ */
struct ExtractTaskData {
const MeshRenderData *mr = nullptr;
MeshBatchCache *cache = nullptr;
ExtractorRunDatas *extractors = nullptr;
MeshBufferList *buffers = nullptr;
eMRIterType iter_type;
bool use_threading = false;
ExtractTaskData(const MeshRenderData &mr,
MeshBatchCache &cache,
ExtractorRunDatas *extractors,
MeshBufferList *buffers,
const bool use_threading)
: mr(&mr),
cache(&cache),
extractors(extractors),
buffers(buffers),
use_threading(use_threading)
{
iter_type = extractors->iter_types();
};
ExtractTaskData(const ExtractTaskData &src) = default;
~ExtractTaskData()
{
delete extractors;
}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("DRW:ExtractTaskData")
#endif
};
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Extract Init and Finish
* \{ */
BLI_INLINE void extract_init(const MeshRenderData &mr,
MeshBatchCache &cache,
ExtractorRunDatas &extractors,
MeshBufferList *buffers,
void *data_stack)
{
uint32_t data_offset = 0;
for (ExtractorRunData &run_data : extractors) {
const MeshExtract *extractor = run_data.extractor;
run_data.buffer = mesh_extract_buffer_get(extractor, buffers);
run_data.data_offset = data_offset;
extractor->init(mr, cache, run_data.buffer, POINTER_OFFSET(data_stack, data_offset));
data_offset += uint32_t(extractor->data_size);
}
}
BLI_INLINE void extract_finish(const MeshRenderData &mr,
MeshBatchCache &cache,
const ExtractorRunDatas &extractors,
void *data_stack)
{
for (const ExtractorRunData &run_data : extractors) {
const MeshExtract *extractor = run_data.extractor;
if (extractor->finish) {
extractor->finish(
mr, cache, run_data.buffer, POINTER_OFFSET(data_stack, run_data.data_offset));
}
}
}
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Extract In Parallel Ranges
* \{ */
struct ExtractorIterData {
ExtractorRunDatas extractors;
const MeshRenderData *mr = nullptr;
const void *elems = nullptr;
const int *loose_elems = nullptr;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("DRW:MeshRenderDataUpdateTaskData")
#endif
};
static void extract_task_reduce(const void *__restrict userdata,
void *__restrict chunk_to,
void *__restrict chunk_from)
{
const ExtractorIterData *data = static_cast<const ExtractorIterData *>(userdata);
for (const ExtractorRunData &run_data : data->extractors) {
const MeshExtract *extractor = run_data.extractor;
if (extractor->task_reduce) {
extractor->task_reduce(POINTER_OFFSET(chunk_to, run_data.data_offset),
POINTER_OFFSET(chunk_from, run_data.data_offset));
}
}
}
static void extract_range_iter_looptri_bm(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
void *extract_data = tls->userdata_chunk;
const MeshRenderData &mr = *data->mr;
BMLoop **elt = ((BMLoop * (*)[3]) data->elems)[iter];
BLI_assert(iter < mr.edit_bmesh->looptris.size());
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_looptri_bm(
mr, elt, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
static void extract_range_iter_corner_tri_mesh(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
void *extract_data = tls->userdata_chunk;
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData &mr = *data->mr;
const int3 &tri = ((const int3 *)data->elems)[iter];
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_corner_tri_mesh(
mr, tri, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
static void extract_range_iter_face_bm(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
void *extract_data = tls->userdata_chunk;
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData &mr = *data->mr;
const BMFace *f = ((const BMFace **)data->elems)[iter];
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_face_bm(
mr, f, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
static void extract_range_iter_face_mesh(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
void *extract_data = tls->userdata_chunk;
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData &mr = *data->mr;
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_face_mesh(
mr, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
static void extract_range_iter_loose_edge_bm(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
void *extract_data = tls->userdata_chunk;
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData &mr = *data->mr;
const int loose_edge_i = data->loose_elems[iter];
const BMEdge *eed = ((const BMEdge **)data->elems)[loose_edge_i];
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_loose_edge_bm(
mr, eed, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
static void extract_range_iter_loose_edge_mesh(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
void *extract_data = tls->userdata_chunk;
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData &mr = *data->mr;
const int loose_edge_i = data->loose_elems[iter];
const int2 edge = ((const int2 *)data->elems)[loose_edge_i];
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_loose_edge_mesh(
mr, edge, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
static void extract_range_iter_loose_vert_bm(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
void *extract_data = tls->userdata_chunk;
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData &mr = *data->mr;
const int loose_vert_i = data->loose_elems[iter];
const BMVert *eve = ((const BMVert **)data->elems)[loose_vert_i];
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_loose_vert_bm(
mr, eve, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
static void extract_range_iter_loose_vert_mesh(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
void *extract_data = tls->userdata_chunk;
const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
const MeshRenderData &mr = *data->mr;
for (const ExtractorRunData &run_data : data->extractors) {
run_data.extractor->iter_loose_vert_mesh(
mr, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
BLI_INLINE void extract_task_range_run_iter(const MeshRenderData &mr,
ExtractorRunDatas *extractors,
const eMRIterType iter_type,
bool is_mesh,
TaskParallelSettings *settings)
{
ExtractorIterData range_data;
range_data.mr = &mr;
TaskParallelRangeFunc func;
int stop;
switch (iter_type) {
case MR_ITER_CORNER_TRI:
range_data.elems = is_mesh ? mr.mesh->corner_tris().data() :
(void *)mr.edit_bmesh->looptris.data();
func = is_mesh ? extract_range_iter_corner_tri_mesh : extract_range_iter_looptri_bm;
stop = mr.corner_tris_num;
break;
case MR_ITER_POLY:
range_data.elems = is_mesh ? mr.faces.data().data() : (void *)mr.bm->ftable;
func = is_mesh ? extract_range_iter_face_mesh : extract_range_iter_face_bm;
stop = mr.faces_num;
break;
case MR_ITER_LOOSE_EDGE:
range_data.loose_elems = mr.loose_edges.data();
range_data.elems = is_mesh ? mr.edges.data() : (void *)mr.bm->etable;
func = is_mesh ? extract_range_iter_loose_edge_mesh : extract_range_iter_loose_edge_bm;
stop = mr.loose_edges_num;
break;
case MR_ITER_LOOSE_VERT:
range_data.loose_elems = mr.loose_verts.data();
range_data.elems = is_mesh ? mr.vert_positions.data() : (void *)mr.bm->vtable;
func = is_mesh ? extract_range_iter_loose_vert_mesh : extract_range_iter_loose_vert_bm;
stop = mr.loose_verts_num;
break;
default:
BLI_assert(false);
return;
}
extractors->filter_into(range_data.extractors, iter_type, is_mesh);
BLI_task_parallel_range(0, stop, &range_data, func, settings);
}
static void extract_task_range_run(void *__restrict taskdata)
{
ExtractTaskData *data = (ExtractTaskData *)taskdata;
const eMRIterType iter_type = data->iter_type;
const bool is_mesh = data->mr->extract_type != MR_EXTRACT_BMESH;
size_t userdata_chunk_size = data->extractors->data_size_total();
void *userdata_chunk = MEM_callocN(userdata_chunk_size, __func__);
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = data->use_threading;
settings.userdata_chunk = userdata_chunk;
settings.userdata_chunk_size = userdata_chunk_size;
settings.func_reduce = extract_task_reduce;
settings.min_iter_per_thread = MIN_RANGE_LEN;
extract_init(*data->mr, *data->cache, *data->extractors, data->buffers, userdata_chunk);
if (iter_type & MR_ITER_CORNER_TRI) {
extract_task_range_run_iter(
*data->mr, data->extractors, MR_ITER_CORNER_TRI, is_mesh, &settings);
}
if (iter_type & MR_ITER_POLY) {
extract_task_range_run_iter(*data->mr, data->extractors, MR_ITER_POLY, is_mesh, &settings);
}
if (iter_type & MR_ITER_LOOSE_EDGE) {
extract_task_range_run_iter(
*data->mr, data->extractors, MR_ITER_LOOSE_EDGE, is_mesh, &settings);
}
if (iter_type & MR_ITER_LOOSE_VERT) {
extract_task_range_run_iter(
*data->mr, data->extractors, MR_ITER_LOOSE_VERT, is_mesh, &settings);
}
extract_finish(*data->mr, *data->cache, *data->extractors, userdata_chunk);
MEM_freeN(userdata_chunk);
}
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Extract In Parallel Ranges
* \{ */
static TaskNode *extract_task_node_create(TaskGraph *task_graph,
const MeshRenderData &mr,
MeshBatchCache &cache,
ExtractorRunDatas *extractors,
MeshBufferList *buffers,
const bool use_threading)
{
ExtractTaskData *taskdata = new ExtractTaskData(mr, cache, extractors, buffers, use_threading);
TaskNode *task_node = BLI_task_graph_node_create(
task_graph, extract_task_range_run, taskdata, [](void *data) {
delete static_cast<ExtractTaskData *>(data);
});
return task_node;
}
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Task Node - Update Mesh Render Data
* \{ */
struct MeshRenderDataUpdateTaskData {
MeshRenderData *mr = nullptr;
MeshBufferCache *cache = nullptr;
eMRIterType iter_type;
eMRDataType data_flag;
MeshRenderDataUpdateTaskData(MeshRenderData &mr,
MeshBufferCache &cache,
eMRIterType iter_type,
eMRDataType data_flag)
: mr(&mr), cache(&cache), iter_type(iter_type), data_flag(data_flag)
MeshRenderDataUpdateTaskData(MeshRenderData &mr, MeshBufferCache &cache) : mr(&mr), cache(&cache)
{
}
@@ -525,18 +76,14 @@ static void mesh_extract_render_data_node_exec(void *__restrict task_data)
MeshRenderDataUpdateTaskData *update_task_data = static_cast<MeshRenderDataUpdateTaskData *>(
task_data);
MeshRenderData &mr = *update_task_data->mr;
const eMRIterType iter_type = update_task_data->iter_type;
const eMRDataType data_flag = update_task_data->data_flag;
MeshBufferList &buffers = update_task_data->cache->buff;
const bool request_face_normals = DRW_vbo_requested(buffers.vbo.nor) ||
DRW_vbo_requested(buffers.vbo.fdots_nor) ||
DRW_vbo_requested(buffers.vbo.edge_fac) ||
DRW_vbo_requested(buffers.vbo.mesh_analysis) ||
(data_flag & (MR_DATA_POLY_NOR | MR_DATA_LOOP_NOR)) != 0;
const bool request_corner_normals = DRW_vbo_requested(buffers.vbo.nor) ||
(data_flag & MR_DATA_LOOP_NOR) != 0;
DRW_vbo_requested(buffers.vbo.mesh_analysis);
const bool request_corner_normals = DRW_vbo_requested(buffers.vbo.nor);
const bool force_corner_normals = DRW_vbo_requested(buffers.vbo.tan);
if (request_face_normals) {
@@ -552,9 +99,7 @@ static void mesh_extract_render_data_node_exec(void *__restrict task_data)
DRW_vbo_requested(buffers.vbo.edit_data) ||
DRW_vbo_requested(buffers.vbo.vnor) ||
DRW_vbo_requested(buffers.vbo.vert_idx) ||
DRW_vbo_requested(buffers.vbo.edge_idx) ||
(iter_type & (MR_ITER_LOOSE_EDGE | MR_ITER_LOOSE_VERT)) ||
(data_flag & MR_DATA_LOOSE_GEOM);
DRW_vbo_requested(buffers.vbo.edge_idx);
if (calc_loose_geom) {
mesh_render_data_update_loose_geom(mr, *update_task_data->cache);
@@ -563,12 +108,9 @@ static void mesh_extract_render_data_node_exec(void *__restrict task_data)
static TaskNode *mesh_extract_render_data_node_create(TaskGraph *task_graph,
MeshRenderData &mr,
MeshBufferCache &cache,
const eMRIterType iter_type,
const eMRDataType data_flag)
MeshBufferCache &cache)
{
MeshRenderDataUpdateTaskData *task_data = new MeshRenderDataUpdateTaskData(
mr, cache, iter_type, data_flag);
MeshRenderDataUpdateTaskData *task_data = new MeshRenderDataUpdateTaskData(mr, cache);
TaskNode *task_node = BLI_task_graph_node_create(
task_graph,
@@ -642,11 +184,7 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
const bool do_hq_normals = (scene.r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 ||
GPU_use_hq_normals_workaround();
/* Create an array containing all the extractors that needs to be executed. */
ExtractorRunDatas extractors;
MeshBufferList &buffers = mbc.buff;
const bool attrs_requested = any_attr_requested(buffers);
if (!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) &&
@@ -696,14 +234,8 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
double rdata_end = BLI_time_now_seconds();
#endif
eMRIterType iter_type = extractors.iter_types();
eMRDataType data_flag = extractors.data_types();
TaskNode *task_node_mesh_render_data = mesh_extract_render_data_node_create(
&task_graph, *mr, mbc, iter_type, data_flag);
/* Simple heuristic. */
const bool use_thread = (mr->corners_num + mr->loose_indices_num) > MIN_RANGE_LEN;
&task_graph, *mr, mbc);
if (DRW_vbo_requested(buffers.vbo.pos)) {
struct TaskData {
@@ -1221,43 +753,6 @@ void mesh_buffer_cache_create_requested(TaskGraph &task_graph,
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. */
for (const ExtractorRunData &run_data : extractors) {
const MeshExtract *extractor = run_data.extractor;
if (!extractor->use_threading) {
ExtractorRunDatas *single_threaded_extractors = new ExtractorRunDatas();
single_threaded_extractors->append(extractor);
TaskNode *task_node = extract_task_node_create(
&task_graph, *mr, cache, single_threaded_extractors, &buffers, false);
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
}
}
/* Distribute the remaining extractors into ranges per core. */
ExtractorRunDatas *multi_threaded_extractors = new ExtractorRunDatas();
extractors.filter_threaded_extractors_into(*multi_threaded_extractors);
if (!multi_threaded_extractors->is_empty()) {
TaskNode *task_node = extract_task_node_create(
&task_graph, *mr, cache, multi_threaded_extractors, &buffers, true);
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
}
else {
/* No tasks created freeing extractors list. */
delete multi_threaded_extractors;
}
}
else {
/* Run all requests on the same thread. */
ExtractorRunDatas *extractors_copy = new ExtractorRunDatas(extractors);
TaskNode *task_node = extract_task_node_create(
&task_graph, *mr, cache, extractors_copy, &buffers, false);
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
}
/* Trigger the sub-graph for this mesh. */
BLI_task_graph_node_push_work(task_node_mesh_render_data);
@@ -1296,13 +791,8 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
DRWSubdivCache &subdiv_cache,
MeshRenderData &mr)
{
/* Create an array containing all the extractors that needs to be executed. */
ExtractorRunDatas extractors;
MeshBufferList &buffers = mbc.buff;
const bool attrs_requested = any_attr_requested(buffers);
if (!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.orco) &&
@@ -1412,46 +902,6 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
{cache.attr_used.requests, GPU_MAX_ATTR},
{buffers.vbo.attr, GPU_MAX_ATTR});
}
void *data_stack = MEM_mallocN(extractors.data_size_total(), __func__);
uint32_t data_offset = 0;
for (const ExtractorRunData &run_data : extractors) {
const MeshExtract *extractor = run_data.extractor;
void *buffer = mesh_extract_buffer_get(extractor, &buffers);
void *data = POINTER_OFFSET(data_stack, data_offset);
extractor->init_subdiv(subdiv_cache, mr, cache, buffer, data);
if (extractor->iter_subdiv_mesh || extractor->iter_subdiv_bm) {
int *subdiv_loop_face_index = subdiv_cache.subdiv_loop_face_index;
if (mr.extract_type == MR_EXTRACT_BMESH) {
for (uint i = 0; i < subdiv_cache.num_subdiv_quads; i++) {
/* Multiply by 4 to have the start index of the quad's loop, as subdiv_loop_face_index is
* based on the subdivision loops. */
const int poly_origindex = subdiv_loop_face_index[i * 4];
const BMFace *efa = BM_face_at_index(mr.bm, poly_origindex);
extractor->iter_subdiv_bm(subdiv_cache, mr, data, i, efa);
}
}
else {
for (uint i = 0; i < subdiv_cache.num_subdiv_quads; i++) {
/* Multiply by 4 to have the start index of the quad's loop, as subdiv_loop_face_index is
* based on the subdivision loops. */
const int poly_origindex = subdiv_loop_face_index[i * 4];
extractor->iter_subdiv_mesh(subdiv_cache, mr, data, i, poly_origindex);
}
}
}
if (extractor->iter_loose_geom_subdiv) {
extractor->iter_loose_geom_subdiv(subdiv_cache, mr, buffer, data);
}
if (extractor->finish_subdiv) {
extractor->finish_subdiv(subdiv_cache, mr, cache, buffer, data);
}
}
MEM_freeN(data_stack);
}
/** \} */

View File

@@ -21,31 +21,6 @@
namespace blender::draw {
void *mesh_extract_buffer_get(const MeshExtract *extractor, MeshBufferList *mbuflist)
{
/* NOTE: POINTER_OFFSET on windows platforms casts internally to `void *`, but on GCC/CLANG to
* `MeshBufferList *`. What shows a different usage versus intent. */
void **buffer_ptr = (void **)POINTER_OFFSET(mbuflist, extractor->mesh_buffer_offset);
void *buffer = *buffer_ptr;
BLI_assert(buffer);
return buffer;
}
eMRIterType mesh_extract_iter_type(const MeshExtract *ext)
{
eMRIterType type = (eMRIterType)0;
SET_FLAG_FROM_TEST(
type, (ext->iter_looptri_bm || ext->iter_corner_tri_mesh), MR_ITER_CORNER_TRI);
SET_FLAG_FROM_TEST(type, (ext->iter_face_bm || ext->iter_face_mesh), MR_ITER_POLY);
SET_FLAG_FROM_TEST(
type, (ext->iter_loose_edge_bm || ext->iter_loose_edge_mesh), MR_ITER_LOOSE_EDGE);
SET_FLAG_FROM_TEST(
type, (ext->iter_loose_vert_bm || ext->iter_loose_vert_mesh), MR_ITER_LOOSE_VERT);
return type;
}
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Extract Edit Flag Utils
* \{ */

View File

@@ -180,102 +180,6 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData &mr, const BMFace *e
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Mesh Elements Extract Struct
* \{ */
/* TODO(jbakker): move parameters inside a struct. */
using ExtractTriBMeshFn = void(const MeshRenderData &mr, BMLoop **elt, int elt_index, void *data);
using ExtractTriMeshFn = void(const MeshRenderData &mr,
const int3 &tri,
int elt_index,
void *data);
using ExtractFaceBMeshFn = void(const MeshRenderData &mr,
const BMFace *f,
int f_index,
void *data);
using ExtractFaceMeshFn = void(const MeshRenderData &mr, int face_index, void *data);
using ExtractLEdgeBMeshFn = void(const MeshRenderData &mr,
const BMEdge *eed,
int loose_edge_i,
void *data);
using ExtractLEdgeMeshFn = void(const MeshRenderData &mr, int2 edge, int loose_edge_i, void *data);
using ExtractLVertBMeshFn = void(const MeshRenderData &mr,
const BMVert *eve,
int loose_vert_i,
void *data);
using ExtractLVertMeshFn = void(const MeshRenderData &mr, int loose_vert_i, void *data);
using ExtractLooseGeomSubdivFn = void(const DRWSubdivCache &subdiv_cache,
const MeshRenderData &mr,
void *buffer,
void *data);
using ExtractInitFn = void(const MeshRenderData &mr,
MeshBatchCache &cache,
void *buffer,
void *r_data);
using ExtractFinishFn = void(const MeshRenderData &mr,
MeshBatchCache &cache,
void *buffer,
void *data);
using ExtractTaskReduceFn = void(void *userdata, void *task_userdata);
using ExtractInitSubdivFn = void(const DRWSubdivCache &subdiv_cache,
const MeshRenderData &mr,
MeshBatchCache &cache,
void *buf,
void *data);
using ExtractIterSubdivBMeshFn = void(const DRWSubdivCache &subdiv_cache,
const MeshRenderData &mr,
void *data,
uint subdiv_quad_index,
const BMFace *coarse_quad);
using ExtractIterSubdivMeshFn = void(const DRWSubdivCache &subdiv_cache,
const MeshRenderData &mr,
void *data,
uint subdiv_quad_index,
int coarse_quad_index);
using ExtractFinishSubdivFn = void(const DRWSubdivCache &subdiv_cache,
const MeshRenderData &mr,
MeshBatchCache &cache,
void *buf,
void *data);
struct MeshExtract {
/** Executed on main thread and return user data for iteration functions. */
ExtractInitFn *init;
/** Executed on one (or more if use_threading) worker thread(s). */
ExtractTriBMeshFn *iter_looptri_bm;
ExtractTriMeshFn *iter_corner_tri_mesh;
ExtractFaceBMeshFn *iter_face_bm;
ExtractFaceMeshFn *iter_face_mesh;
ExtractLEdgeBMeshFn *iter_loose_edge_bm;
ExtractLEdgeMeshFn *iter_loose_edge_mesh;
ExtractLVertBMeshFn *iter_loose_vert_bm;
ExtractLVertMeshFn *iter_loose_vert_mesh;
ExtractLooseGeomSubdivFn *iter_loose_geom_subdiv;
/** Executed on one worker thread after all elements iterations. */
ExtractTaskReduceFn *task_reduce;
ExtractFinishFn *finish;
/** Executed on main thread for subdivision evaluation. */
ExtractInitSubdivFn *init_subdiv;
ExtractIterSubdivBMeshFn *iter_subdiv_bm;
ExtractIterSubdivMeshFn *iter_subdiv_mesh;
ExtractFinishSubdivFn *finish_subdiv;
/** Used to request common data. */
eMRDataType data_type;
size_t data_size;
/** Used to know if the element callbacks are thread-safe and can be parallelized. */
bool use_threading;
/**
* Offset in bytes of the buffer inside a MeshBufferList instance. Points to a vertex or index
* buffer.
*/
size_t mesh_buffer_offset;
};
/** \} */
/* `draw_cache_extract_mesh_render_data.cc` */
/**
@@ -310,8 +214,6 @@ struct EditLoopData {
uchar bweight;
};
void *mesh_extract_buffer_get(const MeshExtract *extractor, MeshBufferList *mbuflist);
eMRIterType mesh_extract_iter_type(const MeshExtract *ext);
void mesh_render_data_face_flag(const MeshRenderData &mr,
const BMFace *efa,
BMUVOffsets offsets,