Page MenuHome

Switching Grease Pencil material slot link to Object and back to Data corrupts material
Open, Confirmed, MediumPublic

Description

Blender Version
Broken: 9efe117535c6, master, 2018-05-20

Short description of error
For normal objects switching a material slot link to Object and back to Data will result in the material to reappear in the slot. For Grease Pencil objects the material in the slot will point to 0xcccc.... This causes blender to crash while rendering the viewport.

Exact steps for others to reproduce the error

  1. File -> New -> 2D Animation
  2. Switch Link of material slot to Object (Bottom right button in material slot selector.)
  3. Switch Link of same material slot back to Data
  4. Blender crashes on viewport render

Details

Type
Bug

Event Timeline

Brecht Van Lommel (brecht) triaged this task as Waiting for Developer to Reproduce priority.
Antonio Vazquez (antoniov) lowered the priority of this task from Waiting for Developer to Reproduce to Confirmed, Medium.Wed, May 29, 9:54 AM

@Brecht Van Lommel (brecht) I have been doing debug and I have seen the problem is when retry the material.

The material is recovered using

give_current_material(ob, ob->actcol);

You can find the code in BKE_gpencil_object_material_get_from_brush()

IIRC you told me the function give_current_material() Is used to get the mat for Data and for Objet mode, but in this case, the function is returning NaN. I have checked and the Object parameter is correct and the ob->actcol=1, so not sure why this is not working... at least the function could return NULL intead of garbage data.

Any idea?

I have seen this in the console, not sure if related or not:

find_node_operation: Failed for (MATERIAL_UPDATE, '')
add_relation(Material -> GP Data) - Could not find op_from (OperationKey(type: SHADING, component name: '', operation code: MATERIAL_UPDATE))
add_relation(Material -> GP Data) - Failed, but op_to (ComponentKey(GDStroke, GEOMETRY)) was ok

Could be that the problem is in DepsgraphNodeBuilder::build_object_data_geometry where only materials are handled which are returned by give_current_material. When setting a link to Object, then the material in ob->data is ignored. But I'm not sure how this wouldn't have caused problems with the default cube.

This would fix the problem:

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 93e5dd14ae0..acdf08b7f32 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1191,9 +1191,19 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob
       function_bind(BKE_object_eval_uber_data, _1, scene_cow, object_cow));
   op_node->set_as_exit();
   /* Materials. */
-  if (object->totcol != 0) {
-    for (int a = 1; a <= object->totcol; a++) {
-      Material *ma = give_current_material(object, a);
+  if (object->totcol) {
+    for (int a = 0; a < object->totcol; a++) {
+      Material *ma = object->mat[a];
+      if (ma != NULL) {
+        build_material(ma);
+      }
+    }
+  }
+  short *totcolp = give_totcolp(object);
+  if (*totcolp) {
+    Material ***matarar = give_matarar(object);
+    for (int a = 0; a < *totcolp; a++) {
+      Material *ma = (*matarar)[a];
       if (ma != NULL) {
         build_material(ma);
       }
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 54d5223497e..117b1fd6d19 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1918,8 +1918,18 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
   }
   /* Materials. */
   if (object->totcol) {
-    for (int a = 1; a <= object->totcol; a++) {
-      Material *ma = give_current_material(object, a);
+    for (int a = 0; a < object->totcol; a++) {
+      Material *ma = object->mat[a];
+      if (ma != NULL) {
+        build_material(ma);
+      }
+    }
+  }
+  short *totcolp = give_totcolp(object);
+  if (*totcolp) {
+    Material ***matarar = give_matarar(object);
+    for (int a = 0; a < *totcolp; a++) {
+      Material *ma = (*matarar)[a];
       if (ma != NULL) {
         build_material(ma);
       }