Skip to content

Commit 700ae47

Browse files
Merge pull request #51 from BrendanParmer/shader_node_group_fix
fix: added group io logic to shader nodes
2 parents 8cf57f2 + 9894c54 commit 700ae47

File tree

3 files changed

+91
-138
lines changed

3 files changed

+91
-138
lines changed

geo_nodes.py

Lines changed: 12 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
from .utils import *
55

6-
#node tree input sockets that have default properties
7-
default_sockets = {'VALUE', 'INT', 'BOOLEAN', 'VECTOR', 'RGBA'}
8-
96
geo_node_settings = {
107
# Attribute nodes
118
"GeometryNodeAttributeStatistic" : ["data_type", "domain"],
@@ -212,14 +209,14 @@ def execute(self, context):
212209
used_vars = set()
213210

214211
def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
215-
node_tree_var = create_var(node_tree.name, used_vars)
212+
nt_var = create_var(node_tree.name, used_vars)
216213

217214
outer, inner = make_indents(level)
218215

219216
#initialize node group
220-
file.write(f"{outer}#initialize {node_tree_var} node group\n")
221-
file.write(f"{outer}def {node_tree_var}_node_group():\n")
222-
file.write((f"{inner}{node_tree_var}"
217+
file.write(f"{outer}#initialize {nt_var} node group\n")
218+
file.write(f"{outer}def {nt_var}_node_group():\n")
219+
file.write((f"{inner}{nt_var}"
223220
f"= bpy.data.node_groups.new("
224221
f"type = \"GeometryNodeTree\", "
225222
f"name = \"{node_tree.name}\")\n"))
@@ -229,7 +226,7 @@ def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
229226
outputs_set = False
230227

231228
#initialize nodes
232-
file.write(f"{inner}#initialize {node_tree_var} nodes\n")
229+
file.write(f"{inner}#initialize {nt_var} nodes\n")
233230

234231
sim_inputs = []
235232

@@ -241,138 +238,15 @@ def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
241238
used_vars)
242239
node_trees.add(node_nt)
243240
elif node.bl_idname == 'NodeGroupInput' and not inputs_set:
244-
file.write(f"{inner}#{node_tree_var} inputs\n")
245-
for i, input in enumerate(node.outputs):
246-
if input.bl_idname != "NodeSocketVirtual":
247-
file.write(f"{inner}#input {input.name}\n")
248-
file.write((f"{inner}{node_tree_var}.inputs.new"
249-
f"(\"{input.bl_idname}\", "
250-
f"\"{input.name}\")\n"))
251-
socket = node_tree.inputs[i]
252-
if input.type in default_sockets:
253-
if input.type == 'RGBA':
254-
dv = vec4_to_py_str(socket.default_value)
255-
elif input.type == 'VECTOR':
256-
dv = vec3_to_py_str(socket.default_value)
257-
else:
258-
dv = socket.default_value
259-
260-
#default value
261-
file.write((f"{inner}{node_tree_var}"
262-
f".inputs[{i}]"
263-
f".default_value = {dv}\n"))
264-
265-
#min value
266-
if hasattr(socket, "min_value"):
267-
file.write((f"{inner}{node_tree_var}"
268-
f".inputs[{i}]"
269-
f".min_value = "
270-
f"{socket.min_value}\n"))
271-
#max value
272-
if hasattr(socket, "max_value"):
273-
file.write((f"{inner}{node_tree_var}"
274-
f".inputs[{i}]"
275-
f".max_value = "
276-
f"{socket.max_value}\n"))
277-
#default attribute name
278-
if hasattr(socket, "default_attribute_name"):
279-
if socket.default_attribute_name != "":
280-
file.write((f"{inner}{node_tree_var}"
281-
f".inputs[{i}]"
282-
f".default_attribute_name = \""
283-
f"{socket.default_attribute_name}"
284-
f"\"\n"))
285-
#description
286-
if socket.description != "":
287-
file.write((f"{inner}{node_tree_var}"
288-
f".inputs[{i}]"
289-
f".description = "
290-
f"\"{socket.description}\"\n"))
291-
#hide value
292-
if socket.hide_value is True:
293-
file.write((f"{inner}{node_tree_var}"
294-
f".inputs[{i}]"
295-
f".hide_value = "
296-
f"{socket.hide_value}\n"))
297-
298-
#hide in modifier
299-
if hasattr(socket, "hide_in_modifier"):
300-
if socket.hide_in_modifier is True:
301-
file.write((f"{inner}{node_tree_var}"
302-
f".inputs[{i}]"
303-
f".hide_in_modifier = "
304-
f"{socket.hide_in_modifier}\n"))
305-
file.write("\n")
306-
file.write("\n")
241+
group_io_settings(node, file, inner, "input", nt_var, node_tree)
307242
inputs_set = True
308243

309244
elif node.bl_idname == 'NodeGroupOutput' and not outputs_set:
310-
file.write(f"{inner}#{node_tree_var} outputs\n")
311-
for i, output in enumerate(node.inputs):
312-
if output.bl_idname != 'NodeSocketVirtual':
313-
file.write((f"{inner}{node_tree_var}.outputs"
314-
f".new(\"{output.bl_idname}\", "
315-
f"\"{output.name}\")\n"))
316-
317-
socket = node_tree.outputs[i]
318-
if output.type in default_sockets:
319-
if output.type == 'RGBA':
320-
dv = vec4_to_py_str(socket.default_value)
321-
elif output.type == 'VECTOR':
322-
dv = vec3_to_py_str(socket.default_value)
323-
else:
324-
dv = socket.default_value
325-
326-
#default value
327-
file.write((f"{inner}{node_tree_var}"
328-
f".outputs[{i}]"
329-
f".default_value = {dv}\n"))
330-
331-
#min value
332-
if hasattr(socket, "min_value"):
333-
file.write((f"{inner}{node_tree_var}"
334-
f".outputs[{i}]"
335-
f".min_value = "
336-
f"{socket.min_value}\n"))
337-
#max value
338-
if hasattr(socket, "max_value"):
339-
file.write((f"{inner}{node_tree_var}"
340-
f".outputs[{i}]"
341-
f".max_value = "
342-
f"{socket.max_value}\n"))
343-
#description
344-
if socket.description != "":
345-
file.write((f"{inner}{node_tree_var}"
346-
f".outputs[{i}]"
347-
f".description = "
348-
f"\"{socket.description}\"\n"))
349-
#hide value
350-
if socket.hide_value is True:
351-
file.write((f"{inner}{node_tree_var}"
352-
f".outputs[{i}]"
353-
f".hide_value = "
354-
f"{socket.hide_value}\n"))
355-
356-
#default attribute name
357-
if hasattr(socket, "default_attribute_name"):
358-
if socket.default_attribute_name != "":
359-
file.write((f"{inner}{node_tree_var}"
360-
f".outputs[{i}]"
361-
f".default_attribute_name = \""
362-
f"{socket.default_attribute_name}"
363-
f"\"\n"))
364-
#attribute domain
365-
if hasattr(socket, "attribute_domain"):
366-
file.write((f"{inner}{node_tree_var}"
367-
f".outputs[{i}]"
368-
f".attribute_domain = "
369-
f"\'{socket.attribute_domain}\'\n"))
370-
371-
file.write("\n")
245+
group_io_settings(node, file, inner, "output", nt_var, node_tree)
372246
outputs_set = True
373247

374248
#create node
375-
node_var = create_node(node, file, inner, node_tree_var,
249+
node_var = create_node(node, file, inner, nt_var,
376250
node_vars, used_vars)
377251
set_settings_defaults(node, geo_node_settings, file, inner,
378252
node_var)
@@ -428,13 +302,13 @@ def process_geo_nodes_group(node_tree, level, node_vars, used_vars):
428302
set_locations(node_tree, file, inner, node_vars)
429303
set_dimensions(node_tree, file, inner, node_vars)
430304

431-
init_links(node_tree, file, inner, node_tree_var, node_vars)
305+
init_links(node_tree, file, inner, nt_var, node_vars)
432306

433-
file.write(f"{inner}return {node_tree_var}\n")
307+
file.write(f"{inner}return {nt_var}\n")
434308

435309
#create node group
436-
file.write((f"\n{outer}{node_tree_var} = "
437-
f"{node_tree_var}_node_group()\n\n"))
310+
file.write((f"\n{outer}{nt_var} = "
311+
f"{nt_var}_node_group()\n\n"))
438312
return used_vars
439313

440314
process_geo_nodes_group(nt, 2, node_vars, used_vars)

materials.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
155155
f"name = \"{nt_name}\")\n"))
156156
file.write("\n")
157157

158+
inputs_set = False
159+
outputs_set = False
160+
158161
#initialize nodes
159162
file.write(f"{inner}#initialize {nt_var} nodes\n")
160163

@@ -177,6 +180,13 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
177180
file.write((f"{inner}{node_var}.node_tree = "
178181
f"bpy.data.node_groups"
179182
f"[\"{node.node_tree.name}\"]\n"))
183+
elif node.bl_idname == 'NodeGroupInput' and not inputs_set:
184+
group_io_settings(node, file, inner, "input", nt_var, node_tree)
185+
inputs_set = True
186+
elif node.bl_idname == 'NodeGroupOutput' and not outputs_set:
187+
group_io_settings(node, file, inner, "output", nt_var, node_tree)
188+
outputs_set = True
189+
180190
elif node.bl_idname in image_nodes:
181191
img = node.image
182192
if img.source in {'FILE', 'GENERATED', 'TILED'}:

utils.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
'NodeSocketShader',
1414
'NodeSocketVirtual'}
1515

16+
#node tree input sockets that have default properties
17+
default_sockets = {'VALUE', 'INT', 'BOOLEAN', 'VECTOR', 'RGBA'}
18+
1619
def clean_string(string: str, lower: bool = True) -> str:
1720
"""
1821
Cleans up a string for use as a variable or file name
@@ -265,6 +268,72 @@ def hide_sockets(node, file: TextIO, inner: str, node_var: str):
265268
if socket.hide is True:
266269
file.write(f"{inner}{node_var}.outputs[{i}].hide = True\n")
267270

271+
def group_io_settings(node, file: TextIO, inner: str, io: str, node_tree_var: str, node_tree):
272+
if io == "input":
273+
ios = node.outputs
274+
ntio = node_tree.inputs
275+
else:
276+
ios = node.inputs
277+
ntio = node_tree.outputs
278+
file.write(f"{inner}#{node_tree_var} {io}s\n")
279+
for i, inout in enumerate(ios):
280+
if inout.bl_idname == 'NodeSocketVirtual':
281+
continue
282+
file.write(f"{inner}#{io} {inout.name}\n")
283+
idname = enum_to_py_str(inout.bl_idname)
284+
name = str_to_py_str(inout.name)
285+
file.write(f"{inner}{node_tree_var}.{io}s.new({idname}, {name})\n")
286+
socket = ntio[i]
287+
socket_var = f"{node_tree_var}.{io}s[{i}]"
288+
289+
print(f"{io} {i}: {name}")
290+
if inout.type in default_sockets:
291+
print(socket.default_value)
292+
#default value
293+
if inout.type == 'RGBA':
294+
dv = vec4_to_py_str(socket.default_value)
295+
elif inout.type == 'VECTOR':
296+
dv = vec3_to_py_str(socket.default_value)
297+
else:
298+
dv = socket.default_value
299+
file.write(f"{inner}{socket_var}.default_value = {dv}\n")
300+
301+
#min value
302+
if hasattr(socket, "min_value"):
303+
file.write(f"{inner}{socket_var}.min_value = {socket.min_value}\n")
304+
#max value
305+
if hasattr(socket, "min_value"):
306+
file.write((f"{inner}{socket_var}.max_value = {socket.max_value}\n"))
307+
308+
#default attribute name
309+
if hasattr(socket, "default_attribute_name"):
310+
if socket.default_attribute_name != "":
311+
dan = str_to_py_str(socket.default_attribute_name)
312+
file.write((f"{inner}{socket_var}"
313+
f".default_attribute_name = {dan}\n"))
314+
315+
#attribute domain
316+
if hasattr(socket, "attribute_domain"):
317+
ad = enum_to_py_str(socket.attribute_domain)
318+
file.write(f"{inner}{socket_var}.attribute_domain = {ad}\n")
319+
320+
#tooltip
321+
if socket.description != "":
322+
description = str_to_py_str(socket.description)
323+
file.write((f"{inner}{socket_var}.description = {description}\n"))
324+
325+
#hide_value
326+
if socket.hide_value is True:
327+
file.write(f"{inner}{socket_var}.hide_value = True\n")
328+
329+
#hide in modifier
330+
if hasattr(socket, "hide_in_modifier"):
331+
if socket.hide_in_modifier is True:
332+
file.write(f"{inner}{socket_var}.hide_in_modifier = True\n")
333+
334+
file.write("\n")
335+
file.write("\n")
336+
268337
def color_ramp_settings(node, file: TextIO, inner: str, node_var: str):
269338
"""
270339
Replicate a color ramp node

0 commit comments

Comments
 (0)