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:
Diffstat (limited to 'source/blender/blenkernel/intern/material.c')
-rw-r--r--source/blender/blenkernel/intern/material.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 37d47a984cc..73afea98163 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -77,6 +77,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "GPU_material.h"
@@ -700,6 +701,73 @@ Material *BKE_object_material_get(Object *ob, short act)
return ma_p ? *ma_p : NULL;
}
+static ID *get_evaluated_object_data_with_materials(Object *ob)
+{
+ ID *data = ob->data;
+ /* Meshes in edit mode need special handling. */
+ if (ob->type == OB_MESH && ob->mode == OB_MODE_EDIT) {
+ Mesh *mesh = ob->data;
+ if (mesh->edit_mesh && mesh->edit_mesh->mesh_eval_final) {
+ data = &mesh->edit_mesh->mesh_eval_final->id;
+ }
+ }
+ return data;
+}
+
+/**
+ * On evaluated objects the number of materials on an object and its data might go out of sync.
+ * This is because during evaluation materials can be added/removed on the object data.
+ *
+ * For rendering or exporting we generally use the materials on the object data. However, some
+ * material indices might be overwritten by the object.
+ */
+Material *BKE_object_material_get_eval(Object *ob, short act)
+{
+ BLI_assert(DEG_is_evaluated_object(ob));
+ const int slot_index = act - 1;
+
+ if (slot_index < 0) {
+ return NULL;
+ }
+ ID *data = get_evaluated_object_data_with_materials(ob);
+ const short *tot_slots_data_ptr = BKE_id_material_len_p(data);
+ const int tot_slots_data = tot_slots_data_ptr ? *tot_slots_data_ptr : 0;
+ if (slot_index >= tot_slots_data) {
+ return NULL;
+ }
+ const int tot_slots_object = ob->totcol;
+
+ Material ***materials_data_ptr = BKE_id_material_array_p(data);
+ Material **materials_data = materials_data_ptr ? *materials_data_ptr : NULL;
+ Material **materials_object = ob->mat;
+
+ /* Check if slot is overwritten by object. */
+ if (slot_index < tot_slots_object) {
+ if (ob->matbits) {
+ if (ob->matbits[slot_index]) {
+ Material *material = materials_object[slot_index];
+ if (material != NULL) {
+ return material;
+ }
+ }
+ }
+ }
+ /* Otherwise use data from object-data. */
+ if (slot_index < tot_slots_data) {
+ Material *material = materials_data[slot_index];
+ return material;
+ }
+ return NULL;
+}
+
+int BKE_object_material_count_eval(Object *ob)
+{
+ BLI_assert(DEG_is_evaluated_object(ob));
+ ID *id = get_evaluated_object_data_with_materials(ob);
+ const short *len_p = BKE_id_material_len_p(id);
+ return len_p ? *len_p : 0;
+}
+
Material *BKE_gpencil_material(Object *ob, short act)
{
Material *ma = BKE_object_material_get(ob, act);