Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-08-31 17:09:01 +0300
committerHans Goudey <h.goudey@me.com>2022-08-31 17:09:01 +0300
commitf1c0249f34c4171ec311b5b9882e36fed5889259 (patch)
tree7dd630c9301b8dd468c8279e8c446c62824fb6d6 /source/blender/editors
parent3e73afb5360592fe2bf43419e216035ea3c281f9 (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/editors')
-rw-r--r--source/blender/editors/mesh/meshtools.cc15
-rw-r--r--source/blender/editors/object/object_bake.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c19
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c14
4 files changed, 36 insertions, 15 deletions
diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc
index e9a34cf95cb..330560be026 100644
--- a/source/blender/editors/mesh/meshtools.cc
+++ b/source/blender/editors/mesh/meshtools.cc
@@ -10,6 +10,8 @@
#include "MEM_guardedalloc.h"
+#include "BLI_virtual_array.hh"
+
#include "DNA_key_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -21,6 +23,7 @@
#include "DNA_view3d_types.h"
#include "DNA_workspace_types.h"
+#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
@@ -247,9 +250,19 @@ static void join_mesh_single(Depsgraph *depsgraph,
CustomData_merge(&me->pdata, pdata, CD_MASK_MESH.pmask, CD_SET_DEFAULT, totpoly);
CustomData_copy_data_named(&me->pdata, pdata, 0, *polyofs, me->totpoly);
+ blender::bke::AttributeWriter<int> material_indices =
+ blender::bke::mesh_attributes_for_write(*me).lookup_for_write<int>("material_index");
+ if (material_indices) {
+ blender::MutableVArraySpan<int> material_indices_span(material_indices.varray);
+ for (const int i : material_indices_span.index_range()) {
+ material_indices_span[i] = matmap ? matmap[material_indices_span[i]] : 0;
+ }
+ material_indices_span.save();
+ material_indices.finish();
+ }
+
for (a = 0; a < me->totpoly; a++, mpoly++) {
mpoly->loopstart += *loopofs;
- mpoly->mat_nr = matmap ? matmap[mpoly->mat_nr] : 0;
}
/* Face maps. */
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index effbde41c38..3170ce2c620 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -161,9 +161,10 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
ok = false;
}
else {
+ const int *material_indices = BKE_mesh_material_indices(me);
a = me->totpoly;
while (ok && a--) {
- Image *ima = bake_object_image_get(ob, me->mpoly[a].mat_nr);
+ Image *ima = bake_object_image_get(ob, material_indices ? material_indices[a] : 0);
if (!ima) {
BKE_report(
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 3e5ad9bdc2d..909ae1c783a 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -414,6 +414,7 @@ typedef struct ProjPaintState {
const float (*vert_normals)[3];
const MEdge *medge_eval;
const MPoly *mpoly_eval;
+ const int *material_indices;
const MLoop *mloop_eval;
const MLoopTri *mlooptri_eval;
@@ -542,8 +543,8 @@ static int project_paint_face_paint_tile(Image *ima, const float *uv)
static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int tri_index)
{
- const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
- Material *ma = ps->mat_array[mp->mat_nr];
+ const int poly_i = ps->mlooptri_eval[tri_index].poly;
+ Material *ma = ps->mat_array[ps->material_indices == NULL ? 0 : ps->material_indices[poly_i]];
return ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
}
@@ -553,23 +554,23 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i
return ps->stencil_ima;
}
- const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
- Material *ma = ps->mat_array[mp->mat_nr];
+ const int poly_i = ps->mlooptri_eval[tri_index].poly;
+ Material *ma = ps->mat_array[ps->material_indices == NULL ? 0 : ps->material_indices[poly_i]];
TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
return slot ? slot->ima : ps->canvas_ima;
}
static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int tri_index)
{
- const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
- Material *ma = ps->mat_array[mp->mat_nr];
+ const int poly_i = ps->mlooptri_eval[tri_index].poly;
+ Material *ma = ps->mat_array[ps->material_indices == NULL ? 0 : ps->material_indices[poly_i]];
return ma ? ma->texpaintslot + ma->paint_clone_slot : NULL;
}
static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_index)
{
- const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
- Material *ma = ps->mat_array[mp->mat_nr];
+ const int poly_i = ps->mlooptri_eval[tri_index].poly;
+ Material *ma = ps->mat_array[ps->material_indices == NULL ? 0 : ps->material_indices[poly_i]];
TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : NULL;
return slot ? slot->ima : ps->clone_ima;
}
@@ -4060,6 +4061,8 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
}
ps->mloop_eval = ps->me_eval->mloop;
ps->mpoly_eval = ps->me_eval->mpoly;
+ ps->material_indices = (const int *)CustomData_get_layer_named(
+ &ps->me_eval->pdata, CD_PROP_INT32, "material_index");
ps->totvert_eval = ps->me_eval->totvert;
ps->totedge_eval = ps->me_eval->totedge;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 1f272882100..1429744aca7 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -287,7 +287,6 @@ static void imapaint_pick_uv(
const int tottri = me_eval->runtime.looptris.len;
const MVert *mvert = me_eval->mvert;
- const MPoly *mpoly = me_eval->mpoly;
const MLoop *mloop = me_eval->mloop;
const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
@@ -302,6 +301,9 @@ static void imapaint_pick_uv(
minabsw = 1e10;
uv[0] = uv[1] = 0.0;
+ const int *material_indices = (const int *)CustomData_get_layer_named(
+ &me_eval->pdata, CD_PROP_INT32, "material_index");
+
/* test all faces in the derivedmesh with the original index of the picked face */
/* face means poly here, not triangle, indeed */
for (i = 0; i < tottri; i++, lt++) {
@@ -309,7 +311,6 @@ static void imapaint_pick_uv(
if (findex == faceindex) {
const MLoopUV *mloopuv;
- const MPoly *mp = &mpoly[lt->poly];
const MLoopUV *tri_uv[3];
float tri_co[3][3];
@@ -321,7 +322,8 @@ static void imapaint_pick_uv(
const Material *ma;
const TexPaintSlot *slot;
- ma = BKE_object_material_get(ob_eval, mp->mat_nr + 1);
+ ma = BKE_object_material_get(
+ ob_eval, material_indices == NULL ? 1 : material_indices[lt->poly] + 1);
slot = &ma->texpaintslot[ma->paint_active_slot];
if (!(slot && slot->uvname &&
@@ -410,6 +412,8 @@ void paint_sample_color(
cddata_masks.pmask |= CD_MASK_ORIGINDEX;
Mesh *me = (Mesh *)ob->data;
Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob_eval, &cddata_masks);
+ const int *material_indices = (const int *)CustomData_get_layer_named(
+ &me_eval->pdata, CD_PROP_INT32, "material_index");
ViewContext vc;
const int mval[2] = {x, y};
@@ -427,8 +431,8 @@ void paint_sample_color(
if (use_material) {
/* Image and texture interpolation from material. */
- MPoly *mp = me_eval->mpoly + faceindex;
- Material *ma = BKE_object_material_get(ob_eval, mp->mat_nr + 1);
+ Material *ma = BKE_object_material_get(
+ ob_eval, material_indices ? material_indices[faceindex] + 1 : 1);
/* Force refresh since paint slots are not updated when changing interpolation. */
BKE_texpaint_slot_refresh_cache(scene, ma, ob);