diff options
author | Hans Goudey <h.goudey@me.com> | 2022-08-31 17:09:01 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-08-31 17:09:01 +0300 |
commit | f1c0249f34c4171ec311b5b9882e36fed5889259 (patch) | |
tree | 7dd630c9301b8dd468c8279e8c446c62824fb6d6 /source/blender/draw | |
parent | 3e73afb5360592fe2bf43419e216035ea3c281f9 (diff) |
Mesh: Move material indices to a generic attribute
This patch moves material indices from the mesh `MPoly` struct to a
generic integer attribute. The builtin material index was already
exposed in geometry nodes, but this makes it a "proper" attribute
accessible with Python and visible in the "Attributes" panel.
The goals of the refactor are code simplification and memory and
performance improvements, mainly because the attribute doesn't have
to be stored and processed if there are no materials. However, until
4.0, material indices will still be read and written in the old
format, meaning there may be a temporary increase in memory usage.
Further notes:
* Completely removing the `MPoly.mat_nr` after 4.0 may require
changes to DNA or introducing a new `MPoly` type.
* Geometry nodes regression tests didn't look at material indices,
so the change reveals a bug in the realize instances node that I fixed.
* Access to material indices from the RNA `MeshPolygon` type is slower
with this patch. The `material_index` attribute can be used instead.
* Cycles is changed to read from the attribute instead.
* BMesh isn't changed in this patch. Theoretically it could be though,
to save 2 bytes per face when less than two materials are used.
* Eventually we could use a 16 bit integer attribute type instead.
Ref T95967
Differential Revision: https://developer.blender.org/D15675
Diffstat (limited to 'source/blender/draw')
3 files changed, 15 insertions, 7 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index 86b20a5cb7c..e07fe81840e 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -14,6 +14,7 @@ #include "BLI_math.h" #include "BLI_task.h" +#include "BKE_attribute.hh" #include "BKE_editmesh.h" #include "BKE_editmesh_cache.h" #include "BKE_mesh.h" @@ -231,7 +232,7 @@ static void mesh_render_data_polys_sorted_build(MeshRenderData *mr, MeshBufferCa for (int i = 0; i < mr->poly_len; i++) { if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[i])) { const MPoly *mp = &mr->mpoly[i]; - const int mat = min_ii(mp->mat_nr, mat_last); + const int mat = min_ii(mr->material_indices ? mr->material_indices[i] : 0, mat_last); tri_first_index[i] = mat_tri_offs[mat]; mat_tri_offs[mat] += mp->totloop - 2; } @@ -270,7 +271,7 @@ static void mesh_render_data_mat_tri_len_mesh_range_fn(void *__restrict userdata const MPoly *mp = &mr->mpoly[iter]; if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[iter])) { - int mat = min_ii(mp->mat_nr, mr->mat_len - 1); + int mat = min_ii(mr->material_indices ? mr->material_indices[iter] : 0, mr->mat_len - 1); mat_tri_len[mat] += mp->totloop - 2; } } @@ -576,6 +577,9 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->e_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); mr->p_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX)); + mr->material_indices = static_cast<const int *>( + CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, "material_index")); + mr->hide_vert = static_cast<const bool *>( CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert")); mr->hide_edge = static_cast<const bool *>( diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index f6242aa072d..e02bf57815d 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -7,6 +7,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_attribute.hh" #include "BKE_editmesh.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -19,8 +20,8 @@ #include "BKE_subdiv_modifier.h" #include "BLI_linklist.h" - #include "BLI_string.h" +#include "BLI_virtual_array.hh" #include "PIL_time.h" @@ -1962,17 +1963,20 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache, return; } + const blender::VArraySpan<int> material_indices = blender::bke::mesh_attributes(*mesh_eval) + .lookup_or_default<int>( + "material_index", ATTR_DOMAIN_FACE, 0); + /* Count number of subdivided polygons for each material. */ int *mat_start = static_cast<int *>(MEM_callocN(sizeof(int) * mat_len, "subdiv mat_start")); int *subdiv_polygon_offset = cache->subdiv_polygon_offset; /* TODO: parallel_reduce? */ for (int i = 0; i < mesh_eval->totpoly; i++) { - const MPoly *mpoly = &mesh_eval->mpoly[i]; const int next_offset = (i == mesh_eval->totpoly - 1) ? number_of_quads : subdiv_polygon_offset[i + 1]; const int quad_count = next_offset - subdiv_polygon_offset[i]; - const int mat_index = mpoly->mat_nr; + const int mat_index = material_indices[i]; mat_start[mat_index] += quad_count; } @@ -1991,8 +1995,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache, MEM_mallocN(sizeof(int) * mesh_eval->totpoly, "per_polygon_mat_offset")); for (int i = 0; i < mesh_eval->totpoly; i++) { - const MPoly *mpoly = &mesh_eval->mpoly[i]; - const int mat_index = mpoly->mat_nr; + const int mat_index = material_indices[i]; const int single_material_index = subdiv_polygon_offset[i]; const int material_offset = mat_end[mat_index]; const int next_offset = (i == mesh_eval->totpoly - 1) ? number_of_quads : diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index 5d55af904e8..10b94291e35 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -80,6 +80,7 @@ struct MeshRenderData { BMFace *efa_act_uv; /* Data created on-demand (usually not for #BMesh based data). */ MLoopTri *mlooptri; + const int *material_indices; const float (*vert_normals)[3]; const float (*poly_normals)[3]; const bool *hide_vert; |