Procházet zdrojové kódy

fix compatibility with blender 4.2, socket definitions

turns out 5.0-only constraints cause problems in older blenders
and it also turns out, quite unexpectedly, that subclassing
socket definitions messes things up in the parent class. weird
maybe blender does that on purpose because it expects
parent classes to be abstract base classes (sort of)
Joseph Brandenburg před 2 měsíci
rodič
revize
6efb6b2edc
7 změnil soubory, kde provedl 105 přidání a 9 odebrání
  1. 4 1
      base_definitions.py
  2. 1 1
      blender_manifest.toml
  3. 4 0
      link_nodes.py
  4. 20 1
      link_nodes_ui.py
  5. 1 0
      node_common.py
  6. 1 1
      ops_generate_tree.py
  7. 74 5
      socket_definitions.py

+ 4 - 1
base_definitions.py

@@ -83,7 +83,7 @@ def hash_tree(tree):
 
 MANTIS_VERSION_MAJOR=0
 MANTIS_VERSION_MINOR=13
-MANTIS_VERSION_SUB=0
+MANTIS_VERSION_SUB=1
 
 class MantisTree(NodeTree):
     '''A custom node tree type that will show up in the editor type list'''
@@ -576,6 +576,9 @@ class MantisNodeGroup(Node, MantisUINode):
 class GraphError(Exception):
     pass
 
+class BlenderVersionError(Exception):
+    pass
+
 def get_signature_from_edited_tree(node, context):
     sig_path=[None,]
     for item in context.space_data.path[:-1]:

+ 1 - 1
blender_manifest.toml

@@ -3,7 +3,7 @@ schema_version = "1.0.0"
 # Example of manifest file for a Blender extension
 # Change the values according to your extension
 id = "mantis"
-version = "0.13.0"
+version = "0.13.1"
 name = "Mantis"
 tagline = "Mantis is a rigging nodes toolkit"
 maintainer = "Nodespaghetti <josephbburg@protonmail.com>"

+ 4 - 0
link_nodes.py

@@ -921,6 +921,10 @@ class LinkGeometryAttribute(MantisLinkNode):
         self.set_traverse([("Input Relationship", "Output Relationship")])
 
     def bRelationshipPass(self, bContext = None,):
+        from bpy.app import version
+        from .base_definitions import BlenderVersionError
+        if version < (5,0,0):
+            raise BlenderVersionError("Geometry Attribute Constraint is supported only in Blender 5.0 or greater.")
         prepare_parameters(self)
         for xf in self.GetxForm():
             print

+ 20 - 1
link_nodes_ui.py

@@ -439,7 +439,10 @@ class LinkGeometryAttribute(Node, LinkNode):
     """A node representing Blender's Geometry Attribute Constraint"""
     bl_idname = "LinkGeometryAttribute"
     bl_label = "Geometry Attribute"
-    bl_icon = "CON_GEOMETRYATTRIBUTE"
+    if bpy.app.version >= (5,0,0):
+        bl_icon = "CON_GEOMETRYATTRIBUTE"
+    else:
+        bl_icon = "ERROR"
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name=bl_idname
 
@@ -448,8 +451,24 @@ class LinkGeometryAttribute(Node, LinkNode):
         self.use_custom_color = True
         self.color = linkTransformColor
         self.initialized = True
+    
+    def draw_label(self):
+        if bpy.app.version < (5,0,0):
+            return "ERROR: ONLY SUPPORTED IN Blender 5.0 OR NEWER"
+        elif self.label: 
+            return self.label
+        return self.bl_label
+    
+    def update(self):
+        if bpy.app.version < (5,0,0):
+            self.color = Color((1.0, 0.15, 0.15,)).from_scene_linear_to_srgb()
+        elif self.color != linkTransformColor:
+            self.color = linkTransformColor
+
 
     def display_update(self, parsed_tree, context):
+        if bpy.app.version < (5,0,0):
+            return
         data_type = self.inputs['Data Type'].default_value
         if self.inputs['Data Type'].is_linked:
             node_tree = context.space_data.path[0].node_tree

+ 1 - 0
node_common.py

@@ -8,6 +8,7 @@ from collections.abc import Callable
 # the x_containers files import * from this file
 # so all the top-level imports are carried over
 
+
 #TODO: refactor the socket definitions so this becomes unnecessary.
 def get_socket_value(node_socket):
     value = None

+ 1 - 1
ops_generate_tree.py

@@ -851,7 +851,7 @@ def do_generate_armature(armOb, context, node_tree, parent_node=None):
                 mr_node = node_tree.nodes.new("UtilityMetaRig")
                 meta_rig_nodes[mr_node_name] = mr_node
                 mr_node.inputs[0].search_prop=armOb
-                mr_node.inputs[1].search_prop=armOb
+                mr_node.inputs[1].armature=armOb
                 mr_node.inputs[1].bone=bone.name
                 mr_node.inputs[1].default_value=bone.name
             node_tree.links.new(input=mr_node.outputs[0], output=bone_node.inputs["Matrix"])

+ 74 - 5
socket_definitions.py

@@ -1490,7 +1490,7 @@ class EnumMetaRigSocket(MantisSocket):
     '''Custom node socket type'''
     bl_idname = 'EnumMetaRigSocket'
     bl_label = "Meta Rig"
-
+    color_simple = cString
 
     search_prop:PointerProperty(type=bpy.types.Object, poll=poll_is_armature, update=update_metarig_armature)
 
@@ -1505,9 +1505,8 @@ class EnumMetaRigSocket(MantisSocket):
                 self.search_prop=ob
 
     default_value  : StringProperty(name = "", get=get_default_value, set=set_default_value)
-
-    color_simple = cString
     color : bpy.props.FloatVectorProperty(default=cString, size=4)
+    
     def draw(self, context, layout, node, text):
         if self.is_output:
             layout.label(text=self.name)
@@ -1526,9 +1525,44 @@ class EnumMetaRigSocket(MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class EnumArmature(EnumMetaRigSocket):
+# I donno why but I can't just subclass the above. hmm.so this is a duplicate
+class EnumArmature(MantisSocket):
     bl_idname = "EnumArmature"
     bl_label = "Armature"
+    color_simple = cString
+
+    search_prop:PointerProperty(type=bpy.types.Object, poll=poll_is_armature, update=update_metarig_armature)
+
+    def get_default_value(self):
+        if self.search_prop:
+            return self.search_prop.name
+        return ""
+
+    def set_default_value(self, value):
+        if ob:= bpy.data.objects.get(value):
+            if ob.type == 'ARMATURE':
+                self.search_prop=ob
+
+    default_value  : StringProperty(name = "", get=get_default_value, set=set_default_value)
+    color : bpy.props.FloatVectorProperty(default=cString, size=4)
+    
+    def draw(self, context, layout, node, text):
+        if self.is_output:
+            layout.label(text=self.name)
+        elif not (self.is_linked):
+            layout.prop_search(data=self, property="search_prop", search_data=bpy.data, search_property="objects", text="", icon="OUTLINER_OB_ARMATURE", results_are_suggestions=True)
+        elif hasattr(self.node, "armature"):
+            layout.label(text=self.node.armature)
+            # TODO: we should actually use the parsed tree to query this info directly, since this socket may belong to a node group in/out
+            # which doesn't have this parameter. whatever.
+        else:
+            layout.label(text=self.name)
+
+    def draw_color(self, context, node):
+        return self.color
+    @classmethod
+    def draw_color_simple(self):
+        return self.color_simple
 
 def poll_is_curve(self, obj):
     return obj.type == "CURVE"
@@ -1613,10 +1647,45 @@ class EnumMetaBoneSocket(MantisSocket):
     def draw_color_simple(self):
         return self.color_simple
 
-class EnumExistingBoneSocket(EnumMetaBoneSocket):
+# I don't know why but I can't subclass the above and I had to duplicate it here
+class EnumExistingBoneSocket(MantisSocket): 
     '''Socket to Get a Bone from an object'''
     bl_idname = 'EnumExistingBoneSocket'
     bl_label = "Bone"
+    color_simple = cString
+
+    # this armature property is set by the parent node.
+    armature:PointerProperty(type=bpy.types.Object)
+    bone:StringProperty()
+
+    def populate_bones_list(self, context):
+        # just gonna hardcode the value
+        if (meta_rig := self.armature):
+            retList = []; i = -1
+            retList.append( ('NONE', '', '', 'NONE', i:=i+1 ) )
+            for b in meta_rig.data.bones:
+                retList.append( (b.name, b.name, "Bone to copy matrix from", "BONE_DATA", i:=i+1 ) )
+            return(retList)
+        return None
+
+    default_value  : StringProperty(name = "", update=update_metarig_posebone)
+
+    color : bpy.props.FloatVectorProperty(default=cString, size=4)
+    def draw(self, context, layout, node, text):
+        if not (self.is_linked):
+            if self.armature is None:
+                layout.prop(self, "default_value", text="", icon="BONE_DATA",)
+            else:
+                SearchPBDraw(self, context, layout, node, text="")
+        else:
+            layout.label(text=self.node.pose_bone)
+
+    def draw_color(self, context, node):
+        return self.color
+    @classmethod
+    def draw_color_simple(self):
+        return self.color_simple
+
 
 # TODO: make it so that this makes an item for "missing" widgets
 # for when a widget is moved or deleted