فهرست منبع

Error Display for Bones when names are not unique

Joseph Brandenburg 3 سال پیش
والد
کامیت
81c1fb8e12
3فایلهای تغییر یافته به همراه173 افزوده شده و 58 حذف شده
  1. 89 25
      base_definitions.py
  2. 16 12
      ops_generate_tree.py
  3. 68 21
      xForm_definitions.py

+ 89 - 25
base_definitions.py

@@ -34,11 +34,8 @@ class MantisTree(NodeTree):
         # no idea what this does
         print ("Update Interface function in MantisTree class")
 
-           
     def interface_update(self, context):
         prGreen("interface_update")
-        
-
 
     if bpy.app.version >= (3, 2):  # in 3.1 this can lead to a crash
         @classmethod
@@ -49,11 +46,15 @@ class MantisTree(NodeTree):
             # thank you, Sverchok
             
     def update_tree(self, context):
+        prWhite("Updating.")
         if self.do_live_update == False:
             return
         from mantis import readtree
         prGreen("Validating Tree: %s" % self.name)
-        parsed_tree = readtree.parse_tree(self)
+        try:
+            parsed_tree = readtree.parse_tree(self)
+        except RecursionError:
+            parsed_tree = {}
         self.parsed_tree=parsed_tree
         current_tree = bpy.context.space_data.path[-1].node_tree
         self.tree_valid = True
@@ -66,11 +67,11 @@ class MantisTree(NodeTree):
         current_tree = bpy.context.space_data.path[-1].node_tree
         for node in current_tree.nodes:
             if hasattr(node, "display_update"):
-                try:
+                # try:
                     node.display_update(self.parsed_tree, context)
-                except Exception as e:
-                    print("Node \"%s\" failed to update display with error: %s" %(wrapGreen(node.name), wrapRed(e)))
-                    # raise e
+                # except Exception as e:
+                    # print("Node \"%s\" failed to update display with error: %s" %(wrapGreen(node.name), wrapRed(e)))
+                    # # raise e
         
     
     def execute_tree(self,context):
@@ -79,8 +80,9 @@ class MantisTree(NodeTree):
         readtree.execute_tree(self.parsed_tree, self, context)
 
     
-
+@persistent
 def update_handler(scene):
+    prGreen("Updating from depsgraph-pre handler!")
     context=bpy.context
     if context.space_data:
         node_tree = context.space_data.path[0].node_tree
@@ -94,18 +96,23 @@ def update_handler(scene):
             if node_tree.tree_valid == False:
                 from mantis import readtree
                 node_tree.update_tree(context)
+        # if node_tree.tree_valid and node_tree.do_live_update:
+            # try:
+                # node_tree.execute_tree(context)
+            # except (RecursionError, RuntimeError):
+                # pass
+            # node_tree.tree_valid = False
 
-def execute_handler(scene):
-    context = bpy.context
-    if context.space_data:
-        node_tree = context.space_data.path[0].node_tree
-        if node_tree.tree_valid and node_tree.do_live_update:
-            node_tree.execute_tree(context)
-            self.tree_valid = False
+# @persistent
+# def execute_handler(scene):
+    # prGreen("Executing from depsgraph-post handler!")
+    # context = bpy.context
+    # if context.space_data:
+        # node_tree = context.space_data.path[0].node_tree
 
 # bpy.app.handlers.load_post.append(set_tree_invalid)
-bpy.app.handlers.depsgraph_update_pre.append(update_handler)
-bpy.app.handlers.depsgraph_update_post.append(execute_handler)
+# bpy.app.handlers.depsgraph_update_pre.append(update_handler)
+# bpy.app.handlers.depsgraph_update_post.append(execute_handler)
     
 
 class MantisNode:
@@ -115,18 +122,46 @@ class MantisNode:
     def poll(cls, ntree):
         return (ntree.bl_idname == 'MantisTree')
                 
-    def insert_link(self, link):
+    def init(self, context):
         context = bpy.context
         if context.space_data:
             node_tree = context.space_data.path[0].node_tree
             from mantis import readtree
-            prOrange("Updating from insert_link callback")
+            prOrange("Updating from init callback")
+            node_tree.update_tree(context)
+    
+    # def insert_link(self, link):
+        # context = bpy.context
+        # if context.space_data:
+            # node_tree = context.space_data.path[0].node_tree
+            # from mantis import readtree
+            # prOrange("Updating from insert_link callback")
+            # node_tree.update_tree(context)
+            # if (link.to_socket.is_linked == False):
+                # node_tree.num_links+=1
+            # elif (link.to_socket.is_multi_input and 
+                  # link.to_socket.links < link.to_socket.link_limit ):
+                # node_tree.num_links+=1
+
+    def free(self):
+        context = bpy.context
+        if context.space_data:
+            node_tree = context.space_data.path[0].node_tree
+            from mantis import readtree
+            prOrange("Updating from free callback")
+            node_tree.update_tree(context)
+            sig = get_signature_from_edited_tree(self, context)
+            if node_tree.parsed_tree.get(sig):
+                del node_tree.parsed_tree[sig]
+                node_tree.display_update(context)
+
+    def copy(self, original):
+        context = bpy.context
+        if context.space_data:
+            node_tree = context.space_data.path[0].node_tree
+            from mantis import readtree
+            prOrange("Updating from copy callback")
             node_tree.update_tree(context)
-            if (link.to_socket.is_linked == False):
-                node_tree.num_links+=1
-            elif (link.to_socket.is_multi_input and 
-                  link.to_socket.links < link.to_socket.link_limit ):
-                node_tree.num_links+=1
             
                 
 
@@ -225,3 +260,32 @@ def get_signature_from_edited_tree(self, context):
     for item in context.space_data.path[:-1]:
         sig_path.append(item.node_tree.nodes.active.name)
     return tuple(sig_path+[self.name])
+
+def get_is_name_unique(nc, tree, namespace='BONE'):
+    if namespace == 'BONE':
+        name = nc.evaluate_input("Name")
+        for sig, nc_other in tree.items():
+            if nc.__class__.__name__ in ["xFormBone"]:
+                if nc_other == nc:
+                    continue
+                if name == nc_other.evaluate_input("Name"):
+                    return False
+        return True
+
+# def get_unique_name(name, tree, namespace='BONE'):
+    # if namespace == 'BONE':
+        # stub_index = {}
+        # for sig, nc in tree.items():
+            # if nc.__class__.__name__ in ["xFormBone"]:
+                # name = sig[-1]
+                # split_name = name.split('.')
+                # prWhite(".".join(split_name[:-1]))
+                # try:
+                    # i = int(split_name[-1])
+                    # prGreen(i)
+                # except ValueError:
+                    # i=-1
+                # if i > 0:
+                    # prev_i = stub_index 
+                    # stub_index[".".join(split_name[:-1])]=i
+        # print (stub_index)

+ 16 - 12
ops_generate_tree.py

@@ -377,13 +377,12 @@ def setup_vp_settings(bone_node, pb, do_after, node_tree):
 
 
 def setup_df_settings(bone_node, pb):
-        bone_node.inputs["Deform"] = pb.bone.use_deform
-        # TODO: get the rest of these working
-        # eb.envelope_distance     = self.evaluate_input("Envelope Distance")
-        # eb.envelope_weight       = self.evaluate_input("Envelope Weight")
-        # eb.use_envelope_multiply = self.evaluate_input("Envelope Multiply")
-        # eb.head_radius           = self.evaluate_input("Envelope Head Radius")
-        # eb.tail_radius           = self.evaluate_input("Envelope Tail Radius")
+    bone_node.inputs["Deform"].default_value = pb.bone.use_deform
+    bone_node.inputs["Envelope Distance"].default_value = pb.bone.envelope_distance
+    bone_node.inputs["Envelope Weight"].default_value = pb.bone.envelope_weight
+    bone_node.inputs["Envelope Multiply"].default_value = pb.bone.use_envelope_multiply
+    bone_node.inputs["Envelope Head Radius"].default_value = pb.bone.head_radius
+    bone_node.inputs["Envelope Tail Radius"].default_value = pb.bone.tail_radius
 
 def create_driver(in_node_name, out_node_name, armOb, finished_drivers, switches, driver_vars, fcurves, drivers, node_tree):
     # TODO: CLEAN this ABOMINATION
@@ -654,10 +653,13 @@ def create_driver(in_node_name, out_node_name, armOb, finished_drivers, switches
                     if not prop_in:
                         # try one last thing:
                         property = parameter.split("targets[")[-1]
-                        target_index = int(property[0])
-                        property = "targets[" + property # HACK lol
-                        # get the property by index...
-                        prop_in = out_node.inputs[target_index*2+6+1] # this is the weight, not the target
+                        try:
+                            target_index = int(property[0])
+                            property = "targets[" + property # HACK lol
+                            # get the property by index...
+                            prop_in = out_node.inputs[target_index*2+6+1] # this is the weight, not the target
+                        except ValueError:
+                            prop_in = None
                     if prop_in:
                         prRed ("   found: %s, %s, %s" % (property, out_node.label, out_node.name))
                         node_tree.links.new(driver_node.outputs["Driver"], prop_in)
@@ -845,7 +847,9 @@ def do_generate_armature(context, node_tree):
                 for n in node_tree.nodes:
                     if n.name == out_node_name:
                         shape_xform_n = n
-                        node_tree.links.new(shape_xform_n.outputs["xForm"], node_tree.nodes[in_node_name].inputs['Custom Object xForm Override'])
+                        prRed(n.name, n.bl_idname)
+                        # relying on the socket name like this is probably wrong
+                        node_tree.links.new(shape_xform_n.outputs["xForm Out"], node_tree.nodes[in_node_name].inputs['Custom Object xForm Override'])
                         break
                 else: # make it a task
                     prRed("Cannot set custom object transform override for %s to %s" % (in_node_name, out_node_name))

+ 68 - 21
xForm_definitions.py

@@ -5,7 +5,7 @@ from mantis.utilities import (prRed, prGreen, prPurple, prWhite,
                               prOrange,
                               wrapRed, wrapGreen, wrapPurple, wrapWhite,
                               wrapOrange,)
-from .base_definitions import get_signature_from_edited_tree
+from .base_definitions import get_signature_from_edited_tree, get_is_name_unique
 
 
 def TellClasses():
@@ -74,9 +74,21 @@ class xFormBoneNode(Node, xFormNode):
     display_ik_settings : bpy.props.BoolProperty(default=False)
     display_vp_settings : bpy.props.BoolProperty(default=False)
     display_def_settings : bpy.props.BoolProperty(default=False)
-    socket_count : bpy.props.IntProperty()
+    socket_count : bpy.props.IntProperty() # not needed anymore, right?
+    
+    error : bpy.props.BoolProperty(default=False)
+    error_msg : bpy.props.StringProperty(default="")
+    error_icon : bpy.props.StringProperty(default="NONE")
     
     def init(self, context):
+        
+        context = bpy.context
+        if context.space_data:
+            node_tree = context.space_data.path[0].node_tree
+            from mantis import readtree
+            prOrange("Updating from xFormBone init callback")
+            node_tree.update_tree(context)
+        
         self.inputs.new('StringSocket', "Name")
         self.inputs.new('RotationOrderSocket', "Rotation Order")
         self.inputs.new('RelationshipSocket', "Relationship")
@@ -145,14 +157,26 @@ class xFormBoneNode(Node, xFormNode):
         self.outputs.new('xFormSocket', "xForm Out")
     
     def draw_buttons(self, context, layout):
+        layout.label(text=self.error_msg, icon = self.error_icon)
         layout.operator("mantis.add_custom_property", text='+Add Custom Parameter')
         # layout.label(text="Edit Parameter ... not implemented")
         if (len(self.inputs) > self.socket_count):
             layout.operator("mantis.remove_custom_property", text='-Remove Custom Parameter')
         else:
             layout.label(text="")
+    
+    # def draw_label(self):
+        # if not self.error:
+            # return self.label
+        # else:
+            # return self.error_msg
         
     def display_update(self, parsed_tree, context):
+        errors = []
+        self.error_msg = ""
+        self.error_icon = "NONE"
+        self.error=False
+        
         if context.space_data:
             node_tree = context.space_data.path[0].node_tree
             nc = parsed_tree.get(get_signature_from_edited_tree(self, context))
@@ -213,29 +237,52 @@ class xFormBoneNode(Node, xFormNode):
                         link = inp.links[0]
                     else:
                         link = None
-            #
-            if self.display_ik_settings == True:
-                for inp in self.inputs[4:14]:
-                    inp.hide = False
+                if get_is_name_unique(nc, parsed_tree) == False:
+                    errors.append("Bone name is not unique.")
+                    self.error_icon = "ERROR"
+                    self.color=(1.0,0.0,0.0)
+                    self.error=True
             else:
-                for inp in self.inputs[4:14]:
-                    inp.hide = True
-            if self.display_vp_settings == True:
-                for inp in self.inputs[16:22]:
-                    inp.hide = False
-            else:
-                for inp in self.inputs[16:22]:
-                    inp.hide = True
+                errors.append("Bone is not connected to the tree.")
+                self.color=(0.7,0.35,0.0)
+                self.error_icon = "CANCEL"
+                self.error=True
             #
-            if self.display_def_settings == True:
-                for inp in self.inputs[24:29]:
-                    inp.hide = False
-            else:
-                for inp in self.inputs[24:29]:
-                    inp.hide = True
+        if self.display_ik_settings == True:
+            for inp in self.inputs[4:14]:
+                inp.hide = False
+        else:
+            for inp in self.inputs[4:14]:
+                inp.hide = True
+        if self.display_vp_settings == True:
+            for inp in self.inputs[16:22]:
+                inp.hide = False
+        else:
+            for inp in self.inputs[16:22]:
+                inp.hide = True
+        #
+        if self.display_def_settings == True:
+            for inp in self.inputs[24:29]:
+                inp.hide = False
+        else:
+            for inp in self.inputs[24:29]:
+                inp.hide = True
+                
+        if self.error:
+            print (errors)
+            self.use_custom_color=True
+            self.error_msg= " and ".join(errors)
+        else:
+            self.color=(0.3,0.3,0.3)
+            self.use_custom_color=False
+                
         
-    
+
     # def copy(ectype, archtype):
+        # tree = ectype.id_data.parsed_tree
+        # n = get_unique_name(ectype.name, tree)
+        # ectype.name = "boink!"
+        
         # # TODO: automatically avoid duplicating names
         # ectype.inputs["Name"].default_value = ""