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:
-rw-r--r--source/blender/blenkernel/BKE_material.h4
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c50
-rw-r--r--source/blender/blenkernel/intern/material.c47
-rw-r--r--source/blender/blenkernel/intern/object.c22
4 files changed, 120 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 8aa25a235a8..2407330a237 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -42,6 +42,7 @@ struct ID;
struct Object;
struct Mesh;
struct MTFace;
+struct Scene;
/* materials */
@@ -92,6 +93,9 @@ int material_in_material(struct Material *parmat, struct Material *mat);
void ramp_blend(int type, float r_col[3], const float fac, const float col[3]);
+/* driver update hacks */
+void material_drivers_update(struct Scene *scene, struct Material *mat, float ctime);
+
/* copy/paste */
void clear_matcopybuf(void);
void free_matcopybuf(void);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index a1e67ebd414..99c3b17dee2 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -347,6 +347,44 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node
}
}
+/* XXX: forward def for material driver handling... */
+static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma);
+
+/* recursive handling for material nodetree drivers */
+static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree)
+{
+ bNode *n;
+
+ /* nodetree itself */
+ if (ntree->adt) {
+ dag_add_driver_relation(ntree->adt, dag, node, 1);
+ }
+
+ /* nodetree's nodes... */
+ for (n = ntree->nodes.first; n; n = n->next) {
+ if (n->id && GS(n->id->name) == ID_MA) {
+ dag_add_material_driver_relations(dag, node, (Material *)n->id);
+ }
+ else if (n->type == NODE_GROUP) {
+ dag_add_material_nodetree_driver_relations(dag, node, (bNodeTree *)n->id);
+ }
+ }
+}
+
+/* recursive handling for material drivers */
+static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma)
+{
+ /* material itself */
+ if (ma->adt) {
+ dag_add_driver_relation(ma->adt, dag, node, 1);
+ }
+
+ /* material's nodetree */
+ if (ma->nodetree) {
+ dag_add_material_nodetree_driver_relations(dag, node, ma->nodetree);
+ }
+}
+
static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node)
{
Base *base;
@@ -572,6 +610,18 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
break;
}
+ /* material drivers */
+ if (ob->totcol) {
+ int a;
+
+ for (a = 1; a <= ob->totcol; a++) {
+ Material *ma = give_current_material(ob, a);
+
+ /* recursively figure out if there are drivers, and hook these up to this object */
+ dag_add_material_driver_relations(dag, node, ma);
+ }
+ }
+
/* particles */
psys = ob->particlesystem.first;
if (psys) {
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 48d629a2944..7e8e5455df5 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_anim_types.h"
#include "DNA_curve_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -1050,6 +1051,52 @@ int material_in_material(Material *parmat, Material *mat)
else
return 0;
}
+
+
+/* ****************** */
+
+/* Update drivers for materials in a nodetree */
+static void material_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime)
+{
+ bNode *node;
+
+ /* nodetree itself */
+ if (ntree->adt && ntree->adt->drivers.first) {
+ BKE_animsys_evaluate_animdata(scene, &ntree->id, ntree->adt, ctime, ADT_RECALC_DRIVERS);
+ }
+
+ /* nodes... */
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->id && GS(node->id->name) == ID_MA) {
+ /* TODO: prevent infinite recursion here... */
+ material_drivers_update(scene, (Material *)node->id, ctime);
+ }
+ else if (node->type == NODE_GROUP) {
+ material_node_drivers_update(scene, (bNodeTree *)node->id, ctime);
+ }
+ }
+}
+
+/* Calculate all drivers for materials
+ * FIXME: this is really a terrible method which may result in some things being calculated
+ * multiple times. However, without proper despgraph support for these things, we are forced
+ * into this sort of thing...
+ */
+void material_drivers_update(Scene *scene, Material *ma, float ctime)
+{
+ //if (G.f & G_DEBUG)
+ // printf("material_drivers_update(%s, %s)\n", scene->id.name, ma->id.name);
+
+ /* material itself */
+ if (ma->adt && ma->adt->drivers.first) {
+ BKE_animsys_evaluate_animdata(scene, &ma->id, ma->adt, ctime, ADT_RECALC_DRIVERS);
+ }
+
+ /* nodes */
+ if (ma->nodetree) {
+ material_node_drivers_update(scene, ma->nodetree, ctime);
+ }
+}
/* ****************** */
#if 0 /* UNUSED */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 8fb8d863a8c..74f3d3ddb9d 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2538,7 +2538,7 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
printf("recalcdata %s\n", ob->id.name + 2);
if (adt) {
- /* evaluate drivers */
+ /* evaluate drivers - datalevel */
// XXX: for mesh types, should we push this to derivedmesh instead?
BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS);
}
@@ -2595,8 +2595,24 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
BKE_lattice_modifiers_calc(scene, ob);
break;
}
-
-
+
+ /* related materials */
+ /* XXX: without depsgraph tagging, this will always need to be run, which will be slow!
+ * However, not doing anything (or trying to hack around this lack) is not an option
+ * anymore, especially due to Cycles [#31834]
+ */
+ if (ob->totcol) {
+ int a;
+
+ for (a = 1; a <= ob->totcol; a++) {
+ Material *ma = give_current_material(ob, a);
+
+ /* recursively update drivers for this material */
+ material_drivers_update(scene, ma, ctime);
+ }
+ }
+
+ /* particles */
if (ob->particlesystem.first) {
ParticleSystem *tpsys, *psys;
DerivedMesh *dm;