[Bf-blender-cvs] [6a6a7ebd50f] builtin-simulation-nodes: move builtin node group code to separate file

Jacques Lucke noreply at git.blender.org
Mon Mar 23 13:28:24 CET 2020


Commit: 6a6a7ebd50f0d3bbb2189ceec707e6e57905292d
Author: Jacques Lucke
Date:   Mon Mar 23 11:37:17 2020 +0100
Branches: builtin-simulation-nodes
https://developer.blender.org/rB6a6a7ebd50f0d3bbb2189ceec707e6e57905292d

move builtin node group code to separate file

===================================================================

A	release/scripts/modules/builtin_node_groups.py
M	release/scripts/startup/bl_operators/node.py

===================================================================

diff --git a/release/scripts/modules/builtin_node_groups.py b/release/scripts/modules/builtin_node_groups.py
new file mode 100644
index 00000000000..12d892529b2
--- /dev/null
+++ b/release/scripts/modules/builtin_node_groups.py
@@ -0,0 +1,260 @@
+import os
+import bpy
+import json
+
+
+def get_socket_value(sock):
+    if sock.type in {"VALUE", "INT", "BOOLEAN", "STRING"}:
+        return sock.default_value
+    elif sock.type in {"VECTOR", "RGBA"}:
+        return tuple(sock.default_value)
+    else:
+        return None
+
+def insert_socket_data(sock_data, sock):
+    sock_data["name"] = sock.name
+    sock_data["identifier"] = sock.identifier
+    sock_data["default_value"] = get_socket_value(sock)
+    sock_data["type"] = sock.type
+
+def insert_group_interface(json_data, group):
+    for sock in group.inputs:
+        sock_data = {}
+        insert_socket_data(sock_data, sock)
+        sock_data["bl_socket_idname"] = sock.bl_socket_idname
+        json_data["inputs"].append(sock_data)
+
+    for sock in group.outputs:
+        sock_data = {}
+        insert_socket_data(sock_data, sock)
+        sock_data["bl_socket_idname"] = sock.bl_socket_idname
+        json_data["outputs"].append(sock_data)
+
+def insert_node_data(node_data, node):
+    node_data["name"] = node.name
+    node_data["bl_idname"] = node.bl_idname
+    node_data["location"] = tuple(map(int, node.location))
+    node_data["width"] = int(node.width)
+
+    # Don't compute this only once in the beginning, because addons might register more properties.
+    base_node_property_names = {prop.identifier for prop in bpy.types.Node.bl_rna.properties}
+
+    if node.bl_idname in {"NodeGroupInput", "NodeGroupOutput"}:
+        pass
+    elif node.bl_idname == "SimulationNodeGroup":
+        node_data["group_name"] = getattr(node.node_tree, "name", None)
+    else:
+        node_data["properties"] = {}
+        for prop in node.bl_rna.properties:
+            if prop.identifier not in base_node_property_names:
+                node_data["properties"][prop.identifier] = getattr(node, prop.identifier)
+
+        node_data["inputs"] = []
+        node_data["outputs"] = []
+        for sock in node.inputs:
+            sock_data = {}
+            insert_socket_data(sock_data, sock)
+            node_data["inputs"].append(sock_data)
+        for sock in node.outputs:
+            sock_data = {}
+            insert_socket_data(sock_data, sock)
+            node_data["outputs"].append(sock_data)
+
+def insert_nodes_data(json_data, group):
+    for node in group.nodes:
+        node_data = {}
+        insert_node_data(node_data, node)
+        json_data["nodes"].append(node_data)
+
+def insert_links_data(json_data, group):
+    for link in group.links:
+        link_data = {}
+        link_data["from"] = [link.from_node.name, link.from_socket.identifier, list(link.from_node.outputs).index(link.from_socket)]
+        link_data["to"] = [link.to_node.name, link.to_socket.identifier, list(link.to_node.inputs).index(link.to_socket)]
+        json_data["links"].append(link_data)
+
+def find_direct_dependency_groups(group):
+    dependencies = set()
+    for node in group.nodes:
+        if node.bl_idname == "SimulationNodeGroup":
+            if node.node_tree is not None:
+                dependencies.add(node.node_tree)
+    return dependencies
+
+def insert_dependencies(json_data, group):
+    dependency_names = [dependency.name for dependency in find_direct_dependency_groups(group)]
+    json_data["dependencies"] = dependency_names
+
+def node_group_to_json_data(group):
+    json_data = {}
+    json_data["blender_version"] = bpy.app.version
+    json_data["name"] = group.name
+    json_data["inputs"] = []
+    json_data["outputs"] = []
+    json_data["nodes"] = []
+    json_data["links"] = []
+
+    insert_group_interface(json_data, group)
+    insert_nodes_data(json_data, group)
+    insert_links_data(json_data, group)
+    insert_dependencies(json_data, group)
+
+    return json_data
+
+def save_group_as_json(group, file_path):
+    json_data = node_group_to_json_data(group)
+    json_str = json.dumps(json_data, indent=1)
+    os.makedirs(os.path.dirname(file_path), exist_ok=True)
+    with open(file_path, "w") as f:
+        f.write(json_str)
+
+
+builtin_node_group_directory = os.path.join(bpy.utils.resource_path("LOCAL"), "datafiles", "node_groups")
+
+def group_name_to_file_name(group_name):
+    return group_name.replace(" ", "_") + ".json"
+
+def file_name_to_group_name(file_name):
+    return file_name.replace("_", " ")[:-len(".json")]
+
+def group_name_to_file_path(group_name):
+    file_name = group_name_to_file_name(group_name)
+    return os.path.join(builtin_node_group_directory, file_name)
+
+def property_has_given_value(owner, prop_name, value):
+    prop = owner.bl_rna.properties[prop_name]
+    if prop.type in {'BOOLEAN', 'INT', 'STRING', 'ENUM'}:
+        return getattr(owner, prop_name) == value
+    elif prop.type == 'FLOAT':
+        if prop.array_length <= 1:
+            return getattr(owner, prop_name) == value
+        else:
+            return tuple(getattr(owner, prop_name)) == tuple(value)
+    else:
+        assert False
+
+def group_matches_json_data(group, json_data, loaded_group_by_name, json_data_by_group_name):
+    if len(group.nodes) != len(json_data["nodes"]):
+        return False
+    if len(group.links) != len(json_data["links"]):
+        return False
+    if len(group.inputs) != len(json_data["inputs"]):
+        return False
+    if len(group.outputs) != len(json_data["outputs"]):
+        return False
+
+    for node_data in json_data["nodes"]:
+        node = group.nodes.get(node_data["name"])
+        if node is None:
+            return False
+        if node.bl_idname != node_data["bl_idname"]:
+            return False
+
+        if node.bl_idname in {"NodeGroupInput", "NodeGroupOutput"}:
+            pass
+        elif node.bl_idname == "SimulationNodeGroup":
+            if node.node_tree is None:
+                return False
+            elif node.node_tree == loaded_group_by_name[node_data["group_name"]]:
+                pass
+            elif not group_matches_json_data(node.node_tree,
+                                             json_data_by_group_name[node_data["group_name"]],
+                                             loaded_group_by_name,
+                                             json_data_by_group_name):
+                return False
+
+        else:
+            for key, value in node_data["properties"].items():
+                if getattr(node, key) != value:
+                    return False
+            if len(node.inputs) != len(node_data["inputs"]):
+                return False
+            if len(node.outputs) != len(node_data["outputs"]):
+                return False
+            for sock_data, sock in zip(node_data["inputs"], node.inputs):
+                if hasattr(sock, "default_value"):
+                    if not property_has_given_value(sock, "default_value", sock_data["default_value"]):
+                        return False
+
+    for sock_data, sock in zip(json_data["inputs"], group.inputs):
+        if sock_data["bl_socket_idname"] != sock.bl_socket_idname:
+            return False
+        if sock_data["name"] != sock.name:
+            return False
+
+    for sock_data, sock in zip(json_data["outputs"], group.outputs):
+        if sock_data["bl_socket_idname"] != sock.bl_socket_idname:
+            return False
+        if sock_data["name"] != sock.name:
+            return False
+
+    link_cache = set()
+    for link in group.links:
+        link_cache.add((
+            link.from_node.name, list(link.from_node.outputs).index(link.from_socket),
+            link.to_node.name, list(link.to_node.inputs).index(link.to_socket)))
+    for link_data in json_data["links"]:
+        if (link_data["from"][0], link_data["from"][2], link_data["to"][0], link_data["to"][2]) not in link_cache:
+            return False
+
+    return True
+
+def get_or_create_node_group(json_data, loaded_group_by_name, json_data_by_group_name):
+    for potential_group in bpy.data.node_groups:
+        if group_matches_json_data(potential_group, json_data, loaded_group_by_name, json_data_by_group_name):
+            return potential_group
+
+    group = bpy.data.node_groups.new(json_data["name"], "SimulationNodeTree")
+
+    for node_data in json_data["nodes"]:
+        node = group.nodes.new(node_data["bl_idname"])
+        node.name = node_data["name"]
+        node.location = node_data["location"]
+        node.select = False
+        node.width = node_data["width"]
+
+        if node.bl_idname in {"NodeGroupInput", "NodeGroupOutput"}:
+            pass
+        elif node.bl_idname == "SimulationNodeGroup":
+            node.node_tree = loaded_group_by_name[node_data["group_name"]]
+        else:
+            for key, value in node_data["properties"].items():
+                setattr(node, key, value)
+
+            for sock_data, sock in zip(node_data["inputs"], node.inputs):
+                if hasattr(sock, "default_value"):
+                    sock.default_value = sock_data["default_value"]
+
+    for sock_data in json_data["inputs"]:
+        group.inputs.new(sock_data["bl_socket_idname"], sock_data["name"])
+
+    for sock_data in json_data["outputs"]:
+        group.outputs.new(sock_data["bl_socket_idname"], sock_data["name"])
+
+    for link_data in json_data["links"]:
+        from_socket = group.nodes[link_data["from"][0]].outputs[link_data["from"][2]]
+        to_socket = group.nodes[link_data["to"][0]].inputs[link_data["to"][2]]
+        group.links.new(from_socket, to_socket)
+
+    return group
+
+from collections import OrderedDict
+
+def get_json_data_for_all_groups_to_load(main_group_name):
+    json_data_by_group_name = OrderedDict()
+
+    def load(group_name):
+        if group_name in json_data_by_group_name:
+            return
+        else:
+            file_path = group_name_to_file_path(group_name)
+            with open(file_path, "r") as f:
+                json_str = f.read()
+            json_data = json.loads(json_str)
+            assert group_name == json_data["name"]
+            for dependency_n

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list