diff options
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 50 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 47 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 22 |
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; |