@@ -29,6 +29,20 @@ class NTP_Operator(Operator):
2929 ]
3030 )
3131
32+ #node tree input sockets that have default properties
33+ if bpy .app .version < (4 , 0 , 0 ):
34+ default_sockets_v3 = {'VALUE' , 'INT' , 'BOOLEAN' , 'VECTOR' , 'RGBA' }
35+ else :
36+ nondefault_sockets_v4 = {
37+ bpy .types .NodeTreeInterfaceSocketCollection ,
38+ bpy .types .NodeTreeInterfaceSocketGeometry ,
39+ bpy .types .NodeTreeInterfaceSocketImage ,
40+ bpy .types .NodeTreeInterfaceSocketMaterial ,
41+ bpy .types .NodeTreeInterfaceSocketObject ,
42+ bpy .types .NodeTreeInterfaceSocketShader ,
43+ bpy .types .NodeTreeInterfaceSocketTexture
44+ }
45+
3246 def __init__ (self ):
3347 super ().__init__ ()
3448
@@ -275,7 +289,7 @@ def _set_group_socket_default_v3(self, socket_interface: NodeSocketInterface,
275289 inner (str): indentation string
276290 socket_var (str): variable name for the socket
277291 """
278- if socket_interface .type not in default_sockets :
292+ if socket_interface .type not in self . default_sockets_v3 :
279293 return
280294
281295 if socket_interface .type == 'RGBA' :
@@ -295,77 +309,236 @@ def _set_group_socket_default_v3(self, socket_interface: NodeSocketInterface,
295309 max_val = socket_interface .max_value
296310 self ._write ((f"{ inner } { socket_var } .max_value = { max_val } \n " ))
297311
298- def _group_io_settings (self , node : bpy .types .Node , inner : str ,
299- io : str , # TODO: convert to enum
300- ntp_node_tree : NTP_NodeTree ) -> None :
301- """
302- Set the settings for group input and output sockets
312+ def _group_io_settings_v3 (self , node : bpy .types .Node , inner : str ,
313+ io : str , # TODO: convert to enum
314+ ntp_node_tree : NTP_NodeTree ) -> None :
315+ """
316+ Set the settings for group input and output sockets
303317
304- Parameters:
305- node (bpy.types.Node) : group input/output node
306- inner (str): indentation string
307- io (str): whether we're generating the input or output settings
308- node_tree_var (str): variable name of the generated node tree
309- node_tree (bpy.types.NodeTree): node tree that we're generating input
310- and output settings for
311- """
312- node_tree_var = ntp_node_tree .var
313- node_tree = ntp_node_tree .node_tree
318+ Parameters:
319+ node (bpy.types.Node) : group input/output node
320+ inner (str): indentation string
321+ io (str): whether we're generating the input or output settings
322+ node_tree_var (str): variable name of the generated node tree
323+ node_tree (bpy.types.NodeTree): node tree that we're generating
324+ input and output settings for
325+ """
326+ node_tree_var = ntp_node_tree .var
327+ node_tree = ntp_node_tree .node_tree
314328
315- if io == "input" :
316- io_sockets = node .outputs
317- io_socket_interfaces = node_tree .inputs
318- else :
319- io_sockets = node .inputs
320- io_socket_interfaces = node_tree .outputs
329+ if io == "input" :
330+ io_sockets = node .outputs
331+ io_socket_interfaces = node_tree .inputs
332+ else :
333+ io_sockets = node .inputs
334+ io_socket_interfaces = node_tree .outputs
335+
336+ self ._write (f"{ inner } #{ node_tree_var } { io } s\n " )
337+ for i , inout in enumerate (io_sockets ):
338+ if inout .bl_idname == 'NodeSocketVirtual' :
339+ continue
340+ self ._write (f"{ inner } #{ io } { inout .name } \n " )
341+ idname = enum_to_py_str (inout .bl_idname )
342+ name = str_to_py_str (inout .name )
343+ self ._write (
344+ f"{ inner } { node_tree_var } .{ io } s.new({ idname } , { name } )\n " )
345+ socket_interface = io_socket_interfaces [i ]
346+ socket_var = f"{ node_tree_var } .{ io } s[{ i } ]"
347+
348+ self ._set_group_socket_default_v3 (socket_interface , inner ,
349+ socket_var )
350+
351+ # default attribute name
352+ if hasattr (socket_interface , "default_attribute_name" ):
353+ if socket_interface .default_attribute_name != "" :
354+ dan = str_to_py_str (
355+ socket_interface .default_attribute_name )
356+ self ._write ((f"{ inner } { socket_var } "
357+ f".default_attribute_name = { dan } \n " ))
358+
359+ # attribute domain
360+ if hasattr (socket_interface , "attribute_domain" ):
361+ ad = enum_to_py_str (socket_interface .attribute_domain )
362+ self ._write (f"{ inner } { socket_var } .attribute_domain = { ad } \n " )
363+
364+ # tooltip
365+ if socket_interface .description != "" :
366+ description = str_to_py_str (socket_interface .description )
367+ self ._write (
368+ (f"{ inner } { socket_var } .description = { description } \n " ))
321369
322- self ._write (f"{ inner } #{ node_tree_var } { io } s\n " )
323- for i , inout in enumerate (io_sockets ):
324- if inout .bl_idname == 'NodeSocketVirtual' :
325- continue
326- self ._write (f"{ inner } #{ io } { inout .name } \n " )
327- idname = enum_to_py_str (inout .bl_idname )
328- name = str_to_py_str (inout .name )
329- self ._write (
330- f"{ inner } { node_tree_var } .{ io } s.new({ idname } , { name } )\n " )
331- socket_interface = io_socket_interfaces [i ]
332- socket_var = f"{ node_tree_var } .{ io } s[{ i } ]"
370+ # hide_value
371+ if socket_interface .hide_value is True :
372+ self ._write (f"{ inner } { socket_var } .hide_value = True\n " )
373+
374+ # hide in modifier
375+ if hasattr (socket_interface , "hide_in_modifier" ):
376+ if socket_interface .hide_in_modifier is True :
377+ self ._write (
378+ f"{ inner } { socket_var } .hide_in_modifier = True\n " )
379+
380+ self ._write ("\n " )
381+ self ._write ("\n " )
382+
383+ elif bpy .app .version >= (4 , 0 , 0 ):
384+ def _set_group_socket_default_v4 (self , socket_interface : bpy .types .NodeTreeInterfaceSocket ,
385+ inner : str , socket_var : str ) -> None :
386+ """
387+ Set a node group input/output's default properties if they exist
388+
389+ Parameters:
390+ socket_interface (NodeTreeInterfaceSocket): socket interface associated
391+ with the input/output
392+ inner (str): indentation string
393+ socket_var (str): variable name for the socket
394+ """
395+ if type (socket_interface ) in self .nondefault_sockets_v4 :
396+ return
333397
334- if bpy .app .version < (4 , 0 , 0 ):
335- self ._set_group_socket_default_v3 (
336- socket_interface , inner , socket_var )
398+ dv = socket_interface .default_value
337399
338- # default attribute name
339- if hasattr (socket_interface , "default_attribute_name" ):
400+ if type (socket_interface ) == bpy .types .NodeTreeInterfaceSocketColor :
401+ dv = vec4_to_py_str (dv )
402+ elif type (dv ) in {mathutils .Vector , mathutils .Euler }:
403+ dv = vec3_to_py_str (dv )
404+ elif type (dv ) == str :
405+ dv = str_to_py_str (dv )
406+ self ._write (f"{ inner } { socket_var } .default_value = { dv } \n " )
407+
408+ # min value
409+ if hasattr (socket_interface , "min_value" ):
410+ min_val = socket_interface .min_value
411+ self ._write (f"{ inner } { socket_var } .min_value = { min_val } \n " )
412+ # max value
413+ if hasattr (socket_interface , "min_value" ):
414+ max_val = socket_interface .max_value
415+ self ._write ((f"{ inner } { socket_var } .max_value = { max_val } \n " ))
416+
417+ def _group_io_settings_v4 (self , node : bpy .types .Node , inner : str ,
418+ io : str , # TODO: convert to enum
419+ ntp_node_tree : NTP_NodeTree ) -> None :
420+ """
421+ Set the settings for group input and output sockets
422+
423+ Parameters:
424+ node (bpy.types.Node) : group input/output node
425+ inner (str): indentation string
426+ io (str): whether we're generating the input or output settings
427+ node_tree_var (str): variable name of the generated node tree
428+ node_tree (bpy.types.NodeTree): node tree that we're generating
429+ input and output settings for
430+ """
431+ node_tree_var = ntp_node_tree .var
432+ node_tree = ntp_node_tree .node_tree
433+
434+ if io == "input" :
435+ io_sockets = node .outputs # Might be removeable,
436+ # think we can get all the info from the inouts
437+ # from the socket interfaces, need to double check.
438+ # If so, then we can just run these at the initialization
439+ # of the node tree, meaning we can clean up the clunky
440+ # Group Input/Group Output node reliance, two calls
441+ # Should be pretty easy to add in panels afterwards,
442+ # looks like those are tied fairly close to the new socket
443+ # system
444+ items_tree = node_tree .interface .items_tree
445+ io_socket_interfaces = [item for item in items_tree
446+ if item .item_type == 'SOCKET'
447+ and item .in_out == 'INPUT' ]
448+ else :
449+ io_sockets = node .inputs
450+ items_tree = node_tree .interface .items_tree
451+ io_socket_interfaces = [item for item in items_tree
452+ if item .item_type == 'SOCKET'
453+ and item .in_out == 'OUTPUT' ]
454+
455+ self ._write (f"{ inner } #{ node_tree_var } { io } s\n " )
456+ for i , socket_interface in enumerate (io_socket_interfaces ):
457+ self ._write (f"{ inner } #{ io } { socket_interface .name } \n " )
458+
459+ socket_interface : bpy .types .NodeTreeInterfaceSocket = io_socket_interfaces [i ]
460+
461+ #initialization
462+ socket_var = clean_string (socket_interface .name ) + "_socket"
463+ name = str_to_py_str (socket_interface .name )
464+ in_out_enum = enum_to_py_str (socket_interface .in_out )
465+
466+ socket_type = enum_to_py_str (socket_interface .bl_socket_idname )
467+ """
468+ I might be missing something, but the Python API's set up a bit
469+ weird here now. The new socket initialization only accepts types
470+ from a list of basic ones, but there doesn't seem to be a way of
471+ retrieving just this basic typewithout the subtype information.
472+ """
473+ if 'Float' in socket_type :
474+ socket_type = enum_to_py_str ('NodeSocketFloat' )
475+ elif 'Int' in socket_type :
476+ socket_type = enum_to_py_str ('NodeSocketInt' )
477+ elif 'Vector' in socket_type :
478+ socket_type = enum_to_py_str ('NodeSocketVector' )
479+
480+
481+ self ._write (f"{ inner } { socket_var } = "
482+ f"{ node_tree_var } .interface.new_socket("
483+ f"name = { name } , in_out={ in_out_enum } , "
484+ f"socket_type = { socket_type } )\n " )
485+
486+ #subtype
487+ if hasattr (socket_interface , "subtype" ):
488+ subtype = enum_to_py_str (socket_interface .subtype )
489+ self ._write (f"{ inner } { socket_var } .subtype = { subtype } \n " )
490+
491+ self ._set_group_socket_default_v4 (socket_interface , inner ,
492+ socket_var )
493+
494+ # default attribute name
340495 if socket_interface .default_attribute_name != "" :
341- dan = str_to_py_str (
342- socket_interface .default_attribute_name )
343- self ._write ((f"{ inner } { socket_var } "
344- f".default_attribute_name = { dan } \n " ))
496+ dan = str_to_py_str (socket_interface .default_attribute_name )
497+ self ._write ((f"{ inner } { socket_var } .default_attribute_name = { dan } \n " ))
345498
346- # attribute domain
347- if hasattr (socket_interface , "attribute_domain" ):
499+ # attribute domain
348500 ad = enum_to_py_str (socket_interface .attribute_domain )
349501 self ._write (f"{ inner } { socket_var } .attribute_domain = { ad } \n " )
350502
351- # tooltip
352- if socket_interface .description != "" :
353- description = str_to_py_str (socket_interface .description )
354- self ._write (
355- (f"{ inner } { socket_var } .description = { description } \n " ))
503+ # tooltip
504+ if socket_interface .description != "" :
505+ description = str_to_py_str (socket_interface .description )
506+ self ._write (
507+ (f"{ inner } { socket_var } .description = { description } \n " ))
356508
357- # hide_value
358- if socket_interface .hide_value is True :
359- self ._write (f"{ inner } { socket_var } .hide_value = True\n " )
509+ # hide_value
510+ if socket_interface .hide_value is True :
511+ self ._write (f"{ inner } { socket_var } .hide_value = True\n " )
360512
361- # hide in modifier
362- if hasattr (socket_interface , "hide_in_modifier" ):
513+ # hide in modifier
363514 if socket_interface .hide_in_modifier is True :
364- self ._write (
365- f"{ inner } { socket_var } .hide_in_modifier = True\n " )
515+ self ._write (f"{ inner } { socket_var } .hide_in_modifier = True\n " )
516+
517+ #force non field
518+ if socket_interface .force_non_field is True :
519+ self ._write (f"{ inner } { socket_var } .force_non_field = True\n " )
366520
521+ self ._write ("\n " )
367522 self ._write ("\n " )
368- self ._write ("\n " )
523+
524+ def _group_io_settings (self , node : bpy .types .Node , inner : str ,
525+ io : str , # TODO: convert to enum
526+ ntp_node_tree : NTP_NodeTree ) -> None :
527+ """
528+ Set the settings for group input and output sockets
529+
530+ Parameters:
531+ node (bpy.types.Node) : group input/output node
532+ inner (str): indentation string
533+ io (str): whether we're generating the input or output settings
534+ node_tree_var (str): variable name of the generated node tree
535+ node_tree (bpy.types.NodeTree): node tree that we're generating
536+ input and output settings for
537+ """
538+ if bpy .app .version < (4 , 0 , 0 ):
539+ self ._group_io_settings_v3 (node , inner , io , ntp_node_tree )
540+ else :
541+ self ._group_io_settings_v4 (node , inner , io , ntp_node_tree )
369542
370543 def _set_input_defaults (self , node : bpy .types .Node , inner : str ,
371544 node_var : str ) -> None :
0 commit comments