Fix T52432: Blender crashes while using Ghost (new depsgraph)
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 18 Sep 2017 10:50:27 +0000 (15:50 +0500)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 18 Sep 2017 10:50:27 +0000 (15:50 +0500)
source/blender/depsgraph/intern/eval/deg_eval_flush.cc

index c230ab4c8fd4490213bb58bc3cf29225c6ac4279..40f6901de33d1a2dfcaad596d4ccce76a54194ba 100644 (file)
@@ -54,6 +54,12 @@ extern "C" {
 
 namespace DEG {
 
+enum {
+       COMPONENT_STATE_NONE      = 0,
+       COMPONENT_STATE_SCHEDULED = 1,
+       COMPONENT_STATE_DONE      = 2,
+};
+
 namespace {
 
 // TODO(sergey): De-duplicate with depsgraph_tag,cc
@@ -83,7 +89,7 @@ static void flush_init_func(void *data_v, int i)
        ComponentDepsNode *comp_node = node->owner;
        IDDepsNode *id_node = comp_node->owner;
        id_node->done = 0;
-       comp_node->done = 0;
+       comp_node->done = COMPONENT_STATE_NONE;
        node->scheduled = false;
 }
 
@@ -146,7 +152,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
                                lib_id_recalc_data_tag(bmain, id);
                        }
 
-                       if (comp_node->done == 0) {
+                       if (comp_node->done != COMPONENT_STATE_DONE) {
                                Object *object = NULL;
                                if (GS(id->name) == ID_OB) {
                                        object = (Object *)id;
@@ -190,9 +196,21 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
                                                        break;
                                        }
                                }
+                               /* When some target changes bone, we might need to re-run the
+                                * whole IK solver, otherwise result might be unpredictable.
+                                */
+                               if (comp_node->type == DEG_NODE_TYPE_BONE) {
+                                       ComponentDepsNode *pose_comp =
+                                               id_node->find_component(DEG_NODE_TYPE_EVAL_POSE);
+                                       BLI_assert(pose_comp != NULL);
+                                       if (pose_comp->done == COMPONENT_STATE_NONE) {
+                                               queue.push_front(pose_comp->get_entry_operation());
+                                               pose_comp->done = COMPONENT_STATE_SCHEDULED;
+                                       }
+                               }
                        }
 
-                       id_node->done = 1;
+                       id_node->done = COMPONENT_STATE_DONE;
                        comp_node->done = 1;
 
                        /* Flush to nodes along links... */