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:
authorJacques Lucke <jacques@blender.org>2021-05-19 11:23:09 +0300
committerJacques Lucke <jacques@blender.org>2021-05-19 11:23:09 +0300
commit1a81d268a19f2f1402f408ad1dadf92c7a399607 (patch)
treed3f1b657efc1676b6b1f4b1cc34b4623529c379c /source/blender/makesrna
parentd373b43f07f5403826035b5dee71b09f433b0540 (diff)
Materials: support changing materials during evaluation
This commit allows that the evaluated geometry of an object has different materials from the original geometry. This is needed for geometry nodes. The main thing that changes for render engines and exporters is that the number of material slots on an object and its geometry might not match anymore. For original data, the slot counts are still equal, but not for evaluated data. Accessing material slots though rna stays the same. The behavior adapts automatically depending on whether the object is evaluated. When accessing materials of an object through `BKE_object_material_*` one has to use a new api for evaluated objects: `BKE_object_material_get_eval` and `BKE_object_material_count_eval`. In the future, the different behavior might be hidden behind a more general C api, but that would require quite a few more changes. The ground truth for the number of materials is the number of materials on the geometry now. This is important in the current design, because Eevee needs to know the number of materials just based on the mesh in `mesh_render_mat_len_get` and similar places. In a few places I had to add a special case for mesh edit mode to get it to work properly. This is unfortunate, but I don't see a way around that for now. Differential Revision: https://developer.blender.org/D11236
Diffstat (limited to 'source/blender/makesrna')
-rw-r--r--source/blender/makesrna/intern/rna_object.c90
1 files changed, 74 insertions, 16 deletions
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 3edfd5c44f4..3126b45cb82 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -62,6 +62,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "DEG_depsgraph_query.h"
+
const EnumPropertyItem rna_enum_object_mode_items[] = {
{OB_MODE_OBJECT, "OBJECT", ICON_OBJECT_DATAMODE, "Object Mode", ""},
{OB_MODE_EDIT, "EDIT", ICON_EDITMODE_HLT, "Edit Mode", ""},
@@ -1253,10 +1255,15 @@ static int rna_Object_rotation_4d_editable(PointerRNA *ptr, int index)
return PROP_EDITABLE;
}
+static int rna_MaterialSlot_index(PointerRNA *ptr)
+{
+ return POINTER_AS_INT(ptr->data);
+}
+
static int rna_MaterialSlot_material_editable(PointerRNA *ptr, const char **UNUSED(r_info))
{
Object *ob = (Object *)ptr->owner_id;
- const int index = (Material **)ptr->data - ob->mat;
+ const int index = rna_MaterialSlot_index(ptr);
bool is_editable;
if ((ob->matbits == NULL) || ob->matbits[index]) {
@@ -1273,9 +1280,14 @@ static PointerRNA rna_MaterialSlot_material_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
Material *ma;
- const int index = (Material **)ptr->data - ob->mat;
+ const int index = rna_MaterialSlot_index(ptr);
- ma = BKE_object_material_get(ob, index + 1);
+ if (DEG_is_evaluated_object(ob)) {
+ ma = BKE_object_material_get_eval(ob, index + 1);
+ }
+ else {
+ ma = BKE_object_material_get(ob, index + 1);
+ }
return rna_pointer_inherit_refine(ptr, &RNA_Material, ma);
}
@@ -1284,7 +1296,7 @@ static void rna_MaterialSlot_material_set(PointerRNA *ptr,
struct ReportList *UNUSED(reports))
{
Object *ob = (Object *)ptr->owner_id;
- int index = (Material **)ptr->data - ob->mat;
+ int index = rna_MaterialSlot_index(ptr);
BLI_assert(BKE_id_is_in_global_main(&ob->id));
BLI_assert(BKE_id_is_in_global_main(value.data));
@@ -1309,15 +1321,17 @@ static bool rna_MaterialSlot_material_poll(PointerRNA *ptr, PointerRNA value)
static int rna_MaterialSlot_link_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
- int index = (Material **)ptr->data - ob->mat;
-
- return ob->matbits[index] != 0;
+ int index = rna_MaterialSlot_index(ptr);
+ if (index < ob->totcol) {
+ return ob->matbits[index] != 0;
+ }
+ return false;
}
static void rna_MaterialSlot_link_set(PointerRNA *ptr, int value)
{
Object *ob = (Object *)ptr->owner_id;
- int index = (Material **)ptr->data - ob->mat;
+ int index = rna_MaterialSlot_index(ptr);
if (value) {
ob->matbits[index] = 1;
@@ -1335,7 +1349,7 @@ static int rna_MaterialSlot_name_length(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
Material *ma;
- int index = (Material **)ptr->data - ob->mat;
+ int index = rna_MaterialSlot_index(ptr);
ma = BKE_object_material_get(ob, index + 1);
@@ -1350,7 +1364,7 @@ static void rna_MaterialSlot_name_get(PointerRNA *ptr, char *str)
{
Object *ob = (Object *)ptr->owner_id;
Material *ma;
- int index = (Material **)ptr->data - ob->mat;
+ int index = rna_MaterialSlot_index(ptr);
ma = BKE_object_material_get(ob, index + 1);
@@ -1373,10 +1387,48 @@ static void rna_MaterialSlot_update(Main *bmain, Scene *scene, PointerRNA *ptr)
static char *rna_MaterialSlot_path(PointerRNA *ptr)
{
+ int index = rna_MaterialSlot_index(ptr);
+ return BLI_sprintfN("material_slots[%d]", index);
+}
+
+static int rna_Object_material_slots_length(PointerRNA *ptr)
+{
Object *ob = (Object *)ptr->owner_id;
- int index = (Material **)ptr->data - ob->mat;
+ if (DEG_is_evaluated_object(ob)) {
+ return BKE_object_material_count_eval(ob);
+ }
+ else {
+ return ob->totcol;
+ }
+}
- return BLI_sprintfN("material_slots[%d]", index);
+static void rna_Object_material_slots_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ const int length = rna_Object_material_slots_length(ptr);
+ iter->internal.count.item = 0;
+ iter->internal.count.ptr = ptr->owner_id;
+ iter->valid = length > 0;
+}
+
+static void rna_Object_material_slots_next(CollectionPropertyIterator *iter)
+{
+ const int length = rna_Object_material_slots_length(&iter->ptr);
+ iter->internal.count.item++;
+ iter->valid = iter->internal.count.item < length;
+}
+
+static PointerRNA rna_Object_material_slots_get(CollectionPropertyIterator *iter)
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)iter->internal.count.ptr,
+ &RNA_MaterialSlot,
+ POINTER_FROM_INT(iter->internal.count.item),
+ &ptr);
+ return ptr;
+}
+
+static void rna_Object_material_slots_end(CollectionPropertyIterator *UNUSED(iter))
+{
}
static PointerRNA rna_Object_display_get(PointerRNA *ptr)
@@ -2958,12 +3010,18 @@ static void rna_def_object(BlenderRNA *brna)
/* materials */
prop = RNA_def_property(srna, "material_slots", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol");
RNA_def_property_struct_type(prop, "MaterialSlot");
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_PROP_NAME);
- /* don't dereference pointer! */
- RNA_def_property_collection_funcs(
- prop, NULL, NULL, NULL, "rna_iterator_array_get", NULL, NULL, NULL, NULL);
+ /* Don't dereference the material slot pointer, it is the slot index encoded in a pointer. */
+ RNA_def_property_collection_funcs(prop,
+ "rna_Object_material_slots_begin",
+ "rna_Object_material_slots_next",
+ "rna_Object_material_slots_end",
+ "rna_Object_material_slots_get",
+ "rna_Object_material_slots_length",
+ NULL,
+ NULL,
+ NULL);
RNA_def_property_ui_text(prop, "Material Slots", "Material slots in the object");
prop = RNA_def_property(srna, "active_material", PROP_POINTER, PROP_NONE);