| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 | import bpyfrom .base_definitions import xFormNodefrom bpy.types import Nodefrom mantis.utilities import (prRed, prGreen, prPurple, prWhite,                              prOrange,                              wrapRed, wrapGreen, wrapPurple, wrapWhite,                              wrapOrange,)from .base_definitions import get_signature_from_edited_treedef TellClasses():    return [        # xFormNullNode,        xFormBoneNode,        xFormRootNode,        xFormArmatureNode,        xFormGeometryObjectNode,        ]def default_traverse(self, socket):    if (socket == self.outputs["xForm Out"]):        return self.inputs["Relationship"]    if (socket == self.inputs["Relationship"]):        return self.outputs["xForm Out"]    return None# Representing an Empty or non-armature-Object# class xFormNullNode(Node, xFormNode):#     '''A node representing a Null node'''#     bl_idname = 'xFormNullNode'#     bl_label = "Null"#     bl_icon = 'EMPTY_AXIS'#     # === Optional Functions ===#     def init(self, context):#         self.inputs.new('StringSocket', "Name")#         self.inputs.new('RelationshipSocket', "Relationship")#         self.inputs.new('RotationOrderSocket', "Rotation Order")#         self.inputs.new('MatrixSocket', "Matrix")#         self.outputs.new('xFormSocket', "xForm Out")def check_if_connected(start, end, line):    started=False    for path_nc in line:        prWhite("    ", path_nc.signature)        if path_nc.signature == start.signature:            started = True        elif path_nc.signature == end.signature:            break        if started:            if path_nc.inputs.get("Connected"):                if path_nc.evaluate_input("Connected") == False:                    return False    else:        return False    return Trueclass xFormRootNode(Node, xFormNode):    '''A node representing the world node'''    bl_idname = 'xFormRootNode'    bl_label = "World Root"    bl_icon = 'WORLD'    def init(self, context):        self.outputs.new('RelationshipSocket', "World Out")        class xFormBoneNode(Node, xFormNode):    '''A node representing a Bone'''    bl_idname = 'xFormBoneNode'    bl_label = "Bone"    bl_icon = 'BONE_DATA'        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()        def init(self, context):        self.inputs.new('StringSocket', "Name")        self.inputs.new('RotationOrderSocket', "Rotation Order")        self.inputs.new('RelationshipSocket', "Relationship")        self.inputs.new('MatrixSocket', "Matrix")        # IK SETTINGS        a = []        # a.append(self.inputs.new ('LabelSocket', "IK Settings"))        a.append(self.inputs.new ('FloatFactorSocket', "IK Stretch"))        a.append(self.inputs.new ('BooleanThreeTupleSocket', "Lock IK"))        a.append(self.inputs.new ('NodeSocketVector', "IK Stiffness"))        a.append(self.inputs.new ('BooleanThreeTupleSocket', "Limit IK"))        a.append(self.inputs.new ('NodeSocketFloatAngle', "X Min"))        a.append(self.inputs.new ('NodeSocketFloatAngle', "X Max"))        a.append(self.inputs.new ('NodeSocketFloatAngle', "Y Min"))        a.append(self.inputs.new ('NodeSocketFloatAngle', "Y Max"))        a.append(self.inputs.new ('NodeSocketFloatAngle', "Z Min"))        a.append(self.inputs.new ('NodeSocketFloatAngle', "Z Max"))        #4-14                # visual settings:        b = []        b.append(self.inputs.new ('LayerMaskSocket', "Layer Mask"))        b.append(self.inputs.new ('xFormSocket', "Custom Object"))        b.append(self.inputs.new ('xFormSocket', "Custom Object xForm Override"))        b.append(self.inputs.new ('BooleanSocket', "Custom Object Scale to Bone Length"))        b.append(self.inputs.new ('BooleanSocket', "Custom Object Wireframe"))        b.append(self.inputs.new ('VectorScaleSocket', "Custom Object Scale"))        b.append(self.inputs.new ('VectorSocket', "Custom Object Translation"))        b.append(self.inputs.new ('VectorEulerSocket', "Custom Object Rotation"))        b.append(self.inputs.new ('StringSocket', "Bone Group"))        # 16-22        # Deform Settings:        c = []        c.append(self.inputs.new ('BooleanSocket', "Deform"))        c.append(self.inputs.new ('FloatPositiveSocket', "Envelope Distance"))        c.append(self.inputs.new ('FloatFactorSocket',   "Envelope Weight"))        c.append(self.inputs.new ('BooleanSocket', "Envelope Multiply"))        c.append(self.inputs.new ('FloatPositiveSocket', "Envelope Head Radius"))        c.append(self.inputs.new ('FloatPositiveSocket', "Envelope Tail Radius"))        #24-28                # c[0].default_value=False                # Hide should be last        b.append(self.inputs.new ('HideSocket',   "Hide"))                    for sock in a:            sock.hide = True        for sock in b:            if sock.name in ['Custom Object', 'Layer Mask']:                continue            sock.hide = True        for sock in c:            if sock.name == 'Deform':                continue            sock.hide = True                    # Thinking about using colors for nodes, why not?        # cxForm          = (0.443137, 0.242157, 0.188235,) #could even fetch the theme colors...        # self.color=cxForm        # self.use_custom_color=True        self.socket_count = len(self.inputs)        #        self.outputs.new('xFormSocket', "xForm Out")        def draw_buttons(self, context, layout):        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 display_update(self, parsed_tree, context):        if context.space_data:            node_tree = context.space_data.path[0].node_tree            nc = parsed_tree.get(get_signature_from_edited_tree(self, context))            other_nc = None            if len(self.inputs.get("Relationship").links)>0:                prev_node = self.inputs.get("Relationship").links[0].from_node                if prev_node:                    other_nc = parsed_tree.get(get_signature_from_edited_tree(prev_node, context))                        if nc and other_nc:                self.display_vp_settings = nc.inputs["Custom Object"].is_connected                self.display_def_settings = nc.evaluate_input("Deform")                self.display_ik_settings = False                #                from .node_container_common import ( trace_all_lines_up,                                                     trace_single_line)                trace = trace_all_lines_up(nc, "xForm Out")                                for key in trace.keys():                    if (ik_nc:= parsed_tree.get(key)):                        if ik_nc.__class__.__name__ in ["LinkInverseKinematics"]:                            # if the tree is invalid? This shouldn't be necessary.                            if ik_nc.inputs["Input Relationship"].is_connected:                                chain_count = ik_nc.evaluate_input("Chain Length")                                if chain_count == 0:                                    self.display_ik_settings = True                                else:                                    if ik_nc.evaluate_input("Use Tail") == False:                                        chain_count+=1                                    for line in trace[key]:                                        # preprocess it to get rid of non-xForms:                                        xForm_line=[]                                        for path_nc in line:                                            if path_nc == ik_nc:                                                if ik_nc.inputs["Input Relationship"].links[0].from_node != prev_path_nc:                                                    break # not a constraint connection                                            if path_nc.node_type == 'XFORM':                                                xForm_line.append(path_nc)                                            prev_path_nc = path_nc                                                                                    else:                                            if len(xForm_line) < chain_count:                                                self.display_ik_settings = True                                inp = nc.inputs["Relationship"]                link = None                if inp.is_connected:                    link = inp.links[0]                while(link):                    if link.from_node.__class__.__name__ in ["LinkInverseKinematics"]:                        self.display_ik_settings = link.from_node.evaluate_input("Use Tail")                        break                    inp = link.from_node.outputs[link.from_socket]                    inp = inp.traverse_target                    if not inp:                        break                    if inp.links:                        link = inp.links[0]                    else:                        link = None            #            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                # def copy(ectype, archtype):        # # TODO: automatically avoid duplicating names        # ectype.inputs["Name"].default_value = ""class xFormArmatureNode(Node, xFormNode):    '''A node representing an Armature object node'''    bl_idname = 'xFormArmatureNode'    bl_label = "Armature"    bl_icon = 'OUTLINER_OB_ARMATURE'    def init(self, context):        self.inputs.new('StringSocket', "Name")        self.inputs.new('RelationshipSocket', "Relationship")        self.inputs.new('RotationOrderSocket', "Rotation Order")        self.inputs.new('MatrixSocket', "Matrix")        self.outputs.new('xFormSocket', "xForm Out")class xFormGeometryObjectNode(Node, xFormNode):    """Represents a curve or mesh object."""    bl_idname = "xFormGeometryObject"    bl_label = "Geometry Object"    bl_icon = "EMPTY_AXIS"        def init(self, context):        self.inputs.new('StringSocket', "Name")        self.inputs.new('GeometrySocket', "Geometry")        self.inputs.new('MatrixSocket', "Matrix")        self.inputs.new('RelationshipSocket', "Relationship")        self.outputs.new('xFormSocket', "xForm Out")
 |