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