[Bf-blender-cvs] [21668359b79] master: Fix T66234: Issue on switching material mode between Object and Data

Sergey Sharybin noreply at git.blender.org
Wed Jul 3 16:35:17 CEST 2019


Commit: 21668359b79bd4a44a1f34e479a7bd8072ecdc69
Author: Sergey Sharybin
Date:   Wed Jul 3 15:15:11 2019 +0200
Branches: master
https://developer.blender.org/rB21668359b79bd4a44a1f34e479a7bd8072ecdc69

Fix T66234: Issue on switching material mode between Object and Data

The root of the issue comes to the fact that part of dependency graph
is being removed, without doing any further remapping.
This was happening because only materials used by objects were pulled
in, so when material mode is changed some material became unused and
removed from the dependency graph and freed, causing object or its
data to point to a freed memory in its materials array.

Simplest and safest way to solve this is to pull materials referenced
by both object and object data. This causes somewhat higher memory
usage but keeps evaluated state of scene in an always consistent state,
without any need to tag/update object's data on material mode change.

Don't think it is a problem in practice.

Reviewers: brecht, fclem

Reviewed By: brecht, fclem

Differential Revision: https://developer.blender.org/D5172

===================================================================

M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.h
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations.h

===================================================================

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 9b02f231be4..46a1ea17041 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -697,6 +697,12 @@ void DepsgraphNodeBuilder::build_object_data(Object *object, bool is_object_visi
       break;
     }
   }
+  /* Materials. */
+  Material ***materials_ptr = give_matarar(object);
+  if (materials_ptr != NULL) {
+    short *num_materials_ptr = give_totcolp(object);
+    build_materials(*materials_ptr, *num_materials_ptr);
+  }
 }
 
 void DepsgraphNodeBuilder::build_object_data_camera(Object *object)
@@ -1195,14 +1201,7 @@ 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 (ma != NULL) {
-        build_material(ma);
-      }
-    }
-  }
+  build_materials(object->mat, object->totcol);
   /* Point caches. */
   build_object_pointcache(object);
   /* Geometry. */
@@ -1434,6 +1433,16 @@ void DepsgraphNodeBuilder::build_material(Material *material)
   build_nodetree(material->nodetree);
 }
 
+void DepsgraphNodeBuilder::build_materials(Material **materials, int num_materials)
+{
+  for (int i = 0; i < num_materials; ++i) {
+    if (materials[i] == NULL) {
+      continue;
+    }
+    build_material(materials[i]);
+  }
+}
+
 /* Recursively build graph for texture */
 void DepsgraphNodeBuilder::build_texture(Tex *texture)
 {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 9983b346355..de9f0e4d6cd 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -202,6 +202,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
   void build_light(Light *lamp);
   void build_nodetree(bNodeTree *ntree);
   void build_material(Material *ma);
+  void build_materials(Material **materials, int num_materials);
   void build_texture(Tex *tex);
   void build_image(Image *image);
   void build_world(World *world);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index c2216e068fc..d2f06136b7e 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -751,6 +751,12 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
     add_relation(key_key, geometry_key, "Shapekeys");
     build_nested_shapekey(&object->id, key);
   }
+  /* Materials. */
+  Material ***materials_ptr = give_matarar(object);
+  if (materials_ptr != NULL) {
+    short *num_materials_ptr = give_totcolp(object);
+    build_materials(*materials_ptr, *num_materials_ptr);
+  }
 }
 
 void DepsgraphRelationBuilder::build_object_data_camera(Object *object)
@@ -1934,14 +1940,7 @@ 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);
-      if (ma != NULL) {
-        build_material(ma);
-      }
-    }
-  }
+  build_materials(object->mat, object->totcol);
   /* Geometry collision. */
   if (ELEM(object->type, OB_MESH, OB_CURVE, OB_LATTICE)) {
     // add geometry collider relations
@@ -2236,6 +2235,16 @@ void DepsgraphRelationBuilder::build_material(Material *material)
   }
 }
 
+void DepsgraphRelationBuilder::build_materials(Material **materials, int num_materials)
+{
+  for (int i = 0; i < num_materials; ++i) {
+    if (materials[i] == NULL) {
+      continue;
+    }
+    build_material(materials[i]);
+  }
+}
+
 /* Recursively build graph for texture */
 void DepsgraphRelationBuilder::build_texture(Tex *texture)
 {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 257cae7d127..0e15818622f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -264,6 +264,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
   void build_light(Light *lamp);
   void build_nodetree(bNodeTree *ntree);
   void build_material(Material *ma);
+  void build_materials(Material **materials, int num_materials);
   void build_texture(Tex *tex);
   void build_image(Image *image);
   void build_gpencil(bGPdata *gpd);



More information about the Bf-blender-cvs mailing list