WIP: Fix: Geometry Nodes: Don't create dependency graph relations for linked socket values #109268

Draft
Iliya Katushenock wants to merge 5 commits from mod_moder/blender:fix_dont_relate_linked_sockets into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 99 additions and 37 deletions

View File

@ -354,6 +354,8 @@ extern bNodeTreeType NodeTreeTypeUndefined;
extern bNodeType NodeTypeUndefined;
extern bNodeSocketType NodeSocketTypeUndefined;
bool socket_is_useless(const bNode &node, const bNodeSocket &socket);
} // namespace blender::bke
#define NODE_STORAGE_FUNCS(StorageT) \

View File

@ -825,6 +825,50 @@ template<typename T> const T *bNodeSocket::default_value_typed() const
return static_cast<const T *>(this->default_value);
}
inline ID *bNodeSocket::default_value_to_id()
{
switch (eNodeSocketDatatype(this->type)) {
case SOCK_OBJECT:
return reinterpret_cast<ID *>(this->default_value_typed<bNodeSocketValueObject>()->value);
case SOCK_COLLECTION:
return reinterpret_cast<ID *>(
this->default_value_typed<bNodeSocketValueCollection>()->value);
case SOCK_MATERIAL:
return reinterpret_cast<ID *>(this->default_value_typed<bNodeSocketValueMaterial>()->value);
case SOCK_TEXTURE:
return reinterpret_cast<ID *>(this->default_value_typed<bNodeSocketValueTexture>()->value);
case SOCK_IMAGE:
return reinterpret_cast<ID *>(this->default_value_typed<bNodeSocketValueImage>()->value);
default:
BLI_assert_unreachable();
}
return nullptr;
}
inline const ID *bNodeSocket::default_value_to_id() const
{
switch (eNodeSocketDatatype(this->type)) {
case SOCK_OBJECT:
return reinterpret_cast<const ID *>(
this->default_value_typed<bNodeSocketValueObject>()->value);
case SOCK_COLLECTION:
return reinterpret_cast<const ID *>(
this->default_value_typed<bNodeSocketValueCollection>()->value);
case SOCK_MATERIAL:
return reinterpret_cast<const ID *>(
this->default_value_typed<bNodeSocketValueMaterial>()->value);
case SOCK_TEXTURE:
return reinterpret_cast<const ID *>(
this->default_value_typed<bNodeSocketValueTexture>()->value);
case SOCK_IMAGE:
return reinterpret_cast<const ID *>(
this->default_value_typed<bNodeSocketValueImage>()->value);
default:
BLI_assert_unreachable();
}
return nullptr;
}
inline bool bNodeSocket::is_input() const
{
return this->in_out == SOCK_IN;

View File

@ -1178,9 +1178,11 @@ void BKE_ntree_update_tag_link_removed(bNodeTree *ntree)
add_tree_tag(ntree, NTREE_CHANGED_LINK);
}
void BKE_ntree_update_tag_link_added(bNodeTree *ntree, bNodeLink * /*link*/)
void BKE_ntree_update_tag_link_added(bNodeTree *ntree, bNodeLink *link)
{
add_tree_tag(ntree, NTREE_CHANGED_LINK);
if (link != nullptr && link->tosock != nullptr) {
}
}
void BKE_ntree_update_tag_link_mute(bNodeTree *ntree, bNodeLink * /*link*/)

View File

@ -188,6 +188,8 @@ typedef struct bNodeSocket {
/** Utility to access the value of the socket. */
template<typename T> T *default_value_typed();
template<typename T> const T *default_value_typed() const;
ID *default_value_to_id();
const ID *default_value_to_id() const;
/* The following methods are only available when #bNodeTree.ensure_topology_cache has been
* called. */

View File

@ -121,41 +121,47 @@ static void initData(ModifierData *md)
nmd->simulation_cache = new_simulation_cache();
}
static void add_used_ids_from_sockets(const ListBase &sockets, Set<ID *> &ids)
static bool ignore_socket_value_for_relationships(const bNode &node, const bNodeSocket &socket)
{
LISTBASE_FOREACH (const bNodeSocket *, socket, &sockets) {
switch (socket->type) {
case SOCK_OBJECT: {
if (Object *object = ((bNodeSocketValueObject *)socket->default_value)->value) {
ids.add(&object->id);
}
break;
}
case SOCK_COLLECTION: {
if (Collection *collection = ((bNodeSocketValueCollection *)socket->default_value)->value)
{
ids.add(&collection->id);
}
break;
}
case SOCK_MATERIAL: {
if (Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value) {
ids.add(&material->id);
}
break;
}
case SOCK_TEXTURE: {
if (Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value) {
ids.add(&texture->id);
}
break;
}
case SOCK_IMAGE: {
if (Image *image = ((bNodeSocketValueImage *)socket->default_value)->value) {
ids.add(&image->id);
}
break;
}
if (socket.is_output()) {
/* Output sockets can not contains value. */
return false;
}
if (node.type == NODE_GROUP_OUTPUT) {
/* If this node tree is processed, it output node and it sockets is used. */
return true;
}
if (!node.is_muted()) {
/* Node is worked, socket is used. */
if (socket.flag & SOCK_IS_LINKED) {
/* Socket value is not used. */
return true;
}
return false;
}
for (const bNodeLink &link : node.internal_links()) {
if (link.fromsock == &socket) {
/* Can not ignore value even if node is muted. */
return false;
}
}
return true;
}
static void add_used_ids_from_sockets(const bNode &node,
const Span<const bNodeSocket *> sockets,
Set<ID *> &ids)
{
for (const bNodeSocket *socket : sockets) {
if (ignore_socket_value_for_relationships(node, *socket)) {
continue;
}
if (!ELEM(socket->type, SOCK_OBJECT, SOCK_COLLECTION, SOCK_MATERIAL, SOCK_TEXTURE, SOCK_IMAGE))
{
continue;
}
if (const ID *id = socket->default_value_to_id()) {
ids.add(const_cast<ID *>(id));
}
}
}
@ -168,6 +174,9 @@ static void add_used_ids_from_sockets(const ListBase &sockets, Set<ID *> &ids)
*/
static bool node_needs_own_transform_relation(const bNode &node)
{
if (node.is_muted()) {
return false;
}
if (node.type == GEO_NODE_COLLECTION_INFO) {
const NodeGeometryCollectionInfo &storage = *static_cast<const NodeGeometryCollectionInfo *>(
node.storage);
@ -201,12 +210,15 @@ static void process_nodes_for_depsgraph(const bNodeTree &tree,
tree.ensure_topology_cache();
for (const bNode *node : tree.all_nodes()) {
add_used_ids_from_sockets(node->inputs, ids);
add_used_ids_from_sockets(node->outputs, ids);
add_used_ids_from_sockets(*node, node->input_sockets(), ids);
add_used_ids_from_sockets(*node, node->output_sockets(), ids);
r_needs_own_transform_relation |= node_needs_own_transform_relation(*node);
}
for (const bNode *node : tree.group_nodes()) {
if (node->is_muted()) {
continue;
}
if (const bNodeTree *sub_tree = reinterpret_cast<const bNodeTree *>(node->id)) {
process_nodes_for_depsgraph(*sub_tree, ids, r_needs_own_transform_relation, checked_groups);
}