Depsgraph: Add code which helps catching cases when requested ID node is not ready yet
This shows the bug when IK solver doesn't update reliably when targeted an external object and when that object is handled by build_object() after the armature.
This commit is contained in:
@@ -786,8 +786,6 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key)
|
||||
// XXX: what happens if the datablock is shared!
|
||||
void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
|
||||
{
|
||||
ID *obdata = (ID *)ob->data;
|
||||
ID *obdata_cow = get_cow_id(obdata);
|
||||
OperationDepsNode *op_node;
|
||||
Scene *scene_cow = get_cow_datablock(scene);
|
||||
Object *object_cow = get_cow_datablock(ob);
|
||||
@@ -858,9 +856,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
|
||||
// add geometry collider relations
|
||||
}
|
||||
|
||||
ID *obdata = (ID *)ob->data;
|
||||
if (obdata->tag & LIB_TAG_DOIT) {
|
||||
return;
|
||||
}
|
||||
obdata->tag |= LIB_TAG_DOIT;
|
||||
/* Make sure we've got an ID node before requesting CoW pointer. */
|
||||
(void) add_id_node((ID *)obdata);
|
||||
ID *obdata_cow = get_cow_id(obdata);
|
||||
|
||||
/* ShapeKeys */
|
||||
Key *key = BKE_key_from_object(ob);
|
||||
|
||||
@@ -412,6 +412,16 @@ ID *Depsgraph::get_cow_id(const ID *id_orig) const
|
||||
{
|
||||
IDDepsNode *id_node = find_id_node(id_orig);
|
||||
if (id_node == NULL) {
|
||||
/* This function is used from places where we expect ID to be either
|
||||
* already a copy-on-write version or have a corresponding copy-on-write
|
||||
* version.
|
||||
*
|
||||
* We try to enforce that in debug builds, for for release we play a bit
|
||||
* safer game here.
|
||||
*/
|
||||
if ((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0) {
|
||||
BLI_assert(!"Request for non-existing copy-on-write ID");
|
||||
}
|
||||
return (ID *)id_orig;
|
||||
}
|
||||
return id_node->id_cow;
|
||||
|
||||
@@ -286,6 +286,35 @@ Scene *scene_copy_no_main(Scene *scene)
|
||||
return new_scene;
|
||||
}
|
||||
|
||||
/* Check whether given ID is expanded or still a shallow copy. */
|
||||
BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
|
||||
{
|
||||
return (id_cow->name[0] != '\0');
|
||||
}
|
||||
|
||||
/* Check whether datablock was already expanded during depsgraph
|
||||
* construction.
|
||||
*/
|
||||
static bool check_datablock_expanded_at_construction(const ID *id_orig)
|
||||
{
|
||||
const short id_type = GS(id_orig->name);
|
||||
return (id_type == ID_SCE) ||
|
||||
(id_type == ID_OB && ((Object *)id_orig)->type == OB_ARMATURE) ||
|
||||
(id_type == ID_AR);
|
||||
}
|
||||
|
||||
/* Those are datablocks which are not covered by dependency graph and hence
|
||||
* does not need any remapping or anything.
|
||||
*/
|
||||
static bool check_datablocks_copy_on_writable(const ID *id_orig)
|
||||
{
|
||||
const short id_type = GS(id_orig->name);
|
||||
return !ELEM(id_type, ID_BR,
|
||||
ID_TE,
|
||||
ID_IM,
|
||||
ID_LS);
|
||||
}
|
||||
|
||||
/* Callback for BKE_library_foreach_ID_link which remaps original ID pointer
|
||||
* with the one created by CoW system.
|
||||
*/
|
||||
@@ -320,7 +349,7 @@ int foreach_libblock_remap_callback(void *user_data_v,
|
||||
id_orig->name, id_orig, user_data->real_id);
|
||||
*id_p = user_data->real_id;
|
||||
}
|
||||
else {
|
||||
else if (check_datablocks_copy_on_writable(id_orig)) {
|
||||
ID *id_cow = depsgraph->get_cow_id(id_orig);
|
||||
BLI_assert(id_cow != NULL);
|
||||
DEG_COW_PRINT(" Remapping datablock for %s: id_orig=%p id_cow=%p\n",
|
||||
@@ -331,23 +360,6 @@ int foreach_libblock_remap_callback(void *user_data_v,
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
/* Check whether given ID is expanded or still a shallow copy. */
|
||||
BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
|
||||
{
|
||||
return (id_cow->name[0] != '\0');
|
||||
}
|
||||
|
||||
/* Check whether datablock was already expanded during depsgraph
|
||||
* construction.
|
||||
*/
|
||||
static bool check_datablock_expanded_at_construction(const ID *id_orig)
|
||||
{
|
||||
const short id_type = GS(id_orig->name);
|
||||
return (id_type == ID_SCE) ||
|
||||
(id_type == ID_OB && ((Object *)id_orig)->type == OB_ARMATURE) ||
|
||||
(id_type == ID_AR);
|
||||
}
|
||||
|
||||
/* Do some special treatment of data transfer from original ID to it's
|
||||
* CoW complementary part.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user