Blender  V3.3
deg_builder_relations_impl.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. All rights reserved. */
3 
8 #pragma once
9 
11 
12 #include <iostream>
13 
14 #include "DNA_ID.h"
15 #include "DNA_object_types.h"
16 #include "DNA_rigidbody_types.h"
17 
18 namespace blender::deg {
19 
20 template<typename KeyType>
22 {
23  Node *node = get_node(key);
24  return node != nullptr ? node->get_exit_operation() : nullptr;
25 }
26 
27 template<typename KeyFrom, typename KeyTo>
29  const KeyTo &key_to,
30  const char *description,
31  int flags)
32 {
33  Node *node_from = get_node(key_from);
34  Node *node_to = get_node(key_to);
35  OperationNode *op_from = node_from ? node_from->get_exit_operation() : nullptr;
36  OperationNode *op_to = node_to ? node_to->get_entry_operation() : nullptr;
37 
38  if (op_from && op_to) {
39  return add_operation_relation(op_from, op_to, description, flags);
40  }
41 
42  /* TODO(sergey): Report error in the interface. */
43 
44  std::cerr << "--------------------------------------------------------------------\n";
45  std::cerr << "Failed to add relation \"" << description << "\"\n";
46 
47  if (!op_from) {
48  std::cerr << "Could not find op_from: " << key_from.identifier() << "\n";
49  }
50 
51  if (!op_to) {
52  std::cerr << "Could not find op_to: " << key_to.identifier() << "\n";
53  }
54 
55  if (!stack_.is_empty()) {
56  std::cerr << "\nTrace:\n\n";
57  stack_.print_backtrace(std::cerr);
58  std::cerr << "\n";
59  }
60 
61  return nullptr;
62 }
63 
64 template<typename KeyTo>
66  const KeyTo &key_to,
67  const char *description,
68  int flags)
69 {
70  TimeSourceNode *time_from = get_node(key_from);
71  Node *node_to = get_node(key_to);
72  OperationNode *op_to = node_to ? node_to->get_entry_operation() : nullptr;
73  if (time_from != nullptr && op_to != nullptr) {
74  return add_time_relation(time_from, op_to, description, flags);
75  }
76  return nullptr;
77 }
78 
79 template<typename KeyType>
81  const DepsNodeHandle *handle,
82  const char *description,
83  int flags)
84 {
85  Node *node_from = get_node(key_from);
86  OperationNode *op_from = node_from ? node_from->get_exit_operation() : nullptr;
87  OperationNode *op_to = handle->node->get_entry_operation();
88  if (op_from != nullptr && op_to != nullptr) {
89  return add_operation_relation(op_from, op_to, description, flags);
90  }
91  else {
92  if (!op_from) {
93  fprintf(stderr,
94  "add_node_handle_relation(%s) - Could not find op_from (%s)\n",
95  description,
96  key_from.identifier().c_str());
97  }
98  if (!op_to) {
99  fprintf(stderr,
100  "add_node_handle_relation(%s) - Could not find op_to (%s)\n",
101  description,
102  key_from.identifier().c_str());
103  }
104  }
105  return nullptr;
106 }
107 
109 {
110  if (rbo == nullptr) {
111  return false;
112  }
114  if (rbo->mesh_source != RBO_MESH_BASE) {
115  return true;
116  }
117  }
118  return false;
119 }
120 
121 template<typename KeyTo>
123  const KeyTo &key_to,
124  const char *description,
125  int flags)
126 {
127  if (GS(id->name) == ID_OB) {
128  Object *object = reinterpret_cast<Object *>(id);
131  return add_relation(transform_key, key_to, description, flags);
132  }
133  }
134  ComponentKey transform_key(id, NodeType::TRANSFORM);
135  return add_relation(transform_key, key_to, description, flags);
136 }
137 
138 template<typename KeyType>
140  const char *default_name)
141 {
142  return DepsNodeHandle(this, get_node(key), default_name);
143 }
144 
145 /* Rig compatibility: we check if bone is using local transform as a variable
146  * for driver on itself and ignore those relations to avoid "false-positive"
147  * dependency cycles.
148  */
149 template<typename KeyFrom, typename KeyTo>
151  const KeyTo &key_to)
152 {
153  /* Get operations for requested keys. */
154  Node *node_from = get_node(key_from);
155  Node *node_to = get_node(key_to);
156  if (node_from == nullptr || node_to == nullptr) {
157  return false;
158  }
159  OperationNode *op_from = node_from->get_exit_operation();
160  OperationNode *op_to = node_to->get_entry_operation();
161  if (op_from == nullptr || op_to == nullptr) {
162  return false;
163  }
164  /* Different armatures, bone can't be the same. */
165  if (op_from->owner->owner != op_to->owner->owner) {
166  return false;
167  }
168  /* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */
169  if (!(op_from->opcode == OperationCode::BONE_DONE &&
170  op_to->opcode == OperationCode::BONE_LOCAL)) {
171  return false;
172  }
173  /* ... BUT, we also need to check if it's same bone. */
174  if (op_from->owner->name != op_to->owner->name) {
175  return false;
176  }
177  return true;
178 }
179 
180 template<typename KeyFrom, typename KeyTo>
182  const KeyTo &key_to)
183 {
184  /* Get operations for requested keys. */
185  Node *node_from = get_node(key_from);
186  Node *node_to = get_node(key_to);
187  if (node_from == nullptr || node_to == nullptr) {
188  return false;
189  }
190  OperationNode *op_from = node_from->get_exit_operation();
191  OperationNode *op_to = node_to->get_entry_operation();
192  if (op_from == nullptr || op_to == nullptr) {
193  return false;
194  }
195  /* Check if this is actually a node tree. */
196  if (GS(op_from->owner->owner->id_orig->name) != ID_NT) {
197  return false;
198  }
199  /* Different node trees. */
200  if (op_from->owner->owner != op_to->owner->owner) {
201  return false;
202  }
203  /* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */
204  if (!(op_from->opcode == OperationCode::PARAMETERS_EVAL &&
206  return false;
207  }
208  return true;
209 }
210 
211 } // namespace blender::deg
#define ELEM(...)
ID and Library types, which are fundamental for sdna.
@ ID_NT
Definition: DNA_ID_enums.h:68
@ ID_OB
Definition: DNA_ID_enums.h:47
Object is a sort of wrapper for general info.
Types and defines for representing Rigid Body entities.
@ RBO_MESH_BASE
@ RB_SHAPE_CONVEXH
@ RB_SHAPE_TRIMESH
void print_backtrace(std::ostream &stream)
Relation * add_depends_on_transform_relation(ID *id, const KeyTo &key_to, const char *description, int flags=0)
TimeSourceNode * get_node(const TimeSourceKey &key) const
bool is_same_nodetree_node_dependency(const KeyFrom &key_from, const KeyTo &key_to)
bool is_same_bone_dependency(const KeyFrom &key_from, const KeyTo &key_to)
Relation * add_node_handle_relation(const KeyType &key_from, const DepsNodeHandle *handle, const char *description, int flags=0)
Relation * add_relation(const KeyFrom &key_from, const KeyTo &key_to, const char *description, int flags=0)
Relation * add_operation_relation(OperationNode *node_from, OperationNode *node_to, const char *description, int flags=0)
OperationNode * find_operation_node(const KeyType &key)
DepsNodeHandle create_node_handle(const KeyType &key, const char *default_name="")
Relation * add_time_relation(TimeSourceNode *timesrc, Node *node_to, const char *description, int flags=0)
OperationNode * node
#define GS(x)
Definition: iris.c:225
static bool rigidbody_object_depends_on_evaluated_geometry(const RigidBodyOb *rbo)
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
struct RigidBodyOb * rigidbody_object
virtual OperationNode * get_exit_operation()
Definition: deg_node.h:202
virtual OperationNode * get_entry_operation()
Definition: deg_node.h:198
virtual OperationNode * get_entry_operation() override