Geometry Nodes: Link drag search value moving improvement #107470

Merged
Hans Goudey merged 7 commits from mod_moder/blender:tmp_add_other_value_option_to_dnd_moving into main 2023-05-02 18:50:42 +02:00
1 changed files with 86 additions and 40 deletions

View File

@ -65,6 +65,7 @@
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_type_conversions.hh"
#include "RNA_access.h"
#include "RNA_define.h"
@ -2426,6 +2427,71 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree,
return node_dst;
}
/**
* Type of value storage related with socket is the same.
* \param socket: Node can have multiple sockets & storages pairs.
*/
static void *node_static_value_storage_for(bNode &node, const bNodeSocket &socket)
{
if (!socket.is_output()) {
return nullptr;
}
switch (node.type) {
case FN_NODE_INPUT_BOOL:
return &reinterpret_cast<NodeInputBool *>(node.storage)->boolean;
case FN_NODE_INPUT_INT:
mod_moder marked this conversation as resolved Outdated

IMO the brackets don't really help here, they just make the function take more space. They aren't necessary since you aren't declaring any variables in the cases. Same with below.

IMO the brackets don't really help here, they just make the function take more space. They aren't necessary since you aren't declaring any variables in the cases. Same with below.
return &reinterpret_cast<NodeInputInt *>(node.storage)->integer;
case FN_NODE_INPUT_VECTOR:
return &reinterpret_cast<NodeInputVector *>(node.storage)->vector;
case FN_NODE_INPUT_COLOR:
return &reinterpret_cast<NodeInputColor *>(node.storage)->color;
case GEO_NODE_IMAGE:
return &node.id;
default:
break;
}
return nullptr;
}
static void *socket_value_storage(bNodeSocket &socket)
mod_moder marked this conversation as resolved Outdated
/home/hans/blender-git/blender/source/blender/blenkernel/intern/node.cc:2434:7: warning: no previous declaration for ‘void* blender::bke::node_static_value_storage_for(bNode&, const bNodeSocket&)’ [-Wmissing-declarations]
 2434 | void *node_static_value_storage_for(bNode &node, const bNodeSocket &socket)
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/hans/blender-git/blender/source/blender/blenkernel/intern/node.cc:2458:7: warning: no previous declaration for ‘void* blender::bke::socket_value_storage(bNodeSocket&)’ [-Wmissing-declarations]
 2458 | void *socket_value_storage(bNodeSocket &socket)
      |       ^~~~~~~~~~~~~~~~~~~~
``` /home/hans/blender-git/blender/source/blender/blenkernel/intern/node.cc:2434:7: warning: no previous declaration for ‘void* blender::bke::node_static_value_storage_for(bNode&, const bNodeSocket&)’ [-Wmissing-declarations] 2434 | void *node_static_value_storage_for(bNode &node, const bNodeSocket &socket) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/hans/blender-git/blender/source/blender/blenkernel/intern/node.cc:2458:7: warning: no previous declaration for ‘void* blender::bke::socket_value_storage(bNodeSocket&)’ [-Wmissing-declarations] 2458 | void *socket_value_storage(bNodeSocket &socket) | ^~~~~~~~~~~~~~~~~~~~ ```
{
switch (eNodeSocketDatatype(socket.type)) {
case SOCK_BOOLEAN:
return &socket.default_value_typed<bNodeSocketValueBoolean>()->value;
case SOCK_INT:
return &socket.default_value_typed<bNodeSocketValueInt>()->value;
case SOCK_FLOAT:
return &socket.default_value_typed<bNodeSocketValueFloat>()->value;
case SOCK_VECTOR:
return &socket.default_value_typed<bNodeSocketValueVector>()->value;
case SOCK_RGBA:
return &socket.default_value_typed<bNodeSocketValueRGBA>()->value;
case SOCK_IMAGE:
return &socket.default_value_typed<bNodeSocketValueImage>()->value;
case SOCK_TEXTURE:
return &socket.default_value_typed<bNodeSocketValueTexture>()->value;
case SOCK_COLLECTION:
return &socket.default_value_typed<bNodeSocketValueCollection>()->value;
case SOCK_OBJECT:
return &socket.default_value_typed<bNodeSocketValueObject>()->value;
case SOCK_MATERIAL:
return &socket.default_value_typed<bNodeSocketValueMaterial>()->value;
case SOCK_STRING:
/* We don't want do this now! */
mod_moder marked this conversation as resolved Outdated

Seems simpler to return null here as a way to not support strings, rather than checking again below:

    case SOCK_STRING:
      /* Strings are not supported here. */
      return nullptr;
Seems simpler to return null here as a way to not support strings, rather than checking again below: ``` case SOCK_STRING: /* Strings are not supported here. */ return nullptr; ```
return nullptr;
case __SOCK_MESH:
case SOCK_CUSTOM:
case SOCK_SHADER:
case SOCK_GEOMETRY:
/* Unmovable types. */
break;
}
return nullptr;
}
void node_socket_move_default_value(Main & /*bmain*/,
bNodeTree &tree,
bNodeSocket &src,
@ -2436,6 +2502,11 @@ void node_socket_move_default_value(Main & /*bmain*/,
bNode &dst_node = dst.owner_node();
bNode &src_node = src.owner_node();
const CPPType &src_type = *src.typeinfo->base_cpp_type;
const CPPType &dst_type = *dst.typeinfo->base_cpp_type;
const bke::DataTypeConversions &convert = bke::get_implicit_type_conversions();
if (src.is_multi_input()) {
/* Multi input sockets no have value. */
return;
@ -2444,54 +2515,29 @@ void node_socket_move_default_value(Main & /*bmain*/,
/* Reroute node can't have ownership of socket value directly. */
return;
}
if (dst.type != src.type) {
/* It could be possible to support conversion in future. */
return;
}
ID **src_socket_value = nullptr;
Vector<ID **> dst_values;
switch (dst.type) {
case SOCK_IMAGE: {
Image **tmp_socket_value = &src.default_value_typed<bNodeSocketValueImage>()->value;
src_socket_value = reinterpret_cast<ID **>(tmp_socket_value);
if (*src_socket_value == nullptr) {
break;
}
switch (dst_node.type) {
case GEO_NODE_IMAGE: {
dst_values.append(&dst_node.id);
break;
}
default: {
break;
}
}
break;
}
case SOCK_CUSTOM:
case SOCK_SHADER:
case SOCK_GEOMETRY: {
/* Unmovable types. */
if (&src_type != &dst_type) {
if (!convert.is_convertible(src_type, dst_type)) {
return;
}
default: {
break;
}
}
if (dst_values.is_empty() || src_socket_value == nullptr) {
void *src_value = socket_value_storage(src);
void *dst_value = node_static_value_storage_for(dst_node, dst);
if (!dst_value || !src_value) {
return;
}
for (ID **dst_value : dst_values) {
*dst_value = *src_socket_value;
id_us_plus(*dst_value);
}
convert.convert_to_uninitialized(src_type, dst_type, src_value, dst_value);
id_us_min(*src_socket_value);
*src_socket_value = nullptr;
src_type.destruct(src_value);
if (ELEM(eNodeSocketDatatype(src.type),
SOCK_COLLECTION,
SOCK_IMAGE,
SOCK_MATERIAL,
SOCK_TEXTURE,
SOCK_OBJECT)) {
src_type.value_initialize(src_value);
}
}
bNode *node_copy(bNodeTree *dst_tree, const bNode &src_node, const int flag, const bool use_unique)
mod_moder marked this conversation as resolved Outdated

Why cast to void ** here? Seems like void * would be fine.

Why cast to `void **` here? Seems like `void *` would be fine.