Mesh: Simplify triangle draw extraction slightly
- Don't store triangulation or triangle face indices in MeshRenderData. This makes more automatic use of the lazy calculation and saves the calculation of the face indices in some cases. - Don't use the "extractor" abstraction for the triangle index buffer. This is part of the ongoing transition described by #116901. - Pass the "face sorted" data directly to the triangle index buffer creation. That's the only place that needs it. This makes the dependencies more explicit and might make better use of CPU cache.
This commit is contained in:
@@ -398,7 +398,8 @@ BLI_INLINE void extract_task_range_run_iter(const MeshRenderData &mr,
|
||||
int stop;
|
||||
switch (iter_type) {
|
||||
case MR_ITER_CORNER_TRI:
|
||||
range_data.elems = is_mesh ? mr.corner_tris.data() : (void *)mr.edit_bmesh->looptris.data();
|
||||
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;
|
||||
@@ -535,9 +536,7 @@ static void mesh_extract_render_data_node_exec(void *__restrict task_data)
|
||||
const eMRDataType data_flag = update_task_data->data_flag;
|
||||
|
||||
mesh_render_data_update_normals(mr, data_flag);
|
||||
mesh_render_data_update_corner_tris(mr, iter_type, data_flag);
|
||||
mesh_render_data_update_loose_geom(mr, *update_task_data->cache, iter_type, data_flag);
|
||||
mesh_render_data_update_faces_sorted(mr, *update_task_data->cache, data_flag);
|
||||
}
|
||||
|
||||
static TaskNode *mesh_extract_render_data_node_create(TaskGraph *task_graph,
|
||||
@@ -653,7 +652,6 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
||||
EXTRACT_ADD_REQUESTED(vbo, attr_viewer);
|
||||
EXTRACT_ADD_REQUESTED(vbo, vnor);
|
||||
|
||||
EXTRACT_ADD_REQUESTED(ibo, tris);
|
||||
EXTRACT_ADD_REQUESTED(ibo, points);
|
||||
EXTRACT_ADD_REQUESTED(ibo, fdots);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask);
|
||||
@@ -666,7 +664,7 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
||||
#undef EXTRACT_ADD_REQUESTED
|
||||
|
||||
if (extractors.is_empty() && !DRW_ibo_requested(buffers.ibo.lines) &&
|
||||
!DRW_ibo_requested(buffers.ibo.lines_loose))
|
||||
!DRW_ibo_requested(buffers.ibo.lines_loose) && !DRW_ibo_requested(buffers.ibo.tris))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -702,6 +700,24 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
||||
/* Simple heuristic. */
|
||||
const bool use_thread = (mr->corners_num + mr->loose_indices_num) > MIN_RANGE_LEN;
|
||||
|
||||
if (DRW_ibo_requested(buffers.ibo.tris)) {
|
||||
struct LooseEdgedata {
|
||||
MeshRenderData &mr;
|
||||
MeshBufferCache &mbc;
|
||||
MeshBatchCache &cache;
|
||||
};
|
||||
TaskNode *task_node = BLI_task_graph_node_create(
|
||||
task_graph,
|
||||
[](void *__restrict task_data) {
|
||||
const LooseEdgedata &data = *static_cast<LooseEdgedata *>(task_data);
|
||||
const SortedFaceData &face_sorted = mesh_render_data_faces_sorted_ensure(data.mr,
|
||||
data.mbc);
|
||||
extract_tris(data.mr, face_sorted, data.cache, *data.mbc.buff.ibo.tris);
|
||||
},
|
||||
new LooseEdgedata{*mr, mbc, cache},
|
||||
[](void *task_data) { delete static_cast<LooseEdgedata *>(task_data); });
|
||||
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
|
||||
}
|
||||
if (DRW_ibo_requested(buffers.ibo.lines) || DRW_ibo_requested(buffers.ibo.lines_loose)) {
|
||||
struct LooseEdgedata {
|
||||
MeshRenderData &mr;
|
||||
@@ -810,10 +826,6 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* The order in which extractors are added to the list matters somewhat, as some buffers are
|
||||
* reused when building others. */
|
||||
EXTRACT_ADD_REQUESTED(ibo, tris);
|
||||
|
||||
/* Orcos are extracted at the same time as positions. */
|
||||
if (DRW_vbo_requested(buffers.vbo.pos) || DRW_vbo_requested(buffers.vbo.orco)) {
|
||||
extractors.append(&extract_pos);
|
||||
@@ -854,12 +866,11 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
#undef EXTRACT_ADD_REQUESTED
|
||||
|
||||
if (extractors.is_empty() && !DRW_ibo_requested(buffers.ibo.lines) &&
|
||||
!DRW_ibo_requested(buffers.ibo.lines_loose))
|
||||
!DRW_ibo_requested(buffers.ibo.lines_loose) && !DRW_ibo_requested(buffers.ibo.tris))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mesh_render_data_update_corner_tris(mr, MR_ITER_CORNER_TRI, MR_DATA_CORNER_TRI);
|
||||
mesh_render_data_update_normals(mr, MR_DATA_TAN_LOOP_NOR);
|
||||
mesh_render_data_update_loose_geom(
|
||||
mr, mbc, MR_ITER_LOOSE_EDGE | MR_ITER_LOOSE_VERT, MR_DATA_LOOSE_GEOM);
|
||||
@@ -869,6 +880,9 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
||||
extract_lines_subdiv(
|
||||
subdiv_cache, mr, buffers.ibo.lines, buffers.ibo.lines_loose, cache.no_loose_wire);
|
||||
}
|
||||
if (DRW_ibo_requested(buffers.ibo.tris)) {
|
||||
extract_tris_subdiv(subdiv_cache, cache, *buffers.ibo.tris);
|
||||
}
|
||||
|
||||
void *data_stack = MEM_mallocN(extractors.data_size_total(), __func__);
|
||||
uint32_t data_offset = 0;
|
||||
|
||||
@@ -354,22 +354,13 @@ static SortedFaceData mesh_render_data_faces_sorted_build(const MeshRenderData &
|
||||
return cache;
|
||||
}
|
||||
|
||||
static void mesh_render_data_faces_sorted_ensure(MeshRenderData &mr, MeshBufferCache &cache)
|
||||
const SortedFaceData &mesh_render_data_faces_sorted_ensure(const MeshRenderData &mr,
|
||||
MeshBufferCache &cache)
|
||||
{
|
||||
if (cache.face_sorted.visible_tris_num > 0) {
|
||||
return;
|
||||
}
|
||||
cache.face_sorted = mesh_render_data_faces_sorted_build(mr);
|
||||
}
|
||||
|
||||
void mesh_render_data_update_faces_sorted(MeshRenderData &mr,
|
||||
MeshBufferCache &cache,
|
||||
const eMRDataType data_flag)
|
||||
{
|
||||
if (data_flag & MR_DATA_POLYS_SORTED) {
|
||||
mesh_render_data_faces_sorted_ensure(mr, cache);
|
||||
mr.face_sorted = &cache.face_sorted;
|
||||
if (cache.face_sorted.visible_tris_num == 0) {
|
||||
cache.face_sorted = mesh_render_data_faces_sorted_build(mr);
|
||||
}
|
||||
return cache.face_sorted;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -453,26 +444,6 @@ const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *mesh)
|
||||
return &mesh->vert_data;
|
||||
}
|
||||
|
||||
void mesh_render_data_update_corner_tris(MeshRenderData &mr,
|
||||
const eMRIterType iter_type,
|
||||
const eMRDataType data_flag)
|
||||
{
|
||||
if (mr.extract_type != MR_EXTRACT_BMESH) {
|
||||
/* Mesh */
|
||||
if ((iter_type & MR_ITER_CORNER_TRI) || (data_flag & MR_DATA_CORNER_TRI)) {
|
||||
mr.corner_tris = mr.mesh->corner_tris();
|
||||
mr.corner_tri_faces = mr.mesh->corner_tri_faces();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* #BMesh */
|
||||
if ((iter_type & MR_ITER_CORNER_TRI) || (data_flag & MR_DATA_CORNER_TRI)) {
|
||||
/* Edit mode ensures this is valid, no need to calculate. */
|
||||
BLI_assert((mr.bm->totloop == 0) || !mr.edit_bmesh->looptris.is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool bm_edge_is_sharp(const BMEdge *const &edge)
|
||||
{
|
||||
return !BM_elem_flag_test(edge, BM_ELEM_SMOOTH);
|
||||
|
||||
@@ -102,8 +102,6 @@ struct MeshRenderData {
|
||||
BMFace *efa_act;
|
||||
BMFace *efa_act_uv;
|
||||
/* The triangulation of #Mesh faces, owned by the mesh. */
|
||||
Span<int3> corner_tris;
|
||||
Span<int> corner_tri_faces;
|
||||
VArraySpan<int> material_indices;
|
||||
|
||||
bke::MeshNormalDomain normals_domain;
|
||||
@@ -121,7 +119,6 @@ struct MeshRenderData {
|
||||
|
||||
Span<int> loose_verts;
|
||||
Span<int> loose_edges;
|
||||
const SortedFaceData *face_sorted;
|
||||
|
||||
const char *active_color_name;
|
||||
const char *default_color_name;
|
||||
@@ -298,15 +295,8 @@ void mesh_render_data_update_loose_geom(MeshRenderData &mr,
|
||||
MeshBufferCache &cache,
|
||||
eMRIterType iter_type,
|
||||
eMRDataType data_flag);
|
||||
void mesh_render_data_update_faces_sorted(MeshRenderData &mr,
|
||||
MeshBufferCache &cache,
|
||||
eMRDataType data_flag);
|
||||
/**
|
||||
* Part of the creation of the #MeshRenderData that happens in a thread.
|
||||
*/
|
||||
void mesh_render_data_update_corner_tris(MeshRenderData &mr,
|
||||
eMRIterType iter_type,
|
||||
eMRDataType data_flag);
|
||||
const SortedFaceData &mesh_render_data_faces_sorted_ensure(const MeshRenderData &mr,
|
||||
MeshBufferCache &cache);
|
||||
|
||||
/* draw_cache_extract_mesh_extractors.c */
|
||||
|
||||
@@ -352,6 +342,14 @@ void extract_mesh_loose_edge_data(const Span<T> vert_data,
|
||||
});
|
||||
}
|
||||
|
||||
void extract_tris(const MeshRenderData &mr,
|
||||
const SortedFaceData &face_sorted,
|
||||
MeshBatchCache &cache,
|
||||
gpu::IndexBuf &ibo);
|
||||
void extract_tris_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
MeshBatchCache &cache,
|
||||
gpu::IndexBuf &ibo);
|
||||
|
||||
void extract_lines(const MeshRenderData &mr,
|
||||
gpu::IndexBuf *lines,
|
||||
gpu::IndexBuf *lines_loose,
|
||||
@@ -362,7 +360,6 @@ void extract_lines_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
gpu::IndexBuf *lines_loose,
|
||||
bool &no_loose_wire);
|
||||
|
||||
extern const MeshExtract extract_tris;
|
||||
extern const MeshExtract extract_points;
|
||||
extern const MeshExtract extract_fdots;
|
||||
extern const MeshExtract extract_lines_paint_mask;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace blender::draw {
|
||||
|
||||
struct MeshExtract_EditUvElem_Data {
|
||||
GPUIndexBufBuilder elb;
|
||||
Span<int> corner_tri_faces;
|
||||
bool sync_selection;
|
||||
};
|
||||
|
||||
@@ -29,6 +30,7 @@ static void extract_edituv_tris_init(const MeshRenderData &mr,
|
||||
{
|
||||
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
|
||||
GPU_indexbuf_init(&data->elb, GPU_PRIM_TRIS, mr.corner_tris_num, mr.corners_num);
|
||||
data->corner_tri_faces = mr.mesh->corner_tri_faces();
|
||||
data->sync_selection = (mr.toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
|
||||
}
|
||||
|
||||
@@ -60,7 +62,7 @@ static void extract_edituv_tris_iter_corner_tri_mesh(const MeshRenderData &mr,
|
||||
void *_data)
|
||||
{
|
||||
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
|
||||
const int face_i = mr.corner_tri_faces[elt_index];
|
||||
const int face_i = data->corner_tri_faces[elt_index];
|
||||
const BMFace *efa = bm_original_face_get(mr, face_i);
|
||||
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
|
||||
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace blender::draw {
|
||||
#define NO_EDGE INT_MAX
|
||||
|
||||
struct MeshExtract_LineAdjacency_Data {
|
||||
Span<int> corner_tri_faces;
|
||||
GPUIndexBufBuilder elb;
|
||||
Map<OrderedEdge, int> *eh;
|
||||
bool is_manifold;
|
||||
@@ -57,6 +58,7 @@ static void extract_lines_adjacency_init(const MeshRenderData &mr,
|
||||
uint tess_edge_len = mr.corners_num + mr.corner_tris_num - mr.faces_num;
|
||||
|
||||
MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(tls_data);
|
||||
data->corner_tri_faces = mr.mesh->corner_tri_faces();
|
||||
line_adjacency_data_init(data, mr.verts_num, mr.corners_num, tess_edge_len);
|
||||
}
|
||||
|
||||
@@ -131,7 +133,7 @@ static void extract_lines_adjacency_iter_corner_tri_mesh(const MeshRenderData &m
|
||||
void *_data)
|
||||
{
|
||||
MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
|
||||
const int face_i = mr.corner_tri_faces[elt_index];
|
||||
const int face_i = data->corner_tri_faces[elt_index];
|
||||
const bool hidden = mr.use_hide && !mr.hide_poly.is_empty() && mr.hide_poly[face_i];
|
||||
if (hidden) {
|
||||
return;
|
||||
|
||||
@@ -16,17 +16,15 @@
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Triangles Indices (multi material)
|
||||
* \{ */
|
||||
|
||||
static void extract_tris_mesh(const MeshRenderData &mr, gpu::IndexBuf &ibo)
|
||||
static void extract_tris_mesh(const MeshRenderData &mr,
|
||||
const SortedFaceData &face_sorted,
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
const Span<int3> corner_tris = mr.corner_tris;
|
||||
if (!mr.face_sorted->face_tri_offsets) {
|
||||
const Span<int3> corner_tris = mr.mesh->corner_tris();
|
||||
if (!face_sorted.face_tri_offsets) {
|
||||
/* There are no hidden faces and no reordering is necessary to group triangles with the same
|
||||
* material. The corner indices from #Mesh::corner_tris() can be copied directly to the GPU. */
|
||||
BLI_assert(mr.face_sorted->visible_tris_num == corner_tris.size());
|
||||
BLI_assert(face_sorted.visible_tris_num == corner_tris.size());
|
||||
GPU_indexbuf_build_in_place_from_memory(&ibo,
|
||||
GPU_PRIM_TRIS,
|
||||
corner_tris.cast<uint32_t>().data(),
|
||||
@@ -41,10 +39,10 @@ static void extract_tris_mesh(const MeshRenderData &mr, gpu::IndexBuf &ibo)
|
||||
const Span<bool> hide_poly = mr.hide_poly;
|
||||
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_TRIS, mr.face_sorted->visible_tris_num, mr.corners_num);
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_TRIS, face_sorted.visible_tris_num, mr.corners_num);
|
||||
MutableSpan<uint3> data = GPU_indexbuf_get_data(&builder).cast<uint3>();
|
||||
|
||||
const Span<int> face_tri_offsets = mr.face_sorted->face_tri_offsets->as_span();
|
||||
const Span<int> face_tri_offsets = face_sorted.face_tri_offsets->as_span();
|
||||
threading::parallel_for(faces.index_range(), 2048, [&](const IndexRange range) {
|
||||
for (const int face : range) {
|
||||
if (!hide_poly.is_empty() && hide_poly[face]) {
|
||||
@@ -60,15 +58,17 @@ static void extract_tris_mesh(const MeshRenderData &mr, gpu::IndexBuf &ibo)
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, mr.corners_num, false, &ibo);
|
||||
}
|
||||
|
||||
static void extract_tris_bmesh(const MeshRenderData &mr, gpu::IndexBuf &ibo)
|
||||
static void extract_tris_bmesh(const MeshRenderData &mr,
|
||||
const SortedFaceData &face_sorted,
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_TRIS, mr.face_sorted->visible_tris_num, mr.corners_num);
|
||||
GPU_indexbuf_init(&builder, GPU_PRIM_TRIS, face_sorted.visible_tris_num, mr.corners_num);
|
||||
MutableSpan<uint3> data = GPU_indexbuf_get_data(&builder).cast<uint3>();
|
||||
|
||||
BMesh &bm = *mr.bm;
|
||||
const Span<std::array<BMLoop *, 3>> looptris = mr.edit_bmesh->looptris;
|
||||
const Span<int> face_tri_offsets = *mr.face_sorted->face_tri_offsets;
|
||||
const Span<int> face_tri_offsets = *face_sorted.face_tri_offsets;
|
||||
threading::parallel_for(IndexRange(bm.totface), 1024, [&](const IndexRange range) {
|
||||
for (const int face_index : range) {
|
||||
const BMFace &face = *BM_face_at_index(&bm, face_index);
|
||||
@@ -90,56 +90,52 @@ static void extract_tris_bmesh(const MeshRenderData &mr, gpu::IndexBuf &ibo)
|
||||
GPU_indexbuf_build_in_place_ex(&builder, 0, bm.totloop, false, &ibo);
|
||||
}
|
||||
|
||||
static void extract_tris_finish(const MeshRenderData &mr,
|
||||
MeshBatchCache &cache,
|
||||
gpu::IndexBuf &ibo)
|
||||
static void create_material_subranges(const MeshRenderData &mr,
|
||||
const SortedFaceData &face_sorted,
|
||||
MeshBatchCache &cache,
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
/* Create ibo sub-ranges. Always do this to avoid error when the standard surface batch
|
||||
* is created before the surfaces-per-material. */
|
||||
if (mr.use_final_mesh && cache.tris_per_mat) {
|
||||
int mat_start = 0;
|
||||
for (int i = 0; i < mr.materials_num; i++) {
|
||||
/* These IBOs have not been queried yet but we create them just in case they are needed
|
||||
* later since they are not tracked by mesh_buffer_cache_create_requested(). */
|
||||
if (cache.tris_per_mat[i] == nullptr) {
|
||||
cache.tris_per_mat[i] = GPU_indexbuf_calloc();
|
||||
}
|
||||
const int mat_tri_len = mr.face_sorted->tris_num_by_material[i];
|
||||
/* Multiply by 3 because these are triangle indices. */
|
||||
const int start = mat_start * 3;
|
||||
const int len = mat_tri_len * 3;
|
||||
GPU_indexbuf_create_subrange_in_place(cache.tris_per_mat[i], &ibo, start, len);
|
||||
mat_start += mat_tri_len;
|
||||
int mat_start = 0;
|
||||
for (int i = 0; i < mr.materials_num; i++) {
|
||||
/* These IBOs have not been queried yet but we create them just in case they are needed
|
||||
* later since they are not tracked by mesh_buffer_cache_create_requested(). */
|
||||
if (cache.tris_per_mat[i] == nullptr) {
|
||||
cache.tris_per_mat[i] = GPU_indexbuf_calloc();
|
||||
}
|
||||
const int mat_tri_len = face_sorted.tris_num_by_material[i];
|
||||
/* Multiply by 3 because these are triangle indices. */
|
||||
const int start = mat_start * 3;
|
||||
const int len = mat_tri_len * 3;
|
||||
GPU_indexbuf_create_subrange_in_place(cache.tris_per_mat[i], &ibo, start, len);
|
||||
mat_start += mat_tri_len;
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_tris_init(const MeshRenderData &mr,
|
||||
MeshBatchCache &cache,
|
||||
void *ibo_v,
|
||||
void * /*tls_data*/)
|
||||
void extract_tris(const MeshRenderData &mr,
|
||||
const SortedFaceData &face_sorted,
|
||||
MeshBatchCache &cache,
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
gpu::IndexBuf &ibo = *static_cast<gpu::IndexBuf *>(ibo_v);
|
||||
|
||||
if (mr.extract_type == MR_EXTRACT_MESH) {
|
||||
extract_tris_mesh(mr, ibo);
|
||||
extract_tris_mesh(mr, face_sorted, ibo);
|
||||
}
|
||||
else {
|
||||
extract_tris_bmesh(mr, ibo);
|
||||
extract_tris_bmesh(mr, face_sorted, ibo);
|
||||
}
|
||||
|
||||
extract_tris_finish(mr, cache, ibo);
|
||||
if (mr.use_final_mesh && cache.tris_per_mat) {
|
||||
create_material_subranges(mr, face_sorted, cache, ibo);
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_tris_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData & /*mr*/,
|
||||
MeshBatchCache &cache,
|
||||
void *buffer,
|
||||
void * /*data*/)
|
||||
void extract_tris_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
MeshBatchCache &cache,
|
||||
gpu::IndexBuf &ibo)
|
||||
{
|
||||
gpu::IndexBuf *ibo = static_cast<gpu::IndexBuf *>(buffer);
|
||||
/* Initialize the index buffer, it was already allocated, it will be filled on the device. */
|
||||
GPU_indexbuf_init_build_on_device(ibo, subdiv_cache.num_subdiv_triangles * 3);
|
||||
GPU_indexbuf_init_build_on_device(&ibo, subdiv_cache.num_subdiv_triangles * 3);
|
||||
|
||||
if (cache.tris_per_mat) {
|
||||
for (int i = 0; i < cache.mat_len; i++) {
|
||||
@@ -150,26 +146,11 @@ static void extract_tris_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
/* Multiply by 6 since we have 2 triangles per quad. */
|
||||
const int start = subdiv_cache.mat_start[i] * 6;
|
||||
const int len = (subdiv_cache.mat_end[i] - subdiv_cache.mat_start[i]) * 6;
|
||||
GPU_indexbuf_create_subrange_in_place(cache.tris_per_mat[i], ibo, start, len);
|
||||
GPU_indexbuf_create_subrange_in_place(cache.tris_per_mat[i], &ibo, start, len);
|
||||
}
|
||||
}
|
||||
|
||||
draw_subdiv_build_tris_buffer(subdiv_cache, ibo, cache.mat_len);
|
||||
draw_subdiv_build_tris_buffer(subdiv_cache, &ibo, cache.mat_len);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_tris()
|
||||
{
|
||||
MeshExtract extractor = {nullptr};
|
||||
extractor.init = extract_tris_init;
|
||||
extractor.init_subdiv = extract_tris_init_subdiv;
|
||||
extractor.data_type = MR_DATA_CORNER_TRI | MR_DATA_POLYS_SORTED;
|
||||
extractor.use_threading = true;
|
||||
extractor.mesh_buffer_offset = offsetof(MeshBufferList, ibo.tris);
|
||||
return extractor;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
const MeshExtract extract_tris = create_extractor_tris();
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
@@ -217,8 +217,8 @@ static void statvis_calc_thickness(const MeshRenderData &mr, float *r_thickness)
|
||||
BVHTreeFromMesh treeData = {nullptr};
|
||||
|
||||
BVHTree *tree = BKE_bvhtree_from_mesh_get(&treeData, mr.mesh, BVHTREE_FROM_CORNER_TRIS, 4);
|
||||
const Span<int3> corner_tris = mr.corner_tris;
|
||||
const Span<int> tri_faces = mr.corner_tri_faces;
|
||||
const Span<int3> corner_tris = mr.mesh->corner_tris();
|
||||
const Span<int> tri_faces = mr.mesh->corner_tri_faces();
|
||||
for (const int i : corner_tris.index_range()) {
|
||||
const int index = tri_faces[i];
|
||||
const float *cos[3] = {mr.vert_positions[mr.corner_verts[corner_tris[i][0]]],
|
||||
@@ -349,16 +349,16 @@ static void statvis_calc_intersect(const MeshRenderData &mr, float *r_intersect)
|
||||
BVHTree_OverlapData data = {};
|
||||
data.positions = mr.vert_positions;
|
||||
data.corner_verts = mr.corner_verts;
|
||||
data.corner_tris = mr.corner_tris;
|
||||
data.tri_faces = mr.corner_tri_faces;
|
||||
data.corner_tris = mr.mesh->corner_tris();
|
||||
data.tri_faces = mr.mesh->corner_tri_faces();
|
||||
data.epsilon = BLI_bvhtree_get_epsilon(tree);
|
||||
|
||||
BVHTreeOverlap *overlap = BLI_bvhtree_overlap_self(tree, &overlap_len, bvh_overlap_cb, &data);
|
||||
if (overlap) {
|
||||
for (int i = 0; i < overlap_len; i++) {
|
||||
|
||||
for (const IndexRange f_hit : {mr.faces[mr.corner_tri_faces[overlap[i].indexA]],
|
||||
mr.faces[mr.corner_tri_faces[overlap[i].indexB]]})
|
||||
for (const IndexRange f_hit : {mr.faces[data.tri_faces[overlap[i].indexA]],
|
||||
mr.faces[data.tri_faces[overlap[i].indexB]]})
|
||||
{
|
||||
int l_index = f_hit.start();
|
||||
for (int k = 0; k < f_hit.size(); k++, l_index++) {
|
||||
|
||||
@@ -58,6 +58,9 @@ static void extract_tan_init_common(const MeshRenderData &mr,
|
||||
use_orco_tan = false;
|
||||
}
|
||||
|
||||
const Span<int3> corner_tris = mr.mesh->corner_tris();
|
||||
const Span<int> corner_tri_faces = mr.mesh->corner_tri_faces();
|
||||
|
||||
for (int i = 0; i < MAX_MTFACE; i++) {
|
||||
if (tan_layers & (1 << i)) {
|
||||
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
|
||||
@@ -123,8 +126,8 @@ static void extract_tan_init_common(const MeshRenderData &mr,
|
||||
BKE_mesh_calc_loop_tangent_ex(reinterpret_cast<const float(*)[3]>(mr.vert_positions.data()),
|
||||
mr.faces,
|
||||
mr.corner_verts.data(),
|
||||
mr.corner_tris.data(),
|
||||
mr.corner_tri_faces.data(),
|
||||
corner_tris.data(),
|
||||
corner_tri_faces.data(),
|
||||
mr.corner_tris_num,
|
||||
mr.sharp_faces,
|
||||
cd_ldata,
|
||||
|
||||
Reference in New Issue
Block a user