Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 12 additions & 138 deletions geo_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@

from .utils import *

#node tree input sockets that have default properties
default_sockets = {'VALUE', 'INT', 'BOOLEAN', 'VECTOR', 'RGBA'}

geo_node_settings = {
# Attribute nodes
"GeometryNodeAttributeStatistic" : ["data_type", "domain"],
Expand Down Expand Up @@ -212,14 +209,14 @@ def execute(self, context):
used_vars = set()

def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
node_tree_var = create_var(node_tree.name, used_vars)
nt_var = create_var(node_tree.name, used_vars)

outer, inner = make_indents(level)

#initialize node group
file.write(f"{outer}#initialize {node_tree_var} node group\n")
file.write(f"{outer}def {node_tree_var}_node_group():\n")
file.write((f"{inner}{node_tree_var}"
file.write(f"{outer}#initialize {nt_var} node group\n")
file.write(f"{outer}def {nt_var}_node_group():\n")
file.write((f"{inner}{nt_var}"
f"= bpy.data.node_groups.new("
f"type = \"GeometryNodeTree\", "
f"name = \"{node_tree.name}\")\n"))
Expand All @@ -229,7 +226,7 @@ def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
outputs_set = False

#initialize nodes
file.write(f"{inner}#initialize {node_tree_var} nodes\n")
file.write(f"{inner}#initialize {nt_var} nodes\n")

sim_inputs = []

Expand All @@ -241,138 +238,15 @@ def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
used_vars)
node_trees.add(node_nt)
elif node.bl_idname == 'NodeGroupInput' and not inputs_set:
file.write(f"{inner}#{node_tree_var} inputs\n")
for i, input in enumerate(node.outputs):
if input.bl_idname != "NodeSocketVirtual":
file.write(f"{inner}#input {input.name}\n")
file.write((f"{inner}{node_tree_var}.inputs.new"
f"(\"{input.bl_idname}\", "
f"\"{input.name}\")\n"))
socket = node_tree.inputs[i]
if input.type in default_sockets:
if input.type == 'RGBA':
dv = vec4_to_py_str(socket.default_value)
elif input.type == 'VECTOR':
dv = vec3_to_py_str(socket.default_value)
else:
dv = socket.default_value

#default value
file.write((f"{inner}{node_tree_var}"
f".inputs[{i}]"
f".default_value = {dv}\n"))

#min value
if hasattr(socket, "min_value"):
file.write((f"{inner}{node_tree_var}"
f".inputs[{i}]"
f".min_value = "
f"{socket.min_value}\n"))
#max value
if hasattr(socket, "max_value"):
file.write((f"{inner}{node_tree_var}"
f".inputs[{i}]"
f".max_value = "
f"{socket.max_value}\n"))
#default attribute name
if hasattr(socket, "default_attribute_name"):
if socket.default_attribute_name != "":
file.write((f"{inner}{node_tree_var}"
f".inputs[{i}]"
f".default_attribute_name = \""
f"{socket.default_attribute_name}"
f"\"\n"))
#description
if socket.description != "":
file.write((f"{inner}{node_tree_var}"
f".inputs[{i}]"
f".description = "
f"\"{socket.description}\"\n"))
#hide value
if socket.hide_value is True:
file.write((f"{inner}{node_tree_var}"
f".inputs[{i}]"
f".hide_value = "
f"{socket.hide_value}\n"))

#hide in modifier
if hasattr(socket, "hide_in_modifier"):
if socket.hide_in_modifier is True:
file.write((f"{inner}{node_tree_var}"
f".inputs[{i}]"
f".hide_in_modifier = "
f"{socket.hide_in_modifier}\n"))
file.write("\n")
file.write("\n")
group_io_settings(node, file, inner, "input", nt_var, node_tree)
inputs_set = True

elif node.bl_idname == 'NodeGroupOutput' and not outputs_set:
file.write(f"{inner}#{node_tree_var} outputs\n")
for i, output in enumerate(node.inputs):
if output.bl_idname != 'NodeSocketVirtual':
file.write((f"{inner}{node_tree_var}.outputs"
f".new(\"{output.bl_idname}\", "
f"\"{output.name}\")\n"))

socket = node_tree.outputs[i]
if output.type in default_sockets:
if output.type == 'RGBA':
dv = vec4_to_py_str(socket.default_value)
elif output.type == 'VECTOR':
dv = vec3_to_py_str(socket.default_value)
else:
dv = socket.default_value

#default value
file.write((f"{inner}{node_tree_var}"
f".outputs[{i}]"
f".default_value = {dv}\n"))

#min value
if hasattr(socket, "min_value"):
file.write((f"{inner}{node_tree_var}"
f".outputs[{i}]"
f".min_value = "
f"{socket.min_value}\n"))
#max value
if hasattr(socket, "max_value"):
file.write((f"{inner}{node_tree_var}"
f".outputs[{i}]"
f".max_value = "
f"{socket.max_value}\n"))
#description
if socket.description != "":
file.write((f"{inner}{node_tree_var}"
f".outputs[{i}]"
f".description = "
f"\"{socket.description}\"\n"))
#hide value
if socket.hide_value is True:
file.write((f"{inner}{node_tree_var}"
f".outputs[{i}]"
f".hide_value = "
f"{socket.hide_value}\n"))

#default attribute name
if hasattr(socket, "default_attribute_name"):
if socket.default_attribute_name != "":
file.write((f"{inner}{node_tree_var}"
f".outputs[{i}]"
f".default_attribute_name = \""
f"{socket.default_attribute_name}"
f"\"\n"))
#attribute domain
if hasattr(socket, "attribute_domain"):
file.write((f"{inner}{node_tree_var}"
f".outputs[{i}]"
f".attribute_domain = "
f"\'{socket.attribute_domain}\'\n"))

file.write("\n")
group_io_settings(node, file, inner, "output", nt_var, node_tree)
outputs_set = True

#create node
node_var = create_node(node, file, inner, node_tree_var,
node_var = create_node(node, file, inner, nt_var,
node_vars, used_vars)
set_settings_defaults(node, geo_node_settings, file, inner,
node_var)
Expand Down Expand Up @@ -428,13 +302,13 @@ def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
set_locations(node_tree, file, inner, node_vars)
set_dimensions(node_tree, file, inner, node_vars)

init_links(node_tree, file, inner, node_tree_var, node_vars)
init_links(node_tree, file, inner, nt_var, node_vars)

file.write(f"{inner}return {node_tree_var}\n")
file.write(f"{inner}return {nt_var}\n")

#create node group
file.write((f"\n{outer}{node_tree_var} = "
f"{node_tree_var}_node_group()\n\n"))
file.write((f"\n{outer}{nt_var} = "
f"{nt_var}_node_group()\n\n"))
return used_vars

process_geo_nodes_group(nt, 2, node_vars, used_vars)
Expand Down
10 changes: 10 additions & 0 deletions materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
f"name = \"{nt_name}\")\n"))
file.write("\n")

inputs_set = False
outputs_set = False

#initialize nodes
file.write(f"{inner}#initialize {nt_var} nodes\n")

Expand All @@ -177,6 +180,13 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
file.write((f"{inner}{node_var}.node_tree = "
f"bpy.data.node_groups"
f"[\"{node.node_tree.name}\"]\n"))
elif node.bl_idname == 'NodeGroupInput' and not inputs_set:
group_io_settings(node, file, inner, "input", nt_var, node_tree)
inputs_set = True
elif node.bl_idname == 'NodeGroupOutput' and not outputs_set:
group_io_settings(node, file, inner, "output", nt_var, node_tree)
outputs_set = True

elif node.bl_idname in image_nodes:
img = node.image
if img.source in {'FILE', 'GENERATED', 'TILED'}:
Expand Down
69 changes: 69 additions & 0 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
'NodeSocketShader',
'NodeSocketVirtual'}

#node tree input sockets that have default properties
default_sockets = {'VALUE', 'INT', 'BOOLEAN', 'VECTOR', 'RGBA'}

def clean_string(string: str, lower: bool = True) -> str:
"""
Cleans up a string for use as a variable or file name
Expand Down Expand Up @@ -265,6 +268,72 @@ def hide_sockets(node, file: TextIO, inner: str, node_var: str):
if socket.hide is True:
file.write(f"{inner}{node_var}.outputs[{i}].hide = True\n")

def group_io_settings(node, file: TextIO, inner: str, io: str, node_tree_var: str, node_tree):
if io == "input":
ios = node.outputs
ntio = node_tree.inputs
else:
ios = node.inputs
ntio = node_tree.outputs
file.write(f"{inner}#{node_tree_var} {io}s\n")
for i, inout in enumerate(ios):
if inout.bl_idname == 'NodeSocketVirtual':
continue
file.write(f"{inner}#{io} {inout.name}\n")
idname = enum_to_py_str(inout.bl_idname)
name = str_to_py_str(inout.name)
file.write(f"{inner}{node_tree_var}.{io}s.new({idname}, {name})\n")
socket = ntio[i]
socket_var = f"{node_tree_var}.{io}s[{i}]"

print(f"{io} {i}: {name}")
if inout.type in default_sockets:
print(socket.default_value)
#default value
if inout.type == 'RGBA':
dv = vec4_to_py_str(socket.default_value)
elif inout.type == 'VECTOR':
dv = vec3_to_py_str(socket.default_value)
else:
dv = socket.default_value
file.write(f"{inner}{socket_var}.default_value = {dv}\n")

#min value
if hasattr(socket, "min_value"):
file.write(f"{inner}{socket_var}.min_value = {socket.min_value}\n")
#max value
if hasattr(socket, "min_value"):
file.write((f"{inner}{socket_var}.max_value = {socket.max_value}\n"))

#default attribute name
if hasattr(socket, "default_attribute_name"):
if socket.default_attribute_name != "":
dan = str_to_py_str(socket.default_attribute_name)
file.write((f"{inner}{socket_var}"
f".default_attribute_name = {dan}\n"))

#attribute domain
if hasattr(socket, "attribute_domain"):
ad = enum_to_py_str(socket.attribute_domain)
file.write(f"{inner}{socket_var}.attribute_domain = {ad}\n")

#tooltip
if socket.description != "":
description = str_to_py_str(socket.description)
file.write((f"{inner}{socket_var}.description = {description}\n"))

#hide_value
if socket.hide_value is True:
file.write(f"{inner}{socket_var}.hide_value = True\n")

#hide in modifier
if hasattr(socket, "hide_in_modifier"):
if socket.hide_in_modifier is True:
file.write(f"{inner}{socket_var}.hide_in_modifier = True\n")

file.write("\n")
file.write("\n")

def color_ramp_settings(node, file: TextIO, inner: str, node_var: str):
"""
Replicate a color ramp node
Expand Down