Depsgraph: Add ability to check whether relation exists before adding it

Currently not used, but this is aimed to be used when adding relations from
FCurve to property which is being animated.
This commit is contained in:
Sergey Sharybin 2017-12-05 12:52:17 +01:00
parent 8b3aa8ef45
commit 4a99cc5850
5 changed files with 74 additions and 39 deletions

@ -274,10 +274,11 @@ bool DepsgraphRelationBuilder::has_node(const OperationKey &key) const
void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
DepsNode *node_to,
const char *description)
const char *description,
bool check_unique)
{
if (timesrc && node_to) {
graph_->add_new_relation(timesrc, node_to, description);
graph_->add_new_relation(timesrc, node_to, description, check_unique);
}
else {
DEG_DEBUG_PRINTF("add_time_relation(%p = %s, %p = %s, %s) Failed\n",
@ -290,10 +291,11 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
void DepsgraphRelationBuilder::add_operation_relation(
OperationDepsNode *node_from,
OperationDepsNode *node_to,
const char *description)
const char *description,
bool check_unique)
{
if (node_from && node_to) {
graph_->add_new_relation(node_from, node_to, description);
graph_->add_new_relation(node_from, node_to, description, check_unique);
}
else {
DEG_DEBUG_PRINTF("add_operation_relation(%p = %s, %p = %s, %s) Failed\n",

@ -174,17 +174,20 @@ struct DepsgraphRelationBuilder
template <typename KeyFrom, typename KeyTo>
void add_relation(const KeyFrom& key_from,
const KeyTo& key_to,
const char *description);
const char *description,
bool check_unique = false);
template <typename KeyTo>
void add_relation(const TimeSourceKey& key_from,
const KeyTo& key_to,
const char *description);
const char *description,
bool check_unique = false);
template <typename KeyType>
void add_node_handle_relation(const KeyType& key_from,
const DepsNodeHandle *handle,
const char *description);
const char *description,
bool check_unique = false);
void build_scene(Scene *scene);
void build_group(Object *object, Group *group);
@ -261,10 +264,12 @@ protected:
void add_time_relation(TimeSourceDepsNode *timesrc,
DepsNode *node_to,
const char *description);
const char *description,
bool check_unique = false);
void add_operation_relation(OperationDepsNode *node_from,
OperationDepsNode *node_to,
const char *description);
const char *description,
bool check_unique = false);
template <typename KeyType>
DepsNodeHandle create_node_handle(const KeyType& key,

@ -42,14 +42,15 @@ OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType&
template <typename KeyFrom, typename KeyTo>
void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
const KeyTo &key_to,
const char *description)
const char *description,
bool check_unique)
{
DepsNode *node_from = get_node(key_from);
DepsNode *node_to = get_node(key_to);
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
if (op_from && op_to) {
add_operation_relation(op_from, op_to, description);
add_operation_relation(op_from, op_to, description, check_unique);
}
else {
if (!op_from) {
@ -76,13 +77,14 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
template <typename KeyTo>
void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from,
const KeyTo &key_to,
const char *description)
const char *description,
bool check_unique)
{
TimeSourceDepsNode *time_from = get_node(key_from);
DepsNode *node_to = get_node(key_to);
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
if (time_from != NULL && op_to != NULL) {
add_time_relation(time_from, op_to, description);
add_time_relation(time_from, op_to, description, check_unique);
}
}
@ -90,13 +92,14 @@ template <typename KeyType>
void DepsgraphRelationBuilder::add_node_handle_relation(
const KeyType &key_from,
const DepsNodeHandle *handle,
const char *description)
const char *description,
bool check_unique)
{
DepsNode *node_from = get_node(key_from);
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
OperationDepsNode *op_to = handle->node->get_entry_operation();
if (op_from != NULL && op_to != NULL) {
add_operation_relation(op_from, op_to, description);
add_operation_relation(op_from, op_to, description, check_unique);
}
else {
if (!op_from) {

@ -292,10 +292,18 @@ void Depsgraph::clear_id_nodes()
/* Add new relationship between two nodes. */
DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
OperationDepsNode *to,
const char *description)
const char *description,
bool check_unique)
{
DepsRelation *rel = NULL;
if (check_unique) {
rel = check_nodes_connected(from, to, description);
}
if (rel != NULL) {
return rel;
}
/* Create new relation, and add it to the graph. */
DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
/* TODO(sergey): Find a better place for this. */
#ifdef WITH_OPENSUBDIV
ComponentDepsNode *comp_node = from->owner;
@ -315,13 +323,38 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
/* Add new relation between two nodes */
DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to,
const char *description)
const char *description,
bool check_unique)
{
DepsRelation *rel = NULL;
if (check_unique) {
rel = check_nodes_connected(from, to, description);
}
if (rel != NULL) {
return rel;
}
/* Create new relation, and add it to the graph. */
DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
return rel;
}
DepsRelation *Depsgraph::check_nodes_connected(const DepsNode *from,
const DepsNode *to,
const char *description)
{
foreach (DepsRelation *rel, from->outlinks) {
BLI_assert(rel->from == from);
if (rel->to != to) {
continue;
}
if (description != NULL && !STREQ(rel->name, description)) {
continue;
}
return rel;
}
return NULL;
}
/* ************************ */
/* Relationships Management */
@ -333,24 +366,6 @@ DepsRelation::DepsRelation(DepsNode *from,
name(description),
flag(0)
{
#ifndef NDEBUG
/*
for (OperationDepsNode::Relations::const_iterator it = from->outlinks.begin();
it != from->outlinks.end();
++it)
{
DepsRelation *rel = *it;
if (rel->from == from &&
rel->to == to &&
rel->type == type &&
rel->name == description)
{
BLI_assert(!"Duplicated relation, should not happen!");
}
}
*/
#endif
/* Hook it up to the nodes which use it.
*
* NOTE: We register relation in the nodes which this link connects to here

@ -117,11 +117,21 @@ struct Depsgraph {
/* Add new relationship between two nodes. */
DepsRelation *add_new_relation(OperationDepsNode *from,
OperationDepsNode *to,
const char *description);
const char *description,
bool check_unique);
DepsRelation *add_new_relation(DepsNode *from,
DepsNode *to,
const char *description);
const char *description,
bool check_unique);
/* Check whether two nodes are connected by relation with given
* description. Description might be NULL to check ANY relation between
* given nodes.
*/
DepsRelation *check_nodes_connected(const DepsNode *from,
const DepsNode *to,
const char *description);
/* Tag a specific node as needing updates. */
void add_entry_tag(OperationDepsNode *node);