mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Merge branch 'blender-v5.2-release'
This commit is contained in:
commit
8faae58201
7 changed files with 87 additions and 78 deletions
|
|
@ -28,7 +28,8 @@ struct bNodeType;
|
|||
struct bNodeSocketType;
|
||||
} // namespace bke
|
||||
|
||||
#define NODE_GRID_STEP_SIZE (20.0f * UI_SCALE_FAC) /* Based on the grid nodes snap to. */
|
||||
#define NODE_GRID_UNIT 20.0f
|
||||
#define NODE_GRID_STEP_SIZE (NODE_GRID_UNIT * UI_SCALE_FAC) /* Size of node snap grid. */
|
||||
#define NODE_EDGE_PAN_INSIDE_PAD 2
|
||||
#define NODE_EDGE_PAN_OUTSIDE_PAD 0 /* Disable clamping for node panning, use whole screen. */
|
||||
#define NODE_EDGE_PAN_SPEED_RAMP 1
|
||||
|
|
|
|||
|
|
@ -53,37 +53,33 @@
|
|||
|
||||
namespace blender {
|
||||
|
||||
const bNodeSocket &NodeAndSocket::find_socket_in_node(const bNode &other_node) const
|
||||
const bNodeSocket *NodeAndSocket::find_socket_in_node(const bNode &other_node) const
|
||||
{
|
||||
/* Don't use "by_identifier" functions of bNode because they depend on valid topology cache. */
|
||||
ListBaseT<bNodeSocket> sockets = (this->in_out == SOCK_IN) ? other_node.inputs :
|
||||
other_node.outputs;
|
||||
const bNodeSocket *socket = reinterpret_cast<bNodeSocket *>(BLI_findstring(
|
||||
return reinterpret_cast<bNodeSocket *>(BLI_findstring(
|
||||
&sockets, this->socket_identifier.c_str(), offsetof(bNodeSocket, identifier)));
|
||||
BLI_assert(socket != nullptr);
|
||||
return *socket;
|
||||
}
|
||||
|
||||
bNodeSocket &NodeAndSocket::find_socket_in_node(bNode &other_node) const
|
||||
bNodeSocket *NodeAndSocket::find_socket_in_node(bNode &other_node) const
|
||||
{
|
||||
return const_cast<bNodeSocket &>(
|
||||
return const_cast<bNodeSocket *>(
|
||||
this->find_socket_in_node(const_cast<const bNode &>(other_node)));
|
||||
}
|
||||
|
||||
const bNodeSocket &MutableNodeAndSocket::find_socket_in_node(const bNode &other_node) const
|
||||
const bNodeSocket *MutableNodeAndSocket::find_socket_in_node(const bNode &other_node) const
|
||||
{
|
||||
/* Don't use "by_identifier" functions of bNode because they depend on valid topology cache. */
|
||||
ListBaseT<bNodeSocket> sockets = (this->in_out == SOCK_IN) ? other_node.inputs :
|
||||
other_node.outputs;
|
||||
const bNodeSocket *socket = reinterpret_cast<bNodeSocket *>(BLI_findstring(
|
||||
return reinterpret_cast<bNodeSocket *>(BLI_findstring(
|
||||
&sockets, this->socket_identifier.c_str(), offsetof(bNodeSocket, identifier)));
|
||||
BLI_assert(socket != nullptr);
|
||||
return *socket;
|
||||
}
|
||||
|
||||
bNodeSocket &MutableNodeAndSocket::find_socket_in_node(bNode &other_node) const
|
||||
bNodeSocket *MutableNodeAndSocket::find_socket_in_node(bNode &other_node) const
|
||||
{
|
||||
return const_cast<bNodeSocket &>(
|
||||
return const_cast<bNodeSocket *>(
|
||||
this->find_socket_in_node(const_cast<const bNode &>(other_node)));
|
||||
}
|
||||
|
||||
|
|
@ -397,9 +393,11 @@ void NodeSetInterfaceBuilder::expose_socket(const bNodeSocket &src_socket,
|
|||
if (use_external_socket_key) {
|
||||
/* Create a unique interface socket for each external link. */
|
||||
for (const MutableNodeAndSocket &external_socket : external_links) {
|
||||
if (InterfaceSocketData *data = try_add_socket_data(external_socket.find_socket())) {
|
||||
data->internal_sockets.add({src_socket.owner_node(), src_socket, false});
|
||||
data->external_sockets.add(external_socket);
|
||||
if (const bNodeSocket *socket = external_socket.find_socket()) {
|
||||
if (InterfaceSocketData *data = try_add_socket_data(*socket)) {
|
||||
data->internal_sockets.add({src_socket.owner_node(), src_socket, false});
|
||||
data->external_sockets.add(external_socket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -816,8 +814,12 @@ GroupInputOutputNodes connect_copied_nodes_to_interface(const bContext &C,
|
|||
for (const auto &item : io_mapping.socket_data.items()) {
|
||||
for (const NodeAndSocket &origin : item.value.internal_sockets) {
|
||||
bNode &new_node = *copied_nodes.node_map().lookup(&origin.node);
|
||||
bNodeSocket &new_socket = origin.find_socket_in_node(new_node);
|
||||
if (new_socket.is_input()) {
|
||||
bNodeSocket *new_socket = origin.find_socket_in_node(new_node);
|
||||
/* Some nodes change after unlinking (e.g. viewers), socket may not exist any more. */
|
||||
if (!new_socket) {
|
||||
continue;
|
||||
}
|
||||
if (new_socket->is_input()) {
|
||||
bNodeSocket *group_input_socket = node_group_input_find_socket(io_nodes.input_node,
|
||||
item.key->identifier);
|
||||
BLI_assert(group_input_socket);
|
||||
|
|
@ -826,7 +828,7 @@ GroupInputOutputNodes connect_copied_nodes_to_interface(const bContext &C,
|
|||
*io_nodes.input_node,
|
||||
*group_input_socket,
|
||||
new_node,
|
||||
new_socket,
|
||||
*new_socket,
|
||||
origin.link_muted,
|
||||
origin.multi_input_sort_id);
|
||||
}
|
||||
|
|
@ -837,7 +839,7 @@ GroupInputOutputNodes connect_copied_nodes_to_interface(const bContext &C,
|
|||
add_link_and_make_visible(tree,
|
||||
links_by_socket,
|
||||
new_node,
|
||||
new_socket,
|
||||
*new_socket,
|
||||
*io_nodes.output_node,
|
||||
*group_output_socket,
|
||||
origin.link_muted,
|
||||
|
|
@ -896,9 +898,10 @@ static bool any_link_need_conversion(const Span<MutableNodeAndSocket> links,
|
|||
/* A proxy is needed if any internal or external connection has a different type and therefore
|
||||
* cannot directly be connected without loss of conversion. */
|
||||
for (const MutableNodeAndSocket &in_link : links) {
|
||||
const bNodeSocket &in_socket = in_link.find_socket();
|
||||
if (socket_types_need_conversion(in_socket.idname, io_socket.socket_type)) {
|
||||
return true;
|
||||
if (const bNodeSocket *in_socket = in_link.find_socket()) {
|
||||
if (socket_types_need_conversion(in_socket->idname, io_socket.socket_type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -1159,15 +1162,19 @@ InterfaceProxyNodes connect_copied_nodes_to_external_sockets(
|
|||
|
||||
/* Map the old internal to the new socket in the target tree. */
|
||||
bNode &new_node = *copied_nodes.node_map().lookup_default(&origin.node, nullptr);
|
||||
bNodeSocket &new_socket = origin.find_socket_in_node(new_node);
|
||||
bNodeSocket *new_socket = origin.find_socket_in_node(new_node);
|
||||
/* Some nodes change after unlinking (e.g. viewers), socket may not exist any more. */
|
||||
if (!new_socket) {
|
||||
continue;
|
||||
}
|
||||
if (is_input) {
|
||||
outgoing_links.append(
|
||||
{new_node, new_socket, origin.link_muted, origin.multi_input_sort_id});
|
||||
{new_node, *new_socket, origin.link_muted, origin.multi_input_sort_id});
|
||||
}
|
||||
else {
|
||||
/* Outputs shouldn't have multi-input sort ids. */
|
||||
BLI_assert(!origin.multi_input_sort_id.has_value());
|
||||
incoming_links.append({new_node, new_socket, origin.link_muted});
|
||||
incoming_links.append({new_node, *new_socket, origin.link_muted});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1191,14 +1198,18 @@ InterfaceProxyNodes connect_copied_nodes_to_external_sockets(
|
|||
const bool link_muted = item.first.link_muted || item.second.link_muted;
|
||||
/* Outputs shouldn't have multi-input sort ids. */
|
||||
BLI_assert(!item.first.multi_input_sort_id.has_value());
|
||||
add_link_and_make_visible(dst_tree,
|
||||
links_by_socket,
|
||||
item.first.node,
|
||||
item.first.find_socket(),
|
||||
item.second.node,
|
||||
item.second.find_socket(),
|
||||
link_muted,
|
||||
item.second.multi_input_sort_id);
|
||||
bNodeSocket *from_socket = item.first.find_socket();
|
||||
bNodeSocket *to_socket = item.second.find_socket();
|
||||
if (from_socket && to_socket) {
|
||||
add_link_and_make_visible(dst_tree,
|
||||
links_by_socket,
|
||||
item.first.node,
|
||||
*from_socket,
|
||||
item.second.node,
|
||||
*to_socket,
|
||||
link_muted,
|
||||
item.second.multi_input_sort_id);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_animdata_copy_by_basepath(
|
||||
|
|
@ -1235,14 +1246,16 @@ void connect_group_node_to_external_sockets(bNode &group_node,
|
|||
}
|
||||
for (const MutableNodeAndSocket &link : data->external_sockets) {
|
||||
BLI_assert(owner_tree.all_nodes().contains(&link.node));
|
||||
add_link_and_make_visible(owner_tree,
|
||||
links_by_socket,
|
||||
link.node,
|
||||
link.find_socket(),
|
||||
group_node,
|
||||
*group_node_input,
|
||||
link.link_muted,
|
||||
std::nullopt);
|
||||
if (bNodeSocket *link_socket = link.find_socket()) {
|
||||
add_link_and_make_visible(owner_tree,
|
||||
links_by_socket,
|
||||
link.node,
|
||||
*link_socket,
|
||||
group_node,
|
||||
*group_node_input,
|
||||
link.link_muted,
|
||||
std::nullopt);
|
||||
}
|
||||
}
|
||||
/* Keep old socket visibility. */
|
||||
SET_FLAG_FROM_TEST(group_node_input->flag, data->hidden, SOCK_HIDDEN);
|
||||
|
|
@ -1260,14 +1273,16 @@ void connect_group_node_to_external_sockets(bNode &group_node,
|
|||
}
|
||||
for (const MutableNodeAndSocket &link : data->external_sockets) {
|
||||
BLI_assert(owner_tree.all_nodes().contains(&link.node));
|
||||
add_link_and_make_visible(owner_tree,
|
||||
links_by_socket,
|
||||
group_node,
|
||||
*group_node_output,
|
||||
link.node,
|
||||
link.find_socket(),
|
||||
link.link_muted,
|
||||
link.multi_input_sort_id);
|
||||
if (bNodeSocket *link_socket = link.find_socket()) {
|
||||
add_link_and_make_visible(owner_tree,
|
||||
links_by_socket,
|
||||
group_node,
|
||||
*group_node_output,
|
||||
link.node,
|
||||
*link_socket,
|
||||
link.link_muted,
|
||||
link.multi_input_sort_id);
|
||||
}
|
||||
}
|
||||
/* Keep old socket visibility. */
|
||||
SET_FLAG_FROM_TEST(group_node_output->flag, data->hidden, SOCK_HIDDEN);
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ float nearest_node_grid_coord(float co)
|
|||
{
|
||||
/* Size and location of nodes are independent of UI scale, so grid size should be independent of
|
||||
* UI scale as well. */
|
||||
float grid_size = grid_size_get() / UI_SCALE_FAC;
|
||||
float grid_size = NODE_GRID_UNIT;
|
||||
float rest = fmod(co, grid_size);
|
||||
float offset = rest - grid_size / 2 >= 0 ? grid_size : 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -97,10 +97,10 @@ struct NodeAndSocket {
|
|||
return in_out == SOCK_OUT;
|
||||
}
|
||||
|
||||
const bNodeSocket &find_socket_in_node(const bNode &other_node) const;
|
||||
bNodeSocket &find_socket_in_node(bNode &other_node) const;
|
||||
const bNodeSocket *find_socket_in_node(const bNode &other_node) const;
|
||||
bNodeSocket *find_socket_in_node(bNode &other_node) const;
|
||||
|
||||
const bNodeSocket &find_socket() const
|
||||
const bNodeSocket *find_socket() const
|
||||
{
|
||||
return find_socket_in_node(this->node);
|
||||
}
|
||||
|
|
@ -174,10 +174,10 @@ struct MutableNodeAndSocket {
|
|||
return in_out == SOCK_OUT;
|
||||
}
|
||||
|
||||
const bNodeSocket &find_socket_in_node(const bNode &other_node) const;
|
||||
bNodeSocket &find_socket_in_node(bNode &other_node) const;
|
||||
const bNodeSocket *find_socket_in_node(const bNode &other_node) const;
|
||||
bNodeSocket *find_socket_in_node(bNode &other_node) const;
|
||||
|
||||
bNodeSocket &find_socket() const
|
||||
bNodeSocket *find_socket() const
|
||||
{
|
||||
return find_socket_in_node(this->node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
b.use_custom_socket_order();
|
||||
b.allow_any_socket_order();
|
||||
|
||||
b.add_input<decl::Geometry>("Target"_ustr);
|
||||
auto &target_geo = b.add_input<decl::Geometry>("Target"_ustr);
|
||||
b.add_output<decl::Geometry>("Target"_ustr).align_with_previous().propagate_all_geometry();
|
||||
b.add_output<decl::String>("Transferred Names"_ustr)
|
||||
.structure_type(StructureType::List)
|
||||
|
|
@ -40,10 +40,10 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
|
||||
for (BaseSocketDeclarationBuilder *socket : sockets) {
|
||||
socket->default_input_type(NODE_DEFAULT_INPUT_INDEX_FIELD);
|
||||
socket->structure_type(StructureType::Field);
|
||||
socket->evaluated_geometry_field({target_geo.index()});
|
||||
}
|
||||
}
|
||||
b.add_input<decl::Geometry>("Source"_ustr);
|
||||
auto &source_geo = b.add_input<decl::Geometry>("Source"_ustr);
|
||||
{
|
||||
auto &p = b.add_panel("Source IDs"_ustr).default_closed(true);
|
||||
Vector<BaseSocketDeclarationBuilder *> sockets;
|
||||
|
|
@ -56,7 +56,7 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
|
||||
for (BaseSocketDeclarationBuilder *socket : sockets) {
|
||||
socket->default_input_type(NODE_DEFAULT_INPUT_INDEX_FIELD);
|
||||
socket->structure_type(StructureType::Field);
|
||||
socket->evaluated_geometry_field({source_geo.index()});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d9044d14df274a4d9df0e12f3a66fc00ecabb2cb86b5eed33de7c2a45eaec605
|
||||
size 336847
|
||||
oid sha256:5cd9cb11dbb559a807c3915aa8de6ac1c5a1d1c4bd02b80b6038322a356b187a
|
||||
size 341071
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ from mathutils import Vector
|
|||
|
||||
import bpy
|
||||
|
||||
# To update the test data, set the `BLENDER_TEST_UPDATE` environment variable:
|
||||
# `BLENDER_TEST_UPDATE=1 ctest -R bl_node_copy_operators`
|
||||
#
|
||||
# Test cases listed below must have a test data in the "Tests" node group in the main test file.
|
||||
# Each test case should have a frame node whose content is used as input for operators.
|
||||
# Nodes labeled "external" are excluded from the grouping operator to test external links.
|
||||
|
|
@ -27,13 +30,6 @@ import bpy
|
|||
# - bpy.data.node_groups["ExpectedUngroup"]: Result of node.ungroup operator.
|
||||
# - bpy.data.node_groups["ExpectedGroupSeparateCopy"]: Result of node.group_separate operator with type='COPY'.
|
||||
# - bpy.data.node_groups["ExpectedGroupSeparateMove"]: Result of node.group_separate operator with type='MOVE'.
|
||||
#
|
||||
# The script can be invoked with an additional argument '--generate' to update the ground truth test data.
|
||||
# Nodes in the "Expected***" node trees are replaced with the result of operators applied to the "Tests" node tree.
|
||||
#
|
||||
# ./bin/blender --factory-startup --python <SOURCEPATH>/tests/python/bl_node_copy_operators.py
|
||||
# --
|
||||
# --testdir <SOURCEPATH>/tests/files/node_group --generate
|
||||
|
||||
args = None
|
||||
testfile = "node_copy_operators.blend"
|
||||
|
|
@ -65,6 +61,7 @@ all_test_cases = [
|
|||
('test_insert_group_with_sockets', {'GROUP_INSERT'}),
|
||||
('test_ungroup_multiple', {'NODE_GROUP'}),
|
||||
('test_ungroup_proxy_nodes', {'NODE_GROUP'}),
|
||||
('test_viewer_node', {}),
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -404,7 +401,6 @@ class AbstractNodeCopyOperatorTest(unittest.TestCase):
|
|||
self.assertTrue(args.testdir.exists(),
|
||||
'Test dir {0} should exist'.format(args.testdir))
|
||||
open_test_file()
|
||||
self.assertEqual(bpy.data.version, (5, 2, 5))
|
||||
|
||||
def tearDown(self):
|
||||
self._tempdir.cleanup()
|
||||
|
|
@ -632,6 +628,7 @@ def generate_test_data():
|
|||
def main():
|
||||
global args
|
||||
import argparse
|
||||
import os
|
||||
|
||||
if '--' in sys.argv:
|
||||
argv = [sys.argv[0]] + sys.argv[sys.argv.index('--') + 1:]
|
||||
|
|
@ -640,17 +637,13 @@ def main():
|
|||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--testdir', required=True, type=pathlib.Path)
|
||||
parser.add_argument(
|
||||
'--generate',
|
||||
action='store_true',
|
||||
help="Generate ground truth test data instead of running the test")
|
||||
parser.add_argument('--subtest', default=None, help="Select a single test case")
|
||||
args, remaining = parser.parse_known_args(argv)
|
||||
|
||||
if args.generate:
|
||||
if os.getenv("BLENDER_TEST_UPDATE") is not None:
|
||||
generate_test_data()
|
||||
else:
|
||||
unittest.main(argv=remaining)
|
||||
|
||||
unittest.main(argv=remaining)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue