Kaynağa Gözat

Further Workaround for 4.5.0 LTS

this one adresses schema and improves organization
it also fixes adding a socket from the menu
Joseph Brandenburg 3 ay önce
ebeveyn
işleme
44a6c90c1f
5 değiştirilmiş dosya ile 81 ekleme ve 49 silme
  1. 2 0
      base_definitions.py
  2. 3 22
      i_o.py
  3. 17 12
      socket_definitions.py
  4. 9 14
      utilities.py
  5. 50 1
      versioning.py

+ 2 - 0
base_definitions.py

@@ -35,6 +35,8 @@ def valid_interface_types(cls : NodeTree, socket_idname : str):
     #TODO: do the versioning code to handle this so it can be in all versions
     if bpy.app.version <= (4,4,0): # should work in 4.4.1
         return socket_idname in [cls.bl_idname for cls in TellClasses()]
+    elif bpy.app.version == (4,5,0): # workaround for a BUG
+        return ['NodeSocketGeometry']
     else: # once versioning is finished this will be unnecesary.
         return socket_idname in tell_valid_bl_idnames()
 

+ 3 - 22
i_o.py

@@ -480,28 +480,9 @@ def do_import(data, context):
                 if bpy.app.version != (4,5,0):
                     sock = tree.interface.new_socket(s_props["name"], in_out=s_props["in_out"], socket_type=socket_type)
                 else: # blender 4.5.0 LTS, have to workaround a bug!
-                    prRed("There is a bug in Blender 4.5.0 regarding node-group interface sockets. Working around it.")
-                    sock = tree.interface.new_socket(s_props["name"], in_out=s_props["in_out"], socket_type='NodeSocketGeometry')
-                    import json
-                    interface_helper = {} # initialize it if it is empty
-                    if tree.interface_helper: # may be empty, check here
-                        interface_helper = json.loads(tree.interface_helper)
-                    category =  s_props.get("parent", '')
-                    if category: # annoying
-                        category = category.name
-                    error_message= 'There is a bug in Blender 4.5.0 LTS, that is why these sockets are blue.'\
-                                   ' This will be fixed in future Blender versions.'
-                    interface_helper[sock.identifier] = {
-                            'name'             : sock.name,
-                            'identifier'       : sock.identifier,
-                            'in_out'           : sock.in_out,
-                            'socket_type'      : socket_type,
-                            'bl_socket_idname' : socket_type,
-                            'mantis_socket_category' : category,
-                            'description' : error_message,
-                        }
-                    sock.description = error_message # this tells the user why the socket looks weird.
-                    tree.interface_helper = json.dumps(interface_helper)
+                    from .versioning import workaround_4_5_0_interface_update
+                    sock = workaround_4_5_0_interface_update(tree=tree, name=name, in_out=s_props["in_out"],
+                                                            sock_type=socket_type, parent_name=s_props.get("parent", ''))
 
                 tree_sock_id_map[s_name] = sock.identifier
                 if not (socket_position := s_props.get('position')):

+ 17 - 12
socket_definitions.py

@@ -20,9 +20,14 @@ no_default_value= [
 ]
 # the sockets that do not have this field do not transfer data.
 # instead, it is the link itself which is meaningful.
-
-class MantisSocket(NodeSocket):
-    is_valid_interface_type=False
+from bpy.app import version as bpy_version
+if bpy_version == (4,5,0): # THere is a bug that requires the socket type to inherit from a Blender class
+    from bpy.types import NodeSocketGeometry # so we will just inherit from NodeSocketGeometry
+    class MantisSocket(NodeSocketGeometry, NodeSocket): # even though that is kinda silly
+        is_valid_interface_type=False
+else:
+    class MantisSocket(NodeSocket):
+        is_valid_interface_type=False
     
 
 from .utilities import (prRed, prGreen, prPurple, prWhite,
@@ -841,7 +846,7 @@ class UnsignedIntSocket(MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class StringSocket(bpy.types.NodeSocketString, MantisSocket):
+class StringSocket(MantisSocket):
     """Float Input socket"""
     bl_idname = 'StringSocket'
     bl_label = "String"
@@ -2227,7 +2232,7 @@ class EnumDriverType(MantisSocket):
 # eventually gonna make it to the fancy stuff
 
 
-class FloatSocket(bpy.types.NodeSocketFloat, MantisSocket):
+class FloatSocket(MantisSocket):
     """Float Input socket"""
     bl_idname = 'FloatSocket'
     bl_label = "Float"
@@ -2244,7 +2249,7 @@ class FloatSocket(bpy.types.NodeSocketFloat, MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
         
-class FloatPositiveSocket(bpy.types.NodeSocketFloat, MantisSocket):
+class FloatPositiveSocket(MantisSocket):
     """Float Input socket"""
     bl_idname = 'FloatPositiveSocket'
     bl_label = "Float (Positive)"
@@ -2261,7 +2266,7 @@ class FloatPositiveSocket(bpy.types.NodeSocketFloat, MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class FloatFactorSocket(bpy.types.NodeSocketFloatFactor, MantisSocket):
+class FloatFactorSocket(MantisSocket):
     '''xFrom Input Output'''
     bl_idname = 'FloatFactorSocket'
     bl_label = "Float (Factor)"
@@ -2283,7 +2288,7 @@ class FloatFactorSocket(bpy.types.NodeSocketFloatFactor, MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class FloatAngleSocket(bpy.types.NodeSocketFloatAngle, MantisSocket):
+class FloatAngleSocket(MantisSocket):
     '''xFrom Input Output'''
     bl_idname = 'FloatAngleSocket'
     bl_label = "Float (Angle)"
@@ -2305,7 +2310,7 @@ class FloatAngleSocket(bpy.types.NodeSocketFloatAngle, MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class VectorSocket(bpy.types.NodeSocketVectorEuler, MantisSocket):
+class VectorSocket(MantisSocket):
     """Vector Input socket"""
     bl_idname = 'VectorSocket'
     bl_label = "Vector"
@@ -2324,7 +2329,7 @@ class VectorSocket(bpy.types.NodeSocketVectorEuler, MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class VectorEulerSocket(bpy.types.NodeSocketVectorEuler, MantisSocket):
+class VectorEulerSocket(MantisSocket):
     """Vector Input socket"""
     bl_idname = 'VectorEulerSocket'
     bl_label = "Euler"
@@ -2344,7 +2349,7 @@ class VectorEulerSocket(bpy.types.NodeSocketVectorEuler, MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class VectorTranslationSocket(bpy.types.NodeSocketVectorTranslation, MantisSocket):
+class VectorTranslationSocket(MantisSocket):
     """Vector Input socket"""
     bl_idname = 'VectorTranslationSocket'
     bl_label = "Vector (Translation)"
@@ -2364,7 +2369,7 @@ class VectorTranslationSocket(bpy.types.NodeSocketVectorTranslation, MantisSocke
     def draw_color_simple(self):
         return self.color_simple
 
-class VectorScaleSocket(bpy.types.NodeSocketVectorXYZ, MantisSocket):
+class VectorScaleSocket(MantisSocket):
     """Vector Input socket"""
     bl_idname = 'VectorScaleSocket'
     bl_label = "Vector (Scale)"

+ 9 - 14
utilities.py

@@ -204,10 +204,16 @@ def do_relink(node, s, map, in_out='INPUT', parent_name = ''):
                 pass
 
 def update_interface(interface, name, in_out, sock_type, parent_name):
+    from bpy.app import version as bpy_version
     if parent_name:
         if not (interface_parent := interface.items_tree.get(parent_name)):
             interface_parent = interface.new_panel(name=parent_name)
-        socket = interface.new_socket(name=name,in_out=in_out, socket_type=sock_type, parent=interface_parent)
+        if bpy_version != (4,5,0):
+            socket = interface.new_socket(name=name,in_out=in_out, socket_type=sock_type, parent=interface_parent)
+        else: # blender 4.5.0 LTS, have to workaround a bug!
+            from .versioning import workaround_4_5_0_interface_update
+            socket = workaround_4_5_0_interface_update(tree=interface.id_data, name=name, in_out=in_out,
+                                                       sock_type=sock_type, parent_name=parent_name, do_parent=True)
         if parent_name == 'Connection':
             in_out = 'OUTPUT' if in_out == 'INPUT' else 'INPUT' # flip this make sure connections always do both
             interface.new_socket(name=name,in_out=in_out, socket_type=sock_type, parent=interface_parent)
@@ -216,19 +222,6 @@ def update_interface(interface, name, in_out, sock_type, parent_name):
         raise RuntimeError(wrapRed("Cannot add interface item to tree without specifying type."))
 
 
-def socket_add_workaround_for_4_5_0_LTS(item, socket_collection, multi):
-    import json
-    tree = item.id_data
-    interface_helper = json.loads(tree.interface_helper)
-    socket_info = interface_helper.get(item.identifier)
-    if not socket_info: raise RuntimeError(f"There has been an error adding the socket {item.name}")
-    s = socket_collection.new(
-        type=socket_info['bl_socket_idname'],
-        name=socket_info['name'],
-        identifier=item.identifier,
-        use_multi_input=multi, )
-    return s
-
 # D.node_groups['Rigging Nodes'].interface.new_socket('beans', description='the b word', socket_type='NodeSocketGeometry')
 #UGLY BAD REFACTOR
 def relink_socket_map_add_socket(node, socket_collection, item, in_out=None,):
@@ -239,11 +232,13 @@ def relink_socket_map_add_socket(node, socket_collection, item, in_out=None,):
         # have to work around a bug in 4.5.0 that prevents me from declaring custom socket types
         # I have arbitrarily chosen to use the NodeSocketGeometry type to signal that this one is affected.
         if bpy_version == (4, 5, 0) and item.bl_socket_idname == 'NodeSocketGeometry':
+            from .versioning import socket_add_workaround_for_4_5_0_LTS
             s = socket_add_workaround_for_4_5_0_LTS(item, socket_collection, multi)
         else:
             s = socket_collection.new(type=item.bl_socket_idname, name=item.name, identifier=item.identifier,  use_multi_input=multi)
     else:
         if bpy_version == (4, 5, 0) and item.bl_socket_idname == 'NodeSocketGeometry':
+            from .versioning import socket_add_workaround_for_4_5_0_LTS
             s = socket_add_workaround_for_4_5_0_LTS(item, socket_collection, multi=False,)
         else:
             s = socket_collection.new(type=item.bl_socket_idname, name=item.name, identifier=item.identifier)

+ 50 - 1
versioning.py

@@ -180,4 +180,53 @@ versioning_tasks = [
     (['ALL'], version_upgrade_very_old, ['node_tree', 'node'],),
     (['xFormBoneNode'], version_upgrade_bone_0_12_0_from_older, ['node'],),
     (['xFormBoneNode'], up_0_12_1_add_inherit_color, ['node'],),
-]
+]
+
+
+
+
+# WORKAROUNDS for bugs should go here:
+# 4.5.0 LTS valid socket types bug:
+def workaround_4_5_0_interface_update(tree, name, in_out, sock_type, parent_name, do_parent=False):
+    # TODO: dedupe this code from i_o.py
+    prRed("There is a bug in Blender 4.5.0 regarding node-group interface sockets. Working around it.")
+    sock = tree.interface.new_socket(name=name, in_out=in_out, socket_type="NodeSocketGeometry")
+    import json
+    interface_helper = {} # initialize it if it is empty
+    if tree.interface_helper: # may be empty, check here
+        interface_helper = json.loads(tree.interface_helper)
+    error_message= 'There is a bug in Blender 4.5.0 LTS, that is why these sockets are blue.'\
+                    ' This will be fixed in future Blender versions.'
+    interface_helper[sock.identifier] = {
+            'name'             : sock.name,
+            'identifier'       : sock.identifier,
+            'in_out'           : sock.in_out,
+            'socket_type'      : sock_type,
+            'bl_socket_idname' : sock_type,
+            'mantis_socket_category' : parent_name,
+            'description' : error_message,
+        }
+    sock.description = error_message # this tells the user why the socket looks weird.
+    tree.interface_helper = json.dumps(interface_helper)
+    if do_parent and (parent := tree.interface.items_tree.get(parent_name)):
+        prRed(parent.name)
+
+        tree.interface.move_to_parent(
+                                sock,
+                                parent,
+                                0, # what to do here?
+                                )
+    return sock
+
+def socket_add_workaround_for_4_5_0_LTS(item, socket_collection, multi):
+    import json
+    tree = item.id_data
+    interface_helper = json.loads(tree.interface_helper)
+    socket_info = interface_helper.get(item.identifier)
+    if not socket_info: raise RuntimeError(f"There has been an error adding the socket {item.name}")
+    s = socket_collection.new(
+        type=socket_info['bl_socket_idname'],
+        name=item.name, # in case the user has changed it
+        identifier=item.identifier,
+        use_multi_input=multi, )
+    return s